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

Python code coverage for Lib/distutils/cmd.py

#countcontent
1n/a"""distutils.cmd
2n/a
3n/aProvides the Command class, the base class for the command classes
4n/ain the distutils.command package.
5n/a"""
6n/a
7n/aimport sys, os, re
8n/afrom distutils.errors import DistutilsOptionError
9n/afrom distutils import util, dir_util, file_util, archive_util, dep_util
10n/afrom distutils import log
11n/a
12n/aclass Command:
13n/a """Abstract base class for defining command classes, the "worker bees"
14n/a of the Distutils. A useful analogy for command classes is to think of
15n/a them as subroutines with local variables called "options". The options
16n/a are "declared" in 'initialize_options()' and "defined" (given their
17n/a final values, aka "finalized") in 'finalize_options()', both of which
18n/a must be defined by every command class. The distinction between the
19n/a two is necessary because option values might come from the outside
20n/a world (command line, config file, ...), and any options dependent on
21n/a other options must be computed *after* these outside influences have
22n/a been processed -- hence 'finalize_options()'. The "body" of the
23n/a subroutine, where it does all its work based on the values of its
24n/a options, is the 'run()' method, which must also be implemented by every
25n/a command class.
26n/a """
27n/a
28n/a # 'sub_commands' formalizes the notion of a "family" of commands,
29n/a # eg. "install" as the parent with sub-commands "install_lib",
30n/a # "install_headers", etc. The parent of a family of commands
31n/a # defines 'sub_commands' as a class attribute; it's a list of
32n/a # (command_name : string, predicate : unbound_method | string | None)
33n/a # tuples, where 'predicate' is a method of the parent command that
34n/a # determines whether the corresponding command is applicable in the
35n/a # current situation. (Eg. we "install_headers" is only applicable if
36n/a # we have any C header files to install.) If 'predicate' is None,
37n/a # that command is always applicable.
38n/a #
39n/a # 'sub_commands' is usually defined at the *end* of a class, because
40n/a # predicates can be unbound methods, so they must already have been
41n/a # defined. The canonical example is the "install" command.
42n/a sub_commands = []
43n/a
44n/a
45n/a # -- Creation/initialization methods -------------------------------
46n/a
47n/a def __init__(self, dist):
48n/a """Create and initialize a new Command object. Most importantly,
49n/a invokes the 'initialize_options()' method, which is the real
50n/a initializer and depends on the actual command being
51n/a instantiated.
52n/a """
53n/a # late import because of mutual dependence between these classes
54n/a from distutils.dist import Distribution
55n/a
56n/a if not isinstance(dist, Distribution):
57n/a raise TypeError("dist must be a Distribution instance")
58n/a if self.__class__ is Command:
59n/a raise RuntimeError("Command is an abstract class")
60n/a
61n/a self.distribution = dist
62n/a self.initialize_options()
63n/a
64n/a # Per-command versions of the global flags, so that the user can
65n/a # customize Distutils' behaviour command-by-command and let some
66n/a # commands fall back on the Distribution's behaviour. None means
67n/a # "not defined, check self.distribution's copy", while 0 or 1 mean
68n/a # false and true (duh). Note that this means figuring out the real
69n/a # value of each flag is a touch complicated -- hence "self._dry_run"
70n/a # will be handled by __getattr__, below.
71n/a # XXX This needs to be fixed.
72n/a self._dry_run = None
73n/a
74n/a # verbose is largely ignored, but needs to be set for
75n/a # backwards compatibility (I think)?
76n/a self.verbose = dist.verbose
77n/a
78n/a # Some commands define a 'self.force' option to ignore file
79n/a # timestamps, but methods defined *here* assume that
80n/a # 'self.force' exists for all commands. So define it here
81n/a # just to be safe.
82n/a self.force = None
83n/a
84n/a # The 'help' flag is just used for command-line parsing, so
85n/a # none of that complicated bureaucracy is needed.
86n/a self.help = 0
87n/a
88n/a # 'finalized' records whether or not 'finalize_options()' has been
89n/a # called. 'finalize_options()' itself should not pay attention to
90n/a # this flag: it is the business of 'ensure_finalized()', which
91n/a # always calls 'finalize_options()', to respect/update it.
92n/a self.finalized = 0
93n/a
94n/a # XXX A more explicit way to customize dry_run would be better.
95n/a def __getattr__(self, attr):
96n/a if attr == 'dry_run':
97n/a myval = getattr(self, "_" + attr)
98n/a if myval is None:
99n/a return getattr(self.distribution, attr)
100n/a else:
101n/a return myval
102n/a else:
103n/a raise AttributeError(attr)
104n/a
105n/a def ensure_finalized(self):
106n/a if not self.finalized:
107n/a self.finalize_options()
108n/a self.finalized = 1
109n/a
110n/a # Subclasses must define:
111n/a # initialize_options()
112n/a # provide default values for all options; may be customized by
113n/a # setup script, by options from config file(s), or by command-line
114n/a # options
115n/a # finalize_options()
116n/a # decide on the final values for all options; this is called
117n/a # after all possible intervention from the outside world
118n/a # (command-line, option file, etc.) has been processed
119n/a # run()
120n/a # run the command: do whatever it is we're here to do,
121n/a # controlled by the command's various option values
122n/a
123n/a def initialize_options(self):
124n/a """Set default values for all the options that this command
125n/a supports. Note that these defaults may be overridden by other
126n/a commands, by the setup script, by config files, or by the
127n/a command-line. Thus, this is not the place to code dependencies
128n/a between options; generally, 'initialize_options()' implementations
129n/a are just a bunch of "self.foo = None" assignments.
130n/a
131n/a This method must be implemented by all command classes.
132n/a """
133n/a raise RuntimeError("abstract method -- subclass %s must override"
134n/a % self.__class__)
135n/a
136n/a def finalize_options(self):
137n/a """Set final values for all the options that this command supports.
138n/a This is always called as late as possible, ie. after any option
139n/a assignments from the command-line or from other commands have been
140n/a done. Thus, this is the place to code option dependencies: if
141n/a 'foo' depends on 'bar', then it is safe to set 'foo' from 'bar' as
142n/a long as 'foo' still has the same value it was assigned in
143n/a 'initialize_options()'.
144n/a
145n/a This method must be implemented by all command classes.
146n/a """
147n/a raise RuntimeError("abstract method -- subclass %s must override"
148n/a % self.__class__)
149n/a
150n/a
151n/a def dump_options(self, header=None, indent=""):
152n/a from distutils.fancy_getopt import longopt_xlate
153n/a if header is None:
154n/a header = "command options for '%s':" % self.get_command_name()
155n/a self.announce(indent + header, level=log.INFO)
156n/a indent = indent + " "
157n/a for (option, _, _) in self.user_options:
158n/a option = option.translate(longopt_xlate)
159n/a if option[-1] == "=":
160n/a option = option[:-1]
161n/a value = getattr(self, option)
162n/a self.announce(indent + "%s = %s" % (option, value),
163n/a level=log.INFO)
164n/a
165n/a def run(self):
166n/a """A command's raison d'etre: carry out the action it exists to
167n/a perform, controlled by the options initialized in
168n/a 'initialize_options()', customized by other commands, the setup
169n/a script, the command-line, and config files, and finalized in
170n/a 'finalize_options()'. All terminal output and filesystem
171n/a interaction should be done by 'run()'.
172n/a
173n/a This method must be implemented by all command classes.
174n/a """
175n/a raise RuntimeError("abstract method -- subclass %s must override"
176n/a % self.__class__)
177n/a
178n/a def announce(self, msg, level=1):
179n/a """If the current verbosity level is of greater than or equal to
180n/a 'level' print 'msg' to stdout.
181n/a """
182n/a log.log(level, msg)
183n/a
184n/a def debug_print(self, msg):
185n/a """Print 'msg' to stdout if the global DEBUG (taken from the
186n/a DISTUTILS_DEBUG environment variable) flag is true.
187n/a """
188n/a from distutils.debug import DEBUG
189n/a if DEBUG:
190n/a print(msg)
191n/a sys.stdout.flush()
192n/a
193n/a
194n/a # -- Option validation methods -------------------------------------
195n/a # (these are very handy in writing the 'finalize_options()' method)
196n/a #
197n/a # NB. the general philosophy here is to ensure that a particular option
198n/a # value meets certain type and value constraints. If not, we try to
199n/a # force it into conformance (eg. if we expect a list but have a string,
200n/a # split the string on comma and/or whitespace). If we can't force the
201n/a # option into conformance, raise DistutilsOptionError. Thus, command
202n/a # classes need do nothing more than (eg.)
203n/a # self.ensure_string_list('foo')
204n/a # and they can be guaranteed that thereafter, self.foo will be
205n/a # a list of strings.
206n/a
207n/a def _ensure_stringlike(self, option, what, default=None):
208n/a val = getattr(self, option)
209n/a if val is None:
210n/a setattr(self, option, default)
211n/a return default
212n/a elif not isinstance(val, str):
213n/a raise DistutilsOptionError("'%s' must be a %s (got `%s`)"
214n/a % (option, what, val))
215n/a return val
216n/a
217n/a def ensure_string(self, option, default=None):
218n/a """Ensure that 'option' is a string; if not defined, set it to
219n/a 'default'.
220n/a """
221n/a self._ensure_stringlike(option, "string", default)
222n/a
223n/a def ensure_string_list(self, option):
224n/a r"""Ensure that 'option' is a list of strings. If 'option' is
225n/a currently a string, we split it either on /,\s*/ or /\s+/, so
226n/a "foo bar baz", "foo,bar,baz", and "foo, bar baz" all become
227n/a ["foo", "bar", "baz"].
228n/a """
229n/a val = getattr(self, option)
230n/a if val is None:
231n/a return
232n/a elif isinstance(val, str):
233n/a setattr(self, option, re.split(r',\s*|\s+', val))
234n/a else:
235n/a if isinstance(val, list):
236n/a ok = all(isinstance(v, str) for v in val)
237n/a else:
238n/a ok = False
239n/a if not ok:
240n/a raise DistutilsOptionError(
241n/a "'%s' must be a list of strings (got %r)"
242n/a % (option, val))
243n/a
244n/a def _ensure_tested_string(self, option, tester, what, error_fmt,
245n/a default=None):
246n/a val = self._ensure_stringlike(option, what, default)
247n/a if val is not None and not tester(val):
248n/a raise DistutilsOptionError(("error in '%s' option: " + error_fmt)
249n/a % (option, val))
250n/a
251n/a def ensure_filename(self, option):
252n/a """Ensure that 'option' is the name of an existing file."""
253n/a self._ensure_tested_string(option, os.path.isfile,
254n/a "filename",
255n/a "'%s' does not exist or is not a file")
256n/a
257n/a def ensure_dirname(self, option):
258n/a self._ensure_tested_string(option, os.path.isdir,
259n/a "directory name",
260n/a "'%s' does not exist or is not a directory")
261n/a
262n/a
263n/a # -- Convenience methods for commands ------------------------------
264n/a
265n/a def get_command_name(self):
266n/a if hasattr(self, 'command_name'):
267n/a return self.command_name
268n/a else:
269n/a return self.__class__.__name__
270n/a
271n/a def set_undefined_options(self, src_cmd, *option_pairs):
272n/a """Set the values of any "undefined" options from corresponding
273n/a option values in some other command object. "Undefined" here means
274n/a "is None", which is the convention used to indicate that an option
275n/a has not been changed between 'initialize_options()' and
276n/a 'finalize_options()'. Usually called from 'finalize_options()' for
277n/a options that depend on some other command rather than another
278n/a option of the same command. 'src_cmd' is the other command from
279n/a which option values will be taken (a command object will be created
280n/a for it if necessary); the remaining arguments are
281n/a '(src_option,dst_option)' tuples which mean "take the value of
282n/a 'src_option' in the 'src_cmd' command object, and copy it to
283n/a 'dst_option' in the current command object".
284n/a """
285n/a # Option_pairs: list of (src_option, dst_option) tuples
286n/a src_cmd_obj = self.distribution.get_command_obj(src_cmd)
287n/a src_cmd_obj.ensure_finalized()
288n/a for (src_option, dst_option) in option_pairs:
289n/a if getattr(self, dst_option) is None:
290n/a setattr(self, dst_option, getattr(src_cmd_obj, src_option))
291n/a
292n/a def get_finalized_command(self, command, create=1):
293n/a """Wrapper around Distribution's 'get_command_obj()' method: find
294n/a (create if necessary and 'create' is true) the command object for
295n/a 'command', call its 'ensure_finalized()' method, and return the
296n/a finalized command object.
297n/a """
298n/a cmd_obj = self.distribution.get_command_obj(command, create)
299n/a cmd_obj.ensure_finalized()
300n/a return cmd_obj
301n/a
302n/a # XXX rename to 'get_reinitialized_command()'? (should do the
303n/a # same in dist.py, if so)
304n/a def reinitialize_command(self, command, reinit_subcommands=0):
305n/a return self.distribution.reinitialize_command(command,
306n/a reinit_subcommands)
307n/a
308n/a def run_command(self, command):
309n/a """Run some other command: uses the 'run_command()' method of
310n/a Distribution, which creates and finalizes the command object if
311n/a necessary and then invokes its 'run()' method.
312n/a """
313n/a self.distribution.run_command(command)
314n/a
315n/a def get_sub_commands(self):
316n/a """Determine the sub-commands that are relevant in the current
317n/a distribution (ie., that need to be run). This is based on the
318n/a 'sub_commands' class attribute: each tuple in that list may include
319n/a a method that we call to determine if the subcommand needs to be
320n/a run for the current distribution. Return a list of command names.
321n/a """
322n/a commands = []
323n/a for (cmd_name, method) in self.sub_commands:
324n/a if method is None or method(self):
325n/a commands.append(cmd_name)
326n/a return commands
327n/a
328n/a
329n/a # -- External world manipulation -----------------------------------
330n/a
331n/a def warn(self, msg):
332n/a log.warn("warning: %s: %s\n", self.get_command_name(), msg)
333n/a
334n/a def execute(self, func, args, msg=None, level=1):
335n/a util.execute(func, args, msg, dry_run=self.dry_run)
336n/a
337n/a def mkpath(self, name, mode=0o777):
338n/a dir_util.mkpath(name, mode, dry_run=self.dry_run)
339n/a
340n/a def copy_file(self, infile, outfile, preserve_mode=1, preserve_times=1,
341n/a link=None, level=1):
342n/a """Copy a file respecting verbose, dry-run and force flags. (The
343n/a former two default to whatever is in the Distribution object, and
344n/a the latter defaults to false for commands that don't define it.)"""
345n/a return file_util.copy_file(infile, outfile, preserve_mode,
346n/a preserve_times, not self.force, link,
347n/a dry_run=self.dry_run)
348n/a
349n/a def copy_tree(self, infile, outfile, preserve_mode=1, preserve_times=1,
350n/a preserve_symlinks=0, level=1):
351n/a """Copy an entire directory tree respecting verbose, dry-run,
352n/a and force flags.
353n/a """
354n/a return dir_util.copy_tree(infile, outfile, preserve_mode,
355n/a preserve_times, preserve_symlinks,
356n/a not self.force, dry_run=self.dry_run)
357n/a
358n/a def move_file (self, src, dst, level=1):
359n/a """Move a file respecting dry-run flag."""
360n/a return file_util.move_file(src, dst, dry_run=self.dry_run)
361n/a
362n/a def spawn(self, cmd, search_path=1, level=1):
363n/a """Spawn an external command respecting dry-run flag."""
364n/a from distutils.spawn import spawn
365n/a spawn(cmd, search_path, dry_run=self.dry_run)
366n/a
367n/a def make_archive(self, base_name, format, root_dir=None, base_dir=None,
368n/a owner=None, group=None):
369n/a return archive_util.make_archive(base_name, format, root_dir, base_dir,
370n/a dry_run=self.dry_run,
371n/a owner=owner, group=group)
372n/a
373n/a def make_file(self, infiles, outfile, func, args,
374n/a exec_msg=None, skip_msg=None, level=1):
375n/a """Special case of 'execute()' for operations that process one or
376n/a more input files and generate one output file. Works just like
377n/a 'execute()', except the operation is skipped and a different
378n/a message printed if 'outfile' already exists and is newer than all
379n/a files listed in 'infiles'. If the command defined 'self.force',
380n/a and it is true, then the command is unconditionally run -- does no
381n/a timestamp checks.
382n/a """
383n/a if skip_msg is None:
384n/a skip_msg = "skipping %s (inputs unchanged)" % outfile
385n/a
386n/a # Allow 'infiles' to be a single string
387n/a if isinstance(infiles, str):
388n/a infiles = (infiles,)
389n/a elif not isinstance(infiles, (list, tuple)):
390n/a raise TypeError(
391n/a "'infiles' must be a string, or a list or tuple of strings")
392n/a
393n/a if exec_msg is None:
394n/a exec_msg = "generating %s from %s" % (outfile, ', '.join(infiles))
395n/a
396n/a # If 'outfile' must be regenerated (either because it doesn't
397n/a # exist, is out-of-date, or the 'force' flag is true) then
398n/a # perform the action that presumably regenerates it
399n/a if self.force or dep_util.newer_group(infiles, outfile):
400n/a self.execute(func, args, exec_msg, level)
401n/a # Otherwise, print the "skip" message
402n/a else:
403n/a log.debug(skip_msg)