summaryrefslogtreecommitdiffstats
path: root/Lib/site.py
diff options
context:
space:
mode:
authorINADA Naoki <methane@users.noreply.github.com>2017-06-28 15:31:53 (GMT)
committerGitHub <noreply@github.com>2017-06-28 15:31:53 (GMT)
commita8f8d5b4bd30dbe0828550469d98f12d2ebb2ef4 (patch)
treec980c5c35f6c0a8710b7c3ea1bda301b67a395eb /Lib/site.py
parent79d37ae979a65ada0b2ac820279ccc3b1cd41ba6 (diff)
downloadcpython-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.py78
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):