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 2026-03-17 19:02:08
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-jupyter-core (Old)
 and      /work/SRC/openSUSE:Factory/.python-jupyter-core.new.8177 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-jupyter-core"

Tue Mar 17 19:02:08 2026 rev:29 rq:1339150 version:5.9.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-jupyter-core/python-jupyter-core.changes  
2025-06-23 14:56:29.311863102 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-jupyter-core.new.8177/python-jupyter-core.changes
        2026-03-17 19:02:16.879170177 +0100
@@ -1,0 +2,12 @@
+Sat Dec 13 13:56:04 UTC 2025 - Dirk Müller <[email protected]>
+
+- update to 5.9.1:
+  * nicer traceback in missing loop case outside except in
+    run_sync #437 (@AThePeanut4)
+  * Fix missing `f` specifier in f-string used to print config
+    file path #433 (@krassowski)
+  * validate inputs to is_hidden #429 (@minrk)
+  * [Docs] Use extension:filetype mapping in sphinx configuration
+    #443 (@Carreau)
+
+-------------------------------------------------------------------

Old:
----
  jupyter_core-5.8.1.tar.gz

New:
----
  jupyter_core-5.9.1.tar.gz

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

Other differences:
------------------
++++++ python-jupyter-core.spec ++++++
--- /var/tmp/diff_new_pack.EHRars/_old  2026-03-17 19:02:17.459193963 +0100
+++ /var/tmp/diff_new_pack.EHRars/_new  2026-03-17 19:02:17.463194127 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-jupyter-core
 #
-# Copyright (c) 2025 SUSE LLC
+# Copyright (c) 2025 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -32,7 +32,7 @@
 %endif
 %{?sle15_python_module_pythons}
 Name:           python-jupyter-core%{psuffix}
-Version:        5.8.1
+Version:        5.9.1
 Release:        0
 Summary:        Base package on which Jupyter projects rely
 License:        BSD-3-Clause

++++++ jupyter_core-5.8.1.tar.gz -> jupyter_core-5.9.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jupyter_core-5.8.1/.github/workflows/codeql-analysis.yml 
new/jupyter_core-5.9.1/.github/workflows/codeql-analysis.yml
--- old/jupyter_core-5.8.1/.github/workflows/codeql-analysis.yml        
2020-02-02 01:00:00.000000000 +0100
+++ new/jupyter_core-5.9.1/.github/workflows/codeql-analysis.yml        
2020-02-02 01:00:00.000000000 +0100
@@ -40,11 +40,11 @@
 
     steps:
       - name: Checkout repository
-        uses: actions/checkout@v4
+        uses: actions/checkout@v5
 
       # Initializes the CodeQL tools for scanning.
       - name: Initialize CodeQL
-        uses: github/codeql-action/init@v3
+        uses: github/codeql-action/init@v4
         with:
           languages: ${{ matrix.language }}
           # If you wish to specify custom queries, you can do so here or in a 
config file.
@@ -56,7 +56,7 @@
       # Autobuild attempts to build any compiled languages  (C/C++, C#, or 
Java).
       # If this step fails, then you should remove it and run the build 
manually (see below)
       - name: Autobuild
-        uses: github/codeql-action/autobuild@v3
+        uses: github/codeql-action/autobuild@v4
 
       # ℹ️ Command-line programs to run using the OS shell.
       # 📚 https://git.io/JvXDl
@@ -70,4 +70,4 @@
       #   make release
 
       - name: Perform CodeQL Analysis
-        uses: github/codeql-action/analyze@v3
+        uses: github/codeql-action/analyze@v4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.8.1/.github/workflows/downstream.yml 
new/jupyter_core-5.9.1/.github/workflows/downstream.yml
--- old/jupyter_core-5.8.1/.github/workflows/downstream.yml     2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.9.1/.github/workflows/downstream.yml     2020-02-02 
01:00:00.000000000 +0100
@@ -14,7 +14,7 @@
     runs-on: ubuntu-latest
     timeout-minutes: 15
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
       - uses: jupyterlab/maintainer-tools/.github/actions/downstream-test@v1
         with:
@@ -24,7 +24,7 @@
     runs-on: ubuntu-latest
     timeout-minutes: 15
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
       - uses: jupyterlab/maintainer-tools/.github/actions/downstream-test@v1
         with:
@@ -35,7 +35,7 @@
     runs-on: ubuntu-latest
     timeout-minutes: 15
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
       - uses: jupyterlab/maintainer-tools/.github/actions/downstream-test@v1
         with:
@@ -46,7 +46,7 @@
     runs-on: ubuntu-latest
     timeout-minutes: 15
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
       - uses: jupyterlab/maintainer-tools/.github/actions/downstream-test@v1
         with:
@@ -56,7 +56,7 @@
     runs-on: ubuntu-latest
     steps:
       - name: Checkout
-        uses: actions/checkout@v4
+        uses: actions/checkout@v5
 
       - name: Base Setup
         uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
@@ -65,12 +65,13 @@
         uses: jupyterlab/maintainer-tools/.github/actions/downstream-test@v1
         with:
           package_name: jupyter_client
+          package_spec: "anyio .[test]"
 
   pytest_jupyter:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout
-        uses: actions/checkout@v4
+        uses: actions/checkout@v5
 
       - name: Base Setup
         uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.8.1/.github/workflows/test.yml 
new/jupyter_core-5.9.1/.github/workflows/test.yml
--- old/jupyter_core-5.8.1/.github/workflows/test.yml   2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.9.1/.github/workflows/test.yml   2020-02-02 
01:00:00.000000000 +0100
@@ -28,19 +28,19 @@
       fail-fast: false
       matrix:
         os: [ubuntu-latest, windows-latest, macos-latest]
-        python-version: ["3.8", "3.12", "3.13"]
+        python-version: ["3.12", "3.13", "3.14", "3.14t"]
         include:
           - os: windows-latest
-            python-version: "3.9"
+            python-version: "3.10"
           - os: ubuntu-latest
             python-version: "3.11"
           - os: ubuntu-latest
-            python-version: "pypy-3.9"
+            python-version: "pypy-3.10"
           - os: macos-latest
             python-version: "3.10"
     steps:
-      - uses: actions/checkout@v4
-      - uses: actions/setup-python@v5
+      - uses: actions/checkout@v5
+      - uses: actions/setup-python@v6
         with:
           python-version: ${{ matrix.python-version }}
           cache: pip
@@ -70,7 +70,7 @@
     needs:
       - build
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - uses: jupyterlab/maintainer-tools/.github/actions/report-coverage@v1
 
   test_minimum_versions:
@@ -78,32 +78,33 @@
     timeout-minutes: 20
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
         with:
           dependency_type: minimum
+          python_version: "3.10"
       - name: Run the unit tests
         run: |
-          hatch run test:nowarn || hatch run test:nowarn --lf
+          hatch run test:test
 
   test_prereleases:
     name: Test Prereleases
     runs-on: ubuntu-latest
     timeout-minutes: 20
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
         with:
           dependency_type: pre
       - name: Run the tests
         run: |
-          hatch run test:nowarn || hatch run test:nowarn --lf
+          hatch run test:test
 
   test_docs:
     name: Test Docs
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
       - name: Build API docs
         run: |
@@ -120,7 +121,7 @@
     name: Test Lint
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
       - name: Run Linters
         run: |
@@ -135,7 +136,7 @@
     runs-on: ubuntu-latest
     timeout-minutes: 10
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
       - uses: jupyterlab/maintainer-tools/.github/actions/make-sdist@v1
 
@@ -152,7 +153,7 @@
     runs-on: ubuntu-latest
     steps:
       - name: Checkout
-        uses: actions/checkout@v4
+        uses: actions/checkout@v5
       - name: Base Setup
         uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
       - name: Install Dependencies
@@ -168,7 +169,7 @@
     runs-on: ubuntu-latest
     timeout-minutes: 15
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
       - uses: jupyterlab/maintainer-tools/.github/actions/check-links@v1
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.8.1/.pre-commit-config.yaml 
new/jupyter_core-5.9.1/.pre-commit-config.yaml
--- old/jupyter_core-5.8.1/.pre-commit-config.yaml      2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.9.1/.pre-commit-config.yaml      2020-02-02 
01:00:00.000000000 +0100
@@ -4,7 +4,7 @@
 
 repos:
   - repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v5.0.0
+    rev: v6.0.0
     hooks:
       - id: check-case-conflict
       - id: check-ast
@@ -21,11 +21,11 @@
       - id: trailing-whitespace
 
   - repo: https://github.com/python-jsonschema/check-jsonschema
-    rev: 0.33.0
+    rev: 0.34.1
     hooks:
       - id: check-github-workflows
 
-  - repo: https://github.com/executablebooks/mdformat
+  - repo: https://github.com/hukkin/mdformat
     rev: 0.7.22
     hooks:
       - id: mdformat
@@ -39,13 +39,13 @@
         types_or: [yaml, html, json]
 
   - repo: https://github.com/adamchainz/blacken-docs
-    rev: "1.19.1"
+    rev: "1.20.0"
     hooks:
       - id: blacken-docs
         additional_dependencies: [black==23.7.0]
 
   - repo: https://github.com/pre-commit/mirrors-mypy
-    rev: "v1.15.0"
+    rev: "v1.18.2"
     hooks:
       - id: mypy
         files: jupyter_core
@@ -67,16 +67,16 @@
       - id: rst-inline-touching-normal
 
   - repo: https://github.com/astral-sh/ruff-pre-commit
-    rev: v0.11.11
+    rev: v0.14.0
     hooks:
-      - id: ruff
+      - id: ruff-check
         types_or: [python, jupyter]
         args: ["--fix", "--show-fixes"]
       - id: ruff-format
         types_or: [python, jupyter]
 
   - repo: https://github.com/scientific-python/cookie
-    rev: "2025.05.02"
+    rev: "2025.10.01"
     hooks:
       - id: sp-repo-review
         additional_dependencies: ["repo-review[cli]"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.8.1/CHANGELOG.md 
new/jupyter_core-5.9.1/CHANGELOG.md
--- old/jupyter_core-5.8.1/CHANGELOG.md 2020-02-02 01:00:00.000000000 +0100
+++ new/jupyter_core-5.9.1/CHANGELOG.md 2020-02-02 01:00:00.000000000 +0100
@@ -4,12 +4,50 @@
 
 <!-- START SILENT CHANGELOG ENTRY -->
 
-## 5.8.1
+## 5.9.1
 
 <!-- END SILENT CHANGELOG ENTRY -->
 
 <!-- <END NEW CHANGELOG ENTRY> -->
 
+## 5.9.0
+
+([Full 
Changelog](https://github.com/jupyter/jupyter_core/compare/v5.8.1...735131c141102c376539303564f5d305dc666333))
+
+### Enhancements made
+
+- nicer traceback in missing loop case outside except in run_sync 
[#437](https://github.com/jupyter/jupyter_core/pull/437) 
([@AThePeanut4](https://github.com/AThePeanut4))
+
+### Bugs fixed
+
+- Fix missing `f` specifier in f-string used to print config file path 
[#433](https://github.com/jupyter/jupyter_core/pull/433) 
([@krassowski](https://github.com/krassowski))
+- validate inputs to is_hidden 
[#429](https://github.com/jupyter/jupyter_core/pull/429) 
([@minrk](https://github.com/minrk))
+
+### Maintenance and upkeep improvements
+
+- try to fix some downstream tests 
[#448](https://github.com/jupyter/jupyter_core/pull/448) 
([@Carreau](https://github.com/Carreau))
+- remove deprecation warning, platformdirs won't become default 
[#447](https://github.com/jupyter/jupyter_core/pull/447) 
([@minrk](https://github.com/minrk))
+- Bump github/codeql-action from 3 to 4 in the actions group 
[#446](https://github.com/jupyter/jupyter_core/pull/446) 
([@dependabot](https://github.com/dependabot))
+- require python 3.10, start to test on 3.14 and 3.14-free-threaded 
[#445](https://github.com/jupyter/jupyter_core/pull/445) 
([@Carreau](https://github.com/Carreau))
+- remove pywin32 dependency so free-threading can fly (like pypy) 
[#441](https://github.com/jupyter/jupyter_core/pull/441) 
([@stonebig](https://github.com/stonebig))
+- Bump the actions group across 1 directory with 2 updates 
[#440](https://github.com/jupyter/jupyter_core/pull/440) 
([@dependabot](https://github.com/dependabot))
+
+### Documentation improvements
+
+- [Docs] Use extension:filetype mapping in sphinx configuration 
[#443](https://github.com/jupyter/jupyter_core/pull/443) 
([@Carreau](https://github.com/Carreau))
+
+### Contributors to this release
+
+([GitHub contributors page for this 
release](https://github.com/jupyter/jupyter_core/graphs/contributors?from=2025-05-27&to=2025-10-16&type=c))
+
+[@AThePeanut4](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_core+involves%3AAThePeanut4+updated%3A2025-05-27..2025-10-16&type=Issues)
 | 
[@Carreau](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_core+involves%3ACarreau+updated%3A2025-05-27..2025-10-16&type=Issues)
 | 
[@dependabot](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_core+involves%3Adependabot+updated%3A2025-05-27..2025-10-16&type=Issues)
 | 
[@krassowski](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_core+involves%3Akrassowski+updated%3A2025-05-27..2025-10-16&type=Issues)
 | 
[@minrk](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_core+involves%3Aminrk+updated%3A2025-05-27..2025-10-16&type=Issues)
 | 
[@nikimagic](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_core+involves%3Anikimagic+updated%3A2025-05-27..2025-10-16&type=Issues)
 | 
[@stonebig](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_core+involves%3Astonebig+updated%3A2025-05-27..2025-10-16&type=Issues)
+
+<!-- START SILENT CHANGELOG ENTRY -->
+
+## 5.8.1
+
+<!-- END SILENT CHANGELOG ENTRY -->
+
 <!-- START SILENT CHANGELOG ENTRY -->
 
 ## 5.8.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.8.1/PKG-INFO 
new/jupyter_core-5.9.1/PKG-INFO
--- old/jupyter_core-5.8.1/PKG-INFO     2020-02-02 01:00:00.000000000 +0100
+++ new/jupyter_core-5.9.1/PKG-INFO     2020-02-02 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: jupyter_core
-Version: 5.8.1
+Version: 5.9.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/
@@ -15,9 +15,8 @@
 Classifier: Intended Audience :: System Administrators
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 3
-Requires-Python: >=3.8
+Requires-Python: >=3.10
 Requires-Dist: platformdirs>=2.5
-Requires-Dist: pywin32>=300; sys_platform == 'win32' and 
platform_python_implementation != 'PyPy'
 Requires-Dist: traitlets>=5.3
 Provides-Extra: docs
 Requires-Dist: intersphinx-registry; extra == 'docs'
@@ -34,4 +33,4 @@
 Requires-Dist: pytest<9; extra == 'test'
 Description-Content-Type: text/plain
 
-There is no reason to install this package on its own.
\ No newline at end of file
+Jupyter core package. A base package on which Jupyter projects rely.
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.8.1/docs/conf.py 
new/jupyter_core-5.9.1/docs/conf.py
--- old/jupyter_core-5.8.1/docs/conf.py 2020-02-02 01:00:00.000000000 +0100
+++ new/jupyter_core-5.9.1/docs/conf.py 2020-02-02 01:00:00.000000000 +0100
@@ -51,7 +51,7 @@
 # The suffix(es) of source filenames.
 # You can specify multiple suffix as a list of string:
 # source_suffix = ['.rst', '.md']
-source_suffix = ".rst"
+source_suffix = {".rst": "restructuredtext"}
 
 # The encoding of source files.
 # source_encoding = 'utf-8-sig'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.8.1/jupyter_core/application.py 
new/jupyter_core-5.9.1/jupyter_core/application.py
--- old/jupyter_core-5.8.1/jupyter_core/application.py  2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.9.1/jupyter_core/application.py  2020-02-02 
01:00:00.000000000 +0100
@@ -158,7 +158,7 @@
                 return
 
         config_text = self.generate_config_file()
-        print("Writing default config to: {config_file!r}")
+        print(f"Writing default config to: {config_file!r}")
         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)
@@ -177,7 +177,7 @@
             f_marker.close()
             return  # so we must have already migrated -> bail out
 
-        from .migrate import get_ipython_dir, migrate
+        from .migrate import get_ipython_dir, migrate  # noqa: PLC0415
 
         # No IPython dir, nothing to migrate
         if not Path(get_ipython_dir()).exists():
@@ -264,7 +264,7 @@
     def start(self) -> None:
         """Start the whole thing"""
         if self.subcommand:
-            os.execv(self.subcommand, [self.subcommand] + self.argv[1:])  # 
noqa: S606
+            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.8.1/jupyter_core/command.py 
new/jupyter_core-5.9.1/jupyter_core/command.py
--- old/jupyter_core-5.8.1/jupyter_core/command.py      2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.9.1/jupyter_core/command.py      2020-02-02 
01:00:00.000000000 +0100
@@ -43,7 +43,7 @@
     def argcomplete(self) -> None:
         """Trigger auto-completion, if enabled"""
         try:
-            import argcomplete
+            import argcomplete  # noqa: PLC0415
 
             argcomplete.autocomplete(self)
         except ImportError:
@@ -123,10 +123,10 @@
         if cmd_path is None:
             msg = f"{cmd!r} not found"
             raise OSError(msg, errno.ENOENT)
-        p = Popen([cmd_path] + argv[1:])  # noqa: S603
+        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
+        import signal  # noqa: PLC0415
 
         signal.signal(signal.SIGINT, signal.SIG_IGN)
         p.wait()
@@ -203,7 +203,7 @@
     try:
         # traitlets >= 5.8 provides some argcomplete support,
         # use helper methods to jump to argcomplete
-        from traitlets.config.argcomplete_config import (
+        from traitlets.config.argcomplete_config import (  # noqa: PLC0415
             get_argcomplete_cwords,
             increment_argcomplete_index,
         )
@@ -237,7 +237,7 @@
         # Avoids argparse gobbling up args passed to subcommand, such as `-h`.
         subcommand = argv[1]
     else:
-        args, opts = parser.parse_known_args()
+        args, _opts = parser.parse_known_args()
         subcommand = args.subcommand
         if args.version:
             print("Selected Jupyter core packages...")
@@ -399,7 +399,7 @@
         sys.exit(str(e))
 
     try:
-        _execvp(command, [command] + argv[2:])
+        _execvp(command, [command, *argv[2:]])
     except OSError as e:
         sys.exit(f"Error executing Jupyter command {subcommand!r}: {e}")
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.8.1/jupyter_core/paths.py 
new/jupyter_core-5.9.1/jupyter_core/paths.py
--- old/jupyter_core-5.8.1/jupyter_core/paths.py        2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.9.1/jupyter_core/paths.py        2020-02-02 
01:00:00.000000000 +0100
@@ -15,14 +15,13 @@
 import sys
 import tempfile
 import warnings
+from collections.abc import Iterator
 from contextlib import contextmanager
 from pathlib import Path
-from typing import Any, Iterator, Literal, Optional, overload
+from typing import Any, overload
 
 import platformdirs
 
-from .utils import deprecation
-
 pjoin = os.path.join
 
 # Capitalize Jupyter in paths only on Windows and MacOS (when not in Homebrew)
@@ -43,10 +42,10 @@
 
 
 @overload
-def envset(name: str, default: Literal[None]) -> Optional[bool]: ...
+def envset(name: str, default: None) -> bool | None: ...
 
 
-def envset(name: str, default: Optional[bool] = False) -> Optional[bool]:
+def envset(name: str, default: bool | None = False) -> bool | None:
     """Return the boolean value of a given environment variable.
 
     An environment variable is considered set if it is assigned to a value
@@ -63,8 +62,7 @@
 def use_platform_dirs() -> bool:
     """Determine if platformdirs should be used for system-specific paths.
 
-    We plan for this to default to False in jupyter_core version 5 and to True
-    in jupyter_core version 6.
+    The default is False.
     """
     return envset("JUPYTER_PLATFORM_DIRS", False)
 
@@ -182,12 +180,14 @@
 
     if sys.platform == "darwin":
         return str(Path(home, "Library", "Jupyter"))
+    # Bug in mypy which thinks it's unreachable: 
https://github.com/python/mypy/issues/10773
     if sys.platform == "win32":
         appdata = os.environ.get("APPDATA", None)
         if appdata:
             return str(Path(appdata, "jupyter").resolve())
         return pjoin(jupyter_config_dir(), "data")
     # Linux, non-OS X Unix, AIX, etc.
+    # Bug in mypy which thinks it's unreachable: 
https://github.com/python/mypy/issues/10773
     xdg = env.get("XDG_DATA_HOME", None)
     if not xdg:
         xdg = pjoin(home, ".local", "share")
@@ -226,14 +226,8 @@
         SYSTEM_JUPYTER_PATH = platformdirs.site_data_dir(
             APPNAME, appauthor=False, multipath=True
         ).split(os.pathsep)
-else:
-    deprecation(
-        "Jupyter is migrating its paths to use standard platformdirs\n"
-        "given by the platformdirs library.  To remove this warning and\n"
-        "see the appropriate new directories, set the environment variable\n"
-        "`JUPYTER_PLATFORM_DIRS=1` and then run `jupyter --paths`.\n"
-        "The use of platformdirs will be the default in `jupyter_core` v6"
-    )
+else:  # noqa: PLR5501
+    # default dirs
     if os.name == "nt":
         # PROGRAMDATA is not defined by default on XP, and not safe by default
         if _win_programdata:
@@ -303,7 +297,7 @@
     if site.ENABLE_USER_SITE:
         # Check if site.getuserbase() exists to be compatible with virtualenv,
         # which often does not have this method.
-        userbase: Optional[str]
+        userbase: str | None
         userbase = site.getuserbase() if hasattr(site, "getuserbase") else 
site.USER_BASE
 
         if userbase:
@@ -400,7 +394,7 @@
     # Next is environment or user, depending on the JUPYTER_PREFER_ENV_PATH 
flag
     user = [jupyter_config_dir()]
     if site.ENABLE_USER_SITE:
-        userbase: Optional[str]
+        userbase: str | None
         # Check if site.getuserbase() exists to be compatible with virtualenv,
         # which often does not have this method.
         userbase = site.getuserbase() if hasattr(site, "getuserbase") else 
site.USER_BASE
@@ -442,7 +436,7 @@
     return True
 
 
-def is_file_hidden_win(abs_path: str, stat_res: Optional[Any] = None) -> bool:
+def is_file_hidden_win(abs_path: str | Path, stat_res: Any | None = None) -> 
bool:
     """Is a file hidden?
 
     This only checks the file itself; it should be called in combination with
@@ -458,7 +452,8 @@
         The result of calling stat() on abs_path. If not passed, this function
         will call stat() internally.
     """
-    if Path(abs_path).name.startswith("."):
+    abs_path = Path(abs_path)
+    if abs_path.name.startswith("."):
         return True
 
     if stat_res is None:
@@ -487,7 +482,7 @@
     return False
 
 
-def is_file_hidden_posix(abs_path: str, stat_res: Optional[Any] = None) -> 
bool:
+def is_file_hidden_posix(abs_path: str | Path, stat_res: Any | None = None) -> 
bool:
     """Is a file hidden?
 
     This only checks the file itself; it should be called in combination with
@@ -503,12 +498,13 @@
         The result of calling stat() on abs_path. If not passed, this function
         will call stat() internally.
     """
-    if Path(abs_path).name.startswith("."):
+    abs_path = Path(abs_path)
+    if abs_path.name.startswith("."):
         return True
 
     if stat_res is None or stat.S_ISLNK(stat_res.st_mode):
         try:
-            stat_res = Path(abs_path).stat()
+            stat_res = abs_path.stat()
         except OSError as e:
             if e.errno == errno.ENOENT:
                 return False
@@ -533,7 +529,7 @@
     is_file_hidden = is_file_hidden_posix
 
 
-def is_hidden(abs_path: str, abs_root: str = "") -> bool:
+def is_hidden(abs_path: str | Path, abs_root: str | Path = "") -> bool:
     """Is a file hidden or contained in a hidden directory?
 
     This will start with the rightmost path element and work backwards to the
@@ -547,42 +543,56 @@
 
     Parameters
     ----------
-    abs_path : unicode
+    abs_path : str or Path
         The absolute path to check for hidden directories.
-    abs_root : unicode
+    abs_root : str or Path
         The absolute path of the root directory in which hidden directories
         should be checked for.
     """
-    abs_path = os.path.normpath(abs_path)
-    abs_root = os.path.normpath(abs_root)
+    abs_path = Path(os.path.normpath(abs_path))
+    if abs_root:
+        abs_root = Path(os.path.normpath(abs_root))
+    else:
+        abs_root = list(abs_path.parents)[-1]
 
     if abs_path == abs_root:
+        # root itself is never hidden
         return False
 
+    # check that arguments are valid
+    if not abs_path.is_absolute():
+        _msg = f"{abs_path=} is not absolute. abs_path must be absolute."
+        raise ValueError(_msg)
+    if not abs_root.is_absolute():
+        _msg = f"{abs_root=} is not absolute. abs_root must be absolute."
+        raise ValueError(_msg)
+    if not abs_path.is_relative_to(abs_root):
+        _msg = (
+            f"{abs_path=} is not a subdirectory of {abs_root=}. abs_path must 
be within abs_root."
+        )
+        raise ValueError(_msg)
+
     if is_file_hidden(abs_path):
         return True
 
-    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 Path(inside_root).parts):
+    relative_path = abs_path.relative_to(abs_root)
+    if any(part.startswith(".") for part in relative_path.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 = str(Path(abs_path).parent)
-    while path and path.startswith(abs_root) and path != abs_root:
-        if not Path(path).exists():
-            path = str(Path(path).parent)
+    for parent in abs_path.parents:
+        if not parent.exists():
             continue
+        if parent == abs_root:
+            break
         try:
             # may fail on Windows junctions
-            st = os.lstat(path)
+            st = parent.lstat()
         except OSError:
             return True
         if getattr(st, "st_flags", 0) & UF_HIDDEN:
             return True
-        path = str(Path(path).parent)
 
     return False
 
@@ -602,12 +612,12 @@
         The path to the file to secure
     """
     try:
-        import win32api
+        import win32api  # noqa: PLC0415
     except ImportError:
         return _win32_restrict_file_to_user_ctypes(fname)
 
-    import ntsecuritycon as con
-    import win32security
+    import ntsecuritycon as con  # noqa: PLC0415
+    import win32security  # noqa: PLC0415
 
     # everyone, _domain, _type = win32security.LookupAccountName("", 
"Everyone")
     admins = 
win32security.CreateWellKnownSid(win32security.WinBuiltinAdministratorsSid)
@@ -646,8 +656,8 @@
     fname : unicode
         The path to the file to secure
     """
-    import ctypes
-    from ctypes import wintypes
+    import ctypes  # noqa: PLC0415
+    from ctypes import wintypes  # noqa: PLC0415
 
     advapi32 = ctypes.WinDLL("advapi32", use_last_error=True)  # 
type:ignore[attr-defined]
     secur32 = ctypes.WinDLL("secur32", use_last_error=True)  # 
type:ignore[attr-defined]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.8.1/jupyter_core/troubleshoot.py 
new/jupyter_core-5.9.1/jupyter_core/troubleshoot.py
--- old/jupyter_core-5.8.1/jupyter_core/troubleshoot.py 2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.9.1/jupyter_core/troubleshoot.py 2020-02-02 
01:00:00.000000000 +0100
@@ -10,10 +10,10 @@
 import platform
 import subprocess
 import sys
-from typing import Any, Optional, Union
+from typing import Any, Union
 
 
-def subs(cmd: Union[list[str], str]) -> Optional[str]:
+def subs(cmd: Union[list[str], str]) -> str | None:
     """
     get data from commands that we need to run outside of python
     """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.8.1/jupyter_core/utils/__init__.py 
new/jupyter_core-5.9.1/jupyter_core/utils/__init__.py
--- old/jupyter_core-5.8.1/jupyter_core/utils/__init__.py       2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.9.1/jupyter_core/utils/__init__.py       2020-02-02 
01:00:00.000000000 +0100
@@ -9,10 +9,11 @@
 import sys
 import threading
 import warnings
+from collections.abc import Awaitable, Callable
 from contextvars import ContextVar
 from pathlib import Path
 from types import FrameType
-from typing import Any, Awaitable, Callable, TypeVar, cast
+from typing import Any, TypeVar, cast
 
 
 def ensure_dir_exists(path: str | Path, mode: int = 0o777) -> None:
@@ -150,9 +151,15 @@
     def wrapped(*args: Any, **kwargs: Any) -> Any:
         name = threading.current_thread().name
         inner = coro(*args, **kwargs)
+
+        loop_running = False
         try:
             asyncio.get_running_loop()
+            loop_running = True
         except RuntimeError:
+            pass
+
+        if not loop_running:
             # No loop running, run the loop for this thread.
             loop = ensure_event_loop()
             return loop.run_until_complete(inner)
@@ -176,7 +183,17 @@
         loop = asyncio.get_running_loop()
     except RuntimeError:
         if sys.platform == "win32" and prefer_selector_loop:
-            loop = asyncio.WindowsSelectorEventLoopPolicy().new_event_loop()
+            if (3, 14) <= sys.version_info < (3, 15):
+                # ignore deprecation only for 3.14 and revisit later.
+                with warnings.catch_warnings():
+                    warnings.filterwarnings(
+                        "ignore",
+                        category=DeprecationWarning,
+                        message=".*WindowsSelectorEventLoopPolicy.*",
+                    )
+                    loop = 
asyncio.WindowsSelectorEventLoopPolicy().new_event_loop()
+            else:
+                loop = 
asyncio.WindowsSelectorEventLoopPolicy().new_event_loop()
         else:
             loop = asyncio.new_event_loop()
         asyncio.set_event_loop(loop)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.8.1/jupyter_core/version.py 
new/jupyter_core-5.9.1/jupyter_core/version.py
--- old/jupyter_core-5.8.1/jupyter_core/version.py      2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.9.1/jupyter_core/version.py      2020-02-02 
01:00:00.000000000 +0100
@@ -7,7 +7,7 @@
 import re
 
 # Version string must appear intact for hatch versioning
-__version__ = "5.8.1"
+__version__ = "5.9.1"
 
 # Build up version_info tuple for backwards compatibility
 pattern = r"(?P<major>\d+).(?P<minor>\d+).(?P<patch>\d+)(?P<rest>.*)"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.8.1/pyproject.toml 
new/jupyter_core-5.9.1/pyproject.toml
--- old/jupyter_core-5.8.1/pyproject.toml       2020-02-02 01:00:00.000000000 
+0100
+++ new/jupyter_core-5.9.1/pyproject.toml       2020-02-02 01:00:00.000000000 
+0100
@@ -15,11 +15,10 @@
   "Programming Language :: Python",
   "Programming Language :: Python :: 3"
 ]
-requires-python = ">=3.8"
+requires-python = ">=3.10"
 dependencies = [
   "platformdirs>=2.5",
   "traitlets>=5.3",
-  "pywin32>=300 ; sys_platform == 'win32' and platform_python_implementation 
!= 'PyPy'"
 ]
 dynamic = ["version"]
 
@@ -28,7 +27,7 @@
 email = "[email protected]"
 
 [project.readme]
-text = "There is no reason to install this package on its own."
+text = "Jupyter core package. A base package on which Jupyter projects rely."
 content-type = "text/plain"
 
 [project.urls]
@@ -97,13 +96,13 @@
 detached = true
 [tool.hatch.envs.lint.scripts]
 build = [
-  "pre-commit run --all-files ruff",
+  "pre-commit run --all-files ruff-check",
   "pre-commit run --all-files ruff-format"
 ]
 
 [tool.mypy]
 files = "jupyter_core"
-python_version = "3.8"
+python_version = "3.14"
 strict = true
 enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
 warn_unreachable = true
@@ -111,6 +110,11 @@
 disallow_untyped_defs = true
 warn_redundant_casts = true
 disallow_untyped_calls = true
+# This is a workaround for a mypy bug which is incapable of treating 
sys.platform
+# correctly https://github.com/python/mypy/issues/10773
+# With pre-commit running on user platform and linux on CI you can't get the
+# types right, so we pin platform to linux
+platform = "linux"
 
 [tool.pytest.ini_options]
 minversion = "7.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.8.1/tests/test_application.py 
new/jupyter_core-5.9.1/tests/test_application.py
--- old/jupyter_core-5.8.1/tests/test_application.py    2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.9.1/tests/test_application.py    2020-02-02 
01:00:00.000000000 +0100
@@ -3,6 +3,7 @@
 import asyncio
 import os
 import shutil
+import sys
 from tempfile import mkdtemp
 from unittest.mock import patch
 
@@ -179,6 +180,7 @@
     _prefer_selector_loop = True
 
 
[email protected](sys.platform == "win32", reason="does not run on windows")
 def test_async_tornado_app():
     AsyncTornadoApp.launch_instance([])
     app = AsyncApp.instance()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.8.1/tests/test_command.py 
new/jupyter_core-5.9.1/tests/test_command.py
--- old/jupyter_core-5.8.1/tests/test_command.py        2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.9.1/tests/test_command.py        2020-02-02 
01:00:00.000000000 +0100
@@ -65,7 +65,7 @@
 
     if sys.platform == "win32":
         try:
-            import importlib.resources
+            import importlib.resources  # noqa: PLC0415
 
             if not hasattr(importlib.resources, "files"):
                 raise ImportError
@@ -152,7 +152,7 @@
     assert "Jupyter command `jupyter-nonexistant-subcommand` not found." in 
stderr
 
 
[email protected](sys, "argv", [__file__] + sys.argv[1:])
[email protected](sys, "argv", [__file__, *sys.argv[1:]])
 def test_subcommand_list(tmpdir):
     a = tmpdir.mkdir("a")
     for cmd in ("jupyter-foo-bar", "jupyter-xyz", "jupyter-babel-fish"):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.8.1/tests/test_migrate.py 
new/jupyter_core-5.9.1/tests/test_migrate.py
--- old/jupyter_core-5.8.1/tests/test_migrate.py        2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_core-5.9.1/tests/test_migrate.py        2020-02-02 
01:00:00.000000000 +0100
@@ -132,8 +132,9 @@
         called["migrate_dir"] = True
         return migrate_dir(src, dst)
 
-    with patch.object(migrate_mod, "migrate_file", notice_m_file), 
patch.object(
-        migrate_mod, "migrate_dir", notice_m_dir
+    with (
+        patch.object(migrate_mod, "migrate_file", notice_m_file),
+        patch.object(migrate_mod, "migrate_dir", notice_m_dir),
     ):
         assert migrate_one(src, dst)
         assert called == {"migrate_file": True}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_core-5.8.1/tests/test_paths.py 
new/jupyter_core-5.9.1/tests/test_paths.py
--- old/jupyter_core-5.8.1/tests/test_paths.py  2020-02-02 01:00:00.000000000 
+0100
+++ new/jupyter_core-5.9.1/tests/test_paths.py  2020-02-02 01:00:00.000000000 
+0100
@@ -301,7 +301,7 @@
                 ]
             )
         )
-        for p, v in zip(path, values):
+        for p, v in zip(path, values, strict=False):
             assert p == v
 
 
@@ -358,7 +358,7 @@
             ]
         )
     )
-    for p, v in zip(path, values):
+    for p, v in zip(path, values, strict=False):
         assert p == v
 
 
@@ -383,7 +383,7 @@
             ]
         )
     )
-    for p, v in zip(path, values):
+    for p, v in zip(path, values, strict=False):
         assert p == v
 
 
@@ -473,6 +473,19 @@
             assert is_hidden(subdir78, root)
 
 
[email protected](
+    ("abs_path", "abs_root"),
+    [
+        ("relative.py", "/absolute"),
+        ("/absolute/path.py", "relative"),
+        ("/absolute/path.py", "/absolute/not/parent"),
+    ],
+)
+def test_is_hidden_invalid(abs_path, abs_root):
+    with pytest.raises(ValueError, match="abs"):
+        is_hidden(abs_path, abs_root)
+
+
 @pytest.mark.skipif(
     not (
         sys.platform == "win32"
@@ -499,7 +512,7 @@
     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: F401
+    import ctypes  # noqa: F401, PLC0415
 
     with tempfile.TemporaryDirectory() as root:
         subdir1 = os.path.join(root, "subdir")

Reply via email to