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