Bug report
Python 3.15 implements PEP 829 and moved .pth handling out of site.addpackage() into site.StartupState._exec_imports(). import lines in .pth files are still exec()'d, but now from a different frame, and the local variable holding the path of the .pth file being processed was renamed from fullname to filename. Any .pth file generated before 3.15 that reads fullname now raises NameError on every interpreter startup.
Reproducer
import os, site, tempfile
with tempfile.TemporaryDirectory() as d:
with open(os.path.join(d, "foo.pth"), "w") as f:
f.write("import sys; print(fullname)\n")
site.addpackage(d, "foo.pth", set())
On 3.14 this prints the path of the .pth file. On 3.15 and on main:
Error in import line from /tmp/tmp3kbbbxtg/foo.pth: import sys; print(fullname)
Traceback (most recent call last):
File "Lib/site.py", line 533, in _exec_imports
exec(line)
~~~~^^^^^^
File "<string>", line 1, in <module>
NameError: name 'fullname' is not defined. Did you mean: 'filename'?
Real-world impact
Every wheel built by wheel-axle before 0.0.13 installs a .pth file containing import wheel_axle.runtime; wheel_axle.runtime.finalize(fullname);, and there are published wheels in the wild carrying that line. The interpreter still starts, because site prints the traceback and continues, but the post-install hook never runs, so the symlinks the wheel declares are never created, and the error is printed again on every single startup because the .pth is never consumed. Downstream tracking issue: karellen/wheel-axle#38
PEP 829 keeps executing .pth import lines through 3.17, so this is not a case where the old mechanism has been retired. The lines still run; they just run against a frame that no longer exposes the name they were written against.
Suggested fix
This is the same class of regression as gh-149671, fixed in f7ab7c4 by injecting the sitedir local into _exec_imports() for compatibility with the -nspkg.pth files generated by setuptools. fullname needs identical treatment, immediately below the existing sitedir shim:
# Inject 'fullname' local variable in the current frame for
# compatibility with Python 3.14, where the path of the ".pth"
# file being processed was available to import lines under that
# name.
fullname = filename
I have this working locally against 3.15 with a regression test alongside test_sitedir_variable, and will open a PR.
Your environment
- CPython versions tested on: 3.15 (
v3.15.0rc1-86-gd0484ab51a7), main
- Operating system and architecture: Linux x86-64
Linked PRs
Bug report
Python 3.15 implements PEP 829 and moved
.pthhandling out ofsite.addpackage()intosite.StartupState._exec_imports().importlines in.pthfiles are stillexec()'d, but now from a different frame, and the local variable holding the path of the.pthfile being processed was renamed fromfullnametofilename. Any.pthfile generated before 3.15 that readsfullnamenow raisesNameErroron every interpreter startup.Reproducer
On 3.14 this prints the path of the
.pthfile. On 3.15 and onmain:Real-world impact
Every wheel built by
wheel-axlebefore 0.0.13 installs a.pthfile containingimport wheel_axle.runtime; wheel_axle.runtime.finalize(fullname);, and there are published wheels in the wild carrying that line. The interpreter still starts, becausesiteprints the traceback and continues, but the post-install hook never runs, so the symlinks the wheel declares are never created, and the error is printed again on every single startup because the.pthis never consumed. Downstream tracking issue: karellen/wheel-axle#38PEP 829 keeps executing
.pthimportlines through 3.17, so this is not a case where the old mechanism has been retired. The lines still run; they just run against a frame that no longer exposes the name they were written against.Suggested fix
This is the same class of regression as gh-149671, fixed in f7ab7c4 by injecting the
sitedirlocal into_exec_imports()for compatibility with the-nspkg.pthfiles generated by setuptools.fullnameneeds identical treatment, immediately below the existingsitedirshim:I have this working locally against
3.15with a regression test alongsidetest_sitedir_variable, and will open a PR.Your environment
v3.15.0rc1-86-gd0484ab51a7),mainLinked PRs