ยปCore Development>Code coverage>Lib/distutils/core.py

Python code coverage for Lib/distutils/core.py

#countcontent
1n/a"""distutils.core
2n/a
3n/aThe only module that needs to be imported to use the Distutils; provides
4n/athe 'setup' function (which is to be called from the setup script). Also
5n/aindirectly provides the Distribution and Command classes, although they are
6n/areally defined in distutils.dist and distutils.cmd.
7n/a"""
8n/a
9n/aimport os
10n/aimport sys
11n/a
12n/afrom distutils.debug import DEBUG
13n/afrom distutils.errors import *
14n/a
15n/a# Mainly import these so setup scripts can "from distutils.core import" them.
16n/afrom distutils.dist import Distribution
17n/afrom distutils.cmd import Command
18n/afrom distutils.config import PyPIRCCommand
19n/afrom distutils.extension import Extension
20n/a
21n/a# This is a barebones help message generated displayed when the user
22n/a# runs the setup script with no arguments at all. More useful help
23n/a# is generated with various --help options: global help, list commands,
24n/a# and per-command help.
25n/aUSAGE = """\
26n/ausage: %(script)s [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
27n/a or: %(script)s --help [cmd1 cmd2 ...]
28n/a or: %(script)s --help-commands
29n/a or: %(script)s cmd --help
30n/a"""
31n/a
32n/adef gen_usage (script_name):
33n/a script = os.path.basename(script_name)
34n/a return USAGE % vars()
35n/a
36n/a
37n/a# Some mild magic to control the behaviour of 'setup()' from 'run_setup()'.
38n/a_setup_stop_after = None
39n/a_setup_distribution = None
40n/a
41n/a# Legal keyword arguments for the setup() function
42n/asetup_keywords = ('distclass', 'script_name', 'script_args', 'options',
43n/a 'name', 'version', 'author', 'author_email',
44n/a 'maintainer', 'maintainer_email', 'url', 'license',
45n/a 'description', 'long_description', 'keywords',
46n/a 'platforms', 'classifiers', 'download_url',
47n/a 'requires', 'provides', 'obsoletes',
48n/a )
49n/a
50n/a# Legal keyword arguments for the Extension constructor
51n/aextension_keywords = ('name', 'sources', 'include_dirs',
52n/a 'define_macros', 'undef_macros',
53n/a 'library_dirs', 'libraries', 'runtime_library_dirs',
54n/a 'extra_objects', 'extra_compile_args', 'extra_link_args',
55n/a 'swig_opts', 'export_symbols', 'depends', 'language')
56n/a
57n/adef setup (**attrs):
58n/a """The gateway to the Distutils: do everything your setup script needs
59n/a to do, in a highly flexible and user-driven way. Briefly: create a
60n/a Distribution instance; find and parse config files; parse the command
61n/a line; run each Distutils command found there, customized by the options
62n/a supplied to 'setup()' (as keyword arguments), in config files, and on
63n/a the command line.
64n/a
65n/a The Distribution instance might be an instance of a class supplied via
66n/a the 'distclass' keyword argument to 'setup'; if no such class is
67n/a supplied, then the Distribution class (in dist.py) is instantiated.
68n/a All other arguments to 'setup' (except for 'cmdclass') are used to set
69n/a attributes of the Distribution instance.
70n/a
71n/a The 'cmdclass' argument, if supplied, is a dictionary mapping command
72n/a names to command classes. Each command encountered on the command line
73n/a will be turned into a command class, which is in turn instantiated; any
74n/a class found in 'cmdclass' is used in place of the default, which is
75n/a (for command 'foo_bar') class 'foo_bar' in module
76n/a 'distutils.command.foo_bar'. The command class must provide a
77n/a 'user_options' attribute which is a list of option specifiers for
78n/a 'distutils.fancy_getopt'. Any command-line options between the current
79n/a and the next command are used to set attributes of the current command
80n/a object.
81n/a
82n/a When the entire command-line has been successfully parsed, calls the
83n/a 'run()' method on each command object in turn. This method will be
84n/a driven entirely by the Distribution object (which each command object
85n/a has a reference to, thanks to its constructor), and the
86n/a command-specific options that became attributes of each command
87n/a object.
88n/a """
89n/a
90n/a global _setup_stop_after, _setup_distribution
91n/a
92n/a # Determine the distribution class -- either caller-supplied or
93n/a # our Distribution (see below).
94n/a klass = attrs.get('distclass')
95n/a if klass:
96n/a del attrs['distclass']
97n/a else:
98n/a klass = Distribution
99n/a
100n/a if 'script_name' not in attrs:
101n/a attrs['script_name'] = os.path.basename(sys.argv[0])
102n/a if 'script_args' not in attrs:
103n/a attrs['script_args'] = sys.argv[1:]
104n/a
105n/a # Create the Distribution instance, using the remaining arguments
106n/a # (ie. everything except distclass) to initialize it
107n/a try:
108n/a _setup_distribution = dist = klass(attrs)
109n/a except DistutilsSetupError as msg:
110n/a if 'name' not in attrs:
111n/a raise SystemExit("error in setup command: %s" % msg)
112n/a else:
113n/a raise SystemExit("error in %s setup command: %s" % \
114n/a (attrs['name'], msg))
115n/a
116n/a if _setup_stop_after == "init":
117n/a return dist
118n/a
119n/a # Find and parse the config file(s): they will override options from
120n/a # the setup script, but be overridden by the command line.
121n/a dist.parse_config_files()
122n/a
123n/a if DEBUG:
124n/a print("options (after parsing config files):")
125n/a dist.dump_option_dicts()
126n/a
127n/a if _setup_stop_after == "config":
128n/a return dist
129n/a
130n/a # Parse the command line and override config files; any
131n/a # command-line errors are the end user's fault, so turn them into
132n/a # SystemExit to suppress tracebacks.
133n/a try:
134n/a ok = dist.parse_command_line()
135n/a except DistutilsArgError as msg:
136n/a raise SystemExit(gen_usage(dist.script_name) + "\nerror: %s" % msg)
137n/a
138n/a if DEBUG:
139n/a print("options (after parsing command line):")
140n/a dist.dump_option_dicts()
141n/a
142n/a if _setup_stop_after == "commandline":
143n/a return dist
144n/a
145n/a # And finally, run all the commands found on the command line.
146n/a if ok:
147n/a try:
148n/a dist.run_commands()
149n/a except KeyboardInterrupt:
150n/a raise SystemExit("interrupted")
151n/a except OSError as exc:
152n/a if DEBUG:
153n/a sys.stderr.write("error: %s\n" % (exc,))
154n/a raise
155n/a else:
156n/a raise SystemExit("error: %s" % (exc,))
157n/a
158n/a except (DistutilsError,
159n/a CCompilerError) as msg:
160n/a if DEBUG:
161n/a raise
162n/a else:
163n/a raise SystemExit("error: " + str(msg))
164n/a
165n/a return dist
166n/a
167n/a# setup ()
168n/a
169n/a
170n/adef run_setup (script_name, script_args=None, stop_after="run"):
171n/a """Run a setup script in a somewhat controlled environment, and
172n/a return the Distribution instance that drives things. This is useful
173n/a if you need to find out the distribution meta-data (passed as
174n/a keyword args from 'script' to 'setup()', or the contents of the
175n/a config files or command-line.
176n/a
177n/a 'script_name' is a file that will be read and run with 'exec()';
178n/a 'sys.argv[0]' will be replaced with 'script' for the duration of the
179n/a call. 'script_args' is a list of strings; if supplied,
180n/a 'sys.argv[1:]' will be replaced by 'script_args' for the duration of
181n/a the call.
182n/a
183n/a 'stop_after' tells 'setup()' when to stop processing; possible
184n/a values:
185n/a init
186n/a stop after the Distribution instance has been created and
187n/a populated with the keyword arguments to 'setup()'
188n/a config
189n/a stop after config files have been parsed (and their data
190n/a stored in the Distribution instance)
191n/a commandline
192n/a stop after the command-line ('sys.argv[1:]' or 'script_args')
193n/a have been parsed (and the data stored in the Distribution)
194n/a run [default]
195n/a stop after all commands have been run (the same as if 'setup()'
196n/a had been called in the usual way
197n/a
198n/a Returns the Distribution instance, which provides all information
199n/a used to drive the Distutils.
200n/a """
201n/a if stop_after not in ('init', 'config', 'commandline', 'run'):
202n/a raise ValueError("invalid value for 'stop_after': %r" % (stop_after,))
203n/a
204n/a global _setup_stop_after, _setup_distribution
205n/a _setup_stop_after = stop_after
206n/a
207n/a save_argv = sys.argv.copy()
208n/a g = {'__file__': script_name}
209n/a try:
210n/a try:
211n/a sys.argv[0] = script_name
212n/a if script_args is not None:
213n/a sys.argv[1:] = script_args
214n/a with open(script_name, 'rb') as f:
215n/a exec(f.read(), g)
216n/a finally:
217n/a sys.argv = save_argv
218n/a _setup_stop_after = None
219n/a except SystemExit:
220n/a # Hmm, should we do something if exiting with a non-zero code
221n/a # (ie. error)?
222n/a pass
223n/a
224n/a if _setup_distribution is None:
225n/a raise RuntimeError(("'distutils.core.setup()' was never called -- "
226n/a "perhaps '%s' is not a Distutils setup script?") % \
227n/a script_name)
228n/a
229n/a # I wonder if the setup script's namespace -- g and l -- would be of
230n/a # any interest to callers?
231n/a #print "_setup_distribution:", _setup_distribution
232n/a return _setup_distribution
233n/a
234n/a# run_setup ()