@@ -163,6 +163,13 @@ def _init_pathinfo():
163163_pending_importexecs = {}
164164
165165
166+ def _take_pending (mapping ):
167+ """Return the pending data and clear it before running startup code."""
168+ pending = mapping .copy ()
169+ mapping .clear ()
170+ return pending
171+
172+
166173def _read_pthstart_file (sitedir , name , suffix ):
167174 """Parse a .start or .pth file and return (lines, filename).
168175
@@ -280,11 +287,14 @@ def _read_start_file(sitedir, name):
280287 entrypoints .append (line )
281288
282289
283- def _extend_syspath ():
290+ def _extend_syspath (pending_syspaths = None ):
284291 # We've already filtered out duplicates, either in the existing sys.path
285292 # or in all the .pth files we've seen. We've also abspath/normpath'd all
286293 # the entries, so all that's left to do is to ensure that the path exists.
287- for filename , dirs in _pending_syspaths .items ():
294+ if pending_syspaths is None :
295+ pending_syspaths = _pending_syspaths
296+
297+ for filename , dirs in pending_syspaths .items ():
288298 for dir_ in dirs :
289299 if os .path .exists (dir_ ):
290300 _trace (f"Extending sys.path with { dir_ } from { filename } " )
@@ -295,16 +305,21 @@ def _extend_syspath():
295305 f"skipping sys.path append" )
296306
297307
298- def _exec_imports ():
308+ def _exec_imports (pending_importexecs = None , pending_entrypoints = None ):
299309 # For all the `import` lines we've seen in .pth files, exec() them in
300310 # order. However, if they come from a file with a matching .start, then
301311 # we ignore these import lines. For the ones we do process, print a
302312 # warning but only when -v was given.
303- for filename , imports in _pending_importexecs .items ():
313+ if pending_importexecs is None :
314+ pending_importexecs = _pending_importexecs
315+ if pending_entrypoints is None :
316+ pending_entrypoints = _pending_entrypoints
317+
318+ for filename , imports in pending_importexecs .items ():
304319 name , dot , pth = filename .rpartition ("." )
305320 assert dot == "." and pth == "pth" , f"Bad startup filename: { filename } "
306321
307- if f"{ name } .start" in _pending_entrypoints :
322+ if f"{ name } .start" in pending_entrypoints :
308323 # Skip import lines in favor of entry points.
309324 continue
310325
@@ -322,15 +337,18 @@ def _exec_imports():
322337 f"Error in import line from { filename } : { line } " , exc )
323338
324339
325- def _execute_start_entrypoints ():
340+ def _execute_start_entrypoints (pending_entrypoints = None ):
326341 """Execute all accumulated .start file entry points.
327342
328343 Called after all site-packages directories have been processed so that
329344 sys.path is fully populated before any entry point code runs. Uses
330345 pkgutil.resolve_name(strict=True) which both validates the strict
331346 pkg.mod:callable form and resolves the entry point in one step.
332347 """
333- for filename , entrypoints in _pending_entrypoints .items ():
348+ if pending_entrypoints is None :
349+ pending_entrypoints = _pending_entrypoints
350+
351+ for filename , entrypoints in pending_entrypoints .items ():
334352 for entrypoint in entrypoints :
335353 try :
336354 _trace (f"Executing entry point: { entrypoint } from { filename } " )
@@ -355,12 +373,15 @@ def _execute_start_entrypoints():
355373
356374def process_startup_files ():
357375 """Flush all pending sys.path and entry points."""
358- _extend_syspath ()
359- _exec_imports ()
360- _execute_start_entrypoints ()
361- _pending_syspaths .clear ()
362- _pending_importexecs .clear ()
363- _pending_entrypoints .clear ()
376+ # Startup code may call addsitedir(), so remove this batch from the
377+ # globals before executing any import lines or entry points.
378+ pending_syspaths = _take_pending (_pending_syspaths )
379+ pending_importexecs = _take_pending (_pending_importexecs )
380+ pending_entrypoints = _take_pending (_pending_entrypoints )
381+
382+ _extend_syspath (pending_syspaths )
383+ _exec_imports (pending_importexecs , pending_entrypoints )
384+ _execute_start_entrypoints (pending_entrypoints )
364385
365386
366387def addpackage (sitedir , name , known_paths ):
0 commit comments