Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hhhrrrttt222111
GitHub Repository: hhhrrrttt222111/Dorkify
Path: blob/master/venv/Lib/site-packages/setuptools/_distutils/sysconfig.py
811 views
1
"""Provide access to Python's configuration information. The specific
2
configuration variables available depend heavily on the platform and
3
configuration. The values may be retrieved using
4
get_config_var(name), and the list of variables is available via
5
get_config_vars().keys(). Additional convenience functions are also
6
available.
7
8
Written by: Fred L. Drake, Jr.
9
Email: <[email protected]>
10
"""
11
12
import _imp
13
import os
14
import re
15
import sys
16
17
from .errors import DistutilsPlatformError
18
19
IS_PYPY = '__pypy__' in sys.builtin_module_names
20
21
# These are needed in a couple of spots, so just compute them once.
22
PREFIX = os.path.normpath(sys.prefix)
23
EXEC_PREFIX = os.path.normpath(sys.exec_prefix)
24
BASE_PREFIX = os.path.normpath(sys.base_prefix)
25
BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix)
26
27
# Path to the base directory of the project. On Windows the binary may
28
# live in project/PCbuild/win32 or project/PCbuild/amd64.
29
# set for cross builds
30
if "_PYTHON_PROJECT_BASE" in os.environ:
31
project_base = os.path.abspath(os.environ["_PYTHON_PROJECT_BASE"])
32
else:
33
if sys.executable:
34
project_base = os.path.dirname(os.path.abspath(sys.executable))
35
else:
36
# sys.executable can be empty if argv[0] has been changed and Python is
37
# unable to retrieve the real program name
38
project_base = os.getcwd()
39
40
41
# python_build: (Boolean) if true, we're either building Python or
42
# building an extension with an un-installed Python, so we use
43
# different (hard-wired) directories.
44
def _is_python_source_dir(d):
45
for fn in ("Setup", "Setup.local"):
46
if os.path.isfile(os.path.join(d, "Modules", fn)):
47
return True
48
return False
49
50
_sys_home = getattr(sys, '_home', None)
51
52
if os.name == 'nt':
53
def _fix_pcbuild(d):
54
if d and os.path.normcase(d).startswith(
55
os.path.normcase(os.path.join(PREFIX, "PCbuild"))):
56
return PREFIX
57
return d
58
project_base = _fix_pcbuild(project_base)
59
_sys_home = _fix_pcbuild(_sys_home)
60
61
def _python_build():
62
if _sys_home:
63
return _is_python_source_dir(_sys_home)
64
return _is_python_source_dir(project_base)
65
66
python_build = _python_build()
67
68
69
# Calculate the build qualifier flags if they are defined. Adding the flags
70
# to the include and lib directories only makes sense for an installation, not
71
# an in-source build.
72
build_flags = ''
73
try:
74
if not python_build:
75
build_flags = sys.abiflags
76
except AttributeError:
77
# It's not a configure-based build, so the sys module doesn't have
78
# this attribute, which is fine.
79
pass
80
81
def get_python_version():
82
"""Return a string containing the major and minor Python version,
83
leaving off the patchlevel. Sample return values could be '1.5'
84
or '2.2'.
85
"""
86
return '%d.%d' % sys.version_info[:2]
87
88
89
def get_python_inc(plat_specific=0, prefix=None):
90
"""Return the directory containing installed Python header files.
91
92
If 'plat_specific' is false (the default), this is the path to the
93
non-platform-specific header files, i.e. Python.h and so on;
94
otherwise, this is the path to platform-specific header files
95
(namely pyconfig.h).
96
97
If 'prefix' is supplied, use it instead of sys.base_prefix or
98
sys.base_exec_prefix -- i.e., ignore 'plat_specific'.
99
"""
100
if prefix is None:
101
prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX
102
if IS_PYPY:
103
return os.path.join(prefix, 'include')
104
elif os.name == "posix":
105
if python_build:
106
# Assume the executable is in the build directory. The
107
# pyconfig.h file should be in the same directory. Since
108
# the build directory may not be the source directory, we
109
# must use "srcdir" from the makefile to find the "Include"
110
# directory.
111
if plat_specific:
112
return _sys_home or project_base
113
else:
114
incdir = os.path.join(get_config_var('srcdir'), 'Include')
115
return os.path.normpath(incdir)
116
python_dir = 'python' + get_python_version() + build_flags
117
return os.path.join(prefix, "include", python_dir)
118
elif os.name == "nt":
119
if python_build:
120
# Include both the include and PC dir to ensure we can find
121
# pyconfig.h
122
return (os.path.join(prefix, "include") + os.path.pathsep +
123
os.path.join(prefix, "PC"))
124
return os.path.join(prefix, "include")
125
else:
126
raise DistutilsPlatformError(
127
"I don't know where Python installs its C header files "
128
"on platform '%s'" % os.name)
129
130
131
def get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
132
"""Return the directory containing the Python library (standard or
133
site additions).
134
135
If 'plat_specific' is true, return the directory containing
136
platform-specific modules, i.e. any module from a non-pure-Python
137
module distribution; otherwise, return the platform-shared library
138
directory. If 'standard_lib' is true, return the directory
139
containing standard Python library modules; otherwise, return the
140
directory for site-specific modules.
141
142
If 'prefix' is supplied, use it instead of sys.base_prefix or
143
sys.base_exec_prefix -- i.e., ignore 'plat_specific'.
144
"""
145
if IS_PYPY:
146
# PyPy-specific schema
147
if prefix is None:
148
prefix = PREFIX
149
if standard_lib:
150
return os.path.join(prefix, "lib-python", sys.version[0])
151
return os.path.join(prefix, 'site-packages')
152
153
if prefix is None:
154
if standard_lib:
155
prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX
156
else:
157
prefix = plat_specific and EXEC_PREFIX or PREFIX
158
159
if os.name == "posix":
160
if plat_specific or standard_lib:
161
# Platform-specific modules (any module from a non-pure-Python
162
# module distribution) or standard Python library modules.
163
libdir = getattr(sys, "platlibdir", "lib")
164
else:
165
# Pure Python
166
libdir = "lib"
167
libpython = os.path.join(prefix, libdir,
168
"python" + get_python_version())
169
if standard_lib:
170
return libpython
171
else:
172
return os.path.join(libpython, "site-packages")
173
elif os.name == "nt":
174
if standard_lib:
175
return os.path.join(prefix, "Lib")
176
else:
177
return os.path.join(prefix, "Lib", "site-packages")
178
else:
179
raise DistutilsPlatformError(
180
"I don't know where Python installs its library "
181
"on platform '%s'" % os.name)
182
183
184
185
def customize_compiler(compiler):
186
"""Do any platform-specific customization of a CCompiler instance.
187
188
Mainly needed on Unix, so we can plug in the information that
189
varies across Unices and is stored in Python's Makefile.
190
"""
191
if compiler.compiler_type == "unix":
192
if sys.platform == "darwin":
193
# Perform first-time customization of compiler-related
194
# config vars on OS X now that we know we need a compiler.
195
# This is primarily to support Pythons from binary
196
# installers. The kind and paths to build tools on
197
# the user system may vary significantly from the system
198
# that Python itself was built on. Also the user OS
199
# version and build tools may not support the same set
200
# of CPU architectures for universal builds.
201
global _config_vars
202
# Use get_config_var() to ensure _config_vars is initialized.
203
if not get_config_var('CUSTOMIZED_OSX_COMPILER'):
204
import _osx_support
205
_osx_support.customize_compiler(_config_vars)
206
_config_vars['CUSTOMIZED_OSX_COMPILER'] = 'True'
207
208
(cc, cxx, cflags, ccshared, ldshared, shlib_suffix, ar, ar_flags) = \
209
get_config_vars('CC', 'CXX', 'CFLAGS',
210
'CCSHARED', 'LDSHARED', 'SHLIB_SUFFIX', 'AR', 'ARFLAGS')
211
212
if 'CC' in os.environ:
213
newcc = os.environ['CC']
214
if (sys.platform == 'darwin'
215
and 'LDSHARED' not in os.environ
216
and ldshared.startswith(cc)):
217
# On OS X, if CC is overridden, use that as the default
218
# command for LDSHARED as well
219
ldshared = newcc + ldshared[len(cc):]
220
cc = newcc
221
if 'CXX' in os.environ:
222
cxx = os.environ['CXX']
223
if 'LDSHARED' in os.environ:
224
ldshared = os.environ['LDSHARED']
225
if 'CPP' in os.environ:
226
cpp = os.environ['CPP']
227
else:
228
cpp = cc + " -E" # not always
229
if 'LDFLAGS' in os.environ:
230
ldshared = ldshared + ' ' + os.environ['LDFLAGS']
231
if 'CFLAGS' in os.environ:
232
cflags = cflags + ' ' + os.environ['CFLAGS']
233
ldshared = ldshared + ' ' + os.environ['CFLAGS']
234
if 'CPPFLAGS' in os.environ:
235
cpp = cpp + ' ' + os.environ['CPPFLAGS']
236
cflags = cflags + ' ' + os.environ['CPPFLAGS']
237
ldshared = ldshared + ' ' + os.environ['CPPFLAGS']
238
if 'AR' in os.environ:
239
ar = os.environ['AR']
240
if 'ARFLAGS' in os.environ:
241
archiver = ar + ' ' + os.environ['ARFLAGS']
242
else:
243
archiver = ar + ' ' + ar_flags
244
245
cc_cmd = cc + ' ' + cflags
246
compiler.set_executables(
247
preprocessor=cpp,
248
compiler=cc_cmd,
249
compiler_so=cc_cmd + ' ' + ccshared,
250
compiler_cxx=cxx,
251
linker_so=ldshared,
252
linker_exe=cc,
253
archiver=archiver)
254
255
compiler.shared_lib_extension = shlib_suffix
256
257
258
def get_config_h_filename():
259
"""Return full pathname of installed pyconfig.h file."""
260
if python_build:
261
if os.name == "nt":
262
inc_dir = os.path.join(_sys_home or project_base, "PC")
263
else:
264
inc_dir = _sys_home or project_base
265
else:
266
inc_dir = get_python_inc(plat_specific=1)
267
268
return os.path.join(inc_dir, 'pyconfig.h')
269
270
271
def get_makefile_filename():
272
"""Return full pathname of installed Makefile from the Python build."""
273
if python_build:
274
return os.path.join(_sys_home or project_base, "Makefile")
275
lib_dir = get_python_lib(plat_specific=0, standard_lib=1)
276
config_file = 'config-{}{}'.format(get_python_version(), build_flags)
277
if hasattr(sys.implementation, '_multiarch'):
278
config_file += '-%s' % sys.implementation._multiarch
279
return os.path.join(lib_dir, config_file, 'Makefile')
280
281
282
def parse_config_h(fp, g=None):
283
"""Parse a config.h-style file.
284
285
A dictionary containing name/value pairs is returned. If an
286
optional dictionary is passed in as the second argument, it is
287
used instead of a new dictionary.
288
"""
289
if g is None:
290
g = {}
291
define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n")
292
undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n")
293
#
294
while True:
295
line = fp.readline()
296
if not line:
297
break
298
m = define_rx.match(line)
299
if m:
300
n, v = m.group(1, 2)
301
try: v = int(v)
302
except ValueError: pass
303
g[n] = v
304
else:
305
m = undef_rx.match(line)
306
if m:
307
g[m.group(1)] = 0
308
return g
309
310
311
# Regexes needed for parsing Makefile (and similar syntaxes,
312
# like old-style Setup files).
313
_variable_rx = re.compile(r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)")
314
_findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)")
315
_findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}")
316
317
def parse_makefile(fn, g=None):
318
"""Parse a Makefile-style file.
319
320
A dictionary containing name/value pairs is returned. If an
321
optional dictionary is passed in as the second argument, it is
322
used instead of a new dictionary.
323
"""
324
from distutils.text_file import TextFile
325
fp = TextFile(fn, strip_comments=1, skip_blanks=1, join_lines=1, errors="surrogateescape")
326
327
if g is None:
328
g = {}
329
done = {}
330
notdone = {}
331
332
while True:
333
line = fp.readline()
334
if line is None: # eof
335
break
336
m = _variable_rx.match(line)
337
if m:
338
n, v = m.group(1, 2)
339
v = v.strip()
340
# `$$' is a literal `$' in make
341
tmpv = v.replace('$$', '')
342
343
if "$" in tmpv:
344
notdone[n] = v
345
else:
346
try:
347
v = int(v)
348
except ValueError:
349
# insert literal `$'
350
done[n] = v.replace('$$', '$')
351
else:
352
done[n] = v
353
354
# Variables with a 'PY_' prefix in the makefile. These need to
355
# be made available without that prefix through sysconfig.
356
# Special care is needed to ensure that variable expansion works, even
357
# if the expansion uses the name without a prefix.
358
renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS')
359
360
# do variable interpolation here
361
while notdone:
362
for name in list(notdone):
363
value = notdone[name]
364
m = _findvar1_rx.search(value) or _findvar2_rx.search(value)
365
if m:
366
n = m.group(1)
367
found = True
368
if n in done:
369
item = str(done[n])
370
elif n in notdone:
371
# get it on a subsequent round
372
found = False
373
elif n in os.environ:
374
# do it like make: fall back to environment
375
item = os.environ[n]
376
377
elif n in renamed_variables:
378
if name.startswith('PY_') and name[3:] in renamed_variables:
379
item = ""
380
381
elif 'PY_' + n in notdone:
382
found = False
383
384
else:
385
item = str(done['PY_' + n])
386
else:
387
done[n] = item = ""
388
if found:
389
after = value[m.end():]
390
value = value[:m.start()] + item + after
391
if "$" in after:
392
notdone[name] = value
393
else:
394
try: value = int(value)
395
except ValueError:
396
done[name] = value.strip()
397
else:
398
done[name] = value
399
del notdone[name]
400
401
if name.startswith('PY_') \
402
and name[3:] in renamed_variables:
403
404
name = name[3:]
405
if name not in done:
406
done[name] = value
407
else:
408
# bogus variable reference; just drop it since we can't deal
409
del notdone[name]
410
411
fp.close()
412
413
# strip spurious spaces
414
for k, v in done.items():
415
if isinstance(v, str):
416
done[k] = v.strip()
417
418
# save the results in the global dictionary
419
g.update(done)
420
return g
421
422
423
def expand_makefile_vars(s, vars):
424
"""Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in
425
'string' according to 'vars' (a dictionary mapping variable names to
426
values). Variables not present in 'vars' are silently expanded to the
427
empty string. The variable values in 'vars' should not contain further
428
variable expansions; if 'vars' is the output of 'parse_makefile()',
429
you're fine. Returns a variable-expanded version of 's'.
430
"""
431
432
# This algorithm does multiple expansion, so if vars['foo'] contains
433
# "${bar}", it will expand ${foo} to ${bar}, and then expand
434
# ${bar}... and so forth. This is fine as long as 'vars' comes from
435
# 'parse_makefile()', which takes care of such expansions eagerly,
436
# according to make's variable expansion semantics.
437
438
while True:
439
m = _findvar1_rx.search(s) or _findvar2_rx.search(s)
440
if m:
441
(beg, end) = m.span()
442
s = s[0:beg] + vars.get(m.group(1)) + s[end:]
443
else:
444
break
445
return s
446
447
448
_config_vars = None
449
450
def _init_posix():
451
"""Initialize the module as appropriate for POSIX systems."""
452
# _sysconfigdata is generated at build time, see the sysconfig module
453
name = os.environ.get('_PYTHON_SYSCONFIGDATA_NAME',
454
'_sysconfigdata_{abi}_{platform}_{multiarch}'.format(
455
abi=sys.abiflags,
456
platform=sys.platform,
457
multiarch=getattr(sys.implementation, '_multiarch', ''),
458
))
459
try:
460
_temp = __import__(name, globals(), locals(), ['build_time_vars'], 0)
461
except ImportError:
462
# Python 3.5 and pypy 7.3.1
463
_temp = __import__(
464
'_sysconfigdata', globals(), locals(), ['build_time_vars'], 0)
465
build_time_vars = _temp.build_time_vars
466
global _config_vars
467
_config_vars = {}
468
_config_vars.update(build_time_vars)
469
470
471
def _init_nt():
472
"""Initialize the module as appropriate for NT"""
473
g = {}
474
# set basic install directories
475
g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
476
g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
477
478
# XXX hmmm.. a normal install puts include files here
479
g['INCLUDEPY'] = get_python_inc(plat_specific=0)
480
481
g['EXT_SUFFIX'] = _imp.extension_suffixes()[0]
482
g['EXE'] = ".exe"
483
g['VERSION'] = get_python_version().replace(".", "")
484
g['BINDIR'] = os.path.dirname(os.path.abspath(sys.executable))
485
486
global _config_vars
487
_config_vars = g
488
489
490
def get_config_vars(*args):
491
"""With no arguments, return a dictionary of all configuration
492
variables relevant for the current platform. Generally this includes
493
everything needed to build extensions and install both pure modules and
494
extensions. On Unix, this means every variable defined in Python's
495
installed Makefile; on Windows it's a much smaller set.
496
497
With arguments, return a list of values that result from looking up
498
each argument in the configuration variable dictionary.
499
"""
500
global _config_vars
501
if _config_vars is None:
502
func = globals().get("_init_" + os.name)
503
if func:
504
func()
505
else:
506
_config_vars = {}
507
508
# Normalized versions of prefix and exec_prefix are handy to have;
509
# in fact, these are the standard versions used most places in the
510
# Distutils.
511
_config_vars['prefix'] = PREFIX
512
_config_vars['exec_prefix'] = EXEC_PREFIX
513
514
if not IS_PYPY:
515
# For backward compatibility, see issue19555
516
SO = _config_vars.get('EXT_SUFFIX')
517
if SO is not None:
518
_config_vars['SO'] = SO
519
520
# Always convert srcdir to an absolute path
521
srcdir = _config_vars.get('srcdir', project_base)
522
if os.name == 'posix':
523
if python_build:
524
# If srcdir is a relative path (typically '.' or '..')
525
# then it should be interpreted relative to the directory
526
# containing Makefile.
527
base = os.path.dirname(get_makefile_filename())
528
srcdir = os.path.join(base, srcdir)
529
else:
530
# srcdir is not meaningful since the installation is
531
# spread about the filesystem. We choose the
532
# directory containing the Makefile since we know it
533
# exists.
534
srcdir = os.path.dirname(get_makefile_filename())
535
_config_vars['srcdir'] = os.path.abspath(os.path.normpath(srcdir))
536
537
# Convert srcdir into an absolute path if it appears necessary.
538
# Normally it is relative to the build directory. However, during
539
# testing, for example, we might be running a non-installed python
540
# from a different directory.
541
if python_build and os.name == "posix":
542
base = project_base
543
if (not os.path.isabs(_config_vars['srcdir']) and
544
base != os.getcwd()):
545
# srcdir is relative and we are not in the same directory
546
# as the executable. Assume executable is in the build
547
# directory and make srcdir absolute.
548
srcdir = os.path.join(base, _config_vars['srcdir'])
549
_config_vars['srcdir'] = os.path.normpath(srcdir)
550
551
# OS X platforms require special customization to handle
552
# multi-architecture, multi-os-version installers
553
if sys.platform == 'darwin':
554
import _osx_support
555
_osx_support.customize_config_vars(_config_vars)
556
557
if args:
558
vals = []
559
for name in args:
560
vals.append(_config_vars.get(name))
561
return vals
562
else:
563
return _config_vars
564
565
def get_config_var(name):
566
"""Return the value of a single variable using the dictionary
567
returned by 'get_config_vars()'. Equivalent to
568
get_config_vars().get(name)
569
"""
570
if name == 'SO':
571
import warnings
572
warnings.warn('SO is deprecated, use EXT_SUFFIX', DeprecationWarning, 2)
573
return get_config_vars().get(name)
574
575