Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-jupyter-core for 
openSUSE:Factory checked in at 2023-12-25 19:05:32
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-jupyter-core (Old)
 and      /work/SRC/openSUSE:Factory/.python-jupyter-core.new.28375 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-jupyter-core"

Mon Dec 25 19:05:32 2023 rev:22 rq:1134926 version:5.5.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-jupyter-core/python-jupyter-core.changes  
2023-11-27 22:43:30.594133525 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-jupyter-core.new.28375/python-jupyter-core.changes
       2023-12-25 19:05:46.622526147 +0100
@@ -1,0 +2,7 @@
+Sat Dec 23 19:23:58 UTC 2023 - Ben Greiner <c...@bnavigator.de>
+
+- Update to 5.5.1
+  * Account for read only file systems in migration #379
+    (@blink1073)
+
+-------------------------------------------------------------------

Old:
----
  jupyter_core-5.5.0.tar.gz

New:
----
  jupyter_core-5.5.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-jupyter-core.spec ++++++
--- /var/tmp/diff_new_pack.oxcSN8/_old  2023-12-25 19:05:47.278550087 +0100
+++ /var/tmp/diff_new_pack.oxcSN8/_new  2023-12-25 19:05:47.278550087 +0100
@@ -32,7 +32,7 @@
 %endif
 
 Name:           python-jupyter-core%{psuffix}
-Version:        5.5.0
+Version:        5.5.1
 Release:        0
 Summary:        Base package on which Jupyter projects rely
 License:        BSD-3-Clause

++++++ jupyter_core-5.5.0.tar.gz -> jupyter_core-5.5.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/.github/workflows/downstream.yml 
new/jupyter_core-5.5.1/.github/workflows/downstream.yml
--- old/jupyter_core-5.5.0/.github/workflows/downstream.yml     1970-01-01 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.5.1/.github/workflows/downstream.yml     2020-02-02 
01:00:00.000000000 +0100
@@ -0,0 +1,82 @@
+name: Test downstream projects
+
+on:
+  push:
+    branches: ["main"]
+  pull_request:
+
+concurrency:
+  group: downstream-${{ github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  ipykernel:
+    runs-on: ubuntu-latest
+    timeout-minutes: 15
+    steps:
+      - uses: actions/checkout@v4
+      - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
+      - uses: jupyterlab/maintainer-tools/.github/actions/downstream-test@v1
+        with:
+          package_name: ipykernel
+
+  nbclient:
+    runs-on: ubuntu-latest
+    timeout-minutes: 15
+    steps:
+      - uses: actions/checkout@v4
+      - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
+      - uses: jupyterlab/maintainer-tools/.github/actions/downstream-test@v1
+        with:
+          package_name: nbclient
+          env_values: IPYKERNEL_CELL_NAME=\<IPY-INPUT\>
+
+  nbconvert:
+    runs-on: ubuntu-latest
+    timeout-minutes: 15
+    steps:
+      - uses: actions/checkout@v4
+      - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
+      - uses: jupyterlab/maintainer-tools/.github/actions/downstream-test@v1
+        with:
+          package_name: nbconvert
+          package_spec: pip install -e ".[test]"
+
+  jupyter_server:
+    runs-on: ubuntu-latest
+    timeout-minutes: 15
+    steps:
+      - uses: actions/checkout@v4
+      - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
+      - uses: jupyterlab/maintainer-tools/.github/actions/downstream-test@v1
+        with:
+          package_name: jupyter_server
+
+  jupyter_client:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+
+      - name: Base Setup
+        uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
+
+      - name: Run Test
+        uses: jupyterlab/maintainer-tools/.github/actions/downstream-test@v1
+        with:
+          package_name: jupyter_client
+
+  downstreams_check: # This job does nothing and is only used for the branch 
protection
+    if: always()
+    needs:
+      - ipykernel
+      - nbclient
+      - nbconvert
+      - jupyter_server
+      - jupyter_client
+    runs-on: ubuntu-latest
+    steps:
+      - name: Decide whether the needed jobs succeeded or failed
+        uses: re-actors/alls-green@release/v1
+        with:
+          jobs: ${{ toJSON(needs) }}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/.github/workflows/test.yml 
new/jupyter_core-5.5.1/.github/workflows/test.yml
--- old/jupyter_core-5.5.0/.github/workflows/test.yml   2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.5.1/.github/workflows/test.yml   2020-02-02 
01:00:00.000000000 +0100
@@ -112,7 +112,7 @@
       - name: Run Linters
         run: |
           hatch run typing:test
-          hatch run lint:style
+          hatch run lint:build
           pipx run interrogate -v .
           pipx run doc8 --max-line-length=200
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/.pre-commit-config.yaml 
new/jupyter_core-5.5.1/.pre-commit-config.yaml
--- old/jupyter_core-5.5.0/.pre-commit-config.yaml      2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.5.1/.pre-commit-config.yaml      2020-02-02 
01:00:00.000000000 +0100
@@ -21,7 +21,7 @@
       - id: trailing-whitespace
 
   - repo: https://github.com/python-jsonschema/check-jsonschema
-    rev: 0.27.0
+    rev: 0.27.1
     hooks:
       - id: check-github-workflows
 
@@ -33,7 +33,7 @@
           [mdformat-gfm, mdformat-frontmatter, mdformat-footnote]
 
   - repo: https://github.com/pre-commit/mirrors-prettier
-    rev: "v3.0.3"
+    rev: "v3.1.0"
     hooks:
       - id: prettier
         types_or: [yaml, html, json]
@@ -44,6 +44,15 @@
       - id: blacken-docs
         additional_dependencies: [black==23.7.0]
 
+  - repo: https://github.com/pre-commit/mirrors-mypy
+    rev: "v1.7.1"
+    hooks:
+      - id: mypy
+        files: jupyter_core
+        stages: [manual]
+        args: ["--install-types", "--non-interactive"]
+        additional_dependencies: ["traitlets>=5.13", "platformdirs>=3.11"]
+
   - repo: https://github.com/codespell-project/codespell
     rev: "v2.2.6"
     hooks:
@@ -58,14 +67,16 @@
       - id: rst-inline-touching-normal
 
   - repo: https://github.com/astral-sh/ruff-pre-commit
-    rev: v0.1.3
+    rev: v0.1.6
     hooks:
       - id: ruff
+        types_or: [python, jupyter]
         args: ["--fix", "--show-fixes"]
       - id: ruff-format
+        types_or: [python, jupyter]
 
   - repo: https://github.com/scientific-python/cookie
-    rev: "2023.10.27"
+    rev: "2023.11.17"
     hooks:
       - id: sp-repo-review
         additional_dependencies: ["repo-review[cli]"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/CHANGELOG.md 
new/jupyter_core-5.5.1/CHANGELOG.md
--- old/jupyter_core-5.5.0/CHANGELOG.md 2020-02-02 01:00:00.000000000 +0100
+++ new/jupyter_core-5.5.1/CHANGELOG.md 2020-02-02 01:00:00.000000000 +0100
@@ -2,6 +2,28 @@
 
 <!-- <START NEW CHANGELOG ENTRY> -->
 
+## 5.5.1
+
+([Full 
Changelog](https://github.com/jupyter/jupyter_core/compare/v5.5.0...4e387a4e95b1064cca4a97dd7324b29d14b6e3b7))
+
+### Bugs fixed
+
+- Account for read only file systems in migration 
[#379](https://github.com/jupyter/jupyter_core/pull/379) 
([@blink1073](https://github.com/blink1073))
+
+### Maintenance and upkeep improvements
+
+- Update ruff and typings 
[#376](https://github.com/jupyter/jupyter_core/pull/376) 
([@blink1073](https://github.com/blink1073))
+- chore: update pre-commit hooks 
[#374](https://github.com/jupyter/jupyter_core/pull/374) 
([@pre-commit-ci](https://github.com/pre-commit-ci))
+- Clean up lint and add downstream checks 
[#373](https://github.com/jupyter/jupyter_core/pull/373) 
([@blink1073](https://github.com/blink1073))
+
+### Contributors to this release
+
+([GitHub contributors page for this 
release](https://github.com/jupyter/jupyter_core/graphs/contributors?from=2023-10-30&to=2023-12-18&type=c))
+
+[@blink1073](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_core+involves%3Ablink1073+updated%3A2023-10-30..2023-12-18&type=Issues)
 | 
[@mtelka](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_core+involves%3Amtelka+updated%3A2023-10-30..2023-12-18&type=Issues)
 | 
[@pre-commit-ci](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_core+involves%3Apre-commit-ci+updated%3A2023-10-30..2023-12-18&type=Issues)
+
+<!-- <END NEW CHANGELOG ENTRY> -->
+
 ## 5.5.0
 
 ([Full 
Changelog](https://github.com/jupyter/jupyter_core/compare/v5.4.0...df0e9e709ebe208df799ec08030b7d7eb15c9cf9))
@@ -20,8 +42,6 @@
 
 
[@blink1073](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_core+involves%3Ablink1073+updated%3A2023-10-10..2023-10-30&type=Issues)
 | 
[@singingwolfboy](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_core+involves%3Asingingwolfboy+updated%3A2023-10-10..2023-10-30&type=Issues)
 
-<!-- <END NEW CHANGELOG ENTRY> -->
-
 ## 5.4.0
 
 ([Full 
Changelog](https://github.com/jupyter/jupyter_core/compare/v5.3.2...d6a748262a44334f27008e8c90d2557f46481f5b))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/PKG-INFO 
new/jupyter_core-5.5.1/PKG-INFO
--- old/jupyter_core-5.5.0/PKG-INFO     2020-02-02 01:00:00.000000000 +0100
+++ new/jupyter_core-5.5.1/PKG-INFO     2020-02-02 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: jupyter_core
-Version: 5.5.0
+Version: 5.5.1
 Summary: Jupyter core package. A base package on which Jupyter projects rely.
 Project-URL: Homepage, https://jupyter.org
 Project-URL: Documentation, https://jupyter-core.readthedocs.io/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/docs/conf.py 
new/jupyter_core-5.5.1/docs/conf.py
--- old/jupyter_core-5.5.0/docs/conf.py 2020-02-02 01:00:00.000000000 +0100
+++ new/jupyter_core-5.5.1/docs/conf.py 2020-02-02 01:00:00.000000000 +0100
@@ -1,5 +1,3 @@
-#!/usr/bin/env python3
-#
 # jupyter_core documentation build configuration file, created by
 # sphinx-quickstart on Wed Jun 24 11:51:36 2015.
 #
@@ -11,9 +9,10 @@
 #
 # All configuration values have a default; values that are commented out
 # serve to show the default.
+from __future__ import annotations
 
-import os
 import shutil
+from pathlib import Path
 
 from jupyter_core.version import __version__, version_info
 
@@ -39,7 +38,7 @@
 ]
 
 try:
-    import enchant  # type:ignore  # noqa
+    import enchant  # noqa: F401
 
     extensions += ["sphinxcontrib.spelling"]
 except ImportError:
@@ -63,7 +62,7 @@
 
 # General information about the project.
 project = "jupyter_core"
-copyright = "2015, Jupyter Development Team"  # noqa
+copyright = "2015, Jupyter Development Team"
 author = "Jupyter Development Team"
 
 # The version info for the project you're documenting, acts as replacement for
@@ -300,6 +299,6 @@
 intersphinx_mapping = {"https://docs.python.org/3/": None}
 
 
-def setup(app):
-    here = os.path.dirname(os.path.abspath(__file__))
-    shutil.copy(os.path.join(here, "..", "CHANGELOG.md"), "changelog.md")
+def setup(_):
+    here = Path(__file__).parent.resolve()
+    shutil.copy(Path(here, "..", "CHANGELOG.md"), "changelog.md")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/jupyter.py 
new/jupyter_core-5.5.1/jupyter.py
--- old/jupyter_core-5.5.0/jupyter.py   2020-02-02 01:00:00.000000000 +0100
+++ new/jupyter_core-5.5.1/jupyter.py   2020-02-02 01:00:00.000000000 +0100
@@ -1,4 +1,6 @@
 """Launch the root jupyter command"""
+from __future__ import annotations
+
 if __name__ == "__main__":
     from jupyter_core.command import main
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/jupyter_core/__init__.py 
new/jupyter_core-5.5.1/jupyter_core/__init__.py
--- old/jupyter_core-5.5.0/jupyter_core/__init__.py     2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.5.1/jupyter_core/__init__.py     2020-02-02 
01:00:00.000000000 +0100
@@ -1 +0,0 @@
-from .version import __version__, version_info  # noqa
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/jupyter_core/__main__.py 
new/jupyter_core-5.5.1/jupyter_core/__main__.py
--- old/jupyter_core-5.5.0/jupyter_core/__main__.py     2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.5.1/jupyter_core/__main__.py     2020-02-02 
01:00:00.000000000 +0100
@@ -1,4 +1,6 @@
 """Launch the root jupyter command"""
+from __future__ import annotations
+
 from .command import main
 
 main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/jupyter_core/application.py 
new/jupyter_core-5.5.1/jupyter_core/application.py
--- old/jupyter_core-5.5.0/jupyter_core/application.py  2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.5.1/jupyter_core/application.py  2020-02-02 
01:00:00.000000000 +0100
@@ -13,6 +13,7 @@
 import sys
 import typing as t
 from copy import deepcopy
+from pathlib import Path
 from shutil import which
 
 from traitlets import Bool, List, Unicode, observe
@@ -62,7 +63,7 @@
 base_flags.update(_jupyter_flags)
 
 
-class NoStart(Exception):  # noqa
+class NoStart(Exception):
     """Exception to raise when an application shouldn't start"""
 
 
@@ -135,9 +136,9 @@
         if self.config_file:
             config_file = self.config_file
         else:
-            config_file = os.path.join(self.config_dir, self.config_file_name 
+ ".py")
+            config_file = str(Path(self.config_dir, self.config_file_name + 
".py"))
 
-        if os.path.exists(config_file) and not self.answer_yes:
+        if Path(config_file).exists() and not self.answer_yes:
             answer = ""
 
             def ask() -> str:
@@ -157,19 +158,19 @@
 
         config_text = self.generate_config_file()
         print("Writing default config to: %s" % config_file)
-        ensure_dir_exists(os.path.abspath(os.path.dirname(config_file)), 0o700)
-        with open(config_file, mode="w", encoding="utf-8") as f:
+        ensure_dir_exists(Path(config_file).parent.resolve(), 0o700)
+        with Path.open(Path(config_file), mode="w", encoding="utf-8") as f:
             f.write(config_text)
 
     def migrate_config(self) -> None:
         """Migrate config/data from IPython 3"""
         try:  # let's see if we can open the marker file
             # for reading and updating (writing)
-            f_marker = open(os.path.join(self.config_dir, "migrated"), "r+")  
# noqa
-        except PermissionError:  # not readable and/or writable
-            return  # so let's give up migration in such an environment
+            f_marker = Path.open(Path(self.config_dir, "migrated"), "r+")
         except FileNotFoundError:  # cannot find the marker file
             pass  # that means we have not migrated yet, so continue
+        except OSError:  # not readable and/or writable
+            return  # so let's give up migration in such an environment
         else:  # if we got here without raising anything,
             # that means the file exists
             f_marker.close()
@@ -178,7 +179,7 @@
         from .migrate import get_ipython_dir, migrate
 
         # No IPython dir, nothing to migrate
-        if not os.path.exists(get_ipython_dir()):
+        if not Path(get_ipython_dir()).exists():
             return
 
         migrate()
@@ -262,7 +263,7 @@
     def start(self) -> None:
         """Start the whole thing"""
         if self.subcommand:
-            os.execv(self.subcommand, [self.subcommand] + self.argv[1:])  # 
noqa
+            os.execv(self.subcommand, [self.subcommand] + self.argv[1:])  # 
noqa: S606
             raise NoStart()
 
         if self.subapp:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/jupyter_core/command.py 
new/jupyter_core-5.5.1/jupyter_core/command.py
--- old/jupyter_core-5.5.0/jupyter_core/command.py      2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.5.1/jupyter_core/command.py      2020-02-02 
01:00:00.000000000 +0100
@@ -15,6 +15,7 @@
 import site
 import sys
 import sysconfig
+from pathlib import Path
 from shutil import which
 from subprocess import Popen
 from typing import Any
@@ -37,7 +38,6 @@
     @epilog.setter
     def epilog(self, x: Any) -> None:
         """Ignore epilog set in Parser.__init__"""
-        pass
 
     def argcomplete(self) -> None:
         """Trigger auto-completion, if enabled"""
@@ -63,7 +63,7 @@
         "subcommand", type=str, nargs="?", help="the subcommand to launch"
     )
     # For argcomplete, supply all known subcommands
-    subcommand_action.completer = lambda *args, **kwargs: list_subcommands()  
# type: ignore[attr-defined]
+    subcommand_action.completer = lambda *args, **kwargs: list_subcommands()  
# type: ignore[attr-defined]  # noqa: ARG005
 
     group.add_argument("--config-dir", action="store_true", help="show Jupyter 
config dir")
     group.add_argument("--data-dir", action="store_true", help="show Jupyter 
data dir")
@@ -98,7 +98,7 @@
             if name.startswith("jupyter-"):
                 if sys.platform.startswith("win"):
                     # remove file-extension on Windows
-                    name = os.path.splitext(name)[0]  # noqa
+                    name = os.path.splitext(name)[0]  # noqa: PTH122, PLW2901
                 subcommand_tuples.add(tuple(name.split("-")[1:]))
     # build a set of subcommand strings, excluding subcommands whose parents 
are defined
     subcommands = set()
@@ -120,7 +120,7 @@
         cmd_path = which(cmd)
         if cmd_path is None:
             raise OSError("%r not found" % cmd, errno.ENOENT)
-        p = Popen([cmd_path] + argv[1:])  # noqa
+        p = Popen([cmd_path] + argv[1:])  # noqa: S603
         # Don't raise KeyboardInterrupt in the parent process.
         # Set this after spawning, to avoid subprocess inheriting handler.
         import signal
@@ -129,7 +129,7 @@
         p.wait()
         sys.exit(p.returncode)
     else:
-        os.execvp(cmd, argv)  # noqa
+        os.execvp(cmd, argv)  # noqa: S606
 
 
 def _jupyter_abspath(subcommand: str) -> str:
@@ -177,13 +177,13 @@
         path_list.append(bindir)
 
     scripts = [sys.argv[0]]
-    if os.path.islink(scripts[0]):
+    if Path(scripts[0]).is_symlink():
         # include realpath, if `jupyter` is a symlink
         scripts.append(os.path.realpath(scripts[0]))
 
     for script in scripts:
-        bindir = os.path.dirname(script)
-        if os.path.isdir(bindir) and os.access(script, os.X_OK):  # only if 
it's a script
+        bindir = str(Path(script).parent)
+        if Path(bindir).is_dir() and os.access(script, os.X_OK):  # only if 
it's a script
             # ensure executable's dir is on PATH
             # avoids missing subcommands when jupyter is run via absolute path
             path_list.insert(0, bindir)
@@ -211,9 +211,8 @@
             # increment word from which to start handling arguments
             increment_argcomplete_index()
             return cwords
-        else:
-            # Otherwise no subcommand, directly autocomplete and exit
-            parser.argcomplete()
+        # Otherwise no subcommand, directly autocomplete and exit
+        parser.argcomplete()
     except ImportError:
         # traitlets >= 5.8 not available, just try to complete this without
         # worrying about subcommands
@@ -222,7 +221,7 @@
     raise AssertionError(msg)
 
 
-def main() -> None:  # noqa
+def main() -> None:
     """The command entry point."""
     parser = jupyter_parser()
     argv = sys.argv
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/jupyter_core/migrate.py 
new/jupyter_core-5.5.1/jupyter_core/migrate.py
--- old/jupyter_core-5.5.0/jupyter_core/migrate.py      2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.5.1/jupyter_core/migrate.py      2020-02-02 
01:00:00.000000000 +0100
@@ -29,6 +29,7 @@
 import re
 import shutil
 from datetime import datetime, timezone
+from pathlib import Path
 from typing import Any
 
 from traitlets.config.loader import JSONFileConfigLoader, PyFileConfigLoader
@@ -41,20 +42,18 @@
 # mypy: disable-error-code="no-untyped-call"
 
 
-pjoin = os.path.join
-
 migrations = {
-    pjoin("{ipython_dir}", "nbextensions"): pjoin("{jupyter_data}", 
"nbextensions"),
-    pjoin("{ipython_dir}", "kernels"): pjoin("{jupyter_data}", "kernels"),
-    pjoin("{profile}", "nbconfig"): pjoin("{jupyter_config}", "nbconfig"),
+    str(Path("{ipython_dir}", "nbextensions")): str(Path("{jupyter_data}", 
"nbextensions")),
+    str(Path("{ipython_dir}", "kernels")): str(Path("{jupyter_data}", 
"kernels")),
+    str(Path("{profile}", "nbconfig")): str(Path("{jupyter_config}", 
"nbconfig")),
 }
 
-custom_src_t = pjoin("{profile}", "static", "custom")
-custom_dst_t = pjoin("{jupyter_config}", "custom")
+custom_src_t = str(Path("{profile}", "static", "custom"))
+custom_dst_t = str(Path("{jupyter_config}", "custom"))
 
 for security_file in ("notebook_secret", "notebook_cookie_secret", 
"nbsignatures.db"):
-    src = pjoin("{profile}", "security", security_file)
-    dst = pjoin("{jupyter_data}", security_file)
+    src = str(Path("{profile}", "security", security_file))
+    dst = str(Path("{jupyter_data}", security_file))
     migrations[src] = dst
 
 config_migrations = ["notebook", "nbconvert", "qtconsole"]
@@ -81,7 +80,7 @@
     We only need to support the IPython < 4 behavior for migration,
     so importing for forward-compatibility and edge cases is not important.
     """
-    return os.environ.get("IPYTHONDIR", os.path.expanduser("~/.ipython"))
+    return os.environ.get("IPYTHONDIR", str(Path("~/.ipython").expanduser()))
 
 
 def migrate_dir(src: str, dst: str) -> bool:
@@ -90,38 +89,37 @@
     if not os.listdir(src):
         log.debug("No files in %s", src)
         return False
-    if os.path.exists(dst):
+    if Path(dst).exists():
         if os.listdir(dst):
             # already exists, non-empty
             log.debug("%s already exists", dst)
             return False
-        else:
-            os.rmdir(dst)
+        Path(dst).rmdir()
     log.info("Copying %s -> %s", src, dst)
-    ensure_dir_exists(os.path.dirname(dst))
+    ensure_dir_exists(Path(dst).parent)
     shutil.copytree(src, dst, symlinks=True)
     return True
 
 
-def migrate_file(src: str, dst: str, substitutions: Any = None) -> bool:
+def migrate_file(src: str | Path, dst: str | Path, substitutions: Any = None) 
-> bool:
     """Migrate a single file from src to dst
 
     substitutions is an optional dict of {regex: replacement} for performing 
replacements on the file.
     """
     log = get_logger()
-    if os.path.exists(dst):
+    if Path(dst).exists():
         # already exists
         log.debug("%s already exists", dst)
         return False
     log.info("Copying %s -> %s", src, dst)
-    ensure_dir_exists(os.path.dirname(dst))
+    ensure_dir_exists(Path(dst).parent)
     shutil.copy(src, dst)
     if substitutions:
-        with open(dst, encoding="utf-8") as f:
+        with Path.open(Path(dst), encoding="utf-8") as f:
             text = f.read()
         for pat, replacement in substitutions.items():
             text = pat.sub(replacement, text)
-        with open(dst, "w", encoding="utf-8") as f:
+        with Path.open(Path(dst), "w", encoding="utf-8") as f:
             f.write(text)
     return True
 
@@ -132,13 +130,12 @@
     dispatches to migrate_dir/_file
     """
     log = get_logger()
-    if os.path.isfile(src):
+    if Path(src).is_file():
         return migrate_file(src, dst)
-    elif os.path.isdir(src):
+    if Path(src).is_dir():
         return migrate_dir(src, dst)
-    else:
-        log.debug("Nothing to migrate for %s", src)
-        return False
+    log.debug("Nothing to migrate for %s", src)
+    return False
 
 
 def migrate_static_custom(src: str, dst: str) -> bool:
@@ -149,12 +146,12 @@
     log = get_logger()
     migrated = False
 
-    custom_js = pjoin(src, "custom.js")
-    custom_css = pjoin(src, "custom.css")
+    custom_js = Path(src, "custom.js")
+    custom_css = Path(src, "custom.css")
     # check if custom_js is empty:
     custom_js_empty = True
-    if os.path.isfile(custom_js):
-        with open(custom_js, encoding="utf-8") as f:
+    if Path(custom_js).is_file():
+        with Path.open(custom_js, encoding="utf-8") as f:
             js = f.read().strip()
             for line in js.splitlines():
                 if not (line.isspace() or line.strip().startswith(("/*", "*", 
"//"))):
@@ -163,8 +160,8 @@
 
     # check if custom_css is empty:
     custom_css_empty = True
-    if os.path.isfile(custom_css):
-        with open(custom_css, encoding="utf-8") as f:
+    if Path(custom_css).is_file():
+        with Path.open(custom_css, encoding="utf-8") as f:
             css = f.read().strip()
             custom_css_empty = css.startswith("/*") and css.endswith("*/")
 
@@ -181,9 +178,9 @@
     if not custom_js_empty or not custom_css_empty:
         ensure_dir_exists(dst)
 
-    if not custom_js_empty and migrate_file(custom_js, pjoin(dst, 
"custom.js")):
+    if not custom_js_empty and migrate_file(custom_js, Path(dst, "custom.js")):
         migrated = True
-    if not custom_css_empty and migrate_file(custom_css, pjoin(dst, 
"custom.css")):
+    if not custom_css_empty and migrate_file(custom_css, Path(dst, 
"custom.css")):
         migrated = True
 
     return migrated
@@ -195,8 +192,8 @@
     Includes substitutions for updated configurable names.
     """
     log = get_logger()
-    src_base = pjoin("{profile}", "ipython_{name}_config").format(name=name, 
**env)
-    dst_base = pjoin("{jupyter_config}", 
"jupyter_{name}_config").format(name=name, **env)
+    src_base = str(Path(f"{env['profile']}", f"ipython_{name}_config"))
+    dst_base = str(Path(f"{env['jupyter_config']}", f"jupyter_{name}_config"))
     loaders = {
         ".py": PyFileConfigLoader,
         ".json": JSONFileConfigLoader,
@@ -205,7 +202,7 @@
     for ext in (".py", ".json"):
         src = src_base + ext
         dst = dst_base + ext
-        if os.path.exists(src):
+        if Path(src).exists():
             cfg = loaders[ext](src).load_config()
             if cfg:
                 if migrate_file(src, dst, substitutions=config_substitutions):
@@ -222,13 +219,13 @@
         "jupyter_data": jupyter_data_dir(),
         "jupyter_config": jupyter_config_dir(),
         "ipython_dir": get_ipython_dir(),
-        "profile": os.path.join(get_ipython_dir(), "profile_default"),
+        "profile": str(Path(get_ipython_dir(), "profile_default")),
     }
     migrated = False
     for src_t, dst_t in migrations.items():
         src = src_t.format(**env)
         dst = dst_t.format(**env)
-        if os.path.exists(src) and migrate_one(src, dst):
+        if Path(src).exists() and migrate_one(src, dst):
             migrated = True
 
     for name in config_migrations:
@@ -238,12 +235,12 @@
     custom_src = custom_src_t.format(**env)
     custom_dst = custom_dst_t.format(**env)
 
-    if os.path.exists(custom_src) and migrate_static_custom(custom_src, 
custom_dst):
+    if Path(custom_src).exists() and migrate_static_custom(custom_src, 
custom_dst):
         migrated = True
 
     # write a marker to avoid re-running migration checks
     ensure_dir_exists(env["jupyter_config"])
-    with open(os.path.join(env["jupyter_config"], "migrated"), "w", 
encoding="utf-8") as f:
+    with Path.open(Path(env["jupyter_config"], "migrated"), "w", 
encoding="utf-8") as f:
         f.write(datetime.now(tz=timezone.utc).isoformat())
 
     return migrated
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/jupyter_core/paths.py 
new/jupyter_core-5.5.1/jupyter_core/paths.py
--- old/jupyter_core-5.5.0/jupyter_core/paths.py        2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.5.1/jupyter_core/paths.py        2020-02-02 
01:00:00.000000000 +0100
@@ -6,7 +6,7 @@
 # Derived from IPython.utils.path, which is
 # Copyright (c) IPython Development Team.
 # Distributed under the terms of the Modified BSD License.
-
+from __future__ import annotations
 
 import errno
 import os
@@ -17,7 +17,7 @@
 import warnings
 from contextlib import contextmanager
 from pathlib import Path
-from typing import Any, Dict, Iterator, List, Optional
+from typing import Any, Iterator, Optional
 
 import platformdirs
 
@@ -63,14 +63,13 @@
 
 def get_home_dir() -> str:
     """Get the real path of the home directory"""
-    homedir = os.path.expanduser("~")
+    homedir = Path("~").expanduser()
     # Next line will make things work even when /home/ is a symlink to
     # /usr/home as it is on FreeBSD, for example
-    homedir = str(Path(homedir).resolve())
-    return homedir
+    return str(Path(homedir).resolve())
 
 
-_dtemps: Dict[str, str] = {}
+_dtemps: dict[str, str] = {}
 
 
 def _do_i_own(path: str) -> bool:
@@ -85,7 +84,7 @@
     # not always implemented or available
     try:
         return p.owner() == os.getlogin()
-    except Exception:  # noqa
+    except Exception:  # noqa: S110
         pass
 
     if hasattr(os, "geteuid"):
@@ -174,19 +173,17 @@
     home = get_home_dir()
 
     if sys.platform == "darwin":
-        return os.path.join(home, "Library", "Jupyter")
-    elif os.name == "nt":
+        return str(Path(home, "Library", "Jupyter"))
+    if sys.platform == "win32":
         appdata = os.environ.get("APPDATA", None)
         if appdata:
             return str(Path(appdata, "jupyter").resolve())
-        else:
-            return pjoin(jupyter_config_dir(), "data")
-    else:
-        # Linux, non-OS X Unix, AIX, etc.
-        xdg = env.get("XDG_DATA_HOME", None)
-        if not xdg:
-            xdg = pjoin(home, ".local", "share")
-        return pjoin(xdg, "jupyter")
+        return pjoin(jupyter_config_dir(), "data")
+    # Linux, non-OS X Unix, AIX, etc.
+    xdg = env.get("XDG_DATA_HOME", None)
+    if not xdg:
+        xdg = pjoin(home, ".local", "share")
+    return pjoin(xdg, "jupyter")
 
 
 def jupyter_runtime_dir() -> str:
@@ -222,17 +219,17 @@
         if programdata:
             SYSTEM_JUPYTER_PATH = [pjoin(programdata, "jupyter")]
         else:  # PROGRAMDATA is not defined by default on XP.
-            SYSTEM_JUPYTER_PATH = [os.path.join(sys.prefix, "share", 
"jupyter")]
+            SYSTEM_JUPYTER_PATH = [str(Path(sys.prefix, "share", "jupyter"))]
     else:
         SYSTEM_JUPYTER_PATH = [
             "/usr/local/share/jupyter",
             "/usr/share/jupyter",
         ]
 
-ENV_JUPYTER_PATH: List[str] = [os.path.join(sys.prefix, "share", "jupyter")]
+ENV_JUPYTER_PATH: list[str] = [str(Path(sys.prefix, "share", "jupyter"))]
 
 
-def jupyter_path(*subdirs: str) -> List[str]:
+def jupyter_path(*subdirs: str) -> list[str]:
     """Return a list of directories to search for data files
 
     JUPYTER_PATH environment variable has highest priority.
@@ -254,7 +251,7 @@
     ['~/.local/jupyter/kernels', '/usr/local/share/jupyter/kernels']
     """
 
-    paths: List[str] = []
+    paths: list[str] = []
 
     # highest priority is explicit environment variable
     if os.environ.get("JUPYTER_PATH"):
@@ -269,7 +266,7 @@
         userbase = site.getuserbase() if hasattr(site, "getuserbase") else 
site.USER_BASE
 
         if userbase:
-            userdir = os.path.join(userbase, "share", "jupyter")
+            userdir = str(Path(userbase, "share", "jupyter"))
             if userdir not in user:
                 user.append(userdir)
 
@@ -295,11 +292,11 @@
     SYSTEM_CONFIG_PATH = platformdirs.site_config_dir(
         APPNAME, appauthor=False, multipath=True
     ).split(os.pathsep)
-else:  # noqa: PLR5501
+else:
     if os.name == "nt":
         programdata = os.environ.get("PROGRAMDATA", None)
-        if programdata:  # noqa
-            SYSTEM_CONFIG_PATH = [os.path.join(programdata, "jupyter")]
+        if programdata:  # noqa: SIM108
+            SYSTEM_CONFIG_PATH = [str(Path(programdata, "jupyter"))]
         else:  # PROGRAMDATA is not defined by default on XP.
             SYSTEM_CONFIG_PATH = []
     else:
@@ -307,10 +304,10 @@
             "/usr/local/etc/jupyter",
             "/etc/jupyter",
         ]
-ENV_CONFIG_PATH: List[str] = [os.path.join(sys.prefix, "etc", "jupyter")]
+ENV_CONFIG_PATH: list[str] = [str(Path(sys.prefix, "etc", "jupyter"))]
 
 
-def jupyter_config_path() -> List[str]:
+def jupyter_config_path() -> list[str]:
     """Return the search path for Jupyter config files as a list.
 
     If the JUPYTER_PREFER_ENV_PATH environment variable is set, the
@@ -324,7 +321,7 @@
         # jupyter_config_dir makes a blank config when JUPYTER_NO_CONFIG is 
set.
         return [jupyter_config_dir()]
 
-    paths: List[str] = []
+    paths: list[str] = []
 
     # highest priority is explicit environment variable
     if os.environ.get("JUPYTER_CONFIG_PATH"):
@@ -339,7 +336,7 @@
         userbase = site.getuserbase() if hasattr(site, "getuserbase") else 
site.USER_BASE
 
         if userbase:
-            userdir = os.path.join(userbase, "etc", "jupyter")
+            userdir = str(Path(userbase, "etc", "jupyter"))
             if userdir not in user:
                 user.append(userdir)
 
@@ -384,12 +381,12 @@
         The result of calling stat() on abs_path. If not passed, this function
         will call stat() internally.
     """
-    if os.path.basename(abs_path).startswith("."):
+    if Path(abs_path).name.startswith("."):
         return True
 
     if stat_res is None:
         try:
-            stat_res = os.stat(abs_path)
+            stat_res = Path(abs_path).stat()
         except OSError as e:
             if e.errno == errno.ENOENT:
                 return False
@@ -409,7 +406,6 @@
             "hidden files are not detectable on this system, so no file will 
be marked as hidden.",
             stacklevel=2,
         )
-        pass
 
     return False
 
@@ -430,19 +426,19 @@
         The result of calling stat() on abs_path. If not passed, this function
         will call stat() internally.
     """
-    if os.path.basename(abs_path).startswith("."):
+    if Path(abs_path).name.startswith("."):
         return True
 
     if stat_res is None or stat.S_ISLNK(stat_res.st_mode):
         try:
-            stat_res = os.stat(abs_path)
+            stat_res = Path(abs_path).stat()
         except OSError as e:
             if e.errno == errno.ENOENT:
                 return False
             raise
 
     # check that dirs can be listed
-    if stat.S_ISDIR(stat_res.st_mode):  # type:ignore[misc]  # noqa
+    if stat.S_ISDIR(stat_res.st_mode):  # noqa: SIM102
         # use x-access, not actual listing, in case of slow/large listings
         if not os.access(abs_path, os.X_OK | os.R_OK):
             return True
@@ -492,15 +488,15 @@
     if not abs_root:
         abs_root = abs_path.split(os.sep, 1)[0] + os.sep
     inside_root = abs_path[len(abs_root) :]
-    if any(part.startswith(".") for part in inside_root.split(os.sep)):
+    if any(part.startswith(".") for part in Path(inside_root).parts):
         return True
 
     # check UF_HIDDEN on any location up to root.
     # is_file_hidden() already checked the file, so start from its parent dir
-    path = os.path.dirname(abs_path)
+    path = str(Path(abs_path).parent)
     while path and path.startswith(abs_root) and path != abs_root:
-        if not exists(path):
-            path = os.path.dirname(path)
+        if not Path(path).exists():
+            path = str(Path(path).parent)
             continue
         try:
             # may fail on Windows junctions
@@ -509,7 +505,7 @@
             return True
         if getattr(st, "st_flags", 0) & UF_HIDDEN:
             return True
-        path = os.path.dirname(path)
+        path = str(Path(path).parent)
 
     return False
 
@@ -555,9 +551,10 @@
 
     sd.SetSecurityDescriptorDacl(1, dacl, 0)
     win32security.SetFileSecurity(fname, 
win32security.DACL_SECURITY_INFORMATION, sd)
+    return None
 
 
-def _win32_restrict_file_to_user_ctypes(fname: str) -> None:  # noqa
+def _win32_restrict_file_to_user_ctypes(fname: str) -> None:
     """Secure a windows file to read-only access for the user.
 
     Follows guidance from win32 library creator:
@@ -611,7 +608,7 @@
     )
 
     class ACL(ctypes.Structure):
-        _fields_ = [  # noqa
+        _fields_ = [
             ("AclRevision", wintypes.BYTE),
             ("Sbz1", wintypes.BYTE),
             ("AclSize", wintypes.WORD),
@@ -623,7 +620,7 @@
     PACL = ctypes.POINTER(ACL)
     PSECURITY_DESCRIPTOR = ctypes.POINTER(wintypes.BYTE)
 
-    def _nonzero_success(result: int, func: Any, args: Any) -> Any:
+    def _nonzero_success(result: int, func: Any, args: Any) -> Any:  # noqa: 
ARG001
         if not result:
             raise ctypes.WinError(ctypes.get_last_error())  # 
type:ignore[attr-defined]
         return args
@@ -950,7 +947,7 @@
     # the missing least significant bit on the third octal digit. In addition, 
we also tolerate
     # the sticky bit being set, so the lsb from the fourth octal digit is also 
removed.
     return (
-        stat.S_IMODE(os.stat(fname).st_mode) & 0o6677
+        stat.S_IMODE(Path(fname).stat().st_mode) & 0o6677
     )  # Use 4 octal digits since S_IMODE does the same
 
 
@@ -976,7 +973,7 @@
     encoding = None if binary else "utf-8"
     open_flag = os.O_CREAT | os.O_WRONLY | os.O_TRUNC
     try:
-        os.remove(fname)
+        Path(fname).unlink()
     except OSError:
         # Skip any issues with the file not existing
         pass
@@ -999,7 +996,7 @@
         if os.name != "nt":
             # Enforce that the file got the requested permissions before 
writing
             file_mode = get_file_mode(fname)
-            if file_mode != 0o0600:  # noqa
+            if file_mode != 0o0600:
                 if allow_insecure_writes:
                     issue_insecure_write_warning()
                 else:
@@ -1014,7 +1011,7 @@
 def issue_insecure_write_warning() -> None:
     """Issue an insecure write warning."""
 
-    def format_warning(msg: str, *args: Any, **kwargs: Any) -> str:
+    def format_warning(msg: str, *args: Any, **kwargs: Any) -> str:  # noqa: 
ARG001
         return str(msg) + "\n"
 
     warnings.formatwarning = format_warning  # type:ignore[assignment]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/jupyter_core/troubleshoot.py 
new/jupyter_core-5.5.1/jupyter_core/troubleshoot.py
--- old/jupyter_core-5.5.0/jupyter_core/troubleshoot.py 2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.5.1/jupyter_core/troubleshoot.py 2020-02-02 
01:00:00.000000000 +0100
@@ -3,30 +3,31 @@
 display environment information that is frequently
 used to troubleshoot installations of Jupyter or IPython
 """
+from __future__ import annotations
 
 import os
 import platform
 import subprocess
 import sys
-from typing import Any, Dict, List, Optional, Union
+from typing import Any, Optional, Union
 
 
-def subs(cmd: Union[List[str], str]) -> Optional[str]:
+def subs(cmd: Union[list[str], str]) -> Optional[str]:
     """
     get data from commands that we need to run outside of python
     """
     try:
-        stdout = subprocess.check_output(cmd)  # noqa
+        stdout = subprocess.check_output(cmd)  # noqa: S603
         return stdout.decode("utf-8", "replace").strip()
     except (OSError, subprocess.CalledProcessError):
         return None
 
 
-def get_data() -> Dict[str, Any]:
+def get_data() -> dict[str, Any]:
     """
     returns a dict of various user environment data
     """
-    env: Dict[str, Any] = {}
+    env: dict[str, Any] = {}
     env["path"] = os.environ.get("PATH")
     env["sys_path"] = sys.path
     env["sys_exe"] = sys.executable
@@ -45,7 +46,7 @@
     return env
 
 
-def main() -> None:  # noqa
+def main() -> None:
     """
     print out useful info
     """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/jupyter_core/utils/__init__.py 
new/jupyter_core-5.5.1/jupyter_core/utils/__init__.py
--- old/jupyter_core-5.5.0/jupyter_core/utils/__init__.py       2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.5.1/jupyter_core/utils/__init__.py       2020-02-02 
01:00:00.000000000 +0100
@@ -6,7 +6,6 @@
 import atexit
 import errno
 import inspect
-import os
 import sys
 import threading
 import warnings
@@ -15,7 +14,7 @@
 from typing import Any, Awaitable, Callable, TypeVar, cast
 
 
-def ensure_dir_exists(path: str, mode: int = 0o777) -> None:
+def ensure_dir_exists(path: str | Path, mode: int = 0o777) -> None:
     """Ensure that a directory exists
 
     If it doesn't exist, try to create it, protecting against a race condition
@@ -23,11 +22,11 @@
     The default permissions are determined by the current umask.
     """
     try:
-        os.makedirs(path, mode=mode)
+        Path(path).mkdir(parents=True, mode=mode)
     except OSError as e:
         if e.errno != errno.EEXIST:
             raise
-    if not os.path.isdir(path):
+    if not Path(path).is_dir():
         raise OSError("%r exists but is not a directory" % path)
 
 
@@ -108,7 +107,7 @@
 
     def _runner(self) -> None:
         loop = self.__io_loop
-        assert loop is not None  # noqa
+        assert loop is not None
         try:
             loop.run_forever()
         finally:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/jupyter_core/version.py 
new/jupyter_core-5.5.1/jupyter_core/version.py
--- old/jupyter_core-5.5.0/jupyter_core/version.py      2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.5.1/jupyter_core/version.py      2020-02-02 
01:00:00.000000000 +0100
@@ -1,17 +1,18 @@
 """
 store the current version info of the jupyter_core.
 """
+from __future__ import annotations
+
 import re
-from typing import List
 
 # Version string must appear intact for hatch versioning
-__version__ = "5.5.0"
+__version__ = "5.5.1"
 
 # Build up version_info tuple for backwards compatibility
 pattern = r"(?P<major>\d+).(?P<minor>\d+).(?P<patch>\d+)(?P<rest>.*)"
 match = re.match(pattern, __version__)
-assert match is not None  # noqa
-parts: List[object] = [int(match[part]) for part in ["major", "minor", 
"patch"]]
+assert match is not None
+parts: list[object] = [int(match[part]) for part in ["major", "minor", 
"patch"]]
 if match["rest"]:
     parts.append(match["rest"])
 version_info = tuple(parts)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/pyproject.toml 
new/jupyter_core-5.5.1/pyproject.toml
--- old/jupyter_core-5.5.0/pyproject.toml       2020-02-02 01:00:00.000000000 
+0100
+++ new/jupyter_core-5.5.1/pyproject.toml       2020-02-02 01:00:00.000000000 
+0100
@@ -88,31 +88,24 @@
 nowarn = "test -W default {args}"
 
 [tool.hatch.envs.typing]
-features = ["test"]
-dependencies = ["mypy~=1.6.0", "traitlets>=5.13.0"]
+dependencies = ["pre-commit"]
+detached = true
 [tool.hatch.envs.typing.scripts]
-test = "mypy --install-types --non-interactive {args}"
+test = "pre-commit run --all-files --hook-stage manual mypy"
 
 [tool.hatch.envs.lint]
-dependencies = ["mdformat>0.7", "ruff==0.1.3"]
+dependencies = ["pre-commit"]
 detached = true
 [tool.hatch.envs.lint.scripts]
-style = [
-  "ruff {args:.}",
-  "ruff format {args:.}",
-  "mdformat --check {args:*.md}"
-]
-fmt = [
-  "ruff --fix {args:.}",
-  "ruff format {args:.}",
-  "mdformat {args:*.md}"
+build = [
+  "pre-commit run --all-files ruff",
+  "pre-commit run --all-files ruff-format"
 ]
 
 [tool.mypy]
 files = "jupyter_core"
 python_version = "3.8"
 strict = true
-show_error_codes = true
 enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
 warn_unreachable = true
 
@@ -154,24 +147,42 @@
 ]
 
 [tool.ruff]
-target-version = "py38"
 line-length = 100
 
 [tool.ruff.lint]
-select = [
-  "A", "B", "C", "DTZ", "E", "EM", "F", "FBT", "I", "ICN", "N",
-  "PLC", "PLE", "PLR", "PLW", "Q", "RUF", "S", "SIM", "T", "TID", "UP",
-  "W", "YTT",
+extend-select = [
+  "B",           # flake8-bugbear
+  "I",           # isort
+  "ARG",         # flake8-unused-arguments
+  "C4",          # flake8-comprehensions
+  "EM",          # flake8-errmsg
+  "ICN",         # flake8-import-conventions
+  "G",           # flake8-logging-format
+  "PGH",         # pygrep-hooks
+  "PIE",         # flake8-pie
+  "PL",          # pylint
+  "PT",          # flake8-pytest-style
+  "PTH",         # flake8-use-pathlib
+  "RET",         # flake8-return
+  "RUF",         # Ruff-specific
+  "SIM",         # flake8-simplify
+  "T20",         # flake8-print
+  "UP",          # pyupgrade
+  "YTT",         # flake8-2020
+  "EXE",         # flake8-executable
+  "NPY",         # NumPy specific rules
+  "PD",          # pandas-vet
+  "PYI",         # flake8-pyi
+  "S",           # flake8-bandit
 ]
 ignore = [
-  # Q000 Single quotes found but double quotes preferred
-  "Q000",
-  # FBT001 Boolean positional arg in function definition
-  "FBT001", "FBT002", "FBT003",
-  # E501 Line too long (158 > 100 characters)
-  "E501",
-  # SIM105 Use `contextlib.suppress(...)`
-  "SIM105",
+  "PLR",    # Design related pylint codes
+  "Q000",   # Single quotes found but double quotes preferred
+  "E501",   # Line too long (158 > 100 characters)
+  "UP007",  # Use `X | Y` for type annotations"
+  "SIM105", # Use `contextlib.suppress(...)`
+  "S101",   # Use of assert
+  "RUF012"  # Mutable class attributes should be annotated
 ]
 unfixable = [
   # Don't touch print statements
@@ -179,6 +190,7 @@
   # Don't touch noqa lines
   "RUF100",
 ]
+isort.required-imports = ["from __future__ import annotations"]
 
 [tool.ruff.lint.per-file-ignores]
 # B011 Do not call assert False since python -O removes these calls
@@ -188,11 +200,9 @@
 # T201 `print` found
 # B007 Loop control variable `i` not used within the loop body.
 # N802 Function name `assertIn` should be lowercase
-# S101 Use of `assert` detected
-# S108 Probable insecure usage of temporary file or directory: "/tmp"
 # PLR2004 Magic value used in comparison, consider replacing b'WITNESS A' with 
a constant variable
 # S603 `subprocess` call: check for execution of untrusted input
-"tests/*" = ["B011", "F841", "C408", "E402", "T201", "B007", "N802", "S101", 
"S108", "PLR2004", "S603"]
+"tests/*" = ["B011", "F841", "C408", "E402", "T201", "B007", "N802", "S", 
"PTH", "ARG0"]
 # F821 Undefined name `get_config`
 "tests/**/profile_default/*_config.py" = ["F821"]
 # T201 `print` found
@@ -217,6 +227,3 @@
 [tool.check-wheel-contents]
 toplevel = ["jupyter_core/", "jupyter.py"]
 ignore = ["W002"]
-
-[tool.repo-review]
-ignore = ["PY007", "PP308", "GH102", "PC140"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/scripts/jupyter 
new/jupyter_core-5.5.1/scripts/jupyter
--- old/jupyter_core-5.5.0/scripts/jupyter      2020-02-02 01:00:00.000000000 
+0100
+++ new/jupyter_core-5.5.1/scripts/jupyter      2020-02-02 01:00:00.000000000 
+0100
@@ -1,5 +1,6 @@
 #!/usr/bin/env python
 """Launch the root jupyter command"""
+from __future__ import annotations
 
 from jupyter_core.command import main
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/scripts/jupyter-migrate 
new/jupyter_core-5.5.1/scripts/jupyter-migrate
--- old/jupyter_core-5.5.0/scripts/jupyter-migrate      2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.5.1/scripts/jupyter-migrate      2020-02-02 
01:00:00.000000000 +0100
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 # PYTHON_ARGCOMPLETE_OK
 """Migrate Jupyter config from IPython < 4.0"""
+from __future__ import annotations
 
 from jupyter_core.migrate import main
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jupyter_core-5.5.0/tests/dotipython/profile_default/ipython_config.py 
new/jupyter_core-5.5.1/tests/dotipython/profile_default/ipython_config.py
--- old/jupyter_core-5.5.0/tests/dotipython/profile_default/ipython_config.py   
2020-02-02 01:00:00.000000000 +0100
+++ new/jupyter_core-5.5.1/tests/dotipython/profile_default/ipython_config.py   
2020-02-02 01:00:00.000000000 +0100
@@ -1,4 +1,5 @@
 # Configuration file for ipython.
+from __future__ import annotations
 
 c = get_config()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jupyter_core-5.5.0/tests/dotipython/profile_default/ipython_console_config.py
 
new/jupyter_core-5.5.1/tests/dotipython/profile_default/ipython_console_config.py
--- 
old/jupyter_core-5.5.0/tests/dotipython/profile_default/ipython_console_config.py
   2020-02-02 01:00:00.000000000 +0100
+++ 
new/jupyter_core-5.5.1/tests/dotipython/profile_default/ipython_console_config.py
   2020-02-02 01:00:00.000000000 +0100
@@ -1,4 +1,5 @@
 # Configuration file for ipython-console.
+from __future__ import annotations
 
 c = get_config()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jupyter_core-5.5.0/tests/dotipython/profile_default/ipython_kernel_config.py
 
new/jupyter_core-5.5.1/tests/dotipython/profile_default/ipython_kernel_config.py
--- 
old/jupyter_core-5.5.0/tests/dotipython/profile_default/ipython_kernel_config.py
    2020-02-02 01:00:00.000000000 +0100
+++ 
new/jupyter_core-5.5.1/tests/dotipython/profile_default/ipython_kernel_config.py
    2020-02-02 01:00:00.000000000 +0100
@@ -1,4 +1,5 @@
 # Configuration file for ipython-kernel.
+from __future__ import annotations
 
 c = get_config()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jupyter_core-5.5.0/tests/dotipython/profile_default/ipython_nbconvert_config.py
 
new/jupyter_core-5.5.1/tests/dotipython/profile_default/ipython_nbconvert_config.py
--- 
old/jupyter_core-5.5.0/tests/dotipython/profile_default/ipython_nbconvert_config.py
 2020-02-02 01:00:00.000000000 +0100
+++ 
new/jupyter_core-5.5.1/tests/dotipython/profile_default/ipython_nbconvert_config.py
 2020-02-02 01:00:00.000000000 +0100
@@ -1 +1,3 @@
+from __future__ import annotations
+
 c.NbConvertApp.post_processors = []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jupyter_core-5.5.0/tests/dotipython/profile_default/ipython_notebook_config.py
 
new/jupyter_core-5.5.1/tests/dotipython/profile_default/ipython_notebook_config.py
--- 
old/jupyter_core-5.5.0/tests/dotipython/profile_default/ipython_notebook_config.py
  2020-02-02 01:00:00.000000000 +0100
+++ 
new/jupyter_core-5.5.1/tests/dotipython/profile_default/ipython_notebook_config.py
  2020-02-02 01:00:00.000000000 +0100
@@ -1 +1,3 @@
+from __future__ import annotations
+
 c.NotebookApp.open_browser = False
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jupyter_core-5.5.0/tests/dotipython_empty/profile_default/ipython_config.py 
new/jupyter_core-5.5.1/tests/dotipython_empty/profile_default/ipython_config.py
--- 
old/jupyter_core-5.5.0/tests/dotipython_empty/profile_default/ipython_config.py 
    2020-02-02 01:00:00.000000000 +0100
+++ 
new/jupyter_core-5.5.1/tests/dotipython_empty/profile_default/ipython_config.py 
    2020-02-02 01:00:00.000000000 +0100
@@ -1,4 +1,5 @@
 # Configuration file for ipython.
+from __future__ import annotations
 
 c = get_config()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jupyter_core-5.5.0/tests/dotipython_empty/profile_default/ipython_console_config.py
 
new/jupyter_core-5.5.1/tests/dotipython_empty/profile_default/ipython_console_config.py
--- 
old/jupyter_core-5.5.0/tests/dotipython_empty/profile_default/ipython_console_config.py
     2020-02-02 01:00:00.000000000 +0100
+++ 
new/jupyter_core-5.5.1/tests/dotipython_empty/profile_default/ipython_console_config.py
     2020-02-02 01:00:00.000000000 +0100
@@ -1,4 +1,5 @@
 # Configuration file for ipython-console.
+from __future__ import annotations
 
 c = get_config()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jupyter_core-5.5.0/tests/dotipython_empty/profile_default/ipython_kernel_config.py
 
new/jupyter_core-5.5.1/tests/dotipython_empty/profile_default/ipython_kernel_config.py
--- 
old/jupyter_core-5.5.0/tests/dotipython_empty/profile_default/ipython_kernel_config.py
      2020-02-02 01:00:00.000000000 +0100
+++ 
new/jupyter_core-5.5.1/tests/dotipython_empty/profile_default/ipython_kernel_config.py
      2020-02-02 01:00:00.000000000 +0100
@@ -1,4 +1,5 @@
 # Configuration file for ipython-kernel.
+from __future__ import annotations
 
 c = get_config()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jupyter_core-5.5.0/tests/dotipython_empty/profile_default/ipython_nbconvert_config.py
 
new/jupyter_core-5.5.1/tests/dotipython_empty/profile_default/ipython_nbconvert_config.py
--- 
old/jupyter_core-5.5.0/tests/dotipython_empty/profile_default/ipython_nbconvert_config.py
   2020-02-02 01:00:00.000000000 +0100
+++ 
new/jupyter_core-5.5.1/tests/dotipython_empty/profile_default/ipython_nbconvert_config.py
   2020-02-02 01:00:00.000000000 +0100
@@ -1,4 +1,5 @@
 # Configuration file for ipython-nbconvert.
+from __future__ import annotations
 
 c = get_config()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jupyter_core-5.5.0/tests/dotipython_empty/profile_default/ipython_notebook_config.py
 
new/jupyter_core-5.5.1/tests/dotipython_empty/profile_default/ipython_notebook_config.py
--- 
old/jupyter_core-5.5.0/tests/dotipython_empty/profile_default/ipython_notebook_config.py
    2020-02-02 01:00:00.000000000 +0100
+++ 
new/jupyter_core-5.5.1/tests/dotipython_empty/profile_default/ipython_notebook_config.py
    2020-02-02 01:00:00.000000000 +0100
@@ -1,4 +1,5 @@
 # Configuration file for ipython-notebook.
+from __future__ import annotations
 
 c = get_config()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/tests/mocking.py 
new/jupyter_core-5.5.1/tests/mocking.py
--- old/jupyter_core-5.5.0/tests/mocking.py     2020-02-02 01:00:00.000000000 
+0100
+++ new/jupyter_core-5.5.1/tests/mocking.py     2020-02-02 01:00:00.000000000 
+0100
@@ -2,6 +2,7 @@
 
 # Copyright (c) Jupyter Development Team.
 # Distributed under the terms of the Modified BSD License.
+from __future__ import annotations
 
 import os
 import sys
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/tests/test_application.py 
new/jupyter_core-5.5.1/tests/test_application.py
--- old/jupyter_core-5.5.0/tests/test_application.py    2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.5.1/tests/test_application.py    2020-02-02 
01:00:00.000000000 +0100
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
 import os
 import shutil
 from tempfile import mkdtemp
@@ -107,7 +109,7 @@
     with open(pjoin(config_dir, "dummy_app_config.py"), "w", encoding="utf-8") 
as f:
         f.write('c.DummyApp.m = "a\n')  # Syntax error
 
-    with pytest.raises(SyntaxError):
+    with pytest.raises(SyntaxError):  # noqa: PT012
         app = DummyApp(config_dir=config_dir)
         app.raise_config_file_errors = True
         app.initialize([])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/tests/test_command.py 
new/jupyter_core-5.5.1/tests/test_command.py
--- old/jupyter_core-5.5.0/tests/test_command.py        2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.5.1/tests/test_command.py        2020-02-02 
01:00:00.000000000 +0100
@@ -1,4 +1,5 @@
 """Test the Jupyter command-line"""
+from __future__ import annotations
 
 import json
 import os
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/tests/test_migrate.py 
new/jupyter_core-5.5.1/tests/test_migrate.py
--- old/jupyter_core-5.5.0/tests/test_migrate.py        2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.5.1/tests/test_migrate.py        2020-02-02 
01:00:00.000000000 +0100
@@ -1,6 +1,7 @@
 # Copyright (c) Jupyter Development Team.
 # Distributed under the terms of the Modified BSD License.
 """Test config file migration"""
+from __future__ import annotations
 
 import os
 import re
@@ -28,15 +29,15 @@
 dotipython_empty = pjoin(here, "dotipython_empty")
 
 
-@pytest.fixture
+@pytest.fixture()
 def td(request):
     """Fixture for a temporary directory"""
     td = mkdtemp("μnïcø∂e")
-    request.addfinalizer(lambda: shutil.rmtree(td))
-    return td
+    yield td
+    shutil.rmtree(td)
 
 
-@pytest.fixture
+@pytest.fixture()
 def env(request):
     """Fixture for a full testing environment"""
     td = mkdtemp()
@@ -51,14 +52,10 @@
     env_patch = patch.dict(os.environ, env)
     env_patch.start()
 
-    def fin():
-        """Cleanup test env"""
-        env_patch.stop()
-        shutil.rmtree(td, ignore_errors=os.name == "nt")
+    yield env
 
-    request.addfinalizer(fin)
-
-    return env
+    env_patch.stop()
+    shutil.rmtree(td, ignore_errors=os.name == "nt")
 
 
 def touch(path, content=""):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/tests/test_paths.py 
new/jupyter_core-5.5.1/tests/test_paths.py
--- old/jupyter_core-5.5.0/tests/test_paths.py  2020-02-02 01:00:00.000000000 
+0100
+++ new/jupyter_core-5.5.1/tests/test_paths.py  2020-02-02 01:00:00.000000000 
+0100
@@ -2,6 +2,7 @@
 
 # Copyright (c) Jupyter Development Team.
 # Distributed under the terms of the Modified BSD License.
+from __future__ import annotations
 
 import os
 import re
@@ -468,13 +469,11 @@
     reason="only run on windows/cpython or pypy >= 7.3.6: 
https://foss.heptapod.net/pypy/pypy/-/issues/3469";,
 )
 def test_is_hidden_win32_cpython():
-    import ctypes  # noqa
-
     with tempfile.TemporaryDirectory() as root:
         subdir1 = os.path.join(root, "subdir")
         os.makedirs(subdir1)
         assert not is_hidden(subdir1, root)
-        subprocess.check_call(["attrib", "+h", subdir1])  # noqa
+        subprocess.check_call(["attrib", "+h", subdir1])
         assert is_hidden(subdir1, root)
         assert is_file_hidden(subdir1)
 
@@ -488,13 +487,13 @@
     reason="only run on windows/pypy < 7.3.6: 
https://foss.heptapod.net/pypy/pypy/-/issues/3469";,
 )
 def test_is_hidden_win32_pypy():
-    import ctypes  # noqa
+    import ctypes  # noqa: F401
 
     with tempfile.TemporaryDirectory() as root:
         subdir1 = os.path.join(root, "subdir")
         os.makedirs(subdir1)
         assert not is_hidden(subdir1, root)
-        subprocess.check_call(["attrib", "+h", subdir1])  # noqa
+        subprocess.check_call(["attrib", "+h", subdir1])
 
         with warnings.catch_warnings(record=True) as w:
             # Cause all warnings to always be triggered.
@@ -527,12 +526,12 @@
     def fetch_win32_permissions(filename):
         """Extracts file permissions on windows using icacls"""
         role_permissions = {}
-        proc = os.popen("icacls %s" % filename)  # noqa
+        proc = os.popen("icacls %s" % filename)
         lines = proc.read().splitlines()
         proc.close()
         for index, line in enumerate(lines):
             if index == 0:
-                line = line.split(filename)[-1].strip().lower()  # noqa
+                line = line.split(filename)[-1].strip().lower()  # noqa: 
PLW2901
             match = re.match(r"\s*([^:]+):\(([^\)]*)\)", line)
             if match:
                 usergroup, permissions = match.groups()
@@ -575,16 +574,16 @@
         with secure_write(fname) as f:
             f.write("test 1")
         mode = os.stat(fname).st_mode
-        assert 0o0600 == (stat.S_IMODE(mode) & 0o7677)  # noqa # tolerate 
owner-execute bit
+        assert (stat.S_IMODE(mode) & 0o7677) == 0o0600  # tolerate 
owner-execute bit
         with open(fname, encoding="utf-8") as f:
             assert f.read() == "test 1"
 
         # Try changing file permissions ahead of time
-        os.chmod(fname, 0o755)  # noqa
+        os.chmod(fname, 0o755)
         with secure_write(fname) as f:
             f.write("test 2")
         mode = os.stat(fname).st_mode
-        assert 0o0600 == (stat.S_IMODE(mode) & 0o7677)  # noqa # tolerate 
owner-execute bit
+        assert (stat.S_IMODE(mode) & 0o7677) == 0o0600  # tolerate 
owner-execute bit
         with open(fname, encoding="utf-8") as f:
             assert f.read() == "test 2"
     finally:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/tests/test_troubleshoot.py 
new/jupyter_core-5.5.1/tests/test_troubleshoot.py
--- old/jupyter_core-5.5.0/tests/test_troubleshoot.py   2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.5.1/tests/test_troubleshoot.py   2020-02-02 
01:00:00.000000000 +0100
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
 from jupyter_core.troubleshoot import main
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.5.0/tests/test_utils.py 
new/jupyter_core-5.5.1/tests/test_utils.py
--- old/jupyter_core-5.5.0/tests/test_utils.py  2020-02-02 01:00:00.000000000 
+0100
+++ new/jupyter_core-5.5.1/tests/test_utils.py  2020-02-02 01:00:00.000000000 
+0100
@@ -2,6 +2,7 @@
 
 # Copyright (c) Jupyter Development Team.
 # Distributed under the terms of the Modified BSD License.
+from __future__ import annotations
 
 import asyncio
 import os
@@ -41,9 +42,11 @@
     foo_sync = run_sync(foo)
     assert foo_sync() == 1
     assert foo_sync() == 1
+    asyncio.get_event_loop().close()
 
     asyncio.set_event_loop(None)
     assert foo_sync() == 1
+    asyncio.get_event_loop().close()
 
     asyncio.run(foo())
 

++++++ use_rpms_paths.patch ++++++
--- /var/tmp/diff_new_pack.oxcSN8/_old  2023-12-25 19:05:47.382553882 +0100
+++ /var/tmp/diff_new_pack.oxcSN8/_new  2023-12-25 19:05:47.382553882 +0100
@@ -7,13 +7,13 @@
 
 ---
 
-Index: jupyter_core-5.3.2/jupyter_core/paths.py
+Index: jupyter_core-5.5.1/jupyter_core/paths.py
 ===================================================================
---- jupyter_core-5.3.2.orig/jupyter_core/paths.py
-+++ jupyter_core-5.3.2/jupyter_core/paths.py
-@@ -219,10 +219,7 @@ else:
+--- jupyter_core-5.5.1.orig/jupyter_core/paths.py
++++ jupyter_core-5.5.1/jupyter_core/paths.py
+@@ -221,10 +221,7 @@ else:
          else:  # PROGRAMDATA is not defined by default on XP.
-             SYSTEM_JUPYTER_PATH = [os.path.join(sys.prefix, "share", 
"jupyter")]
+             SYSTEM_JUPYTER_PATH = [str(Path(sys.prefix, "share", "jupyter"))]
      else:
 -        SYSTEM_JUPYTER_PATH = [
 -            "/usr/local/share/jupyter",
@@ -21,9 +21,9 @@
 -        ]
 +        SYSTEM_JUPYTER_PATH = [ "@_datadir_jupyter_@" ]
  
- ENV_JUPYTER_PATH: List[str] = [os.path.join(sys.prefix, "share", "jupyter")]
+ ENV_JUPYTER_PATH: list[str] = [str(Path(sys.prefix, "share", "jupyter"))]
  
-@@ -243,10 +240,10 @@ def jupyter_path(*subdirs: str) -> List[
+@@ -245,10 +242,10 @@ def jupyter_path(*subdirs: str) -> list[
  
      Examples:
  
@@ -37,17 +37,15 @@
 +    ['~/.local/share/jupyter/kernels', '@_datadir_jupyter_@/kernels']
      """
  
-     paths: List[str] = []
-@@ -298,10 +295,7 @@ else:  # noqa: PLR5501
-         else:  # PROGRAMDATA is not defined by default on XP.
+     paths: list[str] = []
+@@ -301,8 +298,7 @@ else:
              SYSTEM_CONFIG_PATH = []
      else:
--        SYSTEM_CONFIG_PATH = [
+         SYSTEM_CONFIG_PATH = [
 -            "/usr/local/etc/jupyter",
 -            "/etc/jupyter",
--        ]
-+        SYSTEM_CONFIG_PATH = [ "@_distconfdir_jupyter_@" ]
- ENV_CONFIG_PATH: List[str] = [os.path.join(sys.prefix, "etc", "jupyter")]
- 
++            "@_distconfdir_jupyter_@"
+         ]
+ ENV_CONFIG_PATH: list[str] = [str(Path(sys.prefix, "etc", "jupyter"))]
  
 

Reply via email to