mirror of https://github.com/python/cpython
Branch merge
This commit is contained in:
commit
8c0c9d2641
|
@ -147,11 +147,11 @@ setup script). Indirectly provides the :class:`distutils.dist.Distribution` and
|
||||||
In addition, the :mod:`distutils.core` module exposed a number of classes that
|
In addition, the :mod:`distutils.core` module exposed a number of classes that
|
||||||
live elsewhere.
|
live elsewhere.
|
||||||
|
|
||||||
* :class:`Extension` from :mod:`distutils.extension`
|
* :class:`~distutils.extension.Extension` from :mod:`distutils.extension`
|
||||||
|
|
||||||
* :class:`Command` from :mod:`distutils.cmd`
|
* :class:`~distutils.cmd.Command` from :mod:`distutils.cmd`
|
||||||
|
|
||||||
* :class:`Distribution` from :mod:`distutils.dist`
|
* :class:`~distutils.dist.Distribution` from :mod:`distutils.dist`
|
||||||
|
|
||||||
A short description of each of these follows, but see the relevant module for
|
A short description of each of these follows, but see the relevant module for
|
||||||
the full reference.
|
the full reference.
|
||||||
|
@ -1679,8 +1679,8 @@ lines, and joining lines with backslashes.
|
||||||
===================================================================
|
===================================================================
|
||||||
|
|
||||||
.. module:: distutils.cmd
|
.. module:: distutils.cmd
|
||||||
:synopsis: This module provides the abstract base class Command. This class is subclassed
|
:synopsis: This module provides the abstract base class Command. This class
|
||||||
by the modules in the distutils.command subpackage.
|
is subclassed by the modules in the distutils.command subpackage.
|
||||||
|
|
||||||
|
|
||||||
This module supplies the abstract base class :class:`Command`.
|
This module supplies the abstract base class :class:`Command`.
|
||||||
|
@ -1690,20 +1690,84 @@ This module supplies the abstract base class :class:`Command`.
|
||||||
|
|
||||||
Abstract base class for defining command classes, the "worker bees" of the
|
Abstract base class for defining command classes, the "worker bees" of the
|
||||||
Distutils. A useful analogy for command classes is to think of them as
|
Distutils. A useful analogy for command classes is to think of them as
|
||||||
subroutines with local variables called *options*. The options are declared in
|
subroutines with local variables called *options*. The options are declared
|
||||||
:meth:`initialize_options` and defined (given their final values) in
|
in :meth:`initialize_options` and defined (given their final values) in
|
||||||
:meth:`finalize_options`, both of which must be defined by every command class.
|
:meth:`finalize_options`, both of which must be defined by every command
|
||||||
The distinction between the two is necessary because option values might come
|
class. The distinction between the two is necessary because option values
|
||||||
from the outside world (command line, config file, ...), and any options
|
might come from the outside world (command line, config file, ...), and any
|
||||||
dependent on other options must be computed after these outside influences have
|
options dependent on other options must be computed after these outside
|
||||||
been processed --- hence :meth:`finalize_options`. The body of the subroutine,
|
influences have been processed --- hence :meth:`finalize_options`. The body
|
||||||
where it does all its work based on the values of its options, is the
|
of the subroutine, where it does all its work based on the values of its
|
||||||
:meth:`run` method, which must also be implemented by every command class.
|
options, is the :meth:`run` method, which must also be implemented by every
|
||||||
|
command class.
|
||||||
|
|
||||||
The class constructor takes a single argument *dist*, a :class:`Distribution`
|
The class constructor takes a single argument *dist*, a :class:`Distribution`
|
||||||
instance.
|
instance.
|
||||||
|
|
||||||
|
|
||||||
|
Creating a new Distutils command
|
||||||
|
================================
|
||||||
|
|
||||||
|
This section outlines the steps to create a new Distutils command.
|
||||||
|
|
||||||
|
A new command lives in a module in the :mod:`distutils.command` package. There
|
||||||
|
is a sample template in that directory called :file:`command_template`. Copy
|
||||||
|
this file to a new module with the same name as the new command you're
|
||||||
|
implementing. This module should implement a class with the same name as the
|
||||||
|
module (and the command). So, for instance, to create the command
|
||||||
|
``peel_banana`` (so that users can run ``setup.py peel_banana``), you'd copy
|
||||||
|
:file:`command_template` to :file:`distutils/command/peel_banana.py`, then edit
|
||||||
|
it so that it's implementing the class :class:`peel_banana`, a subclass of
|
||||||
|
:class:`distutils.cmd.Command`.
|
||||||
|
|
||||||
|
Subclasses of :class:`Command` must define the following methods.
|
||||||
|
|
||||||
|
.. method:: Command.initialize_options()
|
||||||
|
|
||||||
|
Set default values for all the options that this command supports. Note that
|
||||||
|
these defaults may be overridden by other commands, by the setup script, by
|
||||||
|
config files, or by the command-line. Thus, this is not the place to code
|
||||||
|
dependencies between options; generally, :meth:`initialize_options`
|
||||||
|
implementations are just a bunch of ``self.foo = None`` assignments.
|
||||||
|
|
||||||
|
|
||||||
|
.. method:: Command.finalize_options()
|
||||||
|
|
||||||
|
Set final values for all the options that this command supports. This is
|
||||||
|
always called as late as possible, ie. after any option assignments from the
|
||||||
|
command-line or from other commands have been done. Thus, this is the place
|
||||||
|
to to code option dependencies: if *foo* depends on *bar*, then it is safe to
|
||||||
|
set *foo* from *bar* as long as *foo* still has the same value it was
|
||||||
|
assigned in :meth:`initialize_options`.
|
||||||
|
|
||||||
|
|
||||||
|
.. method:: Command.run()
|
||||||
|
|
||||||
|
A command's raison d'etre: carry out the action it exists to perform, controlled
|
||||||
|
by the options initialized in :meth:`initialize_options`, customized by other
|
||||||
|
commands, the setup script, the command-line, and config files, and finalized in
|
||||||
|
:meth:`finalize_options`. All terminal output and filesystem interaction should
|
||||||
|
be done by :meth:`run`.
|
||||||
|
|
||||||
|
|
||||||
|
.. attribute:: Command.sub_commands
|
||||||
|
|
||||||
|
*sub_commands* formalizes the notion of a "family" of commands,
|
||||||
|
e.g. ``install`` as the parent with sub-commands ``install_lib``,
|
||||||
|
``install_headers``, etc. The parent of a family of commands defines
|
||||||
|
*sub_commands* as a class attribute; it's a list of 2-tuples ``(command_name,
|
||||||
|
predicate)``, with *command_name* a string and *predicate* a function, a
|
||||||
|
string or ``None``. *predicate* is a method of the parent command that
|
||||||
|
determines whether the corresponding command is applicable in the current
|
||||||
|
situation. (E.g. ``install_headers`` is only applicable if we have any C
|
||||||
|
header files to install.) If *predicate* is ``None``, that command is always
|
||||||
|
applicable.
|
||||||
|
|
||||||
|
*sub_commands* is usually defined at the *end* of a class, because
|
||||||
|
predicates can be methods of the class, so they must already have been
|
||||||
|
defined. The canonical example is the :command:`install` command.
|
||||||
|
|
||||||
|
|
||||||
:mod:`distutils.command` --- Individual Distutils commands
|
:mod:`distutils.command` --- Individual Distutils commands
|
||||||
==========================================================
|
==========================================================
|
||||||
|
|
||||||
|
@ -1926,61 +1990,15 @@ This is described in more detail in :pep:`301`.
|
||||||
.. % todo
|
.. % todo
|
||||||
|
|
||||||
|
|
||||||
Creating a new Distutils command
|
:mod:`distutils.command.check` --- Check the meta-data of a package
|
||||||
================================
|
===================================================================
|
||||||
|
|
||||||
This section outlines the steps to create a new Distutils command.
|
.. module:: distutils.command.check
|
||||||
|
:synopsis: Check the metadata of a package
|
||||||
A new command lives in a module in the :mod:`distutils.command` package. There
|
|
||||||
is a sample template in that directory called :file:`command_template`. Copy
|
|
||||||
this file to a new module with the same name as the new command you're
|
|
||||||
implementing. This module should implement a class with the same name as the
|
|
||||||
module (and the command). So, for instance, to create the command
|
|
||||||
``peel_banana`` (so that users can run ``setup.py peel_banana``), you'd copy
|
|
||||||
:file:`command_template` to :file:`distutils/command/peel_banana.py`, then edit
|
|
||||||
it so that it's implementing the class :class:`peel_banana`, a subclass of
|
|
||||||
:class:`distutils.cmd.Command`.
|
|
||||||
|
|
||||||
Subclasses of :class:`Command` must define the following methods.
|
|
||||||
|
|
||||||
|
|
||||||
.. method:: Command.initialize_options()
|
The ``check`` command performs some tests on the meta-data of a package.
|
||||||
|
For example, it verifies that all required meta-data are provided as
|
||||||
|
the arguments passed to the :func:`setup` function.
|
||||||
|
|
||||||
Set default values for all the options that this command supports. Note that
|
.. % todo
|
||||||
these defaults may be overridden by other commands, by the setup script, by
|
|
||||||
config files, or by the command-line. Thus, this is not the place to code
|
|
||||||
dependencies between options; generally, :meth:`initialize_options`
|
|
||||||
implementations are just a bunch of ``self.foo = None`` assignments.
|
|
||||||
|
|
||||||
|
|
||||||
.. method:: Command.finalize_options()
|
|
||||||
|
|
||||||
Set final values for all the options that this command supports. This is
|
|
||||||
always called as late as possible, ie. after any option assignments from the
|
|
||||||
command-line or from other commands have been done. Thus, this is the place
|
|
||||||
to to code option dependencies: if *foo* depends on *bar*, then it is safe to
|
|
||||||
set *foo* from *bar* as long as *foo* still has the same value it was
|
|
||||||
assigned in :meth:`initialize_options`.
|
|
||||||
|
|
||||||
|
|
||||||
.. method:: Command.run()
|
|
||||||
|
|
||||||
A command's raison d'etre: carry out the action it exists to perform, controlled
|
|
||||||
by the options initialized in :meth:`initialize_options`, customized by other
|
|
||||||
commands, the setup script, the command-line, and config files, and finalized in
|
|
||||||
:meth:`finalize_options`. All terminal output and filesystem interaction should
|
|
||||||
be done by :meth:`run`.
|
|
||||||
|
|
||||||
*sub_commands* formalizes the notion of a "family" of commands, eg. ``install``
|
|
||||||
as the parent with sub-commands ``install_lib``, ``install_headers``, etc. The
|
|
||||||
parent of a family of commands defines *sub_commands* as a class attribute; it's
|
|
||||||
a list of 2-tuples ``(command_name, predicate)``, with *command_name* a string
|
|
||||||
and *predicate* an unbound method, a string or None. *predicate* is a method of
|
|
||||||
the parent command that determines whether the corresponding command is
|
|
||||||
applicable in the current situation. (Eg. we ``install_headers`` is only
|
|
||||||
applicable if we have any C header files to install.) If *predicate* is None,
|
|
||||||
that command is always applicable.
|
|
||||||
|
|
||||||
*sub_commands* is usually defined at the \*end\* of a class, because predicates
|
|
||||||
can be unbound methods, so they must already have been defined. The canonical
|
|
||||||
example is the :command:`install` command.
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ class BuildPyTestCase(support.TempdirManager,
|
||||||
support.LoggingSilencer,
|
support.LoggingSilencer,
|
||||||
unittest.TestCase):
|
unittest.TestCase):
|
||||||
|
|
||||||
def _setup_package_data(self):
|
def test_package_data(self):
|
||||||
sources = self.mkdtemp()
|
sources = self.mkdtemp()
|
||||||
f = open(os.path.join(sources, "__init__.py"), "w")
|
f = open(os.path.join(sources, "__init__.py"), "w")
|
||||||
try:
|
try:
|
||||||
|
@ -57,20 +57,15 @@ class BuildPyTestCase(support.TempdirManager,
|
||||||
self.assertEqual(len(cmd.get_outputs()), 3)
|
self.assertEqual(len(cmd.get_outputs()), 3)
|
||||||
pkgdest = os.path.join(destination, "pkg")
|
pkgdest = os.path.join(destination, "pkg")
|
||||||
files = os.listdir(pkgdest)
|
files = os.listdir(pkgdest)
|
||||||
return files
|
self.assertIn("__init__.py", files)
|
||||||
|
self.assertIn("README.txt", files)
|
||||||
|
# XXX even with -O, distutils writes pyc, not pyo; bug?
|
||||||
|
if sys.dont_write_bytecode:
|
||||||
|
self.assertNotIn("__init__.pyc", files)
|
||||||
|
else:
|
||||||
|
self.assertIn("__init__.pyc", files)
|
||||||
|
|
||||||
def test_package_data(self):
|
def test_empty_package_dir(self):
|
||||||
files = self._setup_package_data()
|
|
||||||
self.assertTrue("__init__.py" in files)
|
|
||||||
self.assertTrue("README.txt" in files)
|
|
||||||
|
|
||||||
@unittest.skipIf(sys.flags.optimize >= 2,
|
|
||||||
"pyc files are not written with -O2 and above")
|
|
||||||
def test_package_data_pyc(self):
|
|
||||||
files = self._setup_package_data()
|
|
||||||
self.assertTrue("__init__.pyc" in files)
|
|
||||||
|
|
||||||
def test_empty_package_dir (self):
|
|
||||||
# See SF 1668596/1720897.
|
# See SF 1668596/1720897.
|
||||||
cwd = os.getcwd()
|
cwd = os.getcwd()
|
||||||
|
|
||||||
|
@ -118,7 +113,7 @@ class BuildPyTestCase(support.TempdirManager,
|
||||||
finally:
|
finally:
|
||||||
sys.dont_write_bytecode = old_dont_write_bytecode
|
sys.dont_write_bytecode = old_dont_write_bytecode
|
||||||
|
|
||||||
self.assertTrue('byte-compiling is disabled' in self.logs[0][1])
|
self.assertIn('byte-compiling is disabled', self.logs[0][1])
|
||||||
|
|
||||||
def test_suite():
|
def test_suite():
|
||||||
return unittest.makeSuite(BuildPyTestCase)
|
return unittest.makeSuite(BuildPyTestCase)
|
||||||
|
|
Loading…
Reference in New Issue