1"""Access to Python's configuration information.""" 2 3import os 4import sys 5from os.path import pardir, realpath 6 7__all__ = [ 8 'get_config_h_filename', 9 'get_config_var', 10 'get_config_vars', 11 'get_makefile_filename', 12 'get_path', 13 'get_path_names', 14 'get_paths', 15 'get_platform', 16 'get_python_version', 17 'get_scheme_names', 18 'parse_config_h', 19] 20 21_INSTALL_SCHEMES = { 22 'posix_prefix': { 23 'stdlib': '{installed_base}/lib/python{py_version_short}', 24 'platstdlib': '{platbase}/lib/python{py_version_short}', 25 'purelib': '{base}/lib/python{py_version_short}/site-packages', 26 'platlib': '{platbase}/lib/python{py_version_short}/site-packages', 27 'include': 28 '{installed_base}/include/python{py_version_short}{abiflags}', 29 'platinclude': 30 '{installed_platbase}/include/python{py_version_short}{abiflags}', 31 'scripts': '{base}/bin', 32 'data': '{base}', 33 }, 34 'posix_home': { 35 'stdlib': '{installed_base}/lib/python', 36 'platstdlib': '{base}/lib/python', 37 'purelib': '{base}/lib/python', 38 'platlib': '{base}/lib/python', 39 'include': '{installed_base}/include/python', 40 'platinclude': '{installed_base}/include/python', 41 'scripts': '{base}/bin', 42 'data': '{base}', 43 }, 44 'nt': { 45 'stdlib': '{installed_base}/Lib', 46 'platstdlib': '{base}/Lib', 47 'purelib': '{base}/Lib/site-packages', 48 'platlib': '{base}/Lib/site-packages', 49 'include': '{installed_base}/Include', 50 'platinclude': '{installed_base}/Include', 51 'scripts': '{base}/Scripts', 52 'data': '{base}', 53 }, 54 'nt_user': { 55 'stdlib': '{userbase}/Python{py_version_nodot}', 56 'platstdlib': '{userbase}/Python{py_version_nodot}', 57 'purelib': '{userbase}/Python{py_version_nodot}/site-packages', 58 'platlib': '{userbase}/Python{py_version_nodot}/site-packages', 59 'include': '{userbase}/Python{py_version_nodot}/Include', 60 'scripts': '{userbase}/Python{py_version_nodot}/Scripts', 61 'data': '{userbase}', 62 }, 63 'posix_user': { 64 'stdlib': '{userbase}/lib/python{py_version_short}', 65 'platstdlib': '{userbase}/lib/python{py_version_short}', 66 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', 67 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', 68 'include': '{userbase}/include/python{py_version_short}', 69 'scripts': '{userbase}/bin', 70 'data': '{userbase}', 71 }, 72 'osx_framework_user': { 73 'stdlib': '{userbase}/lib/python', 74 'platstdlib': '{userbase}/lib/python', 75 'purelib': '{userbase}/lib/python/site-packages', 76 'platlib': '{userbase}/lib/python/site-packages', 77 'include': '{userbase}/include', 78 'scripts': '{userbase}/bin', 79 'data': '{userbase}', 80 }, 81 } 82 83_SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include', 84 'scripts', 'data') 85 86 # FIXME don't rely on sys.version here, its format is an implementation detail 87 # of CPython, use sys.version_info or sys.hexversion 88_PY_VERSION = sys.version.split()[0] 89_PY_VERSION_SHORT = '%d.%d' % sys.version_info[:2] 90_PY_VERSION_SHORT_NO_DOT = '%d%d' % sys.version_info[:2] 91_PREFIX = os.path.normpath(sys.prefix) 92_BASE_PREFIX = os.path.normpath(sys.base_prefix) 93_EXEC_PREFIX = os.path.normpath(sys.exec_prefix) 94_BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix) 95_CONFIG_VARS = None 96_USER_BASE = None 97 98 99def _safe_realpath(path): 100 try: 101 return realpath(path) 102 except OSError: 103 return path 104 105if sys.executable: 106 _PROJECT_BASE = os.path.dirname(_safe_realpath(sys.executable)) 107else: 108 # sys.executable can be empty if argv[0] has been changed and Python is 109 # unable to retrieve the real program name 110 _PROJECT_BASE = _safe_realpath(os.getcwd()) 111 112if (os.name == 'nt' and 113 _PROJECT_BASE.lower().endswith(('\\pcbuild\\win32', '\\pcbuild\\amd64'))): 114 _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) 115 116# set for cross builds 117if "_PYTHON_PROJECT_BASE" in os.environ: 118 _PROJECT_BASE = _safe_realpath(os.environ["_PYTHON_PROJECT_BASE"]) 119 120def _is_python_source_dir(d): 121 for fn in ("Setup.dist", "Setup.local"): 122 if os.path.isfile(os.path.join(d, "Modules", fn)): 123 return True 124 return False 125 126_sys_home = getattr(sys, '_home', None) 127if (_sys_home and os.name == 'nt' and 128 _sys_home.lower().endswith(('\\pcbuild\\win32', '\\pcbuild\\amd64'))): 129 _sys_home = os.path.dirname(os.path.dirname(_sys_home)) 130def is_python_build(check_home=False): 131 if check_home and _sys_home: 132 return _is_python_source_dir(_sys_home) 133 return _is_python_source_dir(_PROJECT_BASE) 134 135_PYTHON_BUILD = is_python_build(True) 136 137if _PYTHON_BUILD: 138 for scheme in ('posix_prefix', 'posix_home'): 139 _INSTALL_SCHEMES[scheme]['include'] = '{srcdir}/Include' 140 _INSTALL_SCHEMES[scheme]['platinclude'] = '{projectbase}/.' 141 142 143def _subst_vars(s, local_vars): 144 try: 145 return s.format(**local_vars) 146 except KeyError: 147 try: 148 return s.format(**os.environ) 149 except KeyError as var: 150 raise AttributeError('{%s}' % var) 151 152def _extend_dict(target_dict, other_dict): 153 target_keys = target_dict.keys() 154 for key, value in other_dict.items(): 155 if key in target_keys: 156 continue 157 target_dict[key] = value 158 159 160def _expand_vars(scheme, vars): 161 res = {} 162 if vars is None: 163 vars = {} 164 _extend_dict(vars, get_config_vars()) 165 166 for key, value in _INSTALL_SCHEMES[scheme].items(): 167 if os.name in ('posix', 'nt'): 168 value = os.path.expanduser(value) 169 res[key] = os.path.normpath(_subst_vars(value, vars)) 170 return res 171 172 173def _get_default_scheme(): 174 if os.name == 'posix': 175 # the default scheme for posix is posix_prefix 176 return 'posix_prefix' 177 return os.name 178 179 180def _getuserbase(): 181 env_base = os.environ.get("PYTHONUSERBASE", None) 182 183 def joinuser(*args): 184 return os.path.expanduser(os.path.join(*args)) 185 186 if os.name == "nt": 187 base = os.environ.get("APPDATA") or "~" 188 if env_base: 189 return env_base 190 else: 191 return joinuser(base, "Python") 192 193 if sys.platform == "darwin": 194 framework = get_config_var("PYTHONFRAMEWORK") 195 if framework: 196 if env_base: 197 return env_base 198 else: 199 return joinuser("~", "Library", framework, "%d.%d" % 200 sys.version_info[:2]) 201 202 if env_base: 203 return env_base 204 else: 205 return joinuser("~", ".local") 206 207 208def _parse_makefile(filename, vars=None): 209 """Parse a Makefile-style file. 210 211 A dictionary containing name/value pairs is returned. If an 212 optional dictionary is passed in as the second argument, it is 213 used instead of a new dictionary. 214 """ 215 # Regexes needed for parsing Makefile (and similar syntaxes, 216 # like old-style Setup files). 217 import re 218 _variable_rx = re.compile(r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)") 219 _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)") 220 _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}") 221 222 if vars is None: 223 vars = {} 224 done = {} 225 notdone = {} 226 227 with open(filename, errors="surrogateescape") as f: 228 lines = f.readlines() 229 230 for line in lines: 231 if line.startswith('#') or line.strip() == '': 232 continue 233 m = _variable_rx.match(line) 234 if m: 235 n, v = m.group(1, 2) 236 v = v.strip() 237 # `$$' is a literal `$' in make 238 tmpv = v.replace('$$', '') 239 240 if "$" in tmpv: 241 notdone[n] = v 242 else: 243 try: 244 v = int(v) 245 except ValueError: 246 # insert literal `$' 247 done[n] = v.replace('$$', '$') 248 else: 249 done[n] = v 250 251 # do variable interpolation here 252 variables = list(notdone.keys()) 253 254 # Variables with a 'PY_' prefix in the makefile. These need to 255 # be made available without that prefix through sysconfig. 256 # Special care is needed to ensure that variable expansion works, even 257 # if the expansion uses the name without a prefix. 258 renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS') 259 260 while len(variables) > 0: 261 for name in tuple(variables): 262 value = notdone[name] 263 m1 = _findvar1_rx.search(value) 264 m2 = _findvar2_rx.search(value) 265 if m1 and m2: 266 m = m1 if m1.start() < m2.start() else m2 267 else: 268 m = m1 if m1 else m2 269 if m is not None: 270 n = m.group(1) 271 found = True 272 if n in done: 273 item = str(done[n]) 274 elif n in notdone: 275 # get it on a subsequent round 276 found = False 277 elif n in os.environ: 278 # do it like make: fall back to environment 279 item = os.environ[n] 280 281 elif n in renamed_variables: 282 if (name.startswith('PY_') and 283 name[3:] in renamed_variables): 284 item = "" 285 286 elif 'PY_' + n in notdone: 287 found = False 288 289 else: 290 item = str(done['PY_' + n]) 291 292 else: 293 done[n] = item = "" 294 295 if found: 296 after = value[m.end():] 297 value = value[:m.start()] + item + after 298 if "$" in after: 299 notdone[name] = value 300 else: 301 try: 302 value = int(value) 303 except ValueError: 304 done[name] = value.strip() 305 else: 306 done[name] = value 307 variables.remove(name) 308 309 if name.startswith('PY_') \ 310 and name[3:] in renamed_variables: 311 312 name = name[3:] 313 if name not in done: 314 done[name] = value 315 316 else: 317 # bogus variable reference (e.g. "prefix=$/opt/python"); 318 # just drop it since we can't deal 319 done[name] = value 320 variables.remove(name) 321 322 # strip spurious spaces 323 for k, v in done.items(): 324 if isinstance(v, str): 325 done[k] = v.strip() 326 327 # save the results in the global dictionary 328 vars.update(done) 329 return vars 330 331 332def get_makefile_filename(): 333 """Return the path of the Makefile.""" 334 if _PYTHON_BUILD: 335 return os.path.join(_sys_home or _PROJECT_BASE, "Makefile") 336 if hasattr(sys, 'abiflags'): 337 config_dir_name = 'config-%s%s' % (_PY_VERSION_SHORT, sys.abiflags) 338 else: 339 config_dir_name = 'config' 340 if hasattr(sys.implementation, '_multiarch'): 341 config_dir_name += '-%s' % sys.implementation._multiarch 342 return os.path.join(get_path('stdlib'), config_dir_name, 'Makefile') 343 344 345def _get_sysconfigdata_name(): 346 return os.environ.get('_PYTHON_SYSCONFIGDATA_NAME', 347 '_sysconfigdata_{abi}_{platform}_{multiarch}'.format( 348 abi=sys.abiflags, 349 platform=sys.platform, 350 multiarch=getattr(sys.implementation, '_multiarch', ''), 351 )) 352 353 354def _generate_posix_vars(): 355 """Generate the Python module containing build-time variables.""" 356 import pprint 357 vars = {} 358 # load the installed Makefile: 359 makefile = get_makefile_filename() 360 try: 361 _parse_makefile(makefile, vars) 362 except OSError as e: 363 msg = "invalid Python installation: unable to open %s" % makefile 364 if hasattr(e, "strerror"): 365 msg = msg + " (%s)" % e.strerror 366 raise OSError(msg) 367 # load the installed pyconfig.h: 368 config_h = get_config_h_filename() 369 try: 370 with open(config_h) as f: 371 parse_config_h(f, vars) 372 except OSError as e: 373 msg = "invalid Python installation: unable to open %s" % config_h 374 if hasattr(e, "strerror"): 375 msg = msg + " (%s)" % e.strerror 376 raise OSError(msg) 377 # On AIX, there are wrong paths to the linker scripts in the Makefile 378 # -- these paths are relative to the Python source, but when installed 379 # the scripts are in another directory. 380 if _PYTHON_BUILD: 381 vars['BLDSHARED'] = vars['LDSHARED'] 382 383 # There's a chicken-and-egg situation on OS X with regards to the 384 # _sysconfigdata module after the changes introduced by #15298: 385 # get_config_vars() is called by get_platform() as part of the 386 # `make pybuilddir.txt` target -- which is a precursor to the 387 # _sysconfigdata.py module being constructed. Unfortunately, 388 # get_config_vars() eventually calls _init_posix(), which attempts 389 # to import _sysconfigdata, which we won't have built yet. In order 390 # for _init_posix() to work, if we're on Darwin, just mock up the 391 # _sysconfigdata module manually and populate it with the build vars. 392 # This is more than sufficient for ensuring the subsequent call to 393 # get_platform() succeeds. 394 name = _get_sysconfigdata_name() 395 if 'darwin' in sys.platform: 396 import types 397 module = types.ModuleType(name) 398 module.build_time_vars = vars 399 sys.modules[name] = module 400 401 pybuilddir = 'build/lib.%s-%s' % (get_platform(), _PY_VERSION_SHORT) 402 if hasattr(sys, "gettotalrefcount"): 403 pybuilddir += '-pydebug' 404 os.makedirs(pybuilddir, exist_ok=True) 405 destfile = os.path.join(pybuilddir, name + '.py') 406 407 with open(destfile, 'w', encoding='utf8') as f: 408 f.write('# system configuration generated and used by' 409 ' the sysconfig module\n') 410 f.write('build_time_vars = ') 411 pprint.pprint(vars, stream=f) 412 413 # Create file used for sys.path fixup -- see Modules/getpath.c 414 with open('pybuilddir.txt', 'w', encoding='ascii') as f: 415 f.write(pybuilddir) 416 417def _init_posix(vars): 418 """Initialize the module as appropriate for POSIX systems.""" 419 # _sysconfigdata is generated at build time, see _generate_posix_vars() 420 name = _get_sysconfigdata_name() 421 _temp = __import__(name, globals(), locals(), ['build_time_vars'], 0) 422 build_time_vars = _temp.build_time_vars 423 vars.update(build_time_vars) 424 425def _init_non_posix(vars): 426 """Initialize the module as appropriate for NT""" 427 # set basic install directories 428 vars['LIBDEST'] = get_path('stdlib') 429 vars['BINLIBDEST'] = get_path('platstdlib') 430 vars['INCLUDEPY'] = get_path('include') 431 vars['EXT_SUFFIX'] = '.pyd' 432 vars['EXE'] = '.exe' 433 vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT 434 vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) 435 436# 437# public APIs 438# 439 440 441def parse_config_h(fp, vars=None): 442 """Parse a config.h-style file. 443 444 A dictionary containing name/value pairs is returned. If an 445 optional dictionary is passed in as the second argument, it is 446 used instead of a new dictionary. 447 """ 448 if vars is None: 449 vars = {} 450 import re 451 define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") 452 undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") 453 454 while True: 455 line = fp.readline() 456 if not line: 457 break 458 m = define_rx.match(line) 459 if m: 460 n, v = m.group(1, 2) 461 try: 462 v = int(v) 463 except ValueError: 464 pass 465 vars[n] = v 466 else: 467 m = undef_rx.match(line) 468 if m: 469 vars[m.group(1)] = 0 470 return vars 471 472 473def get_config_h_filename(): 474 """Return the path of pyconfig.h.""" 475 if _PYTHON_BUILD: 476 if os.name == "nt": 477 inc_dir = os.path.join(_sys_home or _PROJECT_BASE, "PC") 478 else: 479 inc_dir = _sys_home or _PROJECT_BASE 480 else: 481 inc_dir = get_path('platinclude') 482 return os.path.join(inc_dir, 'pyconfig.h') 483 484 485def get_scheme_names(): 486 """Return a tuple containing the schemes names.""" 487 return tuple(sorted(_INSTALL_SCHEMES)) 488 489 490def get_path_names(): 491 """Return a tuple containing the paths names.""" 492 return _SCHEME_KEYS 493 494 495def get_paths(scheme=_get_default_scheme(), vars=None, expand=True): 496 """Return a mapping containing an install scheme. 497 498 ``scheme`` is the install scheme name. If not provided, it will 499 return the default scheme for the current platform. 500 """ 501 if expand: 502 return _expand_vars(scheme, vars) 503 else: 504 return _INSTALL_SCHEMES[scheme] 505 506 507def get_path(name, scheme=_get_default_scheme(), vars=None, expand=True): 508 """Return a path corresponding to the scheme. 509 510 ``scheme`` is the install scheme name. 511 """ 512 return get_paths(scheme, vars, expand)[name] 513 514 515def get_config_vars(*args): 516 """With no arguments, return a dictionary of all configuration 517 variables relevant for the current platform. 518 519 On Unix, this means every variable defined in Python's installed Makefile; 520 On Windows it's a much smaller set. 521 522 With arguments, return a list of values that result from looking up 523 each argument in the configuration variable dictionary. 524 """ 525 global _CONFIG_VARS 526 if _CONFIG_VARS is None: 527 _CONFIG_VARS = {} 528 # Normalized versions of prefix and exec_prefix are handy to have; 529 # in fact, these are the standard versions used most places in the 530 # Distutils. 531 _CONFIG_VARS['prefix'] = _PREFIX 532 _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX 533 _CONFIG_VARS['py_version'] = _PY_VERSION 534 _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT 535 _CONFIG_VARS['py_version_nodot'] = _PY_VERSION_SHORT_NO_DOT 536 _CONFIG_VARS['installed_base'] = _BASE_PREFIX 537 _CONFIG_VARS['base'] = _PREFIX 538 _CONFIG_VARS['installed_platbase'] = _BASE_EXEC_PREFIX 539 _CONFIG_VARS['platbase'] = _EXEC_PREFIX 540 _CONFIG_VARS['projectbase'] = _PROJECT_BASE 541 try: 542 _CONFIG_VARS['abiflags'] = sys.abiflags 543 except AttributeError: 544 # sys.abiflags may not be defined on all platforms. 545 _CONFIG_VARS['abiflags'] = '' 546 547 if os.name == 'nt': 548 _init_non_posix(_CONFIG_VARS) 549 if os.name == 'posix': 550 _init_posix(_CONFIG_VARS) 551 # For backward compatibility, see issue19555 552 SO = _CONFIG_VARS.get('EXT_SUFFIX') 553 if SO is not None: 554 _CONFIG_VARS['SO'] = SO 555 # Setting 'userbase' is done below the call to the 556 # init function to enable using 'get_config_var' in 557 # the init-function. 558 _CONFIG_VARS['userbase'] = _getuserbase() 559 560 # Always convert srcdir to an absolute path 561 srcdir = _CONFIG_VARS.get('srcdir', _PROJECT_BASE) 562 if os.name == 'posix': 563 if _PYTHON_BUILD: 564 # If srcdir is a relative path (typically '.' or '..') 565 # then it should be interpreted relative to the directory 566 # containing Makefile. 567 base = os.path.dirname(get_makefile_filename()) 568 srcdir = os.path.join(base, srcdir) 569 else: 570 # srcdir is not meaningful since the installation is 571 # spread about the filesystem. We choose the 572 # directory containing the Makefile since we know it 573 # exists. 574 srcdir = os.path.dirname(get_makefile_filename()) 575 _CONFIG_VARS['srcdir'] = _safe_realpath(srcdir) 576 577 # OS X platforms require special customization to handle 578 # multi-architecture, multi-os-version installers 579 if sys.platform == 'darwin': 580 import _osx_support 581 _osx_support.customize_config_vars(_CONFIG_VARS) 582 583 if args: 584 vals = [] 585 for name in args: 586 vals.append(_CONFIG_VARS.get(name)) 587 return vals 588 else: 589 return _CONFIG_VARS 590 591 592def get_config_var(name): 593 """Return the value of a single variable using the dictionary returned by 594 'get_config_vars()'. 595 596 Equivalent to get_config_vars().get(name) 597 """ 598 if name == 'SO': 599 import warnings 600 warnings.warn('SO is deprecated, use EXT_SUFFIX', DeprecationWarning, 2) 601 return get_config_vars().get(name) 602 603 604def get_platform(): 605 """Return a string that identifies the current platform. 606 607 This is used mainly to distinguish platform-specific build directories and 608 platform-specific built distributions. Typically includes the OS name 609 and version and the architecture (as supplied by 'os.uname()'), 610 although the exact information included depends on the OS; eg. for IRIX 611 the architecture isn't particularly important (IRIX only runs on SGI 612 hardware), but for Linux the kernel version isn't particularly 613 important. 614 615 Examples of returned values: 616 linux-i586 617 linux-alpha (?) 618 solaris-2.6-sun4u 619 irix-5.3 620 irix64-6.2 621 622 Windows will return one of: 623 win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) 624 win-ia64 (64bit Windows on Itanium) 625 win32 (all others - specifically, sys.platform is returned) 626 627 For other non-POSIX platforms, currently just returns 'sys.platform'. 628 """ 629 if os.name == 'nt': 630 # sniff sys.version for architecture. 631 prefix = " bit (" 632 i = sys.version.find(prefix) 633 if i == -1: 634 return sys.platform 635 j = sys.version.find(")", i) 636 look = sys.version[i+len(prefix):j].lower() 637 if look == 'amd64': 638 return 'win-amd64' 639 if look == 'itanium': 640 return 'win-ia64' 641 return sys.platform 642 643 if os.name != "posix" or not hasattr(os, 'uname'): 644 # XXX what about the architecture? NT is Intel or Alpha 645 return sys.platform 646 647 # Set for cross builds explicitly 648 if "_PYTHON_HOST_PLATFORM" in os.environ: 649 return os.environ["_PYTHON_HOST_PLATFORM"] 650 651 # Try to distinguish various flavours of Unix 652 osname, host, release, version, machine = os.uname() 653 654 # Convert the OS name to lowercase, remove '/' characters 655 # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh") 656 osname = osname.lower().replace('/', '') 657 machine = machine.replace(' ', '_') 658 machine = machine.replace('/', '-') 659 660 if osname[:5] == "linux": 661 # At least on Linux/Intel, 'machine' is the processor -- 662 # i386, etc. 663 # XXX what about Alpha, SPARC, etc? 664 return "%s-%s" % (osname, machine) 665 elif osname[:5] == "sunos": 666 if release[0] >= "5": # SunOS 5 == Solaris 2 667 osname = "solaris" 668 release = "%d.%s" % (int(release[0]) - 3, release[2:]) 669 # We can't use "platform.architecture()[0]" because a 670 # bootstrap problem. We use a dict to get an error 671 # if some suspicious happens. 672 bitness = {2147483647:"32bit", 9223372036854775807:"64bit"} 673 machine += ".%s" % bitness[sys.maxsize] 674 # fall through to standard osname-release-machine representation 675 elif osname[:4] == "irix": # could be "irix64"! 676 return "%s-%s" % (osname, release) 677 elif osname[:3] == "aix": 678 return "%s-%s.%s" % (osname, version, release) 679 elif osname[:6] == "cygwin": 680 osname = "cygwin" 681 import re 682 rel_re = re.compile(r'[\d.]+') 683 m = rel_re.match(release) 684 if m: 685 release = m.group() 686 elif osname[:6] == "darwin": 687 import _osx_support 688 osname, release, machine = _osx_support.get_platform_osx( 689 get_config_vars(), 690 osname, release, machine) 691 692 return "%s-%s-%s" % (osname, release, machine) 693 694 695def get_python_version(): 696 return _PY_VERSION_SHORT 697 698 699def _print_dict(title, data): 700 for index, (key, value) in enumerate(sorted(data.items())): 701 if index == 0: 702 print('%s: ' % (title)) 703 print('\t%s = "%s"' % (key, value)) 704 705 706def _main(): 707 """Display all information sysconfig detains.""" 708 if '--generate-posix-vars' in sys.argv: 709 _generate_posix_vars() 710 return 711 print('Platform: "%s"' % get_platform()) 712 print('Python version: "%s"' % get_python_version()) 713 print('Current installation scheme: "%s"' % _get_default_scheme()) 714 print() 715 _print_dict('Paths', get_paths()) 716 print() 717 _print_dict('Variables', get_config_vars()) 718 719 720if __name__ == '__main__': 721 _main() 722