blob: a98cc71533fa68cd3e7fbb1bf5bb011a934ac5cc [file] [log] [blame]
Tarek Ziade1231a4e2011-05-19 13:07:25 +02001"""Access to Python's configuration information."""
Tarek Ziadéedacea32010-01-29 11:41:03 +00002
Tarek Ziadéedacea32010-01-29 11:41:03 +00003import os
Tarek Ziade1231a4e2011-05-19 13:07:25 +02004import re
5import sys
Florent Xiclunaa4707382010-03-11 00:05:17 +00006from os.path import pardir, realpath
Tarek Ziadéedacea32010-01-29 11:41:03 +00007
Barry Warsawebbef6f2010-09-20 15:29:53 +00008__all__ = [
9 'get_config_h_filename',
10 'get_config_var',
11 'get_config_vars',
12 'get_makefile_filename',
13 'get_path',
14 'get_path_names',
15 'get_paths',
16 'get_platform',
17 'get_python_version',
18 'get_scheme_names',
19 'parse_config_h',
Tarek Ziade1231a4e2011-05-19 13:07:25 +020020]
Tarek Ziadé16ed6cb2010-05-25 09:47:06 +000021
Éric Araujoec177c12012-06-24 03:27:43 -040022_INSTALL_SCHEMES = {
23 'posix_prefix': {
24 'stdlib': '{installed_base}/lib/python{py_version_short}',
25 'platstdlib': '{platbase}/lib/python{py_version_short}',
26 'purelib': '{base}/lib/python{py_version_short}/site-packages',
27 'platlib': '{platbase}/lib/python{py_version_short}/site-packages',
28 'include':
29 '{installed_base}/include/python{py_version_short}{abiflags}',
30 'platinclude':
31 '{installed_platbase}/include/python{py_version_short}{abiflags}',
32 'scripts': '{base}/bin',
33 'data': '{base}',
34 },
35 'posix_home': {
36 'stdlib': '{installed_base}/lib/python',
37 'platstdlib': '{base}/lib/python',
38 'purelib': '{base}/lib/python',
39 'platlib': '{base}/lib/python',
40 'include': '{installed_base}/include/python',
41 'platinclude': '{installed_base}/include/python',
42 'scripts': '{base}/bin',
43 'data': '{base}',
44 },
45 'nt': {
46 'stdlib': '{installed_base}/Lib',
47 'platstdlib': '{base}/Lib',
48 'purelib': '{base}/Lib/site-packages',
49 'platlib': '{base}/Lib/site-packages',
50 'include': '{installed_base}/Include',
51 'platinclude': '{installed_base}/Include',
52 'scripts': '{base}/Scripts',
53 'data': '{base}',
54 },
Éric Araujoec177c12012-06-24 03:27:43 -040055 'nt_user': {
56 'stdlib': '{userbase}/Python{py_version_nodot}',
57 'platstdlib': '{userbase}/Python{py_version_nodot}',
58 'purelib': '{userbase}/Python{py_version_nodot}/site-packages',
59 'platlib': '{userbase}/Python{py_version_nodot}/site-packages',
60 'include': '{userbase}/Python{py_version_nodot}/Include',
61 'scripts': '{userbase}/Scripts',
62 'data': '{userbase}',
63 },
64 'posix_user': {
65 'stdlib': '{userbase}/lib/python{py_version_short}',
66 'platstdlib': '{userbase}/lib/python{py_version_short}',
67 'purelib': '{userbase}/lib/python{py_version_short}/site-packages',
68 'platlib': '{userbase}/lib/python{py_version_short}/site-packages',
69 'include': '{userbase}/include/python{py_version_short}',
70 'scripts': '{userbase}/bin',
71 'data': '{userbase}',
72 },
73 'osx_framework_user': {
74 'stdlib': '{userbase}/lib/python',
75 'platstdlib': '{userbase}/lib/python',
76 'purelib': '{userbase}/lib/python/site-packages',
77 'platlib': '{userbase}/lib/python/site-packages',
78 'include': '{userbase}/include',
79 'scripts': '{userbase}/bin',
80 'data': '{userbase}',
81 },
82 }
Tarek Ziadéedacea32010-01-29 11:41:03 +000083
Éric Araujoec177c12012-06-24 03:27:43 -040084_SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include',
85 'scripts', 'data')
Tarek Ziade1231a4e2011-05-19 13:07:25 +020086
Vinay Sajip7ded1f02012-05-26 03:45:29 +010087 # FIXME don't rely on sys.version here, its format is an implementation detail
Tarek Ziade1231a4e2011-05-19 13:07:25 +020088 # of CPython, use sys.version_info or sys.hexversion
Tarek Ziadéedacea32010-01-29 11:41:03 +000089_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)
Vinay Sajip7ded1f02012-05-26 03:45:29 +010093_BASE_PREFIX = os.path.normpath(sys.base_prefix)
Tarek Ziadéedacea32010-01-29 11:41:03 +000094_EXEC_PREFIX = os.path.normpath(sys.exec_prefix)
Vinay Sajip7ded1f02012-05-26 03:45:29 +010095_BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix)
Tarek Ziadéedacea32010-01-29 11:41:03 +000096_CONFIG_VARS = None
97_USER_BASE = None
Victor Stinnerb103a932010-10-12 22:23:23 +000098
Tarek Ziade1231a4e2011-05-19 13:07:25 +020099
Victor Stinnerb103a932010-10-12 22:23:23 +0000100def _safe_realpath(path):
101 try:
102 return realpath(path)
103 except OSError:
104 return path
105
Victor Stinner171ba052010-03-12 14:20:59 +0000106if sys.executable:
Victor Stinnerb103a932010-10-12 22:23:23 +0000107 _PROJECT_BASE = os.path.dirname(_safe_realpath(sys.executable))
Victor Stinner171ba052010-03-12 14:20:59 +0000108else:
109 # sys.executable can be empty if argv[0] has been changed and Python is
110 # unable to retrieve the real program name
Victor Stinnerb103a932010-10-12 22:23:23 +0000111 _PROJECT_BASE = _safe_realpath(os.getcwd())
Tarek Ziadéedacea32010-01-29 11:41:03 +0000112
113if os.name == "nt" and "pcbuild" in _PROJECT_BASE[-8:].lower():
Victor Stinnerb103a932010-10-12 22:23:23 +0000114 _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir))
Tarek Ziadéedacea32010-01-29 11:41:03 +0000115# PC/VS7.1
116if os.name == "nt" and "\\pc\\v" in _PROJECT_BASE[-10:].lower():
Victor Stinnerb103a932010-10-12 22:23:23 +0000117 _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir))
Tarek Ziadéedacea32010-01-29 11:41:03 +0000118# PC/AMD64
119if os.name == "nt" and "\\pcbuild\\amd64" in _PROJECT_BASE[-14:].lower():
Victor Stinnerb103a932010-10-12 22:23:23 +0000120 _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir))
Tarek Ziadéedacea32010-01-29 11:41:03 +0000121
doko@ubuntu.com1abe1c52012-06-30 20:42:45 +0200122# set for cross builds
doko@ubuntu.com7e6c2e22012-06-30 22:35:00 +0200123if "_PYTHON_PROJECT_BASE" in os.environ:
124 _PROJECT_BASE = _safe_realpath(os.environ["_PYTHON_PROJECT_BASE"])
doko@ubuntu.com1abe1c52012-06-30 20:42:45 +0200125
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100126def _is_python_source_dir(d):
Tarek Ziadéedacea32010-01-29 11:41:03 +0000127 for fn in ("Setup.dist", "Setup.local"):
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100128 if os.path.isfile(os.path.join(d, "Modules", fn)):
Tarek Ziadéedacea32010-01-29 11:41:03 +0000129 return True
130 return False
131
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100132_sys_home = getattr(sys, '_home', None)
Vinay Sajip42211422012-05-26 20:36:12 +0100133if _sys_home and os.name == 'nt' and \
134 _sys_home.lower().endswith(('pcbuild', 'pcbuild\\amd64')):
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100135 _sys_home = os.path.dirname(_sys_home)
Vinay Sajip7e203492012-05-27 17:30:09 +0100136 if _sys_home.endswith('pcbuild'): # must be amd64
137 _sys_home = os.path.dirname(_sys_home)
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100138def is_python_build(check_home=False):
139 if check_home and _sys_home:
140 return _is_python_source_dir(_sys_home)
141 return _is_python_source_dir(_PROJECT_BASE)
142
143_PYTHON_BUILD = is_python_build(True)
Tarek Ziadéedacea32010-01-29 11:41:03 +0000144
145if _PYTHON_BUILD:
146 for scheme in ('posix_prefix', 'posix_home'):
Éric Araujoec177c12012-06-24 03:27:43 -0400147 _INSTALL_SCHEMES[scheme]['include'] = '{srcdir}/Include'
148 _INSTALL_SCHEMES[scheme]['platinclude'] = '{projectbase}/.'
Tarek Ziadéedacea32010-01-29 11:41:03 +0000149
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200150
Éric Araujoec177c12012-06-24 03:27:43 -0400151def _subst_vars(s, local_vars):
152 try:
153 return s.format(**local_vars)
154 except KeyError:
155 try:
156 return s.format(**os.environ)
157 except KeyError as var:
158 raise AttributeError('{%s}' % var)
Tarek Ziadéedacea32010-01-29 11:41:03 +0000159
160def _extend_dict(target_dict, other_dict):
161 target_keys = target_dict.keys()
162 for key, value in other_dict.items():
163 if key in target_keys:
164 continue
165 target_dict[key] = value
166
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200167
Tarek Ziadéedacea32010-01-29 11:41:03 +0000168def _expand_vars(scheme, vars):
169 res = {}
170 if vars is None:
171 vars = {}
172 _extend_dict(vars, get_config_vars())
173
Éric Araujoec177c12012-06-24 03:27:43 -0400174 for key, value in _INSTALL_SCHEMES[scheme].items():
Tarek Ziadéedacea32010-01-29 11:41:03 +0000175 if os.name in ('posix', 'nt'):
176 value = os.path.expanduser(value)
177 res[key] = os.path.normpath(_subst_vars(value, vars))
178 return res
179
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200180
Tarek Ziadéedacea32010-01-29 11:41:03 +0000181def _get_default_scheme():
182 if os.name == 'posix':
183 # the default scheme for posix is posix_prefix
184 return 'posix_prefix'
185 return os.name
186
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200187
Tarek Ziadéedacea32010-01-29 11:41:03 +0000188def _getuserbase():
189 env_base = os.environ.get("PYTHONUSERBASE", None)
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200190
Tarek Ziadéedacea32010-01-29 11:41:03 +0000191 def joinuser(*args):
192 return os.path.expanduser(os.path.join(*args))
193
Tarek Ziadéedacea32010-01-29 11:41:03 +0000194 if os.name == "nt":
195 base = os.environ.get("APPDATA") or "~"
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200196 if env_base:
197 return env_base
198 else:
199 return joinuser(base, "Python")
Tarek Ziadéedacea32010-01-29 11:41:03 +0000200
Ronald Oussoren4cda46a2010-05-08 10:49:43 +0000201 if sys.platform == "darwin":
202 framework = get_config_var("PYTHONFRAMEWORK")
203 if framework:
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200204 if env_base:
205 return env_base
206 else:
207 return joinuser("~", "Library", framework, "%d.%d" %
208 sys.version_info[:2])
Ronald Oussoren4cda46a2010-05-08 10:49:43 +0000209
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200210 if env_base:
211 return env_base
212 else:
213 return joinuser("~", ".local")
Tarek Ziadéedacea32010-01-29 11:41:03 +0000214
215
216def _parse_makefile(filename, vars=None):
217 """Parse a Makefile-style file.
218
219 A dictionary containing name/value pairs is returned. If an
220 optional dictionary is passed in as the second argument, it is
221 used instead of a new dictionary.
222 """
Tarek Ziadéedacea32010-01-29 11:41:03 +0000223 # Regexes needed for parsing Makefile (and similar syntaxes,
224 # like old-style Setup files).
225 _variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)")
226 _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)")
227 _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}")
228
229 if vars is None:
230 vars = {}
231 done = {}
232 notdone = {}
233
Victor Stinner75d8c5c2010-10-23 17:02:31 +0000234 with open(filename, errors="surrogateescape") as f:
Tarek Ziadéedacea32010-01-29 11:41:03 +0000235 lines = f.readlines()
236
237 for line in lines:
238 if line.startswith('#') or line.strip() == '':
239 continue
240 m = _variable_rx.match(line)
241 if m:
242 n, v = m.group(1, 2)
243 v = v.strip()
244 # `$$' is a literal `$' in make
245 tmpv = v.replace('$$', '')
246
247 if "$" in tmpv:
248 notdone[n] = v
249 else:
250 try:
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
Ronald Oussorend21886c2010-07-20 16:07:10 +0000261 # 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
Tarek Ziadéedacea32010-01-29 11:41:03 +0000267 while len(variables) > 0:
268 for name in tuple(variables):
269 value = notdone[name]
270 m = _findvar1_rx.search(value) or _findvar2_rx.search(value)
271 if m is not None:
272 n = m.group(1)
273 found = True
274 if n in done:
275 item = str(done[n])
276 elif n in notdone:
277 # get it on a subsequent round
278 found = False
279 elif n in os.environ:
280 # do it like make: fall back to environment
281 item = os.environ[n]
Ronald Oussorend21886c2010-07-20 16:07:10 +0000282
283 elif n in renamed_variables:
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200284 if (name.startswith('PY_') and
285 name[3:] in renamed_variables):
Ronald Oussorend21886c2010-07-20 16:07:10 +0000286 item = ""
287
288 elif 'PY_' + n in notdone:
289 found = False
290
291 else:
292 item = str(done['PY_' + n])
293
Tarek Ziadéedacea32010-01-29 11:41:03 +0000294 else:
295 done[n] = item = ""
Ronald Oussorend21886c2010-07-20 16:07:10 +0000296
Tarek Ziadéedacea32010-01-29 11:41:03 +0000297 if found:
298 after = value[m.end():]
299 value = value[:m.start()] + item + after
300 if "$" in after:
301 notdone[name] = value
302 else:
303 try:
304 value = int(value)
305 except ValueError:
306 done[name] = value.strip()
307 else:
308 done[name] = value
309 variables.remove(name)
Ronald Oussorend21886c2010-07-20 16:07:10 +0000310
311 if name.startswith('PY_') \
Victor Stinner1273b7c2011-05-24 23:37:07 +0200312 and name[3:] in renamed_variables:
Ronald Oussorend21886c2010-07-20 16:07:10 +0000313
314 name = name[3:]
315 if name not in done:
316 done[name] = value
317
Tarek Ziadéedacea32010-01-29 11:41:03 +0000318 else:
Victor Stinner1273b7c2011-05-24 23:37:07 +0200319 # bogus variable reference (e.g. "prefix=$/opt/python");
320 # just drop it since we can't deal
321 done[name] = value
Tarek Ziadéedacea32010-01-29 11:41:03 +0000322 variables.remove(name)
323
Antoine Pitroudbec7802010-10-10 09:37:12 +0000324 # strip spurious spaces
325 for k, v in done.items():
326 if isinstance(v, str):
327 done[k] = v.strip()
328
Tarek Ziadéedacea32010-01-29 11:41:03 +0000329 # save the results in the global dictionary
330 vars.update(done)
331 return vars
332
Tarek Ziadéedacea32010-01-29 11:41:03 +0000333
Barry Warsawebbef6f2010-09-20 15:29:53 +0000334def get_makefile_filename():
Éric Araujo300623d2010-11-22 01:19:20 +0000335 """Return the path of the Makefile."""
Tarek Ziadéedacea32010-01-29 11:41:03 +0000336 if _PYTHON_BUILD:
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100337 return os.path.join(_sys_home or _PROJECT_BASE, "Makefile")
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200338 if hasattr(sys, 'abiflags'):
339 config_dir_name = 'config-%s%s' % (_PY_VERSION_SHORT, sys.abiflags)
340 else:
341 config_dir_name = 'config'
342 return os.path.join(get_path('stdlib'), config_dir_name, 'Makefile')
Tarek Ziadéedacea32010-01-29 11:41:03 +0000343
Antoine Pitrou1e73a242011-10-18 17:52:24 +0200344def _generate_posix_vars():
345 """Generate the Python module containing build-time variables."""
346 import pprint
347 vars = {}
Tarek Ziadéedacea32010-01-29 11:41:03 +0000348 # load the installed Makefile:
Barry Warsawebbef6f2010-09-20 15:29:53 +0000349 makefile = get_makefile_filename()
Tarek Ziadéedacea32010-01-29 11:41:03 +0000350 try:
351 _parse_makefile(makefile, vars)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200352 except OSError as e:
Tarek Ziadéedacea32010-01-29 11:41:03 +0000353 msg = "invalid Python installation: unable to open %s" % makefile
354 if hasattr(e, "strerror"):
355 msg = msg + " (%s)" % e.strerror
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200356 raise OSError(msg)
Tarek Ziadéedacea32010-01-29 11:41:03 +0000357 # load the installed pyconfig.h:
358 config_h = get_config_h_filename()
359 try:
Antoine Pitroub86680e2010-10-14 21:15:17 +0000360 with open(config_h) as f:
361 parse_config_h(f, vars)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200362 except OSError as e:
Tarek Ziadéedacea32010-01-29 11:41:03 +0000363 msg = "invalid Python installation: unable to open %s" % config_h
364 if hasattr(e, "strerror"):
365 msg = msg + " (%s)" % e.strerror
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200366 raise OSError(msg)
Tarek Ziadéedacea32010-01-29 11:41:03 +0000367 # On AIX, there are wrong paths to the linker scripts in the Makefile
368 # -- these paths are relative to the Python source, but when installed
369 # the scripts are in another directory.
370 if _PYTHON_BUILD:
371 vars['LDSHARED'] = vars['BLDSHARED']
Victor Stinner65651ea2011-10-20 00:41:21 +0200372
Trent Nelsonee528cc2012-10-17 04:23:50 -0400373 # There's a chicken-and-egg situation on OS X with regards to the
374 # _sysconfigdata module after the changes introduced by #15298:
375 # get_config_vars() is called by get_platform() as part of the
376 # `make pybuilddir.txt` target -- which is a precursor to the
377 # _sysconfigdata.py module being constructed. Unfortunately,
378 # get_config_vars() eventually calls _init_posix(), which attempts
Trent Nelsonecbe2a92012-10-17 18:03:24 -0400379 # to import _sysconfigdata, which we won't have built yet. In order
380 # for _init_posix() to work, if we're on Darwin, just mock up the
381 # _sysconfigdata module manually and populate it with the build vars.
382 # This is more than sufficient for ensuring the subsequent call to
383 # get_platform() succeeds.
384 name = '_sysconfigdata'
385 if 'darwin' in sys.platform:
386 import imp
387 module = imp.new_module(name)
388 module.build_time_vars = vars
389 sys.modules[name] = module
Tarek Ziadéedacea32010-01-29 11:41:03 +0000390
Trent Nelsonee528cc2012-10-17 04:23:50 -0400391 pybuilddir = 'build/lib.%s-%s' % (get_platform(), sys.version[:3])
392 if hasattr(sys, "gettotalrefcount"):
393 pybuilddir += '-pydebug'
394 os.makedirs(pybuilddir, exist_ok=True)
Trent Nelsonecbe2a92012-10-17 18:03:24 -0400395 destfile = os.path.join(pybuilddir, name + '.py')
Trent Nelsonee528cc2012-10-17 04:23:50 -0400396
Trent Nelsonecbe2a92012-10-17 18:03:24 -0400397 with open(destfile, 'w', encoding='utf8') as f:
398 f.write('# system configuration generated and used by'
399 ' the sysconfig module\n')
400 f.write('build_time_vars = ')
401 pprint.pprint(vars, stream=f)
Trent Nelsonee528cc2012-10-17 04:23:50 -0400402
Trent Nelsonc101bf32012-10-16 08:13:12 -0400403 # Create file used for sys.path fixup -- see Modules/getpath.c
404 with open('pybuilddir.txt', 'w', encoding='ascii') as f:
405 f.write(pybuilddir)
406
Antoine Pitrou1e73a242011-10-18 17:52:24 +0200407def _init_posix(vars):
408 """Initialize the module as appropriate for POSIX systems."""
409 # _sysconfigdata is generated at build time, see _generate_posix_vars()
410 from _sysconfigdata import build_time_vars
411 vars.update(build_time_vars)
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200412
Tarek Ziadéedacea32010-01-29 11:41:03 +0000413def _init_non_posix(vars):
414 """Initialize the module as appropriate for NT"""
415 # set basic install directories
416 vars['LIBDEST'] = get_path('stdlib')
417 vars['BINLIBDEST'] = get_path('platstdlib')
418 vars['INCLUDEPY'] = get_path('include')
419 vars['SO'] = '.pyd'
420 vars['EXE'] = '.exe'
421 vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT
Victor Stinnerb103a932010-10-12 22:23:23 +0000422 vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable))
Tarek Ziadéedacea32010-01-29 11:41:03 +0000423
424#
425# public APIs
426#
427
Tarek Ziadébd797682010-02-02 23:16:13 +0000428
429def parse_config_h(fp, vars=None):
430 """Parse a config.h-style file.
431
432 A dictionary containing name/value pairs is returned. If an
433 optional dictionary is passed in as the second argument, it is
434 used instead of a new dictionary.
435 """
Tarek Ziadébd797682010-02-02 23:16:13 +0000436 if vars is None:
437 vars = {}
438 define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n")
439 undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n")
440
441 while True:
442 line = fp.readline()
443 if not line:
444 break
445 m = define_rx.match(line)
446 if m:
447 n, v = m.group(1, 2)
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200448 try:
449 v = int(v)
450 except ValueError:
451 pass
Tarek Ziadébd797682010-02-02 23:16:13 +0000452 vars[n] = v
453 else:
454 m = undef_rx.match(line)
455 if m:
456 vars[m.group(1)] = 0
457 return vars
458
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200459
Tarek Ziadébd797682010-02-02 23:16:13 +0000460def get_config_h_filename():
Éric Araujo300623d2010-11-22 01:19:20 +0000461 """Return the path of pyconfig.h."""
Tarek Ziadébd797682010-02-02 23:16:13 +0000462 if _PYTHON_BUILD:
463 if os.name == "nt":
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100464 inc_dir = os.path.join(_sys_home or _PROJECT_BASE, "PC")
Tarek Ziadébd797682010-02-02 23:16:13 +0000465 else:
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100466 inc_dir = _sys_home or _PROJECT_BASE
Tarek Ziadébd797682010-02-02 23:16:13 +0000467 else:
468 inc_dir = get_path('platinclude')
469 return os.path.join(inc_dir, 'pyconfig.h')
470
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200471
Tarek Ziadéedacea32010-01-29 11:41:03 +0000472def get_scheme_names():
Éric Araujo300623d2010-11-22 01:19:20 +0000473 """Return a tuple containing the schemes names."""
Éric Araujoec177c12012-06-24 03:27:43 -0400474 return tuple(sorted(_INSTALL_SCHEMES))
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200475
Tarek Ziadéedacea32010-01-29 11:41:03 +0000476
477def get_path_names():
Éric Araujo300623d2010-11-22 01:19:20 +0000478 """Return a tuple containing the paths names."""
Éric Araujoec177c12012-06-24 03:27:43 -0400479 return _SCHEME_KEYS
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200480
Tarek Ziadéedacea32010-01-29 11:41:03 +0000481
482def get_paths(scheme=_get_default_scheme(), vars=None, expand=True):
Éric Araujo300623d2010-11-22 01:19:20 +0000483 """Return a mapping containing an install scheme.
Tarek Ziadéedacea32010-01-29 11:41:03 +0000484
485 ``scheme`` is the install scheme name. If not provided, it will
486 return the default scheme for the current platform.
487 """
488 if expand:
489 return _expand_vars(scheme, vars)
490 else:
Éric Araujoec177c12012-06-24 03:27:43 -0400491 return _INSTALL_SCHEMES[scheme]
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200492
Tarek Ziadéedacea32010-01-29 11:41:03 +0000493
494def get_path(name, scheme=_get_default_scheme(), vars=None, expand=True):
Éric Araujo300623d2010-11-22 01:19:20 +0000495 """Return a path corresponding to the scheme.
Tarek Ziadéedacea32010-01-29 11:41:03 +0000496
497 ``scheme`` is the install scheme name.
498 """
499 return get_paths(scheme, vars, expand)[name]
500
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200501
Tarek Ziadéedacea32010-01-29 11:41:03 +0000502def get_config_vars(*args):
503 """With no arguments, return a dictionary of all configuration
504 variables relevant for the current platform.
505
506 On Unix, this means every variable defined in Python's installed Makefile;
Ned Deilydf8aa2b2012-07-21 05:36:30 -0700507 On Windows it's a much smaller set.
Tarek Ziadéedacea32010-01-29 11:41:03 +0000508
509 With arguments, return a list of values that result from looking up
510 each argument in the configuration variable dictionary.
511 """
Tarek Ziadéedacea32010-01-29 11:41:03 +0000512 global _CONFIG_VARS
513 if _CONFIG_VARS is None:
514 _CONFIG_VARS = {}
515 # Normalized versions of prefix and exec_prefix are handy to have;
516 # in fact, these are the standard versions used most places in the
Éric Araujo859aad62012-06-24 00:07:41 -0400517 # Distutils.
Tarek Ziadéedacea32010-01-29 11:41:03 +0000518 _CONFIG_VARS['prefix'] = _PREFIX
519 _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX
520 _CONFIG_VARS['py_version'] = _PY_VERSION
521 _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT
522 _CONFIG_VARS['py_version_nodot'] = _PY_VERSION[0] + _PY_VERSION[2]
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100523 _CONFIG_VARS['installed_base'] = _BASE_PREFIX
Tarek Ziadéedacea32010-01-29 11:41:03 +0000524 _CONFIG_VARS['base'] = _PREFIX
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100525 _CONFIG_VARS['installed_platbase'] = _BASE_EXEC_PREFIX
Tarek Ziadéedacea32010-01-29 11:41:03 +0000526 _CONFIG_VARS['platbase'] = _EXEC_PREFIX
Tarek Ziadéedacea32010-01-29 11:41:03 +0000527 _CONFIG_VARS['projectbase'] = _PROJECT_BASE
Barry Warsawd5eaa5f2010-11-25 01:34:47 +0000528 try:
529 _CONFIG_VARS['abiflags'] = sys.abiflags
530 except AttributeError:
531 # sys.abiflags may not be defined on all platforms.
532 _CONFIG_VARS['abiflags'] = ''
Tarek Ziadéedacea32010-01-29 11:41:03 +0000533
Jesus Cea4791a242012-10-05 03:15:39 +0200534 if os.name == 'nt':
Tarek Ziadéedacea32010-01-29 11:41:03 +0000535 _init_non_posix(_CONFIG_VARS)
536 if os.name == 'posix':
537 _init_posix(_CONFIG_VARS)
Ronald Oussoren4cda46a2010-05-08 10:49:43 +0000538 # Setting 'userbase' is done below the call to the
539 # init function to enable using 'get_config_var' in
540 # the init-function.
Éric Araujo2a7cc532011-11-07 09:18:30 +0100541 _CONFIG_VARS['userbase'] = _getuserbase()
Ronald Oussoren4cda46a2010-05-08 10:49:43 +0000542
Richard Oudkerk46874ad2012-07-27 12:06:55 +0100543 # Always convert srcdir to an absolute path
544 srcdir = _CONFIG_VARS.get('srcdir', _PROJECT_BASE)
545 if os.name == 'posix':
546 if _PYTHON_BUILD:
547 # If srcdir is a relative path (typically '.' or '..')
548 # then it should be interpreted relative to the directory
549 # containing Makefile.
550 base = os.path.dirname(get_makefile_filename())
551 srcdir = os.path.join(base, srcdir)
552 else:
553 # srcdir is not meaningful since the installation is
554 # spread about the filesystem. We choose the
555 # directory containing the Makefile since we know it
556 # exists.
557 srcdir = os.path.dirname(get_makefile_filename())
558 _CONFIG_VARS['srcdir'] = _safe_realpath(srcdir)
Tarek Ziadéedacea32010-01-29 11:41:03 +0000559
Ned Deilydf8aa2b2012-07-21 05:36:30 -0700560 # OS X platforms require special customization to handle
561 # multi-architecture, multi-os-version installers
Tarek Ziadéedacea32010-01-29 11:41:03 +0000562 if sys.platform == 'darwin':
Ned Deilydf8aa2b2012-07-21 05:36:30 -0700563 import _osx_support
564 _osx_support.customize_config_vars(_CONFIG_VARS)
Tarek Ziadéedacea32010-01-29 11:41:03 +0000565
566 if args:
567 vals = []
568 for name in args:
569 vals.append(_CONFIG_VARS.get(name))
570 return vals
571 else:
572 return _CONFIG_VARS
573
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200574
Tarek Ziadéedacea32010-01-29 11:41:03 +0000575def get_config_var(name):
576 """Return the value of a single variable using the dictionary returned by
577 'get_config_vars()'.
578
579 Equivalent to get_config_vars().get(name)
580 """
581 return get_config_vars().get(name)
582
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200583
Tarek Ziadéedacea32010-01-29 11:41:03 +0000584def get_platform():
585 """Return a string that identifies the current platform.
586
587 This is used mainly to distinguish platform-specific build directories and
588 platform-specific built distributions. Typically includes the OS name
589 and version and the architecture (as supplied by 'os.uname()'),
590 although the exact information included depends on the OS; eg. for IRIX
591 the architecture isn't particularly important (IRIX only runs on SGI
592 hardware), but for Linux the kernel version isn't particularly
593 important.
594
595 Examples of returned values:
596 linux-i586
597 linux-alpha (?)
598 solaris-2.6-sun4u
599 irix-5.3
600 irix64-6.2
601
602 Windows will return one of:
603 win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc)
604 win-ia64 (64bit Windows on Itanium)
605 win32 (all others - specifically, sys.platform is returned)
606
607 For other non-POSIX platforms, currently just returns 'sys.platform'.
608 """
Tarek Ziadéedacea32010-01-29 11:41:03 +0000609 if os.name == 'nt':
610 # sniff sys.version for architecture.
611 prefix = " bit ("
612 i = sys.version.find(prefix)
613 if i == -1:
614 return sys.platform
615 j = sys.version.find(")", i)
616 look = sys.version[i+len(prefix):j].lower()
617 if look == 'amd64':
618 return 'win-amd64'
619 if look == 'itanium':
620 return 'win-ia64'
621 return sys.platform
622
623 if os.name != "posix" or not hasattr(os, 'uname'):
Ned Deilydf8aa2b2012-07-21 05:36:30 -0700624 # XXX what about the architecture? NT is Intel or Alpha
Tarek Ziadéedacea32010-01-29 11:41:03 +0000625 return sys.platform
626
doko@ubuntu.com1abe1c52012-06-30 20:42:45 +0200627 # Set for cross builds explicitly
628 if "_PYTHON_HOST_PLATFORM" in os.environ:
629 return os.environ["_PYTHON_HOST_PLATFORM"]
630
Tarek Ziadéedacea32010-01-29 11:41:03 +0000631 # Try to distinguish various flavours of Unix
632 osname, host, release, version, machine = os.uname()
633
634 # Convert the OS name to lowercase, remove '/' characters
635 # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh")
636 osname = osname.lower().replace('/', '')
637 machine = machine.replace(' ', '_')
638 machine = machine.replace('/', '-')
639
640 if osname[:5] == "linux":
641 # At least on Linux/Intel, 'machine' is the processor --
642 # i386, etc.
643 # XXX what about Alpha, SPARC, etc?
644 return "%s-%s" % (osname, machine)
645 elif osname[:5] == "sunos":
646 if release[0] >= "5": # SunOS 5 == Solaris 2
647 osname = "solaris"
648 release = "%d.%s" % (int(release[0]) - 3, release[2:])
Jesus Cea1aa1cf32012-01-18 04:49:26 +0100649 # We can't use "platform.architecture()[0]" because a
650 # bootstrap problem. We use a dict to get an error
651 # if some suspicious happens.
652 bitness = {2147483647:"32bit", 9223372036854775807:"64bit"}
Jesus Cea031605a2012-01-18 05:04:49 +0100653 machine += ".%s" % bitness[sys.maxsize]
Tarek Ziadéedacea32010-01-29 11:41:03 +0000654 # fall through to standard osname-release-machine representation
655 elif osname[:4] == "irix": # could be "irix64"!
656 return "%s-%s" % (osname, release)
657 elif osname[:3] == "aix":
658 return "%s-%s.%s" % (osname, version, release)
659 elif osname[:6] == "cygwin":
660 osname = "cygwin"
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200661 rel_re = re.compile(r'[\d.]+')
Tarek Ziadéedacea32010-01-29 11:41:03 +0000662 m = rel_re.match(release)
663 if m:
664 release = m.group()
665 elif osname[:6] == "darwin":
Ned Deilydf8aa2b2012-07-21 05:36:30 -0700666 import _osx_support
667 osname, release, machine = _osx_support.get_platform_osx(
668 get_config_vars(),
669 osname, release, machine)
Tarek Ziadéedacea32010-01-29 11:41:03 +0000670
671 return "%s-%s-%s" % (osname, release, machine)
672
673
674def get_python_version():
675 return _PY_VERSION_SHORT
Tarek Ziadéa7514992010-05-25 09:44:36 +0000676
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200677
Tarek Ziadéa7514992010-05-25 09:44:36 +0000678def _print_dict(title, data):
679 for index, (key, value) in enumerate(sorted(data.items())):
680 if index == 0:
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200681 print('%s: ' % (title))
682 print('\t%s = "%s"' % (key, value))
683
Tarek Ziadéa7514992010-05-25 09:44:36 +0000684
685def _main():
Éric Araujo300623d2010-11-22 01:19:20 +0000686 """Display all information sysconfig detains."""
Antoine Pitrou1e73a242011-10-18 17:52:24 +0200687 if '--generate-posix-vars' in sys.argv:
688 _generate_posix_vars()
689 return
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200690 print('Platform: "%s"' % get_platform())
691 print('Python version: "%s"' % get_python_version())
692 print('Current installation scheme: "%s"' % _get_default_scheme())
Éric Araujo559b5f12011-05-25 18:21:43 +0200693 print()
Tarek Ziadéa7514992010-05-25 09:44:36 +0000694 _print_dict('Paths', get_paths())
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200695 print()
Tarek Ziadéa7514992010-05-25 09:44:36 +0000696 _print_dict('Variables', get_config_vars())
697
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200698
Tarek Ziadéa7514992010-05-25 09:44:36 +0000699if __name__ == '__main__':
700 _main()