summaryrefslogtreecommitdiffstats
path: root/Lib/distutils
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/distutils')
-rw-r--r--Lib/distutils/command/register.py57
-rw-r--r--Lib/distutils/command/sdist.py56
-rw-r--r--Lib/distutils/tests/support.py20
-rw-r--r--Lib/distutils/tests/test_register.py79
-rw-r--r--Lib/distutils/tests/test_sdist.py39
5 files changed, 179 insertions, 72 deletions
diff --git a/Lib/distutils/command/register.py b/Lib/distutils/command/register.py
index 7dd3099..bdf5f8f 100644
--- a/Lib/distutils/command/register.py
+++ b/Lib/distutils/command/register.py
@@ -10,6 +10,7 @@ __revision__ = "$Id$"
import os, string, getpass
import io
import urllib.parse, urllib.request
+from warnings import warn
from distutils.core import PyPIRCCommand
from distutils.errors import *
@@ -21,18 +22,34 @@ class register(PyPIRCCommand):
user_options = PyPIRCCommand.user_options + [
('list-classifiers', None,
'list the valid Trove classifiers'),
+ ('strict', None ,
+ 'Will stop the registering if the meta-data are not fully compliant')
]
boolean_options = PyPIRCCommand.boolean_options + [
- 'verify', 'list-classifiers']
+ 'verify', 'list-classifiers', 'strict']
+
+ sub_commands = [('check', lambda self: True)]
def initialize_options(self):
PyPIRCCommand.initialize_options(self)
self.list_classifiers = 0
+ self.strict = 0
+
+ def finalize_options(self):
+ PyPIRCCommand.finalize_options(self)
+ # setting options for the `check` subcommand
+ check_options = {'strict': ('register', self.strict),
+ 'restructuredtext': ('register', 1)}
+ self.distribution.command_options['check'] = check_options
def run(self):
self.finalize_options()
self._set_config()
- self.check_metadata()
+
+ # Run sub commands
+ for cmd_name in self.get_sub_commands():
+ self.run_command(cmd_name)
+
if self.dry_run:
self.verify_metadata()
elif self.list_classifiers:
@@ -41,34 +58,14 @@ class register(PyPIRCCommand):
self.send_metadata()
def check_metadata(self):
- """Ensure that all required elements of meta-data (name, version,
- URL, (author and author_email) or (maintainer and
- maintainer_email)) are supplied by the Distribution object; warn if
- any are missing.
- """
- metadata = self.distribution.metadata
-
- missing = []
- for attr in ('name', 'version', 'url'):
- if not (hasattr(metadata, attr) and getattr(metadata, attr)):
- missing.append(attr)
-
- if missing:
- self.warn("missing required meta-data: " +
- ", ".join(missing))
-
- if metadata.author:
- if not metadata.author_email:
- self.warn("missing meta-data: if 'author' supplied, " +
- "'author_email' must be supplied too")
- elif metadata.maintainer:
- if not metadata.maintainer_email:
- self.warn("missing meta-data: if 'maintainer' supplied, " +
- "'maintainer_email' must be supplied too")
- else:
- self.warn("missing meta-data: either (author and author_email) " +
- "or (maintainer and maintainer_email) " +
- "must be supplied")
+ """Deprecated API."""
+ warn("distutils.command.register.check_metadata is deprecated, \
+ use the check command instead", PendingDeprecationWarning)
+ check = self.distribution.get_command_obj('check')
+ check.ensure_finalized()
+ check.strict = self.strict
+ check.restructuredtext = 1
+ check.run()
def _set_config(self):
''' Reads the configuration file and set attributes.
diff --git a/Lib/distutils/command/sdist.py b/Lib/distutils/command/sdist.py
index cbb77c2..ace9eee 100644
--- a/Lib/distutils/command/sdist.py
+++ b/Lib/distutils/command/sdist.py
@@ -9,6 +9,8 @@ import string
import sys
from types import *
from glob import glob
+from warnings import warn
+
from distutils.core import Command
from distutils import dir_util, dep_util, file_util, archive_util
from distutils.text_file import TextFile
@@ -35,6 +37,12 @@ class sdist(Command):
description = "create a source distribution (tarball, zip file, etc.)"
+ def checking_metadata(self):
+ """Callable used for the check sub-command.
+
+ Placed here so user_options can view it"""
+ return self.metadata_check
+
user_options = [
('template=', 't',
"name of manifest template file [default: MANIFEST.in]"),
@@ -64,11 +72,14 @@ class sdist(Command):
('dist-dir=', 'd',
"directory to put the source distribution archive(s) in "
"[default: dist]"),
+ ('medata-check', None,
+ "Ensure that all required elements of meta-data "
+ "are supplied. Warn if any missing. [default]"),
]
boolean_options = ['use-defaults', 'prune',
'manifest-only', 'force-manifest',
- 'keep-temp']
+ 'keep-temp', 'metadata-check']
help_options = [
('help-formats', None,
@@ -81,6 +92,8 @@ class sdist(Command):
default_format = {'posix': 'gztar',
'nt': 'zip' }
+ sub_commands = [('check', checking_metadata)]
+
def initialize_options(self):
# 'template' and 'manifest' are, respectively, the names of
# the manifest template and manifest file.
@@ -100,6 +113,7 @@ class sdist(Command):
self.dist_dir = None
self.archive_files = None
+ self.metadata_check = 1
def finalize_options(self):
if self.manifest is None:
@@ -129,9 +143,9 @@ class sdist(Command):
# manifest
self.filelist = FileList()
- # Ensure that all required meta-data is given; warn if not (but
- # don't die, it's not *that* serious!)
- self.check_metadata()
+ # Run sub commands
+ for cmd_name in self.get_sub_commands():
+ self.run_command(cmd_name)
# Do whatever it takes to get the list of files to process
# (process the manifest template, read an existing manifest,
@@ -147,34 +161,12 @@ class sdist(Command):
self.make_distribution()
def check_metadata(self):
- """Ensure that all required elements of meta-data (name, version,
- URL, (author and author_email) or (maintainer and
- maintainer_email)) are supplied by the Distribution object; warn if
- any are missing.
- """
- metadata = self.distribution.metadata
-
- missing = []
- for attr in ('name', 'version', 'url'):
- if not (hasattr(metadata, attr) and getattr(metadata, attr)):
- missing.append(attr)
-
- if missing:
- self.warn("missing required meta-data: " +
- ", ".join(missing))
-
- if metadata.author:
- if not metadata.author_email:
- self.warn("missing meta-data: if 'author' supplied, " +
- "'author_email' must be supplied too")
- elif metadata.maintainer:
- if not metadata.maintainer_email:
- self.warn("missing meta-data: if 'maintainer' supplied, " +
- "'maintainer_email' must be supplied too")
- else:
- self.warn("missing meta-data: either (author and author_email) " +
- "or (maintainer and maintainer_email) " +
- "must be supplied")
+ """Deprecated API."""
+ warn("distutils.command.sdist.check_metadata is deprecated, \
+ use the check command instead", PendingDeprecationWarning)
+ check = self.distribution.get_command_obj('check')
+ check.ensure_finalized()
+ check.run()
def get_file_list(self):
"""Figure out the list of files to include in the source
diff --git a/Lib/distutils/tests/support.py b/Lib/distutils/tests/support.py
index cdcbc37..1255413 100644
--- a/Lib/distutils/tests/support.py
+++ b/Lib/distutils/tests/support.py
@@ -12,11 +12,31 @@ class LoggingSilencer(object):
def setUp(self):
super().setUp()
self.threshold = log.set_threshold(log.FATAL)
+ # catching warnings
+ # when log will be replaced by logging
+ # we won't need such monkey-patch anymore
+ self._old_log = log.Log._log
+ log.Log._log = self._log
+ self.logs = []
def tearDown(self):
log.set_threshold(self.threshold)
+ log.Log._log = self._old_log
super().tearDown()
+ def _log(self, level, msg, args):
+ self.logs.append((level, msg, args))
+
+ def get_logs(self, *levels):
+ def _format(msg, args):
+ if len(args) == 0:
+ return msg
+ return msg % args
+ return [_format(msg, args) for level, msg, args
+ in self.logs if level in levels]
+
+ def clear_logs(self):
+ self.logs = []
class TempdirManager(object):
"""Mix-in class that handles temporary directories for test cases.
diff --git a/Lib/distutils/tests/test_register.py b/Lib/distutils/tests/test_register.py
index 46f7761..f486cf7 100644
--- a/Lib/distutils/tests/test_register.py
+++ b/Lib/distutils/tests/test_register.py
@@ -4,10 +4,14 @@ import os
import unittest
import getpass
import urllib
+import warnings
+
+from test.support import check_warnings
from distutils.command import register as register_module
from distutils.command.register import register
from distutils.core import Distribution
+from distutils.errors import DistutilsSetupError
from distutils.tests import support
from distutils.tests.test_config import PYPIRC, PyPIRCCommandTestCase
@@ -59,7 +63,7 @@ class FakeOpener(object):
def read(self):
return 'xxx'
-class registerTestCase(PyPIRCCommandTestCase):
+class RegisterTestCase(PyPIRCCommandTestCase):
def setUp(self):
PyPIRCCommandTestCase.setUp(self)
@@ -76,10 +80,11 @@ class registerTestCase(PyPIRCCommandTestCase):
urllib.request.build_opener = self.old_opener
PyPIRCCommandTestCase.tearDown(self)
- def _get_cmd(self):
- metadata = {'url': 'xxx', 'author': 'xxx',
- 'author_email': 'xxx',
- 'name': 'xxx', 'version': 'xxx'}
+ def _get_cmd(self, metadata=None):
+ if metadata is None:
+ metadata = {'url': 'xxx', 'author': 'xxx',
+ 'author_email': 'xxx',
+ 'name': 'xxx', 'version': 'xxx'}
pkg_info, dist = self.create_dist(**metadata)
return register(dist)
@@ -184,8 +189,70 @@ class registerTestCase(PyPIRCCommandTestCase):
self.assertEquals(headers['Content-length'], '290')
self.assert_((b'tarek') in req.data)
+ def test_strict(self):
+ # testing the script option
+ # when on, the register command stops if
+ # the metadata is incomplete or if
+ # long_description is not reSt compliant
+
+ # empty metadata
+ cmd = self._get_cmd({})
+ cmd.ensure_finalized()
+ cmd.strict = 1
+ self.assertRaises(DistutilsSetupError, cmd.run)
+
+ # we don't test the reSt feature if docutils
+ # is not installed
+ try:
+ import docutils
+ except ImportError:
+ return
+
+ # metadata are OK but long_description is broken
+ metadata = {'url': 'xxx', 'author': 'xxx',
+ 'author_email': 'xxx',
+ 'name': 'xxx', 'version': 'xxx',
+ 'long_description': 'title\n==\n\ntext'}
+
+ cmd = self._get_cmd(metadata)
+ cmd.ensure_finalized()
+ cmd.strict = 1
+ self.assertRaises(DistutilsSetupError, cmd.run)
+
+ # now something that works
+ metadata['long_description'] = 'title\n=====\n\ntext'
+ cmd = self._get_cmd(metadata)
+ cmd.ensure_finalized()
+ cmd.strict = 1
+ inputs = RawInputs('1', 'tarek', 'y')
+ register_module.raw_input = inputs.__call__
+ # let's run the command
+ try:
+ cmd.run()
+ finally:
+ del register_module.raw_input
+
+ # strict is not by default
+ cmd = self._get_cmd()
+ cmd.ensure_finalized()
+ inputs = RawInputs('1', 'tarek', 'y')
+ register_module.raw_input = inputs.__call__
+ # let's run the command
+ try:
+ cmd.run()
+ finally:
+ del register_module.raw_input
+
+ def test_check_metadata_deprecated(self):
+ # makes sure make_metadata is deprecated
+ cmd = self._get_cmd()
+ with check_warnings() as w:
+ warnings.simplefilter("always")
+ cmd.check_metadata()
+ self.assertEquals(len(w.warnings), 1)
+
def test_suite():
- return unittest.makeSuite(registerTestCase)
+ return unittest.makeSuite(RegisterTestCase)
if __name__ == "__main__":
unittest.main(defaultTest="test_suite")
diff --git a/Lib/distutils/tests/test_sdist.py b/Lib/distutils/tests/test_sdist.py
index 9e27933..b7e5859 100644
--- a/Lib/distutils/tests/test_sdist.py
+++ b/Lib/distutils/tests/test_sdist.py
@@ -6,7 +6,9 @@ import zipfile
from os.path import join
import sys
import tempfile
+import warnings
+from test.support import check_warnings
from test.support import captured_stdout
from distutils.command.sdist import sdist
@@ -16,6 +18,7 @@ from distutils.tests.test_config import PyPIRCCommandTestCase
from distutils.errors import DistutilsExecError, DistutilsOptionError
from distutils.spawn import find_executable
from distutils.tests import support
+from distutils.log import WARN
from distutils.archive_util import ARCHIVE_FORMATS
SETUP_PY = """
@@ -38,12 +41,12 @@ somecode%(sep)sdoc.dat
somecode%(sep)sdoc.txt
"""
-class sdistTestCase(PyPIRCCommandTestCase):
+class SDistTestCase(PyPIRCCommandTestCase):
def setUp(self):
# PyPIRCCommandTestCase creates a temp dir already
# and put it in self.tmp_dir
- super(sdistTestCase, self).setUp()
+ super(SDistTestCase, self).setUp()
# setting up an environment
self.old_path = os.getcwd()
os.mkdir(join(self.tmp_dir, 'somecode'))
@@ -57,7 +60,7 @@ class sdistTestCase(PyPIRCCommandTestCase):
def tearDown(self):
# back to normal
os.chdir(self.old_path)
- super(sdistTestCase, self).tearDown()
+ super(SDistTestCase, self).tearDown()
def get_cmd(self, metadata=None):
"""Returns a cmd"""
@@ -214,6 +217,34 @@ class sdistTestCase(PyPIRCCommandTestCase):
manifest = open(join(self.tmp_dir, 'MANIFEST')).read()
self.assertEquals(manifest, MANIFEST % {'sep': os.sep})
+ def test_metadata_check_option(self):
+ # testing the `medata-check` option
+ dist, cmd = self.get_cmd(metadata={})
+
+ # this should raise some warnings !
+ # with the `check` subcommand
+ cmd.ensure_finalized()
+ cmd.run()
+ warnings = self.get_logs(WARN)
+ self.assertEquals(len(warnings), 2)
+
+ # trying with a complete set of metadata
+ self.clear_logs()
+ dist, cmd = self.get_cmd()
+ cmd.ensure_finalized()
+ cmd.metadata_check = 0
+ cmd.run()
+ warnings = self.get_logs(WARN)
+ self.assertEquals(len(warnings), 0)
+
+ def test_check_metadata_deprecated(self):
+ # makes sure make_metadata is deprecated
+ dist, cmd = self.get_cmd()
+ with check_warnings() as w:
+ warnings.simplefilter("always")
+ cmd.check_metadata()
+ self.assertEquals(len(w.warnings), 1)
+
def test_show_formats(self):
with captured_stdout() as stdout:
show_formats()
@@ -247,7 +278,7 @@ class sdistTestCase(PyPIRCCommandTestCase):
def test_suite():
- return unittest.makeSuite(sdistTestCase)
+ return unittest.makeSuite(SDistTestCase)
if __name__ == "__main__":
unittest.main(defaultTest="test_suite")