Branch merge

This commit is contained in:
Éric Araujo 2011-08-30 16:21:15 +02:00
commit d15b768ddb
22 changed files with 157 additions and 210 deletions

View File

@ -76,7 +76,7 @@ argument. ::
Name: Name:
virtualenv virtualenv
$ pysetup metadata virtualenv --all $ pysetup metadata virtualenv
Metadata-Version: Metadata-Version:
1.0 1.0
Name: Name:

View File

@ -75,9 +75,6 @@ The available formats for built distributions are:
| ``gztar`` | gzipped tar file | (1),(3) | | ``gztar`` | gzipped tar file | (1),(3) |
| | (:file:`.tar.gz`) | | | | (:file:`.tar.gz`) | |
+-------------+------------------------------+---------+ +-------------+------------------------------+---------+
| ``ztar`` | compressed tar file | \(3) |
| | (:file:`.tar.Z`) | |
+-------------+------------------------------+---------+
| ``tar`` | tar file (:file:`.tar`) | \(3) | | ``tar`` | tar file (:file:`.tar`) | \(3) |
+-------------+------------------------------+---------+ +-------------+------------------------------+---------+
| ``zip`` | zip file (:file:`.zip`) | (2),(4) | | ``zip`` | zip file (:file:`.zip`) | (2),(4) |
@ -98,8 +95,8 @@ Notes:
default on Windows default on Windows
(3) (3)
requires external utilities: :program:`tar` and possibly one of :program:`gzip`, requires external utilities: :program:`tar` and possibly one of :program:`gzip`
:program:`bzip2`, or :program:`compress` or :program:`bzip2`
(4) (4)
requires either external :program:`zip` utility or :mod:`zipfile` module (part requires either external :program:`zip` utility or :mod:`zipfile` module (part
@ -109,14 +106,14 @@ You don't have to use the :command:`bdist` command with the :option:`--formats`
option; you can also use the command that directly implements the format you're option; you can also use the command that directly implements the format you're
interested in. Some of these :command:`bdist` "sub-commands" actually generate interested in. Some of these :command:`bdist` "sub-commands" actually generate
several similar formats; for instance, the :command:`bdist_dumb` command several similar formats; for instance, the :command:`bdist_dumb` command
generates all the "dumb" archive formats (``tar``, ``ztar``, ``gztar``, and generates all the "dumb" archive formats (``tar``, ``gztar``, and
``zip``). The :command:`bdist` sub-commands, and the formats generated by ``zip``). The :command:`bdist` sub-commands, and the formats generated by
each, are: each, are:
+--------------------------+-----------------------+ +--------------------------+-----------------------+
| Command | Formats | | Command | Formats |
+==========================+=======================+ +==========================+=======================+
| :command:`bdist_dumb` | tar, ztar, gztar, zip | | :command:`bdist_dumb` | tar, gztar, zip |
+--------------------------+-----------------------+ +--------------------------+-----------------------+
| :command:`bdist_wininst` | wininst | | :command:`bdist_wininst` | wininst |
+--------------------------+-----------------------+ +--------------------------+-----------------------+

View File

@ -32,9 +32,6 @@ to create a gzipped tarball and a zip file. The available formats are:
| ``bztar`` | bzip2'ed tar file | | | ``bztar`` | bzip2'ed tar file | |
| | (:file:`.tar.bz2`) | | | | (:file:`.tar.bz2`) | |
+-----------+-------------------------+---------+ +-----------+-------------------------+---------+
| ``ztar`` | compressed tar file | \(4) |
| | (:file:`.tar.Z`) | |
+-----------+-------------------------+---------+
| ``tar`` | tar file (:file:`.tar`) | | | ``tar`` | tar file (:file:`.tar`) | |
+-----------+-------------------------+---------+ +-----------+-------------------------+---------+
@ -50,11 +47,7 @@ Notes:
requires either external :program:`zip` utility or :mod:`zipfile` module (part requires either external :program:`zip` utility or :mod:`zipfile` module (part
of the standard Python library since Python 1.6) of the standard Python library since Python 1.6)
(4) When using any ``tar`` format (``gztar``, ``bztar`` or
requires the :program:`compress` program. Notice that this format is now
pending for deprecation and will be removed in the future versions of Python.
When using any ``tar`` format (``gztar``, ``bztar``, ``ztar`` or
``tar``) under Unix, you can specify the ``owner`` and ``group`` names ``tar``) under Unix, you can specify the ``owner`` and ``group`` names
that will be set for each member of the archive. that will be set for each member of the archive.

View File

@ -91,6 +91,13 @@ versions.
(:issue:`12100`) (:issue:`12100`)
crypt
-----
Addition of salf and modular crypt format to the :mod:`crypt` module.
(:issue:`10924`)
curses curses
------ ------
@ -184,7 +191,7 @@ in Python 3.2.
sys sys
--- ---
* The :mod:`sys` module has a new :func:`~sys.thread_info` :term:`struct * The :mod:`sys` module has a new :data:`~sys.thread_info` :term:`struct
sequence` holding informations about the thread implementation. sequence` holding informations about the thread implementation.
(:issue:`11223`) (:issue:`11223`)

View File

@ -47,7 +47,7 @@ class bdist_dumb(Command):
self.format = None self.format = None
self.keep_temp = 0 self.keep_temp = 0
self.dist_dir = None self.dist_dir = None
self.skip_build = 0 self.skip_build = None
self.relative = 0 self.relative = 0
def finalize_options(self): def finalize_options(self):
@ -65,7 +65,8 @@ class bdist_dumb(Command):
self.set_undefined_options('bdist', self.set_undefined_options('bdist',
('dist_dir', 'dist_dir'), ('dist_dir', 'dist_dir'),
('plat_name', 'plat_name')) ('plat_name', 'plat_name'),
('skip_build', 'skip_build'))
def run(self): def run(self):
if not self.skip_build: if not self.skip_build:

View File

@ -130,18 +130,22 @@ class bdist_msi(Command):
self.no_target_optimize = 0 self.no_target_optimize = 0
self.target_version = None self.target_version = None
self.dist_dir = None self.dist_dir = None
self.skip_build = 0 self.skip_build = None
self.install_script = None self.install_script = None
self.pre_install_script = None self.pre_install_script = None
self.versions = None self.versions = None
def finalize_options(self): def finalize_options(self):
self.set_undefined_options('bdist', ('skip_build', 'skip_build'))
if self.bdist_dir is None: if self.bdist_dir is None:
bdist_base = self.get_finalized_command('bdist').bdist_base bdist_base = self.get_finalized_command('bdist').bdist_base
self.bdist_dir = os.path.join(bdist_base, 'msi') self.bdist_dir = os.path.join(bdist_base, 'msi')
short_version = get_python_version() short_version = get_python_version()
if (not self.target_version) and self.distribution.has_ext_modules(): if (not self.target_version) and self.distribution.has_ext_modules():
self.target_version = short_version self.target_version = short_version
if self.target_version: if self.target_version:
self.versions = [self.target_version] self.versions = [self.target_version]
if not self.skip_build and self.distribution.has_ext_modules()\ if not self.skip_build and self.distribution.has_ext_modules()\

View File

@ -65,13 +65,15 @@ class bdist_wininst(Command):
self.dist_dir = None self.dist_dir = None
self.bitmap = None self.bitmap = None
self.title = None self.title = None
self.skip_build = 0 self.skip_build = None
self.install_script = None self.install_script = None
self.pre_install_script = None self.pre_install_script = None
self.user_access_control = None self.user_access_control = None
def finalize_options(self): def finalize_options(self):
self.set_undefined_options('bdist', ('skip_build', 'skip_build'))
if self.bdist_dir is None: if self.bdist_dir is None:
if self.skip_build and self.plat_name: if self.skip_build and self.plat_name:
# If build is skipped and plat_name is overridden, bdist will # If build is skipped and plat_name is overridden, bdist will
@ -81,8 +83,10 @@ class bdist_wininst(Command):
# next the command will be initialized using that name # next the command will be initialized using that name
bdist_base = self.get_finalized_command('bdist').bdist_base bdist_base = self.get_finalized_command('bdist').bdist_base
self.bdist_dir = os.path.join(bdist_base, 'wininst') self.bdist_dir = os.path.join(bdist_base, 'wininst')
if not self.target_version: if not self.target_version:
self.target_version = "" self.target_version = ""
if not self.skip_build and self.distribution.has_ext_modules(): if not self.skip_build and self.distribution.has_ext_modules():
short_version = get_python_version() short_version = get_python_version()
if self.target_version and self.target_version != short_version: if self.target_version and self.target_version != short_version:

View File

@ -1,41 +1,47 @@
"""Tests for distutils.command.bdist.""" """Tests for distutils.command.bdist."""
import unittest
import sys
import os import os
import tempfile import unittest
import shutil
from test.support import run_unittest from test.support import run_unittest
from distutils.core import Distribution
from distutils.command.bdist import bdist from distutils.command.bdist import bdist
from distutils.tests import support from distutils.tests import support
from distutils.spawn import find_executable
from distutils import spawn
from distutils.errors import DistutilsExecError
class BuildTestCase(support.TempdirManager, class BuildTestCase(support.TempdirManager,
unittest.TestCase): unittest.TestCase):
def test_formats(self): def test_formats(self):
# let's create a command and make sure # let's create a command and make sure
# we can fix the format # we can set the format
pkg_pth, dist = self.create_dist() dist = self.create_dist()[1]
cmd = bdist(dist) cmd = bdist(dist)
cmd.formats = ['msi'] cmd.formats = ['msi']
cmd.ensure_finalized() cmd.ensure_finalized()
self.assertEqual(cmd.formats, ['msi']) self.assertEqual(cmd.formats, ['msi'])
# what format bdist offers ? # what formats does bdist offer?
# XXX an explicit list in bdist is formats = ['bztar', 'gztar', 'msi', 'rpm', 'tar',
# not the best way to bdist_* commands 'wininst', 'zip', 'ztar']
# we should add a registry found = sorted(cmd.format_command)
formats = ['rpm', 'zip', 'gztar', 'bztar', 'ztar', self.assertEqual(found, formats)
'tar', 'wininst', 'msi']
formats.sort() def test_skip_build(self):
founded = list(cmd.format_command.keys()) # bug #10946: bdist --skip-build should trickle down to subcommands
founded.sort() dist = self.create_dist()[1]
self.assertEqual(founded, formats) cmd = bdist(dist)
cmd.skip_build = 1
cmd.ensure_finalized()
dist.command_obj['bdist'] = cmd
names = ['bdist_dumb', 'bdist_wininst'] # bdist_rpm does not support --skip-build
if os.name == 'nt':
names.append('bdist_msi')
for name in names:
subcmd = cmd.get_finalized_command(name)
self.assertTrue(subcmd.skip_build,
'%s should take --skip-build from bdist' % name)
def test_suite(): def test_suite():
return unittest.makeSuite(BuildTestCase) return unittest.makeSuite(BuildTestCase)

View File

@ -30,6 +30,8 @@ _COMMANDS = {
'upload': 'packaging.command.upload.upload', 'upload': 'packaging.command.upload.upload',
'upload_docs': 'packaging.command.upload_docs.upload_docs'} 'upload_docs': 'packaging.command.upload_docs.upload_docs'}
# XXX use OrderedDict to preserve the grouping (build-related, install-related,
# distribution-related)
STANDARD_COMMANDS = set(_COMMANDS) STANDARD_COMMANDS = set(_COMMANDS)
@ -48,9 +50,9 @@ def get_command_class(name):
"""Return the registered command""" """Return the registered command"""
try: try:
cls = _COMMANDS[name] cls = _COMMANDS[name]
except KeyError:
raise PackagingModuleError("Invalid command %s" % name)
if isinstance(cls, str): if isinstance(cls, str):
cls = resolve_name(cls) cls = resolve_name(cls)
_COMMANDS[name] = cls _COMMANDS[name] = cls
return cls return cls
except KeyError:
raise PackagingModuleError("Invalid command %s" % name)

View File

@ -64,21 +64,19 @@ class bdist(Command):
'os2': 'zip'} 'os2': 'zip'}
# Establish the preferred order (for the --help-formats option). # Establish the preferred order (for the --help-formats option).
format_commands = ['gztar', 'bztar', 'ztar', 'tar', format_commands = ['gztar', 'bztar', 'tar',
'wininst', 'zip', 'msi'] 'wininst', 'zip', 'msi']
# And the real information. # And the real information.
format_command = {'gztar': ('bdist_dumb', "gzip'ed tar file"), format_command = {'gztar': ('bdist_dumb', "gzip'ed tar file"),
'bztar': ('bdist_dumb', "bzip2'ed tar file"), 'bztar': ('bdist_dumb', "bzip2'ed tar file"),
'ztar': ('bdist_dumb', "compressed tar file"),
'tar': ('bdist_dumb', "tar file"), 'tar': ('bdist_dumb', "tar file"),
'wininst': ('bdist_wininst', 'wininst': ('bdist_wininst',
"Windows executable installer"), "Windows executable installer"),
'zip': ('bdist_dumb', "ZIP file"), 'zip': ('bdist_dumb', "ZIP file"),
'msi': ('bdist_msi', "Microsoft Installer") 'msi': ('bdist_msi', "Microsoft Installer"),
} }
def initialize_options(self): def initialize_options(self):
self.bdist_base = None self.bdist_base = None
self.plat_name = None self.plat_name = None
@ -109,7 +107,8 @@ class bdist(Command):
try: try:
self.formats = [self.default_format[os.name]] self.formats = [self.default_format[os.name]]
except KeyError: except KeyError:
raise PackagingPlatformError("don't know how to create built distributions " + \ raise PackagingPlatformError(
"don't know how to create built distributions "
"on platform %s" % os.name) "on platform %s" % os.name)
if self.dist_dir is None: if self.dist_dir is None:

View File

@ -13,6 +13,7 @@ from packaging.command.cmd import Command
from packaging.errors import PackagingPlatformError from packaging.errors import PackagingPlatformError
from packaging import logger from packaging import logger
class bdist_dumb(Command): class bdist_dumb(Command):
description = 'create a "dumb" built distribution' description = 'create a "dumb" built distribution'
@ -23,7 +24,7 @@ class bdist_dumb(Command):
"platform name to embed in generated filenames " "platform name to embed in generated filenames "
"(default: %s)" % get_platform()), "(default: %s)" % get_platform()),
('format=', 'f', ('format=', 'f',
"archive format to create (tar, ztar, gztar, zip)"), "archive format to create (tar, gztar, zip)"),
('keep-temp', 'k', ('keep-temp', 'k',
"keep the pseudo-installation tree around after " + "keep the pseudo-installation tree around after " +
"creating the distribution archive"), "creating the distribution archive"),
@ -44,10 +45,9 @@ class bdist_dumb(Command):
boolean_options = ['keep-temp', 'skip-build', 'relative'] boolean_options = ['keep-temp', 'skip-build', 'relative']
default_format = { 'posix': 'gztar', default_format = {'posix': 'gztar',
'nt': 'zip', 'nt': 'zip',
'os2': 'zip' } 'os2': 'zip'}
def initialize_options(self): def initialize_options(self):
self.bdist_dir = None self.bdist_dir = None
@ -55,7 +55,7 @@ class bdist_dumb(Command):
self.format = None self.format = None
self.keep_temp = False self.keep_temp = False
self.dist_dir = None self.dist_dir = None
self.skip_build = False self.skip_build = None
self.relative = False self.relative = False
self.owner = None self.owner = None
self.group = None self.group = None
@ -69,10 +69,12 @@ class bdist_dumb(Command):
try: try:
self.format = self.default_format[os.name] self.format = self.default_format[os.name]
except KeyError: except KeyError:
raise PackagingPlatformError(("don't know how to create dumb built distributions " + raise PackagingPlatformError(
"on platform %s") % os.name) "don't know how to create dumb built distributions "
"on platform %s" % os.name)
self.set_undefined_options('bdist', 'dist_dir', 'plat_name') self.set_undefined_options('bdist',
'dist_dir', 'plat_name', 'skip_build')
def run(self): def run(self):
if not self.skip_build: if not self.skip_build:

View File

@ -139,18 +139,22 @@ class bdist_msi(Command):
self.no_target_optimize = False self.no_target_optimize = False
self.target_version = None self.target_version = None
self.dist_dir = None self.dist_dir = None
self.skip_build = False self.skip_build = None
self.install_script = None self.install_script = None
self.pre_install_script = None self.pre_install_script = None
self.versions = None self.versions = None
def finalize_options(self): def finalize_options(self):
self.set_undefined_options('bdist', 'skip_build')
if self.bdist_dir is None: if self.bdist_dir is None:
bdist_base = self.get_finalized_command('bdist').bdist_base bdist_base = self.get_finalized_command('bdist').bdist_base
self.bdist_dir = os.path.join(bdist_base, 'msi') self.bdist_dir = os.path.join(bdist_base, 'msi')
short_version = get_python_version() short_version = get_python_version()
if (not self.target_version) and self.distribution.has_ext_modules(): if (not self.target_version) and self.distribution.has_ext_modules():
self.target_version = short_version self.target_version = short_version
if self.target_version: if self.target_version:
self.versions = [self.target_version] self.versions = [self.target_version]
if not self.skip_build and self.distribution.has_ext_modules()\ if not self.skip_build and self.distribution.has_ext_modules()\

View File

@ -67,13 +67,15 @@ class bdist_wininst(Command):
self.dist_dir = None self.dist_dir = None
self.bitmap = None self.bitmap = None
self.title = None self.title = None
self.skip_build = False self.skip_build = None
self.install_script = None self.install_script = None
self.pre_install_script = None self.pre_install_script = None
self.user_access_control = None self.user_access_control = None
def finalize_options(self): def finalize_options(self):
self.set_undefined_options('bdist', 'skip_build')
if self.bdist_dir is None: if self.bdist_dir is None:
if self.skip_build and self.plat_name: if self.skip_build and self.plat_name:
# If build is skipped and plat_name is overridden, bdist will # If build is skipped and plat_name is overridden, bdist will
@ -83,8 +85,10 @@ class bdist_wininst(Command):
# next the command will be initialized using that name # next the command will be initialized using that name
bdist_base = self.get_finalized_command('bdist').bdist_base bdist_base = self.get_finalized_command('bdist').bdist_base
self.bdist_dir = os.path.join(bdist_base, 'wininst') self.bdist_dir = os.path.join(bdist_base, 'wininst')
if not self.target_version: if not self.target_version:
self.target_version = "" self.target_version = ""
if not self.skip_build and self.distribution.has_ext_modules(): if not self.skip_build and self.distribution.has_ext_modules():
short_version = get_python_version() short_version = get_python_version()
if self.target_version and self.target_version != short_version: if self.target_version and self.target_version != short_version:

View File

@ -606,8 +606,7 @@ class build_ext(Command):
template = "python%d%d" template = "python%d%d"
if self.debug: if self.debug:
template = template + '_d' template = template + '_d'
pythonlib = (template % pythonlib = template % sys.version_info[:2]
(sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
# don't extend ext.libraries, it may be shared with other # don't extend ext.libraries, it may be shared with other
# extensions, it is a reference to the original list # extensions, it is a reference to the original list
return ext.libraries + [pythonlib] return ext.libraries + [pythonlib]
@ -621,22 +620,19 @@ class build_ext(Command):
# not at this time - AIM Apr01 # not at this time - AIM Apr01
#if self.debug: #if self.debug:
# template = template + '_d' # template = template + '_d'
pythonlib = (template % pythonlib = template % sys.version_info[:2]
(sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
# don't extend ext.libraries, it may be shared with other # don't extend ext.libraries, it may be shared with other
# extensions, it is a reference to the original list # extensions, it is a reference to the original list
return ext.libraries + [pythonlib] return ext.libraries + [pythonlib]
elif sys.platform[:6] == "cygwin": elif sys.platform[:6] == "cygwin":
template = "python%d.%d" template = "python%d.%d"
pythonlib = (template % pythonlib = template % sys.version_info[:2]
(sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
# don't extend ext.libraries, it may be shared with other # don't extend ext.libraries, it may be shared with other
# extensions, it is a reference to the original list # extensions, it is a reference to the original list
return ext.libraries + [pythonlib] return ext.libraries + [pythonlib]
elif sys.platform[:6] == "atheos": elif sys.platform[:6] == "atheos":
template = "python%d.%d" template = "python%d.%d"
pythonlib = (template % pythonlib = template % sys.version_info[:2]
(sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
# Get SHLIBS from Makefile # Get SHLIBS from Makefile
extra = [] extra = []
for lib in sysconfig.get_config_var('SHLIBS').split(): for lib in sysconfig.get_config_var('SHLIBS').split():
@ -654,9 +650,8 @@ class build_ext(Command):
else: else:
if sysconfig.get_config_var('Py_ENABLE_SHARED'): if sysconfig.get_config_var('Py_ENABLE_SHARED'):
pythonlib = 'python{}.{}{}'.format( template = 'python%d%d' + sys.abiflags
sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff, pythonlib = template % sys.version_info[:2]
sys.abiflags)
return ext.libraries + [pythonlib] return ext.libraries + [pythonlib]
else: else:
return ext.libraries return ext.libraries

View File

@ -1,20 +1,21 @@
"""Class representing the distribution being built/installed/etc.""" """Class representing the project being built/installed/etc."""
import os import os
import re import re
from packaging import logger
from packaging.util import strtobool, resolve_name
from packaging.config import Config
from packaging.errors import (PackagingOptionError, PackagingArgError, from packaging.errors import (PackagingOptionError, PackagingArgError,
PackagingModuleError, PackagingClassError) PackagingModuleError, PackagingClassError)
from packaging.fancy_getopt import FancyGetopt
from packaging.util import strtobool, resolve_name
from packaging import logger
from packaging.metadata import Metadata
from packaging.config import Config
from packaging.command import get_command_class, STANDARD_COMMANDS from packaging.command import get_command_class, STANDARD_COMMANDS
from packaging.command.cmd import Command
from packaging.metadata import Metadata
from packaging.fancy_getopt import FancyGetopt
# Regex to define acceptable Packaging command names. This is not *quite* # Regex to define acceptable Packaging command names. This is not *quite*
# the same as a Python NAME -- I don't allow leading underscores. The fact # the same as a Python name -- leading underscores are not allowed. The fact
# that they're very similar is no coincidence; the default naming scheme is # that they're very similar is no coincidence: the default naming scheme is
# to look for a Python module named after the command. # to look for a Python module named after the command.
command_re = re.compile(r'^[a-zA-Z]([a-zA-Z0-9_]*)$') command_re = re.compile(r'^[a-zA-Z]([a-zA-Z0-9_]*)$')
@ -32,22 +33,16 @@ def gen_usage(script_name):
class Distribution: class Distribution:
"""The core of the Packaging. Most of the work hiding behind 'setup' """Class used to represent a project and work with it.
is really done within a Distribution instance, which farms the work out
to the Packaging commands specified on the command line.
Setup scripts will almost never instantiate Distribution directly, Most of the work hiding behind 'pysetup run' is really done within a
unless the 'setup()' function is totally inadequate to their needs. Distribution instance, which farms the work out to the commands
However, it is conceivable that a setup script might wish to subclass specified on the command line.
Distribution for some specialized purpose, and then pass the subclass
to 'setup()' as the 'distclass' keyword argument. If so, it is
necessary to respect the expectations that 'setup' has of Distribution.
See the code for 'setup()', in run.py, for details.
""" """
# 'global_options' describes the command-line options that may be # 'global_options' describes the command-line options that may be
# supplied to the setup script prior to any actual commands. # supplied to the setup script prior to any actual commands.
# Eg. "pysetup -n" or "pysetup --dry-run" both take advantage of # Eg. "pysetup run -n" or "pysetup run --dry-run" both take advantage of
# these global options. This list should be kept to a bare minimum, # these global options. This list should be kept to a bare minimum,
# since every global option is also valid as a command option -- and we # since every global option is also valid as a command option -- and we
# don't want to pollute the commands with too many options that they # don't want to pollute the commands with too many options that they
@ -63,55 +58,14 @@ class Distribution:
common_usage = """\ common_usage = """\
Common commands: (see '--help-commands' for more) Common commands: (see '--help-commands' for more)
pysetup run build will build the package underneath 'build/' pysetup run build will build the project underneath 'build/'
pysetup run install will install the package pysetup run install will install the project
""" """
# options that are not propagated to the commands # options that are not propagated to the commands
display_options = [ display_options = [
('help-commands', None, ('help-commands', None,
"list all available commands"), "list all available commands"),
# XXX this is obsoleted by the pysetup metadata action
('name', None,
"print package name"),
('version', 'V',
"print package version"),
('fullname', None,
"print <package name>-<version>"),
('author', None,
"print the author's name"),
('author-email', None,
"print the author's email address"),
('maintainer', None,
"print the maintainer's name"),
('maintainer-email', None,
"print the maintainer's email address"),
('contact', None,
"print the maintainer's name if known, else the author's"),
('contact-email', None,
"print the maintainer's email address if known, else the author's"),
('url', None,
"print the URL for this package"),
('license', None,
"print the license of the package"),
('licence', None,
"alias for --license"),
('description', None,
"print the package description"),
('long-description', None,
"print the long package description"),
('platforms', None,
"print the list of platforms"),
('classifier', None,
"print the list of classifiers"),
('keywords', None,
"print the list of keywords"),
('provides', None,
"print the list of packages/modules provided"),
('requires', None,
"print the list of packages/modules required"),
('obsoletes', None,
"print the list of packages/modules made obsolete"),
('use-2to3', None, ('use-2to3', None,
"use 2to3 to make source python 3.x compatible"), "use 2to3 to make source python 3.x compatible"),
('convert-2to3-doctests', None, ('convert-2to3-doctests', None,
@ -347,7 +301,6 @@ Common commands: (see '--help-commands' for more)
self.commands = [] self.commands = []
parser = FancyGetopt(toplevel_options + self.display_options) parser = FancyGetopt(toplevel_options + self.display_options)
parser.set_negative_aliases(self.negative_opt) parser.set_negative_aliases(self.negative_opt)
parser.set_aliases({'licence': 'license'})
args = parser.getopt(args=self.script_args, object=self) args = parser.getopt(args=self.script_args, object=self)
option_order = parser.get_option_order() option_order = parser.get_option_order()
@ -372,7 +325,7 @@ Common commands: (see '--help-commands' for more)
commands=self.commands) commands=self.commands)
return return
return 1 return True
def _get_toplevel_options(self): def _get_toplevel_options(self):
"""Return the non-display options recognized at the top level. """Return the non-display options recognized at the top level.
@ -496,13 +449,10 @@ Common commands: (see '--help-commands' for more)
If 'global_options' is true, lists the global options: If 'global_options' is true, lists the global options:
--dry-run, etc. If 'display_options' is true, lists --dry-run, etc. If 'display_options' is true, lists
the "display-only" options: --name, --version, etc. Finally, the "display-only" options: --help-commands. Finally,
lists per-command help for every command name or command class lists per-command help for every command name or command class
in 'commands'. in 'commands'.
""" """
# late import because of mutual dependence between these modules
from packaging.command.cmd import Command
if global_options: if global_options:
if display_options: if display_options:
options = self._get_toplevel_options() options = self._get_toplevel_options()
@ -536,9 +486,8 @@ Common commands: (see '--help-commands' for more)
def handle_display_options(self, option_order): def handle_display_options(self, option_order):
"""If there were any non-global "display-only" options """If there were any non-global "display-only" options
(--help-commands or the metadata display options) on the command (--help-commands) on the command line, display the requested info and
line, display the requested info and return true; else return return true; else return false.
false.
""" """
# User just wants a list of commands -- we'll print it out and stop # User just wants a list of commands -- we'll print it out and stop
# processing now (ie. if they ran "setup --help-commands foo bar", # processing now (ie. if they ran "setup --help-commands foo bar",
@ -547,7 +496,7 @@ Common commands: (see '--help-commands' for more)
self.print_commands() self.print_commands()
print() print()
print(gen_usage(self.script_name)) print(gen_usage(self.script_name))
return 1 return True
# If user supplied any of the "display metadata" options, then # If user supplied any of the "display metadata" options, then
# display that metadata in the order in which the user supplied the # display that metadata in the order in which the user supplied the
@ -628,18 +577,17 @@ Common commands: (see '--help-commands' for more)
""" """
cmd_obj = self.command_obj.get(command) cmd_obj = self.command_obj.get(command)
if not cmd_obj and create: if not cmd_obj and create:
logger.debug("Distribution.get_command_obj(): " \ logger.debug("Distribution.get_command_obj(): "
"creating %r command object", command) "creating %r command object", command)
cls = get_command_class(command) cls = get_command_class(command)
cmd_obj = self.command_obj[command] = cls(self) cmd_obj = self.command_obj[command] = cls(self)
self.have_run[command] = 0 self.have_run[command] = 0
# Set any options that were supplied in config files # Set any options that were supplied in config files or on the
# or on the command line. (NB. support for error # command line. (XXX support for error reporting is suboptimal
# reporting is lame here: any errors aren't reported # here: errors aren't reported until finalize_options is called,
# until 'finalize_options()' is called, which means # which means we won't report the source of the error.)
# we won't report the source of the error.)
options = self.command_options.get(command) options = self.command_options.get(command)
if options: if options:
self._set_command_options(cmd_obj, options) self._set_command_options(cmd_obj, options)
@ -707,7 +655,6 @@ Common commands: (see '--help-commands' for more)
Returns the reinitialized command object. Returns the reinitialized command object.
""" """
from packaging.command.cmd import Command
if not isinstance(command, Command): if not isinstance(command, Command):
command_name = command command_name = command
command = self.get_command_obj(command_name) command = self.get_command_obj(command_name)
@ -716,6 +663,7 @@ Common commands: (see '--help-commands' for more)
if not command.finalized: if not command.finalized:
return command return command
command.initialize_options() command.initialize_options()
self.have_run[command_name] = 0 self.have_run[command_name] = 0
command.finalized = False command.finalized = False

View File

@ -71,8 +71,8 @@ positional arguments:
""" """
metadata_usage = """\ metadata_usage = """\
Usage: pysetup metadata [dist] [-f field ...] Usage: pysetup metadata [dist]
or: pysetup metadata [dist] [--all] or: pysetup metadata [dist] [-f field ...]
or: pysetup metadata --help or: pysetup metadata --help
Print metadata for the distribution. Print metadata for the distribution.
@ -81,8 +81,7 @@ positional arguments:
dist installed distribution name dist installed distribution name
optional arguments: optional arguments:
-f metadata field to print -f metadata field to print; omit to get all fields
--all print all metadata fields
""" """
remove_usage = """\ remove_usage = """\
@ -252,7 +251,7 @@ def _install(dispatcher, args, **kw):
@action_help(metadata_usage) @action_help(metadata_usage)
def _metadata(dispatcher, args, **kw): def _metadata(dispatcher, args, **kw):
opts = _parse_args(args[1:], 'f:', ['all']) opts = _parse_args(args[1:], 'f:', [])
if opts['args']: if opts['args']:
name = opts['args'][0] name = opts['args'][0]
dist = get_distribution(name, use_egg_info=True) dist = get_distribution(name, use_egg_info=True)
@ -269,13 +268,10 @@ def _metadata(dispatcher, args, **kw):
metadata = dist.metadata metadata = dist.metadata
if 'all' in opts:
keys = metadata.keys()
else:
if 'f' in opts: if 'f' in opts:
keys = (k for k in opts['f'] if k in metadata) keys = (k for k in opts['f'] if k in metadata)
else: else:
keys = () keys = metadata.keys()
for key in keys: for key in keys:
if key in metadata: if key in metadata:

View File

@ -1,8 +1,6 @@
"""Tests for distutils.command.bdist.""" """Tests for distutils.command.bdist."""
import os
from packaging import util
from packaging.command.bdist import bdist, show_formats from packaging.command.bdist import bdist, show_formats
from packaging.tests import unittest, support, captured_stdout from packaging.tests import unittest, support, captured_stdout
@ -10,55 +8,38 @@ class BuildTestCase(support.TempdirManager,
support.LoggingCatcher, support.LoggingCatcher,
unittest.TestCase): unittest.TestCase):
def _mock_get_platform(self):
self._get_platform_called = True
return self._get_platform()
def setUp(self):
super(BuildTestCase, self).setUp()
# mock util.get_platform
self._get_platform_called = False
self._get_platform = util.get_platform
util.get_platform = self._mock_get_platform
def tearDown(self):
super(BuildTestCase, self).tearDown()
util.get_platform = self._get_platform
def test_formats(self): def test_formats(self):
# let's create a command and make sure # let's create a command and make sure
# we can fix the format # we can set the format
pkg_pth, dist = self.create_dist() dist = self.create_dist()[1]
cmd = bdist(dist) cmd = bdist(dist)
cmd.formats = ['msi'] cmd.formats = ['msi']
cmd.ensure_finalized() cmd.ensure_finalized()
self.assertEqual(cmd.formats, ['msi']) self.assertEqual(cmd.formats, ['msi'])
# what format bdist offers ? # what formats does bdist offer?
# XXX an explicit list in bdist is # XXX hard-coded lists are not the best way to find available bdist_*
# not the best way to bdist_* commands # commands; we should add a registry
# we should add a registry formats = ['bztar', 'gztar', 'msi', 'tar', 'wininst', 'zip']
formats = sorted(('zip', 'gztar', 'bztar', 'ztar',
'tar', 'wininst', 'msi'))
found = sorted(cmd.format_command) found = sorted(cmd.format_command)
self.assertEqual(found, formats) self.assertEqual(found, formats)
def test_skip_build(self): def test_skip_build(self):
pkg_pth, dist = self.create_dist() # bug #10946: bdist --skip-build should trickle down to subcommands
cmd = bdist(dist) dist = self.create_dist()[1]
cmd.skip_build = False
cmd.formats = ['ztar']
cmd.ensure_finalized()
self.assertFalse(self._get_platform_called)
pkg_pth, dist = self.create_dist()
cmd = bdist(dist) cmd = bdist(dist)
cmd.skip_build = True cmd.skip_build = True
cmd.formats = ['ztar']
cmd.ensure_finalized() cmd.ensure_finalized()
self.assertTrue(self._get_platform_called) dist.command_obj['bdist'] = cmd
names = ['bdist_dumb', 'bdist_wininst']
if os.name == 'nt':
names.append('bdist_msi')
for name in names:
subcmd = cmd.get_finalized_command(name)
self.assertTrue(subcmd.skip_build,
'%s should take --skip-build from bdist' % name)
def test_show_formats(self): def test_show_formats(self):
__, stdout = captured_stdout(show_formats) __, stdout = captured_stdout(show_formats)

View File

@ -35,7 +35,7 @@ class BuildDumbTestCase(support.TempdirManager,
dist = Distribution({'name': 'foo', 'version': '0.1', dist = Distribution({'name': 'foo', 'version': '0.1',
'py_modules': ['foo'], 'py_modules': ['foo'],
'url': 'xxx', 'author': 'xxx', 'home-page': 'xxx', 'author': 'xxx',
'author_email': 'xxx'}) 'author_email': 'xxx'})
os.chdir(pkg_dir) os.chdir(pkg_dir)
cmd = bdist_dumb(dist) cmd = bdist_dumb(dist)

View File

@ -99,7 +99,7 @@ class RegisterTestCase(support.TempdirManager,
def _get_cmd(self, metadata=None): def _get_cmd(self, metadata=None):
if metadata is None: if metadata is None:
metadata = {'url': 'xxx', 'author': 'xxx', metadata = {'home-page': 'xxx', 'author': 'xxx',
'author_email': 'xxx', 'author_email': 'xxx',
'name': 'xxx', 'version': 'xxx'} 'name': 'xxx', 'version': 'xxx'}
pkg_info, dist = self.create_dist(**metadata) pkg_info, dist = self.create_dist(**metadata)

View File

@ -72,7 +72,7 @@ class SDistTestCase(support.TempdirManager,
"""Returns a cmd""" """Returns a cmd"""
if metadata is None: if metadata is None:
metadata = {'name': 'fake', 'version': '1.0', metadata = {'name': 'fake', 'version': '1.0',
'url': 'xxx', 'author': 'xxx', 'home_page': 'xxx', 'author': 'xxx',
'author_email': 'xxx'} 'author_email': 'xxx'}
dist = Distribution(metadata) dist = Distribution(metadata)
dist.packages = ['somecode'] dist.packages = ['somecode']

View File

@ -98,7 +98,7 @@ class DistributionTestCase(support.TempdirManager,
Distribution(attrs={'author': 'xxx', Distribution(attrs={'author': 'xxx',
'name': 'xxx', 'name': 'xxx',
'version': '1.2', 'version': '1.2',
'url': 'xxxx', 'home-page': 'xxxx',
'badoptname': 'xxx'}) 'badoptname': 'xxx'})
logs = self.get_logs(logging.WARNING) logs = self.get_logs(logging.WARNING)
self.assertEqual(1, len(logs)) self.assertEqual(1, len(logs))
@ -108,7 +108,7 @@ class DistributionTestCase(support.TempdirManager,
Distribution(attrs={'author': 'xxx', Distribution(attrs={'author': 'xxx',
'name': 'xxx', 'name': 'xxx',
'version': 'xxx', 'version': 'xxx',
'url': 'xxxx'}) 'home-page': 'xxxx'})
logs = self.get_logs(logging.WARNING) logs = self.get_logs(logging.WARNING)
self.assertEqual(1, len(logs)) self.assertEqual(1, len(logs))
self.assertIn('not a valid version', logs[0]) self.assertIn('not a valid version', logs[0])
@ -119,7 +119,7 @@ class DistributionTestCase(support.TempdirManager,
Distribution(attrs={'author': 'xxx', Distribution(attrs={'author': 'xxx',
'name': 'xxx', 'name': 'xxx',
'version': '1.2', 'version': '1.2',
'url': 'xxxx', 'home-page': 'xxxx',
'options': {}}) 'options': {}})
self.assertEqual([], self.get_logs(logging.WARNING)) self.assertEqual([], self.get_logs(logging.WARNING))
@ -135,7 +135,7 @@ class DistributionTestCase(support.TempdirManager,
dist = Distribution(attrs={'author': 'xxx', dist = Distribution(attrs={'author': 'xxx',
'name': 'xxx', 'name': 'xxx',
'version': 'xxx', 'version': 'xxx',
'url': 'xxxx', 'home-page': 'xxxx',
'options': {'sdist': {'owner': 'root'}}}) 'options': {'sdist': {'owner': 'root'}}})
self.assertIn('owner', dist.get_option_dict('sdist')) self.assertIn('owner', dist.get_option_dict('sdist'))

View File

@ -268,6 +268,10 @@ Core and Builtins
Library Library
------- -------
- Issue #10946: The distutils commands bdist_dumb, bdist_wininst and bdist_msi
now respect a --skip-build option given to bdist. The packaging commands
were fixed too.
- Issue #12847: Fix a crash with negative PUT and LONG_BINPUT arguments in - Issue #12847: Fix a crash with negative PUT and LONG_BINPUT arguments in
the C pickle implementation. the C pickle implementation.