diff --git a/Lib/site.py b/Lib/site.py index 87979383584066..fcf7dde41131ac 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): diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py index ed0a34d662f189..e6618b1d5182ca 100644 --- a/Lib/sysconfig.py +++ b/Lib/sysconfig.py @@ -51,6 +51,7 @@ 'scripts': '{base}/Scripts', 'data': '{base}', }, + # NOTE: When modifying "purelib" scheme, update site._get_path() too. 'nt_user': { 'stdlib': '{userbase}/Python{py_version_nodot}', 'platstdlib': '{userbase}/Python{py_version_nodot}', @@ -177,32 +178,25 @@ def _get_default_scheme(): return os.name +# NOTE: site.py has copy of this function. +# Sync it when modify this function. 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 "~" - if env_base: - return env_base - else: - return joinuser(base, "Python") + return joinuser(base, "Python") - if sys.platform == "darwin": - framework = get_config_var("PYTHONFRAMEWORK") - if framework: - if env_base: - return env_base - else: - return joinuser("~", "Library", framework, "%d.%d" % - sys.version_info[:2]) + if sys.platform == "darwin" and sys._framework: + return joinuser("~", "Library", sys._framework, + "%d.%d" % sys.version_info[:2]) - if env_base: - return env_base - else: - return joinuser("~", ".local") + return joinuser("~", ".local") def _parse_makefile(filename, vars=None): diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index 150162279e6df6..bf7be4ec1c6a20 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -180,6 +180,13 @@ def test_addsitedir(self): finally: pth_file.cleanup() + def test_getuserbase(self): + self.assertEqual(site._getuserbase(), sysconfig._getuserbase()) + + def test_get_path(self): + self.assertEqual(site._get_path(site._getuserbase()), + sysconfig.get_path('purelib', os.name + '_user')) + @unittest.skipUnless(site.ENABLE_USER_SITE, "requires access to PEP 370 " "user-site (site.ENABLE_USER_SITE)") def test_s_option(self): diff --git a/Misc/NEWS.d/next/Library/2017-06-29-00-17-38.bpo-29585.x2V0my.rst b/Misc/NEWS.d/next/Library/2017-06-29-00-17-38.bpo-29585.x2V0my.rst new file mode 100644 index 00000000000000..c841f1b2250efc --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-06-29-00-17-38.bpo-29585.x2V0my.rst @@ -0,0 +1,2 @@ +Avoid importing ``sysconfig`` from ``site`` to improve startup speed. Python +startup is about 5% faster on Linux and 30% faster on macOS. diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 424a88f7086b3e..84673e3fed9737 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1965,6 +1965,7 @@ _PySys_BeginInit(void) SET_SYS_FROM_STRING("_git", Py_BuildValue("(szz)", "CPython", _Py_gitidentifier(), _Py_gitversion())); + SET_SYS_FROM_STRING("_framework", PyUnicode_FromString(PYTHONFRAMEWORK)); SET_SYS_FROM_STRING("api_version", PyLong_FromLong(PYTHON_API_VERSION)); SET_SYS_FROM_STRING("copyright", diff --git a/configure b/configure index ec42e08f8961c1..ff8152d7d19312 100755 --- a/configure +++ b/configure @@ -783,6 +783,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -896,6 +897,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1148,6 +1150,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1285,7 +1296,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1438,6 +1449,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -3231,6 +3243,12 @@ fi + +cat >>confdefs.h <<_ACEOF +#define PYTHONFRAMEWORK "${PYTHONFRAMEWORK}" +_ACEOF + + ##AC_ARG_WITH(dyld, ## AS_HELP_STRING([--with-dyld], ## [Use (OpenStep|Rhapsody) dynamic linker])) diff --git a/configure.ac b/configure.ac index 18b940ab329172..815769f534bedd 100644 --- a/configure.ac +++ b/configure.ac @@ -355,6 +355,8 @@ AC_SUBST(FRAMEWORKPYTHONW) AC_SUBST(FRAMEWORKUNIXTOOLSPREFIX) AC_SUBST(FRAMEWORKINSTALLAPPSPREFIX) +AC_DEFINE_UNQUOTED(PYTHONFRAMEWORK, "${PYTHONFRAMEWORK}", [framework name]) + ##AC_ARG_WITH(dyld, ## AS_HELP_STRING([--with-dyld], ## [Use (OpenStep|Rhapsody) dynamic linker])) diff --git a/pyconfig.h.in b/pyconfig.h.in index fa2792b18ad419..f7c50eadcafc12 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -1247,6 +1247,9 @@ /* Define as the preferred size in bits of long digits */ #undef PYLONG_BITS_IN_DIGIT +/* framework name */ +#undef PYTHONFRAMEWORK + /* Define if you want to coerce the C locale to a UTF-8 based locale */ #undef PY_COERCE_C_LOCALE pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy