diff options
Diffstat (limited to 'venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.py')
-rw-r--r-- | venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.py | 788 |
1 files changed, 788 insertions, 0 deletions
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.py new file mode 100644 index 0000000..b243da3 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.py | |||
@@ -0,0 +1,788 @@ | |||
1 | # -*- coding: utf-8 -*- | ||
2 | # | ||
3 | # Copyright (C) 2012 The Python Software Foundation. | ||
4 | # See LICENSE.txt and CONTRIBUTORS.txt. | ||
5 | # | ||
6 | """Access to Python's configuration information.""" | ||
7 | |||
8 | import codecs | ||
9 | import os | ||
10 | import re | ||
11 | import sys | ||
12 | from os.path import pardir, realpath | ||
13 | try: | ||
14 | import configparser | ||
15 | except ImportError: | ||
16 | import ConfigParser as configparser | ||
17 | |||
18 | |||
19 | __all__ = [ | ||
20 | 'get_config_h_filename', | ||
21 | 'get_config_var', | ||
22 | 'get_config_vars', | ||
23 | 'get_makefile_filename', | ||
24 | 'get_path', | ||
25 | 'get_path_names', | ||
26 | 'get_paths', | ||
27 | 'get_platform', | ||
28 | 'get_python_version', | ||
29 | 'get_scheme_names', | ||
30 | 'parse_config_h', | ||
31 | ] | ||
32 | |||
33 | |||
34 | def _safe_realpath(path): | ||
35 | try: | ||
36 | return realpath(path) | ||
37 | except OSError: | ||
38 | return path | ||
39 | |||
40 | |||
41 | if sys.executable: | ||
42 | _PROJECT_BASE = os.path.dirname(_safe_realpath(sys.executable)) | ||
43 | else: | ||
44 | # sys.executable can be empty if argv[0] has been changed and Python is | ||
45 | # unable to retrieve the real program name | ||
46 | _PROJECT_BASE = _safe_realpath(os.getcwd()) | ||
47 | |||
48 | if os.name == "nt" and "pcbuild" in _PROJECT_BASE[-8:].lower(): | ||
49 | _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir)) | ||
50 | # PC/VS7.1 | ||
51 | if os.name == "nt" and "\\pc\\v" in _PROJECT_BASE[-10:].lower(): | ||
52 | _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) | ||
53 | # PC/AMD64 | ||
54 | if os.name == "nt" and "\\pcbuild\\amd64" in _PROJECT_BASE[-14:].lower(): | ||
55 | _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) | ||
56 | |||
57 | |||
58 | def is_python_build(): | ||
59 | for fn in ("Setup.dist", "Setup.local"): | ||
60 | if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)): | ||
61 | return True | ||
62 | return False | ||
63 | |||
64 | _PYTHON_BUILD = is_python_build() | ||
65 | |||
66 | _cfg_read = False | ||
67 | |||
68 | def _ensure_cfg_read(): | ||
69 | global _cfg_read | ||
70 | if not _cfg_read: | ||
71 | from ..resources import finder | ||
72 | backport_package = __name__.rsplit('.', 1)[0] | ||
73 | _finder = finder(backport_package) | ||
74 | _cfgfile = _finder.find('sysconfig.cfg') | ||
75 | assert _cfgfile, 'sysconfig.cfg exists' | ||
76 | with _cfgfile.as_stream() as s: | ||
77 | _SCHEMES.readfp(s) | ||
78 | if _PYTHON_BUILD: | ||
79 | for scheme in ('posix_prefix', 'posix_home'): | ||
80 | _SCHEMES.set(scheme, 'include', '{srcdir}/Include') | ||
81 | _SCHEMES.set(scheme, 'platinclude', '{projectbase}/.') | ||
82 | |||
83 | _cfg_read = True | ||
84 | |||
85 | |||
86 | _SCHEMES = configparser.RawConfigParser() | ||
87 | _VAR_REPL = re.compile(r'\{([^{]*?)\}') | ||
88 | |||
89 | def _expand_globals(config): | ||
90 | _ensure_cfg_read() | ||
91 | if config.has_section('globals'): | ||
92 | globals = config.items('globals') | ||
93 | else: | ||
94 | globals = tuple() | ||
95 | |||
96 | sections = config.sections() | ||
97 | for section in sections: | ||
98 | if section == 'globals': | ||
99 | continue | ||
100 | for option, value in globals: | ||
101 | if config.has_option(section, option): | ||
102 | continue | ||
103 | config.set(section, option, value) | ||
104 | config.remove_section('globals') | ||
105 | |||
106 | # now expanding local variables defined in the cfg file | ||
107 | # | ||
108 | for section in config.sections(): | ||
109 | variables = dict(config.items(section)) | ||
110 | |||
111 | def _replacer(matchobj): | ||
112 | name = matchobj.group(1) | ||
113 | if name in variables: | ||
114 | return variables[name] | ||
115 | return matchobj.group(0) | ||
116 | |||
117 | for option, value in config.items(section): | ||
118 | config.set(section, option, _VAR_REPL.sub(_replacer, value)) | ||
119 | |||
120 | #_expand_globals(_SCHEMES) | ||
121 | |||
122 | # FIXME don't rely on sys.version here, its format is an implementation detail | ||
123 | # of CPython, use sys.version_info or sys.hexversion | ||
124 | _PY_VERSION = sys.version.split()[0] | ||
125 | _PY_VERSION_SHORT = sys.version[:3] | ||
126 | _PY_VERSION_SHORT_NO_DOT = _PY_VERSION[0] + _PY_VERSION[2] | ||
127 | _PREFIX = os.path.normpath(sys.prefix) | ||
128 | _EXEC_PREFIX = os.path.normpath(sys.exec_prefix) | ||
129 | _CONFIG_VARS = None | ||
130 | _USER_BASE = None | ||
131 | |||
132 | |||
133 | def _subst_vars(path, local_vars): | ||
134 | """In the string `path`, replace tokens like {some.thing} with the | ||
135 | corresponding value from the map `local_vars`. | ||
136 | |||
137 | If there is no corresponding value, leave the token unchanged. | ||
138 | """ | ||
139 | def _replacer(matchobj): | ||
140 | name = matchobj.group(1) | ||
141 | if name in local_vars: | ||
142 | return local_vars[name] | ||
143 | elif name in os.environ: | ||
144 | return os.environ[name] | ||
145 | return matchobj.group(0) | ||
146 | return _VAR_REPL.sub(_replacer, path) | ||
147 | |||
148 | |||
149 | def _extend_dict(target_dict, other_dict): | ||
150 | target_keys = target_dict.keys() | ||
151 | for key, value in other_dict.items(): | ||
152 | if key in target_keys: | ||
153 | continue | ||
154 | target_dict[key] = value | ||
155 | |||
156 | |||
157 | def _expand_vars(scheme, vars): | ||
158 | res = {} | ||
159 | if vars is None: | ||
160 | vars = {} | ||
161 | _extend_dict(vars, get_config_vars()) | ||
162 | |||
163 | for key, value in _SCHEMES.items(scheme): | ||
164 | if os.name in ('posix', 'nt'): | ||
165 | value = os.path.expanduser(value) | ||
166 | res[key] = os.path.normpath(_subst_vars(value, vars)) | ||
167 | return res | ||
168 | |||
169 | |||
170 | def format_value(value, vars): | ||
171 | def _replacer(matchobj): | ||
172 | name = matchobj.group(1) | ||
173 | if name in vars: | ||
174 | return vars[name] | ||
175 | return matchobj.group(0) | ||
176 | return _VAR_REPL.sub(_replacer, value) | ||
177 | |||
178 | |||
179 | def _get_default_scheme(): | ||
180 | if os.name == 'posix': | ||
181 | # the default scheme for posix is posix_prefix | ||
182 | return 'posix_prefix' | ||
183 | return os.name | ||
184 | |||
185 | |||
186 | def _getuserbase(): | ||
187 | env_base = os.environ.get("PYTHONUSERBASE", None) | ||
188 | |||
189 | def joinuser(*args): | ||
190 | return os.path.expanduser(os.path.join(*args)) | ||
191 | |||
192 | # what about 'os2emx', 'riscos' ? | ||
193 | if os.name == "nt": | ||
194 | base = os.environ.get("APPDATA") or "~" | ||
195 | if env_base: | ||
196 | return env_base | ||
197 | else: | ||
198 | return joinuser(base, "Python") | ||
199 | |||
200 | if sys.platform == "darwin": | ||
201 | framework = get_config_var("PYTHONFRAMEWORK") | ||
202 | if framework: | ||
203 | if env_base: | ||
204 | return env_base | ||
205 | else: | ||
206 | return joinuser("~", "Library", framework, "%d.%d" % | ||
207 | sys.version_info[:2]) | ||
208 | |||
209 | if env_base: | ||
210 | return env_base | ||
211 | else: | ||
212 | return joinuser("~", ".local") | ||
213 | |||
214 | |||
215 | def _parse_makefile(filename, vars=None): | ||
216 | """Parse a Makefile-style file. | ||
217 | |||
218 | A dictionary containing name/value pairs is returned. If an | ||
219 | optional dictionary is passed in as the second argument, it is | ||
220 | used instead of a new dictionary. | ||
221 | """ | ||
222 | # Regexes needed for parsing Makefile (and similar syntaxes, | ||
223 | # like old-style Setup files). | ||
224 | _variable_rx = re.compile(r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)") | ||
225 | _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)") | ||
226 | _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}") | ||
227 | |||
228 | if vars is None: | ||
229 | vars = {} | ||
230 | done = {} | ||
231 | notdone = {} | ||
232 | |||
233 | with codecs.open(filename, encoding='utf-8', errors="surrogateescape") as f: | ||
234 | lines = f.readlines() | ||
235 | |||
236 | for line in lines: | ||
237 | if line.startswith('#') or line.strip() == '': | ||
238 | continue | ||
239 | m = _variable_rx.match(line) | ||
240 | if m: | ||
241 | n, v = m.group(1, 2) | ||
242 | v = v.strip() | ||
243 | # `$$' is a literal `$' in make | ||
244 | tmpv = v.replace('$$', '') | ||
245 | |||
246 | if "$" in tmpv: | ||
247 | notdone[n] = v | ||
248 | else: | ||
249 | try: | ||
250 | v = int(v) | ||
251 | except ValueError: | ||
252 | # insert literal `$' | ||
253 | done[n] = v.replace('$$', '$') | ||
254 | else: | ||
255 | done[n] = v | ||
256 | |||
257 | # do variable interpolation here | ||
258 | variables = list(notdone.keys()) | ||
259 | |||
260 | # Variables with a 'PY_' prefix in the makefile. These need to | ||
261 | # be made available without that prefix through sysconfig. | ||
262 | # Special care is needed to ensure that variable expansion works, even | ||
263 | # if the expansion uses the name without a prefix. | ||
264 | renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS') | ||
265 | |||
266 | while len(variables) > 0: | ||
267 | for name in tuple(variables): | ||
268 | value = notdone[name] | ||
269 | m = _findvar1_rx.search(value) or _findvar2_rx.search(value) | ||
270 | if m is not None: | ||
271 | n = m.group(1) | ||
272 | found = True | ||
273 | if n in done: | ||
274 | item = str(done[n]) | ||
275 | elif n in notdone: | ||
276 | # get it on a subsequent round | ||
277 | found = False | ||
278 | elif n in os.environ: | ||
279 | # do it like make: fall back to environment | ||
280 | item = os.environ[n] | ||
281 | |||
282 | elif n in renamed_variables: | ||
283 | if (name.startswith('PY_') and | ||
284 | name[3:] in renamed_variables): | ||
285 | item = "" | ||
286 | |||
287 | elif 'PY_' + n in notdone: | ||
288 | found = False | ||
289 | |||
290 | else: | ||
291 | item = str(done['PY_' + n]) | ||
292 | |||
293 | else: | ||
294 | done[n] = item = "" | ||
295 | |||
296 | if found: | ||
297 | after = value[m.end():] | ||
298 | value = value[:m.start()] + item + after | ||
299 | if "$" in after: | ||
300 | notdone[name] = value | ||
301 | else: | ||
302 | try: | ||
303 | value = int(value) | ||
304 | except ValueError: | ||
305 | done[name] = value.strip() | ||
306 | else: | ||
307 | done[name] = value | ||
308 | variables.remove(name) | ||
309 | |||
310 | if (name.startswith('PY_') and | ||
311 | name[3:] in renamed_variables): | ||
312 | |||
313 | name = name[3:] | ||
314 | if name not in done: | ||
315 | done[name] = value | ||
316 | |||
317 | else: | ||
318 | # bogus variable reference (e.g. "prefix=$/opt/python"); | ||
319 | # just drop it since we can't deal | ||
320 | done[name] = value | ||
321 | variables.remove(name) | ||
322 | |||
323 | # strip spurious spaces | ||
324 | for k, v in done.items(): | ||
325 | if isinstance(v, str): | ||
326 | done[k] = v.strip() | ||
327 | |||
328 | # save the results in the global dictionary | ||
329 | vars.update(done) | ||
330 | return vars | ||
331 | |||
332 | |||
333 | def get_makefile_filename(): | ||
334 | """Return the path of the Makefile.""" | ||
335 | if _PYTHON_BUILD: | ||
336 | return os.path.join(_PROJECT_BASE, "Makefile") | ||
337 | if hasattr(sys, 'abiflags'): | ||
338 | config_dir_name = 'config-%s%s' % (_PY_VERSION_SHORT, sys.abiflags) | ||
339 | else: | ||
340 | config_dir_name = 'config' | ||
341 | return os.path.join(get_path('stdlib'), config_dir_name, 'Makefile') | ||
342 | |||
343 | |||
344 | def _init_posix(vars): | ||
345 | """Initialize the module as appropriate for POSIX systems.""" | ||
346 | # load the installed Makefile: | ||
347 | makefile = get_makefile_filename() | ||
348 | try: | ||
349 | _parse_makefile(makefile, vars) | ||
350 | except IOError as e: | ||
351 | msg = "invalid Python installation: unable to open %s" % makefile | ||
352 | if hasattr(e, "strerror"): | ||
353 | msg = msg + " (%s)" % e.strerror | ||
354 | raise IOError(msg) | ||
355 | # load the installed pyconfig.h: | ||
356 | config_h = get_config_h_filename() | ||
357 | try: | ||
358 | with open(config_h) as f: | ||
359 | parse_config_h(f, vars) | ||
360 | except IOError as e: | ||
361 | msg = "invalid Python installation: unable to open %s" % config_h | ||
362 | if hasattr(e, "strerror"): | ||
363 | msg = msg + " (%s)" % e.strerror | ||
364 | raise IOError(msg) | ||
365 | # On AIX, there are wrong paths to the linker scripts in the Makefile | ||
366 | # -- these paths are relative to the Python source, but when installed | ||
367 | # the scripts are in another directory. | ||
368 | if _PYTHON_BUILD: | ||
369 | vars['LDSHARED'] = vars['BLDSHARED'] | ||
370 | |||
371 | |||
372 | def _init_non_posix(vars): | ||
373 | """Initialize the module as appropriate for NT""" | ||
374 | # set basic install directories | ||
375 | vars['LIBDEST'] = get_path('stdlib') | ||
376 | vars['BINLIBDEST'] = get_path('platstdlib') | ||
377 | vars['INCLUDEPY'] = get_path('include') | ||
378 | vars['SO'] = '.pyd' | ||
379 | vars['EXE'] = '.exe' | ||
380 | vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT | ||
381 | vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) | ||
382 | |||
383 | # | ||
384 | # public APIs | ||
385 | # | ||
386 | |||
387 | |||
388 | def parse_config_h(fp, vars=None): | ||
389 | """Parse a config.h-style file. | ||
390 | |||
391 | A dictionary containing name/value pairs is returned. If an | ||
392 | optional dictionary is passed in as the second argument, it is | ||
393 | used instead of a new dictionary. | ||
394 | """ | ||
395 | if vars is None: | ||
396 | vars = {} | ||
397 | define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") | ||
398 | undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") | ||
399 | |||
400 | while True: | ||
401 | line = fp.readline() | ||
402 | if not line: | ||
403 | break | ||
404 | m = define_rx.match(line) | ||
405 | if m: | ||
406 | n, v = m.group(1, 2) | ||
407 | try: | ||
408 | v = int(v) | ||
409 | except ValueError: | ||
410 | pass | ||
411 | vars[n] = v | ||
412 | else: | ||
413 | m = undef_rx.match(line) | ||
414 | if m: | ||
415 | vars[m.group(1)] = 0 | ||
416 | return vars | ||
417 | |||
418 | |||
419 | def get_config_h_filename(): | ||
420 | """Return the path of pyconfig.h.""" | ||
421 | if _PYTHON_BUILD: | ||
422 | if os.name == "nt": | ||
423 | inc_dir = os.path.join(_PROJECT_BASE, "PC") | ||
424 | else: | ||
425 | inc_dir = _PROJECT_BASE | ||
426 | else: | ||
427 | inc_dir = get_path('platinclude') | ||
428 | return os.path.join(inc_dir, 'pyconfig.h') | ||
429 | |||
430 | |||
431 | def get_scheme_names(): | ||
432 | """Return a tuple containing the schemes names.""" | ||
433 | return tuple(sorted(_SCHEMES.sections())) | ||
434 | |||
435 | |||
436 | def get_path_names(): | ||
437 | """Return a tuple containing the paths names.""" | ||
438 | # xxx see if we want a static list | ||
439 | return _SCHEMES.options('posix_prefix') | ||
440 | |||
441 | |||
442 | def get_paths(scheme=_get_default_scheme(), vars=None, expand=True): | ||
443 | """Return a mapping containing an install scheme. | ||
444 | |||
445 | ``scheme`` is the install scheme name. If not provided, it will | ||
446 | return the default scheme for the current platform. | ||
447 | """ | ||
448 | _ensure_cfg_read() | ||
449 | if expand: | ||
450 | return _expand_vars(scheme, vars) | ||
451 | else: | ||
452 | return dict(_SCHEMES.items(scheme)) | ||
453 | |||
454 | |||
455 | def get_path(name, scheme=_get_default_scheme(), vars=None, expand=True): | ||
456 | """Return a path corresponding to the scheme. | ||
457 | |||
458 | ``scheme`` is the install scheme name. | ||
459 | """ | ||
460 | return get_paths(scheme, vars, expand)[name] | ||
461 | |||
462 | |||
463 | def get_config_vars(*args): | ||
464 | """With no arguments, return a dictionary of all configuration | ||
465 | variables relevant for the current platform. | ||
466 | |||
467 | On Unix, this means every variable defined in Python's installed Makefile; | ||
468 | On Windows and Mac OS it's a much smaller set. | ||
469 | |||
470 | With arguments, return a list of values that result from looking up | ||
471 | each argument in the configuration variable dictionary. | ||
472 | """ | ||
473 | global _CONFIG_VARS | ||
474 | if _CONFIG_VARS is None: | ||
475 | _CONFIG_VARS = {} | ||
476 | # Normalized versions of prefix and exec_prefix are handy to have; | ||
477 | # in fact, these are the standard versions used most places in the | ||
478 | # distutils2 module. | ||
479 | _CONFIG_VARS['prefix'] = _PREFIX | ||
480 | _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX | ||
481 | _CONFIG_VARS['py_version'] = _PY_VERSION | ||
482 | _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT | ||
483 | _CONFIG_VARS['py_version_nodot'] = _PY_VERSION[0] + _PY_VERSION[2] | ||
484 | _CONFIG_VARS['base'] = _PREFIX | ||
485 | _CONFIG_VARS['platbase'] = _EXEC_PREFIX | ||
486 | _CONFIG_VARS['projectbase'] = _PROJECT_BASE | ||
487 | try: | ||
488 | _CONFIG_VARS['abiflags'] = sys.abiflags | ||
489 | except AttributeError: | ||
490 | # sys.abiflags may not be defined on all platforms. | ||
491 | _CONFIG_VARS['abiflags'] = '' | ||
492 | |||
493 | if os.name in ('nt', 'os2'): | ||
494 | _init_non_posix(_CONFIG_VARS) | ||
495 | if os.name == 'posix': | ||
496 | _init_posix(_CONFIG_VARS) | ||
497 | # Setting 'userbase' is done below the call to the | ||
498 | # init function to enable using 'get_config_var' in | ||
499 | # the init-function. | ||
500 | if sys.version >= '2.6': | ||
501 | _CONFIG_VARS['userbase'] = _getuserbase() | ||
502 | |||
503 | if 'srcdir' not in _CONFIG_VARS: | ||
504 | _CONFIG_VARS['srcdir'] = _PROJECT_BASE | ||
505 | else: | ||
506 | _CONFIG_VARS['srcdir'] = _safe_realpath(_CONFIG_VARS['srcdir']) | ||
507 | |||
508 | # Convert srcdir into an absolute path if it appears necessary. | ||
509 | # Normally it is relative to the build directory. However, during | ||
510 | # testing, for example, we might be running a non-installed python | ||
511 | # from a different directory. | ||
512 | if _PYTHON_BUILD and os.name == "posix": | ||
513 | base = _PROJECT_BASE | ||
514 | try: | ||
515 | cwd = os.getcwd() | ||
516 | except OSError: | ||
517 | cwd = None | ||
518 | if (not os.path.isabs(_CONFIG_VARS['srcdir']) and | ||
519 | base != cwd): | ||
520 | # srcdir is relative and we are not in the same directory | ||
521 | # as the executable. Assume executable is in the build | ||
522 | # directory and make srcdir absolute. | ||
523 | srcdir = os.path.join(base, _CONFIG_VARS['srcdir']) | ||
524 | _CONFIG_VARS['srcdir'] = os.path.normpath(srcdir) | ||
525 | |||
526 | if sys.platform == 'darwin': | ||
527 | kernel_version = os.uname()[2] # Kernel version (8.4.3) | ||
528 | major_version = int(kernel_version.split('.')[0]) | ||
529 | |||
530 | if major_version < 8: | ||
531 | # On Mac OS X before 10.4, check if -arch and -isysroot | ||
532 | # are in CFLAGS or LDFLAGS and remove them if they are. | ||
533 | # This is needed when building extensions on a 10.3 system | ||
534 | # using a universal build of python. | ||
535 | for key in ('LDFLAGS', 'BASECFLAGS', | ||
536 | # a number of derived variables. These need to be | ||
537 | # patched up as well. | ||
538 | 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): | ||
539 | flags = _CONFIG_VARS[key] | ||
540 | flags = re.sub(r'-arch\s+\w+\s', ' ', flags) | ||
541 | flags = re.sub('-isysroot [^ \t]*', ' ', flags) | ||
542 | _CONFIG_VARS[key] = flags | ||
543 | else: | ||
544 | # Allow the user to override the architecture flags using | ||
545 | # an environment variable. | ||
546 | # NOTE: This name was introduced by Apple in OSX 10.5 and | ||
547 | # is used by several scripting languages distributed with | ||
548 | # that OS release. | ||
549 | if 'ARCHFLAGS' in os.environ: | ||
550 | arch = os.environ['ARCHFLAGS'] | ||
551 | for key in ('LDFLAGS', 'BASECFLAGS', | ||
552 | # a number of derived variables. These need to be | ||
553 | # patched up as well. | ||
554 | 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): | ||
555 | |||
556 | flags = _CONFIG_VARS[key] | ||
557 | flags = re.sub(r'-arch\s+\w+\s', ' ', flags) | ||
558 | flags = flags + ' ' + arch | ||
559 | _CONFIG_VARS[key] = flags | ||
560 | |||
561 | # If we're on OSX 10.5 or later and the user tries to | ||
562 | # compiles an extension using an SDK that is not present | ||
563 | # on the current machine it is better to not use an SDK | ||
564 | # than to fail. | ||
565 | # | ||
566 | # The major usecase for this is users using a Python.org | ||
567 | # binary installer on OSX 10.6: that installer uses | ||
568 | # the 10.4u SDK, but that SDK is not installed by default | ||
569 | # when you install Xcode. | ||
570 | # | ||
571 | CFLAGS = _CONFIG_VARS.get('CFLAGS', '') | ||
572 | m = re.search(r'-isysroot\s+(\S+)', CFLAGS) | ||
573 | if m is not None: | ||
574 | sdk = m.group(1) | ||
575 | if not os.path.exists(sdk): | ||
576 | for key in ('LDFLAGS', 'BASECFLAGS', | ||
577 | # a number of derived variables. These need to be | ||
578 | # patched up as well. | ||
579 | 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): | ||
580 | |||
581 | flags = _CONFIG_VARS[key] | ||
582 | flags = re.sub(r'-isysroot\s+\S+(\s|$)', ' ', flags) | ||
583 | _CONFIG_VARS[key] = flags | ||
584 | |||
585 | if args: | ||
586 | vals = [] | ||
587 | for name in args: | ||
588 | vals.append(_CONFIG_VARS.get(name)) | ||
589 | return vals | ||
590 | else: | ||
591 | return _CONFIG_VARS | ||
592 | |||
593 | |||
594 | def get_config_var(name): | ||
595 | """Return the value of a single variable using the dictionary returned by | ||
596 | 'get_config_vars()'. | ||
597 | |||
598 | Equivalent to get_config_vars().get(name) | ||
599 | """ | ||
600 | return get_config_vars().get(name) | ||
601 | |||
602 | |||
603 | def get_platform(): | ||
604 | """Return a string that identifies the current platform. | ||
605 | |||
606 | This is used mainly to distinguish platform-specific build directories and | ||
607 | platform-specific built distributions. Typically includes the OS name | ||
608 | and version and the architecture (as supplied by 'os.uname()'), | ||
609 | although the exact information included depends on the OS; eg. for IRIX | ||
610 | the architecture isn't particularly important (IRIX only runs on SGI | ||
611 | hardware), but for Linux the kernel version isn't particularly | ||
612 | important. | ||
613 | |||
614 | Examples of returned values: | ||
615 | linux-i586 | ||
616 | linux-alpha (?) | ||
617 | solaris-2.6-sun4u | ||
618 | irix-5.3 | ||
619 | irix64-6.2 | ||
620 | |||
621 | Windows will return one of: | ||
622 | win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) | ||
623 | win-ia64 (64bit Windows on Itanium) | ||
624 | win32 (all others - specifically, sys.platform is returned) | ||
625 | |||
626 | For other non-POSIX platforms, currently just returns 'sys.platform'. | ||
627 | """ | ||
628 | if os.name == 'nt': | ||
629 | # sniff sys.version for architecture. | ||
630 | prefix = " bit (" | ||
631 | i = sys.version.find(prefix) | ||
632 | if i == -1: | ||
633 | return sys.platform | ||
634 | j = sys.version.find(")", i) | ||
635 | look = sys.version[i+len(prefix):j].lower() | ||
636 | if look == 'amd64': | ||
637 | return 'win-amd64' | ||
638 | if look == 'itanium': | ||
639 | return 'win-ia64' | ||
640 | return sys.platform | ||
641 | |||
642 | if os.name != "posix" or not hasattr(os, 'uname'): | ||
643 | # XXX what about the architecture? NT is Intel or Alpha, | ||
644 | # Mac OS is M68k or PPC, etc. | ||
645 | return sys.platform | ||
646 | |||
647 | # Try to distinguish various flavours of Unix | ||
648 | osname, host, release, version, machine = os.uname() | ||
649 | |||
650 | # Convert the OS name to lowercase, remove '/' characters | ||
651 | # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh") | ||
652 | osname = osname.lower().replace('/', '') | ||
653 | machine = machine.replace(' ', '_') | ||
654 | machine = machine.replace('/', '-') | ||
655 | |||
656 | if osname[:5] == "linux": | ||
657 | # At least on Linux/Intel, 'machine' is the processor -- | ||
658 | # i386, etc. | ||
659 | # XXX what about Alpha, SPARC, etc? | ||
660 | return "%s-%s" % (osname, machine) | ||
661 | elif osname[:5] == "sunos": | ||
662 | if release[0] >= "5": # SunOS 5 == Solaris 2 | ||
663 | osname = "solaris" | ||
664 | release = "%d.%s" % (int(release[0]) - 3, release[2:]) | ||
665 | # fall through to standard osname-release-machine representation | ||
666 | elif osname[:4] == "irix": # could be "irix64"! | ||
667 | return "%s-%s" % (osname, release) | ||
668 | elif osname[:3] == "aix": | ||
669 | return "%s-%s.%s" % (osname, version, release) | ||
670 | elif osname[:6] == "cygwin": | ||
671 | osname = "cygwin" | ||
672 | rel_re = re.compile(r'[\d.]+') | ||
673 | m = rel_re.match(release) | ||
674 | if m: | ||
675 | release = m.group() | ||
676 | elif osname[:6] == "darwin": | ||
677 | # | ||
678 | # For our purposes, we'll assume that the system version from | ||
679 | # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set | ||
680 | # to. This makes the compatibility story a bit more sane because the | ||
681 | # machine is going to compile and link as if it were | ||
682 | # MACOSX_DEPLOYMENT_TARGET. | ||
683 | cfgvars = get_config_vars() | ||
684 | macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET') | ||
685 | |||
686 | if True: | ||
687 | # Always calculate the release of the running machine, | ||
688 | # needed to determine if we can build fat binaries or not. | ||
689 | |||
690 | macrelease = macver | ||
691 | # Get the system version. Reading this plist is a documented | ||
692 | # way to get the system version (see the documentation for | ||
693 | # the Gestalt Manager) | ||
694 | try: | ||
695 | f = open('/System/Library/CoreServices/SystemVersion.plist') | ||
696 | except IOError: | ||
697 | # We're on a plain darwin box, fall back to the default | ||
698 | # behaviour. | ||
699 | pass | ||
700 | else: | ||
701 | try: | ||
702 | m = re.search(r'<key>ProductUserVisibleVersion</key>\s*' | ||
703 | r'<string>(.*?)</string>', f.read()) | ||
704 | finally: | ||
705 | f.close() | ||
706 | if m is not None: | ||
707 | macrelease = '.'.join(m.group(1).split('.')[:2]) | ||
708 | # else: fall back to the default behaviour | ||
709 | |||
710 | if not macver: | ||
711 | macver = macrelease | ||
712 | |||
713 | if macver: | ||
714 | release = macver | ||
715 | osname = "macosx" | ||
716 | |||
717 | if ((macrelease + '.') >= '10.4.' and | ||
718 | '-arch' in get_config_vars().get('CFLAGS', '').strip()): | ||
719 | # The universal build will build fat binaries, but not on | ||
720 | # systems before 10.4 | ||
721 | # | ||
722 | # Try to detect 4-way universal builds, those have machine-type | ||
723 | # 'universal' instead of 'fat'. | ||
724 | |||
725 | machine = 'fat' | ||
726 | cflags = get_config_vars().get('CFLAGS') | ||
727 | |||
728 | archs = re.findall(r'-arch\s+(\S+)', cflags) | ||
729 | archs = tuple(sorted(set(archs))) | ||
730 | |||
731 | if len(archs) == 1: | ||
732 | machine = archs[0] | ||
733 | elif archs == ('i386', 'ppc'): | ||
734 | machine = 'fat' | ||
735 | elif archs == ('i386', 'x86_64'): | ||
736 | machine = 'intel' | ||
737 | elif archs == ('i386', 'ppc', 'x86_64'): | ||
738 | machine = 'fat3' | ||
739 | elif archs == ('ppc64', 'x86_64'): | ||
740 | machine = 'fat64' | ||
741 | elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'): | ||
742 | machine = 'universal' | ||
743 | else: | ||
744 | raise ValueError( | ||
745 | "Don't know machine value for archs=%r" % (archs,)) | ||
746 | |||
747 | elif machine == 'i386': | ||
748 | # On OSX the machine type returned by uname is always the | ||
749 | # 32-bit variant, even if the executable architecture is | ||
750 | # the 64-bit variant | ||
751 | if sys.maxsize >= 2**32: | ||
752 | machine = 'x86_64' | ||
753 | |||
754 | elif machine in ('PowerPC', 'Power_Macintosh'): | ||
755 | # Pick a sane name for the PPC architecture. | ||
756 | # See 'i386' case | ||
757 | if sys.maxsize >= 2**32: | ||
758 | machine = 'ppc64' | ||
759 | else: | ||
760 | machine = 'ppc' | ||
761 | |||
762 | return "%s-%s-%s" % (osname, release, machine) | ||
763 | |||
764 | |||
765 | def get_python_version(): | ||
766 | return _PY_VERSION_SHORT | ||
767 | |||
768 | |||
769 | def _print_dict(title, data): | ||
770 | for index, (key, value) in enumerate(sorted(data.items())): | ||
771 | if index == 0: | ||
772 | print('%s: ' % (title)) | ||
773 | print('\t%s = "%s"' % (key, value)) | ||
774 | |||
775 | |||
776 | def _main(): | ||
777 | """Display all information sysconfig detains.""" | ||
778 | print('Platform: "%s"' % get_platform()) | ||
779 | print('Python version: "%s"' % get_python_version()) | ||
780 | print('Current installation scheme: "%s"' % _get_default_scheme()) | ||
781 | print() | ||
782 | _print_dict('Paths', get_paths()) | ||
783 | print() | ||
784 | _print_dict('Variables', get_config_vars()) | ||
785 | |||
786 | |||
787 | if __name__ == '__main__': | ||
788 | _main() | ||