diff options
author | INADA Naoki <methane@users.noreply.github.com> | 2017-06-28 15:31:53 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-28 15:31:53 (GMT) |
commit | a8f8d5b4bd30dbe0828550469d98f12d2ebb2ef4 (patch) | |
tree | c980c5c35f6c0a8710b7c3ea1bda301b67a395eb /Lib/site.py | |
parent | 79d37ae979a65ada0b2ac820279ccc3b1cd41ba6 (diff) | |
download | cpython-a8f8d5b4bd30dbe0828550469d98f12d2ebb2ef4.zip cpython-a8f8d5b4bd30dbe0828550469d98f12d2ebb2ef4.tar.gz cpython-a8f8d5b4bd30dbe0828550469d98f12d2ebb2ef4.tar.bz2 |
bpo-29585: optimize site.py startup time (GH-136)
Avoid importing `sysconfig` from `site` by copying minimum code.
Python startup is 5% faster on Linux and 30% faster on macOS
Diffstat (limited to 'Lib/site.py')
-rw-r--r-- | Lib/site.py | 78 |
1 files changed, 52 insertions, 26 deletions
diff --git a/Lib/site.py b/Lib/site.py index 8797938..fcf7dde 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -124,7 +124,7 @@ def removeduppaths(): # if they only differ in case); turn relative paths into absolute # paths. dir, dircase = makepath(dir) - if not dircase in known_paths: + if dircase not in known_paths: L.append(dir) known_paths.add(dircase) sys.path[:] = L @@ -234,6 +234,46 @@ def check_enableusersite(): return True + +# NOTE: sysconfig and it's dependencies are relatively large but site module +# needs very limited part of them. +# To speedup startup time, we have copy of them. +# +# See https://bugs.python.org/issue29585 + +# Copy of sysconfig._getuserbase() +def _getuserbase(): + env_base = os.environ.get("PYTHONUSERBASE", None) + if env_base: + return env_base + + def joinuser(*args): + return os.path.expanduser(os.path.join(*args)) + + if os.name == "nt": + base = os.environ.get("APPDATA") or "~" + return joinuser(base, "Python") + + if sys.platform == "darwin" and sys._framework: + return joinuser("~", "Library", sys._framework, + "%d.%d" % sys.version_info[:2]) + + return joinuser("~", ".local") + + +# Same to sysconfig.get_path('purelib', os.name+'_user') +def _get_path(userbase): + version = sys.version_info + + if os.name == 'nt': + return f'{userbase}/Python{version[0]}{version[1]}/site-packages' + + if sys.platform == 'darwin' and sys._framework: + return f'{userbase}/lib/python/site-packages' + + return f'{userbase}/lib/python{version[0]}.{version[1]}/site-packages' + + def getuserbase(): """Returns the `user base` directory path. @@ -242,12 +282,11 @@ def getuserbase(): it. """ global USER_BASE - if USER_BASE is not None: - return USER_BASE - from sysconfig import get_config_var - USER_BASE = get_config_var('userbase') + if USER_BASE is None: + USER_BASE = _getuserbase() return USER_BASE + def getusersitepackages(): """Returns the user-specific site-packages directory path. @@ -255,20 +294,11 @@ def getusersitepackages(): function will also set it. """ global USER_SITE - user_base = getuserbase() # this will also set USER_BASE - - if USER_SITE is not None: - return USER_SITE - - from sysconfig import get_path + userbase = getuserbase() # this will also set USER_BASE - if sys.platform == 'darwin': - from sysconfig import get_config_var - if get_config_var('PYTHONFRAMEWORK'): - USER_SITE = get_path('purelib', 'osx_framework_user') - return USER_SITE + if USER_SITE is None: + USER_SITE = _get_path(userbase) - USER_SITE = get_path('purelib', '%s_user' % os.name) return USER_SITE def addusersitepackages(known_paths): @@ -310,15 +340,11 @@ def getsitepackages(prefixes=None): else: sitepackages.append(prefix) sitepackages.append(os.path.join(prefix, "lib", "site-packages")) - if sys.platform == "darwin": - # for framework builds *only* we add the standard Apple - # locations. - from sysconfig import get_config_var - framework = get_config_var("PYTHONFRAMEWORK") - if framework: - sitepackages.append( - os.path.join("/Library", framework, - '%d.%d' % sys.version_info[:2], "site-packages")) + # for framework builds *only* we add the standard Apple locations. + if sys.platform == "darwin" and sys._framework: + sitepackages.append( + os.path.join("/Library", framework, + '%d.%d' % sys.version_info[:2], "site-packages")) return sitepackages def addsitepackages(known_paths, prefixes=None): |