mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
Branch merge
This commit is contained in:
commit
3bb8be6d78
28 changed files with 250 additions and 161 deletions
|
@ -19,6 +19,8 @@ information that's already documented for Python in the
|
|||
:local:
|
||||
|
||||
|
||||
.. _setupcfg-syntax:
|
||||
|
||||
Syntax
|
||||
======
|
||||
|
||||
|
@ -117,6 +119,8 @@ from most specialized to most common.
|
|||
file**. This will be useful to let users publish a single file.
|
||||
|
||||
|
||||
.. _setupcfg-sections:
|
||||
|
||||
Description of sections and fields
|
||||
==================================
|
||||
|
||||
|
@ -149,6 +153,8 @@ command sections
|
|||
on the command line.
|
||||
|
||||
|
||||
.. _setupcfg-section-global:
|
||||
|
||||
Global options
|
||||
--------------
|
||||
|
||||
|
@ -194,6 +200,9 @@ setup_hooks
|
|||
setup_hooks = _setuphooks.customize_config
|
||||
|
||||
|
||||
|
||||
.. _setupcfg-section-metadata:
|
||||
|
||||
Metadata
|
||||
--------
|
||||
|
||||
|
@ -318,6 +327,8 @@ You should not give any explicit value for metadata-version: it will be guessed
|
|||
from the fields present in the file.
|
||||
|
||||
|
||||
.. _setupcfg-section-files:
|
||||
|
||||
Files
|
||||
-----
|
||||
|
||||
|
@ -325,7 +336,8 @@ This section describes the files included in the project.
|
|||
|
||||
packages_root
|
||||
the root directory containing all packages and modules
|
||||
(default: current directory). *optional*
|
||||
(default: current directory, i.e. the project's top-level
|
||||
directory where :file:`setup.cfg` lives). *optional*
|
||||
|
||||
packages
|
||||
a list of packages the project includes *optional*, *multi*
|
||||
|
@ -337,8 +349,8 @@ scripts
|
|||
a list of scripts the project includes *optional*, *multi*
|
||||
|
||||
extra_files
|
||||
a list of patterns to include extra files *optional*,
|
||||
*multi*
|
||||
a list of patterns for additional files to include in source distributions
|
||||
(see :ref:`packaging-manifest`) *optional*, *multi*
|
||||
|
||||
Example::
|
||||
|
||||
|
@ -747,8 +759,10 @@ We use brace expansion syntax to place all the shell and batch scripts into
|
|||
{scripts} category.
|
||||
|
||||
|
||||
Extension sections
|
||||
------------------
|
||||
.. _setupcfg-section-extensions:
|
||||
|
||||
Extension modules sections
|
||||
--------------------------
|
||||
|
||||
If a project includes extension modules written in C or C++, each one of them
|
||||
needs to have its options defined in a dedicated section. Here's an example::
|
||||
|
@ -779,8 +793,10 @@ addition, multi-line values accept environment markers on each line, after a
|
|||
``--``.
|
||||
|
||||
|
||||
Command sections
|
||||
----------------
|
||||
.. _setupcfg-section-commands:
|
||||
|
||||
Commands sections
|
||||
-----------------
|
||||
|
||||
To pass options to commands without having to type them on the command line
|
||||
for each invocation, you can write them in the :file:`setup.cfg` file, in a
|
||||
|
@ -803,6 +819,11 @@ section named after the command. Example::
|
|||
Option values given in the configuration file can be overriden on the command
|
||||
line. See :ref:`packaging-setup-config` for more information.
|
||||
|
||||
These sections are also used to define :ref:`command hooks
|
||||
<packaging-command-hooks>`.
|
||||
|
||||
|
||||
.. _setupcfg-extensibility:
|
||||
|
||||
Extensibility
|
||||
=============
|
||||
|
@ -817,6 +838,8 @@ An extension field starts with ``X-``. Example::
|
|||
X-Debian-Name = python-distribute
|
||||
|
||||
|
||||
.. _setupcfg-changes:
|
||||
|
||||
Changes in the specification
|
||||
============================
|
||||
|
||||
|
@ -852,6 +875,8 @@ A tool written to produce 1.x should have these properties:
|
|||
- May write optional fields.
|
||||
|
||||
|
||||
.. _setupcfg-acks:
|
||||
|
||||
Acknowledgments
|
||||
===============
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""Build pure Python modules (just copy to build directory)."""
|
||||
|
||||
import os
|
||||
import imp
|
||||
import sys
|
||||
from glob import glob
|
||||
|
||||
|
@ -330,9 +331,10 @@ class build_py(Command, Mixin2to3):
|
|||
outputs.append(filename)
|
||||
if include_bytecode:
|
||||
if self.compile:
|
||||
outputs.append(filename + "c")
|
||||
outputs.append(imp.cache_from_source(filename))
|
||||
if self.optimize > 0:
|
||||
outputs.append(filename + "o")
|
||||
outputs.append(imp.cache_from_source(filename,
|
||||
debug_override=False))
|
||||
|
||||
outputs += [
|
||||
os.path.join(build_dir, filename)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""Install all modules (extensions and pure Python)."""
|
||||
|
||||
import os
|
||||
import imp
|
||||
import sys
|
||||
import logging
|
||||
|
||||
|
@ -172,9 +173,10 @@ class install_lib(Command):
|
|||
if ext != PYTHON_SOURCE_EXTENSION:
|
||||
continue
|
||||
if self.compile:
|
||||
bytecode_files.append(py_file + "c")
|
||||
bytecode_files.append(imp.cache_from_source(py_file))
|
||||
if self.optimize > 0:
|
||||
bytecode_files.append(py_file + "o")
|
||||
bytecode_files.append(imp.cache_from_source(
|
||||
py_file, debug_override=False))
|
||||
|
||||
return bytecode_files
|
||||
|
||||
|
|
|
@ -185,6 +185,7 @@ _MISSING = object()
|
|||
|
||||
_FILESAFE = re.compile('[^A-Za-z0-9.]+')
|
||||
|
||||
|
||||
class Metadata:
|
||||
"""The metadata of a release.
|
||||
|
||||
|
@ -228,10 +229,8 @@ class Metadata:
|
|||
|
||||
def __delitem__(self, name):
|
||||
field_name = self._convert_name(name)
|
||||
try:
|
||||
del self._fields[field_name]
|
||||
except KeyError:
|
||||
raise KeyError(name)
|
||||
# we let a KeyError propagate
|
||||
del self._fields[field_name]
|
||||
self._set_best_version()
|
||||
|
||||
def __contains__(self, name):
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
# Ripped from importlib tests, thanks Brett!
|
||||
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
from test.support import run_unittest, reap_children, reap_threads
|
||||
|
||||
|
|
|
@ -82,10 +82,13 @@ class LoggingCatcher:
|
|||
configured to record all messages logged to the 'packaging' logger.
|
||||
|
||||
Use get_logs to retrieve messages and self.loghandler.flush to discard
|
||||
them. get_logs automatically flushes the logs; if you test code that
|
||||
generates logging messages but don't use get_logs, you have to flush
|
||||
manually before doing other checks on logging message, otherwise you
|
||||
will get irrelevant results. See example in test_command_check.
|
||||
them. get_logs automatically flushes the logs, unless you pass
|
||||
*flush=False*, for example to make multiple calls to the method with
|
||||
different level arguments. If your test calls some code that generates
|
||||
logging message and then you don't call get_logs, you will need to flush
|
||||
manually before testing other code in the same test_* method, otherwise
|
||||
get_logs in the next lines will see messages from the previous lines.
|
||||
See example in test_command_check.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
|
@ -109,25 +112,23 @@ class LoggingCatcher:
|
|||
logger2to3.setLevel(self._old_levels[1])
|
||||
super(LoggingCatcher, self).tearDown()
|
||||
|
||||
def get_logs(self, *levels):
|
||||
"""Return all log messages with level in *levels*.
|
||||
def get_logs(self, level=logging.WARNING, flush=True):
|
||||
"""Return all log messages with given level.
|
||||
|
||||
Without explicit levels given, returns all messages. *levels* defaults
|
||||
to all levels. For log calls with arguments (i.e.
|
||||
logger.info('bla bla %r', arg)), the messages will be formatted before
|
||||
being returned (e.g. "bla bla 'thing'").
|
||||
*level* defaults to logging.WARNING.
|
||||
|
||||
For log calls with arguments (i.e. logger.info('bla bla %r', arg)),
|
||||
the messages will be formatted before being returned (e.g. "bla bla
|
||||
'thing'").
|
||||
|
||||
Returns a list. Automatically flushes the loghandler after being
|
||||
called.
|
||||
|
||||
Example: self.get_logs(logging.WARN, logging.DEBUG).
|
||||
called, unless *flush* is False (this is useful to get e.g. all
|
||||
warnings then all info messages).
|
||||
"""
|
||||
if not levels:
|
||||
messages = [log.getMessage() for log in self.loghandler.buffer]
|
||||
else:
|
||||
messages = [log.getMessage() for log in self.loghandler.buffer
|
||||
if log.levelno in levels]
|
||||
self.loghandler.flush()
|
||||
messages = [log.getMessage() for log in self.loghandler.buffer
|
||||
if log.levelno == level]
|
||||
if flush:
|
||||
self.loghandler.flush()
|
||||
return messages
|
||||
|
||||
|
||||
|
|
|
@ -102,6 +102,40 @@ class BuildPyTestCase(support.TempdirManager,
|
|||
os.chdir(cwd)
|
||||
sys.stdout = old_stdout
|
||||
|
||||
@unittest.skipIf(sys.dont_write_bytecode, 'byte-compile disabled')
|
||||
def test_byte_compile(self):
|
||||
project_dir, dist = self.create_dist(py_modules=['boiledeggs'])
|
||||
os.chdir(project_dir)
|
||||
self.write_file('boiledeggs.py', 'import antigravity')
|
||||
cmd = build_py(dist)
|
||||
cmd.compile = True
|
||||
cmd.build_lib = 'here'
|
||||
cmd.finalize_options()
|
||||
cmd.run()
|
||||
|
||||
found = os.listdir(cmd.build_lib)
|
||||
self.assertEqual(sorted(found), ['__pycache__', 'boiledeggs.py'])
|
||||
found = os.listdir(os.path.join(cmd.build_lib, '__pycache__'))
|
||||
self.assertEqual(found, ['boiledeggs.%s.pyc' % imp.get_tag()])
|
||||
|
||||
@unittest.skipIf(sys.dont_write_bytecode, 'byte-compile disabled')
|
||||
def test_byte_compile_optimized(self):
|
||||
project_dir, dist = self.create_dist(py_modules=['boiledeggs'])
|
||||
os.chdir(project_dir)
|
||||
self.write_file('boiledeggs.py', 'import antigravity')
|
||||
cmd = build_py(dist)
|
||||
cmd.compile = True
|
||||
cmd.optimize = 1
|
||||
cmd.build_lib = 'here'
|
||||
cmd.finalize_options()
|
||||
cmd.run()
|
||||
|
||||
found = os.listdir(cmd.build_lib)
|
||||
self.assertEqual(sorted(found), ['__pycache__', 'boiledeggs.py'])
|
||||
found = os.listdir(os.path.join(cmd.build_lib, '__pycache__'))
|
||||
self.assertEqual(sorted(found), ['boiledeggs.%s.pyc' % imp.get_tag(),
|
||||
'boiledeggs.%s.pyo' % imp.get_tag()])
|
||||
|
||||
def test_dont_write_bytecode(self):
|
||||
# makes sure byte_compile is not used
|
||||
pkg_dir, dist = self.create_dist()
|
||||
|
@ -118,6 +152,7 @@ class BuildPyTestCase(support.TempdirManager,
|
|||
|
||||
self.assertIn('byte-compiling is disabled', self.get_logs()[0])
|
||||
|
||||
|
||||
def test_suite():
|
||||
return unittest.makeSuite(BuildPyTestCase)
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
"""Tests for distutils.command.check."""
|
||||
|
||||
import logging
|
||||
from packaging.command.check import check
|
||||
from packaging.metadata import _HAS_DOCUTILS
|
||||
from packaging.errors import PackagingSetupError, MetadataMissingError
|
||||
|
@ -27,11 +26,11 @@ class CheckTestCase(support.LoggingCatcher,
|
|||
# let's run the command with no metadata at all
|
||||
# by default, check is checking the metadata
|
||||
# should have some warnings
|
||||
cmd = self._run()
|
||||
self._run()
|
||||
# trick: using assertNotEqual with an empty list will give us a more
|
||||
# useful error message than assertGreater(.., 0) when the code change
|
||||
# and the test fails
|
||||
self.assertNotEqual([], self.get_logs(logging.WARNING))
|
||||
self.assertNotEqual(self.get_logs(), [])
|
||||
|
||||
# now let's add the required fields
|
||||
# and run it again, to make sure we don't get
|
||||
|
@ -40,8 +39,8 @@ class CheckTestCase(support.LoggingCatcher,
|
|||
'author_email': 'xxx',
|
||||
'name': 'xxx', 'version': '4.2',
|
||||
}
|
||||
cmd = self._run(metadata)
|
||||
self.assertEqual([], self.get_logs(logging.WARNING))
|
||||
self._run(metadata)
|
||||
self.assertEqual(self.get_logs(), [])
|
||||
|
||||
# now with the strict mode, we should
|
||||
# get an error if there are missing metadata
|
||||
|
@ -53,8 +52,8 @@ class CheckTestCase(support.LoggingCatcher,
|
|||
self.loghandler.flush()
|
||||
|
||||
# and of course, no error when all metadata fields are present
|
||||
cmd = self._run(metadata, strict=True)
|
||||
self.assertEqual([], self.get_logs(logging.WARNING))
|
||||
self._run(metadata, strict=True)
|
||||
self.assertEqual(self.get_logs(), [])
|
||||
|
||||
# now a test with non-ASCII characters
|
||||
metadata = {'home_page': 'xxx', 'author': '\u00c9ric',
|
||||
|
@ -62,15 +61,15 @@ class CheckTestCase(support.LoggingCatcher,
|
|||
'version': '1.2',
|
||||
'summary': 'Something about esszet \u00df',
|
||||
'description': 'More things about esszet \u00df'}
|
||||
cmd = self._run(metadata)
|
||||
self.assertEqual([], self.get_logs(logging.WARNING))
|
||||
self._run(metadata)
|
||||
self.assertEqual(self.get_logs(), [])
|
||||
|
||||
def test_check_metadata_1_2(self):
|
||||
# let's run the command with no metadata at all
|
||||
# by default, check is checking the metadata
|
||||
# should have some warnings
|
||||
cmd = self._run()
|
||||
self.assertNotEqual([], self.get_logs(logging.WARNING))
|
||||
self._run()
|
||||
self.assertNotEqual(self.get_logs(), [])
|
||||
|
||||
# now let's add the required fields and run it again, to make sure we
|
||||
# don't get any warning anymore let's use requires_python as a marker
|
||||
|
@ -80,8 +79,8 @@ class CheckTestCase(support.LoggingCatcher,
|
|||
'name': 'xxx', 'version': '4.2',
|
||||
'requires_python': '2.4',
|
||||
}
|
||||
cmd = self._run(metadata)
|
||||
self.assertEqual([], self.get_logs(logging.WARNING))
|
||||
self._run(metadata)
|
||||
self.assertEqual(self.get_logs(), [])
|
||||
|
||||
# now with the strict mode, we should
|
||||
# get an error if there are missing metadata
|
||||
|
@ -99,8 +98,8 @@ class CheckTestCase(support.LoggingCatcher,
|
|||
|
||||
# now with correct version format again
|
||||
metadata['version'] = '4.2'
|
||||
cmd = self._run(metadata, strict=True)
|
||||
self.assertEqual([], self.get_logs(logging.WARNING))
|
||||
self._run(metadata, strict=True)
|
||||
self.assertEqual(self.get_logs(), [])
|
||||
|
||||
@unittest.skipUnless(_HAS_DOCUTILS, "requires docutils")
|
||||
def test_check_restructuredtext(self):
|
||||
|
@ -109,9 +108,7 @@ class CheckTestCase(support.LoggingCatcher,
|
|||
pkg_info, dist = self.create_dist(description=broken_rest)
|
||||
cmd = check(dist)
|
||||
cmd.check_restructuredtext()
|
||||
self.assertEqual(len(self.get_logs(logging.WARNING)), 1)
|
||||
# clear warnings from the previous call
|
||||
self.loghandler.flush()
|
||||
self.assertEqual(len(self.get_logs()), 1)
|
||||
|
||||
# let's see if we have an error with strict=1
|
||||
metadata = {'home_page': 'xxx', 'author': 'xxx',
|
||||
|
@ -126,7 +123,7 @@ class CheckTestCase(support.LoggingCatcher,
|
|||
dist = self.create_dist(description='title\n=====\n\ntest \u00df')[1]
|
||||
cmd = check(dist)
|
||||
cmd.check_restructuredtext()
|
||||
self.assertEqual([], self.get_logs(logging.WARNING))
|
||||
self.assertEqual(self.get_logs(), [])
|
||||
|
||||
def test_check_all(self):
|
||||
self.assertRaises(PackagingSetupError, self._run,
|
||||
|
@ -143,18 +140,18 @@ class CheckTestCase(support.LoggingCatcher,
|
|||
}
|
||||
cmd = check(dist)
|
||||
cmd.check_hooks_resolvable()
|
||||
self.assertEqual(len(self.get_logs(logging.WARNING)), 1)
|
||||
self.assertEqual(len(self.get_logs()), 1)
|
||||
|
||||
def test_warn(self):
|
||||
_, dist = self.create_dist()
|
||||
cmd = check(dist)
|
||||
self.assertEqual([], self.get_logs())
|
||||
self.assertEqual(self.get_logs(), [])
|
||||
cmd.warn('hello')
|
||||
self.assertEqual(['check: hello'], self.get_logs())
|
||||
self.assertEqual(self.get_logs(), ['check: hello'])
|
||||
cmd.warn('hello %s', 'world')
|
||||
self.assertEqual(['check: hello world'], self.get_logs())
|
||||
self.assertEqual(self.get_logs(), ['check: hello world'])
|
||||
cmd.warn('hello %s %s', 'beautiful', 'world')
|
||||
self.assertEqual(['check: hello beautiful world'], self.get_logs())
|
||||
self.assertEqual(self.get_logs(), ['check: hello beautiful world'])
|
||||
|
||||
|
||||
def test_suite():
|
||||
|
|
|
@ -23,7 +23,7 @@ class cleanTestCase(support.TempdirManager, support.LoggingCatcher,
|
|||
if name == 'build_base':
|
||||
continue
|
||||
for f in ('one', 'two', 'three'):
|
||||
self.write_file(os.path.join(path, f))
|
||||
self.write_file((path, f))
|
||||
|
||||
# let's run the command
|
||||
cmd.all = True
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
"""Tests for distutils.cmd."""
|
||||
import os
|
||||
import logging
|
||||
|
||||
from packaging.command.cmd import Command
|
||||
from packaging.dist import Distribution
|
||||
|
@ -43,7 +44,7 @@ class CommandTestCase(support.LoggingCatcher,
|
|||
|
||||
wanted = ["command options for 'MyCmd':", ' option1 = 1',
|
||||
' option2 = 1']
|
||||
msgs = self.get_logs()
|
||||
msgs = self.get_logs(logging.INFO)
|
||||
self.assertEqual(msgs, wanted)
|
||||
|
||||
def test_ensure_string(self):
|
||||
|
|
|
@ -117,6 +117,11 @@ class InstallDataTestCase(support.TempdirManager,
|
|||
dist.command_obj['install_distinfo'] = cmd
|
||||
cmd.run()
|
||||
|
||||
# first a few sanity checks
|
||||
self.assertEqual(os.listdir(scripts_dir), ['spamd'])
|
||||
self.assertEqual(os.listdir(install_dir), ['Spamlib-0.1.dist-info'])
|
||||
|
||||
# now the real test
|
||||
fn = os.path.join(install_dir, 'Spamlib-0.1.dist-info', 'RESOURCES')
|
||||
with open(fn, encoding='utf-8') as fp:
|
||||
content = fp.read().strip()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""Tests for packaging.command.install."""
|
||||
|
||||
import os
|
||||
import imp
|
||||
import sys
|
||||
from sysconfig import (get_scheme_names, get_config_vars,
|
||||
_SCHEMES, get_config_var, get_path)
|
||||
|
@ -92,21 +93,20 @@ class InstallTestCase(support.TempdirManager,
|
|||
self.old_expand = os.path.expanduser
|
||||
os.path.expanduser = _expanduser
|
||||
|
||||
try:
|
||||
# this is the actual test
|
||||
self._test_user_site()
|
||||
finally:
|
||||
def cleanup():
|
||||
_CONFIG_VARS['userbase'] = self.old_user_base
|
||||
_SCHEMES.set(scheme, 'purelib', self.old_user_site)
|
||||
os.path.expanduser = self.old_expand
|
||||
|
||||
def _test_user_site(self):
|
||||
self.addCleanup(cleanup)
|
||||
|
||||
schemes = get_scheme_names()
|
||||
for key in ('nt_user', 'posix_user', 'os2_home'):
|
||||
self.assertIn(key, schemes)
|
||||
|
||||
dist = Distribution({'name': 'xx'})
|
||||
cmd = install_dist(dist)
|
||||
|
||||
# making sure the user option is there
|
||||
options = [name for name, short, lable in
|
||||
cmd.user_options]
|
||||
|
@ -181,9 +181,11 @@ class InstallTestCase(support.TempdirManager,
|
|||
def test_old_record(self):
|
||||
# test pre-PEP 376 --record option (outside dist-info dir)
|
||||
install_dir = self.mkdtemp()
|
||||
project_dir, dist = self.create_dist(scripts=['hello'])
|
||||
project_dir, dist = self.create_dist(py_modules=['hello'],
|
||||
scripts=['sayhi'])
|
||||
os.chdir(project_dir)
|
||||
self.write_file('hello', "print('o hai')")
|
||||
self.write_file('hello.py', "def main(): print('o hai')")
|
||||
self.write_file('sayhi', 'from hello import main; main()')
|
||||
|
||||
cmd = install_dist(dist)
|
||||
dist.command_obj['install_dist'] = cmd
|
||||
|
@ -196,8 +198,9 @@ class InstallTestCase(support.TempdirManager,
|
|||
content = f.read()
|
||||
|
||||
found = [os.path.basename(line) for line in content.splitlines()]
|
||||
expected = ['hello', 'METADATA', 'INSTALLER', 'REQUESTED', 'RECORD']
|
||||
self.assertEqual(found, expected)
|
||||
expected = ['hello.py', 'hello.%s.pyc' % imp.get_tag(), 'sayhi',
|
||||
'METADATA', 'INSTALLER', 'REQUESTED', 'RECORD']
|
||||
self.assertEqual(sorted(found), sorted(expected))
|
||||
|
||||
# XXX test that fancy_getopt is okay with options named
|
||||
# record and no-record but unrelated
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
import os
|
||||
import zipfile
|
||||
import tarfile
|
||||
import logging
|
||||
|
||||
from packaging.tests.support import requires_zlib
|
||||
|
||||
|
@ -221,7 +220,7 @@ class SDistTestCase(support.TempdirManager,
|
|||
# with the check subcommand
|
||||
cmd.ensure_finalized()
|
||||
cmd.run()
|
||||
warnings = self.get_logs(logging.WARN)
|
||||
warnings = self.get_logs()
|
||||
self.assertEqual(len(warnings), 4)
|
||||
|
||||
# trying with a complete set of metadata
|
||||
|
@ -230,13 +229,10 @@ class SDistTestCase(support.TempdirManager,
|
|||
cmd.ensure_finalized()
|
||||
cmd.metadata_check = False
|
||||
cmd.run()
|
||||
warnings = self.get_logs(logging.WARN)
|
||||
# removing manifest generated warnings
|
||||
warnings = [warn for warn in warnings if
|
||||
not warn.endswith('-- skipping')]
|
||||
# the remaining warnings are about the use of the default file list and
|
||||
# the absence of setup.cfg
|
||||
warnings = self.get_logs()
|
||||
self.assertEqual(len(warnings), 2)
|
||||
self.assertIn('using default file list', warnings[0])
|
||||
self.assertIn("'setup.cfg' file not found", warnings[1])
|
||||
|
||||
def test_show_formats(self):
|
||||
__, stdout = captured_stdout(show_formats)
|
||||
|
|
|
@ -2,7 +2,6 @@ import os
|
|||
import re
|
||||
import sys
|
||||
import shutil
|
||||
import logging
|
||||
import unittest as ut1
|
||||
import packaging.database
|
||||
|
||||
|
@ -140,7 +139,8 @@ class TestTest(TempdirManager,
|
|||
cmd.run()
|
||||
self.assertEqual(['build has run'], record)
|
||||
|
||||
def _test_works_with_2to3(self):
|
||||
@unittest.skip('needs to be written')
|
||||
def test_works_with_2to3(self):
|
||||
pass
|
||||
|
||||
def test_checks_requires(self):
|
||||
|
@ -149,7 +149,7 @@ class TestTest(TempdirManager,
|
|||
phony_project = 'ohno_ohno-impossible_1234-name_stop-that!'
|
||||
cmd.tests_require = [phony_project]
|
||||
cmd.ensure_finalized()
|
||||
logs = self.get_logs(logging.WARNING)
|
||||
logs = self.get_logs()
|
||||
self.assertIn(phony_project, logs[-1])
|
||||
|
||||
def prepare_a_module(self):
|
||||
|
|
|
@ -129,7 +129,7 @@ class UploadTestCase(support.TempdirManager, support.EnvironRestorer,
|
|||
dist_files = [(command, pyversion, filename)]
|
||||
docs_path = os.path.join(self.tmp_dir, "build", "docs")
|
||||
os.makedirs(docs_path)
|
||||
self.write_file(os.path.join(docs_path, "index.html"), "yellow")
|
||||
self.write_file((docs_path, "index.html"), "yellow")
|
||||
self.write_file(self.rc, PYPIRC)
|
||||
|
||||
# let's run it
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""Tests for packaging.command.upload_docs."""
|
||||
import os
|
||||
import shutil
|
||||
import logging
|
||||
import zipfile
|
||||
try:
|
||||
import _ssl
|
||||
|
@ -70,9 +71,8 @@ class UploadDocsTestCase(support.TempdirManager,
|
|||
if sample_dir is None:
|
||||
sample_dir = self.mkdtemp()
|
||||
os.mkdir(os.path.join(sample_dir, "docs"))
|
||||
self.write_file(os.path.join(sample_dir, "docs", "index.html"),
|
||||
"Ce mortel ennui")
|
||||
self.write_file(os.path.join(sample_dir, "index.html"), "Oh la la")
|
||||
self.write_file((sample_dir, "docs", "index.html"), "Ce mortel ennui")
|
||||
self.write_file((sample_dir, "index.html"), "Oh la la")
|
||||
return sample_dir
|
||||
|
||||
def test_zip_dir(self):
|
||||
|
@ -141,13 +141,16 @@ class UploadDocsTestCase(support.TempdirManager,
|
|||
self.pypi.default_response_status = '403 Forbidden'
|
||||
self.prepare_command()
|
||||
self.cmd.run()
|
||||
self.assertIn('Upload failed (403): Forbidden', self.get_logs()[-1])
|
||||
errors = self.get_logs(logging.ERROR)
|
||||
self.assertEqual(len(errors), 1)
|
||||
self.assertIn('Upload failed (403): Forbidden', errors[0])
|
||||
|
||||
self.pypi.default_response_status = '301 Moved Permanently'
|
||||
self.pypi.default_response_headers.append(
|
||||
("Location", "brand_new_location"))
|
||||
self.cmd.run()
|
||||
self.assertIn('brand_new_location', self.get_logs()[-1])
|
||||
lastlog = self.get_logs(logging.INFO)[-1]
|
||||
self.assertIn('brand_new_location', lastlog)
|
||||
|
||||
def test_reads_pypirc_data(self):
|
||||
self.write_file(self.rc, PYPIRC % self.pypi.full_address)
|
||||
|
@ -171,7 +174,7 @@ class UploadDocsTestCase(support.TempdirManager,
|
|||
self.prepare_command()
|
||||
self.cmd.show_response = True
|
||||
self.cmd.run()
|
||||
record = self.get_logs()[-1]
|
||||
record = self.get_logs(logging.INFO)[-1]
|
||||
self.assertTrue(record, "should report the response")
|
||||
self.assertIn(self.pypi.default_response_data, record)
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
"""Tests for packaging.config."""
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
from io import StringIO
|
||||
|
||||
from packaging import command
|
||||
|
@ -375,15 +374,14 @@ class ConfigTestCase(support.TempdirManager,
|
|||
self.write_file('README', 'yeah')
|
||||
self.write_file('hooks.py', HOOKS_MODULE)
|
||||
self.get_dist()
|
||||
logs = self.get_logs(logging.WARNING)
|
||||
self.assertEqual(['logging_hook called'], logs)
|
||||
self.assertEqual(['logging_hook called'], self.get_logs())
|
||||
self.assertIn('hooks', sys.modules)
|
||||
|
||||
def test_missing_setup_hook_warns(self):
|
||||
self.write_setup({'setup-hooks': 'this.does._not.exist'})
|
||||
self.write_file('README', 'yeah')
|
||||
self.get_dist()
|
||||
logs = self.get_logs(logging.WARNING)
|
||||
logs = self.get_logs()
|
||||
self.assertEqual(1, len(logs))
|
||||
self.assertIn('cannot find setup hook', logs[0])
|
||||
|
||||
|
@ -397,7 +395,7 @@ class ConfigTestCase(support.TempdirManager,
|
|||
dist = self.get_dist()
|
||||
|
||||
self.assertEqual(['haven', 'first', 'third'], dist.py_modules)
|
||||
logs = self.get_logs(logging.WARNING)
|
||||
logs = self.get_logs()
|
||||
self.assertEqual(1, len(logs))
|
||||
self.assertIn('cannot find setup hook', logs[0])
|
||||
|
||||
|
|
|
@ -80,8 +80,7 @@ class CreateTestCase(support.TempdirManager,
|
|||
os.mkdir(os.path.join(tempdir, dir_))
|
||||
|
||||
for file_ in files:
|
||||
path = os.path.join(tempdir, file_)
|
||||
self.write_file(path, 'xxx')
|
||||
self.write_file((tempdir, file_), 'xxx')
|
||||
|
||||
mainprogram._find_files()
|
||||
mainprogram.data['packages'].sort()
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
"""Tests for packaging.dist."""
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
import textwrap
|
||||
|
||||
import packaging.dist
|
||||
|
||||
from packaging.dist import Distribution
|
||||
from packaging.command import set_command
|
||||
from packaging.command import set_command, _COMMANDS
|
||||
from packaging.command.cmd import Command
|
||||
from packaging.errors import PackagingModuleError, PackagingOptionError
|
||||
from packaging.tests import captured_stdout
|
||||
|
@ -29,6 +28,9 @@ class test_dist(Command):
|
|||
def finalize_options(self):
|
||||
pass
|
||||
|
||||
def run(self):
|
||||
pass
|
||||
|
||||
|
||||
class DistributionTestCase(support.TempdirManager,
|
||||
support.LoggingCatcher,
|
||||
|
@ -39,12 +41,18 @@ class DistributionTestCase(support.TempdirManager,
|
|||
|
||||
def setUp(self):
|
||||
super(DistributionTestCase, self).setUp()
|
||||
# XXX this is ugly, we should fix the functions to accept args
|
||||
# (defaulting to sys.argv)
|
||||
self.argv = sys.argv, sys.argv[:]
|
||||
del sys.argv[1:]
|
||||
self._commands = _COMMANDS.copy()
|
||||
|
||||
def tearDown(self):
|
||||
sys.argv = self.argv[0]
|
||||
sys.argv[:] = self.argv[1]
|
||||
# XXX maybe we need a public API to remove commands
|
||||
_COMMANDS.clear()
|
||||
_COMMANDS.update(self._commands)
|
||||
super(DistributionTestCase, self).tearDown()
|
||||
|
||||
@unittest.skip('needs to be updated')
|
||||
|
@ -74,7 +82,7 @@ class DistributionTestCase(support.TempdirManager,
|
|||
'version': '1.2',
|
||||
'home_page': 'xxxx',
|
||||
'badoptname': 'xxx'})
|
||||
logs = self.get_logs(logging.WARNING)
|
||||
logs = self.get_logs()
|
||||
self.assertEqual(len(logs), 1)
|
||||
self.assertIn('unknown argument', logs[0])
|
||||
|
||||
|
@ -85,7 +93,7 @@ class DistributionTestCase(support.TempdirManager,
|
|||
'version': '1.2', 'home_page': 'xxxx',
|
||||
'options': {}})
|
||||
|
||||
self.assertEqual([], self.get_logs(logging.WARNING))
|
||||
self.assertEqual(self.get_logs(), [])
|
||||
self.assertNotIn('options', dir(dist))
|
||||
|
||||
def test_non_empty_options(self):
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
"""Tests for packaging.manifest."""
|
||||
import os
|
||||
import re
|
||||
import logging
|
||||
from io import StringIO
|
||||
from packaging.errors import PackagingTemplateError
|
||||
from packaging.manifest import Manifest, _translate_pattern, _glob_to_re
|
||||
|
@ -37,10 +36,10 @@ class ManifestTestCase(support.TempdirManager,
|
|||
super(ManifestTestCase, self).tearDown()
|
||||
|
||||
def assertNoWarnings(self):
|
||||
self.assertEqual(self.get_logs(logging.WARNING), [])
|
||||
self.assertEqual(self.get_logs(), [])
|
||||
|
||||
def assertWarnings(self):
|
||||
self.assertGreater(len(self.get_logs(logging.WARNING)), 0)
|
||||
self.assertNotEqual(self.get_logs(), [])
|
||||
|
||||
def test_manifest_reader(self):
|
||||
tmpdir = self.mkdtemp()
|
||||
|
@ -51,7 +50,7 @@ class ManifestTestCase(support.TempdirManager,
|
|||
manifest = Manifest()
|
||||
manifest.read_template(MANIFEST)
|
||||
|
||||
warnings = self.get_logs(logging.WARNING)
|
||||
warnings = self.get_logs()
|
||||
# the manifest should have been read and 3 warnings issued
|
||||
# (we didn't provide the files)
|
||||
self.assertEqual(3, len(warnings))
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
"""Tests for packaging.metadata."""
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
from textwrap import dedent
|
||||
from io import StringIO
|
||||
|
||||
|
@ -302,7 +301,7 @@ class MetadataTestCase(LoggingCatcher,
|
|||
'name': 'xxx',
|
||||
'version': 'xxx',
|
||||
'home_page': 'xxxx'})
|
||||
logs = self.get_logs(logging.WARNING)
|
||||
logs = self.get_logs()
|
||||
self.assertEqual(1, len(logs))
|
||||
self.assertIn('not a valid version', logs[0])
|
||||
|
||||
|
@ -418,7 +417,7 @@ class MetadataTestCase(LoggingCatcher,
|
|||
# XXX check PEP and see if 3 == 3.0
|
||||
metadata['Requires-Python'] = '>=2.6, <3.0'
|
||||
metadata['Requires-Dist'] = ['Foo (>=2.6, <3.0)']
|
||||
self.assertEqual([], self.get_logs(logging.WARNING))
|
||||
self.assertEqual(self.get_logs(), [])
|
||||
|
||||
@unittest.skip('needs to be implemented')
|
||||
def test_requires_illegal(self):
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import sys
|
||||
import textwrap
|
||||
|
||||
from packaging.tests import unittest, support
|
||||
|
|
|
@ -61,8 +61,7 @@ class UninstallTestCase(support.TempdirManager,
|
|||
kw['pkg'] = pkg
|
||||
|
||||
pkg_dir = os.path.join(project_dir, pkg)
|
||||
os.mkdir(pkg_dir)
|
||||
os.mkdir(os.path.join(pkg_dir, 'sub'))
|
||||
os.makedirs(os.path.join(pkg_dir, 'sub'))
|
||||
|
||||
self.write_file((project_dir, 'setup.cfg'), SETUP_CFG % kw)
|
||||
self.write_file((pkg_dir, '__init__.py'), '#')
|
||||
|
|
|
@ -4,6 +4,7 @@ import sys
|
|||
import time
|
||||
import logging
|
||||
import tempfile
|
||||
import textwrap
|
||||
import subprocess
|
||||
from io import StringIO
|
||||
|
||||
|
@ -355,55 +356,64 @@ class UtilTestCase(support.EnvironRestorer,
|
|||
#
|
||||
root = self.mkdtemp()
|
||||
pkg1 = os.path.join(root, 'pkg1')
|
||||
os.mkdir(pkg1)
|
||||
self.write_file(os.path.join(pkg1, '__init__.py'))
|
||||
os.mkdir(os.path.join(pkg1, 'pkg2'))
|
||||
self.write_file(os.path.join(pkg1, 'pkg2', '__init__.py'))
|
||||
os.mkdir(os.path.join(pkg1, 'pkg3'))
|
||||
self.write_file(os.path.join(pkg1, 'pkg3', '__init__.py'))
|
||||
os.mkdir(os.path.join(pkg1, 'pkg3', 'pkg6'))
|
||||
self.write_file(os.path.join(pkg1, 'pkg3', 'pkg6', '__init__.py'))
|
||||
os.mkdir(os.path.join(pkg1, 'pkg4'))
|
||||
os.mkdir(os.path.join(pkg1, 'pkg4', 'pkg8'))
|
||||
self.write_file(os.path.join(pkg1, 'pkg4', 'pkg8', '__init__.py'))
|
||||
pkg5 = os.path.join(root, 'pkg5')
|
||||
os.mkdir(pkg5)
|
||||
self.write_file(os.path.join(pkg5, '__init__.py'))
|
||||
os.makedirs(os.path.join(pkg1, 'pkg2'))
|
||||
os.makedirs(os.path.join(pkg1, 'pkg3', 'pkg6'))
|
||||
os.makedirs(os.path.join(pkg1, 'pkg4', 'pkg8'))
|
||||
os.makedirs(os.path.join(root, 'pkg5'))
|
||||
self.write_file((pkg1, '__init__.py'))
|
||||
self.write_file((pkg1, 'pkg2', '__init__.py'))
|
||||
self.write_file((pkg1, 'pkg3', '__init__.py'))
|
||||
self.write_file((pkg1, 'pkg3', 'pkg6', '__init__.py'))
|
||||
self.write_file((pkg1, 'pkg4', 'pkg8', '__init__.py'))
|
||||
self.write_file((root, 'pkg5', '__init__.py'))
|
||||
|
||||
res = find_packages([root], ['pkg1.pkg2'])
|
||||
self.assertEqual(set(res), set(['pkg1', 'pkg5', 'pkg1.pkg3',
|
||||
'pkg1.pkg3.pkg6']))
|
||||
self.assertEqual(sorted(res),
|
||||
['pkg1', 'pkg1.pkg3', 'pkg1.pkg3.pkg6', 'pkg5'])
|
||||
|
||||
def test_resolve_name(self):
|
||||
self.assertIs(str, resolve_name('builtins.str'))
|
||||
self.assertEqual(
|
||||
UtilTestCase.__name__,
|
||||
resolve_name("packaging.tests.test_util.UtilTestCase").__name__)
|
||||
self.assertEqual(
|
||||
UtilTestCase.test_resolve_name.__name__,
|
||||
resolve_name("packaging.tests.test_util.UtilTestCase."
|
||||
"test_resolve_name").__name__)
|
||||
# test raw module name
|
||||
tmpdir = self.mkdtemp()
|
||||
sys.path.append(tmpdir)
|
||||
self.addCleanup(sys.path.remove, tmpdir)
|
||||
self.write_file((tmpdir, 'hello.py'), '')
|
||||
|
||||
self.assertRaises(ImportError, resolve_name,
|
||||
"packaging.tests.test_util.UtilTestCaseNot")
|
||||
self.assertRaises(ImportError, resolve_name,
|
||||
"packaging.tests.test_util.UtilTestCase."
|
||||
"nonexistent_attribute")
|
||||
os.makedirs(os.path.join(tmpdir, 'a', 'b'))
|
||||
self.write_file((tmpdir, 'a', '__init__.py'), '')
|
||||
self.write_file((tmpdir, 'a', 'b', '__init__.py'), '')
|
||||
self.write_file((tmpdir, 'a', 'b', 'c.py'), 'class Foo: pass')
|
||||
self.write_file((tmpdir, 'a', 'b', 'd.py'), textwrap.dedent("""\
|
||||
class FooBar:
|
||||
class Bar:
|
||||
def baz(self):
|
||||
pass
|
||||
"""))
|
||||
|
||||
def test_import_nested_first_time(self):
|
||||
tmp_dir = self.mkdtemp()
|
||||
os.makedirs(os.path.join(tmp_dir, 'a', 'b'))
|
||||
self.write_file(os.path.join(tmp_dir, 'a', '__init__.py'), '')
|
||||
self.write_file(os.path.join(tmp_dir, 'a', 'b', '__init__.py'), '')
|
||||
self.write_file(os.path.join(tmp_dir, 'a', 'b', 'c.py'),
|
||||
'class Foo: pass')
|
||||
# check Python, C and built-in module
|
||||
self.assertEqual(resolve_name('hello').__name__, 'hello')
|
||||
self.assertEqual(resolve_name('_csv').__name__, '_csv')
|
||||
self.assertEqual(resolve_name('sys').__name__, 'sys')
|
||||
|
||||
try:
|
||||
sys.path.append(tmp_dir)
|
||||
resolve_name("a.b.c.Foo")
|
||||
# assert nothing raised
|
||||
finally:
|
||||
sys.path.remove(tmp_dir)
|
||||
# test module.attr
|
||||
self.assertIs(resolve_name('builtins.str'), str)
|
||||
self.assertIsNone(resolve_name('hello.__doc__'))
|
||||
self.assertEqual(resolve_name('a.b.c.Foo').__name__, 'Foo')
|
||||
self.assertEqual(resolve_name('a.b.d.FooBar.Bar.baz').__name__, 'baz')
|
||||
|
||||
# error if module not found
|
||||
self.assertRaises(ImportError, resolve_name, 'nonexistent')
|
||||
self.assertRaises(ImportError, resolve_name, 'non.existent')
|
||||
self.assertRaises(ImportError, resolve_name, 'a.no')
|
||||
self.assertRaises(ImportError, resolve_name, 'a.b.no')
|
||||
self.assertRaises(ImportError, resolve_name, 'a.b.no.no')
|
||||
self.assertRaises(ImportError, resolve_name, 'inva-lid')
|
||||
|
||||
# looking up built-in names is not supported
|
||||
self.assertRaises(ImportError, resolve_name, 'str')
|
||||
|
||||
# error if module found but not attr
|
||||
self.assertRaises(ImportError, resolve_name, 'a.b.Spam')
|
||||
self.assertRaises(ImportError, resolve_name, 'a.b.c.Spam')
|
||||
|
||||
def test_run_2to3_on_code(self):
|
||||
content = "print 'test'"
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
"""Tests for packaging.version."""
|
||||
import doctest
|
||||
import os
|
||||
|
||||
from packaging.version import NormalizedVersion as V
|
||||
from packaging.version import HugeMajorVersionNumError, IrrationalVersionError
|
||||
|
@ -46,7 +45,6 @@ class VersionTestCase(unittest.TestCase):
|
|||
def test_from_parts(self):
|
||||
|
||||
for v, s in self.versions:
|
||||
parts = v.parts
|
||||
v2 = V.from_parts(*v.parts)
|
||||
self.assertEqual(v, v2)
|
||||
self.assertEqual(str(v), str(v2))
|
||||
|
@ -192,7 +190,7 @@ class VersionTestCase(unittest.TestCase):
|
|||
'Hey (>=2.5,<2.7)')
|
||||
|
||||
for predicate in predicates:
|
||||
v = VersionPredicate(predicate)
|
||||
VersionPredicate(predicate)
|
||||
|
||||
self.assertTrue(VersionPredicate('Hey (>=2.5,<2.7)').match('2.6'))
|
||||
self.assertTrue(VersionPredicate('Ho').match('2.6'))
|
||||
|
|
|
@ -630,22 +630,35 @@ def find_packages(paths=(os.curdir,), exclude=()):
|
|||
def resolve_name(name):
|
||||
"""Resolve a name like ``module.object`` to an object and return it.
|
||||
|
||||
Raise ImportError if the module or name is not found.
|
||||
This functions supports packages and attributes without depth limitation:
|
||||
``package.package.module.class.class.function.attr`` is valid input.
|
||||
However, looking up builtins is not directly supported: use
|
||||
``builtins.name``.
|
||||
|
||||
Raises ImportError if importing the module fails or if one requested
|
||||
attribute is not found.
|
||||
"""
|
||||
if '.' not in name:
|
||||
# shortcut
|
||||
__import__(name)
|
||||
return sys.modules[name]
|
||||
|
||||
# FIXME clean up this code!
|
||||
parts = name.split('.')
|
||||
cursor = len(parts)
|
||||
module_name = parts[:cursor]
|
||||
ret = ''
|
||||
|
||||
while cursor > 0:
|
||||
try:
|
||||
ret = __import__('.'.join(module_name))
|
||||
break
|
||||
except ImportError:
|
||||
if cursor == 0:
|
||||
raise
|
||||
cursor -= 1
|
||||
module_name = parts[:cursor]
|
||||
ret = ''
|
||||
|
||||
if ret == '':
|
||||
raise ImportError(parts[0])
|
||||
|
||||
for part in parts[1:]:
|
||||
try:
|
||||
|
|
|
@ -1455,7 +1455,7 @@ Tests
|
|||
the amount of time needed to run the tests. "make test" and "make quicktest"
|
||||
now include some resource-intensive tests, but no longer run the test suite
|
||||
twice to check for bugs in .pyc generation. Tools/scripts/run_test.py provides
|
||||
as an easy platform-independent way to run test suite with sensible defaults.
|
||||
an easy platform-independent way to run test suite with sensible defaults.
|
||||
|
||||
- Issue #12331: The test suite for the packaging module can now run from an
|
||||
installed Python.
|
||||
|
|
3
setup.py
3
setup.py
|
@ -1380,8 +1380,7 @@ class PyBuildExt(build_ext):
|
|||
# End multiprocessing
|
||||
|
||||
# Platform-specific libraries
|
||||
if any(platform.startswith(prefix)
|
||||
for prefix in ("linux", "freebsd", "gnukfreebsd")):
|
||||
if platform.startswith(('linux', 'freebsd', 'gnukfreebsd')):
|
||||
exts.append( Extension('ossaudiodev', ['ossaudiodev.c']) )
|
||||
else:
|
||||
missing.append('ossaudiodev')
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue