Coverage for /pythoncovmergedfiles/medio/medio/usr/lib/python3.9/sysconfig.py: 5%

383 statements  

« prev     ^ index     » next       coverage.py v7.3.1, created at 2023-09-25 06:05 +0000

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}_{multiarch}'.format( 

357 abi=sys.abiflags, 

358 multiarch=getattr(sys.implementation, '_multiarch', ''), 

359 )) 

360 

361 

362def _generate_posix_vars(): 

363 """Generate the Python module containing build-time variables.""" 

364 import pprint 

365 vars = {} 

366 # load the installed Makefile: 

367 makefile = get_makefile_filename() 

368 try: 

369 _parse_makefile(makefile, vars) 

370 except OSError as e: 

371 msg = "invalid Python installation: unable to open %s" % makefile 

372 if hasattr(e, "strerror"): 

373 msg = msg + " (%s)" % e.strerror 

374 raise OSError(msg) 

375 # load the installed pyconfig.h: 

376 config_h = get_config_h_filename() 

377 try: 

378 with open(config_h) as f: 

379 parse_config_h(f, vars) 

380 except OSError as e: 

381 msg = "invalid Python installation: unable to open %s" % config_h 

382 if hasattr(e, "strerror"): 

383 msg = msg + " (%s)" % e.strerror 

384 raise OSError(msg) 

385 # On AIX, there are wrong paths to the linker scripts in the Makefile 

386 # -- these paths are relative to the Python source, but when installed 

387 # the scripts are in another directory. 

388 if _PYTHON_BUILD: 

389 vars['BLDSHARED'] = vars['LDSHARED'] 

390 

391 # There's a chicken-and-egg situation on OS X with regards to the 

392 # _sysconfigdata module after the changes introduced by #15298: 

393 # get_config_vars() is called by get_platform() as part of the 

394 # `make pybuilddir.txt` target -- which is a precursor to the 

395 # _sysconfigdata.py module being constructed. Unfortunately, 

396 # get_config_vars() eventually calls _init_posix(), which attempts 

397 # to import _sysconfigdata, which we won't have built yet. In order 

398 # for _init_posix() to work, if we're on Darwin, just mock up the 

399 # _sysconfigdata module manually and populate it with the build vars. 

400 # This is more than sufficient for ensuring the subsequent call to 

401 # get_platform() succeeds. 

402 name = _get_sysconfigdata_name() 

403 if 'darwin' in sys.platform: 

404 import types 

405 module = types.ModuleType(name) 

406 module.build_time_vars = vars 

407 sys.modules[name] = module 

408 

409 pybuilddir = 'build/lib.%s-%s' % (get_platform(), _PY_VERSION_SHORT) 

410 if hasattr(sys, "gettotalrefcount"): 

411 pybuilddir += '-pydebug' 

412 os.makedirs(pybuilddir, exist_ok=True) 

413 destfile = os.path.join(pybuilddir, name + '.py') 

414 

415 with open(destfile, 'w', encoding='utf8') as f: 

416 f.write('# system configuration generated and used by' 

417 ' the sysconfig module\n') 

418 f.write('build_time_vars = ') 

419 pprint.pprint(vars, stream=f) 

420 

421 # Create file used for sys.path fixup -- see Modules/getpath.c 

422 with open('pybuilddir.txt', 'w', encoding='utf8') as f: 

423 f.write(pybuilddir) 

424 

425def _init_posix(vars): 

426 """Initialize the module as appropriate for POSIX systems.""" 

427 # _sysconfigdata is generated at build time, see _generate_posix_vars() 

428 name = _get_sysconfigdata_name() 

429 _temp = __import__(name, globals(), locals(), ['build_time_vars'], 0) 

430 build_time_vars = _temp.build_time_vars 

431 vars.update(build_time_vars) 

432 

433def _init_non_posix(vars): 

434 """Initialize the module as appropriate for NT""" 

435 # set basic install directories 

436 import _imp 

437 vars['LIBDEST'] = get_path('stdlib') 

438 vars['BINLIBDEST'] = get_path('platstdlib') 

439 vars['INCLUDEPY'] = get_path('include') 

440 vars['EXT_SUFFIX'] = _imp.extension_suffixes()[0] 

441 vars['EXE'] = '.exe' 

442 vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT 

443 vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) 

444 

445# 

446# public APIs 

447# 

448 

449 

450def parse_config_h(fp, vars=None): 

451 """Parse a config.h-style file. 

452 

453 A dictionary containing name/value pairs is returned. If an 

454 optional dictionary is passed in as the second argument, it is 

455 used instead of a new dictionary. 

456 """ 

457 if vars is None: 

458 vars = {} 

459 import re 

460 define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") 

461 undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") 

462 

463 while True: 

464 line = fp.readline() 

465 if not line: 

466 break 

467 m = define_rx.match(line) 

468 if m: 

469 n, v = m.group(1, 2) 

470 try: 

471 if n in _ALWAYS_STR: 

472 raise ValueError 

473 v = int(v) 

474 except ValueError: 

475 pass 

476 vars[n] = v 

477 else: 

478 m = undef_rx.match(line) 

479 if m: 

480 vars[m.group(1)] = 0 

481 return vars 

482 

483 

484def get_config_h_filename(): 

485 """Return the path of pyconfig.h.""" 

486 if _PYTHON_BUILD: 

487 if os.name == "nt": 

488 inc_dir = os.path.join(_sys_home or _PROJECT_BASE, "PC") 

489 else: 

490 inc_dir = _sys_home or _PROJECT_BASE 

491 else: 

492 inc_dir = get_path('platinclude') 

493 return os.path.join(inc_dir, 'pyconfig.h') 

494 

495 

496def get_scheme_names(): 

497 """Return a tuple containing the schemes names.""" 

498 return tuple(sorted(_INSTALL_SCHEMES)) 

499 

500 

501def get_path_names(): 

502 """Return a tuple containing the paths names.""" 

503 return _SCHEME_KEYS 

504 

505 

506def get_paths(scheme=_get_default_scheme(), vars=None, expand=True): 

507 """Return a mapping containing an install scheme. 

508 

509 ``scheme`` is the install scheme name. If not provided, it will 

510 return the default scheme for the current platform. 

511 """ 

512 if expand: 

513 return _expand_vars(scheme, vars) 

514 else: 

515 return _INSTALL_SCHEMES[scheme] 

516 

517 

518def get_path(name, scheme=_get_default_scheme(), vars=None, expand=True): 

519 """Return a path corresponding to the scheme. 

520 

521 ``scheme`` is the install scheme name. 

522 """ 

523 return get_paths(scheme, vars, expand)[name] 

524 

525 

526def get_config_vars(*args): 

527 """With no arguments, return a dictionary of all configuration 

528 variables relevant for the current platform. 

529 

530 On Unix, this means every variable defined in Python's installed Makefile; 

531 On Windows it's a much smaller set. 

532 

533 With arguments, return a list of values that result from looking up 

534 each argument in the configuration variable dictionary. 

535 """ 

536 global _CONFIG_VARS 

537 if _CONFIG_VARS is None: 

538 _CONFIG_VARS = {} 

539 # Normalized versions of prefix and exec_prefix are handy to have; 

540 # in fact, these are the standard versions used most places in the 

541 # Distutils. 

542 _CONFIG_VARS['prefix'] = _PREFIX 

543 _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX 

544 _CONFIG_VARS['py_version'] = _PY_VERSION 

545 _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT 

546 _CONFIG_VARS['py_version_nodot'] = _PY_VERSION_SHORT_NO_DOT 

547 _CONFIG_VARS['installed_base'] = _BASE_PREFIX 

548 _CONFIG_VARS['base'] = _PREFIX 

549 _CONFIG_VARS['installed_platbase'] = _BASE_EXEC_PREFIX 

550 _CONFIG_VARS['platbase'] = _EXEC_PREFIX 

551 _CONFIG_VARS['projectbase'] = _PROJECT_BASE 

552 _CONFIG_VARS['platlibdir'] = sys.platlibdir 

553 try: 

554 _CONFIG_VARS['abiflags'] = sys.abiflags 

555 except AttributeError: 

556 # sys.abiflags may not be defined on all platforms. 

557 _CONFIG_VARS['abiflags'] = '' 

558 

559 if os.name == 'nt': 

560 _init_non_posix(_CONFIG_VARS) 

561 _CONFIG_VARS['TZPATH'] = '' 

562 if os.name == 'posix': 

563 _init_posix(_CONFIG_VARS) 

564 # For backward compatibility, see issue19555 

565 SO = _CONFIG_VARS.get('EXT_SUFFIX') 

566 if SO is not None: 

567 _CONFIG_VARS['SO'] = SO 

568 # Setting 'userbase' is done below the call to the 

569 # init function to enable using 'get_config_var' in 

570 # the init-function. 

571 _CONFIG_VARS['userbase'] = _getuserbase() 

572 

573 multiarch = get_config_var('MULTIARCH') 

574 if multiarch: 

575 _CONFIG_VARS['multiarchsubdir'] = '/' + multiarch 

576 else: 

577 _CONFIG_VARS['multiarchsubdir'] = '' 

578 

579 # Always convert srcdir to an absolute path 

580 srcdir = _CONFIG_VARS.get('srcdir', _PROJECT_BASE) 

581 if os.name == 'posix': 

582 if _PYTHON_BUILD: 

583 # If srcdir is a relative path (typically '.' or '..') 

584 # then it should be interpreted relative to the directory 

585 # containing Makefile. 

586 base = os.path.dirname(get_makefile_filename()) 

587 srcdir = os.path.join(base, srcdir) 

588 else: 

589 # srcdir is not meaningful since the installation is 

590 # spread about the filesystem. We choose the 

591 # directory containing the Makefile since we know it 

592 # exists. 

593 srcdir = os.path.dirname(get_makefile_filename()) 

594 _CONFIG_VARS['srcdir'] = _safe_realpath(srcdir) 

595 

596 # OS X platforms require special customization to handle 

597 # multi-architecture, multi-os-version installers 

598 if sys.platform == 'darwin': 

599 import _osx_support 

600 _osx_support.customize_config_vars(_CONFIG_VARS) 

601 

602 if args: 

603 vals = [] 

604 for name in args: 

605 vals.append(_CONFIG_VARS.get(name)) 

606 return vals 

607 else: 

608 return _CONFIG_VARS 

609 

610 

611def get_config_var(name): 

612 """Return the value of a single variable using the dictionary returned by 

613 'get_config_vars()'. 

614 

615 Equivalent to get_config_vars().get(name) 

616 """ 

617 if name == 'SO': 

618 import warnings 

619 warnings.warn('SO is deprecated, use EXT_SUFFIX', DeprecationWarning, 2) 

620 return get_config_vars().get(name) 

621 

622 

623def get_platform(): 

624 """Return a string that identifies the current platform. 

625 

626 This is used mainly to distinguish platform-specific build directories and 

627 platform-specific built distributions. Typically includes the OS name and 

628 version and the architecture (as supplied by 'os.uname()'), although the 

629 exact information included depends on the OS; on Linux, the kernel version 

630 isn't particularly important. 

631 

632 Examples of returned values: 

633 linux-i586 

634 linux-alpha (?) 

635 solaris-2.6-sun4u 

636 

637 Windows will return one of: 

638 win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) 

639 win32 (all others - specifically, sys.platform is returned) 

640 

641 For other non-POSIX platforms, currently just returns 'sys.platform'. 

642 

643 """ 

644 if os.name == 'nt': 

645 if 'amd64' in sys.version.lower(): 

646 return 'win-amd64' 

647 if '(arm)' in sys.version.lower(): 

648 return 'win-arm32' 

649 if '(arm64)' in sys.version.lower(): 

650 return 'win-arm64' 

651 return sys.platform 

652 

653 if os.name != "posix" or not hasattr(os, 'uname'): 

654 # XXX what about the architecture? NT is Intel or Alpha 

655 return sys.platform 

656 

657 # Set for cross builds explicitly 

658 if "_PYTHON_HOST_PLATFORM" in os.environ: 

659 return os.environ["_PYTHON_HOST_PLATFORM"] 

660 

661 # Try to distinguish various flavours of Unix 

662 osname, host, release, version, machine = os.uname() 

663 

664 # Convert the OS name to lowercase, remove '/' characters, and translate 

665 # spaces (for "Power Macintosh") 

666 osname = osname.lower().replace('/', '') 

667 machine = machine.replace(' ', '_') 

668 machine = machine.replace('/', '-') 

669 

670 if osname[:5] == "linux": 

671 # At least on Linux/Intel, 'machine' is the processor -- 

672 # i386, etc. 

673 # XXX what about Alpha, SPARC, etc? 

674 return "%s-%s" % (osname, machine) 

675 elif osname[:5] == "sunos": 

676 if release[0] >= "5": # SunOS 5 == Solaris 2 

677 osname = "solaris" 

678 release = "%d.%s" % (int(release[0]) - 3, release[2:]) 

679 # We can't use "platform.architecture()[0]" because a 

680 # bootstrap problem. We use a dict to get an error 

681 # if some suspicious happens. 

682 bitness = {2147483647:"32bit", 9223372036854775807:"64bit"} 

683 machine += ".%s" % bitness[sys.maxsize] 

684 # fall through to standard osname-release-machine representation 

685 elif osname[:3] == "aix": 

686 from _aix_support import aix_platform 

687 return aix_platform() 

688 elif osname[:6] == "cygwin": 

689 osname = "cygwin" 

690 import re 

691 rel_re = re.compile(r'[\d.]+') 

692 m = rel_re.match(release) 

693 if m: 

694 release = m.group() 

695 elif osname[:6] == "darwin": 

696 import _osx_support 

697 osname, release, machine = _osx_support.get_platform_osx( 

698 get_config_vars(), 

699 osname, release, machine) 

700 

701 return "%s-%s-%s" % (osname, release, machine) 

702 

703 

704def get_python_version(): 

705 return _PY_VERSION_SHORT 

706 

707 

708def _print_dict(title, data): 

709 for index, (key, value) in enumerate(sorted(data.items())): 

710 if index == 0: 

711 print('%s: ' % (title)) 

712 print('\t%s = "%s"' % (key, value)) 

713 

714 

715def _main(): 

716 """Display all information sysconfig detains.""" 

717 if '--generate-posix-vars' in sys.argv: 

718 _generate_posix_vars() 

719 return 

720 print('Platform: "%s"' % get_platform()) 

721 print('Python version: "%s"' % get_python_version()) 

722 print('Current installation scheme: "%s"' % _get_default_scheme()) 

723 print() 

724 _print_dict('Paths', get_paths()) 

725 print() 

726 _print_dict('Variables', get_config_vars()) 

727 

728 

729if __name__ == '__main__': 

730 _main()