While this original PEP was withdrawn, a variant of this featurewas eventually implemented for Python 3.8 inhttps://bugs.python.org/issue33499
Several of the issues and concerns originally raised in this PEP were resolvedby other changes in the intervening years:
importlib, a fully import-hook based import system implementation__pycache__subdirectories, including thesource_to_cache(path) andcache_to_source(path) APIs that allow the interpreter to automaticallyhandle the redirection to a separate cache directoryThis PEP outlines a mechanism for controlling the generation andlocation of compiled Python bytecode files. This idea originallyarose as a patch request[1] and evolved into a discussion thread onthe python-dev mailing list[2]. The introduction of an environmentvariable will allow people installing Python or Python-basedthird-party packages to control whether or not bytecode files shouldbe generated at installation time, and if so, where they should bewritten. It will also allow users to control whether or not bytecodefiles should be generated at application run-time, and if so, wherethey should be written.
Add a new environment variable, PYTHONBYTECODEBASE, to the mix ofenvironment variables which Python understands. PYTHONBYTECODEBASE isinterpreted as follows:
C:\ – on Windows).a warning is displayed, sys.bytecodebase is set to None andgeneration of bytecode files is suppressed altogether.
After startup initialization, all runtime references are tosys.bytecodebase, not the PYTHONBYTECODEBASE environment variable.sys.path is not modified.
From the above, we see sys.bytecodebase can only take on two validtypes of values: None or a string referring to a valid directory onthe system.
During import, this extension works as follows:
Note that this PEP is explicitlynot about providingmodule-by-module or directory-by-directory control over thedisposition of bytecode files.
When the interpreter is searching for a module, it will use sys.pathas usual. However, when a possible bytecode file is considered, anextra probe for a bytecode file may be made. First, a check is madefor the bytecode file using the directory in sys.path which holds thesource file (the current behavior). If a valid bytecode file is notfound there (either one does not exist or exists but is out-of-date)and the bytecode base is not None, a second probe is made using thedirectory in sys.path prefixed appropriately by the bytecode base.
When the bytecode base is not None, a new bytecode file is written tothe appropriate augmented directory, never directly to a directory insys.path.
Conceptually, the augmented directory for a bytecode file is thedirectory in which the source file exists prefixed by the bytecodebase. In a Unix environment this would be:
pcb=os.path.abspath(sys.bytecodebase)ifsourcefile[0]==os.sep:sourcefile=sourcefile[1:]augdir=os.path.join(pcb,os.path.dirname(sourcefile))
On Windows, which does not have a single-rooted directory tree, thedrive letter of the directory containing the source file is treated asa directory component after removing the trailing colon. Theaugmented directory is thus derived as
pcb=os.path.abspath(sys.bytecodebase)drive,base=os.path.splitdrive(os.path.dirname(sourcefile))drive=drive[:-1]ifbase[0]=="\\":base=base[1:]augdir=os.path.join(pcb,drive,base)
During program startup, the value of the PYTHONBYTECODEBASEenvironment variable is made absolute, checked for validity and addedto the sys module, effectively:
pcb=os.path.abspath(os.environ["PYTHONBYTECODEBASE"])probe=os.path.join(pcb,"foo")try:open(probe,"w")exceptIOError:sys.bytecodebase=Noneelse:os.unlink(probe)sys.bytecodebase=pcb
This allows the user to specify the bytecode base as a relative path,but not have it subject to changes to the current working directoryduring program execution. (I can’t imagine you’d want it to movearound during program execution.)
There is nothing special about sys.bytecodebase. The user may changeit at runtime if desired, but normally it will not be modified.
In many environments it is not possible for non-root users to writeinto directories containing Python source files. Most of the time,this is not a problem as Python source is generally byte compiledduring installation. However, there are situations where bytecodefiles are either missing or need to be updated. If the directorycontaining the source file is not writable by the current user aperformance penalty is incurred each time a program importing themodule is run.[3] Warning messages may also be generated in certaincircumstances. If the directory is writable, nearly simultaneousattempts to write the bytecode file by two separate processesmay occur, resulting in file corruption.[4]
In environments with RAM disks available, it may be desirable forperformance reasons to write bytecode files to a directory on such adisk. Similarly, in environments where Python source code resides onnetwork file systems, it may be desirable to cache bytecode files onlocal disks.
The only other alternative proposed so far[1] seems to be to add a-R flag to the interpreter to disable writing bytecode filesaltogether. This proposal subsumes that. Adding a command-lineoption is certainly possible, but is probably not sufficient, as theinterpreter’s command line is not readily available duringinstallation (early during program startup???).
In the examples which follow, the urllib source code resides in/usr/lib/python2.3/urllib.py and /usr/lib/python2.3 is in sys.path butis not writable by the current user.
In the Windows examples which follow, the urllib source code residesinC:\PYTHON22\urllib.py.C:\PYTHON22 is in sys.path but isnot writable by the current user.
C:\TEMP.C:\PYTHON22\urllib.pycexists and is valid. When urllib is imported, the contents ofC:\PYTHON22\urllib.pyc are used. The augmented directory is notconsulted.C:\TEMP.C:\PYTHON22\urllib.pycexists, but is out-of-date. When urllib is imported, a new bytecodefile is written to the augmented directory which has the valueC:\TEMP\C\PYTHON22. Intermediate directories will be created asneeded.TEMP and the currentworking directory at application startup isH:\NET. Thepotential bytecode base is thusH:\NET\TEMP. If this directoryexists and is writable by the current user, sys.bytecodebase will beset to that value. If not, a warning will be emitted andsys.bytecodebase will be set to None.C:\TEMP. No urllib.pyc file is found.When urllib is imported, the generated bytecode file is written tothe augmented directory which has the valueC:\TEMP\C\PYTHON22.Intermediate directories will be created as needed.See the patch on Sourceforge.[6]
This document has been placed in the public domain.
Source:https://github.com/python/peps/blob/main/peps/pep-0304.rst
Last modified:2025-02-01 08:59:27 GMT