From 7c9f18fb9d1ba6d2d0ff4a9af1aca4a00348e737 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 23 Apr 2024 02:47:11 -0400 Subject: [PATCH 01/29] Migrate the config to pyproject.toml. --- pyproject.toml | 5 +++++ setup.cfg | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 pyproject.toml delete mode 100644 setup.cfg diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..d0e33159 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,5 @@ +[project.optional-dependencies] +docs = [ + # tidelift + "jaraco.tidelift >= 1.4", +] diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index cdb0caa9..00000000 --- a/setup.cfg +++ /dev/null @@ -1,5 +0,0 @@ -[options.extras_require] -docs = - - # tidelift - jaraco.tidelift >= 1.4 From 8de96e4367231c4f436647778d0abdea57617736 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 23 Dec 2024 16:21:25 -0500 Subject: [PATCH 02/29] =?UTF-8?q?=F0=9F=91=B9=20Feed=20the=20hobgoblins=20?= =?UTF-8?q?(delint).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index bd8564ed..002bdf10 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1 +1 @@ -extensions += ['jaraco.tidelift'] +extensions += ["jaraco.tidelift"] From 225b2afaa7819c07d3d1cd306070d0f200b8d086 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 27 Apr 2026 11:58:22 -0400 Subject: [PATCH 03/29] Add agent guidance pointing to skeleton documentation. Closes jaraco/skeleton#197. --- AGENTS.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..49ec34a2 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1 @@ +This project follows the [skeleton](https://blog.jaraco.com/skeleton); please read for context on development. From 91aed9a991ac5ca8ebcd631c8f32ab81ede0d652 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Mon, 27 Apr 2026 12:14:36 -0400 Subject: [PATCH 04/29] Add free-threaded Python builds to CI matrix (jaraco/skeleton#198) Agent-Logs-Url: https://github.com/jaraco/skeleton/sessions/806b3a23-52a0-400c-85ef-08d6842f7c84 Co-authored-by: jaraco <308610+jaraco@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jaraco <308610+jaraco@users.noreply.github.com> --- .github/workflows/main.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d40c74ac..d1837eca 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -36,6 +36,7 @@ jobs: python: - "3.10" - "3.13" + - "3.13t" platform: - ubuntu-latest - macos-latest @@ -47,6 +48,8 @@ jobs: platform: ubuntu-latest - python: "3.14" platform: ubuntu-latest + - python: "3.14t" + platform: ubuntu-latest - python: "3.15" platform: ubuntu-latest - python: pypy3.10 From fb8483bd52023e910a9d37d7508315ffa8c48db6 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 27 Apr 2026 12:18:58 -0400 Subject: [PATCH 05/29] Use Python 3.14 as the latest stable. --- .github/workflows/main.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d1837eca..799666e3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -35,8 +35,8 @@ jobs: matrix: python: - "3.10" - - "3.13" - - "3.13t" + - "3.14" + - "3.14t" platform: - ubuntu-latest - macos-latest @@ -46,9 +46,9 @@ jobs: platform: ubuntu-latest - python: "3.12" platform: ubuntu-latest - - python: "3.14" + - python: "3.13" platform: ubuntu-latest - - python: "3.14t" + - python: "3.13t" platform: ubuntu-latest - python: "3.15" platform: ubuntu-latest From b8f103031f45efad23afc7816be7c79238264a60 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 5 May 2026 19:57:49 -0400 Subject: [PATCH 06/29] More aggressively direct Agents not to add generated artifacts. --- AGENTS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 49ec34a2..8fa416f7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1 +1,3 @@ This project follows the [skeleton](https://blog.jaraco.com/skeleton); please read for context on development. + +Before committing, ensure .git/info/exclude is populated from jaraco/dotfiles .gitignore_global so that generated artifacts are never staged. From a4f728c8fbca13091e5b839ffc51b8fa1b2fd74a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 12 Jul 2026 12:51:43 -0400 Subject: [PATCH 07/29] Bump CI matrix from PyPy 3.10 to PyPy 3.11 PyPy 3.10 no longer has wheels for cryptography and other Rust-built extensions, so projects pulling them transitively fail the pypy job. Closes jaraco/skeleton#205 Co-Authored-By: Claude Opus 4.8 --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 799666e3..10c7e9e4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -52,7 +52,7 @@ jobs: platform: ubuntu-latest - python: "3.15" platform: ubuntu-latest - - python: pypy3.10 + - python: pypy3.11 platform: ubuntu-latest runs-on: ${{ matrix.platform }} continue-on-error: ${{ matrix.python == '3.15' }} From 317be02b9b092a19b6087efcbac667aa636a189d Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos Orfanos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 12 Jul 2026 18:52:12 +0200 Subject: [PATCH 08/29] TOML proper indentation (jaraco/skeleton#202) --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index a25e78ec..1dc1ff1a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,7 +64,7 @@ enabler = [ type = [ # upstream - # Exclude PyPy from type checks (python/mypy#20454 jaraco/skeleton#187) + # Exclude PyPy from type checks (python/mypy#20454 jaraco/skeleton#187) "pytest-mypy >= 1.0.1; platform_python_implementation != 'PyPy'", # local From b5c8ef5a8d788bd3132ba6d71246e0b6ea19a111 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 12 Jul 2026 12:59:45 -0400 Subject: [PATCH 09/29] Remove free-threaded 3.13 (3.13t) from CI matrix CFFI does not support the free-threaded build of CPython 3.13, breaking any project that depends transitively on cffi/cryptography. Free-threaded 3.14+ is supported, so 3.14t remains. Closes jaraco/skeleton#206 Co-Authored-By: Claude Opus 4.8 --- .github/workflows/main.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 10c7e9e4..bb9e8922 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -48,8 +48,6 @@ jobs: platform: ubuntu-latest - python: "3.13" platform: ubuntu-latest - - python: "3.13t" - platform: ubuntu-latest - python: "3.15" platform: ubuntu-latest - python: pypy3.11 From d9a367c8fa38f41dc657c560deaee75663cedb12 Mon Sep 17 00:00:00 2001 From: Avasam Date: Sun, 12 Jul 2026 13:04:17 -0400 Subject: [PATCH 10/29] Expect modern ruff and simplify configs (jaraco/skeleton#185) --------- Co-authored-by: Jason R. Coombs --- ruff.toml | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/ruff.toml b/ruff.toml index 63c0825f..5dba83a8 100644 --- a/ruff.toml +++ b/ruff.toml @@ -5,38 +5,27 @@ extend-select = [ "C901", # complex-structure "I", # isort "PERF401", # manual-list-comprehension + "UP", # pyupgrade (Code modernization for strings, annotations, conditions, ...) # Ensure modern type annotation syntax and best practices # Not including those covered by type-checkers or exclusive to Python 3.11+ "FA", # flake8-future-annotations "F404", # late-future-import "PYI", # flake8-pyi - "UP006", # non-pep585-annotation - "UP007", # non-pep604-annotation - "UP010", # unnecessary-future-import - "UP035", # deprecated-import - "UP037", # quoted-annotation - "UP043", # unnecessary-default-type-args # local ] ignore = [ # upstream + "UP015", # redundant-open-modes, explicit is preferred # Typeshed rejects complex or non-literal defaults for maintenance and testing reasons, # irrelevant to this project. "PYI011", # typed-argument-default-in-stub # https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules "W191", - "E111", - "E114", - "E117", "D206", "D300", - "Q000", - "Q001", - "Q002", - "Q003", "COM812", "COM819", From 384acd94b0c9601cc2b747042d0c5760f5d48606 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sun, 12 Jul 2026 13:10:29 -0400 Subject: [PATCH 11/29] Use reusable workflow to eliminate setup duplication between test and collateral (jaraco/skeleton#199) * Initial plan * Add reusable workflow to share test/collateral setup steps Agent-Logs-Url: https://github.com/jaraco/skeleton/sessions/ae6f447e-da11-4a46-a8d7-23cdbbffe148 Co-authored-by: jaraco <308610+jaraco@users.noreply.github.com> * Remove duplicated env block from main.yml Agent-Logs-Url: https://github.com/jaraco/skeleton/sessions/35bde516-10a9-4b0d-8c1f-6daa390f7011 Co-authored-by: jaraco <308610+jaraco@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jaraco <308610+jaraco@users.noreply.github.com> --- .github/workflows/main.yml | 54 +++++----------------------- .github/workflows/test-suite.yml | 60 ++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 45 deletions(-) create mode 100644 .github/workflows/test-suite.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bb9e8922..e0cebf80 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -15,19 +15,6 @@ on: permissions: contents: read -env: - # Environment variable to support color support (jaraco/skeleton#66) - FORCE_COLOR: 1 - - # Suppress noisy pip warnings - PIP_DISABLE_PIP_VERSION_CHECK: 'true' - PIP_NO_WARN_SCRIPT_LOCATION: 'true' - - # Ensure tests can sense settings about the environment - TOX_OVERRIDE: >- - testenv.pass_env+=GITHUB_*,FORCE_COLOR - - jobs: test: strategy: @@ -52,26 +39,12 @@ jobs: platform: ubuntu-latest - python: pypy3.11 platform: ubuntu-latest - runs-on: ${{ matrix.platform }} + uses: ./.github/workflows/test-suite.yml + with: + python: ${{ matrix.python }} + platform: ${{ matrix.platform }} + # https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idcontinue-on-error continue-on-error: ${{ matrix.python == '3.15' }} - steps: - - uses: actions/checkout@v4 - - name: Install build dependencies - # Install dependencies for building packages on pre-release Pythons - # jaraco/skeleton#161 - if: matrix.python == '3.15' && matrix.platform == 'ubuntu-latest' - run: | - sudo apt update - sudo apt install -y libxml2-dev libxslt-dev - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python }} - allow-prereleases: true - - name: Install tox - run: python -m pip install tox - - name: Run - run: tox collateral: strategy: @@ -80,19 +53,10 @@ jobs: job: - diffcov - docs - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: 3.x - - name: Install tox - run: python -m pip install tox - - name: Eval ${{ matrix.job }} - run: tox -e ${{ matrix.job }} + uses: ./.github/workflows/test-suite.yml + with: + platform: ubuntu-latest + tox-env: ${{ matrix.job }} check: # This job does nothing and is only used for the branch protection if: always() diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml new file mode 100644 index 00000000..7c8a9359 --- /dev/null +++ b/.github/workflows/test-suite.yml @@ -0,0 +1,60 @@ +name: Test Suite + +on: + workflow_call: + inputs: + python: + description: Python version + type: string + default: "3.x" + platform: + description: Runner platform + type: string + default: ubuntu-latest + tox-env: + description: >- + Tox environment to run; if empty, runs default tox + type: string + default: "" + +env: + # Environment variable to support color support (jaraco/skeleton#66) + FORCE_COLOR: 1 + + # Suppress noisy pip warnings + PIP_DISABLE_PIP_VERSION_CHECK: 'true' + PIP_NO_WARN_SCRIPT_LOCATION: 'true' + + # Ensure tests can sense settings about the environment + TOX_OVERRIDE: >- + testenv.pass_env+=GITHUB_*,FORCE_COLOR + +jobs: + run: + runs-on: ${{ inputs.platform }} + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Install build dependencies + # Install dependencies for building packages on pre-release Pythons + # jaraco/skeleton#161 + if: inputs.python == '3.15' && inputs.platform == 'ubuntu-latest' + run: | + sudo apt update + sudo apt install -y libxml2-dev libxslt-dev + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: ${{ inputs.python }} + allow-prereleases: true + - name: Install tox + run: python -m pip install tox + - name: Run + if: ${{ !inputs.tox-env }} + run: tox + - name: Run ${{ inputs.tox-env }} + if: ${{ inputs.tox-env }} + run: tox -e ${{ inputs.tox-env }} From f7aefdf156a54d7f8cee3e3a90574f17f5ca3935 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 12 Jul 2026 15:25:18 -0400 Subject: [PATCH 12/29] Instruct agents to fetch and read the skeleton document as a required first step Co-Authored-By: Claude Opus 4.8 --- AGENTS.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 8fa416f7..700235be 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,3 +1 @@ -This project follows the [skeleton](https://blog.jaraco.com/skeleton); please read for context on development. - -Before committing, ensure .git/info/exclude is populated from jaraco/dotfiles .gitignore_global so that generated artifacts are never staged. +**Required first step:** Before reading further or making any changes, fetch and read the [skeleton](https://blog.jaraco.com/skeleton/) document in its entirety. It is the authoritative source of truth for this project's structure, conventions, testing, and release process, and is not duplicated here. Do not act until you have ingested it. From 1f8c1f07e4d2937181a4116b1c1593685b8ff962 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 14 Jul 2026 19:22:15 -0400 Subject: [PATCH 13/29] Move continue-on-error into the reusable workflow's run job. (jaraco/skeleton#209) A job that calls a reusable workflow may not set 'continue-on-error'; GitHub rejects the whole file at startup ("Unexpected value 'continue-on-error'") before creating any jobs. The reusable-workflow refactor in jaraco/skeleton#199 moved the 'test' job to a reusable-workflow call while keeping the job-level 'continue-on-error', taking CI dark on skeleton and every downstream project that has since merged. Set continue-on-error on the reusable workflow's run job instead, keyed on the pre-release Python version already special-cased there. This preserves the allow-3.15-to-fail behavior in a single file, without threading an extra input through the caller. Co-authored-by: Claude Opus 4.8 --- .github/workflows/main.yml | 2 -- .github/workflows/test-suite.yml | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e0cebf80..072f3d3b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -43,8 +43,6 @@ jobs: with: python: ${{ matrix.python }} platform: ${{ matrix.platform }} - # https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idcontinue-on-error - continue-on-error: ${{ matrix.python == '3.15' }} collateral: strategy: diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index 7c8a9359..5c05f9e2 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -32,6 +32,8 @@ env: jobs: run: runs-on: ${{ inputs.platform }} + # Tolerate failures on pre-release Pythons (jaraco/skeleton#199) + continue-on-error: ${{ inputs.python == '3.15' }} permissions: contents: read steps: From f2c32067e086e4838b5e7b97f6f7f4363c576bed Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 1 Aug 2026 14:40:39 -0400 Subject: [PATCH 14/29] Disable C408 (unnecessary-collection-call) Retain the dict(a=1) call style as an elegant alternative to string-keyed literals rather than have Ruff 0.16's new default rewrite it. Ref jaraco/skeleton#210. Co-Authored-By: Claude Opus 4.8 --- ruff.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ruff.toml b/ruff.toml index 5dba83a8..b3852a7b 100644 --- a/ruff.toml +++ b/ruff.toml @@ -29,6 +29,10 @@ ignore = [ "COM812", "COM819", + # unnecessary-collection-call: retain the dict(a=1) call style rather than + # forcing string-keyed literals. See jaraco/skeleton#210. + "C408", + # local ] From f02e90a821fee92ff5ee2bf0d681b70cf24ebbb0 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 6 Aug 2026 17:01:01 -0400 Subject: [PATCH 15/29] Configure C408 to allow dict(a=1) rather than disabling it Switch from ignoring C408 (unnecessary-collection-call) entirely to enabling flake8-comprehensions allow-dict-calls-with-keyword-arguments, which retains the preferred dict(a=1) keyword-call style while C408 still flags dict() and dict([...]). Suggested by @Avasam; matches the configuration in pypa/setuptools#4785. Ref jaraco/skeleton#210. Co-Authored-By: Claude Opus 4.8 --- ruff.toml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ruff.toml b/ruff.toml index b3852a7b..a46d99e6 100644 --- a/ruff.toml +++ b/ruff.toml @@ -29,13 +29,14 @@ ignore = [ "COM812", "COM819", - # unnecessary-collection-call: retain the dict(a=1) call style rather than - # forcing string-keyed literals. See jaraco/skeleton#210. - "C408", - # local ] +[lint.flake8-comprehensions] +# Retain the elegant dict(a=1) keyword-call style; C408 still flags dict() +# and dict([...]). See jaraco/skeleton#210. +allow-dict-calls-with-keyword-arguments = true + [format] # Enable preview to get hugged parenthesis unwrapping and other nice surprises # See https://github.com/jaraco/skeleton/pull/133#issuecomment-2239538373 From 8aa3460fd351622af70174c72e0bc5f796a470c0 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 16 Aug 2026 15:21:29 -0400 Subject: [PATCH 16/29] Ignore N999 (invalid-module-name) (jaraco/skeleton#212) ruff 0.16 flags N999 for projects whose source directory is the distribution name and is redirected to a different import package (e.g. namespace layouts, as used throughout coherent-oss), even though that dotted name is a valid module. Reported upstream as astral-sh/ruff#27801; ignore it here rather than carry a per-file noqa in every such project. Co-authored-by: Claude Opus 4.8 --- ruff.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ruff.toml b/ruff.toml index a46d99e6..01353f90 100644 --- a/ruff.toml +++ b/ruff.toml @@ -29,6 +29,13 @@ ignore = [ "COM812", "COM819", + # N999 (invalid-module-name) yields false positives when a project's + # source directory is the distribution name and is redirected to a + # different import package (e.g. namespace layouts); the dotted directory + # name is itself a valid module. See + # https://github.com/astral-sh/ruff/issues/27801. + "N999", + # local ] From 2c43cdf7c2faa369083118742a036303b85edf66 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 28 Aug 2026 10:57:31 -0400 Subject: [PATCH 17/29] Ignore B008 (function-call-in-default-argument). (jaraco/skeleton#215) B006 already catches shared mutable defaults; B008 flags every call regardless of mutability, and escaping it requires enumerating fully-qualified names in each downstream project. Closes jaraco/skeleton#214 Co-authored-by: Claude Opus 5 --- ruff.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ruff.toml b/ruff.toml index 01353f90..24393e4f 100644 --- a/ruff.toml +++ b/ruff.toml @@ -36,6 +36,9 @@ ignore = [ # https://github.com/astral-sh/ruff/issues/27801. "N999", + # B008 is over-reaching; see jaraco/skeleton#214 + "B008", # function-call-in-default-argument + # local ] From 9e0812976b1154a7aece47188814385c887bc6c9 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 1 Oct 2026 16:43:13 -0400 Subject: [PATCH 18/29] Ignore PLC0414 (useless-import-alias). (jaraco/skeleton#216) Ref jaraco/skeleton#210. Co-authored-by: Claude Opus 5.5 --- ruff.toml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ruff.toml b/ruff.toml index 24393e4f..1f2aa753 100644 --- a/ruff.toml +++ b/ruff.toml @@ -39,6 +39,11 @@ ignore = [ # B008 is over-reaching; see jaraco/skeleton#214 "B008", # function-call-in-default-argument + # PLC0414 flags `import X as X`, the idiom type checkers recognize as an + # explicit re-export, and its fix (with F401) silently drops public names. + # See jaraco/skeleton#210. + "PLC0414", # useless-import-alias + # local ] From 9695460ebfa879ada16545d62b26b9a489a6d5ed Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 2 Oct 2026 10:01:51 -0400 Subject: [PATCH 19/29] Pass secrets through to the reusable test-suite workflow. (jaraco/skeleton#219) Closes jaraco/skeleton#218 Co-authored-by: Claude Opus 5.5 --- .github/workflows/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 072f3d3b..54c9000e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -43,6 +43,7 @@ jobs: with: python: ${{ matrix.python }} platform: ${{ matrix.platform }} + secrets: inherit collateral: strategy: @@ -55,6 +56,7 @@ jobs: with: platform: ubuntu-latest tox-env: ${{ matrix.job }} + secrets: inherit check: # This job does nothing and is only used for the branch protection if: always() From 9b2cf2ec5743dfd1e0f27f6d17306bd01a1fe8b8 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 17 Oct 2026 10:18:57 -0400 Subject: [PATCH 20/29] Repair the violations from Ruff 0.16's expanded defaults. Ref jaraco/skeleton#210. Co-Authored-By: Claude Opus 5.5 --- importlib_resources/__init__.py | 4 ++-- importlib_resources/_common.py | 8 ++++---- importlib_resources/_itertools.py | 4 ++-- importlib_resources/abc.py | 12 ++++-------- importlib_resources/compat/py39.py | 2 +- importlib_resources/tests/test_contents.py | 4 ++-- importlib_resources/tests/test_files.py | 4 ++-- importlib_resources/tests/test_functional.py | 8 ++++---- importlib_resources/tests/util.py | 4 ++-- importlib_resources/tests/zip.py | 0 10 files changed, 23 insertions(+), 27 deletions(-) mode change 100755 => 100644 importlib_resources/tests/zip.py diff --git a/importlib_resources/__init__.py b/importlib_resources/__init__.py index 27d6c7f8..a2df1ad6 100644 --- a/importlib_resources/__init__.py +++ b/importlib_resources/__init__.py @@ -25,12 +25,12 @@ from .abc import ResourceReader __all__ = [ - 'Package', 'Anchor', + 'Package', 'ResourceReader', 'as_file', - 'files', 'contents', + 'files', 'is_resource', 'open_binary', 'open_text', diff --git a/importlib_resources/_common.py b/importlib_resources/_common.py index 4e7c9137..50efde36 100644 --- a/importlib_resources/_common.py +++ b/importlib_resources/_common.py @@ -7,7 +7,7 @@ import pathlib import tempfile import types -from typing import Optional, cast +from typing import cast from .abc import ResourceReader, Traversable @@ -15,14 +15,14 @@ Anchor = Package -def files(anchor: Optional[Anchor] = None) -> Traversable: +def files(anchor: Anchor | None = None) -> Traversable: """ Get a Traversable resource for an anchor. """ return from_package(resolve(anchor)) -def get_resource_reader(package: types.ModuleType) -> Optional[ResourceReader]: +def get_resource_reader(package: types.ModuleType) -> ResourceReader | None: """ Return the package's loader if it's a ResourceReader. """ @@ -39,7 +39,7 @@ def get_resource_reader(package: types.ModuleType) -> Optional[ResourceReader]: @functools.singledispatch -def resolve(cand: Optional[Anchor]) -> types.ModuleType: +def resolve(cand: Anchor | None) -> types.ModuleType: return cast(types.ModuleType, cand) diff --git a/importlib_resources/_itertools.py b/importlib_resources/_itertools.py index 7b775ef5..57e9879a 100644 --- a/importlib_resources/_itertools.py +++ b/importlib_resources/_itertools.py @@ -30,8 +30,8 @@ def only(iterable, default=None, too_long=None): pass else: msg = ( - 'Expected exactly one item in iterable, but got {!r}, {!r}, ' - 'and perhaps more.'.format(first_value, second_value) + f'Expected exactly one item in iterable, but got {first_value!r}, ' + f'{second_value!r}, and perhaps more.' ) raise too_long or ValueError(msg) diff --git a/importlib_resources/abc.py b/importlib_resources/abc.py index 0b5fdee8..0dfc951b 100644 --- a/importlib_resources/abc.py +++ b/importlib_resources/abc.py @@ -8,9 +8,7 @@ BinaryIO, Literal, NoReturn, - Optional, Protocol, - Text, TextIO, overload, runtime_checkable, @@ -25,7 +23,7 @@ class ResourceReader(metaclass=abc.ABCMeta): """Abstract base class for loaders to provide resource reading support.""" @abc.abstractmethod - def open_resource(self, resource: Text) -> BinaryIO: + def open_resource(self, resource: str) -> BinaryIO: """Return an opened, file-like object for binary reading. The 'resource' argument is expected to represent only a file name. @@ -37,7 +35,7 @@ def open_resource(self, resource: Text) -> BinaryIO: raise FileNotFoundError @abc.abstractmethod - def resource_path(self, resource: Text) -> Text: + def resource_path(self, resource: str) -> str: """Return the file system path to the specified resource. The 'resource' argument is expected to represent only a file name. @@ -50,7 +48,7 @@ def resource_path(self, resource: Text) -> Text: raise FileNotFoundError @abc.abstractmethod - def is_resource(self, path: Text) -> bool: + def is_resource(self, path: str) -> bool: """Return True if the named 'path' is a resource. Files are resources, directories are not. @@ -90,9 +88,7 @@ def read_bytes(self) -> bytes: with self.open('rb') as strm: return strm.read() - def read_text( - self, encoding: Optional[str] = None, errors: Optional[str] = None - ) -> str: + def read_text(self, encoding: str | None = None, errors: str | None = None) -> str: """ Read contents of self as text """ diff --git a/importlib_resources/compat/py39.py b/importlib_resources/compat/py39.py index 684d3c63..540b384f 100644 --- a/importlib_resources/compat/py39.py +++ b/importlib_resources/compat/py39.py @@ -3,7 +3,7 @@ __all__ = ['ZipPath'] -if sys.version_info >= (3, 10): +if sys.version_info >= (3, 10): # noqa: UP036 (shim retained; removal is a separate change) from zipfile import Path as ZipPath else: from zipp import Path as ZipPath diff --git a/importlib_resources/tests/test_contents.py b/importlib_resources/tests/test_contents.py index dcb872ec..c0b2a5a6 100644 --- a/importlib_resources/tests/test_contents.py +++ b/importlib_resources/tests/test_contents.py @@ -6,7 +6,7 @@ class ContentsTests: - expected = { + expected = { # noqa: RUF012 (never mutated; overridden by subclasses) '__init__.py', 'binary.file', 'subdirectory', @@ -30,7 +30,7 @@ class ContentsZipTests(ContentsTests, util.ZipSetup, unittest.TestCase): class ContentsNamespaceTests(ContentsTests, util.DiskSetup, unittest.TestCase): MODULE = 'namespacedata01' - expected = { + expected = { # noqa: RUF012 (never mutated; overridden by subclasses) # no __init__ because of namespace design 'binary.file', 'subdirectory', diff --git a/importlib_resources/tests/test_files.py b/importlib_resources/tests/test_files.py index 06237d7b..94df311f 100644 --- a/importlib_resources/tests/test_files.py +++ b/importlib_resources/tests/test_files.py @@ -88,7 +88,7 @@ def load_fixture(self, name): class ModulesFiles: - spec = { + spec = { # noqa: RUF012 (never mutated; overridden by subclasses) 'mod.py': '', 'res.txt': 'resources are the best', } @@ -118,7 +118,7 @@ class ImplicitContextFiles: val = res.files().joinpath('res.txt').read_text(encoding='utf-8') """ ) - spec = { + spec = { # noqa: RUF012 (never mutated; overridden by subclasses) 'somepkg': { '__init__.py': set_val, 'submod.py': set_val, diff --git a/importlib_resources/tests/test_functional.py b/importlib_resources/tests/test_functional.py index 91612095..adb2011a 100644 --- a/importlib_resources/tests/test_functional.py +++ b/importlib_resources/tests/test_functional.py @@ -123,7 +123,7 @@ def test_open_text(self): resources.open_text(self.anchor01) with self.assertRaises((OSError, resources.abc.TraversalError)): resources.open_text(self.anchor01, 'no-such-file') - with resources.open_text(self.anchor01, 'utf-16.file') as f: + with resources.open_text(self.anchor01, 'utf-16.file') as f: # noqa: SIM117 (kept in sync with CPython) with self.assertRaises(UnicodeDecodeError): f.read() with resources.open_text( @@ -154,10 +154,10 @@ def test_open_binary(self): assert f.read() == b'a resource' def test_path(self): - with resources.path(self.anchor01, 'utf-8.file') as path: + with resources.path(self.anchor01, 'utf-8.file') as path: # noqa: SIM117 (kept in sync with CPython) with open(str(path), encoding='utf-8') as f: assert f.read() == 'Hello, UTF-8 world!\n' - with resources.path(self.anchor01) as path: + with resources.path(self.anchor01) as path: # noqa: SIM117 (kept in sync with CPython) with open(os.path.join(path, 'utf-8.file'), encoding='utf-8') as f: assert f.read() == 'Hello, UTF-8 world!\n' @@ -223,7 +223,7 @@ def test_text_errors(self): resources.read_text, resources.open_text, ): - with self.subTest(func=func): + with self.subTest(func=func): # noqa: SIM117 (kept in sync with CPython) # Multiple path arguments need explicit encoding argument. with self.assertRaises(TypeError): func( diff --git a/importlib_resources/tests/util.py b/importlib_resources/tests/util.py index 67088a66..f45ea5df 100644 --- a/importlib_resources/tests/util.py +++ b/importlib_resources/tests/util.py @@ -145,7 +145,7 @@ def test_useless_loader(self): '__init__.py': '', 'binary.file': bytes(range(4)), 'utf-16.file': '\ufeffHello, UTF-16 world!\n'.encode('utf-16-le'), - 'utf-8.file': 'Hello, UTF-8 world!\n'.encode('utf-8'), + 'utf-8.file': b'Hello, UTF-8 world!\n', 'subdirectory': { '__init__.py': '', 'binary.file': bytes(range(4, 8)), @@ -160,7 +160,7 @@ def test_useless_loader(self): namespacedata01={ 'binary.file': bytes(range(4)), 'utf-16.file': '\ufeffHello, UTF-16 world!\n'.encode('utf-16-le'), - 'utf-8.file': 'Hello, UTF-8 world!\n'.encode('utf-8'), + 'utf-8.file': b'Hello, UTF-8 world!\n', 'subdirectory': { 'binary.file': bytes(range(12, 16)), }, diff --git a/importlib_resources/tests/zip.py b/importlib_resources/tests/zip.py old mode 100755 new mode 100644 From c44e4ad8c3633a5a36860e80b2f089f8d82ef2c5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 17 Oct 2026 11:11:49 -0400 Subject: [PATCH 21/29] Install libxml2/libxslt headers for PyPy jobs too. Closes jaraco/skeleton#222 Co-Authored-By: Claude Opus 5.5 --- .github/workflows/test-suite.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index 5c05f9e2..10d412f4 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -42,8 +42,11 @@ jobs: fetch-depth: 0 - name: Install build dependencies # Install dependencies for building packages on pre-release Pythons - # jaraco/skeleton#161 - if: inputs.python == '3.15' && inputs.platform == 'ubuntu-latest' + # (jaraco/skeleton#161) and PyPy, which often lags on wheels + # (jaraco/skeleton#222). + if: >- + (inputs.python == '3.15' || startsWith(inputs.python, 'pypy')) + && inputs.platform == 'ubuntu-latest' run: | sudo apt update sudo apt install -y libxml2-dev libxslt-dev From 1989ff453bf2987a2b419912390be09e9a846048 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 18 Oct 2026 11:24:30 -0400 Subject: [PATCH 22/29] Ignore B018 (useless-expression). (jaraco/skeleton#220) Ref jaraco/skeleton#112, jaraco/skeleton#210. Co-authored-by: Claude Opus 5.5 --- ruff.toml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ruff.toml b/ruff.toml index 1f2aa753..415476e7 100644 --- a/ruff.toml +++ b/ruff.toml @@ -44,6 +44,11 @@ ignore = [ # See jaraco/skeleton#210. "PLC0414", # useless-import-alias + # B018 flags bare attribute access, which is useful for its side effect + # (forcing a lazy import, probing a property) and more elegant in tests + # than assigning to an ignored name. See jaraco/skeleton#112. + "B018", # useless-expression + # local ] From 4ed9709a6eb10e69b15e5e57ae6e1a7a94979cd1 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 20 Oct 2026 12:28:55 -0400 Subject: [PATCH 23/29] Replace 3.14t with 3.15t in the CI matrix (jaraco/skeleton#224) --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 54c9000e..b607a5ed 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -23,7 +23,7 @@ jobs: python: - "3.10" - "3.14" - - "3.14t" + - "3.15t" platform: - ubuntu-latest - macos-latest From 5c8556172305b2f13e8dd9fad7ba3e37568d4b28 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 20 Oct 2026 12:32:59 -0400 Subject: [PATCH 24/29] Bump Python versions: drop 3.10 (EOL), use 3.15 as stable, add 3.16 pre-release (jaraco/skeleton#225) Co-authored-by: Claude Opus 5.5 --- .github/workflows/main.yml | 10 +++++----- .github/workflows/test-suite.yml | 4 ++-- pyproject.toml | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b607a5ed..d3850a35 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,21 +21,21 @@ jobs: # https://blog.jaraco.com/efficient-use-of-ci-resources/ matrix: python: - - "3.10" - - "3.14" + - "3.11" + - "3.15" - "3.15t" platform: - ubuntu-latest - macos-latest - windows-latest include: - - python: "3.11" - platform: ubuntu-latest - python: "3.12" platform: ubuntu-latest - python: "3.13" platform: ubuntu-latest - - python: "3.15" + - python: "3.14" + platform: ubuntu-latest + - python: "3.16" platform: ubuntu-latest - python: pypy3.11 platform: ubuntu-latest diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index 10d412f4..b9033938 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -33,7 +33,7 @@ jobs: run: runs-on: ${{ inputs.platform }} # Tolerate failures on pre-release Pythons (jaraco/skeleton#199) - continue-on-error: ${{ inputs.python == '3.15' }} + continue-on-error: ${{ inputs.python == '3.16' }} permissions: contents: read steps: @@ -45,7 +45,7 @@ jobs: # (jaraco/skeleton#161) and PyPy, which often lags on wheels # (jaraco/skeleton#222). if: >- - (inputs.python == '3.15' || startsWith(inputs.python, 'pypy')) + (inputs.python == '3.16' || startsWith(inputs.python, 'pypy')) && inputs.platform == 'ubuntu-latest' run: | sudo apt update diff --git a/pyproject.toml b/pyproject.toml index 1dc1ff1a..892aaa90 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ classifiers = [ "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", ] -requires-python = ">=3.10" +requires-python = ">=3.11" license = "MIT" dependencies = [ ] From 134618579820f12d41c704ad914cbcaf8515a3bb Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 21 Oct 2026 12:58:12 -0700 Subject: [PATCH 25/29] Direct agents to `(meta)/agents/` for project guidance (jaraco/skeleton#226) Moves the skeleton pointer to `(meta)/agents/skeleton.md`, leaving `AGENTS.md` as a stable entry point that downstream projects can extend by adding their own files alongside it, without diverging from the skeleton. --- (meta)/agents/skeleton.md | 1 + AGENTS.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 (meta)/agents/skeleton.md diff --git a/(meta)/agents/skeleton.md b/(meta)/agents/skeleton.md new file mode 100644 index 00000000..1bc592a3 --- /dev/null +++ b/(meta)/agents/skeleton.md @@ -0,0 +1 @@ +Fetch and read the [skeleton](https://blog.jaraco.com/skeleton/) document in its entirety. It is the authoritative source of truth for this project's structure, conventions, testing, and release process, and is not duplicated here. diff --git a/AGENTS.md b/AGENTS.md index 700235be..894a4e7e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1 +1 @@ -**Required first step:** Before reading further or making any changes, fetch and read the [skeleton](https://blog.jaraco.com/skeleton/) document in its entirety. It is the authoritative source of truth for this project's structure, conventions, testing, and release process, and is not duplicated here. Do not act until you have ingested it. +**Required first step:** Before reading further or making any changes, read every file in `(meta)/agents/` in its entirety. Those files are the authoritative source of truth for this project's conventions and are not duplicated here. Do not act until you have ingested them. From 322045197aa3ac8d0ae9b70ec8ee3a2df20b5f85 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 21 Oct 2026 13:00:59 -0700 Subject: [PATCH 26/29] Point agents at the stdlib sync methodology. The methodology governs how this codebase is kept in sync with CPython, but nothing in the repository pointed agents to it. --- (meta)/agents/stdlib.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 (meta)/agents/stdlib.md diff --git a/(meta)/agents/stdlib.md b/(meta)/agents/stdlib.md new file mode 100644 index 00000000..d0458533 --- /dev/null +++ b/(meta)/agents/stdlib.md @@ -0,0 +1,3 @@ +This project shares its codebase with the CPython standard library, where it appears as `importlib.resources`. The two trees are kept byte-identical: changes made here are synced downstream into CPython, and changes made in CPython are ported back here. + +Before changing anything under `importlib_resources/`, read the [development methodology](https://github.com/python/importlib_metadata/wiki/Development-Methodology) in its entirety. It governs how the two codebases are kept in sync, which files are excluded from the stdlib, and how to verify the trees agree. From 953ed8625cc95d8859105484d070ccf9a0961059 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 21 Oct 2026 13:36:21 -0700 Subject: [PATCH 27/29] Add a newsfragment for the Python 3.10 drop. --- newsfragments/+drop-python-3.10.feature.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 newsfragments/+drop-python-3.10.feature.rst diff --git a/newsfragments/+drop-python-3.10.feature.rst b/newsfragments/+drop-python-3.10.feature.rst new file mode 100644 index 00000000..6d7da0ad --- /dev/null +++ b/newsfragments/+drop-python-3.10.feature.rst @@ -0,0 +1 @@ +Removed support for Python 3.10, now end-of-life. From 2337c43db2d97a06d5f4102e9e8ce9abe8c9b2e4 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 21 Oct 2026 13:40:02 -0700 Subject: [PATCH 28/29] Remove compatibility shims for Python 3.9 and earlier. `readers` now uses `zipfile.Path` directly and the tests take their helpers from `test.support` directly, both as the stdlib does. That drops the unreachable `zipp; python_version < '3.10'` requirement and the `jaraco.test` test dependency. mypy needs an override for `test.*`, which ships no py.typed marker. --- importlib_resources/compat/py39.py | 9 --------- importlib_resources/readers.py | 6 +++--- importlib_resources/tests/compat/py312.py | 2 +- importlib_resources/tests/compat/py39.py | 13 ------------- importlib_resources/tests/test_custom.py | 3 ++- importlib_resources/tests/test_files.py | 3 ++- importlib_resources/tests/test_functional.py | 3 ++- importlib_resources/tests/util.py | 3 ++- mypy.ini | 4 ++-- pyproject.toml | 2 -- 10 files changed, 14 insertions(+), 34 deletions(-) delete mode 100644 importlib_resources/compat/py39.py delete mode 100644 importlib_resources/tests/compat/py39.py diff --git a/importlib_resources/compat/py39.py b/importlib_resources/compat/py39.py deleted file mode 100644 index 540b384f..00000000 --- a/importlib_resources/compat/py39.py +++ /dev/null @@ -1,9 +0,0 @@ -import sys - -__all__ = ['ZipPath'] - - -if sys.version_info >= (3, 10): # noqa: UP036 (shim retained; removal is a separate change) - from zipfile import Path as ZipPath -else: - from zipp import Path as ZipPath diff --git a/importlib_resources/readers.py b/importlib_resources/readers.py index 99884b6a..5d0ae46d 100644 --- a/importlib_resources/readers.py +++ b/importlib_resources/readers.py @@ -7,11 +7,11 @@ import pathlib import re import warnings +import zipfile from collections.abc import Iterator from . import abc from ._itertools import only -from .compat.py39 import ZipPath def remove_duplicates(items): @@ -57,7 +57,7 @@ def is_resource(self, path): return target.is_file() and target.exists() def files(self): - return ZipPath(self.archive, self.prefix) + return zipfile.Path(self.archive, self.prefix) class MultiplexedPath(abc.Traversable): @@ -170,7 +170,7 @@ def _resolve_zip_path(path_str: str): PermissionError, ): inner = path_str[match.end() :].replace('\\', '/') + '/' - yield ZipPath(path_str[: match.start()], inner.lstrip('/')) + yield zipfile.Path(path_str[: match.start()], inner.lstrip('/')) def resource_path(self, resource): """ diff --git a/importlib_resources/tests/compat/py312.py b/importlib_resources/tests/compat/py312.py index ea9a58ba..904446b1 100644 --- a/importlib_resources/tests/compat/py312.py +++ b/importlib_resources/tests/compat/py312.py @@ -1,6 +1,6 @@ import contextlib -from .py39 import import_helper +from test.support import import_helper @contextlib.contextmanager diff --git a/importlib_resources/tests/compat/py39.py b/importlib_resources/tests/compat/py39.py deleted file mode 100644 index e01d276b..00000000 --- a/importlib_resources/tests/compat/py39.py +++ /dev/null @@ -1,13 +0,0 @@ -""" -Backward-compatability shims to support Python 3.9 and earlier. -""" - -from jaraco.test.cpython import from_test_support, try_import - -import_helper = try_import('import_helper') or from_test_support( - 'modules_setup', 'modules_cleanup', 'DirsOnSysPath' -) -os_helper = try_import('os_helper') or from_test_support('temp_dir') -warnings_helper = try_import('warnings_helper') or from_test_support( - 'ignore_warnings', 'check_warnings' -) diff --git a/importlib_resources/tests/test_custom.py b/importlib_resources/tests/test_custom.py index 25ae0e75..bfecaf6e 100644 --- a/importlib_resources/tests/test_custom.py +++ b/importlib_resources/tests/test_custom.py @@ -2,12 +2,13 @@ import pathlib import unittest +from test.support import os_helper + import importlib_resources as resources from .. import abc from ..abc import ResourceReader, TraversableResources from . import util -from .compat.py39 import os_helper class SimpleLoader: diff --git a/importlib_resources/tests/test_files.py b/importlib_resources/tests/test_files.py index 94df311f..2b290e21 100644 --- a/importlib_resources/tests/test_files.py +++ b/importlib_resources/tests/test_files.py @@ -6,11 +6,12 @@ import unittest import warnings +from test.support import import_helper, os_helper + import importlib_resources as resources from ..abc import Traversable from . import util -from .compat.py39 import import_helper, os_helper @contextlib.contextmanager diff --git a/importlib_resources/tests/test_functional.py b/importlib_resources/tests/test_functional.py index adb2011a..0f744716 100644 --- a/importlib_resources/tests/test_functional.py +++ b/importlib_resources/tests/test_functional.py @@ -2,10 +2,11 @@ import os import unittest +from test.support import warnings_helper + import importlib_resources as resources from . import util -from .compat.py39 import warnings_helper class StringAnchorMixin: diff --git a/importlib_resources/tests/util.py b/importlib_resources/tests/util.py index f45ea5df..1647f6c1 100644 --- a/importlib_resources/tests/util.py +++ b/importlib_resources/tests/util.py @@ -8,10 +8,11 @@ import types from importlib.machinery import ModuleSpec +from test.support import import_helper, os_helper + from ..abc import ResourceReader, Traversable, TraversableResources from . import _path from . import zip as zip_ -from .compat.py39 import import_helper, os_helper class Reader(ResourceReader): diff --git a/mypy.ini b/mypy.ini index d8f1411c..b9a1928f 100644 --- a/mypy.ini +++ b/mypy.ini @@ -18,6 +18,6 @@ disable_error_code = [mypy-zipp] ignore_missing_imports = True -# jaraco/jaraco.test#7 -[mypy-jaraco.test.*] +# CPython's test package ships no py.typed marker +[mypy-test.*] ignore_missing_imports = True diff --git a/pyproject.toml b/pyproject.toml index 34ec109d..29caccb9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,6 @@ classifiers = [ requires-python = ">=3.11" license = "Apache-2.0" dependencies = [ - "zipp >= 3.1.0; python_version < '3.10'", ] dynamic = ["version"] @@ -40,7 +39,6 @@ test = [ # local "zipp >= 3.17", - "jaraco.test >= 5.4", ] doc = [ From da8b5c6812b80104784f8899b29f6db4e5a3cc44 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 29 Oct 2026 10:14:16 -0400 Subject: [PATCH 29/29] Direct users to file directly to GitHub security advisories. --- SECURITY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SECURITY.md b/SECURITY.md index 54f99acb..e4391cf8 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,3 +1,3 @@ # Security Contact -To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. +To report a security vulnerability, please file a security advisory in GitHub. For help or for questions, escalate through the [Tidelift security contact](https://tidelift.com/security).