Skip to content

Document Python 3.15 support and 0.13.21 vendorized upgrades - #98

Merged
arcivanov merged 2 commits into
sourcefrom
python-3.15-support
Aug 25, 2026
Merged

Document Python 3.15 support and 0.13.21 vendorized upgrades#98
arcivanov merged 2 commits into
sourcefrom
python-3.15-support

Conversation

@arcivanov

Copy link
Copy Markdown
Member

Accompanies pybuilder/pybuilder#948.

Release notes — adds the 0.13.21 section covering:

  • Python 3.15 support
  • the PEP 451 loader fix for vendored packages and coverage on 3.15
  • the packaging 26.3 Requirement.__slots__ fix
  • removal of pre-3.10 compatibility workarounds
  • vendorized dependency bumps, notably virtualenv 20.36.1 to 21.7.4

Front page — bumps the supported range to Python 3.10 through 3.15 and adds 3.15 to the tested-versions list.

No announcement post yet, since 0.13.21 has not been cut.

Adds the 0.13.21 release notes covering Python 3.15 support, the PEP 451
loader fix, the `packaging` 26.3 `Requirement.__slots__` fix, the removal of
pre-3.10 compatibility workarounds and the vendorized dependency bumps.

Bumps the supported version range on the front page to 3.10 through 3.15.
Cloudflare-style bot protection now answers htmlproofer's requests to both
hosts with 403, failing every build regardless of the change under test.

Scoped to those two hosts via --ignore-urls rather than adding 403 to
--ignore-status-codes, so a genuinely forbidden link anywhere else still fails
the build. The patterns require a path separator after the host so that
lookalike domains are not silently skipped.
@arcivanov
arcivanov force-pushed the python-3.15-support branch from d210491 to f95bbcd Compare August 24, 2026 23:12
arcivanov added a commit to pybuilder/pybuilder that referenced this pull request Aug 25, 2026
… dependencies [release] (#948)

Releases 0.13.21.

## Python 3.15 support

Python 3.15 removed the legacy `load_module()` fallback from the import
machinery, so meta path loaders must implement the PEP 451
`create_module()`/`exec_module()` protocol. Both `VendorImporter` and
`CoverageImporter` failed at import time without it:

```
AttributeError: 'VendorImporter' object has no attribute 'exec_module'
```

There is a subtlety beyond simply adding the two methods.
`module_from_spec()` unconditionally overwrites `__spec__` on whatever
`create_module()` returns, so returning the vendored module directly
replaces its real spec with the alias spec — which has no origin and a
loader unable to locate resources. That surfaced as a second failure:

```
FileNotFoundError: Can't open orphan path (importlib/resources/_adapters.py:139)
```

when virtualenv looked up its own embedded payload. Both loaders now
stash the real spec in `create_module()` and restore it in
`exec_module()`, preserving the pre-3.15 behaviour exactly.

New regression tests (`extern_tests.py`, `coverage_shim_tests.py`) cover
the alias import, submodule import, spec preservation and resource
lookup. They fail without the fix on 3.10, 3.14 and 3.15.

## Pre-3.10 workaround removal

* `collections.abc` fallback in `utils`
* `types.WrapperDescriptorType` et al. fallback in `remote`
* `multiprocessing.semaphore_tracker` fallback in `remote`
* `importlib_metadata` backport fallback in `pip_common`
* 3.8-only `find_distributions` wrapper in `extern`
* hand-rolled `NodeVisitor` computing `end_lineno` in `vendorize`
* `pybuilder_venv.version >= (3, 3)` gate in `sphinx`
* `py2`/`py3` branching in the scaffolded `setup.py`
* `from __future__ import unicode_literals` in `pep517`
* Python 2 residue in `python_utils`
* version guards in the unit and integration tests

The `datetime.UTC` and `unittest.case._addError` fallbacks are retained
— both landed in 3.11, so 3.10 still needs them.

## Vendorized dependencies

Vendorized at Python 3.10, the minimum supported version, and verified
at 3.15.

* virtualenv 20.36.1 to 21.7.4, which moves interpreter discovery into a
separate `python-discovery` package and drops the `click` dependency
* importlib-metadata 8.7.1 to 9.0.0
* packaging 26.0 to 26.3
* importlib-resources 6.5.2 to 7.1.0
* rich 14.3.2 to 15.0.0
* wheel 0.46.3 to 0.48.0
* setuptools to 84.0.0
* virtualenv's embedded seed wheels: pip 25.0.1/25.3 to 26.0.1/26.2.1
and setuptools 75.3.2/80.9.0 to 82.0.1/84.0.0

Two changes were required to accommodate the new versions:

* `python_discovery` reads its own version from package metadata at
import time, so its dist-info has to survive the vendorize cleanup.
Added to `vendorize_preserve_metadata`.
* `packaging` 26.3 gave `Requirement` a `__slots__` layout, so the
pkg_resources-style `project_name` attribute PyBuilder attached to
requirements can no longer be set. Requirement names now come from
`Requirement.name`.

## CI

`3.15-dev` on the primary and secondary matrices, `3.15t-dev` on the
experimental one. Homebrew builds now skip `-dev` versions, which have
no Homebrew formula yet.

## Verification

Full build green locally at 3.15 (687 unit tests, 56 integration tests)
both before and after the vendorize bump. The rest of the range is
exercised by this PR's matrix.

Documentation accompanies this in pybuilder/pybuilder.github.io#98.
@arcivanov
arcivanov merged commit e4bcb54 into source Aug 25, 2026
1 check passed
@arcivanov
arcivanov deleted the python-3.15-support branch August 25, 2026 01:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant