[pypy-commit] pypy py3k: reapply our sysconfig modifications to 3.2

pjenvey noreply at buildbot.pypy.org
Thu Nov 10 03:21:46 CET 2011


Author: Philip Jenvey <pjenvey at underboss.org>
Branch: py3k
Changeset: r49073:d1ca09d10665
Date: 2011-11-09 18:20 -0800
http://bitbucket.org/pypy/pypy/changeset/d1ca09d10665/

Log:	reapply our sysconfig modifications to 3.2

diff --git a/lib-python/modified-3.2/sysconfig.py b/lib-python/modified-3.2/sysconfig.py
new file mode 100644
--- /dev/null
+++ b/lib-python/modified-3.2/sysconfig.py
@@ -0,0 +1,625 @@
+"""Provide access to Python's configuration information.
+
+"""
+import sys
+import os
+from os.path import pardir, realpath
+
+__all__ = [
+    'get_config_h_filename',
+    'get_config_var',
+    'get_config_vars',
+    'get_makefile_filename',
+    'get_path',
+    'get_path_names',
+    'get_paths',
+    'get_platform',
+    'get_python_version',
+    'get_scheme_names',
+    'parse_config_h',
+    ]
+
+_INSTALL_SCHEMES = {
+    'posix_prefix': {
+        'stdlib': '{base}/lib/python{py_version_short}',
+        'platstdlib': '{platbase}/lib/python{py_version_short}',
+        'purelib': '{base}/lib/python{py_version_short}/site-packages',
+        'platlib': '{platbase}/lib/python{py_version_short}/site-packages',
+        'include':
+            '{base}/include/python{py_version_short}{abiflags}',
+        'platinclude':
+            '{platbase}/include/python{py_version_short}{abiflags}',
+        'scripts': '{base}/bin',
+        'data': '{base}',
+        },
+    'posix_home': {
+        'stdlib': '{base}/lib/python',
+        'platstdlib': '{base}/lib/python',
+        'purelib': '{base}/lib/python',
+        'platlib': '{base}/lib/python',
+        'include': '{base}/include/python',
+        'platinclude': '{base}/include/python',
+        'scripts': '{base}/bin',
+        'data'   : '{base}',
+        },
+    'pypy': {
+        'stdlib': '{base}/lib-python',
+        'platstdlib': '{base}/lib-python',
+        'purelib': '{base}/lib-python',
+        'platlib': '{base}/lib-python',
+        'include': '{base}/include',
+        'platinclude': '{base}/include',
+        'scripts': '{base}/bin',
+        'data'   : '{base}',
+        },
+    'nt': {
+        'stdlib': '{base}/Lib',
+        'platstdlib': '{base}/Lib',
+        'purelib': '{base}/Lib/site-packages',
+        'platlib': '{base}/Lib/site-packages',
+        'include': '{base}/Include',
+        'platinclude': '{base}/Include',
+        'scripts': '{base}/Scripts',
+        'data'   : '{base}',
+        },
+    'os2': {
+        'stdlib': '{base}/Lib',
+        'platstdlib': '{base}/Lib',
+        'purelib': '{base}/Lib/site-packages',
+        'platlib': '{base}/Lib/site-packages',
+        'include': '{base}/Include',
+        'platinclude': '{base}/Include',
+        'scripts': '{base}/Scripts',
+        'data'   : '{base}',
+        },
+    'os2_home': {
+        'stdlib': '{userbase}/lib/python{py_version_short}',
+        'platstdlib': '{userbase}/lib/python{py_version_short}',
+        'purelib': '{userbase}/lib/python{py_version_short}/site-packages',
+        'platlib': '{userbase}/lib/python{py_version_short}/site-packages',
+        'include': '{userbase}/include/python{py_version_short}',
+        'scripts': '{userbase}/bin',
+        'data'   : '{userbase}',
+        },
+    'nt_user': {
+        'stdlib': '{userbase}/Python{py_version_nodot}',
+        'platstdlib': '{userbase}/Python{py_version_nodot}',
+        'purelib': '{userbase}/Python{py_version_nodot}/site-packages',
+        'platlib': '{userbase}/Python{py_version_nodot}/site-packages',
+        'include': '{userbase}/Python{py_version_nodot}/Include',
+        'scripts': '{userbase}/Scripts',
+        'data'   : '{userbase}',
+        },
+    'posix_user': {
+        'stdlib': '{userbase}/lib/python{py_version_short}',
+        'platstdlib': '{userbase}/lib/python{py_version_short}',
+        'purelib': '{userbase}/lib/python{py_version_short}/site-packages',
+        'platlib': '{userbase}/lib/python{py_version_short}/site-packages',
+        'include': '{userbase}/include/python{py_version_short}',
+        'scripts': '{userbase}/bin',
+        'data'   : '{userbase}',
+        },
+    'osx_framework_user': {
+        'stdlib': '{userbase}/lib/python',
+        'platstdlib': '{userbase}/lib/python',
+        'purelib': '{userbase}/lib/python/site-packages',
+        'platlib': '{userbase}/lib/python/site-packages',
+        'include': '{userbase}/include',
+        'scripts': '{userbase}/bin',
+        'data'   : '{userbase}',
+        },
+    }
+
+_SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include',
+                'scripts', 'data')
+_PY_VERSION = sys.version.split()[0]
+_PY_VERSION_SHORT = sys.version[:3]
+_PY_VERSION_SHORT_NO_DOT = _PY_VERSION[0] + _PY_VERSION[2]
+_PREFIX = os.path.normpath(sys.prefix)
+_EXEC_PREFIX = os.path.normpath(sys.exec_prefix)
+_CONFIG_VARS = None
+_USER_BASE = None
+
+def _safe_realpath(path):
+    try:
+        return realpath(path)
+    except OSError:
+        return path
+
+if sys.executable:
+    _PROJECT_BASE = os.path.dirname(_safe_realpath(sys.executable))
+else:
+    # sys.executable can be empty if argv[0] has been changed and Python is
+    # unable to retrieve the real program name
+    _PROJECT_BASE = _safe_realpath(os.getcwd())
+
+if os.name == "nt" and "pcbuild" in _PROJECT_BASE[-8:].lower():
+    _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir))
+# PC/VS7.1
+if os.name == "nt" and "\\pc\\v" in _PROJECT_BASE[-10:].lower():
+    _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir))
+# PC/AMD64
+if os.name == "nt" and "\\pcbuild\\amd64" in _PROJECT_BASE[-14:].lower():
+    _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir))
+
+def is_python_build():
+    for fn in ("Setup.dist", "Setup.local"):
+        if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)):
+            return True
+    return False
+
+_PYTHON_BUILD = is_python_build()
+
+if _PYTHON_BUILD:
+    for scheme in ('posix_prefix', 'posix_home'):
+        _INSTALL_SCHEMES[scheme]['include'] = '{srcdir}/Include'
+        _INSTALL_SCHEMES[scheme]['platinclude'] = '{projectbase}/.'
+
+def _subst_vars(s, local_vars):
+    try:
+        return s.format(**local_vars)
+    except KeyError:
+        try:
+            return s.format(**os.environ)
+        except KeyError as var:
+            raise AttributeError('{%s}' % var)
+
+def _extend_dict(target_dict, other_dict):
+    target_keys = target_dict.keys()
+    for key, value in other_dict.items():
+        if key in target_keys:
+            continue
+        target_dict[key] = value
+
+def _expand_vars(scheme, vars):
+    res = {}
+    if vars is None:
+        vars = {}
+    _extend_dict(vars, get_config_vars())
+
+    for key, value in _INSTALL_SCHEMES[scheme].items():
+        if os.name in ('posix', 'nt'):
+            value = os.path.expanduser(value)
+        res[key] = os.path.normpath(_subst_vars(value, vars))
+    return res
+
+def _get_default_scheme():
+    if '__pypy__' in sys.builtin_module_names:
+        return 'pypy'
+    elif os.name == 'posix':
+        # the default scheme for posix is posix_prefix
+        return 'posix_prefix'
+    return os.name
+
+def _getuserbase():
+    env_base = os.environ.get("PYTHONUSERBASE", None)
+    def joinuser(*args):
+        return os.path.expanduser(os.path.join(*args))
+
+    # what about 'os2emx', 'riscos' ?
+    if os.name == "nt":
+        base = os.environ.get("APPDATA") or "~"
+        return env_base if env_base else joinuser(base, "Python")
+
+    if sys.platform == "darwin":
+        framework = get_config_var("PYTHONFRAMEWORK")
+        if framework:
+            return env_base if env_base else joinuser("~", "Library", framework, "%d.%d"%(
+                sys.version_info[:2]))
+
+    return env_base if env_base else joinuser("~", ".local")
+
+
+def _init_posix(vars):
+    """Initialize the module as appropriate for POSIX systems."""
+    return
+
+def _init_non_posix(vars):
+    """Initialize the module as appropriate for NT"""
+    # set basic install directories
+    vars['LIBDEST'] = get_path('stdlib')
+    vars['BINLIBDEST'] = get_path('platstdlib')
+    vars['INCLUDEPY'] = get_path('include')
+    vars['SO'] = '.pyd'
+    vars['EXE'] = '.exe'
+    vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT
+    vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable))
+
+#
+# public APIs
+#
+
+
+def parse_config_h(fp, vars=None):
+    """Parse a config.h-style file.
+
+    A dictionary containing name/value pairs is returned.  If an
+    optional dictionary is passed in as the second argument, it is
+    used instead of a new dictionary.
+    """
+    import re
+    if vars is None:
+        vars = {}
+    define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n")
+    undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n")
+
+    while True:
+        line = fp.readline()
+        if not line:
+            break
+        m = define_rx.match(line)
+        if m:
+            n, v = m.group(1, 2)
+            try: v = int(v)
+            except ValueError: pass
+            vars[n] = v
+        else:
+            m = undef_rx.match(line)
+            if m:
+                vars[m.group(1)] = 0
+    return vars
+
+def get_config_h_filename():
+    """Return the path of pyconfig.h."""
+    if _PYTHON_BUILD:
+        if os.name == "nt":
+            inc_dir = os.path.join(_PROJECT_BASE, "PC")
+        else:
+            inc_dir = _PROJECT_BASE
+    else:
+        inc_dir = get_path('platinclude')
+    return os.path.join(inc_dir, 'pyconfig.h')
+
+def get_scheme_names():
+    """Return a tuple containing the schemes names."""
+    schemes = list(_INSTALL_SCHEMES.keys())
+    schemes.sort()
+    return tuple(schemes)
+
+def get_path_names():
+    """Return a tuple containing the paths names."""
+    return _SCHEME_KEYS
+
+def get_paths(scheme=_get_default_scheme(), vars=None, expand=True):
+    """Return a mapping containing an install scheme.
+
+    ``scheme`` is the install scheme name. If not provided, it will
+    return the default scheme for the current platform.
+    """
+    if expand:
+        return _expand_vars(scheme, vars)
+    else:
+        return _INSTALL_SCHEMES[scheme]
+
+def get_path(name, scheme=_get_default_scheme(), vars=None, expand=True):
+    """Return a path corresponding to the scheme.
+
+    ``scheme`` is the install scheme name.
+    """
+    return get_paths(scheme, vars, expand)[name]
+
+def get_config_vars(*args):
+    """With no arguments, return a dictionary of all configuration
+    variables relevant for the current platform.
+
+    On Unix, this means every variable defined in Python's installed Makefile;
+    On Windows and Mac OS it's a much smaller set.
+
+    With arguments, return a list of values that result from looking up
+    each argument in the configuration variable dictionary.
+    """
+    import re
+    global _CONFIG_VARS
+    if _CONFIG_VARS is None:
+        _CONFIG_VARS = {}
+        # Normalized versions of prefix and exec_prefix are handy to have;
+        # in fact, these are the standard versions used most places in the
+        # Distutils.
+        _CONFIG_VARS['prefix'] = _PREFIX
+        _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX
+        _CONFIG_VARS['py_version'] = _PY_VERSION
+        _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT
+        _CONFIG_VARS['py_version_nodot'] = _PY_VERSION[0] + _PY_VERSION[2]
+        _CONFIG_VARS['base'] = _PREFIX
+        _CONFIG_VARS['platbase'] = _EXEC_PREFIX
+        _CONFIG_VARS['projectbase'] = _PROJECT_BASE
+        try:
+            _CONFIG_VARS['abiflags'] = sys.abiflags
+        except AttributeError:
+            # sys.abiflags may not be defined on all platforms.
+            _CONFIG_VARS['abiflags'] = ''
+
+        if os.name in ('nt', 'os2'):
+            _init_non_posix(_CONFIG_VARS)
+        if os.name == 'posix':
+            _init_posix(_CONFIG_VARS)
+        # Setting 'userbase' is done below the call to the
+        # init function to enable using 'get_config_var' in
+        # the init-function.
+        _CONFIG_VARS['userbase'] = _getuserbase()
+
+        if 'srcdir' not in _CONFIG_VARS:
+            _CONFIG_VARS['srcdir'] = _PROJECT_BASE
+        else:
+            _CONFIG_VARS['srcdir'] = _safe_realpath(_CONFIG_VARS['srcdir'])
+
+
+        # Convert srcdir into an absolute path if it appears necessary.
+        # Normally it is relative to the build directory.  However, during
+        # testing, for example, we might be running a non-installed python
+        # from a different directory.
+        if _PYTHON_BUILD and os.name == "posix":
+            base = _PROJECT_BASE
+            try:
+                cwd = os.getcwd()
+            except OSError:
+                cwd = None
+            if (not os.path.isabs(_CONFIG_VARS['srcdir']) and
+                base != cwd):
+                # srcdir is relative and we are not in the same directory
+                # as the executable. Assume executable is in the build
+                # directory and make srcdir absolute.
+                srcdir = os.path.join(base, _CONFIG_VARS['srcdir'])
+                _CONFIG_VARS['srcdir'] = os.path.normpath(srcdir)
+
+        if sys.platform == 'darwin':
+            kernel_version = os.uname()[2] # Kernel version (8.4.3)
+            major_version = int(kernel_version.split('.')[0])
+
+            if major_version < 8:
+                # On Mac OS X before 10.4, check if -arch and -isysroot
+                # are in CFLAGS or LDFLAGS and remove them if they are.
+                # This is needed when building extensions on a 10.3 system
+                # using a universal build of python.
+                for key in ('LDFLAGS', 'BASECFLAGS',
+                        # a number of derived variables. These need to be
+                        # patched up as well.
+                        'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
+                    flags = _CONFIG_VARS[key]
+                    flags = re.sub('-arch\s+\w+\s', ' ', flags)
+                    flags = re.sub('-isysroot [^ \t]*', ' ', flags)
+                    _CONFIG_VARS[key] = flags
+            else:
+                # Allow the user to override the architecture flags using
+                # an environment variable.
+                # NOTE: This name was introduced by Apple in OSX 10.5 and
+                # is used by several scripting languages distributed with
+                # that OS release.
+                if 'ARCHFLAGS' in os.environ:
+                    arch = os.environ['ARCHFLAGS']
+                    for key in ('LDFLAGS', 'BASECFLAGS',
+                        # a number of derived variables. These need to be
+                        # patched up as well.
+                        'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
+
+                        flags = _CONFIG_VARS[key]
+                        flags = re.sub('-arch\s+\w+\s', ' ', flags)
+                        flags = flags + ' ' + arch
+                        _CONFIG_VARS[key] = flags
+
+                # If we're on OSX 10.5 or later and the user tries to
+                # compiles an extension using an SDK that is not present
+                # on the current machine it is better to not use an SDK
+                # than to fail.
+                #
+                # The major usecase for this is users using a Python.org
+                # binary installer  on OSX 10.6: that installer uses
+                # the 10.4u SDK, but that SDK is not installed by default
+                # when you install Xcode.
+                #
+                CFLAGS = _CONFIG_VARS.get('CFLAGS', '')
+                m = re.search('-isysroot\s+(\S+)', CFLAGS)
+                if m is not None:
+                    sdk = m.group(1)
+                    if not os.path.exists(sdk):
+                        for key in ('LDFLAGS', 'BASECFLAGS',
+                             # a number of derived variables. These need to be
+                             # patched up as well.
+                            'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
+
+                            flags = _CONFIG_VARS[key]
+                            flags = re.sub('-isysroot\s+\S+(\s|$)', ' ', flags)
+                            _CONFIG_VARS[key] = flags
+
+    if args:
+        vals = []
+        for name in args:
+            vals.append(_CONFIG_VARS.get(name))
+        return vals
+    else:
+        return _CONFIG_VARS
+
+def get_config_var(name):
+    """Return the value of a single variable using the dictionary returned by
+    'get_config_vars()'.
+
+    Equivalent to get_config_vars().get(name)
+    """
+    return get_config_vars().get(name)
+
+def get_platform():
+    """Return a string that identifies the current platform.
+
+    This is used mainly to distinguish platform-specific build directories and
+    platform-specific built distributions.  Typically includes the OS name
+    and version and the architecture (as supplied by 'os.uname()'),
+    although the exact information included depends on the OS; eg. for IRIX
+    the architecture isn't particularly important (IRIX only runs on SGI
+    hardware), but for Linux the kernel version isn't particularly
+    important.
+
+    Examples of returned values:
+       linux-i586
+       linux-alpha (?)
+       solaris-2.6-sun4u
+       irix-5.3
+       irix64-6.2
+
+    Windows will return one of:
+       win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc)
+       win-ia64 (64bit Windows on Itanium)
+       win32 (all others - specifically, sys.platform is returned)
+
+    For other non-POSIX platforms, currently just returns 'sys.platform'.
+    """
+    import re
+    if os.name == 'nt':
+        # sniff sys.version for architecture.
+        prefix = " bit ("
+        i = sys.version.find(prefix)
+        if i == -1:
+            return sys.platform
+        j = sys.version.find(")", i)
+        look = sys.version[i+len(prefix):j].lower()
+        if look == 'amd64':
+            return 'win-amd64'
+        if look == 'itanium':
+            return 'win-ia64'
+        return sys.platform
+
+    if os.name != "posix" or not hasattr(os, 'uname'):
+        # XXX what about the architecture? NT is Intel or Alpha,
+        # Mac OS is M68k or PPC, etc.
+        return sys.platform
+
+    # Try to distinguish various flavours of Unix
+    osname, host, release, version, machine = os.uname()
+
+    # Convert the OS name to lowercase, remove '/' characters
+    # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh")
+    osname = osname.lower().replace('/', '')
+    machine = machine.replace(' ', '_')
+    machine = machine.replace('/', '-')
+
+    if osname[:5] == "linux":
+        # At least on Linux/Intel, 'machine' is the processor --
+        # i386, etc.
+        # XXX what about Alpha, SPARC, etc?
+        return  "%s-%s" % (osname, machine)
+    elif osname[:5] == "sunos":
+        if release[0] >= "5":           # SunOS 5 == Solaris 2
+            osname = "solaris"
+            release = "%d.%s" % (int(release[0]) - 3, release[2:])
+        # fall through to standard osname-release-machine representation
+    elif osname[:4] == "irix":              # could be "irix64"!
+        return "%s-%s" % (osname, release)
+    elif osname[:3] == "aix":
+        return "%s-%s.%s" % (osname, version, release)
+    elif osname[:6] == "cygwin":
+        osname = "cygwin"
+        rel_re = re.compile (r'[\d.]+')
+        m = rel_re.match(release)
+        if m:
+            release = m.group()
+    elif osname[:6] == "darwin":
+        #
+        # For our purposes, we'll assume that the system version from
+        # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set
+        # to. This makes the compatibility story a bit more sane because the
+        # machine is going to compile and link as if it were
+        # MACOSX_DEPLOYMENT_TARGET.
+        #
+        cfgvars = get_config_vars()
+        macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET')
+
+        if 1:
+            # Always calculate the release of the running machine,
+            # needed to determine if we can build fat binaries or not.
+
+            macrelease = macver
+            # Get the system version. Reading this plist is a documented
+            # way to get the system version (see the documentation for
+            # the Gestalt Manager)
+            try:
+                f = open('/System/Library/CoreServices/SystemVersion.plist')
+            except IOError:
+                # We're on a plain darwin box, fall back to the default
+                # behaviour.
+                pass
+            else:
+                try:
+                    m = re.search(
+                            r'<key>ProductUserVisibleVersion</key>\s*' +
+                            r'<string>(.*?)</string>', f.read())
+                    if m is not None:
+                        macrelease = '.'.join(m.group(1).split('.')[:2])
+                    # else: fall back to the default behaviour
+                finally:
+                    f.close()
+
+        if not macver:
+            macver = macrelease
+
+        if macver:
+            release = macver
+            osname = "macosx"
+
+            if (macrelease + '.') >= '10.4.' and \
+                    '-arch' in get_config_vars().get('CFLAGS', '').strip():
+                # The universal build will build fat binaries, but not on
+                # systems before 10.4
+                #
+                # Try to detect 4-way universal builds, those have machine-type
+                # 'universal' instead of 'fat'.
+
+                machine = 'fat'
+                cflags = get_config_vars().get('CFLAGS')
+
+                archs = re.findall('-arch\s+(\S+)', cflags)
+                archs = tuple(sorted(set(archs)))
+
+                if len(archs) == 1:
+                    machine = archs[0]
+                elif archs == ('i386', 'ppc'):
+                    machine = 'fat'
+                elif archs == ('i386', 'x86_64'):
+                    machine = 'intel'
+                elif archs == ('i386', 'ppc', 'x86_64'):
+                    machine = 'fat3'
+                elif archs == ('ppc64', 'x86_64'):
+                    machine = 'fat64'
+                elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'):
+                    machine = 'universal'
+                else:
+                    raise ValueError(
+                       "Don't know machine value for archs=%r"%(archs,))
+
+            elif machine == 'i386':
+                # On OSX the machine type returned by uname is always the
+                # 32-bit variant, even if the executable architecture is
+                # the 64-bit variant
+                if sys.maxsize >= 2**32:
+                    machine = 'x86_64'
+
+            elif machine in ('PowerPC', 'Power_Macintosh'):
+                # Pick a sane name for the PPC architecture.
+                # See 'i386' case
+                if sys.maxsize >= 2**32:
+                    machine = 'ppc64'
+                else:
+                    machine = 'ppc'
+
+    return "%s-%s-%s" % (osname, release, machine)
+
+
+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:
+            print('{0}: '.format(title))
+        print('\t{0} = "{1}"'.format(key, value))
+
+def _main():
+    """Display all information sysconfig detains."""
+    print('Platform: "{0}"'.format(get_platform()))
+    print('Python version: "{0}"'.format(get_python_version()))
+    print('Current installation scheme: "{0}"'.format(_get_default_scheme()))
+    print('')
+    _print_dict('Paths', get_paths())
+    print('')
+    _print_dict('Variables', get_config_vars())
+
+if __name__ == '__main__':
+    _main()
diff --git a/lib-python/modified-3.2/test/test_sysconfig.py b/lib-python/modified-3.2/test/test_sysconfig.py
new file mode 100644
--- /dev/null
+++ b/lib-python/modified-3.2/test/test_sysconfig.py
@@ -0,0 +1,362 @@
+"""Tests for 'site'.
+
+Tests assume the initial paths in sys.path once the interpreter has begun
+executing have not been removed.
+
+"""
+import unittest
+import sys
+import os
+import subprocess
+import shutil
+from copy import copy, deepcopy
+
+from test.support import (run_unittest, TESTFN, unlink, get_attribute,
+                          captured_stdout, skip_unless_symlink)
+
+import sysconfig
+from sysconfig import (get_paths, get_platform, get_config_vars,
+                       get_path, get_path_names, _INSTALL_SCHEMES,
+                       _get_default_scheme, _expand_vars,
+                       get_scheme_names, get_config_var, _main)
+
+class TestSysConfig(unittest.TestCase):
+
+    def setUp(self):
+        """Make a copy of sys.path"""
+        super(TestSysConfig, self).setUp()
+        self.sys_path = sys.path[:]
+        # patching os.uname
+        if hasattr(os, 'uname'):
+            self.uname = os.uname
+            self._uname = os.uname()
+        else:
+            self.uname = None
+            self._uname = None
+        os.uname = self._get_uname
+        # saving the environment
+        self.name = os.name
+        self.platform = sys.platform
+        self.version = sys.version
+        self.sep = os.sep
+        self.join = os.path.join
+        self.isabs = os.path.isabs
+        self.splitdrive = os.path.splitdrive
+        self._config_vars = copy(sysconfig._CONFIG_VARS)
+        self.old_environ = deepcopy(os.environ)
+
+    def tearDown(self):
+        """Restore sys.path"""
+        sys.path[:] = self.sys_path
+        self._cleanup_testfn()
+        if self.uname is not None:
+            os.uname = self.uname
+        else:
+            del os.uname
+        os.name = self.name
+        sys.platform = self.platform
+        sys.version = self.version
+        os.sep = self.sep
+        os.path.join = self.join
+        os.path.isabs = self.isabs
+        os.path.splitdrive = self.splitdrive
+        sysconfig._CONFIG_VARS = copy(self._config_vars)
+        for key, value in self.old_environ.items():
+            if os.environ.get(key) != value:
+                os.environ[key] = value
+
+        for key in list(os.environ.keys()):
+            if key not in self.old_environ:
+                del os.environ[key]
+
+        super(TestSysConfig, self).tearDown()
+
+    def _set_uname(self, uname):
+        self._uname = uname
+
+    def _get_uname(self):
+        return self._uname
+
+    def _cleanup_testfn(self):
+        path = TESTFN
+        if os.path.isfile(path):
+            os.remove(path)
+        elif os.path.isdir(path):
+            shutil.rmtree(path)
+
+    def test_get_path_names(self):
+        self.assertEqual(get_path_names(), sysconfig._SCHEME_KEYS)
+
+    def test_get_paths(self):
+        scheme = get_paths()
+        default_scheme = _get_default_scheme()
+        wanted = _expand_vars(default_scheme, None)
+        wanted = list(wanted.items())
+        wanted.sort()
+        scheme = list(scheme.items())
+        scheme.sort()
+        self.assertEqual(scheme, wanted)
+
+    def test_get_path(self):
+        # xxx make real tests here
+        for scheme in _INSTALL_SCHEMES:
+            for name in _INSTALL_SCHEMES[scheme]:
+                res = get_path(name, scheme)
+
+    def test_get_config_vars(self):
+        cvars = get_config_vars()
+        self.assertTrue(isinstance(cvars, dict))
+        self.assertTrue(cvars)
+
+    def test_get_platform(self):
+        # windows XP, 32bits
+        os.name = 'nt'
+        sys.version = ('2.4.4 (#71, Oct 18 2006, 08:34:43) '
+                       '[MSC v.1310 32 bit (Intel)]')
+        sys.platform = 'win32'
+        self.assertEqual(get_platform(), 'win32')
+
+        # windows XP, amd64
+        os.name = 'nt'
+        sys.version = ('2.4.4 (#71, Oct 18 2006, 08:34:43) '
+                       '[MSC v.1310 32 bit (Amd64)]')
+        sys.platform = 'win32'
+        self.assertEqual(get_platform(), 'win-amd64')
+
+        # windows XP, itanium
+        os.name = 'nt'
+        sys.version = ('2.4.4 (#71, Oct 18 2006, 08:34:43) '
+                       '[MSC v.1310 32 bit (Itanium)]')
+        sys.platform = 'win32'
+        self.assertEqual(get_platform(), 'win-ia64')
+
+        # macbook
+        os.name = 'posix'
+        sys.version = ('2.5 (r25:51918, Sep 19 2006, 08:49:13) '
+                       '\n[GCC 4.0.1 (Apple Computer, Inc. build 5341)]')
+        sys.platform = 'darwin'
+        self._set_uname(('Darwin', 'macziade', '8.11.1',
+                   ('Darwin Kernel Version 8.11.1: '
+                    'Wed Oct 10 18:23:28 PDT 2007; '
+                    'root:xnu-792.25.20~1/RELEASE_I386'), 'PowerPC'))
+
+
+        get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.3'
+
+        get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g '
+                                       '-fwrapv -O3 -Wall -Wstrict-prototypes')
+
+        maxint = sys.maxsize
+        try:
+            sys.maxsize = 2147483647
+            self.assertEqual(get_platform(), 'macosx-10.3-ppc')
+            sys.maxsize = 9223372036854775807
+            self.assertEqual(get_platform(), 'macosx-10.3-ppc64')
+        finally:
+            sys.maxsize = maxint
+
+
+        self._set_uname(('Darwin', 'macziade', '8.11.1',
+                   ('Darwin Kernel Version 8.11.1: '
+                    'Wed Oct 10 18:23:28 PDT 2007; '
+                    'root:xnu-792.25.20~1/RELEASE_I386'), 'i386'))
+        get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.3'
+        get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.3'
+
+        get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g '
+                                       '-fwrapv -O3 -Wall -Wstrict-prototypes')
+        maxint = sys.maxsize
+        try:
+            sys.maxsize = 2147483647
+            self.assertEqual(get_platform(), 'macosx-10.3-i386')
+            sys.maxsize = 9223372036854775807
+            self.assertEqual(get_platform(), 'macosx-10.3-x86_64')
+        finally:
+            sys.maxsize = maxint
+
+        # macbook with fat binaries (fat, universal or fat64)
+        get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.4'
+        get_config_vars()['CFLAGS'] = ('-arch ppc -arch i386 -isysroot '
+                                       '/Developer/SDKs/MacOSX10.4u.sdk  '
+                                       '-fno-strict-aliasing -fno-common '
+                                       '-dynamic -DNDEBUG -g -O3')
+
+        self.assertEqual(get_platform(), 'macosx-10.4-fat')
+
+        get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch i386 -isysroot '
+                                       '/Developer/SDKs/MacOSX10.4u.sdk  '
+                                       '-fno-strict-aliasing -fno-common '
+                                       '-dynamic -DNDEBUG -g -O3')
+
+        self.assertEqual(get_platform(), 'macosx-10.4-intel')
+
+        get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch ppc -arch i386 -isysroot '
+                                       '/Developer/SDKs/MacOSX10.4u.sdk  '
+                                       '-fno-strict-aliasing -fno-common '
+                                       '-dynamic -DNDEBUG -g -O3')
+        self.assertEqual(get_platform(), 'macosx-10.4-fat3')
+
+        get_config_vars()['CFLAGS'] = ('-arch ppc64 -arch x86_64 -arch ppc -arch i386 -isysroot '
+                                       '/Developer/SDKs/MacOSX10.4u.sdk  '
+                                       '-fno-strict-aliasing -fno-common '
+                                       '-dynamic -DNDEBUG -g -O3')
+        self.assertEqual(get_platform(), 'macosx-10.4-universal')
+
+        get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch ppc64 -isysroot '
+                                       '/Developer/SDKs/MacOSX10.4u.sdk  '
+                                       '-fno-strict-aliasing -fno-common '
+                                       '-dynamic -DNDEBUG -g -O3')
+
+        self.assertEqual(get_platform(), 'macosx-10.4-fat64')
+
+        for arch in ('ppc', 'i386', 'x86_64', 'ppc64'):
+            get_config_vars()['CFLAGS'] = ('-arch %s -isysroot '
+                                           '/Developer/SDKs/MacOSX10.4u.sdk  '
+                                           '-fno-strict-aliasing -fno-common '
+                                           '-dynamic -DNDEBUG -g -O3'%(arch,))
+
+            self.assertEqual(get_platform(), 'macosx-10.4-%s'%(arch,))
+
+        # linux debian sarge
+        os.name = 'posix'
+        sys.version = ('2.3.5 (#1, Jul  4 2007, 17:28:59) '
+                       '\n[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)]')
+        sys.platform = 'linux2'
+        self._set_uname(('Linux', 'aglae', '2.6.21.1dedibox-r7',
+                    '#1 Mon Apr 30 17:25:38 CEST 2007', 'i686'))
+
+        self.assertEqual(get_platform(), 'linux-i686')
+
+        # XXX more platforms to tests here
+
+    def test_get_config_h_filename(self):
+        config_h = sysconfig.get_config_h_filename()
+        self.assertTrue(os.path.isfile(config_h), config_h)
+
+    def test_get_scheme_names(self):
+        wanted = ('nt', 'nt_user', 'os2', 'os2_home', 'osx_framework_user',
+                  'posix_home', 'posix_prefix', 'posix_user', 'pypy')
+        self.assertEqual(get_scheme_names(), wanted)
+
+    @skip_unless_symlink
+    def test_symlink(self):
+        # On Windows, the EXE needs to know where pythonXY.dll is at so we have
+        # to add the directory to the path.
+        if sys.platform == "win32":
+            os.environ["Path"] = "{};{}".format(
+                os.path.dirname(sys.executable), os.environ["Path"])
+
+        # Issue 7880
+        def get(python):
+            cmd = [python, '-c',
+                   'import sysconfig; print(sysconfig.get_platform())']
+            p = subprocess.Popen(cmd, stdout=subprocess.PIPE, env=os.environ)
+            return p.communicate()
+        real = os.path.realpath(sys.executable)
+        link = os.path.abspath(TESTFN)
+        os.symlink(real, link)
+        try:
+            self.assertEqual(get(real), get(link))
+        finally:
+            unlink(link)
+
+    def test_user_similar(self):
+        # Issue 8759 : make sure the posix scheme for the users
+        # is similar to the global posix_prefix one
+        base = get_config_var('base')
+        user = get_config_var('userbase')
+        for name in ('stdlib', 'platstdlib', 'purelib', 'platlib'):
+            global_path = get_path(name, 'posix_prefix')
+            user_path = get_path(name, 'posix_user')
+            self.assertEqual(user_path, global_path.replace(base, user))
+
+    def test_main(self):
+        # just making sure _main() runs and returns things in the stdout
+        with captured_stdout() as output:
+            _main()
+        self.assertTrue(len(output.getvalue().split('\n')) > 0)
+
+    @unittest.skipIf(sys.platform == "win32", "Does not apply to Windows")
+    def test_ldshared_value(self):
+        ldflags = sysconfig.get_config_var('LDFLAGS')
+        ldshared = sysconfig.get_config_var('LDSHARED')
+
+        self.assertIn(ldflags, ldshared)
+
+
+    @unittest.skipUnless(sys.platform == "darwin", "test only relevant on MacOSX")
+    def test_platform_in_subprocess(self):
+        my_platform = sysconfig.get_platform()
+
+        # Test without MACOSX_DEPLOYMENT_TARGET in the environment
+
+        env = os.environ.copy()
+        if 'MACOSX_DEPLOYMENT_TARGET' in env:
+            del env['MACOSX_DEPLOYMENT_TARGET']
+
+        with open('/dev/null', 'w') as devnull_fp:
+            p = subprocess.Popen([
+                    sys.executable, '-c',
+                    'import sysconfig; print(sysconfig.get_platform())',
+                ],
+                stdout=subprocess.PIPE,
+                stderr=devnull_fp,
+                env=env)
+        test_platform = p.communicate()[0].strip()
+        test_platform = test_platform.decode('utf-8')
+        status = p.wait()
+
+        self.assertEqual(status, 0)
+        self.assertEqual(my_platform, test_platform)
+
+
+        # Test with MACOSX_DEPLOYMENT_TARGET in the environment, and
+        # using a value that is unlikely to be the default one.
+        env = os.environ.copy()
+        env['MACOSX_DEPLOYMENT_TARGET'] = '10.1'
+
+        p = subprocess.Popen([
+                sys.executable, '-c',
+                'import sysconfig; print(sysconfig.get_platform())',
+            ],
+            stdout=subprocess.PIPE,
+            stderr=open('/dev/null'),
+            env=env)
+        test_platform = p.communicate()[0].strip()
+        test_platform = test_platform.decode('utf-8')
+        status = p.wait()
+
+        self.assertEqual(status, 0)
+        self.assertEqual(my_platform, test_platform)
+
+
+class MakefileTests(unittest.TestCase):
+    @unittest.skipIf(sys.platform.startswith('win'),
+                     'Test is not Windows compatible')
+    def test_get_makefile_filename(self):
+        makefile = sysconfig.get_makefile_filename()
+        self.assertTrue(os.path.isfile(makefile), makefile)
+
+    def test_parse_makefile(self):
+        self.addCleanup(unlink, TESTFN)
+        with open(TESTFN, "w") as makefile:
+            print("var1=a$(VAR2)", file=makefile)
+            print("VAR2=b$(var3)", file=makefile)
+            print("var3=42", file=makefile)
+            print("var4=$/invalid", file=makefile)
+            print("var5=dollar$$5", file=makefile)
+        vars = sysconfig._parse_makefile(TESTFN)
+        self.assertEqual(vars, {
+            'var1': 'ab42',
+            'VAR2': 'b42',
+            'var3': 42,
+            'var4': '$/invalid',
+            'var5': 'dollar$5',
+        })
+
+
+def test_main():
+    run_unittest(TestSysConfig, MakefileTests)
+
+if __name__ == "__main__":
+    test_main()


More information about the pypy-commit mailing list