+++ /dev/null
-"""Provide access to Python's configuration information.\r
-\r
-"""\r
-import sys\r
-import os\r
-from os.path import pardir, realpath\r
-\r
-_INSTALL_SCHEMES = {\r
- 'posix_prefix': {\r
- 'stdlib': '{base}/lib/python{py_version_short}',\r
- 'platstdlib': '{platbase}/lib/python{py_version_short}',\r
- 'purelib': '{base}/lib/python{py_version_short}/site-packages',\r
- 'platlib': '{platbase}/lib/python{py_version_short}/site-packages',\r
- 'include': '{base}/include/python{py_version_short}',\r
- 'platinclude': '{platbase}/include/python{py_version_short}',\r
- 'scripts': '{base}/bin',\r
- 'data': '{base}',\r
- },\r
- 'posix_home': {\r
- 'stdlib': '{base}/lib/python',\r
- 'platstdlib': '{base}/lib/python',\r
- 'purelib': '{base}/lib/python',\r
- 'platlib': '{base}/lib/python',\r
- 'include': '{base}/include/python',\r
- 'platinclude': '{base}/include/python',\r
- 'scripts': '{base}/bin',\r
- 'data' : '{base}',\r
- },\r
- 'nt': {\r
- 'stdlib': '{base}/Lib',\r
- 'platstdlib': '{base}/Lib',\r
- 'purelib': '{base}/Lib/site-packages',\r
- 'platlib': '{base}/Lib/site-packages',\r
- 'include': '{base}/Include',\r
- 'platinclude': '{base}/Include',\r
- 'scripts': '{base}/Scripts',\r
- 'data' : '{base}',\r
- },\r
- 'os2': {\r
- 'stdlib': '{base}/Lib',\r
- 'platstdlib': '{base}/Lib',\r
- 'purelib': '{base}/Lib/site-packages',\r
- 'platlib': '{base}/Lib/site-packages',\r
- 'include': '{base}/Include',\r
- 'platinclude': '{base}/Include',\r
- 'scripts': '{base}/Scripts',\r
- 'data' : '{base}',\r
- },\r
- 'os2_home': {\r
- 'stdlib': '{userbase}/lib/python{py_version_short}',\r
- 'platstdlib': '{userbase}/lib/python{py_version_short}',\r
- 'purelib': '{userbase}/lib/python{py_version_short}/site-packages',\r
- 'platlib': '{userbase}/lib/python{py_version_short}/site-packages',\r
- 'include': '{userbase}/include/python{py_version_short}',\r
- 'scripts': '{userbase}/bin',\r
- 'data' : '{userbase}',\r
- },\r
- 'nt_user': {\r
- 'stdlib': '{userbase}/Python{py_version_nodot}',\r
- 'platstdlib': '{userbase}/Python{py_version_nodot}',\r
- 'purelib': '{userbase}/Python{py_version_nodot}/site-packages',\r
- 'platlib': '{userbase}/Python{py_version_nodot}/site-packages',\r
- 'include': '{userbase}/Python{py_version_nodot}/Include',\r
- 'scripts': '{userbase}/Scripts',\r
- 'data' : '{userbase}',\r
- },\r
- 'posix_user': {\r
- 'stdlib': '{userbase}/lib/python{py_version_short}',\r
- 'platstdlib': '{userbase}/lib/python{py_version_short}',\r
- 'purelib': '{userbase}/lib/python{py_version_short}/site-packages',\r
- 'platlib': '{userbase}/lib/python{py_version_short}/site-packages',\r
- 'include': '{userbase}/include/python{py_version_short}',\r
- 'scripts': '{userbase}/bin',\r
- 'data' : '{userbase}',\r
- },\r
- 'osx_framework_user': {\r
- 'stdlib': '{userbase}/lib/python',\r
- 'platstdlib': '{userbase}/lib/python',\r
- 'purelib': '{userbase}/lib/python/site-packages',\r
- 'platlib': '{userbase}/lib/python/site-packages',\r
- 'include': '{userbase}/include',\r
- 'scripts': '{userbase}/bin',\r
- 'data' : '{userbase}',\r
- },\r
- }\r
-\r
-_SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include',\r
- 'scripts', 'data')\r
-_PY_VERSION = sys.version.split()[0]\r
-_PY_VERSION_SHORT = sys.version[:3]\r
-_PY_VERSION_SHORT_NO_DOT = _PY_VERSION[0] + _PY_VERSION[2]\r
-_PREFIX = os.path.normpath(sys.prefix)\r
-_EXEC_PREFIX = os.path.normpath(sys.exec_prefix)\r
-_CONFIG_VARS = None\r
-_USER_BASE = None\r
-\r
-def _safe_realpath(path):\r
- try:\r
- return realpath(path)\r
- except OSError:\r
- return path\r
-\r
-if sys.executable:\r
- _PROJECT_BASE = os.path.dirname(_safe_realpath(sys.executable))\r
-else:\r
- # sys.executable can be empty if argv[0] has been changed and Python is\r
- # unable to retrieve the real program name\r
- _PROJECT_BASE = _safe_realpath(os.getcwd())\r
-\r
-if os.name == "nt" and "pcbuild" in _PROJECT_BASE[-8:].lower():\r
- _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir))\r
-# PC/VS7.1\r
-if os.name == "nt" and "\\pc\\v" in _PROJECT_BASE[-10:].lower():\r
- _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir))\r
-# PC/AMD64\r
-if os.name == "nt" and "\\pcbuild\\amd64" in _PROJECT_BASE[-14:].lower():\r
- _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir))\r
-\r
-def is_python_build():\r
- for fn in ("Setup.dist", "Setup.local"):\r
- if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)):\r
- return True\r
- return False\r
-\r
-_PYTHON_BUILD = is_python_build()\r
-\r
-if _PYTHON_BUILD:\r
- for scheme in ('posix_prefix', 'posix_home'):\r
- _INSTALL_SCHEMES[scheme]['include'] = '{projectbase}/Include'\r
- _INSTALL_SCHEMES[scheme]['platinclude'] = '{srcdir}'\r
-\r
-def _subst_vars(s, local_vars):\r
- try:\r
- return s.format(**local_vars)\r
- except KeyError:\r
- try:\r
- return s.format(**os.environ)\r
- except KeyError, var:\r
- raise AttributeError('{%s}' % var)\r
-\r
-def _extend_dict(target_dict, other_dict):\r
- target_keys = target_dict.keys()\r
- for key, value in other_dict.items():\r
- if key in target_keys:\r
- continue\r
- target_dict[key] = value\r
-\r
-def _expand_vars(scheme, vars):\r
- res = {}\r
- if vars is None:\r
- vars = {}\r
- _extend_dict(vars, get_config_vars())\r
-\r
- for key, value in _INSTALL_SCHEMES[scheme].items():\r
- if os.name in ('posix', 'nt'):\r
- value = os.path.expanduser(value)\r
- res[key] = os.path.normpath(_subst_vars(value, vars))\r
- return res\r
-\r
-def _get_default_scheme():\r
- if os.name == 'posix':\r
- # the default scheme for posix is posix_prefix\r
- return 'posix_prefix'\r
- return os.name\r
-\r
-def _getuserbase():\r
- env_base = os.environ.get("PYTHONUSERBASE", None)\r
- def joinuser(*args):\r
- return os.path.expanduser(os.path.join(*args))\r
-\r
- # what about 'os2emx', 'riscos' ?\r
- if os.name == "nt":\r
- base = os.environ.get("APPDATA") or "~"\r
- return env_base if env_base else joinuser(base, "Python")\r
-\r
- if sys.platform == "darwin":\r
- framework = get_config_var("PYTHONFRAMEWORK")\r
- if framework:\r
- return joinuser("~", "Library", framework, "%d.%d"%(\r
- sys.version_info[:2]))\r
-\r
- return env_base if env_base else joinuser("~", ".local")\r
-\r
-\r
-def _parse_makefile(filename, vars=None):\r
- """Parse a Makefile-style file.\r
-\r
- A dictionary containing name/value pairs is returned. If an\r
- optional dictionary is passed in as the second argument, it is\r
- used instead of a new dictionary.\r
- """\r
- import re\r
- # Regexes needed for parsing Makefile (and similar syntaxes,\r
- # like old-style Setup files).\r
- _variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)")\r
- _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)")\r
- _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}")\r
-\r
- if vars is None:\r
- vars = {}\r
- done = {}\r
- notdone = {}\r
-\r
- with open(filename) as f:\r
- lines = f.readlines()\r
-\r
- for line in lines:\r
- if line.startswith('#') or line.strip() == '':\r
- continue\r
- m = _variable_rx.match(line)\r
- if m:\r
- n, v = m.group(1, 2)\r
- v = v.strip()\r
- # `$$' is a literal `$' in make\r
- tmpv = v.replace('$$', '')\r
-\r
- if "$" in tmpv:\r
- notdone[n] = v\r
- else:\r
- try:\r
- v = int(v)\r
- except ValueError:\r
- # insert literal `$'\r
- done[n] = v.replace('$$', '$')\r
- else:\r
- done[n] = v\r
-\r
- # do variable interpolation here\r
- while notdone:\r
- for name in notdone.keys():\r
- value = notdone[name]\r
- m = _findvar1_rx.search(value) or _findvar2_rx.search(value)\r
- if m:\r
- n = m.group(1)\r
- found = True\r
- if n in done:\r
- item = str(done[n])\r
- elif n in notdone:\r
- # get it on a subsequent round\r
- found = False\r
- elif n in os.environ:\r
- # do it like make: fall back to environment\r
- item = os.environ[n]\r
- else:\r
- done[n] = item = ""\r
- if found:\r
- after = value[m.end():]\r
- value = value[:m.start()] + item + after\r
- if "$" in after:\r
- notdone[name] = value\r
- else:\r
- try: value = int(value)\r
- except ValueError:\r
- done[name] = value.strip()\r
- else:\r
- done[name] = value\r
- del notdone[name]\r
- else:\r
- # bogus variable reference; just drop it since we can't deal\r
- del notdone[name]\r
- # strip spurious spaces\r
- for k, v in done.items():\r
- if isinstance(v, str):\r
- done[k] = v.strip()\r
-\r
- # save the results in the global dictionary\r
- vars.update(done)\r
- return vars\r
-\r
-\r
-def _get_makefile_filename():\r
- if _PYTHON_BUILD:\r
- return os.path.join(_PROJECT_BASE, "Makefile")\r
- return os.path.join(get_path('platstdlib'), "config", "Makefile")\r
-\r
-\r
-def _init_posix(vars):\r
- """Initialize the module as appropriate for POSIX systems."""\r
- # load the installed Makefile:\r
- makefile = _get_makefile_filename()\r
- try:\r
- _parse_makefile(makefile, vars)\r
- except IOError, e:\r
- msg = "invalid Python installation: unable to open %s" % makefile\r
- if hasattr(e, "strerror"):\r
- msg = msg + " (%s)" % e.strerror\r
- raise IOError(msg)\r
-\r
- # load the installed pyconfig.h:\r
- config_h = get_config_h_filename()\r
- try:\r
- with open(config_h) as f:\r
- parse_config_h(f, vars)\r
- except IOError, e:\r
- msg = "invalid Python installation: unable to open %s" % config_h\r
- if hasattr(e, "strerror"):\r
- msg = msg + " (%s)" % e.strerror\r
- raise IOError(msg)\r
-\r
- # On AIX, there are wrong paths to the linker scripts in the Makefile\r
- # -- these paths are relative to the Python source, but when installed\r
- # the scripts are in another directory.\r
- if _PYTHON_BUILD:\r
- vars['LDSHARED'] = vars['BLDSHARED']\r
-\r
-def _init_non_posix(vars):\r
- """Initialize the module as appropriate for NT"""\r
- # set basic install directories\r
- vars['LIBDEST'] = get_path('stdlib')\r
- vars['BINLIBDEST'] = get_path('platstdlib')\r
- vars['INCLUDEPY'] = get_path('include')\r
- vars['SO'] = '.pyd'\r
- vars['EXE'] = '.exe'\r
- vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT\r
- vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable))\r
-\r
-#\r
-# public APIs\r
-#\r
-\r
-\r
-def parse_config_h(fp, vars=None):\r
- """Parse a config.h-style file.\r
-\r
- A dictionary containing name/value pairs is returned. If an\r
- optional dictionary is passed in as the second argument, it is\r
- used instead of a new dictionary.\r
- """\r
- import re\r
- if vars is None:\r
- vars = {}\r
- define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n")\r
- undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n")\r
-\r
- while True:\r
- line = fp.readline()\r
- if not line:\r
- break\r
- m = define_rx.match(line)\r
- if m:\r
- n, v = m.group(1, 2)\r
- try: v = int(v)\r
- except ValueError: pass\r
- vars[n] = v\r
- else:\r
- m = undef_rx.match(line)\r
- if m:\r
- vars[m.group(1)] = 0\r
- return vars\r
-\r
-def get_config_h_filename():\r
- """Returns the path of pyconfig.h."""\r
- if _PYTHON_BUILD:\r
- if os.name == "nt":\r
- inc_dir = os.path.join(_PROJECT_BASE, "PC")\r
- else:\r
- inc_dir = _PROJECT_BASE\r
- else:\r
- inc_dir = get_path('platinclude')\r
- return os.path.join(inc_dir, 'pyconfig.h')\r
-\r
-def get_scheme_names():\r
- """Returns a tuple containing the schemes names."""\r
- schemes = _INSTALL_SCHEMES.keys()\r
- schemes.sort()\r
- return tuple(schemes)\r
-\r
-def get_path_names():\r
- """Returns a tuple containing the paths names."""\r
- return _SCHEME_KEYS\r
-\r
-def get_paths(scheme=_get_default_scheme(), vars=None, expand=True):\r
- """Returns a mapping containing an install scheme.\r
-\r
- ``scheme`` is the install scheme name. If not provided, it will\r
- return the default scheme for the current platform.\r
- """\r
- if expand:\r
- return _expand_vars(scheme, vars)\r
- else:\r
- return _INSTALL_SCHEMES[scheme]\r
-\r
-def get_path(name, scheme=_get_default_scheme(), vars=None, expand=True):\r
- """Returns a path corresponding to the scheme.\r
-\r
- ``scheme`` is the install scheme name.\r
- """\r
- return get_paths(scheme, vars, expand)[name]\r
-\r
-def get_config_vars(*args):\r
- """With no arguments, return a dictionary of all configuration\r
- variables relevant for the current platform.\r
-\r
- On Unix, this means every variable defined in Python's installed Makefile;\r
- On Windows and Mac OS it's a much smaller set.\r
-\r
- With arguments, return a list of values that result from looking up\r
- each argument in the configuration variable dictionary.\r
- """\r
- import re\r
- global _CONFIG_VARS\r
- if _CONFIG_VARS is None:\r
- _CONFIG_VARS = {}\r
- # Normalized versions of prefix and exec_prefix are handy to have;\r
- # in fact, these are the standard versions used most places in the\r
- # Distutils.\r
- _CONFIG_VARS['prefix'] = _PREFIX\r
- _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX\r
- _CONFIG_VARS['py_version'] = _PY_VERSION\r
- _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT\r
- _CONFIG_VARS['py_version_nodot'] = _PY_VERSION[0] + _PY_VERSION[2]\r
- _CONFIG_VARS['base'] = _PREFIX\r
- _CONFIG_VARS['platbase'] = _EXEC_PREFIX\r
- _CONFIG_VARS['projectbase'] = _PROJECT_BASE\r
-\r
- if os.name in ('nt', 'os2'):\r
- _init_non_posix(_CONFIG_VARS)\r
- if os.name == 'posix':\r
- _init_posix(_CONFIG_VARS)\r
-\r
- # Setting 'userbase' is done below the call to the\r
- # init function to enable using 'get_config_var' in\r
- # the init-function.\r
- _CONFIG_VARS['userbase'] = _getuserbase()\r
-\r
- if 'srcdir' not in _CONFIG_VARS:\r
- _CONFIG_VARS['srcdir'] = _PROJECT_BASE\r
-\r
- # Convert srcdir into an absolute path if it appears necessary.\r
- # Normally it is relative to the build directory. However, during\r
- # testing, for example, we might be running a non-installed python\r
- # from a different directory.\r
- if _PYTHON_BUILD and os.name == "posix":\r
- base = _PROJECT_BASE\r
- try:\r
- cwd = os.getcwd()\r
- except OSError:\r
- cwd = None\r
- if (not os.path.isabs(_CONFIG_VARS['srcdir']) and\r
- base != cwd):\r
- # srcdir is relative and we are not in the same directory\r
- # as the executable. Assume executable is in the build\r
- # directory and make srcdir absolute.\r
- srcdir = os.path.join(base, _CONFIG_VARS['srcdir'])\r
- _CONFIG_VARS['srcdir'] = os.path.normpath(srcdir)\r
-\r
- if sys.platform == 'darwin':\r
- kernel_version = os.uname()[2] # Kernel version (8.4.3)\r
- major_version = int(kernel_version.split('.')[0])\r
-\r
- if major_version < 8:\r
- # On Mac OS X before 10.4, check if -arch and -isysroot\r
- # are in CFLAGS or LDFLAGS and remove them if they are.\r
- # This is needed when building extensions on a 10.3 system\r
- # using a universal build of python.\r
- for key in ('LDFLAGS', 'BASECFLAGS',\r
- # a number of derived variables. These need to be\r
- # patched up as well.\r
- 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):\r
- flags = _CONFIG_VARS[key]\r
- flags = re.sub('-arch\s+\w+\s', ' ', flags)\r
- flags = re.sub('-isysroot [^ \t]*', ' ', flags)\r
- _CONFIG_VARS[key] = flags\r
- else:\r
- # Allow the user to override the architecture flags using\r
- # an environment variable.\r
- # NOTE: This name was introduced by Apple in OSX 10.5 and\r
- # is used by several scripting languages distributed with\r
- # that OS release.\r
- if 'ARCHFLAGS' in os.environ:\r
- arch = os.environ['ARCHFLAGS']\r
- for key in ('LDFLAGS', 'BASECFLAGS',\r
- # a number of derived variables. These need to be\r
- # patched up as well.\r
- 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):\r
-\r
- flags = _CONFIG_VARS[key]\r
- flags = re.sub('-arch\s+\w+\s', ' ', flags)\r
- flags = flags + ' ' + arch\r
- _CONFIG_VARS[key] = flags\r
-\r
- # If we're on OSX 10.5 or later and the user tries to\r
- # compiles an extension using an SDK that is not present\r
- # on the current machine it is better to not use an SDK\r
- # than to fail.\r
- #\r
- # The major usecase for this is users using a Python.org\r
- # binary installer on OSX 10.6: that installer uses\r
- # the 10.4u SDK, but that SDK is not installed by default\r
- # when you install Xcode.\r
- #\r
- CFLAGS = _CONFIG_VARS.get('CFLAGS', '')\r
- m = re.search('-isysroot\s+(\S+)', CFLAGS)\r
- if m is not None:\r
- sdk = m.group(1)\r
- if not os.path.exists(sdk):\r
- for key in ('LDFLAGS', 'BASECFLAGS',\r
- # a number of derived variables. These need to be\r
- # patched up as well.\r
- 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):\r
-\r
- flags = _CONFIG_VARS[key]\r
- flags = re.sub('-isysroot\s+\S+(\s|$)', ' ', flags)\r
- _CONFIG_VARS[key] = flags\r
-\r
- if args:\r
- vals = []\r
- for name in args:\r
- vals.append(_CONFIG_VARS.get(name))\r
- return vals\r
- else:\r
- return _CONFIG_VARS\r
-\r
-def get_config_var(name):\r
- """Return the value of a single variable using the dictionary returned by\r
- 'get_config_vars()'.\r
-\r
- Equivalent to get_config_vars().get(name)\r
- """\r
- return get_config_vars().get(name)\r
-\r
-def get_platform():\r
- """Return a string that identifies the current platform.\r
-\r
- This is used mainly to distinguish platform-specific build directories and\r
- platform-specific built distributions. Typically includes the OS name\r
- and version and the architecture (as supplied by 'os.uname()'),\r
- although the exact information included depends on the OS; eg. for IRIX\r
- the architecture isn't particularly important (IRIX only runs on SGI\r
- hardware), but for Linux the kernel version isn't particularly\r
- important.\r
-\r
- Examples of returned values:\r
- linux-i586\r
- linux-alpha (?)\r
- solaris-2.6-sun4u\r
- irix-5.3\r
- irix64-6.2\r
-\r
- Windows will return one of:\r
- win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc)\r
- win-ia64 (64bit Windows on Itanium)\r
- win32 (all others - specifically, sys.platform is returned)\r
-\r
- For other non-POSIX platforms, currently just returns 'sys.platform'.\r
- """\r
- import re\r
- if os.name == 'nt':\r
- # sniff sys.version for architecture.\r
- prefix = " bit ("\r
- i = sys.version.find(prefix)\r
- if i == -1:\r
- return sys.platform\r
- j = sys.version.find(")", i)\r
- look = sys.version[i+len(prefix):j].lower()\r
- if look == 'amd64':\r
- return 'win-amd64'\r
- if look == 'itanium':\r
- return 'win-ia64'\r
- return sys.platform\r
-\r
- if os.name != "posix" or not hasattr(os, 'uname'):\r
- # XXX what about the architecture? NT is Intel or Alpha,\r
- # Mac OS is M68k or PPC, etc.\r
- return sys.platform\r
-\r
- # Try to distinguish various flavours of Unix\r
- osname, host, release, version, machine = os.uname()\r
-\r
- # Convert the OS name to lowercase, remove '/' characters\r
- # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh")\r
- osname = osname.lower().replace('/', '')\r
- machine = machine.replace(' ', '_')\r
- machine = machine.replace('/', '-')\r
-\r
- if osname[:5] == "linux":\r
- # At least on Linux/Intel, 'machine' is the processor --\r
- # i386, etc.\r
- # XXX what about Alpha, SPARC, etc?\r
- return "%s-%s" % (osname, machine)\r
- elif osname[:5] == "sunos":\r
- if release[0] >= "5": # SunOS 5 == Solaris 2\r
- osname = "solaris"\r
- release = "%d.%s" % (int(release[0]) - 3, release[2:])\r
- # fall through to standard osname-release-machine representation\r
- elif osname[:4] == "irix": # could be "irix64"!\r
- return "%s-%s" % (osname, release)\r
- elif osname[:3] == "aix":\r
- return "%s-%s.%s" % (osname, version, release)\r
- elif osname[:6] == "cygwin":\r
- osname = "cygwin"\r
- rel_re = re.compile (r'[\d.]+')\r
- m = rel_re.match(release)\r
- if m:\r
- release = m.group()\r
- elif osname[:6] == "darwin":\r
- #\r
- # For our purposes, we'll assume that the system version from\r
- # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set\r
- # to. This makes the compatibility story a bit more sane because the\r
- # machine is going to compile and link as if it were\r
- # MACOSX_DEPLOYMENT_TARGET.\r
- cfgvars = get_config_vars()\r
- macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET')\r
-\r
- if 1:\r
- # Always calculate the release of the running machine,\r
- # needed to determine if we can build fat binaries or not.\r
-\r
- macrelease = macver\r
- # Get the system version. Reading this plist is a documented\r
- # way to get the system version (see the documentation for\r
- # the Gestalt Manager)\r
- try:\r
- f = open('/System/Library/CoreServices/SystemVersion.plist')\r
- except IOError:\r
- # We're on a plain darwin box, fall back to the default\r
- # behaviour.\r
- pass\r
- else:\r
- try:\r
- m = re.search(\r
- r'<key>ProductUserVisibleVersion</key>\s*' +\r
- r'<string>(.*?)</string>', f.read())\r
- if m is not None:\r
- macrelease = '.'.join(m.group(1).split('.')[:2])\r
- # else: fall back to the default behaviour\r
- finally:\r
- f.close()\r
-\r
- if not macver:\r
- macver = macrelease\r
-\r
- if macver:\r
- release = macver\r
- osname = "macosx"\r
-\r
- if (macrelease + '.') >= '10.4.' and \\r
- '-arch' in get_config_vars().get('CFLAGS', '').strip():\r
- # The universal build will build fat binaries, but not on\r
- # systems before 10.4\r
- #\r
- # Try to detect 4-way universal builds, those have machine-type\r
- # 'universal' instead of 'fat'.\r
-\r
- machine = 'fat'\r
- cflags = get_config_vars().get('CFLAGS')\r
-\r
- archs = re.findall('-arch\s+(\S+)', cflags)\r
- archs = tuple(sorted(set(archs)))\r
-\r
- if len(archs) == 1:\r
- machine = archs[0]\r
- elif archs == ('i386', 'ppc'):\r
- machine = 'fat'\r
- elif archs == ('i386', 'x86_64'):\r
- machine = 'intel'\r
- elif archs == ('i386', 'ppc', 'x86_64'):\r
- machine = 'fat3'\r
- elif archs == ('ppc64', 'x86_64'):\r
- machine = 'fat64'\r
- elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'):\r
- machine = 'universal'\r
- else:\r
- raise ValueError(\r
- "Don't know machine value for archs=%r"%(archs,))\r
-\r
- elif machine == 'i386':\r
- # On OSX the machine type returned by uname is always the\r
- # 32-bit variant, even if the executable architecture is\r
- # the 64-bit variant\r
- if sys.maxint >= 2**32:\r
- machine = 'x86_64'\r
-\r
- elif machine in ('PowerPC', 'Power_Macintosh'):\r
- # Pick a sane name for the PPC architecture.\r
- # See 'i386' case\r
- if sys.maxint >= 2**32:\r
- machine = 'ppc64'\r
- else:\r
- machine = 'ppc'\r
-\r
- return "%s-%s-%s" % (osname, release, machine)\r
-\r
-\r
-def get_python_version():\r
- return _PY_VERSION_SHORT\r