Skip to content

Commit 615c6e6

Browse files
committed
Checkpointing review changes
* flush_pth_start() -> process_startup_files() * Move around some versionchanged and deprecated-removed sections * Add: kw-only arg `defer_processing_start_files` in several places to ensure that the reverse-engineered semantics of the undocumented functions are preserved.
1 parent e4a1271 commit 615c6e6

3 files changed

Lines changed: 55 additions & 50 deletions

File tree

Doc/library/site.rst

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,31 @@ and lines beginning with ``#`` are skipped.
9191
For backward compatibility, lines starting with ``import`` (followed by space
9292
or tab) are executed with :func:`exec`.
9393

94+
.. versionchanged:: 3.13
95+
96+
The :file:`.pth` files are now decoded by UTF-8 at first and then by the
97+
:term:`locale encoding` if it fails.
98+
9499
.. versionchanged:: next
95100

96-
``import`` lines in :file:`{name}.pth` are ignored when a :ref:`matching
97-
<site-start-files>` :file:`{name}.start` file exists.
101+
:file:`.pth` file lines starting with ``import`` are deprecated. During
102+
the deprecation period, such lines are still executed (except in the case
103+
below), but a diagnostic message is emitted only when the :option:`-v` flag
104+
is given.
105+
106+
``import`` lines in :file:`{name}.pth` are silently ignored when a
107+
:ref:`matching <site-start-files>` :file:`{name}.start` file exists.
108+
109+
Errors on individual lines no longer abort processing of the rest of the
110+
file. Each error is reported and the remaining lines continue to be
111+
processed.
98112

99113
.. deprecated-removed:: next 3.20
100114

115+
Decoding :file:`{name}.pth` files in any encoding other than ``utf-8-sig``
116+
is deprecated in Python 3.15, and support for decoding from the locale
117+
encoding will be removed in Python 3.20.
118+
101119
``import`` lines in :file:`{name}.pth` files are deprecated and will be
102120
silently ignored in Python 3.18 and 3.19. In Python 3.20 a warning will be
103121
produced for ``import`` lines in :file:`{name}.pth` files.
@@ -155,30 +173,6 @@ the remaining entry points.
155173
:file:`{name}.start` files invoke :func:`pkgutil.resolve_name` with
156174
``strict=True``, which requires the full ``pkg.mod:callable`` form.
157175

158-
.. versionchanged:: 3.13
159-
160-
The :file:`.pth` files are now decoded by UTF-8 at first and then by the
161-
:term:`locale encoding` if it fails.
162-
163-
.. deprecated-removed:: next 3.20
164-
165-
Decoding :file:`{name}.pth` files in any encoding other than ``utf-8-sig``
166-
is deprecated in Python 3.15, and support for decoding from the locale
167-
encoding will be removed in Python 3.20.
168-
169-
.. versionchanged:: next
170-
171-
:file:`.pth` file lines starting with ``import`` are deprecated. During
172-
the deprecation period, such lines are still executed, but a diagnostic
173-
message is emitted when the :option:`-v` flag is given. If a
174-
:file:`{name}.start` file with the same base name exists, ``import`` lines
175-
in :file:`{name}.pth` files are silently ignored. See
176-
:ref:`site-start-files` and :pep:`829`.
177-
178-
Errors on individual lines no longer abort processing of the rest of the
179-
file. Each error is reported and the remaining lines continue to be
180-
processed.
181-
182176
.. index::
183177
single: package
184178
triple: path; configuration; file
@@ -362,16 +356,21 @@ Module contents
362356
This function used to be called unconditionally.
363357

364358

365-
.. function:: addsitedir(sitedir, known_paths=None)
359+
.. function:: addsitedir(sitedir, known_paths=None, *, defer_processing_start_files=False)
366360

367-
Add a directory to sys.path and process its :file:`.pth` and
368-
:file:`.start` files. Typically used in :mod:`sitecustomize` or
361+
Add a directory to sys.path and parse the :file:`.pth` and :file:`.start`
362+
files found in that directory. Typically used in :mod:`sitecustomize` or
369363
:mod:`usercustomize` (see above).
370364

371365
The *known_paths* argument is an optional set of case-normalized paths
372366
used to prevent duplicate :data:`sys.path` entries. When ``None`` (the
373367
default), the set is built from the current :data:`sys.path`.
374368

369+
While :file:`.pth` and :file:`.start` files are always parsed, set
370+
*defer_processing_start_files* to ``True`` to prevent processing the
371+
startup data found in those files, so that you can process them explicitly
372+
(this is typically used by the :func:`main` function).
373+
375374
.. versionchanged:: next
376375

377376
Also processes :file:`.start` files. See :ref:`site-start-files`.

Lib/site.py

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@
3232
syntax. These are resolved via pkgutil.resolve_name() and called with no
3333
arguments.
3434
35-
All .pth path extensions are applied before any .start entry points are
36-
executed, ensuring that paths are available before startup code runs.
35+
When called from main(), all .pth path extensions are applied before any
36+
.start entry points are executed, ensuring that paths are available before
37+
startup code runs.
3738
3839
See the documentation for the site module for full details:
3940
https://docs.python.org/3/library/site.html
@@ -352,7 +353,7 @@ def _execute_start_entrypoints():
352353
exc)
353354

354355

355-
def flush_pth_start():
356+
def process_startup_files():
356357
"""Flush all pending sys.path and entry points."""
357358
_extend_syspath()
358359
_exec_imports()
@@ -370,13 +371,13 @@ def addpackage(sitedir, name, known_paths):
370371
else:
371372
reset = False
372373
_read_pth_file(sitedir, name, known_paths)
373-
flush_pth_start()
374+
process_startup_files()
374375
if reset:
375376
known_paths = None
376377
return known_paths
377378

378379

379-
def addsitedir(sitedir, known_paths=None):
380+
def addsitedir(sitedir, known_paths=None, *, defer_processing_start_files=False):
380381
"""Add 'sitedir' argument to sys.path if missing and handle startup
381382
files."""
382383
_trace(f"Adding directory: {sitedir!r}")
@@ -415,8 +416,10 @@ def addsitedir(sitedir, known_paths=None):
415416

416417
# If standalone call (not from main()), flush immediately
417418
# so the caller sees the effect.
419+
if not defer_processing_start_files:
420+
process_startup_files()
421+
418422
if reset:
419-
flush_pth_start()
420423
known_paths = None
421424

422425
return known_paths
@@ -531,7 +534,7 @@ def getusersitepackages():
531534

532535
return USER_SITE
533536

534-
def addusersitepackages(known_paths):
537+
def addusersitepackages(known_paths, *, defer_processing_start_files=False):
535538
"""Add a per user site-package to sys.path
536539
537540
Each user has its own python directory with site-packages in the
@@ -543,7 +546,7 @@ def addusersitepackages(known_paths):
543546
user_site = getusersitepackages()
544547

545548
if ENABLE_USER_SITE and os.path.isdir(user_site):
546-
addsitedir(user_site, known_paths)
549+
addsitedir(user_site, known_paths, defer_processing_start_files=defer_processing_start_files)
547550
return known_paths
548551

549552
def getsitepackages(prefixes=None):
@@ -585,12 +588,12 @@ def getsitepackages(prefixes=None):
585588
sitepackages.append(os.path.join(prefix, "Lib", "site-packages"))
586589
return sitepackages
587590

588-
def addsitepackages(known_paths, prefixes=None):
591+
def addsitepackages(known_paths, prefixes=None, *, defer_processing_start_files=False):
589592
"""Add site-packages to sys.path"""
590593
_trace("Processing global site-packages")
591594
for sitedir in getsitepackages(prefixes):
592595
if os.path.isdir(sitedir):
593-
addsitedir(sitedir, known_paths)
596+
addsitedir(sitedir, known_paths, defer_processing_start_files=defer_processing_start_files)
594597

595598
return known_paths
596599

@@ -872,15 +875,15 @@ def main():
872875
known_paths = venv(known_paths)
873876
if ENABLE_USER_SITE is None:
874877
ENABLE_USER_SITE = check_enableusersite()
875-
known_paths = addusersitepackages(known_paths)
876-
known_paths = addsitepackages(known_paths)
878+
known_paths = addusersitepackages(known_paths, defer_processing_start_files=True)
879+
known_paths = addsitepackages(known_paths, defer_processing_start_files=True)
877880
# PEP 829: flush accumulated data from all .pth and .start files.
878881
# Paths are extended first, then deprecated import lines are exec'd,
879882
# and finally .start entry points are executed — ensuring sys.path is
880-
# fully populated before any startup code runs. flush_pth_start()
883+
# fully populated before any startup code runs. process_startup_files()
881884
# also clears the pending state so a later addsitedir() call does
882885
# not re-apply already-processed data.
883-
flush_pth_start()
886+
process_startup_files()
884887
setquit()
885888
setcopyright()
886889
sethelper()

Lib/test/test_site.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -191,17 +191,20 @@ def test_addsitedir(self):
191191
pth_file.cleanup()
192192

193193
def test_addsitedir_explicit_flush(self):
194-
# addsitedir() reads .pth files and, when called standalone
195-
# (known_paths=None). Flushes paths and import lines explicitly.
194+
# addsitedir() reads .pth files and, with
195+
# defer_processing_start_files=True, accumulates pending state
196+
# without flushing. A subsequent process_startup_files() call
197+
# then applies the paths and runs the import lines.
196198
pth_file = PthFile()
197-
pth_file.cleanup(prep=True) # Make sure that nothing is pre-existing
198-
# that is tested for
199+
# Ensure we have a clean slate.
200+
pth_file.cleanup(prep=True)
199201
try:
200202
pth_file.create()
201-
# Providing known_paths=set() prevents flushing.
202-
site.addsitedir(pth_file.base_dir, set())
203+
# Pass defer_processing_start_files=True to prevent flushing.
204+
site.addsitedir(pth_file.base_dir, set(),
205+
defer_processing_start_files=True)
203206
self.assertNotIn(pth_file.imported, sys.modules)
204-
site.flush_pth_start()
207+
site.process_startup_files()
205208
self.pth_file_tests(pth_file)
206209
finally:
207210
pth_file.cleanup()

0 commit comments

Comments
 (0)