vijayakumaran92 commited on
Commit
b08fe17
·
verified ·
1 Parent(s): c5a22df

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 +1 -0
  2. ACE_plus/Unmodel_training.sh +28 -0
  3. ACE_plus/flashenv/lib/python3.10/site-packages/distutils-precedence.pth +3 -0
  4. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__init__.py +247 -0
  5. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/__init__.cpython-310.pyc +0 -0
  6. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-310.pyc +0 -0
  7. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/_entry_points.cpython-310.pyc +0 -0
  8. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/_imp.cpython-310.pyc +0 -0
  9. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/_importlib.cpython-310.pyc +0 -0
  10. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/_itertools.cpython-310.pyc +0 -0
  11. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/_path.cpython-310.pyc +0 -0
  12. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/_reqs.cpython-310.pyc +0 -0
  13. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/archive_util.cpython-310.pyc +0 -0
  14. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/build_meta.cpython-310.pyc +0 -0
  15. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/dep_util.cpython-310.pyc +0 -0
  16. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/depends.cpython-310.pyc +0 -0
  17. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/discovery.cpython-310.pyc +0 -0
  18. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/dist.cpython-310.pyc +0 -0
  19. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/errors.cpython-310.pyc +0 -0
  20. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/extension.cpython-310.pyc +0 -0
  21. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/glob.cpython-310.pyc +0 -0
  22. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/installer.cpython-310.pyc +0 -0
  23. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/launch.cpython-310.pyc +0 -0
  24. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/logging.cpython-310.pyc +0 -0
  25. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/monkey.cpython-310.pyc +0 -0
  26. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/msvc.cpython-310.pyc +0 -0
  27. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/namespaces.cpython-310.pyc +0 -0
  28. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/package_index.cpython-310.pyc +0 -0
  29. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/py34compat.cpython-310.pyc +0 -0
  30. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/sandbox.cpython-310.pyc +0 -0
  31. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/unicode_utils.cpython-310.pyc +0 -0
  32. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/version.cpython-310.pyc +0 -0
  33. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/wheel.cpython-310.pyc +0 -0
  34. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/windows_support.cpython-310.pyc +0 -0
  35. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_deprecation_warning.py +7 -0
  36. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/__init__.py +24 -0
  37. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/_collections.py +56 -0
  38. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/_macos_compat.py +12 -0
  39. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/_msvccompiler.py +572 -0
  40. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/bcppcompiler.py +408 -0
  41. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/ccompiler.py +1220 -0
  42. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/config.py +139 -0
  43. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/core.py +291 -0
  44. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/cygwinccompiler.py +364 -0
  45. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/debug.py +5 -0
  46. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/dep_util.py +96 -0
  47. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/dist.py +1286 -0
  48. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/errors.py +127 -0
  49. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/extension.py +248 -0
  50. ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/fancy_getopt.py +470 -0
.gitattributes CHANGED
@@ -100,3 +100,4 @@ Training_Data/TigcPerson_4.jpg filter=lfs diff=lfs merge=lfs -text
100
  Training_Data/Inperson_3-V1.png filter=lfs diff=lfs merge=lfs -text
101
  Training_Data/Venusperson_11-Garment.jpg filter=lfs diff=lfs merge=lfs -text
102
  Training_Data/TigcPerson_2.jpg filter=lfs diff=lfs merge=lfs -text
 
 
100
  Training_Data/Inperson_3-V1.png filter=lfs diff=lfs merge=lfs -text
101
  Training_Data/Venusperson_11-Garment.jpg filter=lfs diff=lfs merge=lfs -text
102
  Training_Data/TigcPerson_2.jpg filter=lfs diff=lfs merge=lfs -text
103
+ ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/cli-arm64.exe filter=lfs diff=lfs merge=lfs -text
ACE_plus/Unmodel_training.sh ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ # Script to clean GPU memory and run training
3
+
4
+ # Kill any existing Python processes
5
+ echo "Stopping any running Python processes..."
6
+ pkill -9 python
7
+
8
+ # Clear GPU cache
9
+ echo "Clearing GPU cache..."
10
+ nvidia-smi --gpu-reset
11
+
12
+ # Wait a moment for cleanup
13
+ sleep 5
14
+
15
+ # Check GPU memory status
16
+ echo "Current GPU memory status:"
17
+ nvidia-smi
18
+
19
+ # Set memory optimization environment variables
20
+ export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True
21
+ export PYTORCH_NO_CUDA_MEMORY_CACHING=1
22
+
23
+ # Run training with reduced image size (optional)
24
+ echo "Starting training..."
25
+ python run_train.py --cfg train_config/ace_plus_fft_lora.yaml
26
+
27
+ # Or if you have a specific memory-optimized config:
28
+ # python run_train.py --cfg train_config/ace_plus_fft_lora_low_mem.yaml
ACE_plus/flashenv/lib/python3.10/site-packages/distutils-precedence.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2638ce9e2500e572a5e0de7faed6661eb569d1b696fcba07b0dd223da5f5d224
3
+ size 151
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__init__.py ADDED
@@ -0,0 +1,247 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Extensions to the 'distutils' for large or complex distributions"""
2
+
3
+ import functools
4
+ import os
5
+ import re
6
+ import warnings
7
+
8
+ import _distutils_hack.override # noqa: F401
9
+
10
+ import distutils.core
11
+ from distutils.errors import DistutilsOptionError
12
+ from distutils.util import convert_path as _convert_path
13
+
14
+ from ._deprecation_warning import SetuptoolsDeprecationWarning
15
+
16
+ import setuptools.version
17
+ from setuptools.extension import Extension
18
+ from setuptools.dist import Distribution
19
+ from setuptools.depends import Require
20
+ from setuptools.discovery import PackageFinder, PEP420PackageFinder
21
+ from . import monkey
22
+ from . import logging
23
+
24
+
25
+ __all__ = [
26
+ 'setup',
27
+ 'Distribution',
28
+ 'Command',
29
+ 'Extension',
30
+ 'Require',
31
+ 'SetuptoolsDeprecationWarning',
32
+ 'find_packages',
33
+ 'find_namespace_packages',
34
+ ]
35
+
36
+ __version__ = setuptools.version.__version__
37
+
38
+ bootstrap_install_from = None
39
+
40
+
41
+ find_packages = PackageFinder.find
42
+ find_namespace_packages = PEP420PackageFinder.find
43
+
44
+
45
+ def _install_setup_requires(attrs):
46
+ # Note: do not use `setuptools.Distribution` directly, as
47
+ # our PEP 517 backend patch `distutils.core.Distribution`.
48
+ class MinimalDistribution(distutils.core.Distribution):
49
+ """
50
+ A minimal version of a distribution for supporting the
51
+ fetch_build_eggs interface.
52
+ """
53
+
54
+ def __init__(self, attrs):
55
+ _incl = 'dependency_links', 'setup_requires'
56
+ filtered = {k: attrs[k] for k in set(_incl) & set(attrs)}
57
+ super().__init__(filtered)
58
+ # Prevent accidentally triggering discovery with incomplete set of attrs
59
+ self.set_defaults._disable()
60
+
61
+ def _get_project_config_files(self, filenames=None):
62
+ """Ignore ``pyproject.toml``, they are not related to setup_requires"""
63
+ try:
64
+ cfg, toml = super()._split_standard_project_metadata(filenames)
65
+ return cfg, ()
66
+ except Exception:
67
+ return filenames, ()
68
+
69
+ def finalize_options(self):
70
+ """
71
+ Disable finalize_options to avoid building the working set.
72
+ Ref #2158.
73
+ """
74
+
75
+ dist = MinimalDistribution(attrs)
76
+
77
+ # Honor setup.cfg's options.
78
+ dist.parse_config_files(ignore_option_errors=True)
79
+ if dist.setup_requires:
80
+ dist.fetch_build_eggs(dist.setup_requires)
81
+
82
+
83
+ def setup(**attrs):
84
+ # Make sure we have any requirements needed to interpret 'attrs'.
85
+ logging.configure()
86
+ _install_setup_requires(attrs)
87
+ return distutils.core.setup(**attrs)
88
+
89
+
90
+ setup.__doc__ = distutils.core.setup.__doc__
91
+
92
+
93
+ _Command = monkey.get_unpatched(distutils.core.Command)
94
+
95
+
96
+ class Command(_Command):
97
+ """
98
+ Setuptools internal actions are organized using a *command design pattern*.
99
+ This means that each action (or group of closely related actions) executed during
100
+ the build should be implemented as a ``Command`` subclass.
101
+
102
+ These commands are abstractions and do not necessarily correspond to a command that
103
+ can (or should) be executed via a terminal, in a CLI fashion (although historically
104
+ they would).
105
+
106
+ When creating a new command from scratch, custom defined classes **SHOULD** inherit
107
+ from ``setuptools.Command`` and implement a few mandatory methods.
108
+ Between these mandatory methods, are listed:
109
+
110
+ .. method:: initialize_options(self)
111
+
112
+ Set or (reset) all options/attributes/caches used by the command
113
+ to their default values. Note that these values may be overwritten during
114
+ the build.
115
+
116
+ .. method:: finalize_options(self)
117
+
118
+ Set final values for all options/attributes used by the command.
119
+ Most of the time, each option/attribute/cache should only be set if it does not
120
+ have any value yet (e.g. ``if self.attr is None: self.attr = val``).
121
+
122
+ .. method:: run(self)
123
+
124
+ Execute the actions intended by the command.
125
+ (Side effects **SHOULD** only take place when ``run`` is executed,
126
+ for example, creating new files or writing to the terminal output).
127
+
128
+ A useful analogy for command classes is to think of them as subroutines with local
129
+ variables called "options". The options are "declared" in ``initialize_options()``
130
+ and "defined" (given their final values, aka "finalized") in ``finalize_options()``,
131
+ both of which must be defined by every command class. The "body" of the subroutine,
132
+ (where it does all the work) is the ``run()`` method.
133
+ Between ``initialize_options()`` and ``finalize_options()``, ``setuptools`` may set
134
+ the values for options/attributes based on user's input (or circumstance),
135
+ which means that the implementation should be careful to not overwrite values in
136
+ ``finalize_options`` unless necessary.
137
+
138
+ Please note that other commands (or other parts of setuptools) may also overwrite
139
+ the values of the command's options/attributes multiple times during the build
140
+ process.
141
+ Therefore it is important to consistently implement ``initialize_options()`` and
142
+ ``finalize_options()``. For example, all derived attributes (or attributes that
143
+ depend on the value of other attributes) **SHOULD** be recomputed in
144
+ ``finalize_options``.
145
+
146
+ When overwriting existing commands, custom defined classes **MUST** abide by the
147
+ same APIs implemented by the original class. They also **SHOULD** inherit from the
148
+ original class.
149
+ """
150
+
151
+ command_consumes_arguments = False
152
+
153
+ def __init__(self, dist, **kw):
154
+ """
155
+ Construct the command for dist, updating
156
+ vars(self) with any keyword parameters.
157
+ """
158
+ super().__init__(dist)
159
+ vars(self).update(kw)
160
+
161
+ def _ensure_stringlike(self, option, what, default=None):
162
+ val = getattr(self, option)
163
+ if val is None:
164
+ setattr(self, option, default)
165
+ return default
166
+ elif not isinstance(val, str):
167
+ raise DistutilsOptionError(
168
+ "'%s' must be a %s (got `%s`)" % (option, what, val)
169
+ )
170
+ return val
171
+
172
+ def ensure_string_list(self, option):
173
+ r"""Ensure that 'option' is a list of strings. If 'option' is
174
+ currently a string, we split it either on /,\s*/ or /\s+/, so
175
+ "foo bar baz", "foo,bar,baz", and "foo, bar baz" all become
176
+ ["foo", "bar", "baz"].
177
+
178
+ ..
179
+ TODO: This method seems to be similar to the one in ``distutils.cmd``
180
+ Probably it is just here for backward compatibility with old Python versions?
181
+
182
+ :meta private:
183
+ """
184
+ val = getattr(self, option)
185
+ if val is None:
186
+ return
187
+ elif isinstance(val, str):
188
+ setattr(self, option, re.split(r',\s*|\s+', val))
189
+ else:
190
+ if isinstance(val, list):
191
+ ok = all(isinstance(v, str) for v in val)
192
+ else:
193
+ ok = False
194
+ if not ok:
195
+ raise DistutilsOptionError(
196
+ "'%s' must be a list of strings (got %r)" % (option, val)
197
+ )
198
+
199
+ def reinitialize_command(self, command, reinit_subcommands=0, **kw):
200
+ cmd = _Command.reinitialize_command(self, command, reinit_subcommands)
201
+ vars(cmd).update(kw)
202
+ return cmd
203
+
204
+
205
+ def _find_all_simple(path):
206
+ """
207
+ Find all files under 'path'
208
+ """
209
+ results = (
210
+ os.path.join(base, file)
211
+ for base, dirs, files in os.walk(path, followlinks=True)
212
+ for file in files
213
+ )
214
+ return filter(os.path.isfile, results)
215
+
216
+
217
+ def findall(dir=os.curdir):
218
+ """
219
+ Find all files under 'dir' and return the list of full filenames.
220
+ Unless dir is '.', return full filenames with dir prepended.
221
+ """
222
+ files = _find_all_simple(dir)
223
+ if dir == os.curdir:
224
+ make_rel = functools.partial(os.path.relpath, start=dir)
225
+ files = map(make_rel, files)
226
+ return list(files)
227
+
228
+
229
+ @functools.wraps(_convert_path)
230
+ def convert_path(pathname):
231
+ from inspect import cleandoc
232
+
233
+ msg = """
234
+ The function `convert_path` is considered internal and not part of the public API.
235
+ Its direct usage by 3rd-party packages is considered deprecated and the function
236
+ may be removed in the future.
237
+ """
238
+ warnings.warn(cleandoc(msg), SetuptoolsDeprecationWarning)
239
+ return _convert_path(pathname)
240
+
241
+
242
+ class sic(str):
243
+ """Treat this string as-is (https://en.wikipedia.org/wiki/Sic)"""
244
+
245
+
246
+ # Apply monkey patches
247
+ monkey.patch_all()
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/__init__.cpython-310.pyc ADDED
Binary file (9.52 kB). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-310.pyc ADDED
Binary file (565 Bytes). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/_entry_points.cpython-310.pyc ADDED
Binary file (3.03 kB). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/_imp.cpython-310.pyc ADDED
Binary file (2.09 kB). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/_importlib.cpython-310.pyc ADDED
Binary file (1.36 kB). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/_itertools.cpython-310.pyc ADDED
Binary file (929 Bytes). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/_path.cpython-310.pyc ADDED
Binary file (1.1 kB). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/_reqs.cpython-310.pyc ADDED
Binary file (844 Bytes). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/archive_util.cpython-310.pyc ADDED
Binary file (6.2 kB). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/build_meta.cpython-310.pyc ADDED
Binary file (18.1 kB). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/dep_util.cpython-310.pyc ADDED
Binary file (872 Bytes). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/depends.cpython-310.pyc ADDED
Binary file (5.31 kB). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/discovery.cpython-310.pyc ADDED
Binary file (20.6 kB). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/dist.cpython-310.pyc ADDED
Binary file (38.4 kB). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/errors.cpython-310.pyc ADDED
Binary file (2.5 kB). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/extension.cpython-310.pyc ADDED
Binary file (5.91 kB). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/glob.cpython-310.pyc ADDED
Binary file (3.75 kB). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/installer.cpython-310.pyc ADDED
Binary file (3 kB). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/launch.cpython-310.pyc ADDED
Binary file (922 Bytes). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/logging.cpython-310.pyc ADDED
Binary file (1.26 kB). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/monkey.cpython-310.pyc ADDED
Binary file (4.46 kB). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/msvc.cpython-310.pyc ADDED
Binary file (40.6 kB). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/namespaces.cpython-310.pyc ADDED
Binary file (3.63 kB). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/package_index.cpython-310.pyc ADDED
Binary file (32.7 kB). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/py34compat.cpython-310.pyc ADDED
Binary file (497 Bytes). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/sandbox.cpython-310.pyc ADDED
Binary file (15.8 kB). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/unicode_utils.cpython-310.pyc ADDED
Binary file (1.13 kB). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/version.cpython-310.pyc ADDED
Binary file (339 Bytes). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/wheel.cpython-310.pyc ADDED
Binary file (7.61 kB). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/__pycache__/windows_support.cpython-310.pyc ADDED
Binary file (1.05 kB). View file
 
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_deprecation_warning.py ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ class SetuptoolsDeprecationWarning(Warning):
2
+ """
3
+ Base class for warning deprecations in ``setuptools``
4
+
5
+ This class is not derived from ``DeprecationWarning``, and as such is
6
+ visible by default.
7
+ """
ACE_plus/flashenv/lib/python3.10/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
ACE_plus/flashenv/lib/python3.10/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)))
ACE_plus/flashenv/lib/python3.10/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
ACE_plus/flashenv/lib/python3.10/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
ACE_plus/flashenv/lib/python3.10/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()
ACE_plus/flashenv/lib/python3.10/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
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/config.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils.pypirc
2
+
3
+ Provides the PyPIRCCommand class, the base class for the command classes
4
+ that uses .pypirc in the distutils.command package.
5
+ """
6
+ import os
7
+ from configparser import RawConfigParser
8
+
9
+ from distutils.cmd import Command
10
+
11
+ DEFAULT_PYPIRC = """\
12
+ [distutils]
13
+ index-servers =
14
+ pypi
15
+
16
+ [pypi]
17
+ username:%s
18
+ password:%s
19
+ """
20
+
21
+
22
+ class PyPIRCCommand(Command):
23
+ """Base command that knows how to handle the .pypirc file"""
24
+
25
+ DEFAULT_REPOSITORY = 'https://upload.pypi.org/legacy/'
26
+ DEFAULT_REALM = 'pypi'
27
+ repository = None
28
+ realm = None
29
+
30
+ user_options = [
31
+ ('repository=', 'r', "url of repository [default: %s]" % DEFAULT_REPOSITORY),
32
+ ('show-response', None, 'display full response text from server'),
33
+ ]
34
+
35
+ boolean_options = ['show-response']
36
+
37
+ def _get_rc_file(self):
38
+ """Returns rc file path."""
39
+ return os.path.join(os.path.expanduser('~'), '.pypirc')
40
+
41
+ def _store_pypirc(self, username, password):
42
+ """Creates a default .pypirc file."""
43
+ rc = self._get_rc_file()
44
+ with os.fdopen(os.open(rc, os.O_CREAT | os.O_WRONLY, 0o600), 'w') as f:
45
+ f.write(DEFAULT_PYPIRC % (username, password))
46
+
47
+ def _read_pypirc(self): # noqa: C901
48
+ """Reads the .pypirc file."""
49
+ rc = self._get_rc_file()
50
+ if os.path.exists(rc):
51
+ self.announce('Using PyPI login from %s' % rc)
52
+ repository = self.repository or self.DEFAULT_REPOSITORY
53
+
54
+ config = RawConfigParser()
55
+ config.read(rc)
56
+ sections = config.sections()
57
+ if 'distutils' in sections:
58
+ # let's get the list of servers
59
+ index_servers = config.get('distutils', 'index-servers')
60
+ _servers = [
61
+ server.strip()
62
+ for server in index_servers.split('\n')
63
+ if server.strip() != ''
64
+ ]
65
+ if _servers == []:
66
+ # nothing set, let's try to get the default pypi
67
+ if 'pypi' in sections:
68
+ _servers = ['pypi']
69
+ else:
70
+ # the file is not properly defined, returning
71
+ # an empty dict
72
+ return {}
73
+ for server in _servers:
74
+ current = {'server': server}
75
+ current['username'] = config.get(server, 'username')
76
+
77
+ # optional params
78
+ for key, default in (
79
+ ('repository', self.DEFAULT_REPOSITORY),
80
+ ('realm', self.DEFAULT_REALM),
81
+ ('password', None),
82
+ ):
83
+ if config.has_option(server, key):
84
+ current[key] = config.get(server, key)
85
+ else:
86
+ current[key] = default
87
+
88
+ # work around people having "repository" for the "pypi"
89
+ # section of their config set to the HTTP (rather than
90
+ # HTTPS) URL
91
+ if server == 'pypi' and repository in (
92
+ self.DEFAULT_REPOSITORY,
93
+ 'pypi',
94
+ ):
95
+ current['repository'] = self.DEFAULT_REPOSITORY
96
+ return current
97
+
98
+ if (
99
+ current['server'] == repository
100
+ or current['repository'] == repository
101
+ ):
102
+ return current
103
+ elif 'server-login' in sections:
104
+ # old format
105
+ server = 'server-login'
106
+ if config.has_option(server, 'repository'):
107
+ repository = config.get(server, 'repository')
108
+ else:
109
+ repository = self.DEFAULT_REPOSITORY
110
+ return {
111
+ 'username': config.get(server, 'username'),
112
+ 'password': config.get(server, 'password'),
113
+ 'repository': repository,
114
+ 'server': server,
115
+ 'realm': self.DEFAULT_REALM,
116
+ }
117
+
118
+ return {}
119
+
120
+ def _read_pypi_response(self, response):
121
+ """Read and decode a PyPI HTTP response."""
122
+ import cgi
123
+
124
+ content_type = response.getheader('content-type', 'text/plain')
125
+ encoding = cgi.parse_header(content_type)[1].get('charset', 'ascii')
126
+ return response.read().decode(encoding)
127
+
128
+ def initialize_options(self):
129
+ """Initialize options."""
130
+ self.repository = None
131
+ self.realm = None
132
+ self.show_response = 0
133
+
134
+ def finalize_options(self):
135
+ """Finalizes options."""
136
+ if self.repository is None:
137
+ self.repository = self.DEFAULT_REPOSITORY
138
+ if self.realm is None:
139
+ self.realm = self.DEFAULT_REALM
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/core.py ADDED
@@ -0,0 +1,291 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils.core
2
+
3
+ The only module that needs to be imported to use the Distutils; provides
4
+ the 'setup' function (which is to be called from the setup script). Also
5
+ indirectly provides the Distribution and Command classes, although they are
6
+ really defined in distutils.dist and distutils.cmd.
7
+ """
8
+
9
+ import os
10
+ import sys
11
+ import tokenize
12
+
13
+ from distutils.debug import DEBUG
14
+ from distutils.errors import (
15
+ DistutilsSetupError,
16
+ DistutilsError,
17
+ CCompilerError,
18
+ DistutilsArgError,
19
+ )
20
+
21
+ # Mainly import these so setup scripts can "from distutils.core import" them.
22
+ from distutils.dist import Distribution
23
+ from distutils.cmd import Command
24
+ from distutils.config import PyPIRCCommand
25
+ from distutils.extension import Extension
26
+
27
+
28
+ __all__ = ['Distribution', 'Command', 'PyPIRCCommand', 'Extension', 'setup']
29
+
30
+ # This is a barebones help message generated displayed when the user
31
+ # runs the setup script with no arguments at all. More useful help
32
+ # is generated with various --help options: global help, list commands,
33
+ # and per-command help.
34
+ USAGE = """\
35
+ usage: %(script)s [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
36
+ or: %(script)s --help [cmd1 cmd2 ...]
37
+ or: %(script)s --help-commands
38
+ or: %(script)s cmd --help
39
+ """
40
+
41
+
42
+ def gen_usage(script_name):
43
+ script = os.path.basename(script_name)
44
+ return USAGE % locals()
45
+
46
+
47
+ # Some mild magic to control the behaviour of 'setup()' from 'run_setup()'.
48
+ _setup_stop_after = None
49
+ _setup_distribution = None
50
+
51
+ # Legal keyword arguments for the setup() function
52
+ setup_keywords = (
53
+ 'distclass',
54
+ 'script_name',
55
+ 'script_args',
56
+ 'options',
57
+ 'name',
58
+ 'version',
59
+ 'author',
60
+ 'author_email',
61
+ 'maintainer',
62
+ 'maintainer_email',
63
+ 'url',
64
+ 'license',
65
+ 'description',
66
+ 'long_description',
67
+ 'keywords',
68
+ 'platforms',
69
+ 'classifiers',
70
+ 'download_url',
71
+ 'requires',
72
+ 'provides',
73
+ 'obsoletes',
74
+ )
75
+
76
+ # Legal keyword arguments for the Extension constructor
77
+ extension_keywords = (
78
+ 'name',
79
+ 'sources',
80
+ 'include_dirs',
81
+ 'define_macros',
82
+ 'undef_macros',
83
+ 'library_dirs',
84
+ 'libraries',
85
+ 'runtime_library_dirs',
86
+ 'extra_objects',
87
+ 'extra_compile_args',
88
+ 'extra_link_args',
89
+ 'swig_opts',
90
+ 'export_symbols',
91
+ 'depends',
92
+ 'language',
93
+ )
94
+
95
+
96
+ def setup(**attrs): # noqa: C901
97
+ """The gateway to the Distutils: do everything your setup script needs
98
+ to do, in a highly flexible and user-driven way. Briefly: create a
99
+ Distribution instance; find and parse config files; parse the command
100
+ line; run each Distutils command found there, customized by the options
101
+ supplied to 'setup()' (as keyword arguments), in config files, and on
102
+ the command line.
103
+
104
+ The Distribution instance might be an instance of a class supplied via
105
+ the 'distclass' keyword argument to 'setup'; if no such class is
106
+ supplied, then the Distribution class (in dist.py) is instantiated.
107
+ All other arguments to 'setup' (except for 'cmdclass') are used to set
108
+ attributes of the Distribution instance.
109
+
110
+ The 'cmdclass' argument, if supplied, is a dictionary mapping command
111
+ names to command classes. Each command encountered on the command line
112
+ will be turned into a command class, which is in turn instantiated; any
113
+ class found in 'cmdclass' is used in place of the default, which is
114
+ (for command 'foo_bar') class 'foo_bar' in module
115
+ 'distutils.command.foo_bar'. The command class must provide a
116
+ 'user_options' attribute which is a list of option specifiers for
117
+ 'distutils.fancy_getopt'. Any command-line options between the current
118
+ and the next command are used to set attributes of the current command
119
+ object.
120
+
121
+ When the entire command-line has been successfully parsed, calls the
122
+ 'run()' method on each command object in turn. This method will be
123
+ driven entirely by the Distribution object (which each command object
124
+ has a reference to, thanks to its constructor), and the
125
+ command-specific options that became attributes of each command
126
+ object.
127
+ """
128
+
129
+ global _setup_stop_after, _setup_distribution
130
+
131
+ # Determine the distribution class -- either caller-supplied or
132
+ # our Distribution (see below).
133
+ klass = attrs.get('distclass')
134
+ if klass:
135
+ del attrs['distclass']
136
+ else:
137
+ klass = Distribution
138
+
139
+ if 'script_name' not in attrs:
140
+ attrs['script_name'] = os.path.basename(sys.argv[0])
141
+ if 'script_args' not in attrs:
142
+ attrs['script_args'] = sys.argv[1:]
143
+
144
+ # Create the Distribution instance, using the remaining arguments
145
+ # (ie. everything except distclass) to initialize it
146
+ try:
147
+ _setup_distribution = dist = klass(attrs)
148
+ except DistutilsSetupError as msg:
149
+ if 'name' not in attrs:
150
+ raise SystemExit("error in setup command: %s" % msg)
151
+ else:
152
+ raise SystemExit("error in {} setup command: {}".format(attrs['name'], msg))
153
+
154
+ if _setup_stop_after == "init":
155
+ return dist
156
+
157
+ # Find and parse the config file(s): they will override options from
158
+ # the setup script, but be overridden by the command line.
159
+ dist.parse_config_files()
160
+
161
+ if DEBUG:
162
+ print("options (after parsing config files):")
163
+ dist.dump_option_dicts()
164
+
165
+ if _setup_stop_after == "config":
166
+ return dist
167
+
168
+ # Parse the command line and override config files; any
169
+ # command-line errors are the end user's fault, so turn them into
170
+ # SystemExit to suppress tracebacks.
171
+ try:
172
+ ok = dist.parse_command_line()
173
+ except DistutilsArgError as msg:
174
+ raise SystemExit(gen_usage(dist.script_name) + "\nerror: %s" % msg)
175
+
176
+ if DEBUG:
177
+ print("options (after parsing command line):")
178
+ dist.dump_option_dicts()
179
+
180
+ if _setup_stop_after == "commandline":
181
+ return dist
182
+
183
+ # And finally, run all the commands found on the command line.
184
+ if ok:
185
+ return run_commands(dist)
186
+
187
+ return dist
188
+
189
+
190
+ # setup ()
191
+
192
+
193
+ def run_commands(dist):
194
+ """Given a Distribution object run all the commands,
195
+ raising ``SystemExit`` errors in the case of failure.
196
+
197
+ This function assumes that either ``sys.argv`` or ``dist.script_args``
198
+ is already set accordingly.
199
+ """
200
+ try:
201
+ dist.run_commands()
202
+ except KeyboardInterrupt:
203
+ raise SystemExit("interrupted")
204
+ except OSError as exc:
205
+ if DEBUG:
206
+ sys.stderr.write("error: {}\n".format(exc))
207
+ raise
208
+ else:
209
+ raise SystemExit("error: {}".format(exc))
210
+
211
+ except (DistutilsError, CCompilerError) as msg:
212
+ if DEBUG:
213
+ raise
214
+ else:
215
+ raise SystemExit("error: " + str(msg))
216
+
217
+ return dist
218
+
219
+
220
+ def run_setup(script_name, script_args=None, stop_after="run"):
221
+ """Run a setup script in a somewhat controlled environment, and
222
+ return the Distribution instance that drives things. This is useful
223
+ if you need to find out the distribution meta-data (passed as
224
+ keyword args from 'script' to 'setup()', or the contents of the
225
+ config files or command-line.
226
+
227
+ 'script_name' is a file that will be read and run with 'exec()';
228
+ 'sys.argv[0]' will be replaced with 'script' for the duration of the
229
+ call. 'script_args' is a list of strings; if supplied,
230
+ 'sys.argv[1:]' will be replaced by 'script_args' for the duration of
231
+ the call.
232
+
233
+ 'stop_after' tells 'setup()' when to stop processing; possible
234
+ values:
235
+ init
236
+ stop after the Distribution instance has been created and
237
+ populated with the keyword arguments to 'setup()'
238
+ config
239
+ stop after config files have been parsed (and their data
240
+ stored in the Distribution instance)
241
+ commandline
242
+ stop after the command-line ('sys.argv[1:]' or 'script_args')
243
+ have been parsed (and the data stored in the Distribution)
244
+ run [default]
245
+ stop after all commands have been run (the same as if 'setup()'
246
+ had been called in the usual way
247
+
248
+ Returns the Distribution instance, which provides all information
249
+ used to drive the Distutils.
250
+ """
251
+ if stop_after not in ('init', 'config', 'commandline', 'run'):
252
+ raise ValueError("invalid value for 'stop_after': {!r}".format(stop_after))
253
+
254
+ global _setup_stop_after, _setup_distribution
255
+ _setup_stop_after = stop_after
256
+
257
+ save_argv = sys.argv.copy()
258
+ g = {'__file__': script_name, '__name__': '__main__'}
259
+ try:
260
+ try:
261
+ sys.argv[0] = script_name
262
+ if script_args is not None:
263
+ sys.argv[1:] = script_args
264
+ # tokenize.open supports automatic encoding detection
265
+ with tokenize.open(script_name) as f:
266
+ code = f.read().replace(r'\r\n', r'\n')
267
+ exec(code, g)
268
+ finally:
269
+ sys.argv = save_argv
270
+ _setup_stop_after = None
271
+ except SystemExit:
272
+ # Hmm, should we do something if exiting with a non-zero code
273
+ # (ie. error)?
274
+ pass
275
+
276
+ if _setup_distribution is None:
277
+ raise RuntimeError(
278
+ (
279
+ "'distutils.core.setup()' was never called -- "
280
+ "perhaps '%s' is not a Distutils setup script?"
281
+ )
282
+ % script_name
283
+ )
284
+
285
+ # I wonder if the setup script's namespace -- g and l -- would be of
286
+ # any interest to callers?
287
+ # print "_setup_distribution:", _setup_distribution
288
+ return _setup_distribution
289
+
290
+
291
+ # run_setup ()
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/cygwinccompiler.py ADDED
@@ -0,0 +1,364 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils.cygwinccompiler
2
+
3
+ Provides the CygwinCCompiler class, a subclass of UnixCCompiler that
4
+ handles the Cygwin port of the GNU C compiler to Windows. It also contains
5
+ the Mingw32CCompiler class which handles the mingw32 port of GCC (same as
6
+ cygwin in no-cygwin mode).
7
+ """
8
+
9
+ import os
10
+ import sys
11
+ import copy
12
+ import shlex
13
+ import warnings
14
+ from subprocess import check_output
15
+
16
+ from distutils.unixccompiler import UnixCCompiler
17
+ from distutils.file_util import write_file
18
+ from distutils.errors import (
19
+ DistutilsExecError,
20
+ DistutilsPlatformError,
21
+ CCompilerError,
22
+ CompileError,
23
+ )
24
+ from distutils.version import LooseVersion, suppress_known_deprecation
25
+
26
+
27
+ def get_msvcr():
28
+ """Include the appropriate MSVC runtime library if Python was built
29
+ with MSVC 7.0 or later.
30
+ """
31
+ msc_pos = sys.version.find('MSC v.')
32
+ if msc_pos != -1:
33
+ msc_ver = sys.version[msc_pos + 6 : msc_pos + 10]
34
+ if msc_ver == '1300':
35
+ # MSVC 7.0
36
+ return ['msvcr70']
37
+ elif msc_ver == '1310':
38
+ # MSVC 7.1
39
+ return ['msvcr71']
40
+ elif msc_ver == '1400':
41
+ # VS2005 / MSVC 8.0
42
+ return ['msvcr80']
43
+ elif msc_ver == '1500':
44
+ # VS2008 / MSVC 9.0
45
+ return ['msvcr90']
46
+ elif msc_ver == '1600':
47
+ # VS2010 / MSVC 10.0
48
+ return ['msvcr100']
49
+ elif msc_ver == '1700':
50
+ # VS2012 / MSVC 11.0
51
+ return ['msvcr110']
52
+ elif msc_ver == '1800':
53
+ # VS2013 / MSVC 12.0
54
+ return ['msvcr120']
55
+ elif 1900 <= int(msc_ver) < 2000:
56
+ # VS2015 / MSVC 14.0
57
+ return ['ucrt', 'vcruntime140']
58
+ else:
59
+ raise ValueError("Unknown MS Compiler version %s " % msc_ver)
60
+
61
+
62
+ _runtime_library_dirs_msg = (
63
+ "Unable to set runtime library search path on Windows, "
64
+ "usually indicated by `runtime_library_dirs` parameter to Extension"
65
+ )
66
+
67
+
68
+ class CygwinCCompiler(UnixCCompiler):
69
+ """Handles the Cygwin port of the GNU C compiler to Windows."""
70
+
71
+ compiler_type = 'cygwin'
72
+ obj_extension = ".o"
73
+ static_lib_extension = ".a"
74
+ shared_lib_extension = ".dll.a"
75
+ dylib_lib_extension = ".dll"
76
+ static_lib_format = "lib%s%s"
77
+ shared_lib_format = "lib%s%s"
78
+ dylib_lib_format = "cyg%s%s"
79
+ exe_extension = ".exe"
80
+
81
+ def __init__(self, verbose=0, dry_run=0, force=0):
82
+
83
+ super().__init__(verbose, dry_run, force)
84
+
85
+ status, details = check_config_h()
86
+ self.debug_print(
87
+ "Python's GCC status: {} (details: {})".format(status, details)
88
+ )
89
+ if status is not CONFIG_H_OK:
90
+ self.warn(
91
+ "Python's pyconfig.h doesn't seem to support your compiler. "
92
+ "Reason: %s. "
93
+ "Compiling may fail because of undefined preprocessor macros." % details
94
+ )
95
+
96
+ self.cc = os.environ.get('CC', 'gcc')
97
+ self.cxx = os.environ.get('CXX', 'g++')
98
+
99
+ self.linker_dll = self.cc
100
+ shared_option = "-shared"
101
+
102
+ self.set_executables(
103
+ compiler='%s -mcygwin -O -Wall' % self.cc,
104
+ compiler_so='%s -mcygwin -mdll -O -Wall' % self.cc,
105
+ compiler_cxx='%s -mcygwin -O -Wall' % self.cxx,
106
+ linker_exe='%s -mcygwin' % self.cc,
107
+ linker_so=('{} -mcygwin {}'.format(self.linker_dll, shared_option)),
108
+ )
109
+
110
+ # Include the appropriate MSVC runtime library if Python was built
111
+ # with MSVC 7.0 or later.
112
+ self.dll_libraries = get_msvcr()
113
+
114
+ @property
115
+ def gcc_version(self):
116
+ # Older numpy dependend on this existing to check for ancient
117
+ # gcc versions. This doesn't make much sense with clang etc so
118
+ # just hardcode to something recent.
119
+ # https://github.com/numpy/numpy/pull/20333
120
+ warnings.warn(
121
+ "gcc_version attribute of CygwinCCompiler is deprecated. "
122
+ "Instead of returning actual gcc version a fixed value 11.2.0 is returned.",
123
+ DeprecationWarning,
124
+ stacklevel=2,
125
+ )
126
+ with suppress_known_deprecation():
127
+ return LooseVersion("11.2.0")
128
+
129
+ def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
130
+ """Compiles the source by spawning GCC and windres if needed."""
131
+ if ext == '.rc' or ext == '.res':
132
+ # gcc needs '.res' and '.rc' compiled to object files !!!
133
+ try:
134
+ self.spawn(["windres", "-i", src, "-o", obj])
135
+ except DistutilsExecError as msg:
136
+ raise CompileError(msg)
137
+ else: # for other files use the C-compiler
138
+ try:
139
+ self.spawn(
140
+ self.compiler_so + cc_args + [src, '-o', obj] + extra_postargs
141
+ )
142
+ except DistutilsExecError as msg:
143
+ raise CompileError(msg)
144
+
145
+ def link(
146
+ self,
147
+ target_desc,
148
+ objects,
149
+ output_filename,
150
+ output_dir=None,
151
+ libraries=None,
152
+ library_dirs=None,
153
+ runtime_library_dirs=None,
154
+ export_symbols=None,
155
+ debug=0,
156
+ extra_preargs=None,
157
+ extra_postargs=None,
158
+ build_temp=None,
159
+ target_lang=None,
160
+ ):
161
+ """Link the objects."""
162
+ # use separate copies, so we can modify the lists
163
+ extra_preargs = copy.copy(extra_preargs or [])
164
+ libraries = copy.copy(libraries or [])
165
+ objects = copy.copy(objects or [])
166
+
167
+ if runtime_library_dirs:
168
+ self.warn(_runtime_library_dirs_msg)
169
+
170
+ # Additional libraries
171
+ libraries.extend(self.dll_libraries)
172
+
173
+ # handle export symbols by creating a def-file
174
+ # with executables this only works with gcc/ld as linker
175
+ if (export_symbols is not None) and (
176
+ target_desc != self.EXECUTABLE or self.linker_dll == "gcc"
177
+ ):
178
+ # (The linker doesn't do anything if output is up-to-date.
179
+ # So it would probably better to check if we really need this,
180
+ # but for this we had to insert some unchanged parts of
181
+ # UnixCCompiler, and this is not what we want.)
182
+
183
+ # we want to put some files in the same directory as the
184
+ # object files are, build_temp doesn't help much
185
+ # where are the object files
186
+ temp_dir = os.path.dirname(objects[0])
187
+ # name of dll to give the helper files the same base name
188
+ (dll_name, dll_extension) = os.path.splitext(
189
+ os.path.basename(output_filename)
190
+ )
191
+
192
+ # generate the filenames for these files
193
+ def_file = os.path.join(temp_dir, dll_name + ".def")
194
+
195
+ # Generate .def file
196
+ contents = ["LIBRARY %s" % os.path.basename(output_filename), "EXPORTS"]
197
+ for sym in export_symbols:
198
+ contents.append(sym)
199
+ self.execute(write_file, (def_file, contents), "writing %s" % def_file)
200
+
201
+ # next add options for def-file
202
+
203
+ # for gcc/ld the def-file is specified as any object files
204
+ objects.append(def_file)
205
+
206
+ # end: if ((export_symbols is not None) and
207
+ # (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")):
208
+
209
+ # who wants symbols and a many times larger output file
210
+ # should explicitly switch the debug mode on
211
+ # otherwise we let ld strip the output file
212
+ # (On my machine: 10KiB < stripped_file < ??100KiB
213
+ # unstripped_file = stripped_file + XXX KiB
214
+ # ( XXX=254 for a typical python extension))
215
+ if not debug:
216
+ extra_preargs.append("-s")
217
+
218
+ UnixCCompiler.link(
219
+ self,
220
+ target_desc,
221
+ objects,
222
+ output_filename,
223
+ output_dir,
224
+ libraries,
225
+ library_dirs,
226
+ runtime_library_dirs,
227
+ None, # export_symbols, we do this in our def-file
228
+ debug,
229
+ extra_preargs,
230
+ extra_postargs,
231
+ build_temp,
232
+ target_lang,
233
+ )
234
+
235
+ def runtime_library_dir_option(self, dir):
236
+ # cygwin doesn't support rpath. While in theory we could error
237
+ # out like MSVC does, code might expect it to work like on Unix, so
238
+ # just warn and hope for the best.
239
+ self.warn(_runtime_library_dirs_msg)
240
+ return []
241
+
242
+ # -- Miscellaneous methods -----------------------------------------
243
+
244
+ def _make_out_path(self, output_dir, strip_dir, src_name):
245
+ # use normcase to make sure '.rc' is really '.rc' and not '.RC'
246
+ norm_src_name = os.path.normcase(src_name)
247
+ return super()._make_out_path(output_dir, strip_dir, norm_src_name)
248
+
249
+ @property
250
+ def out_extensions(self):
251
+ """
252
+ Add support for rc and res files.
253
+ """
254
+ return {
255
+ **super().out_extensions,
256
+ **{ext: ext + self.obj_extension for ext in ('.res', '.rc')},
257
+ }
258
+
259
+
260
+ # the same as cygwin plus some additional parameters
261
+ class Mingw32CCompiler(CygwinCCompiler):
262
+ """Handles the Mingw32 port of the GNU C compiler to Windows."""
263
+
264
+ compiler_type = 'mingw32'
265
+
266
+ def __init__(self, verbose=0, dry_run=0, force=0):
267
+
268
+ super().__init__(verbose, dry_run, force)
269
+
270
+ shared_option = "-shared"
271
+
272
+ if is_cygwincc(self.cc):
273
+ raise CCompilerError('Cygwin gcc cannot be used with --compiler=mingw32')
274
+
275
+ self.set_executables(
276
+ compiler='%s -O -Wall' % self.cc,
277
+ compiler_so='%s -mdll -O -Wall' % self.cc,
278
+ compiler_cxx='%s -O -Wall' % self.cxx,
279
+ linker_exe='%s' % self.cc,
280
+ linker_so='{} {}'.format(self.linker_dll, shared_option),
281
+ )
282
+
283
+ # Maybe we should also append -mthreads, but then the finished
284
+ # dlls need another dll (mingwm10.dll see Mingw32 docs)
285
+ # (-mthreads: Support thread-safe exception handling on `Mingw32')
286
+
287
+ # no additional libraries needed
288
+ self.dll_libraries = []
289
+
290
+ # Include the appropriate MSVC runtime library if Python was built
291
+ # with MSVC 7.0 or later.
292
+ self.dll_libraries = get_msvcr()
293
+
294
+ def runtime_library_dir_option(self, dir):
295
+ raise DistutilsPlatformError(_runtime_library_dirs_msg)
296
+
297
+
298
+ # Because these compilers aren't configured in Python's pyconfig.h file by
299
+ # default, we should at least warn the user if he is using an unmodified
300
+ # version.
301
+
302
+ CONFIG_H_OK = "ok"
303
+ CONFIG_H_NOTOK = "not ok"
304
+ CONFIG_H_UNCERTAIN = "uncertain"
305
+
306
+
307
+ def check_config_h():
308
+ """Check if the current Python installation appears amenable to building
309
+ extensions with GCC.
310
+
311
+ Returns a tuple (status, details), where 'status' is one of the following
312
+ constants:
313
+
314
+ - CONFIG_H_OK: all is well, go ahead and compile
315
+ - CONFIG_H_NOTOK: doesn't look good
316
+ - CONFIG_H_UNCERTAIN: not sure -- unable to read pyconfig.h
317
+
318
+ 'details' is a human-readable string explaining the situation.
319
+
320
+ Note there are two ways to conclude "OK": either 'sys.version' contains
321
+ the string "GCC" (implying that this Python was built with GCC), or the
322
+ installed "pyconfig.h" contains the string "__GNUC__".
323
+ """
324
+
325
+ # XXX since this function also checks sys.version, it's not strictly a
326
+ # "pyconfig.h" check -- should probably be renamed...
327
+
328
+ from distutils import sysconfig
329
+
330
+ # if sys.version contains GCC then python was compiled with GCC, and the
331
+ # pyconfig.h file should be OK
332
+ if "GCC" in sys.version:
333
+ return CONFIG_H_OK, "sys.version mentions 'GCC'"
334
+
335
+ # Clang would also work
336
+ if "Clang" in sys.version:
337
+ return CONFIG_H_OK, "sys.version mentions 'Clang'"
338
+
339
+ # let's see if __GNUC__ is mentioned in python.h
340
+ fn = sysconfig.get_config_h_filename()
341
+ try:
342
+ config_h = open(fn)
343
+ try:
344
+ if "__GNUC__" in config_h.read():
345
+ return CONFIG_H_OK, "'%s' mentions '__GNUC__'" % fn
346
+ else:
347
+ return CONFIG_H_NOTOK, "'%s' does not mention '__GNUC__'" % fn
348
+ finally:
349
+ config_h.close()
350
+ except OSError as exc:
351
+ return (CONFIG_H_UNCERTAIN, "couldn't read '{}': {}".format(fn, exc.strerror))
352
+
353
+
354
+ def is_cygwincc(cc):
355
+ '''Try to determine if the compiler that would be used is from cygwin.'''
356
+ out_string = check_output(shlex.split(cc) + ['-dumpmachine'])
357
+ return out_string.strip().endswith(b'cygwin')
358
+
359
+
360
+ get_versions = None
361
+ """
362
+ A stand-in for the previous get_versions() function to prevent failures
363
+ when monkeypatched. See pypa/setuptools#2969.
364
+ """
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/debug.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ import os
2
+
3
+ # If DISTUTILS_DEBUG is anything other than the empty string, we run in
4
+ # debug mode.
5
+ DEBUG = os.environ.get('DISTUTILS_DEBUG')
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/dep_util.py ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils.dep_util
2
+
3
+ Utility functions for simple, timestamp-based dependency of files
4
+ and groups of files; also, function based entirely on such
5
+ timestamp dependency analysis."""
6
+
7
+ import os
8
+ from distutils.errors import DistutilsFileError
9
+
10
+
11
+ def newer(source, target):
12
+ """Return true if 'source' exists and is more recently modified than
13
+ 'target', or if 'source' exists and 'target' doesn't. Return false if
14
+ both exist and 'target' is the same age or younger than 'source'.
15
+ Raise DistutilsFileError if 'source' does not exist.
16
+ """
17
+ if not os.path.exists(source):
18
+ raise DistutilsFileError("file '%s' does not exist" % os.path.abspath(source))
19
+ if not os.path.exists(target):
20
+ return 1
21
+
22
+ from stat import ST_MTIME
23
+
24
+ mtime1 = os.stat(source)[ST_MTIME]
25
+ mtime2 = os.stat(target)[ST_MTIME]
26
+
27
+ return mtime1 > mtime2
28
+
29
+
30
+ # newer ()
31
+
32
+
33
+ def newer_pairwise(sources, targets):
34
+ """Walk two filename lists in parallel, testing if each source is newer
35
+ than its corresponding target. Return a pair of lists (sources,
36
+ targets) where source is newer than target, according to the semantics
37
+ of 'newer()'.
38
+ """
39
+ if len(sources) != len(targets):
40
+ raise ValueError("'sources' and 'targets' must be same length")
41
+
42
+ # build a pair of lists (sources, targets) where source is newer
43
+ n_sources = []
44
+ n_targets = []
45
+ for i in range(len(sources)):
46
+ if newer(sources[i], targets[i]):
47
+ n_sources.append(sources[i])
48
+ n_targets.append(targets[i])
49
+
50
+ return (n_sources, n_targets)
51
+
52
+
53
+ # newer_pairwise ()
54
+
55
+
56
+ def newer_group(sources, target, missing='error'):
57
+ """Return true if 'target' is out-of-date with respect to any file
58
+ listed in 'sources'. In other words, if 'target' exists and is newer
59
+ than every file in 'sources', return false; otherwise return true.
60
+ 'missing' controls what we do when a source file is missing; the
61
+ default ("error") is to blow up with an OSError from inside 'stat()';
62
+ if it is "ignore", we silently drop any missing source files; if it is
63
+ "newer", any missing source files make us assume that 'target' is
64
+ out-of-date (this is handy in "dry-run" mode: it'll make you pretend to
65
+ carry out commands that wouldn't work because inputs are missing, but
66
+ that doesn't matter because you're not actually going to run the
67
+ commands).
68
+ """
69
+ # If the target doesn't even exist, then it's definitely out-of-date.
70
+ if not os.path.exists(target):
71
+ return 1
72
+
73
+ # Otherwise we have to find out the hard way: if *any* source file
74
+ # is more recent than 'target', then 'target' is out-of-date and
75
+ # we can immediately return true. If we fall through to the end
76
+ # of the loop, then 'target' is up-to-date and we return false.
77
+ from stat import ST_MTIME
78
+
79
+ target_mtime = os.stat(target)[ST_MTIME]
80
+ for source in sources:
81
+ if not os.path.exists(source):
82
+ if missing == 'error': # blow up when we stat() the file
83
+ pass
84
+ elif missing == 'ignore': # missing source dropped from
85
+ continue # target's dependency list
86
+ elif missing == 'newer': # missing source means target is
87
+ return 1 # out-of-date
88
+
89
+ source_mtime = os.stat(source)[ST_MTIME]
90
+ if source_mtime > target_mtime:
91
+ return 1
92
+ else:
93
+ return 0
94
+
95
+
96
+ # newer_group ()
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/dist.py ADDED
@@ -0,0 +1,1286 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils.dist
2
+
3
+ Provides the Distribution class, which represents the module distribution
4
+ being built/installed/distributed.
5
+ """
6
+
7
+ import sys
8
+ import os
9
+ import re
10
+ import pathlib
11
+ import contextlib
12
+ from email import message_from_file
13
+
14
+ try:
15
+ import warnings
16
+ except ImportError:
17
+ warnings = None
18
+
19
+ from distutils.errors import (
20
+ DistutilsOptionError,
21
+ DistutilsModuleError,
22
+ DistutilsArgError,
23
+ DistutilsClassError,
24
+ )
25
+ from distutils.fancy_getopt import FancyGetopt, translate_longopt
26
+ from distutils.util import check_environ, strtobool, rfc822_escape
27
+ from distutils import log
28
+ from distutils.debug import DEBUG
29
+
30
+ # Regex to define acceptable Distutils command names. This is not *quite*
31
+ # the same as a Python NAME -- I don't allow leading underscores. The fact
32
+ # that they're very similar is no coincidence; the default naming scheme is
33
+ # to look for a Python module named after the command.
34
+ command_re = re.compile(r'^[a-zA-Z]([a-zA-Z0-9_]*)$')
35
+
36
+
37
+ def _ensure_list(value, fieldname):
38
+ if isinstance(value, str):
39
+ # a string containing comma separated values is okay. It will
40
+ # be converted to a list by Distribution.finalize_options().
41
+ pass
42
+ elif not isinstance(value, list):
43
+ # passing a tuple or an iterator perhaps, warn and convert
44
+ typename = type(value).__name__
45
+ msg = "Warning: '{fieldname}' should be a list, got type '{typename}'"
46
+ msg = msg.format(**locals())
47
+ log.log(log.WARN, msg)
48
+ value = list(value)
49
+ return value
50
+
51
+
52
+ class Distribution:
53
+ """The core of the Distutils. Most of the work hiding behind 'setup'
54
+ is really done within a Distribution instance, which farms the work out
55
+ to the Distutils commands specified on the command line.
56
+
57
+ Setup scripts will almost never instantiate Distribution directly,
58
+ unless the 'setup()' function is totally inadequate to their needs.
59
+ However, it is conceivable that a setup script might wish to subclass
60
+ Distribution for some specialized purpose, and then pass the subclass
61
+ to 'setup()' as the 'distclass' keyword argument. If so, it is
62
+ necessary to respect the expectations that 'setup' has of Distribution.
63
+ See the code for 'setup()', in core.py, for details.
64
+ """
65
+
66
+ # 'global_options' describes the command-line options that may be
67
+ # supplied to the setup script prior to any actual commands.
68
+ # Eg. "./setup.py -n" or "./setup.py --quiet" both take advantage of
69
+ # these global options. This list should be kept to a bare minimum,
70
+ # since every global option is also valid as a command option -- and we
71
+ # don't want to pollute the commands with too many options that they
72
+ # have minimal control over.
73
+ # The fourth entry for verbose means that it can be repeated.
74
+ global_options = [
75
+ ('verbose', 'v', "run verbosely (default)", 1),
76
+ ('quiet', 'q', "run quietly (turns verbosity off)"),
77
+ ('dry-run', 'n', "don't actually do anything"),
78
+ ('help', 'h', "show detailed help message"),
79
+ ('no-user-cfg', None, 'ignore pydistutils.cfg in your home directory'),
80
+ ]
81
+
82
+ # 'common_usage' is a short (2-3 line) string describing the common
83
+ # usage of the setup script.
84
+ common_usage = """\
85
+ Common commands: (see '--help-commands' for more)
86
+
87
+ setup.py build will build the package underneath 'build/'
88
+ setup.py install will install the package
89
+ """
90
+
91
+ # options that are not propagated to the commands
92
+ display_options = [
93
+ ('help-commands', None, "list all available commands"),
94
+ ('name', None, "print package name"),
95
+ ('version', 'V', "print package version"),
96
+ ('fullname', None, "print <package name>-<version>"),
97
+ ('author', None, "print the author's name"),
98
+ ('author-email', None, "print the author's email address"),
99
+ ('maintainer', None, "print the maintainer's name"),
100
+ ('maintainer-email', None, "print the maintainer's email address"),
101
+ ('contact', None, "print the maintainer's name if known, else the author's"),
102
+ (
103
+ 'contact-email',
104
+ None,
105
+ "print the maintainer's email address if known, else the author's",
106
+ ),
107
+ ('url', None, "print the URL for this package"),
108
+ ('license', None, "print the license of the package"),
109
+ ('licence', None, "alias for --license"),
110
+ ('description', None, "print the package description"),
111
+ ('long-description', None, "print the long package description"),
112
+ ('platforms', None, "print the list of platforms"),
113
+ ('classifiers', None, "print the list of classifiers"),
114
+ ('keywords', None, "print the list of keywords"),
115
+ ('provides', None, "print the list of packages/modules provided"),
116
+ ('requires', None, "print the list of packages/modules required"),
117
+ ('obsoletes', None, "print the list of packages/modules made obsolete"),
118
+ ]
119
+ display_option_names = [translate_longopt(x[0]) for x in display_options]
120
+
121
+ # negative options are options that exclude other options
122
+ negative_opt = {'quiet': 'verbose'}
123
+
124
+ # -- Creation/initialization methods -------------------------------
125
+
126
+ def __init__(self, attrs=None): # noqa: C901
127
+ """Construct a new Distribution instance: initialize all the
128
+ attributes of a Distribution, and then use 'attrs' (a dictionary
129
+ mapping attribute names to values) to assign some of those
130
+ attributes their "real" values. (Any attributes not mentioned in
131
+ 'attrs' will be assigned to some null value: 0, None, an empty list
132
+ or dictionary, etc.) Most importantly, initialize the
133
+ 'command_obj' attribute to the empty dictionary; this will be
134
+ filled in with real command objects by 'parse_command_line()'.
135
+ """
136
+
137
+ # Default values for our command-line options
138
+ self.verbose = 1
139
+ self.dry_run = 0
140
+ self.help = 0
141
+ for attr in self.display_option_names:
142
+ setattr(self, attr, 0)
143
+
144
+ # Store the distribution meta-data (name, version, author, and so
145
+ # forth) in a separate object -- we're getting to have enough
146
+ # information here (and enough command-line options) that it's
147
+ # worth it. Also delegate 'get_XXX()' methods to the 'metadata'
148
+ # object in a sneaky and underhanded (but efficient!) way.
149
+ self.metadata = DistributionMetadata()
150
+ for basename in self.metadata._METHOD_BASENAMES:
151
+ method_name = "get_" + basename
152
+ setattr(self, method_name, getattr(self.metadata, method_name))
153
+
154
+ # 'cmdclass' maps command names to class objects, so we
155
+ # can 1) quickly figure out which class to instantiate when
156
+ # we need to create a new command object, and 2) have a way
157
+ # for the setup script to override command classes
158
+ self.cmdclass = {}
159
+
160
+ # 'command_packages' is a list of packages in which commands
161
+ # are searched for. The factory for command 'foo' is expected
162
+ # to be named 'foo' in the module 'foo' in one of the packages
163
+ # named here. This list is searched from the left; an error
164
+ # is raised if no named package provides the command being
165
+ # searched for. (Always access using get_command_packages().)
166
+ self.command_packages = None
167
+
168
+ # 'script_name' and 'script_args' are usually set to sys.argv[0]
169
+ # and sys.argv[1:], but they can be overridden when the caller is
170
+ # not necessarily a setup script run from the command-line.
171
+ self.script_name = None
172
+ self.script_args = None
173
+
174
+ # 'command_options' is where we store command options between
175
+ # parsing them (from config files, the command-line, etc.) and when
176
+ # they are actually needed -- ie. when the command in question is
177
+ # instantiated. It is a dictionary of dictionaries of 2-tuples:
178
+ # command_options = { command_name : { option : (source, value) } }
179
+ self.command_options = {}
180
+
181
+ # 'dist_files' is the list of (command, pyversion, file) that
182
+ # have been created by any dist commands run so far. This is
183
+ # filled regardless of whether the run is dry or not. pyversion
184
+ # gives sysconfig.get_python_version() if the dist file is
185
+ # specific to a Python version, 'any' if it is good for all
186
+ # Python versions on the target platform, and '' for a source
187
+ # file. pyversion should not be used to specify minimum or
188
+ # maximum required Python versions; use the metainfo for that
189
+ # instead.
190
+ self.dist_files = []
191
+
192
+ # These options are really the business of various commands, rather
193
+ # than of the Distribution itself. We provide aliases for them in
194
+ # Distribution as a convenience to the developer.
195
+ self.packages = None
196
+ self.package_data = {}
197
+ self.package_dir = None
198
+ self.py_modules = None
199
+ self.libraries = None
200
+ self.headers = None
201
+ self.ext_modules = None
202
+ self.ext_package = None
203
+ self.include_dirs = None
204
+ self.extra_path = None
205
+ self.scripts = None
206
+ self.data_files = None
207
+ self.password = ''
208
+
209
+ # And now initialize bookkeeping stuff that can't be supplied by
210
+ # the caller at all. 'command_obj' maps command names to
211
+ # Command instances -- that's how we enforce that every command
212
+ # class is a singleton.
213
+ self.command_obj = {}
214
+
215
+ # 'have_run' maps command names to boolean values; it keeps track
216
+ # of whether we have actually run a particular command, to make it
217
+ # cheap to "run" a command whenever we think we might need to -- if
218
+ # it's already been done, no need for expensive filesystem
219
+ # operations, we just check the 'have_run' dictionary and carry on.
220
+ # It's only safe to query 'have_run' for a command class that has
221
+ # been instantiated -- a false value will be inserted when the
222
+ # command object is created, and replaced with a true value when
223
+ # the command is successfully run. Thus it's probably best to use
224
+ # '.get()' rather than a straight lookup.
225
+ self.have_run = {}
226
+
227
+ # Now we'll use the attrs dictionary (ultimately, keyword args from
228
+ # the setup script) to possibly override any or all of these
229
+ # distribution options.
230
+
231
+ if attrs:
232
+ # Pull out the set of command options and work on them
233
+ # specifically. Note that this order guarantees that aliased
234
+ # command options will override any supplied redundantly
235
+ # through the general options dictionary.
236
+ options = attrs.get('options')
237
+ if options is not None:
238
+ del attrs['options']
239
+ for (command, cmd_options) in options.items():
240
+ opt_dict = self.get_option_dict(command)
241
+ for (opt, val) in cmd_options.items():
242
+ opt_dict[opt] = ("setup script", val)
243
+
244
+ if 'licence' in attrs:
245
+ attrs['license'] = attrs['licence']
246
+ del attrs['licence']
247
+ msg = "'licence' distribution option is deprecated; use 'license'"
248
+ if warnings is not None:
249
+ warnings.warn(msg)
250
+ else:
251
+ sys.stderr.write(msg + "\n")
252
+
253
+ # Now work on the rest of the attributes. Any attribute that's
254
+ # not already defined is invalid!
255
+ for (key, val) in attrs.items():
256
+ if hasattr(self.metadata, "set_" + key):
257
+ getattr(self.metadata, "set_" + key)(val)
258
+ elif hasattr(self.metadata, key):
259
+ setattr(self.metadata, key, val)
260
+ elif hasattr(self, key):
261
+ setattr(self, key, val)
262
+ else:
263
+ msg = "Unknown distribution option: %s" % repr(key)
264
+ warnings.warn(msg)
265
+
266
+ # no-user-cfg is handled before other command line args
267
+ # because other args override the config files, and this
268
+ # one is needed before we can load the config files.
269
+ # If attrs['script_args'] wasn't passed, assume false.
270
+ #
271
+ # This also make sure we just look at the global options
272
+ self.want_user_cfg = True
273
+
274
+ if self.script_args is not None:
275
+ for arg in self.script_args:
276
+ if not arg.startswith('-'):
277
+ break
278
+ if arg == '--no-user-cfg':
279
+ self.want_user_cfg = False
280
+ break
281
+
282
+ self.finalize_options()
283
+
284
+ def get_option_dict(self, command):
285
+ """Get the option dictionary for a given command. If that
286
+ command's option dictionary hasn't been created yet, then create it
287
+ and return the new dictionary; otherwise, return the existing
288
+ option dictionary.
289
+ """
290
+ dict = self.command_options.get(command)
291
+ if dict is None:
292
+ dict = self.command_options[command] = {}
293
+ return dict
294
+
295
+ def dump_option_dicts(self, header=None, commands=None, indent=""):
296
+ from pprint import pformat
297
+
298
+ if commands is None: # dump all command option dicts
299
+ commands = sorted(self.command_options.keys())
300
+
301
+ if header is not None:
302
+ self.announce(indent + header)
303
+ indent = indent + " "
304
+
305
+ if not commands:
306
+ self.announce(indent + "no commands known yet")
307
+ return
308
+
309
+ for cmd_name in commands:
310
+ opt_dict = self.command_options.get(cmd_name)
311
+ if opt_dict is None:
312
+ self.announce(indent + "no option dict for '%s' command" % cmd_name)
313
+ else:
314
+ self.announce(indent + "option dict for '%s' command:" % cmd_name)
315
+ out = pformat(opt_dict)
316
+ for line in out.split('\n'):
317
+ self.announce(indent + " " + line)
318
+
319
+ # -- Config file finding/parsing methods ---------------------------
320
+
321
+ def find_config_files(self):
322
+ """Find as many configuration files as should be processed for this
323
+ platform, and return a list of filenames in the order in which they
324
+ should be parsed. The filenames returned are guaranteed to exist
325
+ (modulo nasty race conditions).
326
+
327
+ There are multiple possible config files:
328
+ - distutils.cfg in the Distutils installation directory (i.e.
329
+ where the top-level Distutils __inst__.py file lives)
330
+ - a file in the user's home directory named .pydistutils.cfg
331
+ on Unix and pydistutils.cfg on Windows/Mac; may be disabled
332
+ with the ``--no-user-cfg`` option
333
+ - setup.cfg in the current directory
334
+ - a file named by an environment variable
335
+ """
336
+ check_environ()
337
+ files = [str(path) for path in self._gen_paths() if os.path.isfile(path)]
338
+
339
+ if DEBUG:
340
+ self.announce("using config files: %s" % ', '.join(files))
341
+
342
+ return files
343
+
344
+ def _gen_paths(self):
345
+ # The system-wide Distutils config file
346
+ sys_dir = pathlib.Path(sys.modules['distutils'].__file__).parent
347
+ yield sys_dir / "distutils.cfg"
348
+
349
+ # The per-user config file
350
+ prefix = '.' * (os.name == 'posix')
351
+ filename = prefix + 'pydistutils.cfg'
352
+ if self.want_user_cfg:
353
+ yield pathlib.Path('~').expanduser() / filename
354
+
355
+ # All platforms support local setup.cfg
356
+ yield pathlib.Path('setup.cfg')
357
+
358
+ # Additional config indicated in the environment
359
+ with contextlib.suppress(TypeError):
360
+ yield pathlib.Path(os.getenv("DIST_EXTRA_CONFIG"))
361
+
362
+ def parse_config_files(self, filenames=None): # noqa: C901
363
+ from configparser import ConfigParser
364
+
365
+ # Ignore install directory options if we have a venv
366
+ if sys.prefix != sys.base_prefix:
367
+ ignore_options = [
368
+ 'install-base',
369
+ 'install-platbase',
370
+ 'install-lib',
371
+ 'install-platlib',
372
+ 'install-purelib',
373
+ 'install-headers',
374
+ 'install-scripts',
375
+ 'install-data',
376
+ 'prefix',
377
+ 'exec-prefix',
378
+ 'home',
379
+ 'user',
380
+ 'root',
381
+ ]
382
+ else:
383
+ ignore_options = []
384
+
385
+ ignore_options = frozenset(ignore_options)
386
+
387
+ if filenames is None:
388
+ filenames = self.find_config_files()
389
+
390
+ if DEBUG:
391
+ self.announce("Distribution.parse_config_files():")
392
+
393
+ parser = ConfigParser()
394
+ for filename in filenames:
395
+ if DEBUG:
396
+ self.announce(" reading %s" % filename)
397
+ parser.read(filename)
398
+ for section in parser.sections():
399
+ options = parser.options(section)
400
+ opt_dict = self.get_option_dict(section)
401
+
402
+ for opt in options:
403
+ if opt != '__name__' and opt not in ignore_options:
404
+ val = parser.get(section, opt)
405
+ opt = opt.replace('-', '_')
406
+ opt_dict[opt] = (filename, val)
407
+
408
+ # Make the ConfigParser forget everything (so we retain
409
+ # the original filenames that options come from)
410
+ parser.__init__()
411
+
412
+ # If there was a "global" section in the config file, use it
413
+ # to set Distribution options.
414
+
415
+ if 'global' in self.command_options:
416
+ for (opt, (src, val)) in self.command_options['global'].items():
417
+ alias = self.negative_opt.get(opt)
418
+ try:
419
+ if alias:
420
+ setattr(self, alias, not strtobool(val))
421
+ elif opt in ('verbose', 'dry_run'): # ugh!
422
+ setattr(self, opt, strtobool(val))
423
+ else:
424
+ setattr(self, opt, val)
425
+ except ValueError as msg:
426
+ raise DistutilsOptionError(msg)
427
+
428
+ # -- Command-line parsing methods ----------------------------------
429
+
430
+ def parse_command_line(self):
431
+ """Parse the setup script's command line, taken from the
432
+ 'script_args' instance attribute (which defaults to 'sys.argv[1:]'
433
+ -- see 'setup()' in core.py). This list is first processed for
434
+ "global options" -- options that set attributes of the Distribution
435
+ instance. Then, it is alternately scanned for Distutils commands
436
+ and options for that command. Each new command terminates the
437
+ options for the previous command. The allowed options for a
438
+ command are determined by the 'user_options' attribute of the
439
+ command class -- thus, we have to be able to load command classes
440
+ in order to parse the command line. Any error in that 'options'
441
+ attribute raises DistutilsGetoptError; any error on the
442
+ command-line raises DistutilsArgError. If no Distutils commands
443
+ were found on the command line, raises DistutilsArgError. Return
444
+ true if command-line was successfully parsed and we should carry
445
+ on with executing commands; false if no errors but we shouldn't
446
+ execute commands (currently, this only happens if user asks for
447
+ help).
448
+ """
449
+ #
450
+ # We now have enough information to show the Macintosh dialog
451
+ # that allows the user to interactively specify the "command line".
452
+ #
453
+ toplevel_options = self._get_toplevel_options()
454
+
455
+ # We have to parse the command line a bit at a time -- global
456
+ # options, then the first command, then its options, and so on --
457
+ # because each command will be handled by a different class, and
458
+ # the options that are valid for a particular class aren't known
459
+ # until we have loaded the command class, which doesn't happen
460
+ # until we know what the command is.
461
+
462
+ self.commands = []
463
+ parser = FancyGetopt(toplevel_options + self.display_options)
464
+ parser.set_negative_aliases(self.negative_opt)
465
+ parser.set_aliases({'licence': 'license'})
466
+ args = parser.getopt(args=self.script_args, object=self)
467
+ option_order = parser.get_option_order()
468
+ log.set_verbosity(self.verbose)
469
+
470
+ # for display options we return immediately
471
+ if self.handle_display_options(option_order):
472
+ return
473
+ while args:
474
+ args = self._parse_command_opts(parser, args)
475
+ if args is None: # user asked for help (and got it)
476
+ return
477
+
478
+ # Handle the cases of --help as a "global" option, ie.
479
+ # "setup.py --help" and "setup.py --help command ...". For the
480
+ # former, we show global options (--verbose, --dry-run, etc.)
481
+ # and display-only options (--name, --version, etc.); for the
482
+ # latter, we omit the display-only options and show help for
483
+ # each command listed on the command line.
484
+ if self.help:
485
+ self._show_help(
486
+ parser, display_options=len(self.commands) == 0, commands=self.commands
487
+ )
488
+ return
489
+
490
+ # Oops, no commands found -- an end-user error
491
+ if not self.commands:
492
+ raise DistutilsArgError("no commands supplied")
493
+
494
+ # All is well: return true
495
+ return True
496
+
497
+ def _get_toplevel_options(self):
498
+ """Return the non-display options recognized at the top level.
499
+
500
+ This includes options that are recognized *only* at the top
501
+ level as well as options recognized for commands.
502
+ """
503
+ return self.global_options + [
504
+ (
505
+ "command-packages=",
506
+ None,
507
+ "list of packages that provide distutils commands",
508
+ ),
509
+ ]
510
+
511
+ def _parse_command_opts(self, parser, args): # noqa: C901
512
+ """Parse the command-line options for a single command.
513
+ 'parser' must be a FancyGetopt instance; 'args' must be the list
514
+ of arguments, starting with the current command (whose options
515
+ we are about to parse). Returns a new version of 'args' with
516
+ the next command at the front of the list; will be the empty
517
+ list if there are no more commands on the command line. Returns
518
+ None if the user asked for help on this command.
519
+ """
520
+ # late import because of mutual dependence between these modules
521
+ from distutils.cmd import Command
522
+
523
+ # Pull the current command from the head of the command line
524
+ command = args[0]
525
+ if not command_re.match(command):
526
+ raise SystemExit("invalid command name '%s'" % command)
527
+ self.commands.append(command)
528
+
529
+ # Dig up the command class that implements this command, so we
530
+ # 1) know that it's a valid command, and 2) know which options
531
+ # it takes.
532
+ try:
533
+ cmd_class = self.get_command_class(command)
534
+ except DistutilsModuleError as msg:
535
+ raise DistutilsArgError(msg)
536
+
537
+ # Require that the command class be derived from Command -- want
538
+ # to be sure that the basic "command" interface is implemented.
539
+ if not issubclass(cmd_class, Command):
540
+ raise DistutilsClassError(
541
+ "command class %s must subclass Command" % cmd_class
542
+ )
543
+
544
+ # Also make sure that the command object provides a list of its
545
+ # known options.
546
+ if not (
547
+ hasattr(cmd_class, 'user_options')
548
+ and isinstance(cmd_class.user_options, list)
549
+ ):
550
+ msg = (
551
+ "command class %s must provide "
552
+ "'user_options' attribute (a list of tuples)"
553
+ )
554
+ raise DistutilsClassError(msg % cmd_class)
555
+
556
+ # If the command class has a list of negative alias options,
557
+ # merge it in with the global negative aliases.
558
+ negative_opt = self.negative_opt
559
+ if hasattr(cmd_class, 'negative_opt'):
560
+ negative_opt = negative_opt.copy()
561
+ negative_opt.update(cmd_class.negative_opt)
562
+
563
+ # Check for help_options in command class. They have a different
564
+ # format (tuple of four) so we need to preprocess them here.
565
+ if hasattr(cmd_class, 'help_options') and isinstance(
566
+ cmd_class.help_options, list
567
+ ):
568
+ help_options = fix_help_options(cmd_class.help_options)
569
+ else:
570
+ help_options = []
571
+
572
+ # All commands support the global options too, just by adding
573
+ # in 'global_options'.
574
+ parser.set_option_table(
575
+ self.global_options + cmd_class.user_options + help_options
576
+ )
577
+ parser.set_negative_aliases(negative_opt)
578
+ (args, opts) = parser.getopt(args[1:])
579
+ if hasattr(opts, 'help') and opts.help:
580
+ self._show_help(parser, display_options=0, commands=[cmd_class])
581
+ return
582
+
583
+ if hasattr(cmd_class, 'help_options') and isinstance(
584
+ cmd_class.help_options, list
585
+ ):
586
+ help_option_found = 0
587
+ for (help_option, short, desc, func) in cmd_class.help_options:
588
+ if hasattr(opts, parser.get_attr_name(help_option)):
589
+ help_option_found = 1
590
+ if callable(func):
591
+ func()
592
+ else:
593
+ raise DistutilsClassError(
594
+ "invalid help function %r for help option '%s': "
595
+ "must be a callable object (function, etc.)"
596
+ % (func, help_option)
597
+ )
598
+
599
+ if help_option_found:
600
+ return
601
+
602
+ # Put the options from the command-line into their official
603
+ # holding pen, the 'command_options' dictionary.
604
+ opt_dict = self.get_option_dict(command)
605
+ for (name, value) in vars(opts).items():
606
+ opt_dict[name] = ("command line", value)
607
+
608
+ return args
609
+
610
+ def finalize_options(self):
611
+ """Set final values for all the options on the Distribution
612
+ instance, analogous to the .finalize_options() method of Command
613
+ objects.
614
+ """
615
+ for attr in ('keywords', 'platforms'):
616
+ value = getattr(self.metadata, attr)
617
+ if value is None:
618
+ continue
619
+ if isinstance(value, str):
620
+ value = [elm.strip() for elm in value.split(',')]
621
+ setattr(self.metadata, attr, value)
622
+
623
+ def _show_help(self, parser, global_options=1, display_options=1, commands=[]):
624
+ """Show help for the setup script command-line in the form of
625
+ several lists of command-line options. 'parser' should be a
626
+ FancyGetopt instance; do not expect it to be returned in the
627
+ same state, as its option table will be reset to make it
628
+ generate the correct help text.
629
+
630
+ If 'global_options' is true, lists the global options:
631
+ --verbose, --dry-run, etc. If 'display_options' is true, lists
632
+ the "display-only" options: --name, --version, etc. Finally,
633
+ lists per-command help for every command name or command class
634
+ in 'commands'.
635
+ """
636
+ # late import because of mutual dependence between these modules
637
+ from distutils.core import gen_usage
638
+ from distutils.cmd import Command
639
+
640
+ if global_options:
641
+ if display_options:
642
+ options = self._get_toplevel_options()
643
+ else:
644
+ options = self.global_options
645
+ parser.set_option_table(options)
646
+ parser.print_help(self.common_usage + "\nGlobal options:")
647
+ print('')
648
+
649
+ if display_options:
650
+ parser.set_option_table(self.display_options)
651
+ parser.print_help(
652
+ "Information display options (just display "
653
+ + "information, ignore any commands)"
654
+ )
655
+ print('')
656
+
657
+ for command in self.commands:
658
+ if isinstance(command, type) and issubclass(command, Command):
659
+ klass = command
660
+ else:
661
+ klass = self.get_command_class(command)
662
+ if hasattr(klass, 'help_options') and isinstance(klass.help_options, list):
663
+ parser.set_option_table(
664
+ klass.user_options + fix_help_options(klass.help_options)
665
+ )
666
+ else:
667
+ parser.set_option_table(klass.user_options)
668
+ parser.print_help("Options for '%s' command:" % klass.__name__)
669
+ print('')
670
+
671
+ print(gen_usage(self.script_name))
672
+
673
+ def handle_display_options(self, option_order):
674
+ """If there were any non-global "display-only" options
675
+ (--help-commands or the metadata display options) on the command
676
+ line, display the requested info and return true; else return
677
+ false.
678
+ """
679
+ from distutils.core import gen_usage
680
+
681
+ # User just wants a list of commands -- we'll print it out and stop
682
+ # processing now (ie. if they ran "setup --help-commands foo bar",
683
+ # we ignore "foo bar").
684
+ if self.help_commands:
685
+ self.print_commands()
686
+ print('')
687
+ print(gen_usage(self.script_name))
688
+ return 1
689
+
690
+ # If user supplied any of the "display metadata" options, then
691
+ # display that metadata in the order in which the user supplied the
692
+ # metadata options.
693
+ any_display_options = 0
694
+ is_display_option = {}
695
+ for option in self.display_options:
696
+ is_display_option[option[0]] = 1
697
+
698
+ for (opt, val) in option_order:
699
+ if val and is_display_option.get(opt):
700
+ opt = translate_longopt(opt)
701
+ value = getattr(self.metadata, "get_" + opt)()
702
+ if opt in ['keywords', 'platforms']:
703
+ print(','.join(value))
704
+ elif opt in ('classifiers', 'provides', 'requires', 'obsoletes'):
705
+ print('\n'.join(value))
706
+ else:
707
+ print(value)
708
+ any_display_options = 1
709
+
710
+ return any_display_options
711
+
712
+ def print_command_list(self, commands, header, max_length):
713
+ """Print a subset of the list of all commands -- used by
714
+ 'print_commands()'.
715
+ """
716
+ print(header + ":")
717
+
718
+ for cmd in commands:
719
+ klass = self.cmdclass.get(cmd)
720
+ if not klass:
721
+ klass = self.get_command_class(cmd)
722
+ try:
723
+ description = klass.description
724
+ except AttributeError:
725
+ description = "(no description available)"
726
+
727
+ print(" %-*s %s" % (max_length, cmd, description))
728
+
729
+ def print_commands(self):
730
+ """Print out a help message listing all available commands with a
731
+ description of each. The list is divided into "standard commands"
732
+ (listed in distutils.command.__all__) and "extra commands"
733
+ (mentioned in self.cmdclass, but not a standard command). The
734
+ descriptions come from the command class attribute
735
+ 'description'.
736
+ """
737
+ import distutils.command
738
+
739
+ std_commands = distutils.command.__all__
740
+ is_std = {}
741
+ for cmd in std_commands:
742
+ is_std[cmd] = 1
743
+
744
+ extra_commands = []
745
+ for cmd in self.cmdclass.keys():
746
+ if not is_std.get(cmd):
747
+ extra_commands.append(cmd)
748
+
749
+ max_length = 0
750
+ for cmd in std_commands + extra_commands:
751
+ if len(cmd) > max_length:
752
+ max_length = len(cmd)
753
+
754
+ self.print_command_list(std_commands, "Standard commands", max_length)
755
+ if extra_commands:
756
+ print()
757
+ self.print_command_list(extra_commands, "Extra commands", max_length)
758
+
759
+ def get_command_list(self):
760
+ """Get a list of (command, description) tuples.
761
+ The list is divided into "standard commands" (listed in
762
+ distutils.command.__all__) and "extra commands" (mentioned in
763
+ self.cmdclass, but not a standard command). The descriptions come
764
+ from the command class attribute 'description'.
765
+ """
766
+ # Currently this is only used on Mac OS, for the Mac-only GUI
767
+ # Distutils interface (by Jack Jansen)
768
+ import distutils.command
769
+
770
+ std_commands = distutils.command.__all__
771
+ is_std = {}
772
+ for cmd in std_commands:
773
+ is_std[cmd] = 1
774
+
775
+ extra_commands = []
776
+ for cmd in self.cmdclass.keys():
777
+ if not is_std.get(cmd):
778
+ extra_commands.append(cmd)
779
+
780
+ rv = []
781
+ for cmd in std_commands + extra_commands:
782
+ klass = self.cmdclass.get(cmd)
783
+ if not klass:
784
+ klass = self.get_command_class(cmd)
785
+ try:
786
+ description = klass.description
787
+ except AttributeError:
788
+ description = "(no description available)"
789
+ rv.append((cmd, description))
790
+ return rv
791
+
792
+ # -- Command class/object methods ----------------------------------
793
+
794
+ def get_command_packages(self):
795
+ """Return a list of packages from which commands are loaded."""
796
+ pkgs = self.command_packages
797
+ if not isinstance(pkgs, list):
798
+ if pkgs is None:
799
+ pkgs = ''
800
+ pkgs = [pkg.strip() for pkg in pkgs.split(',') if pkg != '']
801
+ if "distutils.command" not in pkgs:
802
+ pkgs.insert(0, "distutils.command")
803
+ self.command_packages = pkgs
804
+ return pkgs
805
+
806
+ def get_command_class(self, command):
807
+ """Return the class that implements the Distutils command named by
808
+ 'command'. First we check the 'cmdclass' dictionary; if the
809
+ command is mentioned there, we fetch the class object from the
810
+ dictionary and return it. Otherwise we load the command module
811
+ ("distutils.command." + command) and fetch the command class from
812
+ the module. The loaded class is also stored in 'cmdclass'
813
+ to speed future calls to 'get_command_class()'.
814
+
815
+ Raises DistutilsModuleError if the expected module could not be
816
+ found, or if that module does not define the expected class.
817
+ """
818
+ klass = self.cmdclass.get(command)
819
+ if klass:
820
+ return klass
821
+
822
+ for pkgname in self.get_command_packages():
823
+ module_name = "{}.{}".format(pkgname, command)
824
+ klass_name = command
825
+
826
+ try:
827
+ __import__(module_name)
828
+ module = sys.modules[module_name]
829
+ except ImportError:
830
+ continue
831
+
832
+ try:
833
+ klass = getattr(module, klass_name)
834
+ except AttributeError:
835
+ raise DistutilsModuleError(
836
+ "invalid command '%s' (no class '%s' in module '%s')"
837
+ % (command, klass_name, module_name)
838
+ )
839
+
840
+ self.cmdclass[command] = klass
841
+ return klass
842
+
843
+ raise DistutilsModuleError("invalid command '%s'" % command)
844
+
845
+ def get_command_obj(self, command, create=1):
846
+ """Return the command object for 'command'. Normally this object
847
+ is cached on a previous call to 'get_command_obj()'; if no command
848
+ object for 'command' is in the cache, then we either create and
849
+ return it (if 'create' is true) or return None.
850
+ """
851
+ cmd_obj = self.command_obj.get(command)
852
+ if not cmd_obj and create:
853
+ if DEBUG:
854
+ self.announce(
855
+ "Distribution.get_command_obj(): "
856
+ "creating '%s' command object" % command
857
+ )
858
+
859
+ klass = self.get_command_class(command)
860
+ cmd_obj = self.command_obj[command] = klass(self)
861
+ self.have_run[command] = 0
862
+
863
+ # Set any options that were supplied in config files
864
+ # or on the command line. (NB. support for error
865
+ # reporting is lame here: any errors aren't reported
866
+ # until 'finalize_options()' is called, which means
867
+ # we won't report the source of the error.)
868
+ options = self.command_options.get(command)
869
+ if options:
870
+ self._set_command_options(cmd_obj, options)
871
+
872
+ return cmd_obj
873
+
874
+ def _set_command_options(self, command_obj, option_dict=None): # noqa: C901
875
+ """Set the options for 'command_obj' from 'option_dict'. Basically
876
+ this means copying elements of a dictionary ('option_dict') to
877
+ attributes of an instance ('command').
878
+
879
+ 'command_obj' must be a Command instance. If 'option_dict' is not
880
+ supplied, uses the standard option dictionary for this command
881
+ (from 'self.command_options').
882
+ """
883
+ command_name = command_obj.get_command_name()
884
+ if option_dict is None:
885
+ option_dict = self.get_option_dict(command_name)
886
+
887
+ if DEBUG:
888
+ self.announce(" setting options for '%s' command:" % command_name)
889
+ for (option, (source, value)) in option_dict.items():
890
+ if DEBUG:
891
+ self.announce(" {} = {} (from {})".format(option, value, source))
892
+ try:
893
+ bool_opts = [translate_longopt(o) for o in command_obj.boolean_options]
894
+ except AttributeError:
895
+ bool_opts = []
896
+ try:
897
+ neg_opt = command_obj.negative_opt
898
+ except AttributeError:
899
+ neg_opt = {}
900
+
901
+ try:
902
+ is_string = isinstance(value, str)
903
+ if option in neg_opt and is_string:
904
+ setattr(command_obj, neg_opt[option], not strtobool(value))
905
+ elif option in bool_opts and is_string:
906
+ setattr(command_obj, option, strtobool(value))
907
+ elif hasattr(command_obj, option):
908
+ setattr(command_obj, option, value)
909
+ else:
910
+ raise DistutilsOptionError(
911
+ "error in %s: command '%s' has no such option '%s'"
912
+ % (source, command_name, option)
913
+ )
914
+ except ValueError as msg:
915
+ raise DistutilsOptionError(msg)
916
+
917
+ def reinitialize_command(self, command, reinit_subcommands=0):
918
+ """Reinitializes a command to the state it was in when first
919
+ returned by 'get_command_obj()': ie., initialized but not yet
920
+ finalized. This provides the opportunity to sneak option
921
+ values in programmatically, overriding or supplementing
922
+ user-supplied values from the config files and command line.
923
+ You'll have to re-finalize the command object (by calling
924
+ 'finalize_options()' or 'ensure_finalized()') before using it for
925
+ real.
926
+
927
+ 'command' should be a command name (string) or command object. If
928
+ 'reinit_subcommands' is true, also reinitializes the command's
929
+ sub-commands, as declared by the 'sub_commands' class attribute (if
930
+ it has one). See the "install" command for an example. Only
931
+ reinitializes the sub-commands that actually matter, ie. those
932
+ whose test predicates return true.
933
+
934
+ Returns the reinitialized command object.
935
+ """
936
+ from distutils.cmd import Command
937
+
938
+ if not isinstance(command, Command):
939
+ command_name = command
940
+ command = self.get_command_obj(command_name)
941
+ else:
942
+ command_name = command.get_command_name()
943
+
944
+ if not command.finalized:
945
+ return command
946
+ command.initialize_options()
947
+ command.finalized = 0
948
+ self.have_run[command_name] = 0
949
+ self._set_command_options(command)
950
+
951
+ if reinit_subcommands:
952
+ for sub in command.get_sub_commands():
953
+ self.reinitialize_command(sub, reinit_subcommands)
954
+
955
+ return command
956
+
957
+ # -- Methods that operate on the Distribution ----------------------
958
+
959
+ def announce(self, msg, level=log.INFO):
960
+ log.log(level, msg)
961
+
962
+ def run_commands(self):
963
+ """Run each command that was seen on the setup script command line.
964
+ Uses the list of commands found and cache of command objects
965
+ created by 'get_command_obj()'.
966
+ """
967
+ for cmd in self.commands:
968
+ self.run_command(cmd)
969
+
970
+ # -- Methods that operate on its Commands --------------------------
971
+
972
+ def run_command(self, command):
973
+ """Do whatever it takes to run a command (including nothing at all,
974
+ if the command has already been run). Specifically: if we have
975
+ already created and run the command named by 'command', return
976
+ silently without doing anything. If the command named by 'command'
977
+ doesn't even have a command object yet, create one. Then invoke
978
+ 'run()' on that command object (or an existing one).
979
+ """
980
+ # Already been here, done that? then return silently.
981
+ if self.have_run.get(command):
982
+ return
983
+
984
+ log.info("running %s", command)
985
+ cmd_obj = self.get_command_obj(command)
986
+ cmd_obj.ensure_finalized()
987
+ cmd_obj.run()
988
+ self.have_run[command] = 1
989
+
990
+ # -- Distribution query methods ------------------------------------
991
+
992
+ def has_pure_modules(self):
993
+ return len(self.packages or self.py_modules or []) > 0
994
+
995
+ def has_ext_modules(self):
996
+ return self.ext_modules and len(self.ext_modules) > 0
997
+
998
+ def has_c_libraries(self):
999
+ return self.libraries and len(self.libraries) > 0
1000
+
1001
+ def has_modules(self):
1002
+ return self.has_pure_modules() or self.has_ext_modules()
1003
+
1004
+ def has_headers(self):
1005
+ return self.headers and len(self.headers) > 0
1006
+
1007
+ def has_scripts(self):
1008
+ return self.scripts and len(self.scripts) > 0
1009
+
1010
+ def has_data_files(self):
1011
+ return self.data_files and len(self.data_files) > 0
1012
+
1013
+ def is_pure(self):
1014
+ return (
1015
+ self.has_pure_modules()
1016
+ and not self.has_ext_modules()
1017
+ and not self.has_c_libraries()
1018
+ )
1019
+
1020
+ # -- Metadata query methods ----------------------------------------
1021
+
1022
+ # If you're looking for 'get_name()', 'get_version()', and so forth,
1023
+ # they are defined in a sneaky way: the constructor binds self.get_XXX
1024
+ # to self.metadata.get_XXX. The actual code is in the
1025
+ # DistributionMetadata class, below.
1026
+
1027
+
1028
+ class DistributionMetadata:
1029
+ """Dummy class to hold the distribution meta-data: name, version,
1030
+ author, and so forth.
1031
+ """
1032
+
1033
+ _METHOD_BASENAMES = (
1034
+ "name",
1035
+ "version",
1036
+ "author",
1037
+ "author_email",
1038
+ "maintainer",
1039
+ "maintainer_email",
1040
+ "url",
1041
+ "license",
1042
+ "description",
1043
+ "long_description",
1044
+ "keywords",
1045
+ "platforms",
1046
+ "fullname",
1047
+ "contact",
1048
+ "contact_email",
1049
+ "classifiers",
1050
+ "download_url",
1051
+ # PEP 314
1052
+ "provides",
1053
+ "requires",
1054
+ "obsoletes",
1055
+ )
1056
+
1057
+ def __init__(self, path=None):
1058
+ if path is not None:
1059
+ self.read_pkg_file(open(path))
1060
+ else:
1061
+ self.name = None
1062
+ self.version = None
1063
+ self.author = None
1064
+ self.author_email = None
1065
+ self.maintainer = None
1066
+ self.maintainer_email = None
1067
+ self.url = None
1068
+ self.license = None
1069
+ self.description = None
1070
+ self.long_description = None
1071
+ self.keywords = None
1072
+ self.platforms = None
1073
+ self.classifiers = None
1074
+ self.download_url = None
1075
+ # PEP 314
1076
+ self.provides = None
1077
+ self.requires = None
1078
+ self.obsoletes = None
1079
+
1080
+ def read_pkg_file(self, file):
1081
+ """Reads the metadata values from a file object."""
1082
+ msg = message_from_file(file)
1083
+
1084
+ def _read_field(name):
1085
+ value = msg[name]
1086
+ if value and value != "UNKNOWN":
1087
+ return value
1088
+
1089
+ def _read_list(name):
1090
+ values = msg.get_all(name, None)
1091
+ if values == []:
1092
+ return None
1093
+ return values
1094
+
1095
+ metadata_version = msg['metadata-version']
1096
+ self.name = _read_field('name')
1097
+ self.version = _read_field('version')
1098
+ self.description = _read_field('summary')
1099
+ # we are filling author only.
1100
+ self.author = _read_field('author')
1101
+ self.maintainer = None
1102
+ self.author_email = _read_field('author-email')
1103
+ self.maintainer_email = None
1104
+ self.url = _read_field('home-page')
1105
+ self.license = _read_field('license')
1106
+
1107
+ if 'download-url' in msg:
1108
+ self.download_url = _read_field('download-url')
1109
+ else:
1110
+ self.download_url = None
1111
+
1112
+ self.long_description = _read_field('description')
1113
+ self.description = _read_field('summary')
1114
+
1115
+ if 'keywords' in msg:
1116
+ self.keywords = _read_field('keywords').split(',')
1117
+
1118
+ self.platforms = _read_list('platform')
1119
+ self.classifiers = _read_list('classifier')
1120
+
1121
+ # PEP 314 - these fields only exist in 1.1
1122
+ if metadata_version == '1.1':
1123
+ self.requires = _read_list('requires')
1124
+ self.provides = _read_list('provides')
1125
+ self.obsoletes = _read_list('obsoletes')
1126
+ else:
1127
+ self.requires = None
1128
+ self.provides = None
1129
+ self.obsoletes = None
1130
+
1131
+ def write_pkg_info(self, base_dir):
1132
+ """Write the PKG-INFO file into the release tree."""
1133
+ with open(
1134
+ os.path.join(base_dir, 'PKG-INFO'), 'w', encoding='UTF-8'
1135
+ ) as pkg_info:
1136
+ self.write_pkg_file(pkg_info)
1137
+
1138
+ def write_pkg_file(self, file):
1139
+ """Write the PKG-INFO format data to a file object."""
1140
+ version = '1.0'
1141
+ if (
1142
+ self.provides
1143
+ or self.requires
1144
+ or self.obsoletes
1145
+ or self.classifiers
1146
+ or self.download_url
1147
+ ):
1148
+ version = '1.1'
1149
+
1150
+ # required fields
1151
+ file.write('Metadata-Version: %s\n' % version)
1152
+ file.write('Name: %s\n' % self.get_name())
1153
+ file.write('Version: %s\n' % self.get_version())
1154
+
1155
+ def maybe_write(header, val):
1156
+ if val:
1157
+ file.write(f"{header}: {val}\n")
1158
+
1159
+ # optional fields
1160
+ maybe_write("Summary", self.get_description())
1161
+ maybe_write("Home-page", self.get_url())
1162
+ maybe_write("Author", self.get_contact())
1163
+ maybe_write("Author-email", self.get_contact_email())
1164
+ maybe_write("License", self.get_license())
1165
+ maybe_write("Download-URL", self.download_url)
1166
+ maybe_write("Description", rfc822_escape(self.get_long_description() or ""))
1167
+ maybe_write("Keywords", ",".join(self.get_keywords()))
1168
+
1169
+ self._write_list(file, 'Platform', self.get_platforms())
1170
+ self._write_list(file, 'Classifier', self.get_classifiers())
1171
+
1172
+ # PEP 314
1173
+ self._write_list(file, 'Requires', self.get_requires())
1174
+ self._write_list(file, 'Provides', self.get_provides())
1175
+ self._write_list(file, 'Obsoletes', self.get_obsoletes())
1176
+
1177
+ def _write_list(self, file, name, values):
1178
+ values = values or []
1179
+ for value in values:
1180
+ file.write('{}: {}\n'.format(name, value))
1181
+
1182
+ # -- Metadata query methods ----------------------------------------
1183
+
1184
+ def get_name(self):
1185
+ return self.name or "UNKNOWN"
1186
+
1187
+ def get_version(self):
1188
+ return self.version or "0.0.0"
1189
+
1190
+ def get_fullname(self):
1191
+ return "{}-{}".format(self.get_name(), self.get_version())
1192
+
1193
+ def get_author(self):
1194
+ return self.author
1195
+
1196
+ def get_author_email(self):
1197
+ return self.author_email
1198
+
1199
+ def get_maintainer(self):
1200
+ return self.maintainer
1201
+
1202
+ def get_maintainer_email(self):
1203
+ return self.maintainer_email
1204
+
1205
+ def get_contact(self):
1206
+ return self.maintainer or self.author
1207
+
1208
+ def get_contact_email(self):
1209
+ return self.maintainer_email or self.author_email
1210
+
1211
+ def get_url(self):
1212
+ return self.url
1213
+
1214
+ def get_license(self):
1215
+ return self.license
1216
+
1217
+ get_licence = get_license
1218
+
1219
+ def get_description(self):
1220
+ return self.description
1221
+
1222
+ def get_long_description(self):
1223
+ return self.long_description
1224
+
1225
+ def get_keywords(self):
1226
+ return self.keywords or []
1227
+
1228
+ def set_keywords(self, value):
1229
+ self.keywords = _ensure_list(value, 'keywords')
1230
+
1231
+ def get_platforms(self):
1232
+ return self.platforms
1233
+
1234
+ def set_platforms(self, value):
1235
+ self.platforms = _ensure_list(value, 'platforms')
1236
+
1237
+ def get_classifiers(self):
1238
+ return self.classifiers or []
1239
+
1240
+ def set_classifiers(self, value):
1241
+ self.classifiers = _ensure_list(value, 'classifiers')
1242
+
1243
+ def get_download_url(self):
1244
+ return self.download_url
1245
+
1246
+ # PEP 314
1247
+ def get_requires(self):
1248
+ return self.requires or []
1249
+
1250
+ def set_requires(self, value):
1251
+ import distutils.versionpredicate
1252
+
1253
+ for v in value:
1254
+ distutils.versionpredicate.VersionPredicate(v)
1255
+ self.requires = list(value)
1256
+
1257
+ def get_provides(self):
1258
+ return self.provides or []
1259
+
1260
+ def set_provides(self, value):
1261
+ value = [v.strip() for v in value]
1262
+ for v in value:
1263
+ import distutils.versionpredicate
1264
+
1265
+ distutils.versionpredicate.split_provision(v)
1266
+ self.provides = value
1267
+
1268
+ def get_obsoletes(self):
1269
+ return self.obsoletes or []
1270
+
1271
+ def set_obsoletes(self, value):
1272
+ import distutils.versionpredicate
1273
+
1274
+ for v in value:
1275
+ distutils.versionpredicate.VersionPredicate(v)
1276
+ self.obsoletes = list(value)
1277
+
1278
+
1279
+ def fix_help_options(options):
1280
+ """Convert a 4-tuple 'help_options' list as found in various command
1281
+ classes to the 3-tuple form required by FancyGetopt.
1282
+ """
1283
+ new_options = []
1284
+ for help_tuple in options:
1285
+ new_options.append(help_tuple[0:3])
1286
+ return new_options
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/errors.py ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils.errors
2
+
3
+ Provides exceptions used by the Distutils modules. Note that Distutils
4
+ modules may raise standard exceptions; in particular, SystemExit is
5
+ usually raised for errors that are obviously the end-user's fault
6
+ (eg. bad command-line arguments).
7
+
8
+ This module is safe to use in "from ... import *" mode; it only exports
9
+ symbols whose names start with "Distutils" and end with "Error"."""
10
+
11
+
12
+ class DistutilsError(Exception):
13
+ """The root of all Distutils evil."""
14
+
15
+ pass
16
+
17
+
18
+ class DistutilsModuleError(DistutilsError):
19
+ """Unable to load an expected module, or to find an expected class
20
+ within some module (in particular, command modules and classes)."""
21
+
22
+ pass
23
+
24
+
25
+ class DistutilsClassError(DistutilsError):
26
+ """Some command class (or possibly distribution class, if anyone
27
+ feels a need to subclass Distribution) is found not to be holding
28
+ up its end of the bargain, ie. implementing some part of the
29
+ "command "interface."""
30
+
31
+ pass
32
+
33
+
34
+ class DistutilsGetoptError(DistutilsError):
35
+ """The option table provided to 'fancy_getopt()' is bogus."""
36
+
37
+ pass
38
+
39
+
40
+ class DistutilsArgError(DistutilsError):
41
+ """Raised by fancy_getopt in response to getopt.error -- ie. an
42
+ error in the command line usage."""
43
+
44
+ pass
45
+
46
+
47
+ class DistutilsFileError(DistutilsError):
48
+ """Any problems in the filesystem: expected file not found, etc.
49
+ Typically this is for problems that we detect before OSError
50
+ could be raised."""
51
+
52
+ pass
53
+
54
+
55
+ class DistutilsOptionError(DistutilsError):
56
+ """Syntactic/semantic errors in command options, such as use of
57
+ mutually conflicting options, or inconsistent options,
58
+ badly-spelled values, etc. No distinction is made between option
59
+ values originating in the setup script, the command line, config
60
+ files, or what-have-you -- but if we *know* something originated in
61
+ the setup script, we'll raise DistutilsSetupError instead."""
62
+
63
+ pass
64
+
65
+
66
+ class DistutilsSetupError(DistutilsError):
67
+ """For errors that can be definitely blamed on the setup script,
68
+ such as invalid keyword arguments to 'setup()'."""
69
+
70
+ pass
71
+
72
+
73
+ class DistutilsPlatformError(DistutilsError):
74
+ """We don't know how to do something on the current platform (but
75
+ we do know how to do it on some platform) -- eg. trying to compile
76
+ C files on a platform not supported by a CCompiler subclass."""
77
+
78
+ pass
79
+
80
+
81
+ class DistutilsExecError(DistutilsError):
82
+ """Any problems executing an external program (such as the C
83
+ compiler, when compiling C files)."""
84
+
85
+ pass
86
+
87
+
88
+ class DistutilsInternalError(DistutilsError):
89
+ """Internal inconsistencies or impossibilities (obviously, this
90
+ should never be seen if the code is working!)."""
91
+
92
+ pass
93
+
94
+
95
+ class DistutilsTemplateError(DistutilsError):
96
+ """Syntax error in a file list template."""
97
+
98
+
99
+ class DistutilsByteCompileError(DistutilsError):
100
+ """Byte compile error."""
101
+
102
+
103
+ # Exception classes used by the CCompiler implementation classes
104
+ class CCompilerError(Exception):
105
+ """Some compile/link operation failed."""
106
+
107
+
108
+ class PreprocessError(CCompilerError):
109
+ """Failure to preprocess one or more C/C++ files."""
110
+
111
+
112
+ class CompileError(CCompilerError):
113
+ """Failure to compile one or more C/C++ source files."""
114
+
115
+
116
+ class LibError(CCompilerError):
117
+ """Failure to create a static library from one or more C/C++ object
118
+ files."""
119
+
120
+
121
+ class LinkError(CCompilerError):
122
+ """Failure to link one or more C/C++ object files into an executable
123
+ or shared library file."""
124
+
125
+
126
+ class UnknownFileError(CCompilerError):
127
+ """Attempt to process an unknown file type."""
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/extension.py ADDED
@@ -0,0 +1,248 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils.extension
2
+
3
+ Provides the Extension class, used to describe C/C++ extension
4
+ modules in setup scripts."""
5
+
6
+ import os
7
+ import warnings
8
+
9
+ # This class is really only used by the "build_ext" command, so it might
10
+ # make sense to put it in distutils.command.build_ext. However, that
11
+ # module is already big enough, and I want to make this class a bit more
12
+ # complex to simplify some common cases ("foo" module in "foo.c") and do
13
+ # better error-checking ("foo.c" actually exists).
14
+ #
15
+ # Also, putting this in build_ext.py means every setup script would have to
16
+ # import that large-ish module (indirectly, through distutils.core) in
17
+ # order to do anything.
18
+
19
+
20
+ class Extension:
21
+ """Just a collection of attributes that describes an extension
22
+ module and everything needed to build it (hopefully in a portable
23
+ way, but there are hooks that let you be as unportable as you need).
24
+
25
+ Instance attributes:
26
+ name : string
27
+ the full name of the extension, including any packages -- ie.
28
+ *not* a filename or pathname, but Python dotted name
29
+ sources : [string]
30
+ list of source filenames, relative to the distribution root
31
+ (where the setup script lives), in Unix form (slash-separated)
32
+ for portability. Source files may be C, C++, SWIG (.i),
33
+ platform-specific resource files, or whatever else is recognized
34
+ by the "build_ext" command as source for a Python extension.
35
+ include_dirs : [string]
36
+ list of directories to search for C/C++ header files (in Unix
37
+ form for portability)
38
+ define_macros : [(name : string, value : string|None)]
39
+ list of macros to define; each macro is defined using a 2-tuple,
40
+ where 'value' is either the string to define it to or None to
41
+ define it without a particular value (equivalent of "#define
42
+ FOO" in source or -DFOO on Unix C compiler command line)
43
+ undef_macros : [string]
44
+ list of macros to undefine explicitly
45
+ library_dirs : [string]
46
+ list of directories to search for C/C++ libraries at link time
47
+ libraries : [string]
48
+ list of library names (not filenames or paths) to link against
49
+ runtime_library_dirs : [string]
50
+ list of directories to search for C/C++ libraries at run time
51
+ (for shared extensions, this is when the extension is loaded)
52
+ extra_objects : [string]
53
+ list of extra files to link with (eg. object files not implied
54
+ by 'sources', static library that must be explicitly specified,
55
+ binary resource files, etc.)
56
+ extra_compile_args : [string]
57
+ any extra platform- and compiler-specific information to use
58
+ when compiling the source files in 'sources'. For platforms and
59
+ compilers where "command line" makes sense, this is typically a
60
+ list of command-line arguments, but for other platforms it could
61
+ be anything.
62
+ extra_link_args : [string]
63
+ any extra platform- and compiler-specific information to use
64
+ when linking object files together to create the extension (or
65
+ to create a new static Python interpreter). Similar
66
+ interpretation as for 'extra_compile_args'.
67
+ export_symbols : [string]
68
+ list of symbols to be exported from a shared extension. Not
69
+ used on all platforms, and not generally necessary for Python
70
+ extensions, which typically export exactly one symbol: "init" +
71
+ extension_name.
72
+ swig_opts : [string]
73
+ any extra options to pass to SWIG if a source file has the .i
74
+ extension.
75
+ depends : [string]
76
+ list of files that the extension depends on
77
+ language : string
78
+ extension language (i.e. "c", "c++", "objc"). Will be detected
79
+ from the source extensions if not provided.
80
+ optional : boolean
81
+ specifies that a build failure in the extension should not abort the
82
+ build process, but simply not install the failing extension.
83
+ """
84
+
85
+ # When adding arguments to this constructor, be sure to update
86
+ # setup_keywords in core.py.
87
+ def __init__(
88
+ self,
89
+ name,
90
+ sources,
91
+ include_dirs=None,
92
+ define_macros=None,
93
+ undef_macros=None,
94
+ library_dirs=None,
95
+ libraries=None,
96
+ runtime_library_dirs=None,
97
+ extra_objects=None,
98
+ extra_compile_args=None,
99
+ extra_link_args=None,
100
+ export_symbols=None,
101
+ swig_opts=None,
102
+ depends=None,
103
+ language=None,
104
+ optional=None,
105
+ **kw # To catch unknown keywords
106
+ ):
107
+ if not isinstance(name, str):
108
+ raise AssertionError("'name' must be a string")
109
+ if not (isinstance(sources, list) and all(isinstance(v, str) for v in sources)):
110
+ raise AssertionError("'sources' must be a list of strings")
111
+
112
+ self.name = name
113
+ self.sources = sources
114
+ self.include_dirs = include_dirs or []
115
+ self.define_macros = define_macros or []
116
+ self.undef_macros = undef_macros or []
117
+ self.library_dirs = library_dirs or []
118
+ self.libraries = libraries or []
119
+ self.runtime_library_dirs = runtime_library_dirs or []
120
+ self.extra_objects = extra_objects or []
121
+ self.extra_compile_args = extra_compile_args or []
122
+ self.extra_link_args = extra_link_args or []
123
+ self.export_symbols = export_symbols or []
124
+ self.swig_opts = swig_opts or []
125
+ self.depends = depends or []
126
+ self.language = language
127
+ self.optional = optional
128
+
129
+ # If there are unknown keyword options, warn about them
130
+ if len(kw) > 0:
131
+ options = [repr(option) for option in kw]
132
+ options = ', '.join(sorted(options))
133
+ msg = "Unknown Extension options: %s" % options
134
+ warnings.warn(msg)
135
+
136
+ def __repr__(self):
137
+ return '<{}.{}({!r}) at {:#x}>'.format(
138
+ self.__class__.__module__,
139
+ self.__class__.__qualname__,
140
+ self.name,
141
+ id(self),
142
+ )
143
+
144
+
145
+ def read_setup_file(filename): # noqa: C901
146
+ """Reads a Setup file and returns Extension instances."""
147
+ from distutils.sysconfig import parse_makefile, expand_makefile_vars, _variable_rx
148
+
149
+ from distutils.text_file import TextFile
150
+ from distutils.util import split_quoted
151
+
152
+ # First pass over the file to gather "VAR = VALUE" assignments.
153
+ vars = parse_makefile(filename)
154
+
155
+ # Second pass to gobble up the real content: lines of the form
156
+ # <module> ... [<sourcefile> ...] [<cpparg> ...] [<library> ...]
157
+ file = TextFile(
158
+ filename,
159
+ strip_comments=1,
160
+ skip_blanks=1,
161
+ join_lines=1,
162
+ lstrip_ws=1,
163
+ rstrip_ws=1,
164
+ )
165
+ try:
166
+ extensions = []
167
+
168
+ while True:
169
+ line = file.readline()
170
+ if line is None: # eof
171
+ break
172
+ if _variable_rx.match(line): # VAR=VALUE, handled in first pass
173
+ continue
174
+
175
+ if line[0] == line[-1] == "*":
176
+ file.warn("'%s' lines not handled yet" % line)
177
+ continue
178
+
179
+ line = expand_makefile_vars(line, vars)
180
+ words = split_quoted(line)
181
+
182
+ # NB. this parses a slightly different syntax than the old
183
+ # makesetup script: here, there must be exactly one extension per
184
+ # line, and it must be the first word of the line. I have no idea
185
+ # why the old syntax supported multiple extensions per line, as
186
+ # they all wind up being the same.
187
+
188
+ module = words[0]
189
+ ext = Extension(module, [])
190
+ append_next_word = None
191
+
192
+ for word in words[1:]:
193
+ if append_next_word is not None:
194
+ append_next_word.append(word)
195
+ append_next_word = None
196
+ continue
197
+
198
+ suffix = os.path.splitext(word)[1]
199
+ switch = word[0:2]
200
+ value = word[2:]
201
+
202
+ if suffix in (".c", ".cc", ".cpp", ".cxx", ".c++", ".m", ".mm"):
203
+ # hmm, should we do something about C vs. C++ sources?
204
+ # or leave it up to the CCompiler implementation to
205
+ # worry about?
206
+ ext.sources.append(word)
207
+ elif switch == "-I":
208
+ ext.include_dirs.append(value)
209
+ elif switch == "-D":
210
+ equals = value.find("=")
211
+ if equals == -1: # bare "-DFOO" -- no value
212
+ ext.define_macros.append((value, None))
213
+ else: # "-DFOO=blah"
214
+ ext.define_macros.append((value[0:equals], value[equals + 2 :]))
215
+ elif switch == "-U":
216
+ ext.undef_macros.append(value)
217
+ elif switch == "-C": # only here 'cause makesetup has it!
218
+ ext.extra_compile_args.append(word)
219
+ elif switch == "-l":
220
+ ext.libraries.append(value)
221
+ elif switch == "-L":
222
+ ext.library_dirs.append(value)
223
+ elif switch == "-R":
224
+ ext.runtime_library_dirs.append(value)
225
+ elif word == "-rpath":
226
+ append_next_word = ext.runtime_library_dirs
227
+ elif word == "-Xlinker":
228
+ append_next_word = ext.extra_link_args
229
+ elif word == "-Xcompiler":
230
+ append_next_word = ext.extra_compile_args
231
+ elif switch == "-u":
232
+ ext.extra_link_args.append(word)
233
+ if not value:
234
+ append_next_word = ext.extra_link_args
235
+ elif suffix in (".a", ".so", ".sl", ".o", ".dylib"):
236
+ # NB. a really faithful emulation of makesetup would
237
+ # append a .o file to extra_objects only if it
238
+ # had a slash in it; otherwise, it would s/.o/.c/
239
+ # and append it to sources. Hmmmm.
240
+ ext.extra_objects.append(word)
241
+ else:
242
+ file.warn("unrecognized argument '%s'" % word)
243
+
244
+ extensions.append(ext)
245
+ finally:
246
+ file.close()
247
+
248
+ return extensions
ACE_plus/flashenv/lib/python3.10/site-packages/setuptools/_distutils/fancy_getopt.py ADDED
@@ -0,0 +1,470 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """distutils.fancy_getopt
2
+
3
+ Wrapper around the standard getopt module that provides the following
4
+ additional features:
5
+ * short and long options are tied together
6
+ * options have help strings, so fancy_getopt could potentially
7
+ create a complete usage summary
8
+ * options set attributes of a passed-in object
9
+ """
10
+
11
+ import sys
12
+ import string
13
+ import re
14
+ import getopt
15
+ from distutils.errors import DistutilsGetoptError, DistutilsArgError
16
+
17
+ # Much like command_re in distutils.core, this is close to but not quite
18
+ # the same as a Python NAME -- except, in the spirit of most GNU
19
+ # utilities, we use '-' in place of '_'. (The spirit of LISP lives on!)
20
+ # The similarities to NAME are again not a coincidence...
21
+ longopt_pat = r'[a-zA-Z](?:[a-zA-Z0-9-]*)'
22
+ longopt_re = re.compile(r'^%s$' % longopt_pat)
23
+
24
+ # For recognizing "negative alias" options, eg. "quiet=!verbose"
25
+ neg_alias_re = re.compile("^({})=!({})$".format(longopt_pat, longopt_pat))
26
+
27
+ # This is used to translate long options to legitimate Python identifiers
28
+ # (for use as attributes of some object).
29
+ longopt_xlate = str.maketrans('-', '_')
30
+
31
+
32
+ class FancyGetopt:
33
+ """Wrapper around the standard 'getopt()' module that provides some
34
+ handy extra functionality:
35
+ * short and long options are tied together
36
+ * options have help strings, and help text can be assembled
37
+ from them
38
+ * options set attributes of a passed-in object
39
+ * boolean options can have "negative aliases" -- eg. if
40
+ --quiet is the "negative alias" of --verbose, then "--quiet"
41
+ on the command line sets 'verbose' to false
42
+ """
43
+
44
+ def __init__(self, option_table=None):
45
+ # The option table is (currently) a list of tuples. The
46
+ # tuples may have 3 or four values:
47
+ # (long_option, short_option, help_string [, repeatable])
48
+ # if an option takes an argument, its long_option should have '='
49
+ # appended; short_option should just be a single character, no ':'
50
+ # in any case. If a long_option doesn't have a corresponding
51
+ # short_option, short_option should be None. All option tuples
52
+ # must have long options.
53
+ self.option_table = option_table
54
+
55
+ # 'option_index' maps long option names to entries in the option
56
+ # table (ie. those 3-tuples).
57
+ self.option_index = {}
58
+ if self.option_table:
59
+ self._build_index()
60
+
61
+ # 'alias' records (duh) alias options; {'foo': 'bar'} means
62
+ # --foo is an alias for --bar
63
+ self.alias = {}
64
+
65
+ # 'negative_alias' keeps track of options that are the boolean
66
+ # opposite of some other option
67
+ self.negative_alias = {}
68
+
69
+ # These keep track of the information in the option table. We
70
+ # don't actually populate these structures until we're ready to
71
+ # parse the command-line, since the 'option_table' passed in here
72
+ # isn't necessarily the final word.
73
+ self.short_opts = []
74
+ self.long_opts = []
75
+ self.short2long = {}
76
+ self.attr_name = {}
77
+ self.takes_arg = {}
78
+
79
+ # And 'option_order' is filled up in 'getopt()'; it records the
80
+ # original order of options (and their values) on the command-line,
81
+ # but expands short options, converts aliases, etc.
82
+ self.option_order = []
83
+
84
+ def _build_index(self):
85
+ self.option_index.clear()
86
+ for option in self.option_table:
87
+ self.option_index[option[0]] = option
88
+
89
+ def set_option_table(self, option_table):
90
+ self.option_table = option_table
91
+ self._build_index()
92
+
93
+ def add_option(self, long_option, short_option=None, help_string=None):
94
+ if long_option in self.option_index:
95
+ raise DistutilsGetoptError(
96
+ "option conflict: already an option '%s'" % long_option
97
+ )
98
+ else:
99
+ option = (long_option, short_option, help_string)
100
+ self.option_table.append(option)
101
+ self.option_index[long_option] = option
102
+
103
+ def has_option(self, long_option):
104
+ """Return true if the option table for this parser has an
105
+ option with long name 'long_option'."""
106
+ return long_option in self.option_index
107
+
108
+ def get_attr_name(self, long_option):
109
+ """Translate long option name 'long_option' to the form it
110
+ has as an attribute of some object: ie., translate hyphens
111
+ to underscores."""
112
+ return long_option.translate(longopt_xlate)
113
+
114
+ def _check_alias_dict(self, aliases, what):
115
+ assert isinstance(aliases, dict)
116
+ for (alias, opt) in aliases.items():
117
+ if alias not in self.option_index:
118
+ raise DistutilsGetoptError(
119
+ ("invalid %s '%s': " "option '%s' not defined")
120
+ % (what, alias, alias)
121
+ )
122
+ if opt not in self.option_index:
123
+ raise DistutilsGetoptError(
124
+ ("invalid %s '%s': " "aliased option '%s' not defined")
125
+ % (what, alias, opt)
126
+ )
127
+
128
+ def set_aliases(self, alias):
129
+ """Set the aliases for this option parser."""
130
+ self._check_alias_dict(alias, "alias")
131
+ self.alias = alias
132
+
133
+ def set_negative_aliases(self, negative_alias):
134
+ """Set the negative aliases for this option parser.
135
+ 'negative_alias' should be a dictionary mapping option names to
136
+ option names, both the key and value must already be defined
137
+ in the option table."""
138
+ self._check_alias_dict(negative_alias, "negative alias")
139
+ self.negative_alias = negative_alias
140
+
141
+ def _grok_option_table(self): # noqa: C901
142
+ """Populate the various data structures that keep tabs on the
143
+ option table. Called by 'getopt()' before it can do anything
144
+ worthwhile.
145
+ """
146
+ self.long_opts = []
147
+ self.short_opts = []
148
+ self.short2long.clear()
149
+ self.repeat = {}
150
+
151
+ for option in self.option_table:
152
+ if len(option) == 3:
153
+ long, short, help = option
154
+ repeat = 0
155
+ elif len(option) == 4:
156
+ long, short, help, repeat = option
157
+ else:
158
+ # the option table is part of the code, so simply
159
+ # assert that it is correct
160
+ raise ValueError("invalid option tuple: {!r}".format(option))
161
+
162
+ # Type- and value-check the option names
163
+ if not isinstance(long, str) or len(long) < 2:
164
+ raise DistutilsGetoptError(
165
+ ("invalid long option '%s': " "must be a string of length >= 2")
166
+ % long
167
+ )
168
+
169
+ if not ((short is None) or (isinstance(short, str) and len(short) == 1)):
170
+ raise DistutilsGetoptError(
171
+ "invalid short option '%s': "
172
+ "must a single character or None" % short
173
+ )
174
+
175
+ self.repeat[long] = repeat
176
+ self.long_opts.append(long)
177
+
178
+ if long[-1] == '=': # option takes an argument?
179
+ if short:
180
+ short = short + ':'
181
+ long = long[0:-1]
182
+ self.takes_arg[long] = 1
183
+ else:
184
+ # Is option is a "negative alias" for some other option (eg.
185
+ # "quiet" == "!verbose")?
186
+ alias_to = self.negative_alias.get(long)
187
+ if alias_to is not None:
188
+ if self.takes_arg[alias_to]:
189
+ raise DistutilsGetoptError(
190
+ "invalid negative alias '%s': "
191
+ "aliased option '%s' takes a value" % (long, alias_to)
192
+ )
193
+
194
+ self.long_opts[-1] = long # XXX redundant?!
195
+ self.takes_arg[long] = 0
196
+
197
+ # If this is an alias option, make sure its "takes arg" flag is
198
+ # the same as the option it's aliased to.
199
+ alias_to = self.alias.get(long)
200
+ if alias_to is not None:
201
+ if self.takes_arg[long] != self.takes_arg[alias_to]:
202
+ raise DistutilsGetoptError(
203
+ "invalid alias '%s': inconsistent with "
204
+ "aliased option '%s' (one of them takes a value, "
205
+ "the other doesn't" % (long, alias_to)
206
+ )
207
+
208
+ # Now enforce some bondage on the long option name, so we can
209
+ # later translate it to an attribute name on some object. Have
210
+ # to do this a bit late to make sure we've removed any trailing
211
+ # '='.
212
+ if not longopt_re.match(long):
213
+ raise DistutilsGetoptError(
214
+ "invalid long option name '%s' "
215
+ "(must be letters, numbers, hyphens only" % long
216
+ )
217
+
218
+ self.attr_name[long] = self.get_attr_name(long)
219
+ if short:
220
+ self.short_opts.append(short)
221
+ self.short2long[short[0]] = long
222
+
223
+ def getopt(self, args=None, object=None): # noqa: C901
224
+ """Parse command-line options in args. Store as attributes on object.
225
+
226
+ If 'args' is None or not supplied, uses 'sys.argv[1:]'. If
227
+ 'object' is None or not supplied, creates a new OptionDummy
228
+ object, stores option values there, and returns a tuple (args,
229
+ object). If 'object' is supplied, it is modified in place and
230
+ 'getopt()' just returns 'args'; in both cases, the returned
231
+ 'args' is a modified copy of the passed-in 'args' list, which
232
+ is left untouched.
233
+ """
234
+ if args is None:
235
+ args = sys.argv[1:]
236
+ if object is None:
237
+ object = OptionDummy()
238
+ created_object = True
239
+ else:
240
+ created_object = False
241
+
242
+ self._grok_option_table()
243
+
244
+ short_opts = ' '.join(self.short_opts)
245
+ try:
246
+ opts, args = getopt.getopt(args, short_opts, self.long_opts)
247
+ except getopt.error as msg:
248
+ raise DistutilsArgError(msg)
249
+
250
+ for opt, val in opts:
251
+ if len(opt) == 2 and opt[0] == '-': # it's a short option
252
+ opt = self.short2long[opt[1]]
253
+ else:
254
+ assert len(opt) > 2 and opt[:2] == '--'
255
+ opt = opt[2:]
256
+
257
+ alias = self.alias.get(opt)
258
+ if alias:
259
+ opt = alias
260
+
261
+ if not self.takes_arg[opt]: # boolean option?
262
+ assert val == '', "boolean option can't have value"
263
+ alias = self.negative_alias.get(opt)
264
+ if alias:
265
+ opt = alias
266
+ val = 0
267
+ else:
268
+ val = 1
269
+
270
+ attr = self.attr_name[opt]
271
+ # The only repeating option at the moment is 'verbose'.
272
+ # It has a negative option -q quiet, which should set verbose = 0.
273
+ if val and self.repeat.get(attr) is not None:
274
+ val = getattr(object, attr, 0) + 1
275
+ setattr(object, attr, val)
276
+ self.option_order.append((opt, val))
277
+
278
+ # for opts
279
+ if created_object:
280
+ return args, object
281
+ else:
282
+ return args
283
+
284
+ def get_option_order(self):
285
+ """Returns the list of (option, value) tuples processed by the
286
+ previous run of 'getopt()'. Raises RuntimeError if
287
+ 'getopt()' hasn't been called yet.
288
+ """
289
+ if self.option_order is None:
290
+ raise RuntimeError("'getopt()' hasn't been called yet")
291
+ else:
292
+ return self.option_order
293
+
294
+ def generate_help(self, header=None): # noqa: C901
295
+ """Generate help text (a list of strings, one per suggested line of
296
+ output) from the option table for this FancyGetopt object.
297
+ """
298
+ # Blithely assume the option table is good: probably wouldn't call
299
+ # 'generate_help()' unless you've already called 'getopt()'.
300
+
301
+ # First pass: determine maximum length of long option names
302
+ max_opt = 0
303
+ for option in self.option_table:
304
+ long = option[0]
305
+ short = option[1]
306
+ ell = len(long)
307
+ if long[-1] == '=':
308
+ ell = ell - 1
309
+ if short is not None:
310
+ ell = ell + 5 # " (-x)" where short == 'x'
311
+ if ell > max_opt:
312
+ max_opt = ell
313
+
314
+ opt_width = max_opt + 2 + 2 + 2 # room for indent + dashes + gutter
315
+
316
+ # Typical help block looks like this:
317
+ # --foo controls foonabulation
318
+ # Help block for longest option looks like this:
319
+ # --flimflam set the flim-flam level
320
+ # and with wrapped text:
321
+ # --flimflam set the flim-flam level (must be between
322
+ # 0 and 100, except on Tuesdays)
323
+ # Options with short names will have the short name shown (but
324
+ # it doesn't contribute to max_opt):
325
+ # --foo (-f) controls foonabulation
326
+ # If adding the short option would make the left column too wide,
327
+ # we push the explanation off to the next line
328
+ # --flimflam (-l)
329
+ # set the flim-flam level
330
+ # Important parameters:
331
+ # - 2 spaces before option block start lines
332
+ # - 2 dashes for each long option name
333
+ # - min. 2 spaces between option and explanation (gutter)
334
+ # - 5 characters (incl. space) for short option name
335
+
336
+ # Now generate lines of help text. (If 80 columns were good enough
337
+ # for Jesus, then 78 columns are good enough for me!)
338
+ line_width = 78
339
+ text_width = line_width - opt_width
340
+ big_indent = ' ' * opt_width
341
+ if header:
342
+ lines = [header]
343
+ else:
344
+ lines = ['Option summary:']
345
+
346
+ for option in self.option_table:
347
+ long, short, help = option[:3]
348
+ text = wrap_text(help, text_width)
349
+ if long[-1] == '=':
350
+ long = long[0:-1]
351
+
352
+ # Case 1: no short option at all (makes life easy)
353
+ if short is None:
354
+ if text:
355
+ lines.append(" --%-*s %s" % (max_opt, long, text[0]))
356
+ else:
357
+ lines.append(" --%-*s " % (max_opt, long))
358
+
359
+ # Case 2: we have a short option, so we have to include it
360
+ # just after the long option
361
+ else:
362
+ opt_names = "{} (-{})".format(long, short)
363
+ if text:
364
+ lines.append(" --%-*s %s" % (max_opt, opt_names, text[0]))
365
+ else:
366
+ lines.append(" --%-*s" % opt_names)
367
+
368
+ for ell in text[1:]:
369
+ lines.append(big_indent + ell)
370
+ return lines
371
+
372
+ def print_help(self, header=None, file=None):
373
+ if file is None:
374
+ file = sys.stdout
375
+ for line in self.generate_help(header):
376
+ file.write(line + "\n")
377
+
378
+
379
+ def fancy_getopt(options, negative_opt, object, args):
380
+ parser = FancyGetopt(options)
381
+ parser.set_negative_aliases(negative_opt)
382
+ return parser.getopt(args, object)
383
+
384
+
385
+ WS_TRANS = {ord(_wschar): ' ' for _wschar in string.whitespace}
386
+
387
+
388
+ def wrap_text(text, width):
389
+ """wrap_text(text : string, width : int) -> [string]
390
+
391
+ Split 'text' into multiple lines of no more than 'width' characters
392
+ each, and return the list of strings that results.
393
+ """
394
+ if text is None:
395
+ return []
396
+ if len(text) <= width:
397
+ return [text]
398
+
399
+ text = text.expandtabs()
400
+ text = text.translate(WS_TRANS)
401
+ chunks = re.split(r'( +|-+)', text)
402
+ chunks = [ch for ch in chunks if ch] # ' - ' results in empty strings
403
+ lines = []
404
+
405
+ while chunks:
406
+ cur_line = [] # list of chunks (to-be-joined)
407
+ cur_len = 0 # length of current line
408
+
409
+ while chunks:
410
+ ell = len(chunks[0])
411
+ if cur_len + ell <= width: # can squeeze (at least) this chunk in
412
+ cur_line.append(chunks[0])
413
+ del chunks[0]
414
+ cur_len = cur_len + ell
415
+ else: # this line is full
416
+ # drop last chunk if all space
417
+ if cur_line and cur_line[-1][0] == ' ':
418
+ del cur_line[-1]
419
+ break
420
+
421
+ if chunks: # any chunks left to process?
422
+ # if the current line is still empty, then we had a single
423
+ # chunk that's too big too fit on a line -- so we break
424
+ # down and break it up at the line width
425
+ if cur_len == 0:
426
+ cur_line.append(chunks[0][0:width])
427
+ chunks[0] = chunks[0][width:]
428
+
429
+ # all-whitespace chunks at the end of a line can be discarded
430
+ # (and we know from the re.split above that if a chunk has
431
+ # *any* whitespace, it is *all* whitespace)
432
+ if chunks[0][0] == ' ':
433
+ del chunks[0]
434
+
435
+ # and store this line in the list-of-all-lines -- as a single
436
+ # string, of course!
437
+ lines.append(''.join(cur_line))
438
+
439
+ return lines
440
+
441
+
442
+ def translate_longopt(opt):
443
+ """Convert a long option name to a valid Python identifier by
444
+ changing "-" to "_".
445
+ """
446
+ return opt.translate(longopt_xlate)
447
+
448
+
449
+ class OptionDummy:
450
+ """Dummy class just used as a place to hold command-line option
451
+ values as instance attributes."""
452
+
453
+ def __init__(self, options=[]):
454
+ """Create a new OptionDummy instance. The attributes listed in
455
+ 'options' will be initialized to None."""
456
+ for opt in options:
457
+ setattr(self, opt, None)
458
+
459
+
460
+ if __name__ == "__main__":
461
+ text = """\
462
+ Tra-la-la, supercalifragilisticexpialidocious.
463
+ How *do* you spell that odd word, anyways?
464
+ (Someone ask Mary -- she'll know [or she'll
465
+ say, "How should I know?"].)"""
466
+
467
+ for w in (10, 20, 30, 40):
468
+ print("width: %d" % w)
469
+ print("\n".join(wrap_text(text, w)))
470
+ print()