22
33import os
44import sys
5+ import threading
56from os .path import pardir , realpath
67
78__all__ = [
@@ -172,7 +173,11 @@ def joinuser(*args):
172173_BASE_PREFIX = os .path .normpath (sys .base_prefix )
173174_EXEC_PREFIX = os .path .normpath (sys .exec_prefix )
174175_BASE_EXEC_PREFIX = os .path .normpath (sys .base_exec_prefix )
176+ # Mutex guarding initialization of _CONFIG_VARS.
177+ _CONFIG_VARS_LOCK = threading .RLock ()
175178_CONFIG_VARS = None
179+ # True iff _CONFIG_VARS has been fully initialized.
180+ _CONFIG_VARS_INITIALIZED = False
176181_USER_BASE = None
177182
178183# Regexes needed for parsing Makefile (and similar syntaxes,
@@ -626,6 +631,71 @@ def get_path(name, scheme=get_default_scheme(), vars=None, expand=True):
626631 return get_paths (scheme , vars , expand )[name ]
627632
628633
634+ def _init_config_vars ():
635+ global _CONFIG_VARS
636+ _CONFIG_VARS = {}
637+ # Normalized versions of prefix and exec_prefix are handy to have;
638+ # in fact, these are the standard versions used most places in the
639+ # Distutils.
640+ _CONFIG_VARS ['prefix' ] = _PREFIX
641+ _CONFIG_VARS ['exec_prefix' ] = _EXEC_PREFIX
642+ _CONFIG_VARS ['py_version' ] = _PY_VERSION
643+ _CONFIG_VARS ['py_version_short' ] = _PY_VERSION_SHORT
644+ _CONFIG_VARS ['py_version_nodot' ] = _PY_VERSION_SHORT_NO_DOT
645+ _CONFIG_VARS ['installed_base' ] = _BASE_PREFIX
646+ _CONFIG_VARS ['base' ] = _PREFIX
647+ _CONFIG_VARS ['installed_platbase' ] = _BASE_EXEC_PREFIX
648+ _CONFIG_VARS ['platbase' ] = _EXEC_PREFIX
649+ _CONFIG_VARS ['projectbase' ] = _PROJECT_BASE
650+ _CONFIG_VARS ['platlibdir' ] = sys .platlibdir
651+ try :
652+ _CONFIG_VARS ['abiflags' ] = sys .abiflags
653+ except AttributeError :
654+ # sys.abiflags may not be defined on all platforms.
655+ _CONFIG_VARS ['abiflags' ] = ''
656+ try :
657+ _CONFIG_VARS ['py_version_nodot_plat' ] = sys .winver .replace ('.' , '' )
658+ except AttributeError :
659+ _CONFIG_VARS ['py_version_nodot_plat' ] = ''
660+
661+ if os .name == 'nt' :
662+ _init_non_posix (_CONFIG_VARS )
663+ _CONFIG_VARS ['VPATH' ] = sys ._vpath
664+ if os .name == 'posix' :
665+ _init_posix (_CONFIG_VARS )
666+ if _HAS_USER_BASE :
667+ # Setting 'userbase' is done below the call to the
668+ # init function to enable using 'get_config_var' in
669+ # the init-function.
670+ _CONFIG_VARS ['userbase' ] = _getuserbase ()
671+
672+ # Always convert srcdir to an absolute path
673+ srcdir = _CONFIG_VARS .get ('srcdir' , _PROJECT_BASE )
674+ if os .name == 'posix' :
675+ if _PYTHON_BUILD :
676+ # If srcdir is a relative path (typically '.' or '..')
677+ # then it should be interpreted relative to the directory
678+ # containing Makefile.
679+ base = os .path .dirname (get_makefile_filename ())
680+ srcdir = os .path .join (base , srcdir )
681+ else :
682+ # srcdir is not meaningful since the installation is
683+ # spread about the filesystem. We choose the
684+ # directory containing the Makefile since we know it
685+ # exists.
686+ srcdir = os .path .dirname (get_makefile_filename ())
687+ _CONFIG_VARS ['srcdir' ] = _safe_realpath (srcdir )
688+
689+ # OS X platforms require special customization to handle
690+ # multi-architecture, multi-os-version installers
691+ if sys .platform == 'darwin' :
692+ import _osx_support
693+ _osx_support .customize_config_vars (_CONFIG_VARS )
694+
695+ global _CONFIG_VARS_INITIALIZED
696+ _CONFIG_VARS_INITIALIZED = True
697+
698+
629699def get_config_vars (* args ):
630700 """With no arguments, return a dictionary of all configuration
631701 variables relevant for the current platform.
@@ -636,66 +706,16 @@ def get_config_vars(*args):
636706 With arguments, return a list of values that result from looking up
637707 each argument in the configuration variable dictionary.
638708 """
639- global _CONFIG_VARS
640- if _CONFIG_VARS is None :
641- _CONFIG_VARS = {}
642- # Normalized versions of prefix and exec_prefix are handy to have;
643- # in fact, these are the standard versions used most places in the
644- # Distutils.
645- _CONFIG_VARS ['prefix' ] = _PREFIX
646- _CONFIG_VARS ['exec_prefix' ] = _EXEC_PREFIX
647- _CONFIG_VARS ['py_version' ] = _PY_VERSION
648- _CONFIG_VARS ['py_version_short' ] = _PY_VERSION_SHORT
649- _CONFIG_VARS ['py_version_nodot' ] = _PY_VERSION_SHORT_NO_DOT
650- _CONFIG_VARS ['installed_base' ] = _BASE_PREFIX
651- _CONFIG_VARS ['base' ] = _PREFIX
652- _CONFIG_VARS ['installed_platbase' ] = _BASE_EXEC_PREFIX
653- _CONFIG_VARS ['platbase' ] = _EXEC_PREFIX
654- _CONFIG_VARS ['projectbase' ] = _PROJECT_BASE
655- _CONFIG_VARS ['platlibdir' ] = sys .platlibdir
656- try :
657- _CONFIG_VARS ['abiflags' ] = sys .abiflags
658- except AttributeError :
659- # sys.abiflags may not be defined on all platforms.
660- _CONFIG_VARS ['abiflags' ] = ''
661- try :
662- _CONFIG_VARS ['py_version_nodot_plat' ] = sys .winver .replace ('.' , '' )
663- except AttributeError :
664- _CONFIG_VARS ['py_version_nodot_plat' ] = ''
665-
666- if os .name == 'nt' :
667- _init_non_posix (_CONFIG_VARS )
668- _CONFIG_VARS ['VPATH' ] = sys ._vpath
669- if os .name == 'posix' :
670- _init_posix (_CONFIG_VARS )
671- if _HAS_USER_BASE :
672- # Setting 'userbase' is done below the call to the
673- # init function to enable using 'get_config_var' in
674- # the init-function.
675- _CONFIG_VARS ['userbase' ] = _getuserbase ()
676-
677- # Always convert srcdir to an absolute path
678- srcdir = _CONFIG_VARS .get ('srcdir' , _PROJECT_BASE )
679- if os .name == 'posix' :
680- if _PYTHON_BUILD :
681- # If srcdir is a relative path (typically '.' or '..')
682- # then it should be interpreted relative to the directory
683- # containing Makefile.
684- base = os .path .dirname (get_makefile_filename ())
685- srcdir = os .path .join (base , srcdir )
686- else :
687- # srcdir is not meaningful since the installation is
688- # spread about the filesystem. We choose the
689- # directory containing the Makefile since we know it
690- # exists.
691- srcdir = os .path .dirname (get_makefile_filename ())
692- _CONFIG_VARS ['srcdir' ] = _safe_realpath (srcdir )
693-
694- # OS X platforms require special customization to handle
695- # multi-architecture, multi-os-version installers
696- if sys .platform == 'darwin' :
697- import _osx_support
698- _osx_support .customize_config_vars (_CONFIG_VARS )
709+
710+ # Avoid claiming the lock once initialization is complete.
711+ if not _CONFIG_VARS_INITIALIZED :
712+ with _CONFIG_VARS_LOCK :
713+ # Test again with the lock held to avoid races. Note that
714+ # we test _CONFIG_VARS here, not _CONFIG_VARS_INITIALIZED,
715+ # to ensure that recursive calls to get_config_vars()
716+ # don't re-enter init_config_vars().
717+ if _CONFIG_VARS is None :
718+ _init_config_vars ()
699719
700720 if args :
701721 vals = []
0 commit comments