koichi12 commited on
Commit
2abe095
·
verified ·
1 Parent(s): c7d1343

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +2 -0
  2. .venv/lib/python3.11/site-packages/setuptools/__pycache__/__init__.cpython-311.pyc +0 -0
  3. .venv/lib/python3.11/site-packages/setuptools/__pycache__/_entry_points.cpython-311.pyc +0 -0
  4. .venv/lib/python3.11/site-packages/setuptools/__pycache__/_importlib.cpython-311.pyc +0 -0
  5. .venv/lib/python3.11/site-packages/setuptools/__pycache__/_path.cpython-311.pyc +0 -0
  6. .venv/lib/python3.11/site-packages/setuptools/__pycache__/_reqs.cpython-311.pyc +0 -0
  7. .venv/lib/python3.11/site-packages/setuptools/__pycache__/build_meta.cpython-311.pyc +0 -0
  8. .venv/lib/python3.11/site-packages/setuptools/__pycache__/dep_util.cpython-311.pyc +0 -0
  9. .venv/lib/python3.11/site-packages/setuptools/__pycache__/depends.cpython-311.pyc +0 -0
  10. .venv/lib/python3.11/site-packages/setuptools/__pycache__/dist.cpython-311.pyc +0 -0
  11. .venv/lib/python3.11/site-packages/setuptools/__pycache__/logging.cpython-311.pyc +0 -0
  12. .venv/lib/python3.11/site-packages/setuptools/__pycache__/namespaces.cpython-311.pyc +0 -0
  13. .venv/lib/python3.11/site-packages/setuptools/__pycache__/sandbox.cpython-311.pyc +0 -0
  14. .venv/lib/python3.11/site-packages/setuptools/__pycache__/unicode_utils.cpython-311.pyc +0 -0
  15. .venv/lib/python3.11/site-packages/setuptools/_distutils/__init__.py +24 -0
  16. .venv/lib/python3.11/site-packages/setuptools/_distutils/_collections.py +56 -0
  17. .venv/lib/python3.11/site-packages/setuptools/_distutils/_functools.py +20 -0
  18. .venv/lib/python3.11/site-packages/setuptools/_distutils/_macos_compat.py +12 -0
  19. .venv/lib/python3.11/site-packages/setuptools/_distutils/_msvccompiler.py +572 -0
  20. .venv/lib/python3.11/site-packages/setuptools/_distutils/archive_util.py +280 -0
  21. .venv/lib/python3.11/site-packages/setuptools/_distutils/bcppcompiler.py +408 -0
  22. .venv/lib/python3.11/site-packages/setuptools/_distutils/ccompiler.py +1220 -0
  23. .venv/lib/python3.11/site-packages/setuptools/_distutils/cmd.py +436 -0
  24. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/_framework_compat.cpython-311.pyc +0 -0
  25. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/bdist_dumb.cpython-311.pyc +0 -0
  26. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/bdist_rpm.cpython-311.pyc +0 -0
  27. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/build.cpython-311.pyc +0 -0
  28. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/build_clib.cpython-311.pyc +0 -0
  29. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/build_scripts.cpython-311.pyc +0 -0
  30. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/clean.cpython-311.pyc +0 -0
  31. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/install.cpython-311.pyc +0 -0
  32. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/install_data.cpython-311.pyc +0 -0
  33. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/install_headers.cpython-311.pyc +0 -0
  34. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/install_lib.cpython-311.pyc +0 -0
  35. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/install_scripts.cpython-311.pyc +0 -0
  36. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/py37compat.cpython-311.pyc +0 -0
  37. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/register.cpython-311.pyc +0 -0
  38. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/sdist.cpython-311.pyc +0 -0
  39. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/bdist_dumb.py +144 -0
  40. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/build.py +153 -0
  41. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/build_ext.py +787 -0
  42. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/build_py.py +407 -0
  43. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/build_scripts.py +173 -0
  44. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/config.py +377 -0
  45. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/install.py +814 -0
  46. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/install_data.py +84 -0
  47. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/install_egg_info.py +91 -0
  48. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/install_headers.py +45 -0
  49. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/install_lib.py +238 -0
  50. .venv/lib/python3.11/site-packages/setuptools/_distutils/command/install_scripts.py +61 -0
.gitattributes CHANGED
@@ -259,3 +259,5 @@ tuning-competition-baseline/.venv/lib/python3.11/site-packages/torch/_inductor/_
259
  .venv/lib/python3.11/site-packages/opencv_python_headless.libs/libswresample-3e7db482.so.4.7.100 filter=lfs diff=lfs merge=lfs -text
260
  .venv/lib/python3.11/site-packages/opencv_python_headless.libs/libquadmath-96973f99.so.0.0.0 filter=lfs diff=lfs merge=lfs -text
261
  .venv/lib/python3.11/site-packages/propcache/_helpers_c.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
 
 
 
259
  .venv/lib/python3.11/site-packages/opencv_python_headless.libs/libswresample-3e7db482.so.4.7.100 filter=lfs diff=lfs merge=lfs -text
260
  .venv/lib/python3.11/site-packages/opencv_python_headless.libs/libquadmath-96973f99.so.0.0.0 filter=lfs diff=lfs merge=lfs -text
261
  .venv/lib/python3.11/site-packages/propcache/_helpers_c.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
262
+ .venv/lib/python3.11/site-packages/setuptools/cli-arm64.exe filter=lfs diff=lfs merge=lfs -text
263
+ .venv/lib/python3.11/site-packages/setuptools/gui-arm64.exe filter=lfs diff=lfs merge=lfs -text
.venv/lib/python3.11/site-packages/setuptools/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (12.9 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/__pycache__/_entry_points.cpython-311.pyc ADDED
Binary file (4.79 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/__pycache__/_importlib.cpython-311.pyc ADDED
Binary file (1.95 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/__pycache__/_path.cpython-311.pyc ADDED
Binary file (1.47 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/__pycache__/_reqs.cpython-311.pyc ADDED
Binary file (1.13 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/__pycache__/build_meta.cpython-311.pyc ADDED
Binary file (28.1 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/__pycache__/dep_util.cpython-311.pyc ADDED
Binary file (1.29 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/__pycache__/depends.cpython-311.pyc ADDED
Binary file (7.97 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/__pycache__/dist.cpython-311.pyc ADDED
Binary file (64.1 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/__pycache__/logging.cpython-311.pyc ADDED
Binary file (2.04 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/__pycache__/namespaces.cpython-311.pyc ADDED
Binary file (5.66 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/__pycache__/sandbox.cpython-311.pyc ADDED
Binary file (27.3 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/__pycache__/unicode_utils.cpython-311.pyc ADDED
Binary file (1.82 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/_distutils/__init__.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils
2
+
3
+ The main package for the Python Module Distribution Utilities. Normally
4
+ used from a setup script as
5
+
6
+ from distutils.core import setup
7
+
8
+ setup (...)
9
+ """
10
+
11
+ import sys
12
+ import importlib
13
+
14
+ __version__ = sys.version[: sys.version.index(' ')]
15
+
16
+
17
+ try:
18
+ # Allow Debian and pkgsrc (only) to customize system
19
+ # behavior. Ref pypa/distutils#2 and pypa/distutils#16.
20
+ # This hook is deprecated and no other environments
21
+ # should use it.
22
+ importlib.import_module('_distutils_system_mod')
23
+ except ImportError:
24
+ pass
.venv/lib/python3.11/site-packages/setuptools/_distutils/_collections.py ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import collections
2
+ import itertools
3
+
4
+
5
+ # from jaraco.collections 3.5.1
6
+ class DictStack(list, collections.abc.Mapping):
7
+ """
8
+ A stack of dictionaries that behaves as a view on those dictionaries,
9
+ giving preference to the last.
10
+
11
+ >>> stack = DictStack([dict(a=1, c=2), dict(b=2, a=2)])
12
+ >>> stack['a']
13
+ 2
14
+ >>> stack['b']
15
+ 2
16
+ >>> stack['c']
17
+ 2
18
+ >>> len(stack)
19
+ 3
20
+ >>> stack.push(dict(a=3))
21
+ >>> stack['a']
22
+ 3
23
+ >>> set(stack.keys()) == set(['a', 'b', 'c'])
24
+ True
25
+ >>> set(stack.items()) == set([('a', 3), ('b', 2), ('c', 2)])
26
+ True
27
+ >>> dict(**stack) == dict(stack) == dict(a=3, c=2, b=2)
28
+ True
29
+ >>> d = stack.pop()
30
+ >>> stack['a']
31
+ 2
32
+ >>> d = stack.pop()
33
+ >>> stack['a']
34
+ 1
35
+ >>> stack.get('b', None)
36
+ >>> 'c' in stack
37
+ True
38
+ """
39
+
40
+ def __iter__(self):
41
+ dicts = list.__iter__(self)
42
+ return iter(set(itertools.chain.from_iterable(c.keys() for c in dicts)))
43
+
44
+ def __getitem__(self, key):
45
+ for scope in reversed(tuple(list.__iter__(self))):
46
+ if key in scope:
47
+ return scope[key]
48
+ raise KeyError(key)
49
+
50
+ push = list.append
51
+
52
+ def __contains__(self, other):
53
+ return collections.abc.Mapping.__contains__(self, other)
54
+
55
+ def __len__(self):
56
+ return len(list(iter(self)))
.venv/lib/python3.11/site-packages/setuptools/_distutils/_functools.py ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import functools
2
+
3
+
4
+ # from jaraco.functools 3.5
5
+ def pass_none(func):
6
+ """
7
+ Wrap func so it's not called if its first param is None
8
+
9
+ >>> print_text = pass_none(print)
10
+ >>> print_text('text')
11
+ text
12
+ >>> print_text(None)
13
+ """
14
+
15
+ @functools.wraps(func)
16
+ def wrapper(param, *args, **kwargs):
17
+ if param is not None:
18
+ return func(param, *args, **kwargs)
19
+
20
+ return wrapper
.venv/lib/python3.11/site-packages/setuptools/_distutils/_macos_compat.py ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+ import importlib
3
+
4
+
5
+ def bypass_compiler_fixup(cmd, args):
6
+ return cmd
7
+
8
+
9
+ if sys.platform == 'darwin':
10
+ compiler_fixup = importlib.import_module('_osx_support').compiler_fixup
11
+ else:
12
+ compiler_fixup = bypass_compiler_fixup
.venv/lib/python3.11/site-packages/setuptools/_distutils/_msvccompiler.py ADDED
@@ -0,0 +1,572 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils._msvccompiler
2
+
3
+ Contains MSVCCompiler, an implementation of the abstract CCompiler class
4
+ for Microsoft Visual Studio 2015.
5
+
6
+ The module is compatible with VS 2015 and later. You can find legacy support
7
+ for older versions in distutils.msvc9compiler and distutils.msvccompiler.
8
+ """
9
+
10
+ # Written by Perry Stoll
11
+ # hacked by Robin Becker and Thomas Heller to do a better job of
12
+ # finding DevStudio (through the registry)
13
+ # ported to VS 2005 and VS 2008 by Christian Heimes
14
+ # ported to VS 2015 by Steve Dower
15
+
16
+ import os
17
+ import subprocess
18
+ import contextlib
19
+ import warnings
20
+ import unittest.mock as mock
21
+
22
+ with contextlib.suppress(ImportError):
23
+ import winreg
24
+
25
+ from distutils.errors import (
26
+ DistutilsExecError,
27
+ DistutilsPlatformError,
28
+ CompileError,
29
+ LibError,
30
+ LinkError,
31
+ )
32
+ from distutils.ccompiler import CCompiler, gen_lib_options
33
+ from distutils import log
34
+ from distutils.util import get_platform
35
+
36
+ from itertools import count
37
+
38
+
39
+ def _find_vc2015():
40
+ try:
41
+ key = winreg.OpenKeyEx(
42
+ winreg.HKEY_LOCAL_MACHINE,
43
+ r"Software\Microsoft\VisualStudio\SxS\VC7",
44
+ access=winreg.KEY_READ | winreg.KEY_WOW64_32KEY,
45
+ )
46
+ except OSError:
47
+ log.debug("Visual C++ is not registered")
48
+ return None, None
49
+
50
+ best_version = 0
51
+ best_dir = None
52
+ with key:
53
+ for i in count():
54
+ try:
55
+ v, vc_dir, vt = winreg.EnumValue(key, i)
56
+ except OSError:
57
+ break
58
+ if v and vt == winreg.REG_SZ and os.path.isdir(vc_dir):
59
+ try:
60
+ version = int(float(v))
61
+ except (ValueError, TypeError):
62
+ continue
63
+ if version >= 14 and version > best_version:
64
+ best_version, best_dir = version, vc_dir
65
+ return best_version, best_dir
66
+
67
+
68
+ def _find_vc2017():
69
+ """Returns "15, path" based on the result of invoking vswhere.exe
70
+ If no install is found, returns "None, None"
71
+
72
+ The version is returned to avoid unnecessarily changing the function
73
+ result. It may be ignored when the path is not None.
74
+
75
+ If vswhere.exe is not available, by definition, VS 2017 is not
76
+ installed.
77
+ """
78
+ root = os.environ.get("ProgramFiles(x86)") or os.environ.get("ProgramFiles")
79
+ if not root:
80
+ return None, None
81
+
82
+ try:
83
+ path = subprocess.check_output(
84
+ [
85
+ os.path.join(
86
+ root, "Microsoft Visual Studio", "Installer", "vswhere.exe"
87
+ ),
88
+ "-latest",
89
+ "-prerelease",
90
+ "-requires",
91
+ "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
92
+ "-property",
93
+ "installationPath",
94
+ "-products",
95
+ "*",
96
+ ],
97
+ encoding="mbcs",
98
+ errors="strict",
99
+ ).strip()
100
+ except (subprocess.CalledProcessError, OSError, UnicodeDecodeError):
101
+ return None, None
102
+
103
+ path = os.path.join(path, "VC", "Auxiliary", "Build")
104
+ if os.path.isdir(path):
105
+ return 15, path
106
+
107
+ return None, None
108
+
109
+
110
+ PLAT_SPEC_TO_RUNTIME = {
111
+ 'x86': 'x86',
112
+ 'x86_amd64': 'x64',
113
+ 'x86_arm': 'arm',
114
+ 'x86_arm64': 'arm64',
115
+ }
116
+
117
+
118
+ def _find_vcvarsall(plat_spec):
119
+ # bpo-38597: Removed vcruntime return value
120
+ _, best_dir = _find_vc2017()
121
+
122
+ if not best_dir:
123
+ best_version, best_dir = _find_vc2015()
124
+
125
+ if not best_dir:
126
+ log.debug("No suitable Visual C++ version found")
127
+ return None, None
128
+
129
+ vcvarsall = os.path.join(best_dir, "vcvarsall.bat")
130
+ if not os.path.isfile(vcvarsall):
131
+ log.debug("%s cannot be found", vcvarsall)
132
+ return None, None
133
+
134
+ return vcvarsall, None
135
+
136
+
137
+ def _get_vc_env(plat_spec):
138
+ if os.getenv("DISTUTILS_USE_SDK"):
139
+ return {key.lower(): value for key, value in os.environ.items()}
140
+
141
+ vcvarsall, _ = _find_vcvarsall(plat_spec)
142
+ if not vcvarsall:
143
+ raise DistutilsPlatformError("Unable to find vcvarsall.bat")
144
+
145
+ try:
146
+ out = subprocess.check_output(
147
+ f'cmd /u /c "{vcvarsall}" {plat_spec} && set',
148
+ stderr=subprocess.STDOUT,
149
+ ).decode('utf-16le', errors='replace')
150
+ except subprocess.CalledProcessError as exc:
151
+ log.error(exc.output)
152
+ raise DistutilsPlatformError(f"Error executing {exc.cmd}")
153
+
154
+ env = {
155
+ key.lower(): value
156
+ for key, _, value in (line.partition('=') for line in out.splitlines())
157
+ if key and value
158
+ }
159
+
160
+ return env
161
+
162
+
163
+ def _find_exe(exe, paths=None):
164
+ """Return path to an MSVC executable program.
165
+
166
+ Tries to find the program in several places: first, one of the
167
+ MSVC program search paths from the registry; next, the directories
168
+ in the PATH environment variable. If any of those work, return an
169
+ absolute path that is known to exist. If none of them work, just
170
+ return the original program name, 'exe'.
171
+ """
172
+ if not paths:
173
+ paths = os.getenv('path').split(os.pathsep)
174
+ for p in paths:
175
+ fn = os.path.join(os.path.abspath(p), exe)
176
+ if os.path.isfile(fn):
177
+ return fn
178
+ return exe
179
+
180
+
181
+ # A map keyed by get_platform() return values to values accepted by
182
+ # 'vcvarsall.bat'. Always cross-compile from x86 to work with the
183
+ # lighter-weight MSVC installs that do not include native 64-bit tools.
184
+ PLAT_TO_VCVARS = {
185
+ 'win32': 'x86',
186
+ 'win-amd64': 'x86_amd64',
187
+ 'win-arm32': 'x86_arm',
188
+ 'win-arm64': 'x86_arm64',
189
+ }
190
+
191
+
192
+ class MSVCCompiler(CCompiler):
193
+ """Concrete class that implements an interface to Microsoft Visual C++,
194
+ as defined by the CCompiler abstract class."""
195
+
196
+ compiler_type = 'msvc'
197
+
198
+ # Just set this so CCompiler's constructor doesn't barf. We currently
199
+ # don't use the 'set_executables()' bureaucracy provided by CCompiler,
200
+ # as it really isn't necessary for this sort of single-compiler class.
201
+ # Would be nice to have a consistent interface with UnixCCompiler,
202
+ # though, so it's worth thinking about.
203
+ executables = {}
204
+
205
+ # Private class data (need to distinguish C from C++ source for compiler)
206
+ _c_extensions = ['.c']
207
+ _cpp_extensions = ['.cc', '.cpp', '.cxx']
208
+ _rc_extensions = ['.rc']
209
+ _mc_extensions = ['.mc']
210
+
211
+ # Needed for the filename generation methods provided by the
212
+ # base class, CCompiler.
213
+ src_extensions = _c_extensions + _cpp_extensions + _rc_extensions + _mc_extensions
214
+ res_extension = '.res'
215
+ obj_extension = '.obj'
216
+ static_lib_extension = '.lib'
217
+ shared_lib_extension = '.dll'
218
+ static_lib_format = shared_lib_format = '%s%s'
219
+ exe_extension = '.exe'
220
+
221
+ def __init__(self, verbose=0, dry_run=0, force=0):
222
+ super().__init__(verbose, dry_run, force)
223
+ # target platform (.plat_name is consistent with 'bdist')
224
+ self.plat_name = None
225
+ self.initialized = False
226
+
227
+ @classmethod
228
+ def _configure(cls, vc_env):
229
+ """
230
+ Set class-level include/lib dirs.
231
+ """
232
+ cls.include_dirs = cls._parse_path(vc_env.get('include', ''))
233
+ cls.library_dirs = cls._parse_path(vc_env.get('lib', ''))
234
+
235
+ @staticmethod
236
+ def _parse_path(val):
237
+ return [dir.rstrip(os.sep) for dir in val.split(os.pathsep) if dir]
238
+
239
+ def initialize(self, plat_name=None):
240
+ # multi-init means we would need to check platform same each time...
241
+ assert not self.initialized, "don't init multiple times"
242
+ if plat_name is None:
243
+ plat_name = get_platform()
244
+ # sanity check for platforms to prevent obscure errors later.
245
+ if plat_name not in PLAT_TO_VCVARS:
246
+ raise DistutilsPlatformError(
247
+ f"--plat-name must be one of {tuple(PLAT_TO_VCVARS)}"
248
+ )
249
+
250
+ # Get the vcvarsall.bat spec for the requested platform.
251
+ plat_spec = PLAT_TO_VCVARS[plat_name]
252
+
253
+ vc_env = _get_vc_env(plat_spec)
254
+ if not vc_env:
255
+ raise DistutilsPlatformError(
256
+ "Unable to find a compatible " "Visual Studio installation."
257
+ )
258
+ self._configure(vc_env)
259
+
260
+ self._paths = vc_env.get('path', '')
261
+ paths = self._paths.split(os.pathsep)
262
+ self.cc = _find_exe("cl.exe", paths)
263
+ self.linker = _find_exe("link.exe", paths)
264
+ self.lib = _find_exe("lib.exe", paths)
265
+ self.rc = _find_exe("rc.exe", paths) # resource compiler
266
+ self.mc = _find_exe("mc.exe", paths) # message compiler
267
+ self.mt = _find_exe("mt.exe", paths) # message compiler
268
+
269
+ self.preprocess_options = None
270
+ # bpo-38597: Always compile with dynamic linking
271
+ # Future releases of Python 3.x will include all past
272
+ # versions of vcruntime*.dll for compatibility.
273
+ self.compile_options = ['/nologo', '/O2', '/W3', '/GL', '/DNDEBUG', '/MD']
274
+
275
+ self.compile_options_debug = [
276
+ '/nologo',
277
+ '/Od',
278
+ '/MDd',
279
+ '/Zi',
280
+ '/W3',
281
+ '/D_DEBUG',
282
+ ]
283
+
284
+ ldflags = ['/nologo', '/INCREMENTAL:NO', '/LTCG']
285
+
286
+ ldflags_debug = ['/nologo', '/INCREMENTAL:NO', '/LTCG', '/DEBUG:FULL']
287
+
288
+ self.ldflags_exe = [*ldflags, '/MANIFEST:EMBED,ID=1']
289
+ self.ldflags_exe_debug = [*ldflags_debug, '/MANIFEST:EMBED,ID=1']
290
+ self.ldflags_shared = [
291
+ *ldflags,
292
+ '/DLL',
293
+ '/MANIFEST:EMBED,ID=2',
294
+ '/MANIFESTUAC:NO',
295
+ ]
296
+ self.ldflags_shared_debug = [
297
+ *ldflags_debug,
298
+ '/DLL',
299
+ '/MANIFEST:EMBED,ID=2',
300
+ '/MANIFESTUAC:NO',
301
+ ]
302
+ self.ldflags_static = [*ldflags]
303
+ self.ldflags_static_debug = [*ldflags_debug]
304
+
305
+ self._ldflags = {
306
+ (CCompiler.EXECUTABLE, None): self.ldflags_exe,
307
+ (CCompiler.EXECUTABLE, False): self.ldflags_exe,
308
+ (CCompiler.EXECUTABLE, True): self.ldflags_exe_debug,
309
+ (CCompiler.SHARED_OBJECT, None): self.ldflags_shared,
310
+ (CCompiler.SHARED_OBJECT, False): self.ldflags_shared,
311
+ (CCompiler.SHARED_OBJECT, True): self.ldflags_shared_debug,
312
+ (CCompiler.SHARED_LIBRARY, None): self.ldflags_static,
313
+ (CCompiler.SHARED_LIBRARY, False): self.ldflags_static,
314
+ (CCompiler.SHARED_LIBRARY, True): self.ldflags_static_debug,
315
+ }
316
+
317
+ self.initialized = True
318
+
319
+ # -- Worker methods ------------------------------------------------
320
+
321
+ @property
322
+ def out_extensions(self):
323
+ return {
324
+ **super().out_extensions,
325
+ **{
326
+ ext: self.res_extension
327
+ for ext in self._rc_extensions + self._mc_extensions
328
+ },
329
+ }
330
+
331
+ def compile( # noqa: C901
332
+ self,
333
+ sources,
334
+ output_dir=None,
335
+ macros=None,
336
+ include_dirs=None,
337
+ debug=0,
338
+ extra_preargs=None,
339
+ extra_postargs=None,
340
+ depends=None,
341
+ ):
342
+
343
+ if not self.initialized:
344
+ self.initialize()
345
+ compile_info = self._setup_compile(
346
+ output_dir, macros, include_dirs, sources, depends, extra_postargs
347
+ )
348
+ macros, objects, extra_postargs, pp_opts, build = compile_info
349
+
350
+ compile_opts = extra_preargs or []
351
+ compile_opts.append('/c')
352
+ if debug:
353
+ compile_opts.extend(self.compile_options_debug)
354
+ else:
355
+ compile_opts.extend(self.compile_options)
356
+
357
+ add_cpp_opts = False
358
+
359
+ for obj in objects:
360
+ try:
361
+ src, ext = build[obj]
362
+ except KeyError:
363
+ continue
364
+ if debug:
365
+ # pass the full pathname to MSVC in debug mode,
366
+ # this allows the debugger to find the source file
367
+ # without asking the user to browse for it
368
+ src = os.path.abspath(src)
369
+
370
+ if ext in self._c_extensions:
371
+ input_opt = "/Tc" + src
372
+ elif ext in self._cpp_extensions:
373
+ input_opt = "/Tp" + src
374
+ add_cpp_opts = True
375
+ elif ext in self._rc_extensions:
376
+ # compile .RC to .RES file
377
+ input_opt = src
378
+ output_opt = "/fo" + obj
379
+ try:
380
+ self.spawn([self.rc] + pp_opts + [output_opt, input_opt])
381
+ except DistutilsExecError as msg:
382
+ raise CompileError(msg)
383
+ continue
384
+ elif ext in self._mc_extensions:
385
+ # Compile .MC to .RC file to .RES file.
386
+ # * '-h dir' specifies the directory for the
387
+ # generated include file
388
+ # * '-r dir' specifies the target directory of the
389
+ # generated RC file and the binary message resource
390
+ # it includes
391
+ #
392
+ # For now (since there are no options to change this),
393
+ # we use the source-directory for the include file and
394
+ # the build directory for the RC file and message
395
+ # resources. This works at least for win32all.
396
+ h_dir = os.path.dirname(src)
397
+ rc_dir = os.path.dirname(obj)
398
+ try:
399
+ # first compile .MC to .RC and .H file
400
+ self.spawn([self.mc, '-h', h_dir, '-r', rc_dir, src])
401
+ base, _ = os.path.splitext(os.path.basename(src))
402
+ rc_file = os.path.join(rc_dir, base + '.rc')
403
+ # then compile .RC to .RES file
404
+ self.spawn([self.rc, "/fo" + obj, rc_file])
405
+
406
+ except DistutilsExecError as msg:
407
+ raise CompileError(msg)
408
+ continue
409
+ else:
410
+ # how to handle this file?
411
+ raise CompileError(f"Don't know how to compile {src} to {obj}")
412
+
413
+ args = [self.cc] + compile_opts + pp_opts
414
+ if add_cpp_opts:
415
+ args.append('/EHsc')
416
+ args.append(input_opt)
417
+ args.append("/Fo" + obj)
418
+ args.extend(extra_postargs)
419
+
420
+ try:
421
+ self.spawn(args)
422
+ except DistutilsExecError as msg:
423
+ raise CompileError(msg)
424
+
425
+ return objects
426
+
427
+ def create_static_lib(
428
+ self, objects, output_libname, output_dir=None, debug=0, target_lang=None
429
+ ):
430
+
431
+ if not self.initialized:
432
+ self.initialize()
433
+ objects, output_dir = self._fix_object_args(objects, output_dir)
434
+ output_filename = self.library_filename(output_libname, output_dir=output_dir)
435
+
436
+ if self._need_link(objects, output_filename):
437
+ lib_args = objects + ['/OUT:' + output_filename]
438
+ if debug:
439
+ pass # XXX what goes here?
440
+ try:
441
+ log.debug('Executing "%s" %s', self.lib, ' '.join(lib_args))
442
+ self.spawn([self.lib] + lib_args)
443
+ except DistutilsExecError as msg:
444
+ raise LibError(msg)
445
+ else:
446
+ log.debug("skipping %s (up-to-date)", output_filename)
447
+
448
+ def link(
449
+ self,
450
+ target_desc,
451
+ objects,
452
+ output_filename,
453
+ output_dir=None,
454
+ libraries=None,
455
+ library_dirs=None,
456
+ runtime_library_dirs=None,
457
+ export_symbols=None,
458
+ debug=0,
459
+ extra_preargs=None,
460
+ extra_postargs=None,
461
+ build_temp=None,
462
+ target_lang=None,
463
+ ):
464
+
465
+ if not self.initialized:
466
+ self.initialize()
467
+ objects, output_dir = self._fix_object_args(objects, output_dir)
468
+ fixed_args = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs)
469
+ libraries, library_dirs, runtime_library_dirs = fixed_args
470
+
471
+ if runtime_library_dirs:
472
+ self.warn(
473
+ "I don't know what to do with 'runtime_library_dirs': "
474
+ + str(runtime_library_dirs)
475
+ )
476
+
477
+ lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries)
478
+ if output_dir is not None:
479
+ output_filename = os.path.join(output_dir, output_filename)
480
+
481
+ if self._need_link(objects, output_filename):
482
+ ldflags = self._ldflags[target_desc, debug]
483
+
484
+ export_opts = ["/EXPORT:" + sym for sym in (export_symbols or [])]
485
+
486
+ ld_args = (
487
+ ldflags + lib_opts + export_opts + objects + ['/OUT:' + output_filename]
488
+ )
489
+
490
+ # The MSVC linker generates .lib and .exp files, which cannot be
491
+ # suppressed by any linker switches. The .lib files may even be
492
+ # needed! Make sure they are generated in the temporary build
493
+ # directory. Since they have different names for debug and release
494
+ # builds, they can go into the same directory.
495
+ build_temp = os.path.dirname(objects[0])
496
+ if export_symbols is not None:
497
+ (dll_name, dll_ext) = os.path.splitext(
498
+ os.path.basename(output_filename)
499
+ )
500
+ implib_file = os.path.join(build_temp, self.library_filename(dll_name))
501
+ ld_args.append('/IMPLIB:' + implib_file)
502
+
503
+ if extra_preargs:
504
+ ld_args[:0] = extra_preargs
505
+ if extra_postargs:
506
+ ld_args.extend(extra_postargs)
507
+
508
+ output_dir = os.path.dirname(os.path.abspath(output_filename))
509
+ self.mkpath(output_dir)
510
+ try:
511
+ log.debug('Executing "%s" %s', self.linker, ' '.join(ld_args))
512
+ self.spawn([self.linker] + ld_args)
513
+ except DistutilsExecError as msg:
514
+ raise LinkError(msg)
515
+ else:
516
+ log.debug("skipping %s (up-to-date)", output_filename)
517
+
518
+ def spawn(self, cmd):
519
+ env = dict(os.environ, PATH=self._paths)
520
+ with self._fallback_spawn(cmd, env) as fallback:
521
+ return super().spawn(cmd, env=env)
522
+ return fallback.value
523
+
524
+ @contextlib.contextmanager
525
+ def _fallback_spawn(self, cmd, env):
526
+ """
527
+ Discovered in pypa/distutils#15, some tools monkeypatch the compiler,
528
+ so the 'env' kwarg causes a TypeError. Detect this condition and
529
+ restore the legacy, unsafe behavior.
530
+ """
531
+ bag = type('Bag', (), {})()
532
+ try:
533
+ yield bag
534
+ except TypeError as exc:
535
+ if "unexpected keyword argument 'env'" not in str(exc):
536
+ raise
537
+ else:
538
+ return
539
+ warnings.warn("Fallback spawn triggered. Please update distutils monkeypatch.")
540
+ with mock.patch.dict('os.environ', env):
541
+ bag.value = super().spawn(cmd)
542
+
543
+ # -- Miscellaneous methods -----------------------------------------
544
+ # These are all used by the 'gen_lib_options() function, in
545
+ # ccompiler.py.
546
+
547
+ def library_dir_option(self, dir):
548
+ return "/LIBPATH:" + dir
549
+
550
+ def runtime_library_dir_option(self, dir):
551
+ raise DistutilsPlatformError(
552
+ "don't know how to set runtime library search path for MSVC"
553
+ )
554
+
555
+ def library_option(self, lib):
556
+ return self.library_filename(lib)
557
+
558
+ def find_library_file(self, dirs, lib, debug=0):
559
+ # Prefer a debugging library if found (and requested), but deal
560
+ # with it if we don't have one.
561
+ if debug:
562
+ try_names = [lib + "_d", lib]
563
+ else:
564
+ try_names = [lib]
565
+ for dir in dirs:
566
+ for name in try_names:
567
+ libfile = os.path.join(dir, self.library_filename(name))
568
+ if os.path.isfile(libfile):
569
+ return libfile
570
+ else:
571
+ # Oops, didn't find it in *any* of 'dirs'
572
+ return None
.venv/lib/python3.11/site-packages/setuptools/_distutils/archive_util.py ADDED
@@ -0,0 +1,280 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils.archive_util
2
+
3
+ Utility functions for creating archive files (tarballs, zip files,
4
+ that sort of thing)."""
5
+
6
+ import os
7
+ from warnings import warn
8
+ import sys
9
+
10
+ try:
11
+ import zipfile
12
+ except ImportError:
13
+ zipfile = None
14
+
15
+
16
+ from distutils.errors import DistutilsExecError
17
+ from distutils.spawn import spawn
18
+ from distutils.dir_util import mkpath
19
+ from distutils import log
20
+
21
+ try:
22
+ from pwd import getpwnam
23
+ except ImportError:
24
+ getpwnam = None
25
+
26
+ try:
27
+ from grp import getgrnam
28
+ except ImportError:
29
+ getgrnam = None
30
+
31
+
32
+ def _get_gid(name):
33
+ """Returns a gid, given a group name."""
34
+ if getgrnam is None or name is None:
35
+ return None
36
+ try:
37
+ result = getgrnam(name)
38
+ except KeyError:
39
+ result = None
40
+ if result is not None:
41
+ return result[2]
42
+ return None
43
+
44
+
45
+ def _get_uid(name):
46
+ """Returns an uid, given a user name."""
47
+ if getpwnam is None or name is None:
48
+ return None
49
+ try:
50
+ result = getpwnam(name)
51
+ except KeyError:
52
+ result = None
53
+ if result is not None:
54
+ return result[2]
55
+ return None
56
+
57
+
58
+ def make_tarball(
59
+ base_name, base_dir, compress="gzip", verbose=0, dry_run=0, owner=None, group=None
60
+ ):
61
+ """Create a (possibly compressed) tar file from all the files under
62
+ 'base_dir'.
63
+
64
+ 'compress' must be "gzip" (the default), "bzip2", "xz", "compress", or
65
+ None. ("compress" will be deprecated in Python 3.2)
66
+
67
+ 'owner' and 'group' can be used to define an owner and a group for the
68
+ archive that is being built. If not provided, the current owner and group
69
+ will be used.
70
+
71
+ The output tar file will be named 'base_dir' + ".tar", possibly plus
72
+ the appropriate compression extension (".gz", ".bz2", ".xz" or ".Z").
73
+
74
+ Returns the output filename.
75
+ """
76
+ tar_compression = {
77
+ 'gzip': 'gz',
78
+ 'bzip2': 'bz2',
79
+ 'xz': 'xz',
80
+ None: '',
81
+ 'compress': '',
82
+ }
83
+ compress_ext = {'gzip': '.gz', 'bzip2': '.bz2', 'xz': '.xz', 'compress': '.Z'}
84
+
85
+ # flags for compression program, each element of list will be an argument
86
+ if compress is not None and compress not in compress_ext.keys():
87
+ raise ValueError(
88
+ "bad value for 'compress': must be None, 'gzip', 'bzip2', "
89
+ "'xz' or 'compress'"
90
+ )
91
+
92
+ archive_name = base_name + '.tar'
93
+ if compress != 'compress':
94
+ archive_name += compress_ext.get(compress, '')
95
+
96
+ mkpath(os.path.dirname(archive_name), dry_run=dry_run)
97
+
98
+ # creating the tarball
99
+ import tarfile # late import so Python build itself doesn't break
100
+
101
+ log.info('Creating tar archive')
102
+
103
+ uid = _get_uid(owner)
104
+ gid = _get_gid(group)
105
+
106
+ def _set_uid_gid(tarinfo):
107
+ if gid is not None:
108
+ tarinfo.gid = gid
109
+ tarinfo.gname = group
110
+ if uid is not None:
111
+ tarinfo.uid = uid
112
+ tarinfo.uname = owner
113
+ return tarinfo
114
+
115
+ if not dry_run:
116
+ tar = tarfile.open(archive_name, 'w|%s' % tar_compression[compress])
117
+ try:
118
+ tar.add(base_dir, filter=_set_uid_gid)
119
+ finally:
120
+ tar.close()
121
+
122
+ # compression using `compress`
123
+ if compress == 'compress':
124
+ warn("'compress' is deprecated.", DeprecationWarning)
125
+ # the option varies depending on the platform
126
+ compressed_name = archive_name + compress_ext[compress]
127
+ if sys.platform == 'win32':
128
+ cmd = [compress, archive_name, compressed_name]
129
+ else:
130
+ cmd = [compress, '-f', archive_name]
131
+ spawn(cmd, dry_run=dry_run)
132
+ return compressed_name
133
+
134
+ return archive_name
135
+
136
+
137
+ def make_zipfile(base_name, base_dir, verbose=0, dry_run=0): # noqa: C901
138
+ """Create a zip file from all the files under 'base_dir'.
139
+
140
+ The output zip file will be named 'base_name' + ".zip". Uses either the
141
+ "zipfile" Python module (if available) or the InfoZIP "zip" utility
142
+ (if installed and found on the default search path). If neither tool is
143
+ available, raises DistutilsExecError. Returns the name of the output zip
144
+ file.
145
+ """
146
+ zip_filename = base_name + ".zip"
147
+ mkpath(os.path.dirname(zip_filename), dry_run=dry_run)
148
+
149
+ # If zipfile module is not available, try spawning an external
150
+ # 'zip' command.
151
+ if zipfile is None:
152
+ if verbose:
153
+ zipoptions = "-r"
154
+ else:
155
+ zipoptions = "-rq"
156
+
157
+ try:
158
+ spawn(["zip", zipoptions, zip_filename, base_dir], dry_run=dry_run)
159
+ except DistutilsExecError:
160
+ # XXX really should distinguish between "couldn't find
161
+ # external 'zip' command" and "zip failed".
162
+ raise DistutilsExecError(
163
+ (
164
+ "unable to create zip file '%s': "
165
+ "could neither import the 'zipfile' module nor "
166
+ "find a standalone zip utility"
167
+ )
168
+ % zip_filename
169
+ )
170
+
171
+ else:
172
+ log.info("creating '%s' and adding '%s' to it", zip_filename, base_dir)
173
+
174
+ if not dry_run:
175
+ try:
176
+ zip = zipfile.ZipFile(
177
+ zip_filename, "w", compression=zipfile.ZIP_DEFLATED
178
+ )
179
+ except RuntimeError:
180
+ zip = zipfile.ZipFile(zip_filename, "w", compression=zipfile.ZIP_STORED)
181
+
182
+ with zip:
183
+ if base_dir != os.curdir:
184
+ path = os.path.normpath(os.path.join(base_dir, ''))
185
+ zip.write(path, path)
186
+ log.info("adding '%s'", path)
187
+ for dirpath, dirnames, filenames in os.walk(base_dir):
188
+ for name in dirnames:
189
+ path = os.path.normpath(os.path.join(dirpath, name, ''))
190
+ zip.write(path, path)
191
+ log.info("adding '%s'", path)
192
+ for name in filenames:
193
+ path = os.path.normpath(os.path.join(dirpath, name))
194
+ if os.path.isfile(path):
195
+ zip.write(path, path)
196
+ log.info("adding '%s'", path)
197
+
198
+ return zip_filename
199
+
200
+
201
+ ARCHIVE_FORMATS = {
202
+ 'gztar': (make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"),
203
+ 'bztar': (make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"),
204
+ 'xztar': (make_tarball, [('compress', 'xz')], "xz'ed tar-file"),
205
+ 'ztar': (make_tarball, [('compress', 'compress')], "compressed tar file"),
206
+ 'tar': (make_tarball, [('compress', None)], "uncompressed tar file"),
207
+ 'zip': (make_zipfile, [], "ZIP file"),
208
+ }
209
+
210
+
211
+ def check_archive_formats(formats):
212
+ """Returns the first format from the 'format' list that is unknown.
213
+
214
+ If all formats are known, returns None
215
+ """
216
+ for format in formats:
217
+ if format not in ARCHIVE_FORMATS:
218
+ return format
219
+ return None
220
+
221
+
222
+ def make_archive(
223
+ base_name,
224
+ format,
225
+ root_dir=None,
226
+ base_dir=None,
227
+ verbose=0,
228
+ dry_run=0,
229
+ owner=None,
230
+ group=None,
231
+ ):
232
+ """Create an archive file (eg. zip or tar).
233
+
234
+ 'base_name' is the name of the file to create, minus any format-specific
235
+ extension; 'format' is the archive format: one of "zip", "tar", "gztar",
236
+ "bztar", "xztar", or "ztar".
237
+
238
+ 'root_dir' is a directory that will be the root directory of the
239
+ archive; ie. we typically chdir into 'root_dir' before creating the
240
+ archive. 'base_dir' is the directory where we start archiving from;
241
+ ie. 'base_dir' will be the common prefix of all files and
242
+ directories in the archive. 'root_dir' and 'base_dir' both default
243
+ to the current directory. Returns the name of the archive file.
244
+
245
+ 'owner' and 'group' are used when creating a tar archive. By default,
246
+ uses the current owner and group.
247
+ """
248
+ save_cwd = os.getcwd()
249
+ if root_dir is not None:
250
+ log.debug("changing into '%s'", root_dir)
251
+ base_name = os.path.abspath(base_name)
252
+ if not dry_run:
253
+ os.chdir(root_dir)
254
+
255
+ if base_dir is None:
256
+ base_dir = os.curdir
257
+
258
+ kwargs = {'dry_run': dry_run}
259
+
260
+ try:
261
+ format_info = ARCHIVE_FORMATS[format]
262
+ except KeyError:
263
+ raise ValueError("unknown archive format '%s'" % format)
264
+
265
+ func = format_info[0]
266
+ for arg, val in format_info[1]:
267
+ kwargs[arg] = val
268
+
269
+ if format != 'zip':
270
+ kwargs['owner'] = owner
271
+ kwargs['group'] = group
272
+
273
+ try:
274
+ filename = func(base_name, base_dir, **kwargs)
275
+ finally:
276
+ if root_dir is not None:
277
+ log.debug("changing back to '%s'", save_cwd)
278
+ os.chdir(save_cwd)
279
+
280
+ return filename
.venv/lib/python3.11/site-packages/setuptools/_distutils/bcppcompiler.py ADDED
@@ -0,0 +1,408 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils.bcppcompiler
2
+
3
+ Contains BorlandCCompiler, an implementation of the abstract CCompiler class
4
+ for the Borland C++ compiler.
5
+ """
6
+
7
+ # This implementation by Lyle Johnson, based on the original msvccompiler.py
8
+ # module and using the directions originally published by Gordon Williams.
9
+
10
+ # XXX looks like there's a LOT of overlap between these two classes:
11
+ # someone should sit down and factor out the common code as
12
+ # WindowsCCompiler! --GPW
13
+
14
+
15
+ import os
16
+ import warnings
17
+
18
+ from distutils.errors import (
19
+ DistutilsExecError,
20
+ CompileError,
21
+ LibError,
22
+ LinkError,
23
+ UnknownFileError,
24
+ )
25
+ from distutils.ccompiler import CCompiler, gen_preprocess_options
26
+ from distutils.file_util import write_file
27
+ from distutils.dep_util import newer
28
+ from distutils import log
29
+
30
+
31
+ warnings.warn(
32
+ "bcppcompiler is deprecated and slated to be removed "
33
+ "in the future. Please discontinue use or file an issue "
34
+ "with pypa/distutils describing your use case.",
35
+ DeprecationWarning,
36
+ )
37
+
38
+
39
+ class BCPPCompiler(CCompiler):
40
+ """Concrete class that implements an interface to the Borland C/C++
41
+ compiler, as defined by the CCompiler abstract class.
42
+ """
43
+
44
+ compiler_type = 'bcpp'
45
+
46
+ # Just set this so CCompiler's constructor doesn't barf. We currently
47
+ # don't use the 'set_executables()' bureaucracy provided by CCompiler,
48
+ # as it really isn't necessary for this sort of single-compiler class.
49
+ # Would be nice to have a consistent interface with UnixCCompiler,
50
+ # though, so it's worth thinking about.
51
+ executables = {}
52
+
53
+ # Private class data (need to distinguish C from C++ source for compiler)
54
+ _c_extensions = ['.c']
55
+ _cpp_extensions = ['.cc', '.cpp', '.cxx']
56
+
57
+ # Needed for the filename generation methods provided by the
58
+ # base class, CCompiler.
59
+ src_extensions = _c_extensions + _cpp_extensions
60
+ obj_extension = '.obj'
61
+ static_lib_extension = '.lib'
62
+ shared_lib_extension = '.dll'
63
+ static_lib_format = shared_lib_format = '%s%s'
64
+ exe_extension = '.exe'
65
+
66
+ def __init__(self, verbose=0, dry_run=0, force=0):
67
+
68
+ super().__init__(verbose, dry_run, force)
69
+
70
+ # These executables are assumed to all be in the path.
71
+ # Borland doesn't seem to use any special registry settings to
72
+ # indicate their installation locations.
73
+
74
+ self.cc = "bcc32.exe"
75
+ self.linker = "ilink32.exe"
76
+ self.lib = "tlib.exe"
77
+
78
+ self.preprocess_options = None
79
+ self.compile_options = ['/tWM', '/O2', '/q', '/g0']
80
+ self.compile_options_debug = ['/tWM', '/Od', '/q', '/g0']
81
+
82
+ self.ldflags_shared = ['/Tpd', '/Gn', '/q', '/x']
83
+ self.ldflags_shared_debug = ['/Tpd', '/Gn', '/q', '/x']
84
+ self.ldflags_static = []
85
+ self.ldflags_exe = ['/Gn', '/q', '/x']
86
+ self.ldflags_exe_debug = ['/Gn', '/q', '/x', '/r']
87
+
88
+ # -- Worker methods ------------------------------------------------
89
+
90
+ def compile( # noqa: C901
91
+ self,
92
+ sources,
93
+ output_dir=None,
94
+ macros=None,
95
+ include_dirs=None,
96
+ debug=0,
97
+ extra_preargs=None,
98
+ extra_postargs=None,
99
+ depends=None,
100
+ ):
101
+
102
+ macros, objects, extra_postargs, pp_opts, build = self._setup_compile(
103
+ output_dir, macros, include_dirs, sources, depends, extra_postargs
104
+ )
105
+ compile_opts = extra_preargs or []
106
+ compile_opts.append('-c')
107
+ if debug:
108
+ compile_opts.extend(self.compile_options_debug)
109
+ else:
110
+ compile_opts.extend(self.compile_options)
111
+
112
+ for obj in objects:
113
+ try:
114
+ src, ext = build[obj]
115
+ except KeyError:
116
+ continue
117
+ # XXX why do the normpath here?
118
+ src = os.path.normpath(src)
119
+ obj = os.path.normpath(obj)
120
+ # XXX _setup_compile() did a mkpath() too but before the normpath.
121
+ # Is it possible to skip the normpath?
122
+ self.mkpath(os.path.dirname(obj))
123
+
124
+ if ext == '.res':
125
+ # This is already a binary file -- skip it.
126
+ continue # the 'for' loop
127
+ if ext == '.rc':
128
+ # This needs to be compiled to a .res file -- do it now.
129
+ try:
130
+ self.spawn(["brcc32", "-fo", obj, src])
131
+ except DistutilsExecError as msg:
132
+ raise CompileError(msg)
133
+ continue # the 'for' loop
134
+
135
+ # The next two are both for the real compiler.
136
+ if ext in self._c_extensions:
137
+ input_opt = ""
138
+ elif ext in self._cpp_extensions:
139
+ input_opt = "-P"
140
+ else:
141
+ # Unknown file type -- no extra options. The compiler
142
+ # will probably fail, but let it just in case this is a
143
+ # file the compiler recognizes even if we don't.
144
+ input_opt = ""
145
+
146
+ output_opt = "-o" + obj
147
+
148
+ # Compiler command line syntax is: "bcc32 [options] file(s)".
149
+ # Note that the source file names must appear at the end of
150
+ # the command line.
151
+ try:
152
+ self.spawn(
153
+ [self.cc]
154
+ + compile_opts
155
+ + pp_opts
156
+ + [input_opt, output_opt]
157
+ + extra_postargs
158
+ + [src]
159
+ )
160
+ except DistutilsExecError as msg:
161
+ raise CompileError(msg)
162
+
163
+ return objects
164
+
165
+ # compile ()
166
+
167
+ def create_static_lib(
168
+ self, objects, output_libname, output_dir=None, debug=0, target_lang=None
169
+ ):
170
+
171
+ (objects, output_dir) = self._fix_object_args(objects, output_dir)
172
+ output_filename = self.library_filename(output_libname, output_dir=output_dir)
173
+
174
+ if self._need_link(objects, output_filename):
175
+ lib_args = [output_filename, '/u'] + objects
176
+ if debug:
177
+ pass # XXX what goes here?
178
+ try:
179
+ self.spawn([self.lib] + lib_args)
180
+ except DistutilsExecError as msg:
181
+ raise LibError(msg)
182
+ else:
183
+ log.debug("skipping %s (up-to-date)", output_filename)
184
+
185
+ # create_static_lib ()
186
+
187
+ def link( # noqa: C901
188
+ self,
189
+ target_desc,
190
+ objects,
191
+ output_filename,
192
+ output_dir=None,
193
+ libraries=None,
194
+ library_dirs=None,
195
+ runtime_library_dirs=None,
196
+ export_symbols=None,
197
+ debug=0,
198
+ extra_preargs=None,
199
+ extra_postargs=None,
200
+ build_temp=None,
201
+ target_lang=None,
202
+ ):
203
+
204
+ # XXX this ignores 'build_temp'! should follow the lead of
205
+ # msvccompiler.py
206
+
207
+ (objects, output_dir) = self._fix_object_args(objects, output_dir)
208
+ (libraries, library_dirs, runtime_library_dirs) = self._fix_lib_args(
209
+ libraries, library_dirs, runtime_library_dirs
210
+ )
211
+
212
+ if runtime_library_dirs:
213
+ log.warn(
214
+ "I don't know what to do with 'runtime_library_dirs': %s",
215
+ str(runtime_library_dirs),
216
+ )
217
+
218
+ if output_dir is not None:
219
+ output_filename = os.path.join(output_dir, output_filename)
220
+
221
+ if self._need_link(objects, output_filename):
222
+
223
+ # Figure out linker args based on type of target.
224
+ if target_desc == CCompiler.EXECUTABLE:
225
+ startup_obj = 'c0w32'
226
+ if debug:
227
+ ld_args = self.ldflags_exe_debug[:]
228
+ else:
229
+ ld_args = self.ldflags_exe[:]
230
+ else:
231
+ startup_obj = 'c0d32'
232
+ if debug:
233
+ ld_args = self.ldflags_shared_debug[:]
234
+ else:
235
+ ld_args = self.ldflags_shared[:]
236
+
237
+ # Create a temporary exports file for use by the linker
238
+ if export_symbols is None:
239
+ def_file = ''
240
+ else:
241
+ head, tail = os.path.split(output_filename)
242
+ modname, ext = os.path.splitext(tail)
243
+ temp_dir = os.path.dirname(objects[0]) # preserve tree structure
244
+ def_file = os.path.join(temp_dir, '%s.def' % modname)
245
+ contents = ['EXPORTS']
246
+ for sym in export_symbols or []:
247
+ contents.append(' {}=_{}'.format(sym, sym))
248
+ self.execute(write_file, (def_file, contents), "writing %s" % def_file)
249
+
250
+ # Borland C++ has problems with '/' in paths
251
+ objects2 = map(os.path.normpath, objects)
252
+ # split objects in .obj and .res files
253
+ # Borland C++ needs them at different positions in the command line
254
+ objects = [startup_obj]
255
+ resources = []
256
+ for file in objects2:
257
+ (base, ext) = os.path.splitext(os.path.normcase(file))
258
+ if ext == '.res':
259
+ resources.append(file)
260
+ else:
261
+ objects.append(file)
262
+
263
+ for ell in library_dirs:
264
+ ld_args.append("/L%s" % os.path.normpath(ell))
265
+ ld_args.append("/L.") # we sometimes use relative paths
266
+
267
+ # list of object files
268
+ ld_args.extend(objects)
269
+
270
+ # XXX the command-line syntax for Borland C++ is a bit wonky;
271
+ # certain filenames are jammed together in one big string, but
272
+ # comma-delimited. This doesn't mesh too well with the
273
+ # Unix-centric attitude (with a DOS/Windows quoting hack) of
274
+ # 'spawn()', so constructing the argument list is a bit
275
+ # awkward. Note that doing the obvious thing and jamming all
276
+ # the filenames and commas into one argument would be wrong,
277
+ # because 'spawn()' would quote any filenames with spaces in
278
+ # them. Arghghh!. Apparently it works fine as coded...
279
+
280
+ # name of dll/exe file
281
+ ld_args.extend([',', output_filename])
282
+ # no map file and start libraries
283
+ ld_args.append(',,')
284
+
285
+ for lib in libraries:
286
+ # see if we find it and if there is a bcpp specific lib
287
+ # (xxx_bcpp.lib)
288
+ libfile = self.find_library_file(library_dirs, lib, debug)
289
+ if libfile is None:
290
+ ld_args.append(lib)
291
+ # probably a BCPP internal library -- don't warn
292
+ else:
293
+ # full name which prefers bcpp_xxx.lib over xxx.lib
294
+ ld_args.append(libfile)
295
+
296
+ # some default libraries
297
+ ld_args.append('import32')
298
+ ld_args.append('cw32mt')
299
+
300
+ # def file for export symbols
301
+ ld_args.extend([',', def_file])
302
+ # add resource files
303
+ ld_args.append(',')
304
+ ld_args.extend(resources)
305
+
306
+ if extra_preargs:
307
+ ld_args[:0] = extra_preargs
308
+ if extra_postargs:
309
+ ld_args.extend(extra_postargs)
310
+
311
+ self.mkpath(os.path.dirname(output_filename))
312
+ try:
313
+ self.spawn([self.linker] + ld_args)
314
+ except DistutilsExecError as msg:
315
+ raise LinkError(msg)
316
+
317
+ else:
318
+ log.debug("skipping %s (up-to-date)", output_filename)
319
+
320
+ # link ()
321
+
322
+ # -- Miscellaneous methods -----------------------------------------
323
+
324
+ def find_library_file(self, dirs, lib, debug=0):
325
+ # List of effective library names to try, in order of preference:
326
+ # xxx_bcpp.lib is better than xxx.lib
327
+ # and xxx_d.lib is better than xxx.lib if debug is set
328
+ #
329
+ # The "_bcpp" suffix is to handle a Python installation for people
330
+ # with multiple compilers (primarily Distutils hackers, I suspect
331
+ # ;-). The idea is they'd have one static library for each
332
+ # compiler they care about, since (almost?) every Windows compiler
333
+ # seems to have a different format for static libraries.
334
+ if debug:
335
+ dlib = lib + "_d"
336
+ try_names = (dlib + "_bcpp", lib + "_bcpp", dlib, lib)
337
+ else:
338
+ try_names = (lib + "_bcpp", lib)
339
+
340
+ for dir in dirs:
341
+ for name in try_names:
342
+ libfile = os.path.join(dir, self.library_filename(name))
343
+ if os.path.exists(libfile):
344
+ return libfile
345
+ else:
346
+ # Oops, didn't find it in *any* of 'dirs'
347
+ return None
348
+
349
+ # overwrite the one from CCompiler to support rc and res-files
350
+ def object_filenames(self, source_filenames, strip_dir=0, output_dir=''):
351
+ if output_dir is None:
352
+ output_dir = ''
353
+ obj_names = []
354
+ for src_name in source_filenames:
355
+ # use normcase to make sure '.rc' is really '.rc' and not '.RC'
356
+ (base, ext) = os.path.splitext(os.path.normcase(src_name))
357
+ if ext not in (self.src_extensions + ['.rc', '.res']):
358
+ raise UnknownFileError(
359
+ "unknown file type '{}' (from '{}')".format(ext, src_name)
360
+ )
361
+ if strip_dir:
362
+ base = os.path.basename(base)
363
+ if ext == '.res':
364
+ # these can go unchanged
365
+ obj_names.append(os.path.join(output_dir, base + ext))
366
+ elif ext == '.rc':
367
+ # these need to be compiled to .res-files
368
+ obj_names.append(os.path.join(output_dir, base + '.res'))
369
+ else:
370
+ obj_names.append(os.path.join(output_dir, base + self.obj_extension))
371
+ return obj_names
372
+
373
+ # object_filenames ()
374
+
375
+ def preprocess(
376
+ self,
377
+ source,
378
+ output_file=None,
379
+ macros=None,
380
+ include_dirs=None,
381
+ extra_preargs=None,
382
+ extra_postargs=None,
383
+ ):
384
+
385
+ (_, macros, include_dirs) = self._fix_compile_args(None, macros, include_dirs)
386
+ pp_opts = gen_preprocess_options(macros, include_dirs)
387
+ pp_args = ['cpp32.exe'] + pp_opts
388
+ if output_file is not None:
389
+ pp_args.append('-o' + output_file)
390
+ if extra_preargs:
391
+ pp_args[:0] = extra_preargs
392
+ if extra_postargs:
393
+ pp_args.extend(extra_postargs)
394
+ pp_args.append(source)
395
+
396
+ # We need to preprocess: either we're being forced to, or the
397
+ # source file is newer than the target (or the target doesn't
398
+ # exist).
399
+ if self.force or output_file is None or newer(source, output_file):
400
+ if output_file:
401
+ self.mkpath(os.path.dirname(output_file))
402
+ try:
403
+ self.spawn(pp_args)
404
+ except DistutilsExecError as msg:
405
+ print(msg)
406
+ raise CompileError(msg)
407
+
408
+ # preprocess()
.venv/lib/python3.11/site-packages/setuptools/_distutils/ccompiler.py ADDED
@@ -0,0 +1,1220 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils.ccompiler
2
+
3
+ Contains CCompiler, an abstract base class that defines the interface
4
+ for the Distutils compiler abstraction model."""
5
+
6
+ import sys
7
+ import os
8
+ import re
9
+
10
+ from distutils.errors import (
11
+ CompileError,
12
+ LinkError,
13
+ UnknownFileError,
14
+ DistutilsPlatformError,
15
+ DistutilsModuleError,
16
+ )
17
+ from distutils.spawn import spawn
18
+ from distutils.file_util import move_file
19
+ from distutils.dir_util import mkpath
20
+ from distutils.dep_util import newer_group
21
+ from distutils.util import split_quoted, execute
22
+ from distutils import log
23
+
24
+
25
+ class CCompiler:
26
+ """Abstract base class to define the interface that must be implemented
27
+ by real compiler classes. Also has some utility methods used by
28
+ several compiler classes.
29
+
30
+ The basic idea behind a compiler abstraction class is that each
31
+ instance can be used for all the compile/link steps in building a
32
+ single project. Thus, attributes common to all of those compile and
33
+ link steps -- include directories, macros to define, libraries to link
34
+ against, etc. -- are attributes of the compiler instance. To allow for
35
+ variability in how individual files are treated, most of those
36
+ attributes may be varied on a per-compilation or per-link basis.
37
+ """
38
+
39
+ # 'compiler_type' is a class attribute that identifies this class. It
40
+ # keeps code that wants to know what kind of compiler it's dealing with
41
+ # from having to import all possible compiler classes just to do an
42
+ # 'isinstance'. In concrete CCompiler subclasses, 'compiler_type'
43
+ # should really, really be one of the keys of the 'compiler_class'
44
+ # dictionary (see below -- used by the 'new_compiler()' factory
45
+ # function) -- authors of new compiler interface classes are
46
+ # responsible for updating 'compiler_class'!
47
+ compiler_type = None
48
+
49
+ # XXX things not handled by this compiler abstraction model:
50
+ # * client can't provide additional options for a compiler,
51
+ # e.g. warning, optimization, debugging flags. Perhaps this
52
+ # should be the domain of concrete compiler abstraction classes
53
+ # (UnixCCompiler, MSVCCompiler, etc.) -- or perhaps the base
54
+ # class should have methods for the common ones.
55
+ # * can't completely override the include or library searchg
56
+ # path, ie. no "cc -I -Idir1 -Idir2" or "cc -L -Ldir1 -Ldir2".
57
+ # I'm not sure how widely supported this is even by Unix
58
+ # compilers, much less on other platforms. And I'm even less
59
+ # sure how useful it is; maybe for cross-compiling, but
60
+ # support for that is a ways off. (And anyways, cross
61
+ # compilers probably have a dedicated binary with the
62
+ # right paths compiled in. I hope.)
63
+ # * can't do really freaky things with the library list/library
64
+ # dirs, e.g. "-Ldir1 -lfoo -Ldir2 -lfoo" to link against
65
+ # different versions of libfoo.a in different locations. I
66
+ # think this is useless without the ability to null out the
67
+ # library search path anyways.
68
+
69
+ # Subclasses that rely on the standard filename generation methods
70
+ # implemented below should override these; see the comment near
71
+ # those methods ('object_filenames()' et. al.) for details:
72
+ src_extensions = None # list of strings
73
+ obj_extension = None # string
74
+ static_lib_extension = None
75
+ shared_lib_extension = None # string
76
+ static_lib_format = None # format string
77
+ shared_lib_format = None # prob. same as static_lib_format
78
+ exe_extension = None # string
79
+
80
+ # Default language settings. language_map is used to detect a source
81
+ # file or Extension target language, checking source filenames.
82
+ # language_order is used to detect the language precedence, when deciding
83
+ # what language to use when mixing source types. For example, if some
84
+ # extension has two files with ".c" extension, and one with ".cpp", it
85
+ # is still linked as c++.
86
+ language_map = {
87
+ ".c": "c",
88
+ ".cc": "c++",
89
+ ".cpp": "c++",
90
+ ".cxx": "c++",
91
+ ".m": "objc",
92
+ }
93
+ language_order = ["c++", "objc", "c"]
94
+
95
+ include_dirs = []
96
+ """
97
+ include dirs specific to this compiler class
98
+ """
99
+
100
+ library_dirs = []
101
+ """
102
+ library dirs specific to this compiler class
103
+ """
104
+
105
+ def __init__(self, verbose=0, dry_run=0, force=0):
106
+ self.dry_run = dry_run
107
+ self.force = force
108
+ self.verbose = verbose
109
+
110
+ # 'output_dir': a common output directory for object, library,
111
+ # shared object, and shared library files
112
+ self.output_dir = None
113
+
114
+ # 'macros': a list of macro definitions (or undefinitions). A
115
+ # macro definition is a 2-tuple (name, value), where the value is
116
+ # either a string or None (no explicit value). A macro
117
+ # undefinition is a 1-tuple (name,).
118
+ self.macros = []
119
+
120
+ # 'include_dirs': a list of directories to search for include files
121
+ self.include_dirs = []
122
+
123
+ # 'libraries': a list of libraries to include in any link
124
+ # (library names, not filenames: eg. "foo" not "libfoo.a")
125
+ self.libraries = []
126
+
127
+ # 'library_dirs': a list of directories to search for libraries
128
+ self.library_dirs = []
129
+
130
+ # 'runtime_library_dirs': a list of directories to search for
131
+ # shared libraries/objects at runtime
132
+ self.runtime_library_dirs = []
133
+
134
+ # 'objects': a list of object files (or similar, such as explicitly
135
+ # named library files) to include on any link
136
+ self.objects = []
137
+
138
+ for key in self.executables.keys():
139
+ self.set_executable(key, self.executables[key])
140
+
141
+ def set_executables(self, **kwargs):
142
+ """Define the executables (and options for them) that will be run
143
+ to perform the various stages of compilation. The exact set of
144
+ executables that may be specified here depends on the compiler
145
+ class (via the 'executables' class attribute), but most will have:
146
+ compiler the C/C++ compiler
147
+ linker_so linker used to create shared objects and libraries
148
+ linker_exe linker used to create binary executables
149
+ archiver static library creator
150
+
151
+ On platforms with a command-line (Unix, DOS/Windows), each of these
152
+ is a string that will be split into executable name and (optional)
153
+ list of arguments. (Splitting the string is done similarly to how
154
+ Unix shells operate: words are delimited by spaces, but quotes and
155
+ backslashes can override this. See
156
+ 'distutils.util.split_quoted()'.)
157
+ """
158
+
159
+ # Note that some CCompiler implementation classes will define class
160
+ # attributes 'cpp', 'cc', etc. with hard-coded executable names;
161
+ # this is appropriate when a compiler class is for exactly one
162
+ # compiler/OS combination (eg. MSVCCompiler). Other compiler
163
+ # classes (UnixCCompiler, in particular) are driven by information
164
+ # discovered at run-time, since there are many different ways to do
165
+ # basically the same things with Unix C compilers.
166
+
167
+ for key in kwargs:
168
+ if key not in self.executables:
169
+ raise ValueError(
170
+ "unknown executable '%s' for class %s"
171
+ % (key, self.__class__.__name__)
172
+ )
173
+ self.set_executable(key, kwargs[key])
174
+
175
+ def set_executable(self, key, value):
176
+ if isinstance(value, str):
177
+ setattr(self, key, split_quoted(value))
178
+ else:
179
+ setattr(self, key, value)
180
+
181
+ def _find_macro(self, name):
182
+ i = 0
183
+ for defn in self.macros:
184
+ if defn[0] == name:
185
+ return i
186
+ i += 1
187
+ return None
188
+
189
+ def _check_macro_definitions(self, definitions):
190
+ """Ensures that every element of 'definitions' is a valid macro
191
+ definition, ie. either (name,value) 2-tuple or a (name,) tuple. Do
192
+ nothing if all definitions are OK, raise TypeError otherwise.
193
+ """
194
+ for defn in definitions:
195
+ if not (
196
+ isinstance(defn, tuple)
197
+ and (
198
+ len(defn) in (1, 2)
199
+ and (isinstance(defn[1], str) or defn[1] is None)
200
+ )
201
+ and isinstance(defn[0], str)
202
+ ):
203
+ raise TypeError(
204
+ ("invalid macro definition '%s': " % defn)
205
+ + "must be tuple (string,), (string, string), or "
206
+ + "(string, None)"
207
+ )
208
+
209
+ # -- Bookkeeping methods -------------------------------------------
210
+
211
+ def define_macro(self, name, value=None):
212
+ """Define a preprocessor macro for all compilations driven by this
213
+ compiler object. The optional parameter 'value' should be a
214
+ string; if it is not supplied, then the macro will be defined
215
+ without an explicit value and the exact outcome depends on the
216
+ compiler used (XXX true? does ANSI say anything about this?)
217
+ """
218
+ # Delete from the list of macro definitions/undefinitions if
219
+ # already there (so that this one will take precedence).
220
+ i = self._find_macro(name)
221
+ if i is not None:
222
+ del self.macros[i]
223
+
224
+ self.macros.append((name, value))
225
+
226
+ def undefine_macro(self, name):
227
+ """Undefine a preprocessor macro for all compilations driven by
228
+ this compiler object. If the same macro is defined by
229
+ 'define_macro()' and undefined by 'undefine_macro()' the last call
230
+ takes precedence (including multiple redefinitions or
231
+ undefinitions). If the macro is redefined/undefined on a
232
+ per-compilation basis (ie. in the call to 'compile()'), then that
233
+ takes precedence.
234
+ """
235
+ # Delete from the list of macro definitions/undefinitions if
236
+ # already there (so that this one will take precedence).
237
+ i = self._find_macro(name)
238
+ if i is not None:
239
+ del self.macros[i]
240
+
241
+ undefn = (name,)
242
+ self.macros.append(undefn)
243
+
244
+ def add_include_dir(self, dir):
245
+ """Add 'dir' to the list of directories that will be searched for
246
+ header files. The compiler is instructed to search directories in
247
+ the order in which they are supplied by successive calls to
248
+ 'add_include_dir()'.
249
+ """
250
+ self.include_dirs.append(dir)
251
+
252
+ def set_include_dirs(self, dirs):
253
+ """Set the list of directories that will be searched to 'dirs' (a
254
+ list of strings). Overrides any preceding calls to
255
+ 'add_include_dir()'; subsequence calls to 'add_include_dir()' add
256
+ to the list passed to 'set_include_dirs()'. This does not affect
257
+ any list of standard include directories that the compiler may
258
+ search by default.
259
+ """
260
+ self.include_dirs = dirs[:]
261
+
262
+ def add_library(self, libname):
263
+ """Add 'libname' to the list of libraries that will be included in
264
+ all links driven by this compiler object. Note that 'libname'
265
+ should *not* be the name of a file containing a library, but the
266
+ name of the library itself: the actual filename will be inferred by
267
+ the linker, the compiler, or the compiler class (depending on the
268
+ platform).
269
+
270
+ The linker will be instructed to link against libraries in the
271
+ order they were supplied to 'add_library()' and/or
272
+ 'set_libraries()'. It is perfectly valid to duplicate library
273
+ names; the linker will be instructed to link against libraries as
274
+ many times as they are mentioned.
275
+ """
276
+ self.libraries.append(libname)
277
+
278
+ def set_libraries(self, libnames):
279
+ """Set the list of libraries to be included in all links driven by
280
+ this compiler object to 'libnames' (a list of strings). This does
281
+ not affect any standard system libraries that the linker may
282
+ include by default.
283
+ """
284
+ self.libraries = libnames[:]
285
+
286
+ def add_library_dir(self, dir):
287
+ """Add 'dir' to the list of directories that will be searched for
288
+ libraries specified to 'add_library()' and 'set_libraries()'. The
289
+ linker will be instructed to search for libraries in the order they
290
+ are supplied to 'add_library_dir()' and/or 'set_library_dirs()'.
291
+ """
292
+ self.library_dirs.append(dir)
293
+
294
+ def set_library_dirs(self, dirs):
295
+ """Set the list of library search directories to 'dirs' (a list of
296
+ strings). This does not affect any standard library search path
297
+ that the linker may search by default.
298
+ """
299
+ self.library_dirs = dirs[:]
300
+
301
+ def add_runtime_library_dir(self, dir):
302
+ """Add 'dir' to the list of directories that will be searched for
303
+ shared libraries at runtime.
304
+ """
305
+ self.runtime_library_dirs.append(dir)
306
+
307
+ def set_runtime_library_dirs(self, dirs):
308
+ """Set the list of directories to search for shared libraries at
309
+ runtime to 'dirs' (a list of strings). This does not affect any
310
+ standard search path that the runtime linker may search by
311
+ default.
312
+ """
313
+ self.runtime_library_dirs = dirs[:]
314
+
315
+ def add_link_object(self, object):
316
+ """Add 'object' to the list of object files (or analogues, such as
317
+ explicitly named library files or the output of "resource
318
+ compilers") to be included in every link driven by this compiler
319
+ object.
320
+ """
321
+ self.objects.append(object)
322
+
323
+ def set_link_objects(self, objects):
324
+ """Set the list of object files (or analogues) to be included in
325
+ every link to 'objects'. This does not affect any standard object
326
+ files that the linker may include by default (such as system
327
+ libraries).
328
+ """
329
+ self.objects = objects[:]
330
+
331
+ # -- Private utility methods --------------------------------------
332
+ # (here for the convenience of subclasses)
333
+
334
+ # Helper method to prep compiler in subclass compile() methods
335
+
336
+ def _setup_compile(self, outdir, macros, incdirs, sources, depends, extra):
337
+ """Process arguments and decide which source files to compile."""
338
+ outdir, macros, incdirs = self._fix_compile_args(outdir, macros, incdirs)
339
+
340
+ if extra is None:
341
+ extra = []
342
+
343
+ # Get the list of expected output (object) files
344
+ objects = self.object_filenames(sources, strip_dir=0, output_dir=outdir)
345
+ assert len(objects) == len(sources)
346
+
347
+ pp_opts = gen_preprocess_options(macros, incdirs)
348
+
349
+ build = {}
350
+ for i in range(len(sources)):
351
+ src = sources[i]
352
+ obj = objects[i]
353
+ ext = os.path.splitext(src)[1]
354
+ self.mkpath(os.path.dirname(obj))
355
+ build[obj] = (src, ext)
356
+
357
+ return macros, objects, extra, pp_opts, build
358
+
359
+ def _get_cc_args(self, pp_opts, debug, before):
360
+ # works for unixccompiler, cygwinccompiler
361
+ cc_args = pp_opts + ['-c']
362
+ if debug:
363
+ cc_args[:0] = ['-g']
364
+ if before:
365
+ cc_args[:0] = before
366
+ return cc_args
367
+
368
+ def _fix_compile_args(self, output_dir, macros, include_dirs):
369
+ """Typecheck and fix-up some of the arguments to the 'compile()'
370
+ method, and return fixed-up values. Specifically: if 'output_dir'
371
+ is None, replaces it with 'self.output_dir'; ensures that 'macros'
372
+ is a list, and augments it with 'self.macros'; ensures that
373
+ 'include_dirs' is a list, and augments it with 'self.include_dirs'.
374
+ Guarantees that the returned values are of the correct type,
375
+ i.e. for 'output_dir' either string or None, and for 'macros' and
376
+ 'include_dirs' either list or None.
377
+ """
378
+ if output_dir is None:
379
+ output_dir = self.output_dir
380
+ elif not isinstance(output_dir, str):
381
+ raise TypeError("'output_dir' must be a string or None")
382
+
383
+ if macros is None:
384
+ macros = self.macros
385
+ elif isinstance(macros, list):
386
+ macros = macros + (self.macros or [])
387
+ else:
388
+ raise TypeError("'macros' (if supplied) must be a list of tuples")
389
+
390
+ if include_dirs is None:
391
+ include_dirs = self.include_dirs
392
+ elif isinstance(include_dirs, (list, tuple)):
393
+ include_dirs = list(include_dirs) + (self.include_dirs or [])
394
+ else:
395
+ raise TypeError("'include_dirs' (if supplied) must be a list of strings")
396
+
397
+ # add include dirs for class
398
+ include_dirs += self.__class__.include_dirs
399
+
400
+ return output_dir, macros, include_dirs
401
+
402
+ def _prep_compile(self, sources, output_dir, depends=None):
403
+ """Decide which source files must be recompiled.
404
+
405
+ Determine the list of object files corresponding to 'sources',
406
+ and figure out which ones really need to be recompiled.
407
+ Return a list of all object files and a dictionary telling
408
+ which source files can be skipped.
409
+ """
410
+ # Get the list of expected output (object) files
411
+ objects = self.object_filenames(sources, output_dir=output_dir)
412
+ assert len(objects) == len(sources)
413
+
414
+ # Return an empty dict for the "which source files can be skipped"
415
+ # return value to preserve API compatibility.
416
+ return objects, {}
417
+
418
+ def _fix_object_args(self, objects, output_dir):
419
+ """Typecheck and fix up some arguments supplied to various methods.
420
+ Specifically: ensure that 'objects' is a list; if output_dir is
421
+ None, replace with self.output_dir. Return fixed versions of
422
+ 'objects' and 'output_dir'.
423
+ """
424
+ if not isinstance(objects, (list, tuple)):
425
+ raise TypeError("'objects' must be a list or tuple of strings")
426
+ objects = list(objects)
427
+
428
+ if output_dir is None:
429
+ output_dir = self.output_dir
430
+ elif not isinstance(output_dir, str):
431
+ raise TypeError("'output_dir' must be a string or None")
432
+
433
+ return (objects, output_dir)
434
+
435
+ def _fix_lib_args(self, libraries, library_dirs, runtime_library_dirs):
436
+ """Typecheck and fix up some of the arguments supplied to the
437
+ 'link_*' methods. Specifically: ensure that all arguments are
438
+ lists, and augment them with their permanent versions
439
+ (eg. 'self.libraries' augments 'libraries'). Return a tuple with
440
+ fixed versions of all arguments.
441
+ """
442
+ if libraries is None:
443
+ libraries = self.libraries
444
+ elif isinstance(libraries, (list, tuple)):
445
+ libraries = list(libraries) + (self.libraries or [])
446
+ else:
447
+ raise TypeError("'libraries' (if supplied) must be a list of strings")
448
+
449
+ if library_dirs is None:
450
+ library_dirs = self.library_dirs
451
+ elif isinstance(library_dirs, (list, tuple)):
452
+ library_dirs = list(library_dirs) + (self.library_dirs or [])
453
+ else:
454
+ raise TypeError("'library_dirs' (if supplied) must be a list of strings")
455
+
456
+ # add library dirs for class
457
+ library_dirs += self.__class__.library_dirs
458
+
459
+ if runtime_library_dirs is None:
460
+ runtime_library_dirs = self.runtime_library_dirs
461
+ elif isinstance(runtime_library_dirs, (list, tuple)):
462
+ runtime_library_dirs = list(runtime_library_dirs) + (
463
+ self.runtime_library_dirs or []
464
+ )
465
+ else:
466
+ raise TypeError(
467
+ "'runtime_library_dirs' (if supplied) " "must be a list of strings"
468
+ )
469
+
470
+ return (libraries, library_dirs, runtime_library_dirs)
471
+
472
+ def _need_link(self, objects, output_file):
473
+ """Return true if we need to relink the files listed in 'objects'
474
+ to recreate 'output_file'.
475
+ """
476
+ if self.force:
477
+ return True
478
+ else:
479
+ if self.dry_run:
480
+ newer = newer_group(objects, output_file, missing='newer')
481
+ else:
482
+ newer = newer_group(objects, output_file)
483
+ return newer
484
+
485
+ def detect_language(self, sources):
486
+ """Detect the language of a given file, or list of files. Uses
487
+ language_map, and language_order to do the job.
488
+ """
489
+ if not isinstance(sources, list):
490
+ sources = [sources]
491
+ lang = None
492
+ index = len(self.language_order)
493
+ for source in sources:
494
+ base, ext = os.path.splitext(source)
495
+ extlang = self.language_map.get(ext)
496
+ try:
497
+ extindex = self.language_order.index(extlang)
498
+ if extindex < index:
499
+ lang = extlang
500
+ index = extindex
501
+ except ValueError:
502
+ pass
503
+ return lang
504
+
505
+ # -- Worker methods ------------------------------------------------
506
+ # (must be implemented by subclasses)
507
+
508
+ def preprocess(
509
+ self,
510
+ source,
511
+ output_file=None,
512
+ macros=None,
513
+ include_dirs=None,
514
+ extra_preargs=None,
515
+ extra_postargs=None,
516
+ ):
517
+ """Preprocess a single C/C++ source file, named in 'source'.
518
+ Output will be written to file named 'output_file', or stdout if
519
+ 'output_file' not supplied. 'macros' is a list of macro
520
+ definitions as for 'compile()', which will augment the macros set
521
+ with 'define_macro()' and 'undefine_macro()'. 'include_dirs' is a
522
+ list of directory names that will be added to the default list.
523
+
524
+ Raises PreprocessError on failure.
525
+ """
526
+ pass
527
+
528
+ def compile(
529
+ self,
530
+ sources,
531
+ output_dir=None,
532
+ macros=None,
533
+ include_dirs=None,
534
+ debug=0,
535
+ extra_preargs=None,
536
+ extra_postargs=None,
537
+ depends=None,
538
+ ):
539
+ """Compile one or more source files.
540
+
541
+ 'sources' must be a list of filenames, most likely C/C++
542
+ files, but in reality anything that can be handled by a
543
+ particular compiler and compiler class (eg. MSVCCompiler can
544
+ handle resource files in 'sources'). Return a list of object
545
+ filenames, one per source filename in 'sources'. Depending on
546
+ the implementation, not all source files will necessarily be
547
+ compiled, but all corresponding object filenames will be
548
+ returned.
549
+
550
+ If 'output_dir' is given, object files will be put under it, while
551
+ retaining their original path component. That is, "foo/bar.c"
552
+ normally compiles to "foo/bar.o" (for a Unix implementation); if
553
+ 'output_dir' is "build", then it would compile to
554
+ "build/foo/bar.o".
555
+
556
+ 'macros', if given, must be a list of macro definitions. A macro
557
+ definition is either a (name, value) 2-tuple or a (name,) 1-tuple.
558
+ The former defines a macro; if the value is None, the macro is
559
+ defined without an explicit value. The 1-tuple case undefines a
560
+ macro. Later definitions/redefinitions/ undefinitions take
561
+ precedence.
562
+
563
+ 'include_dirs', if given, must be a list of strings, the
564
+ directories to add to the default include file search path for this
565
+ compilation only.
566
+
567
+ 'debug' is a boolean; if true, the compiler will be instructed to
568
+ output debug symbols in (or alongside) the object file(s).
569
+
570
+ 'extra_preargs' and 'extra_postargs' are implementation- dependent.
571
+ On platforms that have the notion of a command-line (e.g. Unix,
572
+ DOS/Windows), they are most likely lists of strings: extra
573
+ command-line arguments to prepend/append to the compiler command
574
+ line. On other platforms, consult the implementation class
575
+ documentation. In any event, they are intended as an escape hatch
576
+ for those occasions when the abstract compiler framework doesn't
577
+ cut the mustard.
578
+
579
+ 'depends', if given, is a list of filenames that all targets
580
+ depend on. If a source file is older than any file in
581
+ depends, then the source file will be recompiled. This
582
+ supports dependency tracking, but only at a coarse
583
+ granularity.
584
+
585
+ Raises CompileError on failure.
586
+ """
587
+ # A concrete compiler class can either override this method
588
+ # entirely or implement _compile().
589
+ macros, objects, extra_postargs, pp_opts, build = self._setup_compile(
590
+ output_dir, macros, include_dirs, sources, depends, extra_postargs
591
+ )
592
+ cc_args = self._get_cc_args(pp_opts, debug, extra_preargs)
593
+
594
+ for obj in objects:
595
+ try:
596
+ src, ext = build[obj]
597
+ except KeyError:
598
+ continue
599
+ self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts)
600
+
601
+ # Return *all* object filenames, not just the ones we just built.
602
+ return objects
603
+
604
+ def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
605
+ """Compile 'src' to product 'obj'."""
606
+ # A concrete compiler class that does not override compile()
607
+ # should implement _compile().
608
+ pass
609
+
610
+ def create_static_lib(
611
+ self, objects, output_libname, output_dir=None, debug=0, target_lang=None
612
+ ):
613
+ """Link a bunch of stuff together to create a static library file.
614
+ The "bunch of stuff" consists of the list of object files supplied
615
+ as 'objects', the extra object files supplied to
616
+ 'add_link_object()' and/or 'set_link_objects()', the libraries
617
+ supplied to 'add_library()' and/or 'set_libraries()', and the
618
+ libraries supplied as 'libraries' (if any).
619
+
620
+ 'output_libname' should be a library name, not a filename; the
621
+ filename will be inferred from the library name. 'output_dir' is
622
+ the directory where the library file will be put.
623
+
624
+ 'debug' is a boolean; if true, debugging information will be
625
+ included in the library (note that on most platforms, it is the
626
+ compile step where this matters: the 'debug' flag is included here
627
+ just for consistency).
628
+
629
+ 'target_lang' is the target language for which the given objects
630
+ are being compiled. This allows specific linkage time treatment of
631
+ certain languages.
632
+
633
+ Raises LibError on failure.
634
+ """
635
+ pass
636
+
637
+ # values for target_desc parameter in link()
638
+ SHARED_OBJECT = "shared_object"
639
+ SHARED_LIBRARY = "shared_library"
640
+ EXECUTABLE = "executable"
641
+
642
+ def link(
643
+ self,
644
+ target_desc,
645
+ objects,
646
+ output_filename,
647
+ output_dir=None,
648
+ libraries=None,
649
+ library_dirs=None,
650
+ runtime_library_dirs=None,
651
+ export_symbols=None,
652
+ debug=0,
653
+ extra_preargs=None,
654
+ extra_postargs=None,
655
+ build_temp=None,
656
+ target_lang=None,
657
+ ):
658
+ """Link a bunch of stuff together to create an executable or
659
+ shared library file.
660
+
661
+ The "bunch of stuff" consists of the list of object files supplied
662
+ as 'objects'. 'output_filename' should be a filename. If
663
+ 'output_dir' is supplied, 'output_filename' is relative to it
664
+ (i.e. 'output_filename' can provide directory components if
665
+ needed).
666
+
667
+ 'libraries' is a list of libraries to link against. These are
668
+ library names, not filenames, since they're translated into
669
+ filenames in a platform-specific way (eg. "foo" becomes "libfoo.a"
670
+ on Unix and "foo.lib" on DOS/Windows). However, they can include a
671
+ directory component, which means the linker will look in that
672
+ specific directory rather than searching all the normal locations.
673
+
674
+ 'library_dirs', if supplied, should be a list of directories to
675
+ search for libraries that were specified as bare library names
676
+ (ie. no directory component). These are on top of the system
677
+ default and those supplied to 'add_library_dir()' and/or
678
+ 'set_library_dirs()'. 'runtime_library_dirs' is a list of
679
+ directories that will be embedded into the shared library and used
680
+ to search for other shared libraries that *it* depends on at
681
+ run-time. (This may only be relevant on Unix.)
682
+
683
+ 'export_symbols' is a list of symbols that the shared library will
684
+ export. (This appears to be relevant only on Windows.)
685
+
686
+ 'debug' is as for 'compile()' and 'create_static_lib()', with the
687
+ slight distinction that it actually matters on most platforms (as
688
+ opposed to 'create_static_lib()', which includes a 'debug' flag
689
+ mostly for form's sake).
690
+
691
+ 'extra_preargs' and 'extra_postargs' are as for 'compile()' (except
692
+ of course that they supply command-line arguments for the
693
+ particular linker being used).
694
+
695
+ 'target_lang' is the target language for which the given objects
696
+ are being compiled. This allows specific linkage time treatment of
697
+ certain languages.
698
+
699
+ Raises LinkError on failure.
700
+ """
701
+ raise NotImplementedError
702
+
703
+ # Old 'link_*()' methods, rewritten to use the new 'link()' method.
704
+
705
+ def link_shared_lib(
706
+ self,
707
+ objects,
708
+ output_libname,
709
+ output_dir=None,
710
+ libraries=None,
711
+ library_dirs=None,
712
+ runtime_library_dirs=None,
713
+ export_symbols=None,
714
+ debug=0,
715
+ extra_preargs=None,
716
+ extra_postargs=None,
717
+ build_temp=None,
718
+ target_lang=None,
719
+ ):
720
+ self.link(
721
+ CCompiler.SHARED_LIBRARY,
722
+ objects,
723
+ self.library_filename(output_libname, lib_type='shared'),
724
+ output_dir,
725
+ libraries,
726
+ library_dirs,
727
+ runtime_library_dirs,
728
+ export_symbols,
729
+ debug,
730
+ extra_preargs,
731
+ extra_postargs,
732
+ build_temp,
733
+ target_lang,
734
+ )
735
+
736
+ def link_shared_object(
737
+ self,
738
+ objects,
739
+ output_filename,
740
+ output_dir=None,
741
+ libraries=None,
742
+ library_dirs=None,
743
+ runtime_library_dirs=None,
744
+ export_symbols=None,
745
+ debug=0,
746
+ extra_preargs=None,
747
+ extra_postargs=None,
748
+ build_temp=None,
749
+ target_lang=None,
750
+ ):
751
+ self.link(
752
+ CCompiler.SHARED_OBJECT,
753
+ objects,
754
+ output_filename,
755
+ output_dir,
756
+ libraries,
757
+ library_dirs,
758
+ runtime_library_dirs,
759
+ export_symbols,
760
+ debug,
761
+ extra_preargs,
762
+ extra_postargs,
763
+ build_temp,
764
+ target_lang,
765
+ )
766
+
767
+ def link_executable(
768
+ self,
769
+ objects,
770
+ output_progname,
771
+ output_dir=None,
772
+ libraries=None,
773
+ library_dirs=None,
774
+ runtime_library_dirs=None,
775
+ debug=0,
776
+ extra_preargs=None,
777
+ extra_postargs=None,
778
+ target_lang=None,
779
+ ):
780
+ self.link(
781
+ CCompiler.EXECUTABLE,
782
+ objects,
783
+ self.executable_filename(output_progname),
784
+ output_dir,
785
+ libraries,
786
+ library_dirs,
787
+ runtime_library_dirs,
788
+ None,
789
+ debug,
790
+ extra_preargs,
791
+ extra_postargs,
792
+ None,
793
+ target_lang,
794
+ )
795
+
796
+ # -- Miscellaneous methods -----------------------------------------
797
+ # These are all used by the 'gen_lib_options() function; there is
798
+ # no appropriate default implementation so subclasses should
799
+ # implement all of these.
800
+
801
+ def library_dir_option(self, dir):
802
+ """Return the compiler option to add 'dir' to the list of
803
+ directories searched for libraries.
804
+ """
805
+ raise NotImplementedError
806
+
807
+ def runtime_library_dir_option(self, dir):
808
+ """Return the compiler option to add 'dir' to the list of
809
+ directories searched for runtime libraries.
810
+ """
811
+ raise NotImplementedError
812
+
813
+ def library_option(self, lib):
814
+ """Return the compiler option to add 'lib' to the list of libraries
815
+ linked into the shared library or executable.
816
+ """
817
+ raise NotImplementedError
818
+
819
+ def has_function( # noqa: C901
820
+ self,
821
+ funcname,
822
+ includes=None,
823
+ include_dirs=None,
824
+ libraries=None,
825
+ library_dirs=None,
826
+ ):
827
+ """Return a boolean indicating whether funcname is supported on
828
+ the current platform. The optional arguments can be used to
829
+ augment the compilation environment.
830
+ """
831
+ # this can't be included at module scope because it tries to
832
+ # import math which might not be available at that point - maybe
833
+ # the necessary logic should just be inlined?
834
+ import tempfile
835
+
836
+ if includes is None:
837
+ includes = []
838
+ if include_dirs is None:
839
+ include_dirs = []
840
+ if libraries is None:
841
+ libraries = []
842
+ if library_dirs is None:
843
+ library_dirs = []
844
+ fd, fname = tempfile.mkstemp(".c", funcname, text=True)
845
+ f = os.fdopen(fd, "w")
846
+ try:
847
+ for incl in includes:
848
+ f.write("""#include "%s"\n""" % incl)
849
+ f.write(
850
+ """\
851
+ int main (int argc, char **argv) {
852
+ %s();
853
+ return 0;
854
+ }
855
+ """
856
+ % funcname
857
+ )
858
+ finally:
859
+ f.close()
860
+ try:
861
+ objects = self.compile([fname], include_dirs=include_dirs)
862
+ except CompileError:
863
+ return False
864
+ finally:
865
+ os.remove(fname)
866
+
867
+ try:
868
+ self.link_executable(
869
+ objects, "a.out", libraries=libraries, library_dirs=library_dirs
870
+ )
871
+ except (LinkError, TypeError):
872
+ return False
873
+ else:
874
+ os.remove(os.path.join(self.output_dir or '', "a.out"))
875
+ finally:
876
+ for fn in objects:
877
+ os.remove(fn)
878
+ return True
879
+
880
+ def find_library_file(self, dirs, lib, debug=0):
881
+ """Search the specified list of directories for a static or shared
882
+ library file 'lib' and return the full path to that file. If
883
+ 'debug' true, look for a debugging version (if that makes sense on
884
+ the current platform). Return None if 'lib' wasn't found in any of
885
+ the specified directories.
886
+ """
887
+ raise NotImplementedError
888
+
889
+ # -- Filename generation methods -----------------------------------
890
+
891
+ # The default implementation of the filename generating methods are
892
+ # prejudiced towards the Unix/DOS/Windows view of the world:
893
+ # * object files are named by replacing the source file extension
894
+ # (eg. .c/.cpp -> .o/.obj)
895
+ # * library files (shared or static) are named by plugging the
896
+ # library name and extension into a format string, eg.
897
+ # "lib%s.%s" % (lib_name, ".a") for Unix static libraries
898
+ # * executables are named by appending an extension (possibly
899
+ # empty) to the program name: eg. progname + ".exe" for
900
+ # Windows
901
+ #
902
+ # To reduce redundant code, these methods expect to find
903
+ # several attributes in the current object (presumably defined
904
+ # as class attributes):
905
+ # * src_extensions -
906
+ # list of C/C++ source file extensions, eg. ['.c', '.cpp']
907
+ # * obj_extension -
908
+ # object file extension, eg. '.o' or '.obj'
909
+ # * static_lib_extension -
910
+ # extension for static library files, eg. '.a' or '.lib'
911
+ # * shared_lib_extension -
912
+ # extension for shared library/object files, eg. '.so', '.dll'
913
+ # * static_lib_format -
914
+ # format string for generating static library filenames,
915
+ # eg. 'lib%s.%s' or '%s.%s'
916
+ # * shared_lib_format
917
+ # format string for generating shared library filenames
918
+ # (probably same as static_lib_format, since the extension
919
+ # is one of the intended parameters to the format string)
920
+ # * exe_extension -
921
+ # extension for executable files, eg. '' or '.exe'
922
+
923
+ def object_filenames(self, source_filenames, strip_dir=0, output_dir=''):
924
+ if output_dir is None:
925
+ output_dir = ''
926
+ return list(
927
+ self._make_out_path(output_dir, strip_dir, src_name)
928
+ for src_name in source_filenames
929
+ )
930
+
931
+ @property
932
+ def out_extensions(self):
933
+ return dict.fromkeys(self.src_extensions, self.obj_extension)
934
+
935
+ def _make_out_path(self, output_dir, strip_dir, src_name):
936
+ base, ext = os.path.splitext(src_name)
937
+ base = self._make_relative(base)
938
+ try:
939
+ new_ext = self.out_extensions[ext]
940
+ except LookupError:
941
+ raise UnknownFileError(
942
+ "unknown file type '{}' (from '{}')".format(ext, src_name)
943
+ )
944
+ if strip_dir:
945
+ base = os.path.basename(base)
946
+ return os.path.join(output_dir, base + new_ext)
947
+
948
+ @staticmethod
949
+ def _make_relative(base):
950
+ """
951
+ In order to ensure that a filename always honors the
952
+ indicated output_dir, make sure it's relative.
953
+ Ref python/cpython#37775.
954
+ """
955
+ # Chop off the drive
956
+ no_drive = os.path.splitdrive(base)[1]
957
+ # If abs, chop off leading /
958
+ return no_drive[os.path.isabs(no_drive) :]
959
+
960
+ def shared_object_filename(self, basename, strip_dir=0, output_dir=''):
961
+ assert output_dir is not None
962
+ if strip_dir:
963
+ basename = os.path.basename(basename)
964
+ return os.path.join(output_dir, basename + self.shared_lib_extension)
965
+
966
+ def executable_filename(self, basename, strip_dir=0, output_dir=''):
967
+ assert output_dir is not None
968
+ if strip_dir:
969
+ basename = os.path.basename(basename)
970
+ return os.path.join(output_dir, basename + (self.exe_extension or ''))
971
+
972
+ def library_filename(
973
+ self, libname, lib_type='static', strip_dir=0, output_dir='' # or 'shared'
974
+ ):
975
+ assert output_dir is not None
976
+ expected = '"static", "shared", "dylib", "xcode_stub"'
977
+ if lib_type not in eval(expected):
978
+ raise ValueError(f"'lib_type' must be {expected}")
979
+ fmt = getattr(self, lib_type + "_lib_format")
980
+ ext = getattr(self, lib_type + "_lib_extension")
981
+
982
+ dir, base = os.path.split(libname)
983
+ filename = fmt % (base, ext)
984
+ if strip_dir:
985
+ dir = ''
986
+
987
+ return os.path.join(output_dir, dir, filename)
988
+
989
+ # -- Utility methods -----------------------------------------------
990
+
991
+ def announce(self, msg, level=1):
992
+ log.debug(msg)
993
+
994
+ def debug_print(self, msg):
995
+ from distutils.debug import DEBUG
996
+
997
+ if DEBUG:
998
+ print(msg)
999
+
1000
+ def warn(self, msg):
1001
+ sys.stderr.write("warning: %s\n" % msg)
1002
+
1003
+ def execute(self, func, args, msg=None, level=1):
1004
+ execute(func, args, msg, self.dry_run)
1005
+
1006
+ def spawn(self, cmd, **kwargs):
1007
+ spawn(cmd, dry_run=self.dry_run, **kwargs)
1008
+
1009
+ def move_file(self, src, dst):
1010
+ return move_file(src, dst, dry_run=self.dry_run)
1011
+
1012
+ def mkpath(self, name, mode=0o777):
1013
+ mkpath(name, mode, dry_run=self.dry_run)
1014
+
1015
+
1016
+ # Map a sys.platform/os.name ('posix', 'nt') to the default compiler
1017
+ # type for that platform. Keys are interpreted as re match
1018
+ # patterns. Order is important; platform mappings are preferred over
1019
+ # OS names.
1020
+ _default_compilers = (
1021
+ # Platform string mappings
1022
+ # on a cygwin built python we can use gcc like an ordinary UNIXish
1023
+ # compiler
1024
+ ('cygwin.*', 'unix'),
1025
+ # OS name mappings
1026
+ ('posix', 'unix'),
1027
+ ('nt', 'msvc'),
1028
+ )
1029
+
1030
+
1031
+ def get_default_compiler(osname=None, platform=None):
1032
+ """Determine the default compiler to use for the given platform.
1033
+
1034
+ osname should be one of the standard Python OS names (i.e. the
1035
+ ones returned by os.name) and platform the common value
1036
+ returned by sys.platform for the platform in question.
1037
+
1038
+ The default values are os.name and sys.platform in case the
1039
+ parameters are not given.
1040
+ """
1041
+ if osname is None:
1042
+ osname = os.name
1043
+ if platform is None:
1044
+ platform = sys.platform
1045
+ for pattern, compiler in _default_compilers:
1046
+ if (
1047
+ re.match(pattern, platform) is not None
1048
+ or re.match(pattern, osname) is not None
1049
+ ):
1050
+ return compiler
1051
+ # Default to Unix compiler
1052
+ return 'unix'
1053
+
1054
+
1055
+ # Map compiler types to (module_name, class_name) pairs -- ie. where to
1056
+ # find the code that implements an interface to this compiler. (The module
1057
+ # is assumed to be in the 'distutils' package.)
1058
+ compiler_class = {
1059
+ 'unix': ('unixccompiler', 'UnixCCompiler', "standard UNIX-style compiler"),
1060
+ 'msvc': ('_msvccompiler', 'MSVCCompiler', "Microsoft Visual C++"),
1061
+ 'cygwin': (
1062
+ 'cygwinccompiler',
1063
+ 'CygwinCCompiler',
1064
+ "Cygwin port of GNU C Compiler for Win32",
1065
+ ),
1066
+ 'mingw32': (
1067
+ 'cygwinccompiler',
1068
+ 'Mingw32CCompiler',
1069
+ "Mingw32 port of GNU C Compiler for Win32",
1070
+ ),
1071
+ 'bcpp': ('bcppcompiler', 'BCPPCompiler', "Borland C++ Compiler"),
1072
+ }
1073
+
1074
+
1075
+ def show_compilers():
1076
+ """Print list of available compilers (used by the "--help-compiler"
1077
+ options to "build", "build_ext", "build_clib").
1078
+ """
1079
+ # XXX this "knows" that the compiler option it's describing is
1080
+ # "--compiler", which just happens to be the case for the three
1081
+ # commands that use it.
1082
+ from distutils.fancy_getopt import FancyGetopt
1083
+
1084
+ compilers = []
1085
+ for compiler in compiler_class.keys():
1086
+ compilers.append(("compiler=" + compiler, None, compiler_class[compiler][2]))
1087
+ compilers.sort()
1088
+ pretty_printer = FancyGetopt(compilers)
1089
+ pretty_printer.print_help("List of available compilers:")
1090
+
1091
+
1092
+ def new_compiler(plat=None, compiler=None, verbose=0, dry_run=0, force=0):
1093
+ """Generate an instance of some CCompiler subclass for the supplied
1094
+ platform/compiler combination. 'plat' defaults to 'os.name'
1095
+ (eg. 'posix', 'nt'), and 'compiler' defaults to the default compiler
1096
+ for that platform. Currently only 'posix' and 'nt' are supported, and
1097
+ the default compilers are "traditional Unix interface" (UnixCCompiler
1098
+ class) and Visual C++ (MSVCCompiler class). Note that it's perfectly
1099
+ possible to ask for a Unix compiler object under Windows, and a
1100
+ Microsoft compiler object under Unix -- if you supply a value for
1101
+ 'compiler', 'plat' is ignored.
1102
+ """
1103
+ if plat is None:
1104
+ plat = os.name
1105
+
1106
+ try:
1107
+ if compiler is None:
1108
+ compiler = get_default_compiler(plat)
1109
+
1110
+ (module_name, class_name, long_description) = compiler_class[compiler]
1111
+ except KeyError:
1112
+ msg = "don't know how to compile C/C++ code on platform '%s'" % plat
1113
+ if compiler is not None:
1114
+ msg = msg + " with '%s' compiler" % compiler
1115
+ raise DistutilsPlatformError(msg)
1116
+
1117
+ try:
1118
+ module_name = "distutils." + module_name
1119
+ __import__(module_name)
1120
+ module = sys.modules[module_name]
1121
+ klass = vars(module)[class_name]
1122
+ except ImportError:
1123
+ raise DistutilsModuleError(
1124
+ "can't compile C/C++ code: unable to load module '%s'" % module_name
1125
+ )
1126
+ except KeyError:
1127
+ raise DistutilsModuleError(
1128
+ "can't compile C/C++ code: unable to find class '%s' "
1129
+ "in module '%s'" % (class_name, module_name)
1130
+ )
1131
+
1132
+ # XXX The None is necessary to preserve backwards compatibility
1133
+ # with classes that expect verbose to be the first positional
1134
+ # argument.
1135
+ return klass(None, dry_run, force)
1136
+
1137
+
1138
+ def gen_preprocess_options(macros, include_dirs):
1139
+ """Generate C pre-processor options (-D, -U, -I) as used by at least
1140
+ two types of compilers: the typical Unix compiler and Visual C++.
1141
+ 'macros' is the usual thing, a list of 1- or 2-tuples, where (name,)
1142
+ means undefine (-U) macro 'name', and (name,value) means define (-D)
1143
+ macro 'name' to 'value'. 'include_dirs' is just a list of directory
1144
+ names to be added to the header file search path (-I). Returns a list
1145
+ of command-line options suitable for either Unix compilers or Visual
1146
+ C++.
1147
+ """
1148
+ # XXX it would be nice (mainly aesthetic, and so we don't generate
1149
+ # stupid-looking command lines) to go over 'macros' and eliminate
1150
+ # redundant definitions/undefinitions (ie. ensure that only the
1151
+ # latest mention of a particular macro winds up on the command
1152
+ # line). I don't think it's essential, though, since most (all?)
1153
+ # Unix C compilers only pay attention to the latest -D or -U
1154
+ # mention of a macro on their command line. Similar situation for
1155
+ # 'include_dirs'. I'm punting on both for now. Anyways, weeding out
1156
+ # redundancies like this should probably be the province of
1157
+ # CCompiler, since the data structures used are inherited from it
1158
+ # and therefore common to all CCompiler classes.
1159
+ pp_opts = []
1160
+ for macro in macros:
1161
+ if not (isinstance(macro, tuple) and 1 <= len(macro) <= 2):
1162
+ raise TypeError(
1163
+ "bad macro definition '%s': "
1164
+ "each element of 'macros' list must be a 1- or 2-tuple" % macro
1165
+ )
1166
+
1167
+ if len(macro) == 1: # undefine this macro
1168
+ pp_opts.append("-U%s" % macro[0])
1169
+ elif len(macro) == 2:
1170
+ if macro[1] is None: # define with no explicit value
1171
+ pp_opts.append("-D%s" % macro[0])
1172
+ else:
1173
+ # XXX *don't* need to be clever about quoting the
1174
+ # macro value here, because we're going to avoid the
1175
+ # shell at all costs when we spawn the command!
1176
+ pp_opts.append("-D%s=%s" % macro)
1177
+
1178
+ for dir in include_dirs:
1179
+ pp_opts.append("-I%s" % dir)
1180
+ return pp_opts
1181
+
1182
+
1183
+ def gen_lib_options(compiler, library_dirs, runtime_library_dirs, libraries):
1184
+ """Generate linker options for searching library directories and
1185
+ linking with specific libraries. 'libraries' and 'library_dirs' are,
1186
+ respectively, lists of library names (not filenames!) and search
1187
+ directories. Returns a list of command-line options suitable for use
1188
+ with some compiler (depending on the two format strings passed in).
1189
+ """
1190
+ lib_opts = []
1191
+
1192
+ for dir in library_dirs:
1193
+ lib_opts.append(compiler.library_dir_option(dir))
1194
+
1195
+ for dir in runtime_library_dirs:
1196
+ opt = compiler.runtime_library_dir_option(dir)
1197
+ if isinstance(opt, list):
1198
+ lib_opts = lib_opts + opt
1199
+ else:
1200
+ lib_opts.append(opt)
1201
+
1202
+ # XXX it's important that we *not* remove redundant library mentions!
1203
+ # sometimes you really do have to say "-lfoo -lbar -lfoo" in order to
1204
+ # resolve all symbols. I just hope we never have to say "-lfoo obj.o
1205
+ # -lbar" to get things to work -- that's certainly a possibility, but a
1206
+ # pretty nasty way to arrange your C code.
1207
+
1208
+ for lib in libraries:
1209
+ (lib_dir, lib_name) = os.path.split(lib)
1210
+ if lib_dir:
1211
+ lib_file = compiler.find_library_file([lib_dir], lib_name)
1212
+ if lib_file:
1213
+ lib_opts.append(lib_file)
1214
+ else:
1215
+ compiler.warn(
1216
+ "no library file corresponding to " "'%s' found (skipping)" % lib
1217
+ )
1218
+ else:
1219
+ lib_opts.append(compiler.library_option(lib))
1220
+ return lib_opts
.venv/lib/python3.11/site-packages/setuptools/_distutils/cmd.py ADDED
@@ -0,0 +1,436 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils.cmd
2
+
3
+ Provides the Command class, the base class for the command classes
4
+ in the distutils.command package.
5
+ """
6
+
7
+ import sys
8
+ import os
9
+ import re
10
+ from distutils.errors import DistutilsOptionError
11
+ from distutils import util, dir_util, file_util, archive_util, dep_util
12
+ from distutils import log
13
+
14
+
15
+ class Command:
16
+ """Abstract base class for defining command classes, the "worker bees"
17
+ of the Distutils. A useful analogy for command classes is to think of
18
+ them as subroutines with local variables called "options". The options
19
+ are "declared" in 'initialize_options()' and "defined" (given their
20
+ final values, aka "finalized") in 'finalize_options()', both of which
21
+ must be defined by every command class. The distinction between the
22
+ two is necessary because option values might come from the outside
23
+ world (command line, config file, ...), and any options dependent on
24
+ other options must be computed *after* these outside influences have
25
+ been processed -- hence 'finalize_options()'. The "body" of the
26
+ subroutine, where it does all its work based on the values of its
27
+ options, is the 'run()' method, which must also be implemented by every
28
+ command class.
29
+ """
30
+
31
+ # 'sub_commands' formalizes the notion of a "family" of commands,
32
+ # eg. "install" as the parent with sub-commands "install_lib",
33
+ # "install_headers", etc. The parent of a family of commands
34
+ # defines 'sub_commands' as a class attribute; it's a list of
35
+ # (command_name : string, predicate : unbound_method | string | None)
36
+ # tuples, where 'predicate' is a method of the parent command that
37
+ # determines whether the corresponding command is applicable in the
38
+ # current situation. (Eg. we "install_headers" is only applicable if
39
+ # we have any C header files to install.) If 'predicate' is None,
40
+ # that command is always applicable.
41
+ #
42
+ # 'sub_commands' is usually defined at the *end* of a class, because
43
+ # predicates can be unbound methods, so they must already have been
44
+ # defined. The canonical example is the "install" command.
45
+ sub_commands = []
46
+
47
+ # -- Creation/initialization methods -------------------------------
48
+
49
+ def __init__(self, dist):
50
+ """Create and initialize a new Command object. Most importantly,
51
+ invokes the 'initialize_options()' method, which is the real
52
+ initializer and depends on the actual command being
53
+ instantiated.
54
+ """
55
+ # late import because of mutual dependence between these classes
56
+ from distutils.dist import Distribution
57
+
58
+ if not isinstance(dist, Distribution):
59
+ raise TypeError("dist must be a Distribution instance")
60
+ if self.__class__ is Command:
61
+ raise RuntimeError("Command is an abstract class")
62
+
63
+ self.distribution = dist
64
+ self.initialize_options()
65
+
66
+ # Per-command versions of the global flags, so that the user can
67
+ # customize Distutils' behaviour command-by-command and let some
68
+ # commands fall back on the Distribution's behaviour. None means
69
+ # "not defined, check self.distribution's copy", while 0 or 1 mean
70
+ # false and true (duh). Note that this means figuring out the real
71
+ # value of each flag is a touch complicated -- hence "self._dry_run"
72
+ # will be handled by __getattr__, below.
73
+ # XXX This needs to be fixed.
74
+ self._dry_run = None
75
+
76
+ # verbose is largely ignored, but needs to be set for
77
+ # backwards compatibility (I think)?
78
+ self.verbose = dist.verbose
79
+
80
+ # Some commands define a 'self.force' option to ignore file
81
+ # timestamps, but methods defined *here* assume that
82
+ # 'self.force' exists for all commands. So define it here
83
+ # just to be safe.
84
+ self.force = None
85
+
86
+ # The 'help' flag is just used for command-line parsing, so
87
+ # none of that complicated bureaucracy is needed.
88
+ self.help = 0
89
+
90
+ # 'finalized' records whether or not 'finalize_options()' has been
91
+ # called. 'finalize_options()' itself should not pay attention to
92
+ # this flag: it is the business of 'ensure_finalized()', which
93
+ # always calls 'finalize_options()', to respect/update it.
94
+ self.finalized = 0
95
+
96
+ # XXX A more explicit way to customize dry_run would be better.
97
+ def __getattr__(self, attr):
98
+ if attr == 'dry_run':
99
+ myval = getattr(self, "_" + attr)
100
+ if myval is None:
101
+ return getattr(self.distribution, attr)
102
+ else:
103
+ return myval
104
+ else:
105
+ raise AttributeError(attr)
106
+
107
+ def ensure_finalized(self):
108
+ if not self.finalized:
109
+ self.finalize_options()
110
+ self.finalized = 1
111
+
112
+ # Subclasses must define:
113
+ # initialize_options()
114
+ # provide default values for all options; may be customized by
115
+ # setup script, by options from config file(s), or by command-line
116
+ # options
117
+ # finalize_options()
118
+ # decide on the final values for all options; this is called
119
+ # after all possible intervention from the outside world
120
+ # (command-line, option file, etc.) has been processed
121
+ # run()
122
+ # run the command: do whatever it is we're here to do,
123
+ # controlled by the command's various option values
124
+
125
+ def initialize_options(self):
126
+ """Set default values for all the options that this command
127
+ supports. Note that these defaults may be overridden by other
128
+ commands, by the setup script, by config files, or by the
129
+ command-line. Thus, this is not the place to code dependencies
130
+ between options; generally, 'initialize_options()' implementations
131
+ are just a bunch of "self.foo = None" assignments.
132
+
133
+ This method must be implemented by all command classes.
134
+ """
135
+ raise RuntimeError(
136
+ "abstract method -- subclass %s must override" % self.__class__
137
+ )
138
+
139
+ def finalize_options(self):
140
+ """Set final values for all the options that this command supports.
141
+ This is always called as late as possible, ie. after any option
142
+ assignments from the command-line or from other commands have been
143
+ done. Thus, this is the place to code option dependencies: if
144
+ 'foo' depends on 'bar', then it is safe to set 'foo' from 'bar' as
145
+ long as 'foo' still has the same value it was assigned in
146
+ 'initialize_options()'.
147
+
148
+ This method must be implemented by all command classes.
149
+ """
150
+ raise RuntimeError(
151
+ "abstract method -- subclass %s must override" % self.__class__
152
+ )
153
+
154
+ def dump_options(self, header=None, indent=""):
155
+ from distutils.fancy_getopt import longopt_xlate
156
+
157
+ if header is None:
158
+ header = "command options for '%s':" % self.get_command_name()
159
+ self.announce(indent + header, level=log.INFO)
160
+ indent = indent + " "
161
+ for (option, _, _) in self.user_options:
162
+ option = option.translate(longopt_xlate)
163
+ if option[-1] == "=":
164
+ option = option[:-1]
165
+ value = getattr(self, option)
166
+ self.announce(indent + "{} = {}".format(option, value), level=log.INFO)
167
+
168
+ def run(self):
169
+ """A command's raison d'etre: carry out the action it exists to
170
+ perform, controlled by the options initialized in
171
+ 'initialize_options()', customized by other commands, the setup
172
+ script, the command-line, and config files, and finalized in
173
+ 'finalize_options()'. All terminal output and filesystem
174
+ interaction should be done by 'run()'.
175
+
176
+ This method must be implemented by all command classes.
177
+ """
178
+ raise RuntimeError(
179
+ "abstract method -- subclass %s must override" % self.__class__
180
+ )
181
+
182
+ def announce(self, msg, level=1):
183
+ """If the current verbosity level is of greater than or equal to
184
+ 'level' print 'msg' to stdout.
185
+ """
186
+ log.log(level, msg)
187
+
188
+ def debug_print(self, msg):
189
+ """Print 'msg' to stdout if the global DEBUG (taken from the
190
+ DISTUTILS_DEBUG environment variable) flag is true.
191
+ """
192
+ from distutils.debug import DEBUG
193
+
194
+ if DEBUG:
195
+ print(msg)
196
+ sys.stdout.flush()
197
+
198
+ # -- Option validation methods -------------------------------------
199
+ # (these are very handy in writing the 'finalize_options()' method)
200
+ #
201
+ # NB. the general philosophy here is to ensure that a particular option
202
+ # value meets certain type and value constraints. If not, we try to
203
+ # force it into conformance (eg. if we expect a list but have a string,
204
+ # split the string on comma and/or whitespace). If we can't force the
205
+ # option into conformance, raise DistutilsOptionError. Thus, command
206
+ # classes need do nothing more than (eg.)
207
+ # self.ensure_string_list('foo')
208
+ # and they can be guaranteed that thereafter, self.foo will be
209
+ # a list of strings.
210
+
211
+ def _ensure_stringlike(self, option, what, default=None):
212
+ val = getattr(self, option)
213
+ if val is None:
214
+ setattr(self, option, default)
215
+ return default
216
+ elif not isinstance(val, str):
217
+ raise DistutilsOptionError(
218
+ "'{}' must be a {} (got `{}`)".format(option, what, val)
219
+ )
220
+ return val
221
+
222
+ def ensure_string(self, option, default=None):
223
+ """Ensure that 'option' is a string; if not defined, set it to
224
+ 'default'.
225
+ """
226
+ self._ensure_stringlike(option, "string", default)
227
+
228
+ def ensure_string_list(self, option):
229
+ r"""Ensure that 'option' is a list of strings. If 'option' is
230
+ currently a string, we split it either on /,\s*/ or /\s+/, so
231
+ "foo bar baz", "foo,bar,baz", and "foo, bar baz" all become
232
+ ["foo", "bar", "baz"].
233
+ """
234
+ val = getattr(self, option)
235
+ if val is None:
236
+ return
237
+ elif isinstance(val, str):
238
+ setattr(self, option, re.split(r',\s*|\s+', val))
239
+ else:
240
+ if isinstance(val, list):
241
+ ok = all(isinstance(v, str) for v in val)
242
+ else:
243
+ ok = False
244
+ if not ok:
245
+ raise DistutilsOptionError(
246
+ "'{}' must be a list of strings (got {!r})".format(option, val)
247
+ )
248
+
249
+ def _ensure_tested_string(self, option, tester, what, error_fmt, default=None):
250
+ val = self._ensure_stringlike(option, what, default)
251
+ if val is not None and not tester(val):
252
+ raise DistutilsOptionError(
253
+ ("error in '%s' option: " + error_fmt) % (option, val)
254
+ )
255
+
256
+ def ensure_filename(self, option):
257
+ """Ensure that 'option' is the name of an existing file."""
258
+ self._ensure_tested_string(
259
+ option, os.path.isfile, "filename", "'%s' does not exist or is not a file"
260
+ )
261
+
262
+ def ensure_dirname(self, option):
263
+ self._ensure_tested_string(
264
+ option,
265
+ os.path.isdir,
266
+ "directory name",
267
+ "'%s' does not exist or is not a directory",
268
+ )
269
+
270
+ # -- Convenience methods for commands ------------------------------
271
+
272
+ def get_command_name(self):
273
+ if hasattr(self, 'command_name'):
274
+ return self.command_name
275
+ else:
276
+ return self.__class__.__name__
277
+
278
+ def set_undefined_options(self, src_cmd, *option_pairs):
279
+ """Set the values of any "undefined" options from corresponding
280
+ option values in some other command object. "Undefined" here means
281
+ "is None", which is the convention used to indicate that an option
282
+ has not been changed between 'initialize_options()' and
283
+ 'finalize_options()'. Usually called from 'finalize_options()' for
284
+ options that depend on some other command rather than another
285
+ option of the same command. 'src_cmd' is the other command from
286
+ which option values will be taken (a command object will be created
287
+ for it if necessary); the remaining arguments are
288
+ '(src_option,dst_option)' tuples which mean "take the value of
289
+ 'src_option' in the 'src_cmd' command object, and copy it to
290
+ 'dst_option' in the current command object".
291
+ """
292
+ # Option_pairs: list of (src_option, dst_option) tuples
293
+ src_cmd_obj = self.distribution.get_command_obj(src_cmd)
294
+ src_cmd_obj.ensure_finalized()
295
+ for (src_option, dst_option) in option_pairs:
296
+ if getattr(self, dst_option) is None:
297
+ setattr(self, dst_option, getattr(src_cmd_obj, src_option))
298
+
299
+ def get_finalized_command(self, command, create=1):
300
+ """Wrapper around Distribution's 'get_command_obj()' method: find
301
+ (create if necessary and 'create' is true) the command object for
302
+ 'command', call its 'ensure_finalized()' method, and return the
303
+ finalized command object.
304
+ """
305
+ cmd_obj = self.distribution.get_command_obj(command, create)
306
+ cmd_obj.ensure_finalized()
307
+ return cmd_obj
308
+
309
+ # XXX rename to 'get_reinitialized_command()'? (should do the
310
+ # same in dist.py, if so)
311
+ def reinitialize_command(self, command, reinit_subcommands=0):
312
+ return self.distribution.reinitialize_command(command, reinit_subcommands)
313
+
314
+ def run_command(self, command):
315
+ """Run some other command: uses the 'run_command()' method of
316
+ Distribution, which creates and finalizes the command object if
317
+ necessary and then invokes its 'run()' method.
318
+ """
319
+ self.distribution.run_command(command)
320
+
321
+ def get_sub_commands(self):
322
+ """Determine the sub-commands that are relevant in the current
323
+ distribution (ie., that need to be run). This is based on the
324
+ 'sub_commands' class attribute: each tuple in that list may include
325
+ a method that we call to determine if the subcommand needs to be
326
+ run for the current distribution. Return a list of command names.
327
+ """
328
+ commands = []
329
+ for (cmd_name, method) in self.sub_commands:
330
+ if method is None or method(self):
331
+ commands.append(cmd_name)
332
+ return commands
333
+
334
+ # -- External world manipulation -----------------------------------
335
+
336
+ def warn(self, msg):
337
+ log.warn("warning: %s: %s\n", self.get_command_name(), msg)
338
+
339
+ def execute(self, func, args, msg=None, level=1):
340
+ util.execute(func, args, msg, dry_run=self.dry_run)
341
+
342
+ def mkpath(self, name, mode=0o777):
343
+ dir_util.mkpath(name, mode, dry_run=self.dry_run)
344
+
345
+ def copy_file(
346
+ self, infile, outfile, preserve_mode=1, preserve_times=1, link=None, level=1
347
+ ):
348
+ """Copy a file respecting verbose, dry-run and force flags. (The
349
+ former two default to whatever is in the Distribution object, and
350
+ the latter defaults to false for commands that don't define it.)"""
351
+ return file_util.copy_file(
352
+ infile,
353
+ outfile,
354
+ preserve_mode,
355
+ preserve_times,
356
+ not self.force,
357
+ link,
358
+ dry_run=self.dry_run,
359
+ )
360
+
361
+ def copy_tree(
362
+ self,
363
+ infile,
364
+ outfile,
365
+ preserve_mode=1,
366
+ preserve_times=1,
367
+ preserve_symlinks=0,
368
+ level=1,
369
+ ):
370
+ """Copy an entire directory tree respecting verbose, dry-run,
371
+ and force flags.
372
+ """
373
+ return dir_util.copy_tree(
374
+ infile,
375
+ outfile,
376
+ preserve_mode,
377
+ preserve_times,
378
+ preserve_symlinks,
379
+ not self.force,
380
+ dry_run=self.dry_run,
381
+ )
382
+
383
+ def move_file(self, src, dst, level=1):
384
+ """Move a file respecting dry-run flag."""
385
+ return file_util.move_file(src, dst, dry_run=self.dry_run)
386
+
387
+ def spawn(self, cmd, search_path=1, level=1):
388
+ """Spawn an external command respecting dry-run flag."""
389
+ from distutils.spawn import spawn
390
+
391
+ spawn(cmd, search_path, dry_run=self.dry_run)
392
+
393
+ def make_archive(
394
+ self, base_name, format, root_dir=None, base_dir=None, owner=None, group=None
395
+ ):
396
+ return archive_util.make_archive(
397
+ base_name,
398
+ format,
399
+ root_dir,
400
+ base_dir,
401
+ dry_run=self.dry_run,
402
+ owner=owner,
403
+ group=group,
404
+ )
405
+
406
+ def make_file(
407
+ self, infiles, outfile, func, args, exec_msg=None, skip_msg=None, level=1
408
+ ):
409
+ """Special case of 'execute()' for operations that process one or
410
+ more input files and generate one output file. Works just like
411
+ 'execute()', except the operation is skipped and a different
412
+ message printed if 'outfile' already exists and is newer than all
413
+ files listed in 'infiles'. If the command defined 'self.force',
414
+ and it is true, then the command is unconditionally run -- does no
415
+ timestamp checks.
416
+ """
417
+ if skip_msg is None:
418
+ skip_msg = "skipping %s (inputs unchanged)" % outfile
419
+
420
+ # Allow 'infiles' to be a single string
421
+ if isinstance(infiles, str):
422
+ infiles = (infiles,)
423
+ elif not isinstance(infiles, (list, tuple)):
424
+ raise TypeError("'infiles' must be a string, or a list or tuple of strings")
425
+
426
+ if exec_msg is None:
427
+ exec_msg = "generating {} from {}".format(outfile, ', '.join(infiles))
428
+
429
+ # If 'outfile' must be regenerated (either because it doesn't
430
+ # exist, is out-of-date, or the 'force' flag is true) then
431
+ # perform the action that presumably regenerates it
432
+ if self.force or dep_util.newer_group(infiles, outfile):
433
+ self.execute(func, args, exec_msg, level)
434
+ # Otherwise, print the "skip" message
435
+ else:
436
+ log.debug(skip_msg)
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/_framework_compat.cpython-311.pyc ADDED
Binary file (2.78 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/bdist_dumb.cpython-311.pyc ADDED
Binary file (5.76 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/bdist_rpm.cpython-311.pyc ADDED
Binary file (23.3 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/build.cpython-311.pyc ADDED
Binary file (6.09 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/build_clib.cpython-311.pyc ADDED
Binary file (7.79 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/build_scripts.cpython-311.pyc ADDED
Binary file (7.86 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/clean.cpython-311.pyc ADDED
Binary file (3.19 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/install.cpython-311.pyc ADDED
Binary file (29.4 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/install_data.cpython-311.pyc ADDED
Binary file (3.78 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/install_headers.cpython-311.pyc ADDED
Binary file (2.36 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/install_lib.cpython-311.pyc ADDED
Binary file (8.69 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/install_scripts.cpython-311.pyc ADDED
Binary file (3.16 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/py37compat.cpython-311.pyc ADDED
Binary file (1.54 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/register.cpython-311.pyc ADDED
Binary file (15.5 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/sdist.cpython-311.pyc ADDED
Binary file (23.8 kB). View file
 
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/bdist_dumb.py ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils.command.bdist_dumb
2
+
3
+ Implements the Distutils 'bdist_dumb' command (create a "dumb" built
4
+ distribution -- i.e., just an archive to be unpacked under $prefix or
5
+ $exec_prefix)."""
6
+
7
+ import os
8
+ from distutils.core import Command
9
+ from distutils.util import get_platform
10
+ from distutils.dir_util import remove_tree, ensure_relative
11
+ from distutils.errors import DistutilsPlatformError
12
+ from distutils.sysconfig import get_python_version
13
+ from distutils import log
14
+
15
+
16
+ class bdist_dumb(Command):
17
+
18
+ description = "create a \"dumb\" built distribution"
19
+
20
+ user_options = [
21
+ ('bdist-dir=', 'd', "temporary directory for creating the distribution"),
22
+ (
23
+ 'plat-name=',
24
+ 'p',
25
+ "platform name to embed in generated filenames "
26
+ "(default: %s)" % get_platform(),
27
+ ),
28
+ (
29
+ 'format=',
30
+ 'f',
31
+ "archive format to create (tar, gztar, bztar, xztar, " "ztar, zip)",
32
+ ),
33
+ (
34
+ 'keep-temp',
35
+ 'k',
36
+ "keep the pseudo-installation tree around after "
37
+ + "creating the distribution archive",
38
+ ),
39
+ ('dist-dir=', 'd', "directory to put final built distributions in"),
40
+ ('skip-build', None, "skip rebuilding everything (for testing/debugging)"),
41
+ (
42
+ 'relative',
43
+ None,
44
+ "build the archive using relative paths " "(default: false)",
45
+ ),
46
+ (
47
+ 'owner=',
48
+ 'u',
49
+ "Owner name used when creating a tar file" " [default: current user]",
50
+ ),
51
+ (
52
+ 'group=',
53
+ 'g',
54
+ "Group name used when creating a tar file" " [default: current group]",
55
+ ),
56
+ ]
57
+
58
+ boolean_options = ['keep-temp', 'skip-build', 'relative']
59
+
60
+ default_format = {'posix': 'gztar', 'nt': 'zip'}
61
+
62
+ def initialize_options(self):
63
+ self.bdist_dir = None
64
+ self.plat_name = None
65
+ self.format = None
66
+ self.keep_temp = 0
67
+ self.dist_dir = None
68
+ self.skip_build = None
69
+ self.relative = 0
70
+ self.owner = None
71
+ self.group = None
72
+
73
+ def finalize_options(self):
74
+ if self.bdist_dir is None:
75
+ bdist_base = self.get_finalized_command('bdist').bdist_base
76
+ self.bdist_dir = os.path.join(bdist_base, 'dumb')
77
+
78
+ if self.format is None:
79
+ try:
80
+ self.format = self.default_format[os.name]
81
+ except KeyError:
82
+ raise DistutilsPlatformError(
83
+ "don't know how to create dumb built distributions "
84
+ "on platform %s" % os.name
85
+ )
86
+
87
+ self.set_undefined_options(
88
+ 'bdist',
89
+ ('dist_dir', 'dist_dir'),
90
+ ('plat_name', 'plat_name'),
91
+ ('skip_build', 'skip_build'),
92
+ )
93
+
94
+ def run(self):
95
+ if not self.skip_build:
96
+ self.run_command('build')
97
+
98
+ install = self.reinitialize_command('install', reinit_subcommands=1)
99
+ install.root = self.bdist_dir
100
+ install.skip_build = self.skip_build
101
+ install.warn_dir = 0
102
+
103
+ log.info("installing to %s", self.bdist_dir)
104
+ self.run_command('install')
105
+
106
+ # And make an archive relative to the root of the
107
+ # pseudo-installation tree.
108
+ archive_basename = "{}.{}".format(
109
+ self.distribution.get_fullname(), self.plat_name
110
+ )
111
+
112
+ pseudoinstall_root = os.path.join(self.dist_dir, archive_basename)
113
+ if not self.relative:
114
+ archive_root = self.bdist_dir
115
+ else:
116
+ if self.distribution.has_ext_modules() and (
117
+ install.install_base != install.install_platbase
118
+ ):
119
+ raise DistutilsPlatformError(
120
+ "can't make a dumb built distribution where "
121
+ "base and platbase are different (%s, %s)"
122
+ % (repr(install.install_base), repr(install.install_platbase))
123
+ )
124
+ else:
125
+ archive_root = os.path.join(
126
+ self.bdist_dir, ensure_relative(install.install_base)
127
+ )
128
+
129
+ # Make the archive
130
+ filename = self.make_archive(
131
+ pseudoinstall_root,
132
+ self.format,
133
+ root_dir=archive_root,
134
+ owner=self.owner,
135
+ group=self.group,
136
+ )
137
+ if self.distribution.has_ext_modules():
138
+ pyversion = get_python_version()
139
+ else:
140
+ pyversion = 'any'
141
+ self.distribution.dist_files.append(('bdist_dumb', pyversion, filename))
142
+
143
+ if not self.keep_temp:
144
+ remove_tree(self.bdist_dir, dry_run=self.dry_run)
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/build.py ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils.command.build
2
+
3
+ Implements the Distutils 'build' command."""
4
+
5
+ import sys
6
+ import os
7
+ from distutils.core import Command
8
+ from distutils.errors import DistutilsOptionError
9
+ from distutils.util import get_platform
10
+
11
+
12
+ def show_compilers():
13
+ from distutils.ccompiler import show_compilers
14
+
15
+ show_compilers()
16
+
17
+
18
+ class build(Command):
19
+
20
+ description = "build everything needed to install"
21
+
22
+ user_options = [
23
+ ('build-base=', 'b', "base directory for build library"),
24
+ ('build-purelib=', None, "build directory for platform-neutral distributions"),
25
+ ('build-platlib=', None, "build directory for platform-specific distributions"),
26
+ (
27
+ 'build-lib=',
28
+ None,
29
+ "build directory for all distribution (defaults to either "
30
+ + "build-purelib or build-platlib",
31
+ ),
32
+ ('build-scripts=', None, "build directory for scripts"),
33
+ ('build-temp=', 't', "temporary build directory"),
34
+ (
35
+ 'plat-name=',
36
+ 'p',
37
+ "platform name to build for, if supported "
38
+ "(default: %s)" % get_platform(),
39
+ ),
40
+ ('compiler=', 'c', "specify the compiler type"),
41
+ ('parallel=', 'j', "number of parallel build jobs"),
42
+ ('debug', 'g', "compile extensions and libraries with debugging information"),
43
+ ('force', 'f', "forcibly build everything (ignore file timestamps)"),
44
+ ('executable=', 'e', "specify final destination interpreter path (build.py)"),
45
+ ]
46
+
47
+ boolean_options = ['debug', 'force']
48
+
49
+ help_options = [
50
+ ('help-compiler', None, "list available compilers", show_compilers),
51
+ ]
52
+
53
+ def initialize_options(self):
54
+ self.build_base = 'build'
55
+ # these are decided only after 'build_base' has its final value
56
+ # (unless overridden by the user or client)
57
+ self.build_purelib = None
58
+ self.build_platlib = None
59
+ self.build_lib = None
60
+ self.build_temp = None
61
+ self.build_scripts = None
62
+ self.compiler = None
63
+ self.plat_name = None
64
+ self.debug = None
65
+ self.force = 0
66
+ self.executable = None
67
+ self.parallel = None
68
+
69
+ def finalize_options(self): # noqa: C901
70
+ if self.plat_name is None:
71
+ self.plat_name = get_platform()
72
+ else:
73
+ # plat-name only supported for windows (other platforms are
74
+ # supported via ./configure flags, if at all). Avoid misleading
75
+ # other platforms.
76
+ if os.name != 'nt':
77
+ raise DistutilsOptionError(
78
+ "--plat-name only supported on Windows (try "
79
+ "using './configure --help' on your platform)"
80
+ )
81
+
82
+ plat_specifier = ".{}-{}".format(self.plat_name, sys.implementation.cache_tag)
83
+
84
+ # Make it so Python 2.x and Python 2.x with --with-pydebug don't
85
+ # share the same build directories. Doing so confuses the build
86
+ # process for C modules
87
+ if hasattr(sys, 'gettotalrefcount'):
88
+ plat_specifier += '-pydebug'
89
+
90
+ # 'build_purelib' and 'build_platlib' just default to 'lib' and
91
+ # 'lib.<plat>' under the base build directory. We only use one of
92
+ # them for a given distribution, though --
93
+ if self.build_purelib is None:
94
+ self.build_purelib = os.path.join(self.build_base, 'lib')
95
+ if self.build_platlib is None:
96
+ self.build_platlib = os.path.join(self.build_base, 'lib' + plat_specifier)
97
+
98
+ # 'build_lib' is the actual directory that we will use for this
99
+ # particular module distribution -- if user didn't supply it, pick
100
+ # one of 'build_purelib' or 'build_platlib'.
101
+ if self.build_lib is None:
102
+ if self.distribution.has_ext_modules():
103
+ self.build_lib = self.build_platlib
104
+ else:
105
+ self.build_lib = self.build_purelib
106
+
107
+ # 'build_temp' -- temporary directory for compiler turds,
108
+ # "build/temp.<plat>"
109
+ if self.build_temp is None:
110
+ self.build_temp = os.path.join(self.build_base, 'temp' + plat_specifier)
111
+ if self.build_scripts is None:
112
+ self.build_scripts = os.path.join(
113
+ self.build_base, 'scripts-%d.%d' % sys.version_info[:2]
114
+ )
115
+
116
+ if self.executable is None and sys.executable:
117
+ self.executable = os.path.normpath(sys.executable)
118
+
119
+ if isinstance(self.parallel, str):
120
+ try:
121
+ self.parallel = int(self.parallel)
122
+ except ValueError:
123
+ raise DistutilsOptionError("parallel should be an integer")
124
+
125
+ def run(self):
126
+ # Run all relevant sub-commands. This will be some subset of:
127
+ # - build_py - pure Python modules
128
+ # - build_clib - standalone C libraries
129
+ # - build_ext - Python extensions
130
+ # - build_scripts - (Python) scripts
131
+ for cmd_name in self.get_sub_commands():
132
+ self.run_command(cmd_name)
133
+
134
+ # -- Predicates for the sub-command list ---------------------------
135
+
136
+ def has_pure_modules(self):
137
+ return self.distribution.has_pure_modules()
138
+
139
+ def has_c_libraries(self):
140
+ return self.distribution.has_c_libraries()
141
+
142
+ def has_ext_modules(self):
143
+ return self.distribution.has_ext_modules()
144
+
145
+ def has_scripts(self):
146
+ return self.distribution.has_scripts()
147
+
148
+ sub_commands = [
149
+ ('build_py', has_pure_modules),
150
+ ('build_clib', has_c_libraries),
151
+ ('build_ext', has_ext_modules),
152
+ ('build_scripts', has_scripts),
153
+ ]
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/build_ext.py ADDED
@@ -0,0 +1,787 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils.command.build_ext
2
+
3
+ Implements the Distutils 'build_ext' command, for building extension
4
+ modules (currently limited to C extensions, should accommodate C++
5
+ extensions ASAP)."""
6
+
7
+ import contextlib
8
+ import os
9
+ import re
10
+ import sys
11
+ from distutils.core import Command
12
+ from distutils.errors import (
13
+ DistutilsOptionError,
14
+ DistutilsSetupError,
15
+ CCompilerError,
16
+ DistutilsError,
17
+ CompileError,
18
+ DistutilsPlatformError,
19
+ )
20
+ from distutils.sysconfig import customize_compiler, get_python_version
21
+ from distutils.sysconfig import get_config_h_filename
22
+ from distutils.dep_util import newer_group
23
+ from distutils.extension import Extension
24
+ from distutils.util import get_platform
25
+ from distutils import log
26
+ from . import py37compat
27
+
28
+ from site import USER_BASE
29
+
30
+ # An extension name is just a dot-separated list of Python NAMEs (ie.
31
+ # the same as a fully-qualified module name).
32
+ extension_name_re = re.compile(r'^[a-zA-Z_][a-zA-Z_0-9]*(\.[a-zA-Z_][a-zA-Z_0-9]*)*$')
33
+
34
+
35
+ def show_compilers():
36
+ from distutils.ccompiler import show_compilers
37
+
38
+ show_compilers()
39
+
40
+
41
+ class build_ext(Command):
42
+
43
+ description = "build C/C++ extensions (compile/link to build directory)"
44
+
45
+ # XXX thoughts on how to deal with complex command-line options like
46
+ # these, i.e. how to make it so fancy_getopt can suck them off the
47
+ # command line and make it look like setup.py defined the appropriate
48
+ # lists of tuples of what-have-you.
49
+ # - each command needs a callback to process its command-line options
50
+ # - Command.__init__() needs access to its share of the whole
51
+ # command line (must ultimately come from
52
+ # Distribution.parse_command_line())
53
+ # - it then calls the current command class' option-parsing
54
+ # callback to deal with weird options like -D, which have to
55
+ # parse the option text and churn out some custom data
56
+ # structure
57
+ # - that data structure (in this case, a list of 2-tuples)
58
+ # will then be present in the command object by the time
59
+ # we get to finalize_options() (i.e. the constructor
60
+ # takes care of both command-line and client options
61
+ # in between initialize_options() and finalize_options())
62
+
63
+ sep_by = " (separated by '%s')" % os.pathsep
64
+ user_options = [
65
+ ('build-lib=', 'b', "directory for compiled extension modules"),
66
+ ('build-temp=', 't', "directory for temporary files (build by-products)"),
67
+ (
68
+ 'plat-name=',
69
+ 'p',
70
+ "platform name to cross-compile for, if supported "
71
+ "(default: %s)" % get_platform(),
72
+ ),
73
+ (
74
+ 'inplace',
75
+ 'i',
76
+ "ignore build-lib and put compiled extensions into the source "
77
+ + "directory alongside your pure Python modules",
78
+ ),
79
+ (
80
+ 'include-dirs=',
81
+ 'I',
82
+ "list of directories to search for header files" + sep_by,
83
+ ),
84
+ ('define=', 'D', "C preprocessor macros to define"),
85
+ ('undef=', 'U', "C preprocessor macros to undefine"),
86
+ ('libraries=', 'l', "external C libraries to link with"),
87
+ (
88
+ 'library-dirs=',
89
+ 'L',
90
+ "directories to search for external C libraries" + sep_by,
91
+ ),
92
+ ('rpath=', 'R', "directories to search for shared C libraries at runtime"),
93
+ ('link-objects=', 'O', "extra explicit link objects to include in the link"),
94
+ ('debug', 'g', "compile/link with debugging information"),
95
+ ('force', 'f', "forcibly build everything (ignore file timestamps)"),
96
+ ('compiler=', 'c', "specify the compiler type"),
97
+ ('parallel=', 'j', "number of parallel build jobs"),
98
+ ('swig-cpp', None, "make SWIG create C++ files (default is C)"),
99
+ ('swig-opts=', None, "list of SWIG command line options"),
100
+ ('swig=', None, "path to the SWIG executable"),
101
+ ('user', None, "add user include, library and rpath"),
102
+ ]
103
+
104
+ boolean_options = ['inplace', 'debug', 'force', 'swig-cpp', 'user']
105
+
106
+ help_options = [
107
+ ('help-compiler', None, "list available compilers", show_compilers),
108
+ ]
109
+
110
+ def initialize_options(self):
111
+ self.extensions = None
112
+ self.build_lib = None
113
+ self.plat_name = None
114
+ self.build_temp = None
115
+ self.inplace = 0
116
+ self.package = None
117
+
118
+ self.include_dirs = None
119
+ self.define = None
120
+ self.undef = None
121
+ self.libraries = None
122
+ self.library_dirs = None
123
+ self.rpath = None
124
+ self.link_objects = None
125
+ self.debug = None
126
+ self.force = None
127
+ self.compiler = None
128
+ self.swig = None
129
+ self.swig_cpp = None
130
+ self.swig_opts = None
131
+ self.user = None
132
+ self.parallel = None
133
+
134
+ def finalize_options(self): # noqa: C901
135
+ from distutils import sysconfig
136
+
137
+ self.set_undefined_options(
138
+ 'build',
139
+ ('build_lib', 'build_lib'),
140
+ ('build_temp', 'build_temp'),
141
+ ('compiler', 'compiler'),
142
+ ('debug', 'debug'),
143
+ ('force', 'force'),
144
+ ('parallel', 'parallel'),
145
+ ('plat_name', 'plat_name'),
146
+ )
147
+
148
+ if self.package is None:
149
+ self.package = self.distribution.ext_package
150
+
151
+ self.extensions = self.distribution.ext_modules
152
+
153
+ # Make sure Python's include directories (for Python.h, pyconfig.h,
154
+ # etc.) are in the include search path.
155
+ py_include = sysconfig.get_python_inc()
156
+ plat_py_include = sysconfig.get_python_inc(plat_specific=1)
157
+ if self.include_dirs is None:
158
+ self.include_dirs = self.distribution.include_dirs or []
159
+ if isinstance(self.include_dirs, str):
160
+ self.include_dirs = self.include_dirs.split(os.pathsep)
161
+
162
+ # If in a virtualenv, add its include directory
163
+ # Issue 16116
164
+ if sys.exec_prefix != sys.base_exec_prefix:
165
+ self.include_dirs.append(os.path.join(sys.exec_prefix, 'include'))
166
+
167
+ # Put the Python "system" include dir at the end, so that
168
+ # any local include dirs take precedence.
169
+ self.include_dirs.extend(py_include.split(os.path.pathsep))
170
+ if plat_py_include != py_include:
171
+ self.include_dirs.extend(plat_py_include.split(os.path.pathsep))
172
+
173
+ self.ensure_string_list('libraries')
174
+ self.ensure_string_list('link_objects')
175
+
176
+ # Life is easier if we're not forever checking for None, so
177
+ # simplify these options to empty lists if unset
178
+ if self.libraries is None:
179
+ self.libraries = []
180
+ if self.library_dirs is None:
181
+ self.library_dirs = []
182
+ elif isinstance(self.library_dirs, str):
183
+ self.library_dirs = self.library_dirs.split(os.pathsep)
184
+
185
+ if self.rpath is None:
186
+ self.rpath = []
187
+ elif isinstance(self.rpath, str):
188
+ self.rpath = self.rpath.split(os.pathsep)
189
+
190
+ # for extensions under windows use different directories
191
+ # for Release and Debug builds.
192
+ # also Python's library directory must be appended to library_dirs
193
+ if os.name == 'nt':
194
+ # the 'libs' directory is for binary installs - we assume that
195
+ # must be the *native* platform. But we don't really support
196
+ # cross-compiling via a binary install anyway, so we let it go.
197
+ self.library_dirs.append(os.path.join(sys.exec_prefix, 'libs'))
198
+ if sys.base_exec_prefix != sys.prefix: # Issue 16116
199
+ self.library_dirs.append(os.path.join(sys.base_exec_prefix, 'libs'))
200
+ if self.debug:
201
+ self.build_temp = os.path.join(self.build_temp, "Debug")
202
+ else:
203
+ self.build_temp = os.path.join(self.build_temp, "Release")
204
+
205
+ # Append the source distribution include and library directories,
206
+ # this allows distutils on windows to work in the source tree
207
+ self.include_dirs.append(os.path.dirname(get_config_h_filename()))
208
+ self.library_dirs.append(sys.base_exec_prefix)
209
+
210
+ # Use the .lib files for the correct architecture
211
+ if self.plat_name == 'win32':
212
+ suffix = 'win32'
213
+ else:
214
+ # win-amd64
215
+ suffix = self.plat_name[4:]
216
+ new_lib = os.path.join(sys.exec_prefix, 'PCbuild')
217
+ if suffix:
218
+ new_lib = os.path.join(new_lib, suffix)
219
+ self.library_dirs.append(new_lib)
220
+
221
+ # For extensions under Cygwin, Python's library directory must be
222
+ # appended to library_dirs
223
+ if sys.platform[:6] == 'cygwin':
224
+ if not sysconfig.python_build:
225
+ # building third party extensions
226
+ self.library_dirs.append(
227
+ os.path.join(
228
+ sys.prefix, "lib", "python" + get_python_version(), "config"
229
+ )
230
+ )
231
+ else:
232
+ # building python standard extensions
233
+ self.library_dirs.append('.')
234
+
235
+ # For building extensions with a shared Python library,
236
+ # Python's library directory must be appended to library_dirs
237
+ # See Issues: #1600860, #4366
238
+ if sysconfig.get_config_var('Py_ENABLE_SHARED'):
239
+ if not sysconfig.python_build:
240
+ # building third party extensions
241
+ self.library_dirs.append(sysconfig.get_config_var('LIBDIR'))
242
+ else:
243
+ # building python standard extensions
244
+ self.library_dirs.append('.')
245
+
246
+ # The argument parsing will result in self.define being a string, but
247
+ # it has to be a list of 2-tuples. All the preprocessor symbols
248
+ # specified by the 'define' option will be set to '1'. Multiple
249
+ # symbols can be separated with commas.
250
+
251
+ if self.define:
252
+ defines = self.define.split(',')
253
+ self.define = [(symbol, '1') for symbol in defines]
254
+
255
+ # The option for macros to undefine is also a string from the
256
+ # option parsing, but has to be a list. Multiple symbols can also
257
+ # be separated with commas here.
258
+ if self.undef:
259
+ self.undef = self.undef.split(',')
260
+
261
+ if self.swig_opts is None:
262
+ self.swig_opts = []
263
+ else:
264
+ self.swig_opts = self.swig_opts.split(' ')
265
+
266
+ # Finally add the user include and library directories if requested
267
+ if self.user:
268
+ user_include = os.path.join(USER_BASE, "include")
269
+ user_lib = os.path.join(USER_BASE, "lib")
270
+ if os.path.isdir(user_include):
271
+ self.include_dirs.append(user_include)
272
+ if os.path.isdir(user_lib):
273
+ self.library_dirs.append(user_lib)
274
+ self.rpath.append(user_lib)
275
+
276
+ if isinstance(self.parallel, str):
277
+ try:
278
+ self.parallel = int(self.parallel)
279
+ except ValueError:
280
+ raise DistutilsOptionError("parallel should be an integer")
281
+
282
+ def run(self): # noqa: C901
283
+ from distutils.ccompiler import new_compiler
284
+
285
+ # 'self.extensions', as supplied by setup.py, is a list of
286
+ # Extension instances. See the documentation for Extension (in
287
+ # distutils.extension) for details.
288
+ #
289
+ # For backwards compatibility with Distutils 0.8.2 and earlier, we
290
+ # also allow the 'extensions' list to be a list of tuples:
291
+ # (ext_name, build_info)
292
+ # where build_info is a dictionary containing everything that
293
+ # Extension instances do except the name, with a few things being
294
+ # differently named. We convert these 2-tuples to Extension
295
+ # instances as needed.
296
+
297
+ if not self.extensions:
298
+ return
299
+
300
+ # If we were asked to build any C/C++ libraries, make sure that the
301
+ # directory where we put them is in the library search path for
302
+ # linking extensions.
303
+ if self.distribution.has_c_libraries():
304
+ build_clib = self.get_finalized_command('build_clib')
305
+ self.libraries.extend(build_clib.get_library_names() or [])
306
+ self.library_dirs.append(build_clib.build_clib)
307
+
308
+ # Setup the CCompiler object that we'll use to do all the
309
+ # compiling and linking
310
+ self.compiler = new_compiler(
311
+ compiler=self.compiler,
312
+ verbose=self.verbose,
313
+ dry_run=self.dry_run,
314
+ force=self.force,
315
+ )
316
+ customize_compiler(self.compiler)
317
+ # If we are cross-compiling, init the compiler now (if we are not
318
+ # cross-compiling, init would not hurt, but people may rely on
319
+ # late initialization of compiler even if they shouldn't...)
320
+ if os.name == 'nt' and self.plat_name != get_platform():
321
+ self.compiler.initialize(self.plat_name)
322
+
323
+ # And make sure that any compile/link-related options (which might
324
+ # come from the command-line or from the setup script) are set in
325
+ # that CCompiler object -- that way, they automatically apply to
326
+ # all compiling and linking done here.
327
+ if self.include_dirs is not None:
328
+ self.compiler.set_include_dirs(self.include_dirs)
329
+ if self.define is not None:
330
+ # 'define' option is a list of (name,value) tuples
331
+ for (name, value) in self.define:
332
+ self.compiler.define_macro(name, value)
333
+ if self.undef is not None:
334
+ for macro in self.undef:
335
+ self.compiler.undefine_macro(macro)
336
+ if self.libraries is not None:
337
+ self.compiler.set_libraries(self.libraries)
338
+ if self.library_dirs is not None:
339
+ self.compiler.set_library_dirs(self.library_dirs)
340
+ if self.rpath is not None:
341
+ self.compiler.set_runtime_library_dirs(self.rpath)
342
+ if self.link_objects is not None:
343
+ self.compiler.set_link_objects(self.link_objects)
344
+
345
+ # Now actually compile and link everything.
346
+ self.build_extensions()
347
+
348
+ def check_extensions_list(self, extensions): # noqa: C901
349
+ """Ensure that the list of extensions (presumably provided as a
350
+ command option 'extensions') is valid, i.e. it is a list of
351
+ Extension objects. We also support the old-style list of 2-tuples,
352
+ where the tuples are (ext_name, build_info), which are converted to
353
+ Extension instances here.
354
+
355
+ Raise DistutilsSetupError if the structure is invalid anywhere;
356
+ just returns otherwise.
357
+ """
358
+ if not isinstance(extensions, list):
359
+ raise DistutilsSetupError(
360
+ "'ext_modules' option must be a list of Extension instances"
361
+ )
362
+
363
+ for i, ext in enumerate(extensions):
364
+ if isinstance(ext, Extension):
365
+ continue # OK! (assume type-checking done
366
+ # by Extension constructor)
367
+
368
+ if not isinstance(ext, tuple) or len(ext) != 2:
369
+ raise DistutilsSetupError(
370
+ "each element of 'ext_modules' option must be an "
371
+ "Extension instance or 2-tuple"
372
+ )
373
+
374
+ ext_name, build_info = ext
375
+
376
+ log.warn(
377
+ "old-style (ext_name, build_info) tuple found in "
378
+ "ext_modules for extension '%s' "
379
+ "-- please convert to Extension instance",
380
+ ext_name,
381
+ )
382
+
383
+ if not (isinstance(ext_name, str) and extension_name_re.match(ext_name)):
384
+ raise DistutilsSetupError(
385
+ "first element of each tuple in 'ext_modules' "
386
+ "must be the extension name (a string)"
387
+ )
388
+
389
+ if not isinstance(build_info, dict):
390
+ raise DistutilsSetupError(
391
+ "second element of each tuple in 'ext_modules' "
392
+ "must be a dictionary (build info)"
393
+ )
394
+
395
+ # OK, the (ext_name, build_info) dict is type-safe: convert it
396
+ # to an Extension instance.
397
+ ext = Extension(ext_name, build_info['sources'])
398
+
399
+ # Easy stuff: one-to-one mapping from dict elements to
400
+ # instance attributes.
401
+ for key in (
402
+ 'include_dirs',
403
+ 'library_dirs',
404
+ 'libraries',
405
+ 'extra_objects',
406
+ 'extra_compile_args',
407
+ 'extra_link_args',
408
+ ):
409
+ val = build_info.get(key)
410
+ if val is not None:
411
+ setattr(ext, key, val)
412
+
413
+ # Medium-easy stuff: same syntax/semantics, different names.
414
+ ext.runtime_library_dirs = build_info.get('rpath')
415
+ if 'def_file' in build_info:
416
+ log.warn("'def_file' element of build info dict " "no longer supported")
417
+
418
+ # Non-trivial stuff: 'macros' split into 'define_macros'
419
+ # and 'undef_macros'.
420
+ macros = build_info.get('macros')
421
+ if macros:
422
+ ext.define_macros = []
423
+ ext.undef_macros = []
424
+ for macro in macros:
425
+ if not (isinstance(macro, tuple) and len(macro) in (1, 2)):
426
+ raise DistutilsSetupError(
427
+ "'macros' element of build info dict "
428
+ "must be 1- or 2-tuple"
429
+ )
430
+ if len(macro) == 1:
431
+ ext.undef_macros.append(macro[0])
432
+ elif len(macro) == 2:
433
+ ext.define_macros.append(macro)
434
+
435
+ extensions[i] = ext
436
+
437
+ def get_source_files(self):
438
+ self.check_extensions_list(self.extensions)
439
+ filenames = []
440
+
441
+ # Wouldn't it be neat if we knew the names of header files too...
442
+ for ext in self.extensions:
443
+ filenames.extend(ext.sources)
444
+ return filenames
445
+
446
+ def get_outputs(self):
447
+ # Sanity check the 'extensions' list -- can't assume this is being
448
+ # done in the same run as a 'build_extensions()' call (in fact, we
449
+ # can probably assume that it *isn't*!).
450
+ self.check_extensions_list(self.extensions)
451
+
452
+ # And build the list of output (built) filenames. Note that this
453
+ # ignores the 'inplace' flag, and assumes everything goes in the
454
+ # "build" tree.
455
+ outputs = []
456
+ for ext in self.extensions:
457
+ outputs.append(self.get_ext_fullpath(ext.name))
458
+ return outputs
459
+
460
+ def build_extensions(self):
461
+ # First, sanity-check the 'extensions' list
462
+ self.check_extensions_list(self.extensions)
463
+ if self.parallel:
464
+ self._build_extensions_parallel()
465
+ else:
466
+ self._build_extensions_serial()
467
+
468
+ def _build_extensions_parallel(self):
469
+ workers = self.parallel
470
+ if self.parallel is True:
471
+ workers = os.cpu_count() # may return None
472
+ try:
473
+ from concurrent.futures import ThreadPoolExecutor
474
+ except ImportError:
475
+ workers = None
476
+
477
+ if workers is None:
478
+ self._build_extensions_serial()
479
+ return
480
+
481
+ with ThreadPoolExecutor(max_workers=workers) as executor:
482
+ futures = [
483
+ executor.submit(self.build_extension, ext) for ext in self.extensions
484
+ ]
485
+ for ext, fut in zip(self.extensions, futures):
486
+ with self._filter_build_errors(ext):
487
+ fut.result()
488
+
489
+ def _build_extensions_serial(self):
490
+ for ext in self.extensions:
491
+ with self._filter_build_errors(ext):
492
+ self.build_extension(ext)
493
+
494
+ @contextlib.contextmanager
495
+ def _filter_build_errors(self, ext):
496
+ try:
497
+ yield
498
+ except (CCompilerError, DistutilsError, CompileError) as e:
499
+ if not ext.optional:
500
+ raise
501
+ self.warn('building extension "{}" failed: {}'.format(ext.name, e))
502
+
503
+ def build_extension(self, ext):
504
+ sources = ext.sources
505
+ if sources is None or not isinstance(sources, (list, tuple)):
506
+ raise DistutilsSetupError(
507
+ "in 'ext_modules' option (extension '%s'), "
508
+ "'sources' must be present and must be "
509
+ "a list of source filenames" % ext.name
510
+ )
511
+ # sort to make the resulting .so file build reproducible
512
+ sources = sorted(sources)
513
+
514
+ ext_path = self.get_ext_fullpath(ext.name)
515
+ depends = sources + ext.depends
516
+ if not (self.force or newer_group(depends, ext_path, 'newer')):
517
+ log.debug("skipping '%s' extension (up-to-date)", ext.name)
518
+ return
519
+ else:
520
+ log.info("building '%s' extension", ext.name)
521
+
522
+ # First, scan the sources for SWIG definition files (.i), run
523
+ # SWIG on 'em to create .c files, and modify the sources list
524
+ # accordingly.
525
+ sources = self.swig_sources(sources, ext)
526
+
527
+ # Next, compile the source code to object files.
528
+
529
+ # XXX not honouring 'define_macros' or 'undef_macros' -- the
530
+ # CCompiler API needs to change to accommodate this, and I
531
+ # want to do one thing at a time!
532
+
533
+ # Two possible sources for extra compiler arguments:
534
+ # - 'extra_compile_args' in Extension object
535
+ # - CFLAGS environment variable (not particularly
536
+ # elegant, but people seem to expect it and I
537
+ # guess it's useful)
538
+ # The environment variable should take precedence, and
539
+ # any sensible compiler will give precedence to later
540
+ # command line args. Hence we combine them in order:
541
+ extra_args = ext.extra_compile_args or []
542
+
543
+ macros = ext.define_macros[:]
544
+ for undef in ext.undef_macros:
545
+ macros.append((undef,))
546
+
547
+ objects = self.compiler.compile(
548
+ sources,
549
+ output_dir=self.build_temp,
550
+ macros=macros,
551
+ include_dirs=ext.include_dirs,
552
+ debug=self.debug,
553
+ extra_postargs=extra_args,
554
+ depends=ext.depends,
555
+ )
556
+
557
+ # XXX outdated variable, kept here in case third-part code
558
+ # needs it.
559
+ self._built_objects = objects[:]
560
+
561
+ # Now link the object files together into a "shared object" --
562
+ # of course, first we have to figure out all the other things
563
+ # that go into the mix.
564
+ if ext.extra_objects:
565
+ objects.extend(ext.extra_objects)
566
+ extra_args = ext.extra_link_args or []
567
+
568
+ # Detect target language, if not provided
569
+ language = ext.language or self.compiler.detect_language(sources)
570
+
571
+ self.compiler.link_shared_object(
572
+ objects,
573
+ ext_path,
574
+ libraries=self.get_libraries(ext),
575
+ library_dirs=ext.library_dirs,
576
+ runtime_library_dirs=ext.runtime_library_dirs,
577
+ extra_postargs=extra_args,
578
+ export_symbols=self.get_export_symbols(ext),
579
+ debug=self.debug,
580
+ build_temp=self.build_temp,
581
+ target_lang=language,
582
+ )
583
+
584
+ def swig_sources(self, sources, extension):
585
+ """Walk the list of source files in 'sources', looking for SWIG
586
+ interface (.i) files. Run SWIG on all that are found, and
587
+ return a modified 'sources' list with SWIG source files replaced
588
+ by the generated C (or C++) files.
589
+ """
590
+ new_sources = []
591
+ swig_sources = []
592
+ swig_targets = {}
593
+
594
+ # XXX this drops generated C/C++ files into the source tree, which
595
+ # is fine for developers who want to distribute the generated
596
+ # source -- but there should be an option to put SWIG output in
597
+ # the temp dir.
598
+
599
+ if self.swig_cpp:
600
+ log.warn("--swig-cpp is deprecated - use --swig-opts=-c++")
601
+
602
+ if (
603
+ self.swig_cpp
604
+ or ('-c++' in self.swig_opts)
605
+ or ('-c++' in extension.swig_opts)
606
+ ):
607
+ target_ext = '.cpp'
608
+ else:
609
+ target_ext = '.c'
610
+
611
+ for source in sources:
612
+ (base, ext) = os.path.splitext(source)
613
+ if ext == ".i": # SWIG interface file
614
+ new_sources.append(base + '_wrap' + target_ext)
615
+ swig_sources.append(source)
616
+ swig_targets[source] = new_sources[-1]
617
+ else:
618
+ new_sources.append(source)
619
+
620
+ if not swig_sources:
621
+ return new_sources
622
+
623
+ swig = self.swig or self.find_swig()
624
+ swig_cmd = [swig, "-python"]
625
+ swig_cmd.extend(self.swig_opts)
626
+ if self.swig_cpp:
627
+ swig_cmd.append("-c++")
628
+
629
+ # Do not override commandline arguments
630
+ if not self.swig_opts:
631
+ for o in extension.swig_opts:
632
+ swig_cmd.append(o)
633
+
634
+ for source in swig_sources:
635
+ target = swig_targets[source]
636
+ log.info("swigging %s to %s", source, target)
637
+ self.spawn(swig_cmd + ["-o", target, source])
638
+
639
+ return new_sources
640
+
641
+ def find_swig(self):
642
+ """Return the name of the SWIG executable. On Unix, this is
643
+ just "swig" -- it should be in the PATH. Tries a bit harder on
644
+ Windows.
645
+ """
646
+ if os.name == "posix":
647
+ return "swig"
648
+ elif os.name == "nt":
649
+ # Look for SWIG in its standard installation directory on
650
+ # Windows (or so I presume!). If we find it there, great;
651
+ # if not, act like Unix and assume it's in the PATH.
652
+ for vers in ("1.3", "1.2", "1.1"):
653
+ fn = os.path.join("c:\\swig%s" % vers, "swig.exe")
654
+ if os.path.isfile(fn):
655
+ return fn
656
+ else:
657
+ return "swig.exe"
658
+ else:
659
+ raise DistutilsPlatformError(
660
+ "I don't know how to find (much less run) SWIG "
661
+ "on platform '%s'" % os.name
662
+ )
663
+
664
+ # -- Name generators -----------------------------------------------
665
+ # (extension names, filenames, whatever)
666
+ def get_ext_fullpath(self, ext_name):
667
+ """Returns the path of the filename for a given extension.
668
+
669
+ The file is located in `build_lib` or directly in the package
670
+ (inplace option).
671
+ """
672
+ fullname = self.get_ext_fullname(ext_name)
673
+ modpath = fullname.split('.')
674
+ filename = self.get_ext_filename(modpath[-1])
675
+
676
+ if not self.inplace:
677
+ # no further work needed
678
+ # returning :
679
+ # build_dir/package/path/filename
680
+ filename = os.path.join(*modpath[:-1] + [filename])
681
+ return os.path.join(self.build_lib, filename)
682
+
683
+ # the inplace option requires to find the package directory
684
+ # using the build_py command for that
685
+ package = '.'.join(modpath[0:-1])
686
+ build_py = self.get_finalized_command('build_py')
687
+ package_dir = os.path.abspath(build_py.get_package_dir(package))
688
+
689
+ # returning
690
+ # package_dir/filename
691
+ return os.path.join(package_dir, filename)
692
+
693
+ def get_ext_fullname(self, ext_name):
694
+ """Returns the fullname of a given extension name.
695
+
696
+ Adds the `package.` prefix"""
697
+ if self.package is None:
698
+ return ext_name
699
+ else:
700
+ return self.package + '.' + ext_name
701
+
702
+ def get_ext_filename(self, ext_name):
703
+ r"""Convert the name of an extension (eg. "foo.bar") into the name
704
+ of the file from which it will be loaded (eg. "foo/bar.so", or
705
+ "foo\bar.pyd").
706
+ """
707
+ from distutils.sysconfig import get_config_var
708
+
709
+ ext_path = ext_name.split('.')
710
+ ext_suffix = get_config_var('EXT_SUFFIX')
711
+ return os.path.join(*ext_path) + ext_suffix
712
+
713
+ def get_export_symbols(self, ext):
714
+ """Return the list of symbols that a shared extension has to
715
+ export. This either uses 'ext.export_symbols' or, if it's not
716
+ provided, "PyInit_" + module_name. Only relevant on Windows, where
717
+ the .pyd file (DLL) must export the module "PyInit_" function.
718
+ """
719
+ name = ext.name.split('.')[-1]
720
+ try:
721
+ # Unicode module name support as defined in PEP-489
722
+ # https://www.python.org/dev/peps/pep-0489/#export-hook-name
723
+ name.encode('ascii')
724
+ except UnicodeEncodeError:
725
+ suffix = 'U_' + name.encode('punycode').replace(b'-', b'_').decode('ascii')
726
+ else:
727
+ suffix = "_" + name
728
+
729
+ initfunc_name = "PyInit" + suffix
730
+ if initfunc_name not in ext.export_symbols:
731
+ ext.export_symbols.append(initfunc_name)
732
+ return ext.export_symbols
733
+
734
+ def get_libraries(self, ext): # noqa: C901
735
+ """Return the list of libraries to link against when building a
736
+ shared extension. On most platforms, this is just 'ext.libraries';
737
+ on Windows, we add the Python library (eg. python20.dll).
738
+ """
739
+ # The python library is always needed on Windows. For MSVC, this
740
+ # is redundant, since the library is mentioned in a pragma in
741
+ # pyconfig.h that MSVC groks. The other Windows compilers all seem
742
+ # to need it mentioned explicitly, though, so that's what we do.
743
+ # Append '_d' to the python import library on debug builds.
744
+ if sys.platform == "win32":
745
+ from distutils._msvccompiler import MSVCCompiler
746
+
747
+ if not isinstance(self.compiler, MSVCCompiler):
748
+ template = "python%d%d"
749
+ if self.debug:
750
+ template = template + '_d'
751
+ pythonlib = template % (
752
+ sys.hexversion >> 24,
753
+ (sys.hexversion >> 16) & 0xFF,
754
+ )
755
+ # don't extend ext.libraries, it may be shared with other
756
+ # extensions, it is a reference to the original list
757
+ return ext.libraries + [pythonlib]
758
+ else:
759
+ # On Android only the main executable and LD_PRELOADs are considered
760
+ # to be RTLD_GLOBAL, all the dependencies of the main executable
761
+ # remain RTLD_LOCAL and so the shared libraries must be linked with
762
+ # libpython when python is built with a shared python library (issue
763
+ # bpo-21536).
764
+ # On Cygwin (and if required, other POSIX-like platforms based on
765
+ # Windows like MinGW) it is simply necessary that all symbols in
766
+ # shared libraries are resolved at link time.
767
+ from distutils.sysconfig import get_config_var
768
+
769
+ link_libpython = False
770
+ if get_config_var('Py_ENABLE_SHARED'):
771
+ # A native build on an Android device or on Cygwin
772
+ if hasattr(sys, 'getandroidapilevel'):
773
+ link_libpython = True
774
+ elif sys.platform == 'cygwin':
775
+ link_libpython = True
776
+ elif '_PYTHON_HOST_PLATFORM' in os.environ:
777
+ # We are cross-compiling for one of the relevant platforms
778
+ if get_config_var('ANDROID_API_LEVEL') != 0:
779
+ link_libpython = True
780
+ elif get_config_var('MACHDEP') == 'cygwin':
781
+ link_libpython = True
782
+
783
+ if link_libpython:
784
+ ldversion = get_config_var('LDVERSION')
785
+ return ext.libraries + ['python' + ldversion]
786
+
787
+ return ext.libraries + py37compat.pythonlib()
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/build_py.py ADDED
@@ -0,0 +1,407 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils.command.build_py
2
+
3
+ Implements the Distutils 'build_py' command."""
4
+
5
+ import os
6
+ import importlib.util
7
+ import sys
8
+ import glob
9
+
10
+ from distutils.core import Command
11
+ from distutils.errors import DistutilsOptionError, DistutilsFileError
12
+ from distutils.util import convert_path
13
+ from distutils import log
14
+
15
+
16
+ class build_py(Command):
17
+
18
+ description = "\"build\" pure Python modules (copy to build directory)"
19
+
20
+ user_options = [
21
+ ('build-lib=', 'd', "directory to \"build\" (copy) to"),
22
+ ('compile', 'c', "compile .py to .pyc"),
23
+ ('no-compile', None, "don't compile .py files [default]"),
24
+ (
25
+ 'optimize=',
26
+ 'O',
27
+ "also compile with optimization: -O1 for \"python -O\", "
28
+ "-O2 for \"python -OO\", and -O0 to disable [default: -O0]",
29
+ ),
30
+ ('force', 'f', "forcibly build everything (ignore file timestamps)"),
31
+ ]
32
+
33
+ boolean_options = ['compile', 'force']
34
+ negative_opt = {'no-compile': 'compile'}
35
+
36
+ def initialize_options(self):
37
+ self.build_lib = None
38
+ self.py_modules = None
39
+ self.package = None
40
+ self.package_data = None
41
+ self.package_dir = None
42
+ self.compile = 0
43
+ self.optimize = 0
44
+ self.force = None
45
+
46
+ def finalize_options(self):
47
+ self.set_undefined_options(
48
+ 'build', ('build_lib', 'build_lib'), ('force', 'force')
49
+ )
50
+
51
+ # Get the distribution options that are aliases for build_py
52
+ # options -- list of packages and list of modules.
53
+ self.packages = self.distribution.packages
54
+ self.py_modules = self.distribution.py_modules
55
+ self.package_data = self.distribution.package_data
56
+ self.package_dir = {}
57
+ if self.distribution.package_dir:
58
+ for name, path in self.distribution.package_dir.items():
59
+ self.package_dir[name] = convert_path(path)
60
+ self.data_files = self.get_data_files()
61
+
62
+ # Ick, copied straight from install_lib.py (fancy_getopt needs a
63
+ # type system! Hell, *everything* needs a type system!!!)
64
+ if not isinstance(self.optimize, int):
65
+ try:
66
+ self.optimize = int(self.optimize)
67
+ assert 0 <= self.optimize <= 2
68
+ except (ValueError, AssertionError):
69
+ raise DistutilsOptionError("optimize must be 0, 1, or 2")
70
+
71
+ def run(self):
72
+ # XXX copy_file by default preserves atime and mtime. IMHO this is
73
+ # the right thing to do, but perhaps it should be an option -- in
74
+ # particular, a site administrator might want installed files to
75
+ # reflect the time of installation rather than the last
76
+ # modification time before the installed release.
77
+
78
+ # XXX copy_file by default preserves mode, which appears to be the
79
+ # wrong thing to do: if a file is read-only in the working
80
+ # directory, we want it to be installed read/write so that the next
81
+ # installation of the same module distribution can overwrite it
82
+ # without problems. (This might be a Unix-specific issue.) Thus
83
+ # we turn off 'preserve_mode' when copying to the build directory,
84
+ # since the build directory is supposed to be exactly what the
85
+ # installation will look like (ie. we preserve mode when
86
+ # installing).
87
+
88
+ # Two options control which modules will be installed: 'packages'
89
+ # and 'py_modules'. The former lets us work with whole packages, not
90
+ # specifying individual modules at all; the latter is for
91
+ # specifying modules one-at-a-time.
92
+
93
+ if self.py_modules:
94
+ self.build_modules()
95
+ if self.packages:
96
+ self.build_packages()
97
+ self.build_package_data()
98
+
99
+ self.byte_compile(self.get_outputs(include_bytecode=0))
100
+
101
+ def get_data_files(self):
102
+ """Generate list of '(package,src_dir,build_dir,filenames)' tuples"""
103
+ data = []
104
+ if not self.packages:
105
+ return data
106
+ for package in self.packages:
107
+ # Locate package source directory
108
+ src_dir = self.get_package_dir(package)
109
+
110
+ # Compute package build directory
111
+ build_dir = os.path.join(*([self.build_lib] + package.split('.')))
112
+
113
+ # Length of path to strip from found files
114
+ plen = 0
115
+ if src_dir:
116
+ plen = len(src_dir) + 1
117
+
118
+ # Strip directory from globbed filenames
119
+ filenames = [file[plen:] for file in self.find_data_files(package, src_dir)]
120
+ data.append((package, src_dir, build_dir, filenames))
121
+ return data
122
+
123
+ def find_data_files(self, package, src_dir):
124
+ """Return filenames for package's data files in 'src_dir'"""
125
+ globs = self.package_data.get('', []) + self.package_data.get(package, [])
126
+ files = []
127
+ for pattern in globs:
128
+ # Each pattern has to be converted to a platform-specific path
129
+ filelist = glob.glob(
130
+ os.path.join(glob.escape(src_dir), convert_path(pattern))
131
+ )
132
+ # Files that match more than one pattern are only added once
133
+ files.extend(
134
+ [fn for fn in filelist if fn not in files and os.path.isfile(fn)]
135
+ )
136
+ return files
137
+
138
+ def build_package_data(self):
139
+ """Copy data files into build directory"""
140
+ for package, src_dir, build_dir, filenames in self.data_files:
141
+ for filename in filenames:
142
+ target = os.path.join(build_dir, filename)
143
+ self.mkpath(os.path.dirname(target))
144
+ self.copy_file(
145
+ os.path.join(src_dir, filename), target, preserve_mode=False
146
+ )
147
+
148
+ def get_package_dir(self, package):
149
+ """Return the directory, relative to the top of the source
150
+ distribution, where package 'package' should be found
151
+ (at least according to the 'package_dir' option, if any)."""
152
+ path = package.split('.')
153
+
154
+ if not self.package_dir:
155
+ if path:
156
+ return os.path.join(*path)
157
+ else:
158
+ return ''
159
+ else:
160
+ tail = []
161
+ while path:
162
+ try:
163
+ pdir = self.package_dir['.'.join(path)]
164
+ except KeyError:
165
+ tail.insert(0, path[-1])
166
+ del path[-1]
167
+ else:
168
+ tail.insert(0, pdir)
169
+ return os.path.join(*tail)
170
+ else:
171
+ # Oops, got all the way through 'path' without finding a
172
+ # match in package_dir. If package_dir defines a directory
173
+ # for the root (nameless) package, then fallback on it;
174
+ # otherwise, we might as well have not consulted
175
+ # package_dir at all, as we just use the directory implied
176
+ # by 'tail' (which should be the same as the original value
177
+ # of 'path' at this point).
178
+ pdir = self.package_dir.get('')
179
+ if pdir is not None:
180
+ tail.insert(0, pdir)
181
+
182
+ if tail:
183
+ return os.path.join(*tail)
184
+ else:
185
+ return ''
186
+
187
+ def check_package(self, package, package_dir):
188
+ # Empty dir name means current directory, which we can probably
189
+ # assume exists. Also, os.path.exists and isdir don't know about
190
+ # my "empty string means current dir" convention, so we have to
191
+ # circumvent them.
192
+ if package_dir != "":
193
+ if not os.path.exists(package_dir):
194
+ raise DistutilsFileError(
195
+ "package directory '%s' does not exist" % package_dir
196
+ )
197
+ if not os.path.isdir(package_dir):
198
+ raise DistutilsFileError(
199
+ "supposed package directory '%s' exists, "
200
+ "but is not a directory" % package_dir
201
+ )
202
+
203
+ # Directories without __init__.py are namespace packages (PEP 420).
204
+ if package:
205
+ init_py = os.path.join(package_dir, "__init__.py")
206
+ if os.path.isfile(init_py):
207
+ return init_py
208
+
209
+ # Either not in a package at all (__init__.py not expected), or
210
+ # __init__.py doesn't exist -- so don't return the filename.
211
+ return None
212
+
213
+ def check_module(self, module, module_file):
214
+ if not os.path.isfile(module_file):
215
+ log.warn("file %s (for module %s) not found", module_file, module)
216
+ return False
217
+ else:
218
+ return True
219
+
220
+ def find_package_modules(self, package, package_dir):
221
+ self.check_package(package, package_dir)
222
+ module_files = glob.glob(os.path.join(glob.escape(package_dir), "*.py"))
223
+ modules = []
224
+ setup_script = os.path.abspath(self.distribution.script_name)
225
+
226
+ for f in module_files:
227
+ abs_f = os.path.abspath(f)
228
+ if abs_f != setup_script:
229
+ module = os.path.splitext(os.path.basename(f))[0]
230
+ modules.append((package, module, f))
231
+ else:
232
+ self.debug_print("excluding %s" % setup_script)
233
+ return modules
234
+
235
+ def find_modules(self):
236
+ """Finds individually-specified Python modules, ie. those listed by
237
+ module name in 'self.py_modules'. Returns a list of tuples (package,
238
+ module_base, filename): 'package' is a tuple of the path through
239
+ package-space to the module; 'module_base' is the bare (no
240
+ packages, no dots) module name, and 'filename' is the path to the
241
+ ".py" file (relative to the distribution root) that implements the
242
+ module.
243
+ """
244
+ # Map package names to tuples of useful info about the package:
245
+ # (package_dir, checked)
246
+ # package_dir - the directory where we'll find source files for
247
+ # this package
248
+ # checked - true if we have checked that the package directory
249
+ # is valid (exists, contains __init__.py, ... ?)
250
+ packages = {}
251
+
252
+ # List of (package, module, filename) tuples to return
253
+ modules = []
254
+
255
+ # We treat modules-in-packages almost the same as toplevel modules,
256
+ # just the "package" for a toplevel is empty (either an empty
257
+ # string or empty list, depending on context). Differences:
258
+ # - don't check for __init__.py in directory for empty package
259
+ for module in self.py_modules:
260
+ path = module.split('.')
261
+ package = '.'.join(path[0:-1])
262
+ module_base = path[-1]
263
+
264
+ try:
265
+ (package_dir, checked) = packages[package]
266
+ except KeyError:
267
+ package_dir = self.get_package_dir(package)
268
+ checked = 0
269
+
270
+ if not checked:
271
+ init_py = self.check_package(package, package_dir)
272
+ packages[package] = (package_dir, 1)
273
+ if init_py:
274
+ modules.append((package, "__init__", init_py))
275
+
276
+ # XXX perhaps we should also check for just .pyc files
277
+ # (so greedy closed-source bastards can distribute Python
278
+ # modules too)
279
+ module_file = os.path.join(package_dir, module_base + ".py")
280
+ if not self.check_module(module, module_file):
281
+ continue
282
+
283
+ modules.append((package, module_base, module_file))
284
+
285
+ return modules
286
+
287
+ def find_all_modules(self):
288
+ """Compute the list of all modules that will be built, whether
289
+ they are specified one-module-at-a-time ('self.py_modules') or
290
+ by whole packages ('self.packages'). Return a list of tuples
291
+ (package, module, module_file), just like 'find_modules()' and
292
+ 'find_package_modules()' do."""
293
+ modules = []
294
+ if self.py_modules:
295
+ modules.extend(self.find_modules())
296
+ if self.packages:
297
+ for package in self.packages:
298
+ package_dir = self.get_package_dir(package)
299
+ m = self.find_package_modules(package, package_dir)
300
+ modules.extend(m)
301
+ return modules
302
+
303
+ def get_source_files(self):
304
+ return [module[-1] for module in self.find_all_modules()]
305
+
306
+ def get_module_outfile(self, build_dir, package, module):
307
+ outfile_path = [build_dir] + list(package) + [module + ".py"]
308
+ return os.path.join(*outfile_path)
309
+
310
+ def get_outputs(self, include_bytecode=1):
311
+ modules = self.find_all_modules()
312
+ outputs = []
313
+ for (package, module, module_file) in modules:
314
+ package = package.split('.')
315
+ filename = self.get_module_outfile(self.build_lib, package, module)
316
+ outputs.append(filename)
317
+ if include_bytecode:
318
+ if self.compile:
319
+ outputs.append(
320
+ importlib.util.cache_from_source(filename, optimization='')
321
+ )
322
+ if self.optimize > 0:
323
+ outputs.append(
324
+ importlib.util.cache_from_source(
325
+ filename, optimization=self.optimize
326
+ )
327
+ )
328
+
329
+ outputs += [
330
+ os.path.join(build_dir, filename)
331
+ for package, src_dir, build_dir, filenames in self.data_files
332
+ for filename in filenames
333
+ ]
334
+
335
+ return outputs
336
+
337
+ def build_module(self, module, module_file, package):
338
+ if isinstance(package, str):
339
+ package = package.split('.')
340
+ elif not isinstance(package, (list, tuple)):
341
+ raise TypeError(
342
+ "'package' must be a string (dot-separated), list, or tuple"
343
+ )
344
+
345
+ # Now put the module source file into the "build" area -- this is
346
+ # easy, we just copy it somewhere under self.build_lib (the build
347
+ # directory for Python source).
348
+ outfile = self.get_module_outfile(self.build_lib, package, module)
349
+ dir = os.path.dirname(outfile)
350
+ self.mkpath(dir)
351
+ return self.copy_file(module_file, outfile, preserve_mode=0)
352
+
353
+ def build_modules(self):
354
+ modules = self.find_modules()
355
+ for (package, module, module_file) in modules:
356
+ # Now "build" the module -- ie. copy the source file to
357
+ # self.build_lib (the build directory for Python source).
358
+ # (Actually, it gets copied to the directory for this package
359
+ # under self.build_lib.)
360
+ self.build_module(module, module_file, package)
361
+
362
+ def build_packages(self):
363
+ for package in self.packages:
364
+ # Get list of (package, module, module_file) tuples based on
365
+ # scanning the package directory. 'package' is only included
366
+ # in the tuple so that 'find_modules()' and
367
+ # 'find_package_tuples()' have a consistent interface; it's
368
+ # ignored here (apart from a sanity check). Also, 'module' is
369
+ # the *unqualified* module name (ie. no dots, no package -- we
370
+ # already know its package!), and 'module_file' is the path to
371
+ # the .py file, relative to the current directory
372
+ # (ie. including 'package_dir').
373
+ package_dir = self.get_package_dir(package)
374
+ modules = self.find_package_modules(package, package_dir)
375
+
376
+ # Now loop over the modules we found, "building" each one (just
377
+ # copy it to self.build_lib).
378
+ for (package_, module, module_file) in modules:
379
+ assert package == package_
380
+ self.build_module(module, module_file, package)
381
+
382
+ def byte_compile(self, files):
383
+ if sys.dont_write_bytecode:
384
+ self.warn('byte-compiling is disabled, skipping.')
385
+ return
386
+
387
+ from distutils.util import byte_compile
388
+
389
+ prefix = self.build_lib
390
+ if prefix[-1] != os.sep:
391
+ prefix = prefix + os.sep
392
+
393
+ # XXX this code is essentially the same as the 'byte_compile()
394
+ # method of the "install_lib" command, except for the determination
395
+ # of the 'prefix' string. Hmmm.
396
+ if self.compile:
397
+ byte_compile(
398
+ files, optimize=0, force=self.force, prefix=prefix, dry_run=self.dry_run
399
+ )
400
+ if self.optimize > 0:
401
+ byte_compile(
402
+ files,
403
+ optimize=self.optimize,
404
+ force=self.force,
405
+ prefix=prefix,
406
+ dry_run=self.dry_run,
407
+ )
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/build_scripts.py ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils.command.build_scripts
2
+
3
+ Implements the Distutils 'build_scripts' command."""
4
+
5
+ import os
6
+ import re
7
+ from stat import ST_MODE
8
+ from distutils import sysconfig
9
+ from distutils.core import Command
10
+ from distutils.dep_util import newer
11
+ from distutils.util import convert_path
12
+ from distutils import log
13
+ import tokenize
14
+
15
+ shebang_pattern = re.compile('^#!.*python[0-9.]*([ \t].*)?$')
16
+ """
17
+ Pattern matching a Python interpreter indicated in first line of a script.
18
+ """
19
+
20
+ # for Setuptools compatibility
21
+ first_line_re = shebang_pattern
22
+
23
+
24
+ class build_scripts(Command):
25
+
26
+ description = "\"build\" scripts (copy and fixup #! line)"
27
+
28
+ user_options = [
29
+ ('build-dir=', 'd', "directory to \"build\" (copy) to"),
30
+ ('force', 'f', "forcibly build everything (ignore file timestamps"),
31
+ ('executable=', 'e', "specify final destination interpreter path"),
32
+ ]
33
+
34
+ boolean_options = ['force']
35
+
36
+ def initialize_options(self):
37
+ self.build_dir = None
38
+ self.scripts = None
39
+ self.force = None
40
+ self.executable = None
41
+
42
+ def finalize_options(self):
43
+ self.set_undefined_options(
44
+ 'build',
45
+ ('build_scripts', 'build_dir'),
46
+ ('force', 'force'),
47
+ ('executable', 'executable'),
48
+ )
49
+ self.scripts = self.distribution.scripts
50
+
51
+ def get_source_files(self):
52
+ return self.scripts
53
+
54
+ def run(self):
55
+ if not self.scripts:
56
+ return
57
+ self.copy_scripts()
58
+
59
+ def copy_scripts(self):
60
+ """
61
+ Copy each script listed in ``self.scripts``.
62
+
63
+ If a script is marked as a Python script (first line matches
64
+ 'shebang_pattern', i.e. starts with ``#!`` and contains
65
+ "python"), then adjust in the copy the first line to refer to
66
+ the current Python interpreter.
67
+ """
68
+ self.mkpath(self.build_dir)
69
+ outfiles = []
70
+ updated_files = []
71
+ for script in self.scripts:
72
+ self._copy_script(script, outfiles, updated_files)
73
+
74
+ self._change_modes(outfiles)
75
+
76
+ return outfiles, updated_files
77
+
78
+ def _copy_script(self, script, outfiles, updated_files): # noqa: C901
79
+ shebang_match = None
80
+ script = convert_path(script)
81
+ outfile = os.path.join(self.build_dir, os.path.basename(script))
82
+ outfiles.append(outfile)
83
+
84
+ if not self.force and not newer(script, outfile):
85
+ log.debug("not copying %s (up-to-date)", script)
86
+ return
87
+
88
+ # Always open the file, but ignore failures in dry-run mode
89
+ # in order to attempt to copy directly.
90
+ try:
91
+ f = tokenize.open(script)
92
+ except OSError:
93
+ if not self.dry_run:
94
+ raise
95
+ f = None
96
+ else:
97
+ first_line = f.readline()
98
+ if not first_line:
99
+ self.warn("%s is an empty file (skipping)" % script)
100
+ return
101
+
102
+ shebang_match = shebang_pattern.match(first_line)
103
+
104
+ updated_files.append(outfile)
105
+ if shebang_match:
106
+ log.info("copying and adjusting %s -> %s", script, self.build_dir)
107
+ if not self.dry_run:
108
+ if not sysconfig.python_build:
109
+ executable = self.executable
110
+ else:
111
+ executable = os.path.join(
112
+ sysconfig.get_config_var("BINDIR"),
113
+ "python%s%s"
114
+ % (
115
+ sysconfig.get_config_var("VERSION"),
116
+ sysconfig.get_config_var("EXE"),
117
+ ),
118
+ )
119
+ post_interp = shebang_match.group(1) or ''
120
+ shebang = "#!" + executable + post_interp + "\n"
121
+ self._validate_shebang(shebang, f.encoding)
122
+ with open(outfile, "w", encoding=f.encoding) as outf:
123
+ outf.write(shebang)
124
+ outf.writelines(f.readlines())
125
+ if f:
126
+ f.close()
127
+ else:
128
+ if f:
129
+ f.close()
130
+ self.copy_file(script, outfile)
131
+
132
+ def _change_modes(self, outfiles):
133
+ if os.name != 'posix':
134
+ return
135
+
136
+ for file in outfiles:
137
+ self._change_mode(file)
138
+
139
+ def _change_mode(self, file):
140
+ if self.dry_run:
141
+ log.info("changing mode of %s", file)
142
+ return
143
+
144
+ oldmode = os.stat(file)[ST_MODE] & 0o7777
145
+ newmode = (oldmode | 0o555) & 0o7777
146
+ if newmode != oldmode:
147
+ log.info("changing mode of %s from %o to %o", file, oldmode, newmode)
148
+ os.chmod(file, newmode)
149
+
150
+ @staticmethod
151
+ def _validate_shebang(shebang, encoding):
152
+ # Python parser starts to read a script using UTF-8 until
153
+ # it gets a #coding:xxx cookie. The shebang has to be the
154
+ # first line of a file, the #coding:xxx cookie cannot be
155
+ # written before. So the shebang has to be encodable to
156
+ # UTF-8.
157
+ try:
158
+ shebang.encode('utf-8')
159
+ except UnicodeEncodeError:
160
+ raise ValueError(
161
+ "The shebang ({!r}) is not encodable " "to utf-8".format(shebang)
162
+ )
163
+
164
+ # If the script is encoded to a custom encoding (use a
165
+ # #coding:xxx cookie), the shebang has to be encodable to
166
+ # the script encoding too.
167
+ try:
168
+ shebang.encode(encoding)
169
+ except UnicodeEncodeError:
170
+ raise ValueError(
171
+ "The shebang ({!r}) is not encodable "
172
+ "to the script encoding ({})".format(shebang, encoding)
173
+ )
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/config.py ADDED
@@ -0,0 +1,377 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils.command.config
2
+
3
+ Implements the Distutils 'config' command, a (mostly) empty command class
4
+ that exists mainly to be sub-classed by specific module distributions and
5
+ applications. The idea is that while every "config" command is different,
6
+ at least they're all named the same, and users always see "config" in the
7
+ list of standard commands. Also, this is a good place to put common
8
+ configure-like tasks: "try to compile this C code", or "figure out where
9
+ this header file lives".
10
+ """
11
+
12
+ import os
13
+ import re
14
+
15
+ from distutils.core import Command
16
+ from distutils.errors import DistutilsExecError
17
+ from distutils.sysconfig import customize_compiler
18
+ from distutils import log
19
+
20
+ LANG_EXT = {"c": ".c", "c++": ".cxx"}
21
+
22
+
23
+ class config(Command):
24
+
25
+ description = "prepare to build"
26
+
27
+ user_options = [
28
+ ('compiler=', None, "specify the compiler type"),
29
+ ('cc=', None, "specify the compiler executable"),
30
+ ('include-dirs=', 'I', "list of directories to search for header files"),
31
+ ('define=', 'D', "C preprocessor macros to define"),
32
+ ('undef=', 'U', "C preprocessor macros to undefine"),
33
+ ('libraries=', 'l', "external C libraries to link with"),
34
+ ('library-dirs=', 'L', "directories to search for external C libraries"),
35
+ ('noisy', None, "show every action (compile, link, run, ...) taken"),
36
+ (
37
+ 'dump-source',
38
+ None,
39
+ "dump generated source files before attempting to compile them",
40
+ ),
41
+ ]
42
+
43
+ # The three standard command methods: since the "config" command
44
+ # does nothing by default, these are empty.
45
+
46
+ def initialize_options(self):
47
+ self.compiler = None
48
+ self.cc = None
49
+ self.include_dirs = None
50
+ self.libraries = None
51
+ self.library_dirs = None
52
+
53
+ # maximal output for now
54
+ self.noisy = 1
55
+ self.dump_source = 1
56
+
57
+ # list of temporary files generated along-the-way that we have
58
+ # to clean at some point
59
+ self.temp_files = []
60
+
61
+ def finalize_options(self):
62
+ if self.include_dirs is None:
63
+ self.include_dirs = self.distribution.include_dirs or []
64
+ elif isinstance(self.include_dirs, str):
65
+ self.include_dirs = self.include_dirs.split(os.pathsep)
66
+
67
+ if self.libraries is None:
68
+ self.libraries = []
69
+ elif isinstance(self.libraries, str):
70
+ self.libraries = [self.libraries]
71
+
72
+ if self.library_dirs is None:
73
+ self.library_dirs = []
74
+ elif isinstance(self.library_dirs, str):
75
+ self.library_dirs = self.library_dirs.split(os.pathsep)
76
+
77
+ def run(self):
78
+ pass
79
+
80
+ # Utility methods for actual "config" commands. The interfaces are
81
+ # loosely based on Autoconf macros of similar names. Sub-classes
82
+ # may use these freely.
83
+
84
+ def _check_compiler(self):
85
+ """Check that 'self.compiler' really is a CCompiler object;
86
+ if not, make it one.
87
+ """
88
+ # We do this late, and only on-demand, because this is an expensive
89
+ # import.
90
+ from distutils.ccompiler import CCompiler, new_compiler
91
+
92
+ if not isinstance(self.compiler, CCompiler):
93
+ self.compiler = new_compiler(
94
+ compiler=self.compiler, dry_run=self.dry_run, force=1
95
+ )
96
+ customize_compiler(self.compiler)
97
+ if self.include_dirs:
98
+ self.compiler.set_include_dirs(self.include_dirs)
99
+ if self.libraries:
100
+ self.compiler.set_libraries(self.libraries)
101
+ if self.library_dirs:
102
+ self.compiler.set_library_dirs(self.library_dirs)
103
+
104
+ def _gen_temp_sourcefile(self, body, headers, lang):
105
+ filename = "_configtest" + LANG_EXT[lang]
106
+ with open(filename, "w") as file:
107
+ if headers:
108
+ for header in headers:
109
+ file.write("#include <%s>\n" % header)
110
+ file.write("\n")
111
+ file.write(body)
112
+ if body[-1] != "\n":
113
+ file.write("\n")
114
+ return filename
115
+
116
+ def _preprocess(self, body, headers, include_dirs, lang):
117
+ src = self._gen_temp_sourcefile(body, headers, lang)
118
+ out = "_configtest.i"
119
+ self.temp_files.extend([src, out])
120
+ self.compiler.preprocess(src, out, include_dirs=include_dirs)
121
+ return (src, out)
122
+
123
+ def _compile(self, body, headers, include_dirs, lang):
124
+ src = self._gen_temp_sourcefile(body, headers, lang)
125
+ if self.dump_source:
126
+ dump_file(src, "compiling '%s':" % src)
127
+ (obj,) = self.compiler.object_filenames([src])
128
+ self.temp_files.extend([src, obj])
129
+ self.compiler.compile([src], include_dirs=include_dirs)
130
+ return (src, obj)
131
+
132
+ def _link(self, body, headers, include_dirs, libraries, library_dirs, lang):
133
+ (src, obj) = self._compile(body, headers, include_dirs, lang)
134
+ prog = os.path.splitext(os.path.basename(src))[0]
135
+ self.compiler.link_executable(
136
+ [obj],
137
+ prog,
138
+ libraries=libraries,
139
+ library_dirs=library_dirs,
140
+ target_lang=lang,
141
+ )
142
+
143
+ if self.compiler.exe_extension is not None:
144
+ prog = prog + self.compiler.exe_extension
145
+ self.temp_files.append(prog)
146
+
147
+ return (src, obj, prog)
148
+
149
+ def _clean(self, *filenames):
150
+ if not filenames:
151
+ filenames = self.temp_files
152
+ self.temp_files = []
153
+ log.info("removing: %s", ' '.join(filenames))
154
+ for filename in filenames:
155
+ try:
156
+ os.remove(filename)
157
+ except OSError:
158
+ pass
159
+
160
+ # XXX these ignore the dry-run flag: what to do, what to do? even if
161
+ # you want a dry-run build, you still need some sort of configuration
162
+ # info. My inclination is to make it up to the real config command to
163
+ # consult 'dry_run', and assume a default (minimal) configuration if
164
+ # true. The problem with trying to do it here is that you'd have to
165
+ # return either true or false from all the 'try' methods, neither of
166
+ # which is correct.
167
+
168
+ # XXX need access to the header search path and maybe default macros.
169
+
170
+ def try_cpp(self, body=None, headers=None, include_dirs=None, lang="c"):
171
+ """Construct a source file from 'body' (a string containing lines
172
+ of C/C++ code) and 'headers' (a list of header files to include)
173
+ and run it through the preprocessor. Return true if the
174
+ preprocessor succeeded, false if there were any errors.
175
+ ('body' probably isn't of much use, but what the heck.)
176
+ """
177
+ from distutils.ccompiler import CompileError
178
+
179
+ self._check_compiler()
180
+ ok = True
181
+ try:
182
+ self._preprocess(body, headers, include_dirs, lang)
183
+ except CompileError:
184
+ ok = False
185
+
186
+ self._clean()
187
+ return ok
188
+
189
+ def search_cpp(self, pattern, body=None, headers=None, include_dirs=None, lang="c"):
190
+ """Construct a source file (just like 'try_cpp()'), run it through
191
+ the preprocessor, and return true if any line of the output matches
192
+ 'pattern'. 'pattern' should either be a compiled regex object or a
193
+ string containing a regex. If both 'body' and 'headers' are None,
194
+ preprocesses an empty file -- which can be useful to determine the
195
+ symbols the preprocessor and compiler set by default.
196
+ """
197
+ self._check_compiler()
198
+ src, out = self._preprocess(body, headers, include_dirs, lang)
199
+
200
+ if isinstance(pattern, str):
201
+ pattern = re.compile(pattern)
202
+
203
+ with open(out) as file:
204
+ match = False
205
+ while True:
206
+ line = file.readline()
207
+ if line == '':
208
+ break
209
+ if pattern.search(line):
210
+ match = True
211
+ break
212
+
213
+ self._clean()
214
+ return match
215
+
216
+ def try_compile(self, body, headers=None, include_dirs=None, lang="c"):
217
+ """Try to compile a source file built from 'body' and 'headers'.
218
+ Return true on success, false otherwise.
219
+ """
220
+ from distutils.ccompiler import CompileError
221
+
222
+ self._check_compiler()
223
+ try:
224
+ self._compile(body, headers, include_dirs, lang)
225
+ ok = True
226
+ except CompileError:
227
+ ok = False
228
+
229
+ log.info(ok and "success!" or "failure.")
230
+ self._clean()
231
+ return ok
232
+
233
+ def try_link(
234
+ self,
235
+ body,
236
+ headers=None,
237
+ include_dirs=None,
238
+ libraries=None,
239
+ library_dirs=None,
240
+ lang="c",
241
+ ):
242
+ """Try to compile and link a source file, built from 'body' and
243
+ 'headers', to executable form. Return true on success, false
244
+ otherwise.
245
+ """
246
+ from distutils.ccompiler import CompileError, LinkError
247
+
248
+ self._check_compiler()
249
+ try:
250
+ self._link(body, headers, include_dirs, libraries, library_dirs, lang)
251
+ ok = True
252
+ except (CompileError, LinkError):
253
+ ok = False
254
+
255
+ log.info(ok and "success!" or "failure.")
256
+ self._clean()
257
+ return ok
258
+
259
+ def try_run(
260
+ self,
261
+ body,
262
+ headers=None,
263
+ include_dirs=None,
264
+ libraries=None,
265
+ library_dirs=None,
266
+ lang="c",
267
+ ):
268
+ """Try to compile, link to an executable, and run a program
269
+ built from 'body' and 'headers'. Return true on success, false
270
+ otherwise.
271
+ """
272
+ from distutils.ccompiler import CompileError, LinkError
273
+
274
+ self._check_compiler()
275
+ try:
276
+ src, obj, exe = self._link(
277
+ body, headers, include_dirs, libraries, library_dirs, lang
278
+ )
279
+ self.spawn([exe])
280
+ ok = True
281
+ except (CompileError, LinkError, DistutilsExecError):
282
+ ok = False
283
+
284
+ log.info(ok and "success!" or "failure.")
285
+ self._clean()
286
+ return ok
287
+
288
+ # -- High-level methods --------------------------------------------
289
+ # (these are the ones that are actually likely to be useful
290
+ # when implementing a real-world config command!)
291
+
292
+ def check_func(
293
+ self,
294
+ func,
295
+ headers=None,
296
+ include_dirs=None,
297
+ libraries=None,
298
+ library_dirs=None,
299
+ decl=0,
300
+ call=0,
301
+ ):
302
+ """Determine if function 'func' is available by constructing a
303
+ source file that refers to 'func', and compiles and links it.
304
+ If everything succeeds, returns true; otherwise returns false.
305
+
306
+ The constructed source file starts out by including the header
307
+ files listed in 'headers'. If 'decl' is true, it then declares
308
+ 'func' (as "int func()"); you probably shouldn't supply 'headers'
309
+ and set 'decl' true in the same call, or you might get errors about
310
+ a conflicting declarations for 'func'. Finally, the constructed
311
+ 'main()' function either references 'func' or (if 'call' is true)
312
+ calls it. 'libraries' and 'library_dirs' are used when
313
+ linking.
314
+ """
315
+ self._check_compiler()
316
+ body = []
317
+ if decl:
318
+ body.append("int %s ();" % func)
319
+ body.append("int main () {")
320
+ if call:
321
+ body.append(" %s();" % func)
322
+ else:
323
+ body.append(" %s;" % func)
324
+ body.append("}")
325
+ body = "\n".join(body) + "\n"
326
+
327
+ return self.try_link(body, headers, include_dirs, libraries, library_dirs)
328
+
329
+ def check_lib(
330
+ self,
331
+ library,
332
+ library_dirs=None,
333
+ headers=None,
334
+ include_dirs=None,
335
+ other_libraries=[],
336
+ ):
337
+ """Determine if 'library' is available to be linked against,
338
+ without actually checking that any particular symbols are provided
339
+ by it. 'headers' will be used in constructing the source file to
340
+ be compiled, but the only effect of this is to check if all the
341
+ header files listed are available. Any libraries listed in
342
+ 'other_libraries' will be included in the link, in case 'library'
343
+ has symbols that depend on other libraries.
344
+ """
345
+ self._check_compiler()
346
+ return self.try_link(
347
+ "int main (void) { }",
348
+ headers,
349
+ include_dirs,
350
+ [library] + other_libraries,
351
+ library_dirs,
352
+ )
353
+
354
+ def check_header(self, header, include_dirs=None, library_dirs=None, lang="c"):
355
+ """Determine if the system header file named by 'header_file'
356
+ exists and can be found by the preprocessor; return true if so,
357
+ false otherwise.
358
+ """
359
+ return self.try_cpp(
360
+ body="/* No body */", headers=[header], include_dirs=include_dirs
361
+ )
362
+
363
+
364
+ def dump_file(filename, head=None):
365
+ """Dumps a file content into log.info.
366
+
367
+ If head is not None, will be dumped before the file content.
368
+ """
369
+ if head is None:
370
+ log.info('%s', filename)
371
+ else:
372
+ log.info(head)
373
+ file = open(filename)
374
+ try:
375
+ log.info(file.read())
376
+ finally:
377
+ file.close()
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/install.py ADDED
@@ -0,0 +1,814 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils.command.install
2
+
3
+ Implements the Distutils 'install' command."""
4
+
5
+ import sys
6
+ import os
7
+ import contextlib
8
+ import sysconfig
9
+ import itertools
10
+
11
+ from distutils import log
12
+ from distutils.core import Command
13
+ from distutils.debug import DEBUG
14
+ from distutils.sysconfig import get_config_vars
15
+ from distutils.file_util import write_file
16
+ from distutils.util import convert_path, subst_vars, change_root
17
+ from distutils.util import get_platform
18
+ from distutils.errors import DistutilsOptionError, DistutilsPlatformError
19
+ from . import _framework_compat as fw
20
+ from .. import _collections
21
+
22
+ from site import USER_BASE
23
+ from site import USER_SITE
24
+
25
+ HAS_USER_SITE = True
26
+
27
+ WINDOWS_SCHEME = {
28
+ 'purelib': '{base}/Lib/site-packages',
29
+ 'platlib': '{base}/Lib/site-packages',
30
+ 'headers': '{base}/Include/{dist_name}',
31
+ 'scripts': '{base}/Scripts',
32
+ 'data': '{base}',
33
+ }
34
+
35
+ INSTALL_SCHEMES = {
36
+ 'posix_prefix': {
37
+ 'purelib': '{base}/lib/{implementation_lower}{py_version_short}/site-packages',
38
+ 'platlib': '{platbase}/{platlibdir}/{implementation_lower}'
39
+ '{py_version_short}/site-packages',
40
+ 'headers': '{base}/include/{implementation_lower}'
41
+ '{py_version_short}{abiflags}/{dist_name}',
42
+ 'scripts': '{base}/bin',
43
+ 'data': '{base}',
44
+ },
45
+ 'posix_home': {
46
+ 'purelib': '{base}/lib/{implementation_lower}',
47
+ 'platlib': '{base}/{platlibdir}/{implementation_lower}',
48
+ 'headers': '{base}/include/{implementation_lower}/{dist_name}',
49
+ 'scripts': '{base}/bin',
50
+ 'data': '{base}',
51
+ },
52
+ 'nt': WINDOWS_SCHEME,
53
+ 'pypy': {
54
+ 'purelib': '{base}/site-packages',
55
+ 'platlib': '{base}/site-packages',
56
+ 'headers': '{base}/include/{dist_name}',
57
+ 'scripts': '{base}/bin',
58
+ 'data': '{base}',
59
+ },
60
+ 'pypy_nt': {
61
+ 'purelib': '{base}/site-packages',
62
+ 'platlib': '{base}/site-packages',
63
+ 'headers': '{base}/include/{dist_name}',
64
+ 'scripts': '{base}/Scripts',
65
+ 'data': '{base}',
66
+ },
67
+ }
68
+
69
+ # user site schemes
70
+ if HAS_USER_SITE:
71
+ INSTALL_SCHEMES['nt_user'] = {
72
+ 'purelib': '{usersite}',
73
+ 'platlib': '{usersite}',
74
+ 'headers': '{userbase}/{implementation}{py_version_nodot_plat}'
75
+ '/Include/{dist_name}',
76
+ 'scripts': '{userbase}/{implementation}{py_version_nodot_plat}/Scripts',
77
+ 'data': '{userbase}',
78
+ }
79
+
80
+ INSTALL_SCHEMES['posix_user'] = {
81
+ 'purelib': '{usersite}',
82
+ 'platlib': '{usersite}',
83
+ 'headers': '{userbase}/include/{implementation_lower}'
84
+ '{py_version_short}{abiflags}/{dist_name}',
85
+ 'scripts': '{userbase}/bin',
86
+ 'data': '{userbase}',
87
+ }
88
+
89
+
90
+ INSTALL_SCHEMES.update(fw.schemes)
91
+
92
+
93
+ # The keys to an installation scheme; if any new types of files are to be
94
+ # installed, be sure to add an entry to every installation scheme above,
95
+ # and to SCHEME_KEYS here.
96
+ SCHEME_KEYS = ('purelib', 'platlib', 'headers', 'scripts', 'data')
97
+
98
+
99
+ def _load_sysconfig_schemes():
100
+ with contextlib.suppress(AttributeError):
101
+ return {
102
+ scheme: sysconfig.get_paths(scheme, expand=False)
103
+ for scheme in sysconfig.get_scheme_names()
104
+ }
105
+
106
+
107
+ def _load_schemes():
108
+ """
109
+ Extend default schemes with schemes from sysconfig.
110
+ """
111
+
112
+ sysconfig_schemes = _load_sysconfig_schemes() or {}
113
+
114
+ return {
115
+ scheme: {
116
+ **INSTALL_SCHEMES.get(scheme, {}),
117
+ **sysconfig_schemes.get(scheme, {}),
118
+ }
119
+ for scheme in set(itertools.chain(INSTALL_SCHEMES, sysconfig_schemes))
120
+ }
121
+
122
+
123
+ def _get_implementation():
124
+ if hasattr(sys, 'pypy_version_info'):
125
+ return 'PyPy'
126
+ else:
127
+ return 'Python'
128
+
129
+
130
+ def _select_scheme(ob, name):
131
+ scheme = _inject_headers(name, _load_scheme(_resolve_scheme(name)))
132
+ vars(ob).update(_remove_set(ob, _scheme_attrs(scheme)))
133
+
134
+
135
+ def _remove_set(ob, attrs):
136
+ """
137
+ Include only attrs that are None in ob.
138
+ """
139
+ return {key: value for key, value in attrs.items() if getattr(ob, key) is None}
140
+
141
+
142
+ def _resolve_scheme(name):
143
+ os_name, sep, key = name.partition('_')
144
+ try:
145
+ resolved = sysconfig.get_preferred_scheme(key)
146
+ except Exception:
147
+ resolved = fw.scheme(_pypy_hack(name))
148
+ return resolved
149
+
150
+
151
+ def _load_scheme(name):
152
+ return _load_schemes()[name]
153
+
154
+
155
+ def _inject_headers(name, scheme):
156
+ """
157
+ Given a scheme name and the resolved scheme,
158
+ if the scheme does not include headers, resolve
159
+ the fallback scheme for the name and use headers
160
+ from it. pypa/distutils#88
161
+ """
162
+ # Bypass the preferred scheme, which may not
163
+ # have defined headers.
164
+ fallback = _load_scheme(_pypy_hack(name))
165
+ scheme.setdefault('headers', fallback['headers'])
166
+ return scheme
167
+
168
+
169
+ def _scheme_attrs(scheme):
170
+ """Resolve install directories by applying the install schemes."""
171
+ return {f'install_{key}': scheme[key] for key in SCHEME_KEYS}
172
+
173
+
174
+ def _pypy_hack(name):
175
+ PY37 = sys.version_info < (3, 8)
176
+ old_pypy = hasattr(sys, 'pypy_version_info') and PY37
177
+ prefix = not name.endswith(('_user', '_home'))
178
+ pypy_name = 'pypy' + '_nt' * (os.name == 'nt')
179
+ return pypy_name if old_pypy and prefix else name
180
+
181
+
182
+ class install(Command):
183
+
184
+ description = "install everything from build directory"
185
+
186
+ user_options = [
187
+ # Select installation scheme and set base director(y|ies)
188
+ ('prefix=', None, "installation prefix"),
189
+ ('exec-prefix=', None, "(Unix only) prefix for platform-specific files"),
190
+ ('home=', None, "(Unix only) home directory to install under"),
191
+ # Or, just set the base director(y|ies)
192
+ (
193
+ 'install-base=',
194
+ None,
195
+ "base installation directory (instead of --prefix or --home)",
196
+ ),
197
+ (
198
+ 'install-platbase=',
199
+ None,
200
+ "base installation directory for platform-specific files "
201
+ + "(instead of --exec-prefix or --home)",
202
+ ),
203
+ ('root=', None, "install everything relative to this alternate root directory"),
204
+ # Or, explicitly set the installation scheme
205
+ (
206
+ 'install-purelib=',
207
+ None,
208
+ "installation directory for pure Python module distributions",
209
+ ),
210
+ (
211
+ 'install-platlib=',
212
+ None,
213
+ "installation directory for non-pure module distributions",
214
+ ),
215
+ (
216
+ 'install-lib=',
217
+ None,
218
+ "installation directory for all module distributions "
219
+ + "(overrides --install-purelib and --install-platlib)",
220
+ ),
221
+ ('install-headers=', None, "installation directory for C/C++ headers"),
222
+ ('install-scripts=', None, "installation directory for Python scripts"),
223
+ ('install-data=', None, "installation directory for data files"),
224
+ # Byte-compilation options -- see install_lib.py for details, as
225
+ # these are duplicated from there (but only install_lib does
226
+ # anything with them).
227
+ ('compile', 'c', "compile .py to .pyc [default]"),
228
+ ('no-compile', None, "don't compile .py files"),
229
+ (
230
+ 'optimize=',
231
+ 'O',
232
+ "also compile with optimization: -O1 for \"python -O\", "
233
+ "-O2 for \"python -OO\", and -O0 to disable [default: -O0]",
234
+ ),
235
+ # Miscellaneous control options
236
+ ('force', 'f', "force installation (overwrite any existing files)"),
237
+ ('skip-build', None, "skip rebuilding everything (for testing/debugging)"),
238
+ # Where to install documentation (eventually!)
239
+ # ('doc-format=', None, "format of documentation to generate"),
240
+ # ('install-man=', None, "directory for Unix man pages"),
241
+ # ('install-html=', None, "directory for HTML documentation"),
242
+ # ('install-info=', None, "directory for GNU info files"),
243
+ ('record=', None, "filename in which to record list of installed files"),
244
+ ]
245
+
246
+ boolean_options = ['compile', 'force', 'skip-build']
247
+
248
+ if HAS_USER_SITE:
249
+ user_options.append(
250
+ ('user', None, "install in user site-package '%s'" % USER_SITE)
251
+ )
252
+ boolean_options.append('user')
253
+
254
+ negative_opt = {'no-compile': 'compile'}
255
+
256
+ def initialize_options(self):
257
+ """Initializes options."""
258
+ # High-level options: these select both an installation base
259
+ # and scheme.
260
+ self.prefix = None
261
+ self.exec_prefix = None
262
+ self.home = None
263
+ self.user = 0
264
+
265
+ # These select only the installation base; it's up to the user to
266
+ # specify the installation scheme (currently, that means supplying
267
+ # the --install-{platlib,purelib,scripts,data} options).
268
+ self.install_base = None
269
+ self.install_platbase = None
270
+ self.root = None
271
+
272
+ # These options are the actual installation directories; if not
273
+ # supplied by the user, they are filled in using the installation
274
+ # scheme implied by prefix/exec-prefix/home and the contents of
275
+ # that installation scheme.
276
+ self.install_purelib = None # for pure module distributions
277
+ self.install_platlib = None # non-pure (dists w/ extensions)
278
+ self.install_headers = None # for C/C++ headers
279
+ self.install_lib = None # set to either purelib or platlib
280
+ self.install_scripts = None
281
+ self.install_data = None
282
+ self.install_userbase = USER_BASE
283
+ self.install_usersite = USER_SITE
284
+
285
+ self.compile = None
286
+ self.optimize = None
287
+
288
+ # Deprecated
289
+ # These two are for putting non-packagized distributions into their
290
+ # own directory and creating a .pth file if it makes sense.
291
+ # 'extra_path' comes from the setup file; 'install_path_file' can
292
+ # be turned off if it makes no sense to install a .pth file. (But
293
+ # better to install it uselessly than to guess wrong and not
294
+ # install it when it's necessary and would be used!) Currently,
295
+ # 'install_path_file' is always true unless some outsider meddles
296
+ # with it.
297
+ self.extra_path = None
298
+ self.install_path_file = 1
299
+
300
+ # 'force' forces installation, even if target files are not
301
+ # out-of-date. 'skip_build' skips running the "build" command,
302
+ # handy if you know it's not necessary. 'warn_dir' (which is *not*
303
+ # a user option, it's just there so the bdist_* commands can turn
304
+ # it off) determines whether we warn about installing to a
305
+ # directory not in sys.path.
306
+ self.force = 0
307
+ self.skip_build = 0
308
+ self.warn_dir = 1
309
+
310
+ # These are only here as a conduit from the 'build' command to the
311
+ # 'install_*' commands that do the real work. ('build_base' isn't
312
+ # actually used anywhere, but it might be useful in future.) They
313
+ # are not user options, because if the user told the install
314
+ # command where the build directory is, that wouldn't affect the
315
+ # build command.
316
+ self.build_base = None
317
+ self.build_lib = None
318
+
319
+ # Not defined yet because we don't know anything about
320
+ # documentation yet.
321
+ # self.install_man = None
322
+ # self.install_html = None
323
+ # self.install_info = None
324
+
325
+ self.record = None
326
+
327
+ # -- Option finalizing methods -------------------------------------
328
+ # (This is rather more involved than for most commands,
329
+ # because this is where the policy for installing third-
330
+ # party Python modules on various platforms given a wide
331
+ # array of user input is decided. Yes, it's quite complex!)
332
+
333
+ def finalize_options(self): # noqa: C901
334
+ """Finalizes options."""
335
+ # This method (and its helpers, like 'finalize_unix()',
336
+ # 'finalize_other()', and 'select_scheme()') is where the default
337
+ # installation directories for modules, extension modules, and
338
+ # anything else we care to install from a Python module
339
+ # distribution. Thus, this code makes a pretty important policy
340
+ # statement about how third-party stuff is added to a Python
341
+ # installation! Note that the actual work of installation is done
342
+ # by the relatively simple 'install_*' commands; they just take
343
+ # their orders from the installation directory options determined
344
+ # here.
345
+
346
+ # Check for errors/inconsistencies in the options; first, stuff
347
+ # that's wrong on any platform.
348
+
349
+ if (self.prefix or self.exec_prefix or self.home) and (
350
+ self.install_base or self.install_platbase
351
+ ):
352
+ raise DistutilsOptionError(
353
+ "must supply either prefix/exec-prefix/home or "
354
+ + "install-base/install-platbase -- not both"
355
+ )
356
+
357
+ if self.home and (self.prefix or self.exec_prefix):
358
+ raise DistutilsOptionError(
359
+ "must supply either home or prefix/exec-prefix -- not both"
360
+ )
361
+
362
+ if self.user and (
363
+ self.prefix
364
+ or self.exec_prefix
365
+ or self.home
366
+ or self.install_base
367
+ or self.install_platbase
368
+ ):
369
+ raise DistutilsOptionError(
370
+ "can't combine user with prefix, "
371
+ "exec_prefix/home, or install_(plat)base"
372
+ )
373
+
374
+ # Next, stuff that's wrong (or dubious) only on certain platforms.
375
+ if os.name != "posix":
376
+ if self.exec_prefix:
377
+ self.warn("exec-prefix option ignored on this platform")
378
+ self.exec_prefix = None
379
+
380
+ # Now the interesting logic -- so interesting that we farm it out
381
+ # to other methods. The goal of these methods is to set the final
382
+ # values for the install_{lib,scripts,data,...} options, using as
383
+ # input a heady brew of prefix, exec_prefix, home, install_base,
384
+ # install_platbase, user-supplied versions of
385
+ # install_{purelib,platlib,lib,scripts,data,...}, and the
386
+ # install schemes. Phew!
387
+
388
+ self.dump_dirs("pre-finalize_{unix,other}")
389
+
390
+ if os.name == 'posix':
391
+ self.finalize_unix()
392
+ else:
393
+ self.finalize_other()
394
+
395
+ self.dump_dirs("post-finalize_{unix,other}()")
396
+
397
+ # Expand configuration variables, tilde, etc. in self.install_base
398
+ # and self.install_platbase -- that way, we can use $base or
399
+ # $platbase in the other installation directories and not worry
400
+ # about needing recursive variable expansion (shudder).
401
+
402
+ py_version = sys.version.split()[0]
403
+ (prefix, exec_prefix) = get_config_vars('prefix', 'exec_prefix')
404
+ try:
405
+ abiflags = sys.abiflags
406
+ except AttributeError:
407
+ # sys.abiflags may not be defined on all platforms.
408
+ abiflags = ''
409
+ local_vars = {
410
+ 'dist_name': self.distribution.get_name(),
411
+ 'dist_version': self.distribution.get_version(),
412
+ 'dist_fullname': self.distribution.get_fullname(),
413
+ 'py_version': py_version,
414
+ 'py_version_short': '%d.%d' % sys.version_info[:2],
415
+ 'py_version_nodot': '%d%d' % sys.version_info[:2],
416
+ 'sys_prefix': prefix,
417
+ 'prefix': prefix,
418
+ 'sys_exec_prefix': exec_prefix,
419
+ 'exec_prefix': exec_prefix,
420
+ 'abiflags': abiflags,
421
+ 'platlibdir': getattr(sys, 'platlibdir', 'lib'),
422
+ 'implementation_lower': _get_implementation().lower(),
423
+ 'implementation': _get_implementation(),
424
+ }
425
+
426
+ # vars for compatibility on older Pythons
427
+ compat_vars = dict(
428
+ # Python 3.9 and earlier
429
+ py_version_nodot_plat=getattr(sys, 'winver', '').replace('.', ''),
430
+ )
431
+
432
+ if HAS_USER_SITE:
433
+ local_vars['userbase'] = self.install_userbase
434
+ local_vars['usersite'] = self.install_usersite
435
+
436
+ self.config_vars = _collections.DictStack(
437
+ [fw.vars(), compat_vars, sysconfig.get_config_vars(), local_vars]
438
+ )
439
+
440
+ self.expand_basedirs()
441
+
442
+ self.dump_dirs("post-expand_basedirs()")
443
+
444
+ # Now define config vars for the base directories so we can expand
445
+ # everything else.
446
+ local_vars['base'] = self.install_base
447
+ local_vars['platbase'] = self.install_platbase
448
+
449
+ if DEBUG:
450
+ from pprint import pprint
451
+
452
+ print("config vars:")
453
+ pprint(dict(self.config_vars))
454
+
455
+ # Expand "~" and configuration variables in the installation
456
+ # directories.
457
+ self.expand_dirs()
458
+
459
+ self.dump_dirs("post-expand_dirs()")
460
+
461
+ # Create directories in the home dir:
462
+ if self.user:
463
+ self.create_home_path()
464
+
465
+ # Pick the actual directory to install all modules to: either
466
+ # install_purelib or install_platlib, depending on whether this
467
+ # module distribution is pure or not. Of course, if the user
468
+ # already specified install_lib, use their selection.
469
+ if self.install_lib is None:
470
+ if self.distribution.has_ext_modules(): # has extensions: non-pure
471
+ self.install_lib = self.install_platlib
472
+ else:
473
+ self.install_lib = self.install_purelib
474
+
475
+ # Convert directories from Unix /-separated syntax to the local
476
+ # convention.
477
+ self.convert_paths(
478
+ 'lib',
479
+ 'purelib',
480
+ 'platlib',
481
+ 'scripts',
482
+ 'data',
483
+ 'headers',
484
+ 'userbase',
485
+ 'usersite',
486
+ )
487
+
488
+ # Deprecated
489
+ # Well, we're not actually fully completely finalized yet: we still
490
+ # have to deal with 'extra_path', which is the hack for allowing
491
+ # non-packagized module distributions (hello, Numerical Python!) to
492
+ # get their own directories.
493
+ self.handle_extra_path()
494
+ self.install_libbase = self.install_lib # needed for .pth file
495
+ self.install_lib = os.path.join(self.install_lib, self.extra_dirs)
496
+
497
+ # If a new root directory was supplied, make all the installation
498
+ # dirs relative to it.
499
+ if self.root is not None:
500
+ self.change_roots(
501
+ 'libbase', 'lib', 'purelib', 'platlib', 'scripts', 'data', 'headers'
502
+ )
503
+
504
+ self.dump_dirs("after prepending root")
505
+
506
+ # Find out the build directories, ie. where to install from.
507
+ self.set_undefined_options(
508
+ 'build', ('build_base', 'build_base'), ('build_lib', 'build_lib')
509
+ )
510
+
511
+ # Punt on doc directories for now -- after all, we're punting on
512
+ # documentation completely!
513
+
514
+ def dump_dirs(self, msg):
515
+ """Dumps the list of user options."""
516
+ if not DEBUG:
517
+ return
518
+ from distutils.fancy_getopt import longopt_xlate
519
+
520
+ log.debug(msg + ":")
521
+ for opt in self.user_options:
522
+ opt_name = opt[0]
523
+ if opt_name[-1] == "=":
524
+ opt_name = opt_name[0:-1]
525
+ if opt_name in self.negative_opt:
526
+ opt_name = self.negative_opt[opt_name]
527
+ opt_name = opt_name.translate(longopt_xlate)
528
+ val = not getattr(self, opt_name)
529
+ else:
530
+ opt_name = opt_name.translate(longopt_xlate)
531
+ val = getattr(self, opt_name)
532
+ log.debug(" %s: %s", opt_name, val)
533
+
534
+ def finalize_unix(self):
535
+ """Finalizes options for posix platforms."""
536
+ if self.install_base is not None or self.install_platbase is not None:
537
+ incomplete_scheme = (
538
+ (
539
+ self.install_lib is None
540
+ and self.install_purelib is None
541
+ and self.install_platlib is None
542
+ )
543
+ or self.install_headers is None
544
+ or self.install_scripts is None
545
+ or self.install_data is None
546
+ )
547
+ if incomplete_scheme:
548
+ raise DistutilsOptionError(
549
+ "install-base or install-platbase supplied, but "
550
+ "installation scheme is incomplete"
551
+ )
552
+ return
553
+
554
+ if self.user:
555
+ if self.install_userbase is None:
556
+ raise DistutilsPlatformError("User base directory is not specified")
557
+ self.install_base = self.install_platbase = self.install_userbase
558
+ self.select_scheme("posix_user")
559
+ elif self.home is not None:
560
+ self.install_base = self.install_platbase = self.home
561
+ self.select_scheme("posix_home")
562
+ else:
563
+ if self.prefix is None:
564
+ if self.exec_prefix is not None:
565
+ raise DistutilsOptionError(
566
+ "must not supply exec-prefix without prefix"
567
+ )
568
+
569
+ # Allow Fedora to add components to the prefix
570
+ _prefix_addition = getattr(sysconfig, '_prefix_addition', "")
571
+
572
+ self.prefix = os.path.normpath(sys.prefix) + _prefix_addition
573
+ self.exec_prefix = os.path.normpath(sys.exec_prefix) + _prefix_addition
574
+
575
+ else:
576
+ if self.exec_prefix is None:
577
+ self.exec_prefix = self.prefix
578
+
579
+ self.install_base = self.prefix
580
+ self.install_platbase = self.exec_prefix
581
+ self.select_scheme("posix_prefix")
582
+
583
+ def finalize_other(self):
584
+ """Finalizes options for non-posix platforms"""
585
+ if self.user:
586
+ if self.install_userbase is None:
587
+ raise DistutilsPlatformError("User base directory is not specified")
588
+ self.install_base = self.install_platbase = self.install_userbase
589
+ self.select_scheme(os.name + "_user")
590
+ elif self.home is not None:
591
+ self.install_base = self.install_platbase = self.home
592
+ self.select_scheme("posix_home")
593
+ else:
594
+ if self.prefix is None:
595
+ self.prefix = os.path.normpath(sys.prefix)
596
+
597
+ self.install_base = self.install_platbase = self.prefix
598
+ try:
599
+ self.select_scheme(os.name)
600
+ except KeyError:
601
+ raise DistutilsPlatformError(
602
+ "I don't know how to install stuff on '%s'" % os.name
603
+ )
604
+
605
+ def select_scheme(self, name):
606
+ _select_scheme(self, name)
607
+
608
+ def _expand_attrs(self, attrs):
609
+ for attr in attrs:
610
+ val = getattr(self, attr)
611
+ if val is not None:
612
+ if os.name == 'posix' or os.name == 'nt':
613
+ val = os.path.expanduser(val)
614
+ val = subst_vars(val, self.config_vars)
615
+ setattr(self, attr, val)
616
+
617
+ def expand_basedirs(self):
618
+ """Calls `os.path.expanduser` on install_base, install_platbase and
619
+ root."""
620
+ self._expand_attrs(['install_base', 'install_platbase', 'root'])
621
+
622
+ def expand_dirs(self):
623
+ """Calls `os.path.expanduser` on install dirs."""
624
+ self._expand_attrs(
625
+ [
626
+ 'install_purelib',
627
+ 'install_platlib',
628
+ 'install_lib',
629
+ 'install_headers',
630
+ 'install_scripts',
631
+ 'install_data',
632
+ ]
633
+ )
634
+
635
+ def convert_paths(self, *names):
636
+ """Call `convert_path` over `names`."""
637
+ for name in names:
638
+ attr = "install_" + name
639
+ setattr(self, attr, convert_path(getattr(self, attr)))
640
+
641
+ def handle_extra_path(self):
642
+ """Set `path_file` and `extra_dirs` using `extra_path`."""
643
+ if self.extra_path is None:
644
+ self.extra_path = self.distribution.extra_path
645
+
646
+ if self.extra_path is not None:
647
+ log.warn(
648
+ "Distribution option extra_path is deprecated. "
649
+ "See issue27919 for details."
650
+ )
651
+ if isinstance(self.extra_path, str):
652
+ self.extra_path = self.extra_path.split(',')
653
+
654
+ if len(self.extra_path) == 1:
655
+ path_file = extra_dirs = self.extra_path[0]
656
+ elif len(self.extra_path) == 2:
657
+ path_file, extra_dirs = self.extra_path
658
+ else:
659
+ raise DistutilsOptionError(
660
+ "'extra_path' option must be a list, tuple, or "
661
+ "comma-separated string with 1 or 2 elements"
662
+ )
663
+
664
+ # convert to local form in case Unix notation used (as it
665
+ # should be in setup scripts)
666
+ extra_dirs = convert_path(extra_dirs)
667
+ else:
668
+ path_file = None
669
+ extra_dirs = ''
670
+
671
+ # XXX should we warn if path_file and not extra_dirs? (in which
672
+ # case the path file would be harmless but pointless)
673
+ self.path_file = path_file
674
+ self.extra_dirs = extra_dirs
675
+
676
+ def change_roots(self, *names):
677
+ """Change the install directories pointed by name using root."""
678
+ for name in names:
679
+ attr = "install_" + name
680
+ setattr(self, attr, change_root(self.root, getattr(self, attr)))
681
+
682
+ def create_home_path(self):
683
+ """Create directories under ~."""
684
+ if not self.user:
685
+ return
686
+ home = convert_path(os.path.expanduser("~"))
687
+ for name, path in self.config_vars.items():
688
+ if str(path).startswith(home) and not os.path.isdir(path):
689
+ self.debug_print("os.makedirs('%s', 0o700)" % path)
690
+ os.makedirs(path, 0o700)
691
+
692
+ # -- Command execution methods -------------------------------------
693
+
694
+ def run(self):
695
+ """Runs the command."""
696
+ # Obviously have to build before we can install
697
+ if not self.skip_build:
698
+ self.run_command('build')
699
+ # If we built for any other platform, we can't install.
700
+ build_plat = self.distribution.get_command_obj('build').plat_name
701
+ # check warn_dir - it is a clue that the 'install' is happening
702
+ # internally, and not to sys.path, so we don't check the platform
703
+ # matches what we are running.
704
+ if self.warn_dir and build_plat != get_platform():
705
+ raise DistutilsPlatformError("Can't install when " "cross-compiling")
706
+
707
+ # Run all sub-commands (at least those that need to be run)
708
+ for cmd_name in self.get_sub_commands():
709
+ self.run_command(cmd_name)
710
+
711
+ if self.path_file:
712
+ self.create_path_file()
713
+
714
+ # write list of installed files, if requested.
715
+ if self.record:
716
+ outputs = self.get_outputs()
717
+ if self.root: # strip any package prefix
718
+ root_len = len(self.root)
719
+ for counter in range(len(outputs)):
720
+ outputs[counter] = outputs[counter][root_len:]
721
+ self.execute(
722
+ write_file,
723
+ (self.record, outputs),
724
+ "writing list of installed files to '%s'" % self.record,
725
+ )
726
+
727
+ sys_path = map(os.path.normpath, sys.path)
728
+ sys_path = map(os.path.normcase, sys_path)
729
+ install_lib = os.path.normcase(os.path.normpath(self.install_lib))
730
+ if (
731
+ self.warn_dir
732
+ and not (self.path_file and self.install_path_file)
733
+ and install_lib not in sys_path
734
+ ):
735
+ log.debug(
736
+ (
737
+ "modules installed to '%s', which is not in "
738
+ "Python's module search path (sys.path) -- "
739
+ "you'll have to change the search path yourself"
740
+ ),
741
+ self.install_lib,
742
+ )
743
+
744
+ def create_path_file(self):
745
+ """Creates the .pth file"""
746
+ filename = os.path.join(self.install_libbase, self.path_file + ".pth")
747
+ if self.install_path_file:
748
+ self.execute(
749
+ write_file, (filename, [self.extra_dirs]), "creating %s" % filename
750
+ )
751
+ else:
752
+ self.warn("path file '%s' not created" % filename)
753
+
754
+ # -- Reporting methods ---------------------------------------------
755
+
756
+ def get_outputs(self):
757
+ """Assembles the outputs of all the sub-commands."""
758
+ outputs = []
759
+ for cmd_name in self.get_sub_commands():
760
+ cmd = self.get_finalized_command(cmd_name)
761
+ # Add the contents of cmd.get_outputs(), ensuring
762
+ # that outputs doesn't contain duplicate entries
763
+ for filename in cmd.get_outputs():
764
+ if filename not in outputs:
765
+ outputs.append(filename)
766
+
767
+ if self.path_file and self.install_path_file:
768
+ outputs.append(os.path.join(self.install_libbase, self.path_file + ".pth"))
769
+
770
+ return outputs
771
+
772
+ def get_inputs(self):
773
+ """Returns the inputs of all the sub-commands"""
774
+ # XXX gee, this looks familiar ;-(
775
+ inputs = []
776
+ for cmd_name in self.get_sub_commands():
777
+ cmd = self.get_finalized_command(cmd_name)
778
+ inputs.extend(cmd.get_inputs())
779
+
780
+ return inputs
781
+
782
+ # -- Predicates for sub-command list -------------------------------
783
+
784
+ def has_lib(self):
785
+ """Returns true if the current distribution has any Python
786
+ modules to install."""
787
+ return (
788
+ self.distribution.has_pure_modules() or self.distribution.has_ext_modules()
789
+ )
790
+
791
+ def has_headers(self):
792
+ """Returns true if the current distribution has any headers to
793
+ install."""
794
+ return self.distribution.has_headers()
795
+
796
+ def has_scripts(self):
797
+ """Returns true if the current distribution has any scripts to.
798
+ install."""
799
+ return self.distribution.has_scripts()
800
+
801
+ def has_data(self):
802
+ """Returns true if the current distribution has any data to.
803
+ install."""
804
+ return self.distribution.has_data_files()
805
+
806
+ # 'sub_commands': a list of commands this command might have to run to
807
+ # get its work done. See cmd.py for more info.
808
+ sub_commands = [
809
+ ('install_lib', has_lib),
810
+ ('install_headers', has_headers),
811
+ ('install_scripts', has_scripts),
812
+ ('install_data', has_data),
813
+ ('install_egg_info', lambda self: True),
814
+ ]
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/install_data.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils.command.install_data
2
+
3
+ Implements the Distutils 'install_data' command, for installing
4
+ platform-independent data files."""
5
+
6
+ # contributed by Bastian Kleineidam
7
+
8
+ import os
9
+ from distutils.core import Command
10
+ from distutils.util import change_root, convert_path
11
+
12
+
13
+ class install_data(Command):
14
+
15
+ description = "install data files"
16
+
17
+ user_options = [
18
+ (
19
+ 'install-dir=',
20
+ 'd',
21
+ "base directory for installing data files "
22
+ "(default: installation base dir)",
23
+ ),
24
+ ('root=', None, "install everything relative to this alternate root directory"),
25
+ ('force', 'f', "force installation (overwrite existing files)"),
26
+ ]
27
+
28
+ boolean_options = ['force']
29
+
30
+ def initialize_options(self):
31
+ self.install_dir = None
32
+ self.outfiles = []
33
+ self.root = None
34
+ self.force = 0
35
+ self.data_files = self.distribution.data_files
36
+ self.warn_dir = 1
37
+
38
+ def finalize_options(self):
39
+ self.set_undefined_options(
40
+ 'install',
41
+ ('install_data', 'install_dir'),
42
+ ('root', 'root'),
43
+ ('force', 'force'),
44
+ )
45
+
46
+ def run(self):
47
+ self.mkpath(self.install_dir)
48
+ for f in self.data_files:
49
+ if isinstance(f, str):
50
+ # it's a simple file, so copy it
51
+ f = convert_path(f)
52
+ if self.warn_dir:
53
+ self.warn(
54
+ "setup script did not provide a directory for "
55
+ "'%s' -- installing right in '%s'" % (f, self.install_dir)
56
+ )
57
+ (out, _) = self.copy_file(f, self.install_dir)
58
+ self.outfiles.append(out)
59
+ else:
60
+ # it's a tuple with path to install to and a list of files
61
+ dir = convert_path(f[0])
62
+ if not os.path.isabs(dir):
63
+ dir = os.path.join(self.install_dir, dir)
64
+ elif self.root:
65
+ dir = change_root(self.root, dir)
66
+ self.mkpath(dir)
67
+
68
+ if f[1] == []:
69
+ # If there are no files listed, the user must be
70
+ # trying to create an empty directory, so add the
71
+ # directory to the list of output files.
72
+ self.outfiles.append(dir)
73
+ else:
74
+ # Copy files, adding them to the list of output files.
75
+ for data in f[1]:
76
+ data = convert_path(data)
77
+ (out, _) = self.copy_file(data, dir)
78
+ self.outfiles.append(out)
79
+
80
+ def get_inputs(self):
81
+ return self.data_files or []
82
+
83
+ def get_outputs(self):
84
+ return self.outfiles
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/install_egg_info.py ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ distutils.command.install_egg_info
3
+
4
+ Implements the Distutils 'install_egg_info' command, for installing
5
+ a package's PKG-INFO metadata.
6
+ """
7
+
8
+ import os
9
+ import sys
10
+ import re
11
+
12
+ from distutils.cmd import Command
13
+ from distutils import log, dir_util
14
+
15
+
16
+ class install_egg_info(Command):
17
+ """Install an .egg-info file for the package"""
18
+
19
+ description = "Install package's PKG-INFO metadata as an .egg-info file"
20
+ user_options = [
21
+ ('install-dir=', 'd', "directory to install to"),
22
+ ]
23
+
24
+ def initialize_options(self):
25
+ self.install_dir = None
26
+
27
+ @property
28
+ def basename(self):
29
+ """
30
+ Allow basename to be overridden by child class.
31
+ Ref pypa/distutils#2.
32
+ """
33
+ return "%s-%s-py%d.%d.egg-info" % (
34
+ to_filename(safe_name(self.distribution.get_name())),
35
+ to_filename(safe_version(self.distribution.get_version())),
36
+ *sys.version_info[:2],
37
+ )
38
+
39
+ def finalize_options(self):
40
+ self.set_undefined_options('install_lib', ('install_dir', 'install_dir'))
41
+ self.target = os.path.join(self.install_dir, self.basename)
42
+ self.outputs = [self.target]
43
+
44
+ def run(self):
45
+ target = self.target
46
+ if os.path.isdir(target) and not os.path.islink(target):
47
+ dir_util.remove_tree(target, dry_run=self.dry_run)
48
+ elif os.path.exists(target):
49
+ self.execute(os.unlink, (self.target,), "Removing " + target)
50
+ elif not os.path.isdir(self.install_dir):
51
+ self.execute(
52
+ os.makedirs, (self.install_dir,), "Creating " + self.install_dir
53
+ )
54
+ log.info("Writing %s", target)
55
+ if not self.dry_run:
56
+ with open(target, 'w', encoding='UTF-8') as f:
57
+ self.distribution.metadata.write_pkg_file(f)
58
+
59
+ def get_outputs(self):
60
+ return self.outputs
61
+
62
+
63
+ # The following routines are taken from setuptools' pkg_resources module and
64
+ # can be replaced by importing them from pkg_resources once it is included
65
+ # in the stdlib.
66
+
67
+
68
+ def safe_name(name):
69
+ """Convert an arbitrary string to a standard distribution name
70
+
71
+ Any runs of non-alphanumeric/. characters are replaced with a single '-'.
72
+ """
73
+ return re.sub('[^A-Za-z0-9.]+', '-', name)
74
+
75
+
76
+ def safe_version(version):
77
+ """Convert an arbitrary string to a standard version string
78
+
79
+ Spaces become dots, and all other non-alphanumeric characters become
80
+ dashes, with runs of multiple dashes condensed to a single dash.
81
+ """
82
+ version = version.replace(' ', '.')
83
+ return re.sub('[^A-Za-z0-9.]+', '-', version)
84
+
85
+
86
+ def to_filename(name):
87
+ """Convert a project or version name to its filename-escaped form
88
+
89
+ Any '-' characters are currently replaced with '_'.
90
+ """
91
+ return name.replace('-', '_')
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/install_headers.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils.command.install_headers
2
+
3
+ Implements the Distutils 'install_headers' command, to install C/C++ header
4
+ files to the Python include directory."""
5
+
6
+ from distutils.core import Command
7
+
8
+
9
+ # XXX force is never used
10
+ class install_headers(Command):
11
+
12
+ description = "install C/C++ header files"
13
+
14
+ user_options = [
15
+ ('install-dir=', 'd', "directory to install header files to"),
16
+ ('force', 'f', "force installation (overwrite existing files)"),
17
+ ]
18
+
19
+ boolean_options = ['force']
20
+
21
+ def initialize_options(self):
22
+ self.install_dir = None
23
+ self.force = 0
24
+ self.outfiles = []
25
+
26
+ def finalize_options(self):
27
+ self.set_undefined_options(
28
+ 'install', ('install_headers', 'install_dir'), ('force', 'force')
29
+ )
30
+
31
+ def run(self):
32
+ headers = self.distribution.headers
33
+ if not headers:
34
+ return
35
+
36
+ self.mkpath(self.install_dir)
37
+ for header in headers:
38
+ (out, _) = self.copy_file(header, self.install_dir)
39
+ self.outfiles.append(out)
40
+
41
+ def get_inputs(self):
42
+ return self.distribution.headers or []
43
+
44
+ def get_outputs(self):
45
+ return self.outfiles
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/install_lib.py ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils.command.install_lib
2
+
3
+ Implements the Distutils 'install_lib' command
4
+ (install all Python modules)."""
5
+
6
+ import os
7
+ import importlib.util
8
+ import sys
9
+
10
+ from distutils.core import Command
11
+ from distutils.errors import DistutilsOptionError
12
+
13
+
14
+ # Extension for Python source files.
15
+ PYTHON_SOURCE_EXTENSION = ".py"
16
+
17
+
18
+ class install_lib(Command):
19
+
20
+ description = "install all Python modules (extensions and pure Python)"
21
+
22
+ # The byte-compilation options are a tad confusing. Here are the
23
+ # possible scenarios:
24
+ # 1) no compilation at all (--no-compile --no-optimize)
25
+ # 2) compile .pyc only (--compile --no-optimize; default)
26
+ # 3) compile .pyc and "opt-1" .pyc (--compile --optimize)
27
+ # 4) compile "opt-1" .pyc only (--no-compile --optimize)
28
+ # 5) compile .pyc and "opt-2" .pyc (--compile --optimize-more)
29
+ # 6) compile "opt-2" .pyc only (--no-compile --optimize-more)
30
+ #
31
+ # The UI for this is two options, 'compile' and 'optimize'.
32
+ # 'compile' is strictly boolean, and only decides whether to
33
+ # generate .pyc files. 'optimize' is three-way (0, 1, or 2), and
34
+ # decides both whether to generate .pyc files and what level of
35
+ # optimization to use.
36
+
37
+ user_options = [
38
+ ('install-dir=', 'd', "directory to install to"),
39
+ ('build-dir=', 'b', "build directory (where to install from)"),
40
+ ('force', 'f', "force installation (overwrite existing files)"),
41
+ ('compile', 'c', "compile .py to .pyc [default]"),
42
+ ('no-compile', None, "don't compile .py files"),
43
+ (
44
+ 'optimize=',
45
+ 'O',
46
+ "also compile with optimization: -O1 for \"python -O\", "
47
+ "-O2 for \"python -OO\", and -O0 to disable [default: -O0]",
48
+ ),
49
+ ('skip-build', None, "skip the build steps"),
50
+ ]
51
+
52
+ boolean_options = ['force', 'compile', 'skip-build']
53
+ negative_opt = {'no-compile': 'compile'}
54
+
55
+ def initialize_options(self):
56
+ # let the 'install' command dictate our installation directory
57
+ self.install_dir = None
58
+ self.build_dir = None
59
+ self.force = 0
60
+ self.compile = None
61
+ self.optimize = None
62
+ self.skip_build = None
63
+
64
+ def finalize_options(self):
65
+ # Get all the information we need to install pure Python modules
66
+ # from the umbrella 'install' command -- build (source) directory,
67
+ # install (target) directory, and whether to compile .py files.
68
+ self.set_undefined_options(
69
+ 'install',
70
+ ('build_lib', 'build_dir'),
71
+ ('install_lib', 'install_dir'),
72
+ ('force', 'force'),
73
+ ('compile', 'compile'),
74
+ ('optimize', 'optimize'),
75
+ ('skip_build', 'skip_build'),
76
+ )
77
+
78
+ if self.compile is None:
79
+ self.compile = True
80
+ if self.optimize is None:
81
+ self.optimize = False
82
+
83
+ if not isinstance(self.optimize, int):
84
+ try:
85
+ self.optimize = int(self.optimize)
86
+ if self.optimize not in (0, 1, 2):
87
+ raise AssertionError
88
+ except (ValueError, AssertionError):
89
+ raise DistutilsOptionError("optimize must be 0, 1, or 2")
90
+
91
+ def run(self):
92
+ # Make sure we have built everything we need first
93
+ self.build()
94
+
95
+ # Install everything: simply dump the entire contents of the build
96
+ # directory to the installation directory (that's the beauty of
97
+ # having a build directory!)
98
+ outfiles = self.install()
99
+
100
+ # (Optionally) compile .py to .pyc
101
+ if outfiles is not None and self.distribution.has_pure_modules():
102
+ self.byte_compile(outfiles)
103
+
104
+ # -- Top-level worker functions ------------------------------------
105
+ # (called from 'run()')
106
+
107
+ def build(self):
108
+ if not self.skip_build:
109
+ if self.distribution.has_pure_modules():
110
+ self.run_command('build_py')
111
+ if self.distribution.has_ext_modules():
112
+ self.run_command('build_ext')
113
+
114
+ def install(self):
115
+ if os.path.isdir(self.build_dir):
116
+ outfiles = self.copy_tree(self.build_dir, self.install_dir)
117
+ else:
118
+ self.warn(
119
+ "'%s' does not exist -- no Python modules to install" % self.build_dir
120
+ )
121
+ return
122
+ return outfiles
123
+
124
+ def byte_compile(self, files):
125
+ if sys.dont_write_bytecode:
126
+ self.warn('byte-compiling is disabled, skipping.')
127
+ return
128
+
129
+ from distutils.util import byte_compile
130
+
131
+ # Get the "--root" directory supplied to the "install" command,
132
+ # and use it as a prefix to strip off the purported filename
133
+ # encoded in bytecode files. This is far from complete, but it
134
+ # should at least generate usable bytecode in RPM distributions.
135
+ install_root = self.get_finalized_command('install').root
136
+
137
+ if self.compile:
138
+ byte_compile(
139
+ files,
140
+ optimize=0,
141
+ force=self.force,
142
+ prefix=install_root,
143
+ dry_run=self.dry_run,
144
+ )
145
+ if self.optimize > 0:
146
+ byte_compile(
147
+ files,
148
+ optimize=self.optimize,
149
+ force=self.force,
150
+ prefix=install_root,
151
+ verbose=self.verbose,
152
+ dry_run=self.dry_run,
153
+ )
154
+
155
+ # -- Utility methods -----------------------------------------------
156
+
157
+ def _mutate_outputs(self, has_any, build_cmd, cmd_option, output_dir):
158
+ if not has_any:
159
+ return []
160
+
161
+ build_cmd = self.get_finalized_command(build_cmd)
162
+ build_files = build_cmd.get_outputs()
163
+ build_dir = getattr(build_cmd, cmd_option)
164
+
165
+ prefix_len = len(build_dir) + len(os.sep)
166
+ outputs = []
167
+ for file in build_files:
168
+ outputs.append(os.path.join(output_dir, file[prefix_len:]))
169
+
170
+ return outputs
171
+
172
+ def _bytecode_filenames(self, py_filenames):
173
+ bytecode_files = []
174
+ for py_file in py_filenames:
175
+ # Since build_py handles package data installation, the
176
+ # list of outputs can contain more than just .py files.
177
+ # Make sure we only report bytecode for the .py files.
178
+ ext = os.path.splitext(os.path.normcase(py_file))[1]
179
+ if ext != PYTHON_SOURCE_EXTENSION:
180
+ continue
181
+ if self.compile:
182
+ bytecode_files.append(
183
+ importlib.util.cache_from_source(py_file, optimization='')
184
+ )
185
+ if self.optimize > 0:
186
+ bytecode_files.append(
187
+ importlib.util.cache_from_source(
188
+ py_file, optimization=self.optimize
189
+ )
190
+ )
191
+
192
+ return bytecode_files
193
+
194
+ # -- External interface --------------------------------------------
195
+ # (called by outsiders)
196
+
197
+ def get_outputs(self):
198
+ """Return the list of files that would be installed if this command
199
+ were actually run. Not affected by the "dry-run" flag or whether
200
+ modules have actually been built yet.
201
+ """
202
+ pure_outputs = self._mutate_outputs(
203
+ self.distribution.has_pure_modules(),
204
+ 'build_py',
205
+ 'build_lib',
206
+ self.install_dir,
207
+ )
208
+ if self.compile:
209
+ bytecode_outputs = self._bytecode_filenames(pure_outputs)
210
+ else:
211
+ bytecode_outputs = []
212
+
213
+ ext_outputs = self._mutate_outputs(
214
+ self.distribution.has_ext_modules(),
215
+ 'build_ext',
216
+ 'build_lib',
217
+ self.install_dir,
218
+ )
219
+
220
+ return pure_outputs + bytecode_outputs + ext_outputs
221
+
222
+ def get_inputs(self):
223
+ """Get the list of files that are input to this command, ie. the
224
+ files that get installed as they are named in the build tree.
225
+ The files in this list correspond one-to-one to the output
226
+ filenames returned by 'get_outputs()'.
227
+ """
228
+ inputs = []
229
+
230
+ if self.distribution.has_pure_modules():
231
+ build_py = self.get_finalized_command('build_py')
232
+ inputs.extend(build_py.get_outputs())
233
+
234
+ if self.distribution.has_ext_modules():
235
+ build_ext = self.get_finalized_command('build_ext')
236
+ inputs.extend(build_ext.get_outputs())
237
+
238
+ return inputs
.venv/lib/python3.11/site-packages/setuptools/_distutils/command/install_scripts.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils.command.install_scripts
2
+
3
+ Implements the Distutils 'install_scripts' command, for installing
4
+ Python scripts."""
5
+
6
+ # contributed by Bastian Kleineidam
7
+
8
+ import os
9
+ from distutils.core import Command
10
+ from distutils import log
11
+ from stat import ST_MODE
12
+
13
+
14
+ class install_scripts(Command):
15
+
16
+ description = "install scripts (Python or otherwise)"
17
+
18
+ user_options = [
19
+ ('install-dir=', 'd', "directory to install scripts to"),
20
+ ('build-dir=', 'b', "build directory (where to install from)"),
21
+ ('force', 'f', "force installation (overwrite existing files)"),
22
+ ('skip-build', None, "skip the build steps"),
23
+ ]
24
+
25
+ boolean_options = ['force', 'skip-build']
26
+
27
+ def initialize_options(self):
28
+ self.install_dir = None
29
+ self.force = 0
30
+ self.build_dir = None
31
+ self.skip_build = None
32
+
33
+ def finalize_options(self):
34
+ self.set_undefined_options('build', ('build_scripts', 'build_dir'))
35
+ self.set_undefined_options(
36
+ 'install',
37
+ ('install_scripts', 'install_dir'),
38
+ ('force', 'force'),
39
+ ('skip_build', 'skip_build'),
40
+ )
41
+
42
+ def run(self):
43
+ if not self.skip_build:
44
+ self.run_command('build_scripts')
45
+ self.outfiles = self.copy_tree(self.build_dir, self.install_dir)
46
+ if os.name == 'posix':
47
+ # Set the executable bits (owner, group, and world) on
48
+ # all the scripts we just installed.
49
+ for file in self.get_outputs():
50
+ if self.dry_run:
51
+ log.info("changing mode of %s", file)
52
+ else:
53
+ mode = ((os.stat(file)[ST_MODE]) | 0o555) & 0o7777
54
+ log.info("changing mode of %s to %o", file, mode)
55
+ os.chmod(file, mode)
56
+
57
+ def get_inputs(self):
58
+ return self.distribution.scripts or []
59
+
60
+ def get_outputs(self):
61
+ return self.outfiles or []