mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
Remove display options (--name, etc.) from the Distribution class.
These options were used to implement “setup.py --name”, “setup.py --version”, etc. which are now handled by the pysetup metadata action or direct parsing of the setup.cfg file. As a side effect, the Distribution class no longer accepts a 'url' key in its *attrs* argument: it has to be 'home-page' to be recognized as a valid metadata field and passed down to the dist.metadata object. I cleaned up some comments, docstrings and code along the way.
This commit is contained in:
parent
acddb38602
commit
5e48c78ecf
5 changed files with 34 additions and 86 deletions
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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']
|
||||||
|
|
|
@ -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'))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue