cpython: 66e30c4870bb (original) (raw)
Mercurial > cpython
changeset 82872:66e30c4870bb 2.7
- Issue #13150: sysconfig no longer parses the Makefile and config.h files when imported, instead doing it at build time. This makes importing sysconfig faster and reduces Python startup time by 20%. [#13150]
doko@ubuntu.com | |
---|---|
date | Thu, 21 Mar 2013 15:02:16 -0700 |
parents | 71adf21421d9 |
children | d6336b2e4db6 |
files | Lib/distutils/sysconfig.py Lib/pprint.py Lib/sysconfig.py Makefile.pre.in Misc/NEWS |
diffstat | 5 files changed, 93 insertions(+), 66 deletions(-)[+] [-] Lib/distutils/sysconfig.py 63 Lib/pprint.py 5 Lib/sysconfig.py 75 Makefile.pre.in 12 Misc/NEWS 4 |
line wrap: on
line diff
--- a/Lib/distutils/sysconfig.py +++ b/Lib/distutils/sysconfig.py @@ -387,66 +387,11 @@ def expand_makefile_vars(s, vars): def _init_posix(): """Initialize the module as appropriate for POSIX systems."""
- g = {}
load the installed Makefile:
- try:
filename = get_makefile_filename()[](#l1.10)
parse_makefile(filename, g)[](#l1.11)
- except IOError, msg:
my_msg = "invalid Python installation: unable to open %s" % filename[](#l1.13)
if hasattr(msg, "strerror"):[](#l1.14)
my_msg = my_msg + " (%s)" % msg.strerror[](#l1.15)
raise DistutilsPlatformError(my_msg)[](#l1.17)
load the installed pyconfig.h:
- try:
filename = get_config_h_filename()[](#l1.21)
parse_config_h(file(filename), g)[](#l1.22)
- except IOError, msg:
my_msg = "invalid Python installation: unable to open %s" % filename[](#l1.24)
if hasattr(msg, "strerror"):[](#l1.25)
my_msg = my_msg + " (%s)" % msg.strerror[](#l1.26)
raise DistutilsPlatformError(my_msg)[](#l1.28)
On AIX, there are wrong paths to the linker scripts in the Makefile
-- these paths are relative to the Python source, but when installed
the scripts are in another directory.
- if python_build:
g['LDSHARED'] = g['BLDSHARED'][](#l1.34)
- elif get_python_version() < '2.1':
# The following two branches are for 1.5.2 compatibility.[](#l1.37)
if sys.platform == 'aix4': # what about AIX 3.x ?[](#l1.38)
# Linker script is in the config directory, not in Modules as the[](#l1.39)
# Makefile says.[](#l1.40)
python_lib = get_python_lib(standard_lib=1)[](#l1.41)
ld_so_aix = os.path.join(python_lib, 'config', 'ld_so_aix')[](#l1.42)
python_exp = os.path.join(python_lib, 'config', 'python.exp')[](#l1.43)
g['LDSHARED'] = "%s %s -bI:%s" % (ld_so_aix, g['CC'], python_exp)[](#l1.45)
elif sys.platform == 'beos':[](#l1.47)
# Linker script is in the config directory. In the Makefile it is[](#l1.48)
# relative to the srcdir, which after installation no longer makes[](#l1.49)
# sense.[](#l1.50)
python_lib = get_python_lib(standard_lib=1)[](#l1.51)
linkerscript_path = string.split(g['LDSHARED'])[0][](#l1.52)
linkerscript_name = os.path.basename(linkerscript_path)[](#l1.53)
linkerscript = os.path.join(python_lib, 'config',[](#l1.54)
linkerscript_name)[](#l1.55)
# XXX this isn't the right place to do this: adding the Python[](#l1.57)
# library to the link, if needed, should be in the "build_ext"[](#l1.58)
# command. (It's also needed for non-MS compilers on Windows, and[](#l1.59)
# it's taken care of for them by the 'build_ext.get_libraries()'[](#l1.60)
# method.)[](#l1.61)
g['LDSHARED'] = ("%s -L%s/lib -lpython%s" %[](#l1.62)
(linkerscript, PREFIX, get_python_version()))[](#l1.63)
_sysconfigdata is generated at build time, see the sysconfig module
- from _sysconfigdata import build_time_vars global _config_vars
--- a/Lib/pprint.py +++ b/Lib/pprint.py @@ -37,7 +37,10 @@ saferepr() import sys as _sys import warnings -from cStringIO import StringIO as _StringIO +try:
all = ["pprint","pformat","isreadable","isrecursive","saferepr", "PrettyPrinter"]
--- a/Lib/sysconfig.py +++ b/Lib/sysconfig.py @@ -278,9 +278,10 @@ def _get_makefile_filename(): return os.path.join(_PROJECT_BASE, "Makefile") return os.path.join(get_path('platstdlib'), "config", "Makefile") - -def _init_posix(vars):
- """Generate the Python module containing build-time variables."""
- import pprint
- vars = {}
makefile = _get_makefile_filename() load the installed Makefile: try: @@ -308,6 +309,49 @@ def _init_posix(vars): if _PYTHON_BUILD: vars['LDSHARED'] = vars['BLDSHARED']
There's a chicken-and-egg situation on OS X with regards to the
_sysconfigdata module after the changes introduced by #15298:
get_config_vars() is called by get_platform() as part of the
make pybuilddir.txt
target -- which is a precursor to the_sysconfigdata.py module being constructed. Unfortunately,
get_config_vars() eventually calls _init_posix(), which attempts
to import _sysconfigdata, which we won't have built yet. In order
for _init_posix() to work, if we're on Darwin, just mock up the
_sysconfigdata module manually and populate it with the build vars.
This is more than sufficient for ensuring the subsequent call to
get_platform() succeeds.
- name = '_sysconfigdata'
- if 'darwin' in sys.platform:
import imp[](#l3.34)
module = imp.new_module(name)[](#l3.35)
module.build_time_vars = vars[](#l3.36)
sys.modules[name] = module[](#l3.37)
- pybuilddir = 'build/lib.%s-%s' % (get_platform(), sys.version[:3])
- if hasattr(sys, "gettotalrefcount"):
pybuilddir += '-pydebug'[](#l3.41)
- try:
os.makedirs(pybuilddir)[](#l3.43)
- except OSError:
pass[](#l3.45)
- destfile = os.path.join(pybuilddir, name + '.py')
- with open(destfile, 'wb') as f:
f.write('# system configuration generated and used by'[](#l3.49)
' the sysconfig module\n')[](#l3.50)
f.write('build_time_vars = ')[](#l3.51)
pprint.pprint(vars, stream=f)[](#l3.52)
Create file used for sys.path fixup -- see Modules/getpath.c
- with open('pybuilddir.txt', 'w') as f:
f.write(pybuilddir)[](#l3.56)
- """Initialize the module as appropriate for POSIX systems."""
_sysconfigdata is generated at build time, see _generate_posix_vars()
- from _sysconfigdata import build_time_vars
- vars.update(build_time_vars)
+ def _init_non_posix(vars): """Initialize the module as appropriate for NT""" # set basic install directories @@ -565,3 +609,28 @@ def get_platform(): def get_python_version(): return _PY_VERSION_SHORT + + +def _print_dict(title, data):
- for index, (key, value) in enumerate(sorted(data.items())):
if index == 0:[](#l3.75)
print '%s: ' % (title)[](#l3.76)
print '\t%s = "%s"' % (key, value)[](#l3.77)
- """Display all information sysconfig detains."""
- if '--generate-posix-vars' in sys.argv:
_generate_posix_vars()[](#l3.83)
return[](#l3.84)
- print 'Platform: "%s"' % get_platform()
- print 'Python version: "%s"' % get_python_version()
- print 'Current installation scheme: "%s"' % _get_default_scheme()
- _print_dict('Paths', get_paths())
- _print_dict('Variables', get_config_vars())
--- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -437,15 +437,20 @@ coverage: Modules/python.o [](#l4.4) (BLDLIBRARY)(BLDLIBRARY) (BLDLIBRARY)(LIBS) (MODLIBS)(MODLIBS) (MODLIBS)(SYSLIBS) $(LDLAST) -platform: $(BUILDPYTHON) +platform: $(BUILDPYTHON) pybuilddir.txt (RUNSHARED)(RUNSHARED) (RUNSHARED)(PYTHON_FOR_BUILD) -c 'import sys ; from sysconfig import get_platform ; print get_platform()+"-"+sys.version[0:3]' >platform +# Create build directory and generate the sysconfig build-time data there. +# pybuilddir.txt contains the name of the build dir and is used for +# sys.path fixup -- see Modules/getpath.c. +pybuilddir.txt: $(BUILDPYTHON) + (RUNSHARED)(RUNSHARED) (RUNSHARED)(PYTHON_FOR_BUILD) -S -m sysconfig --generate-posix-vars
Build the shared modules
Under GNU make, MAKEFLAGS are sorted and normalized; the 's' for
-s, --silent or --quiet is always the first char.
Under BSD make, MAKEFLAGS might be " -s -v x=y".
-sharedmods: $(BUILDPYTHON)
+sharedmods: $(BUILDPYTHON) pybuilddir.txt
@case "$$MAKEFLAGS" in [](#l4.23)
\ -s|s*) quiet="-q";; [](#l4.24)
) quiet="";; [](#l4.25)
@@ -955,7 +960,7 @@ libinstall: build_all (srcdir)/Lib/(srcdir)/Lib/(srcdir)/Lib/(PL
else true; [](#l4.27)
fi; [](#l4.28)
done
- @for i in (srcdir)/Lib/∗.py(srcdir)/Lib/.py (srcdir)/Lib/∗.py(srcdir)/Lib/.doc $(srcdir)/Lib/.egg-info ; [](#l4.30)
+ @for i in (srcdir)/Lib/∗.py‘catpybuilddir.txt‘/sysconfigdata.py(srcdir)/Lib/.py cat pybuilddir.txt
/_sysconfigdata.py (srcdir)/Lib/∗.py‘catpybuilddir.txt‘/sysconfigdata.py(srcdir)/Lib/.doc $(srcdir)/Lib/.egg-info ; [](#l4.31)
do [](#l4.32)
if test -x i; then [](#l4.33)
(INSTALLSCRIPT)(INSTALL_SCRIPT) (INSTALLSCRIPT)$i (DESTDIR)(DESTDIR)(DESTDIR)(LIBDEST); [](#l4.34)
@@ -1133,6 +1138,7 @@ sharedinstall: sharedmods
--install-scripts=$(BINDIR) [](#l4.36)
--install-platlib=$(DESTSHARED) [](#l4.37)
--root=$(DESTDIR)/
+ -rm (DESTDIR)(DESTDIR)(DESTDIR)(DESTSHARED)/_sysconfigdata.py
Here are a couple of targets for MacOSX again, to install a full
framework-based Python. frameworkinstall installs everything, the
--- a/Misc/NEWS +++ b/Misc/NEWS @@ -216,6 +216,10 @@ Core and Builtins Library ------- +- Issue #13150: sysconfig no longer parses the Makefile and config.h files