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