@@ -116,8 +116,10 @@ def _getuserbase():
116116 if env_base :
117117 return env_base
118118
119- # Emscripten, iOS, tvOS, VxWorks, WASI, and watchOS have no home directories
120- if sys .platform in {"emscripten" , "ios" , "tvos" , "vxworks" , "wasi" , "watchos" }:
119+ # Emscripten, iOS, tvOS, VxWorks, WASI, and watchOS have no home directories.
120+ # Use _PYTHON_HOST_PLATFORM to get the correct platform when cross-compiling.
121+ system_name = os .environ .get ('_PYTHON_HOST_PLATFORM' , sys .platform ).split ('-' )[0 ]
122+ if system_name in {"emscripten" , "ios" , "tvos" , "vxworks" , "wasi" , "watchos" }:
121123 return None
122124
123125 def joinuser (* args ):
@@ -342,34 +344,53 @@ def get_makefile_filename():
342344 return os .path .join (get_path ('stdlib' ), config_dir_name , 'Makefile' )
343345
344346
347+ def _import_from_directory (path , name ):
348+ if name not in sys .modules :
349+ import importlib .machinery
350+ import importlib .util
351+
352+ spec = importlib .machinery .PathFinder .find_spec (name , [path ])
353+ module = importlib .util .module_from_spec (spec )
354+ spec .loader .exec_module (module )
355+ sys .modules [name ] = module
356+ return sys .modules [name ]
357+
358+
345359def _get_sysconfigdata_name ():
346360 multiarch = getattr (sys .implementation , '_multiarch' , '' )
347361 return os .environ .get (
348362 '_PYTHON_SYSCONFIGDATA_NAME' ,
349363 f'_sysconfigdata_{ sys .abiflags } _{ sys .platform } _{ multiarch } ' ,
350364 )
351365
352- def _init_posix (vars ):
353- """Initialize the module as appropriate for POSIX systems."""
354- # _sysconfigdata is generated at build time, see _generate_posix_vars()
366+
367+ def _get_sysconfigdata ():
368+ import importlib
369+
355370 name = _get_sysconfigdata_name ()
371+ path = os .environ .get ('_PYTHON_SYSCONFIGDATA_PATH' )
372+ module = _import_from_directory (path , name ) if path else importlib .import_module (name )
356373
357- # For cross builds, the path to the target's sysconfigdata must be specified
358- # so it can be imported. It cannot be in PYTHONPATH, as foreign modules in
359- # sys.path can cause crashes when loaded by the host interpreter.
360- # Rely on truthiness as a valueless env variable is still an empty string.
361- # See OS X note in _generate_posix_vars re _sysconfigdata.
362- if (path := os .environ .get ('_PYTHON_SYSCONFIGDATA_PATH' )):
363- from importlib .machinery import FileFinder , SourceFileLoader , SOURCE_SUFFIXES
364- from importlib .util import module_from_spec
365- spec = FileFinder (path , (SourceFileLoader , SOURCE_SUFFIXES )).find_spec (name )
366- _temp = module_from_spec (spec )
367- spec .loader .exec_module (_temp )
368- else :
369- _temp = __import__ (name , globals (), locals (), ['build_time_vars' ], 0 )
370- build_time_vars = _temp .build_time_vars
374+ return module .build_time_vars
375+
376+
377+ def _installation_is_relocated ():
378+ """Is the Python installation running from a different prefix than what was targetted when building?"""
379+ if os .name != 'posix' :
380+ raise NotImplementedError ('sysconfig._installation_is_relocated() is currently only supported on POSIX' )
381+
382+ data = _get_sysconfigdata ()
383+ return (
384+ data ['prefix' ] != getattr (sys , 'base_prefix' , '' )
385+ or data ['exec_prefix' ] != getattr (sys , 'base_exec_prefix' , '' )
386+ )
387+
388+
389+ def _init_posix (vars ):
390+ """Initialize the module as appropriate for POSIX systems."""
371391 # GH-126920: Make sure we don't overwrite any of the keys already set
372- vars .update (build_time_vars | vars )
392+ vars .update (_get_sysconfigdata () | vars )
393+
373394
374395def _init_non_posix (vars ):
375396 """Initialize the module as appropriate for NT"""
0 commit comments