summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/deprecated/python3.rst94
-rw-r--r--docs/references/keywords.rst15
-rw-r--r--docs/userguide/declarative_config.rst4
-rw-r--r--docs/userguide/development_mode.rst8
-rw-r--r--docs/userguide/keywords.rst12
-rw-r--r--pytest.ini3
-rw-r--r--setup.cfg5
-rw-r--r--setuptools/__init__.py43
-rw-r--r--setuptools/command/build_py.py44
-rw-r--r--setuptools/command/develop.py47
-rw-r--r--setuptools/command/test.py71
-rw-r--r--setuptools/config.py97
-rw-r--r--setuptools/dist.py168
-rw-r--r--setuptools/lib2to3_ex.py68
-rw-r--r--setuptools/sandbox.py86
-rw-r--r--setuptools/tests/__init__.py5
-rw-r--r--setuptools/tests/test_config.py353
-rw-r--r--setuptools/tests/test_develop.py73
-rw-r--r--setuptools/tests/test_test.py100
19 files changed, 434 insertions, 862 deletions
diff --git a/docs/deprecated/python3.rst b/docs/deprecated/python3.rst
deleted file mode 100644
index 6b55fe78..00000000
--- a/docs/deprecated/python3.rst
+++ /dev/null
@@ -1,94 +0,0 @@
-=====================================================
-Supporting both Python 2 and Python 3 with Setuptools
-=====================================================
-
-Starting with Distribute version 0.6.2 and Setuptools 0.7, the Setuptools
-project supported Python 3. Installing and
-using setuptools for Python 3 code works exactly the same as for Python 2
-code.
-
-Setuptools provides a facility to invoke 2to3 on the code as a part of the
-build process, by setting the keyword parameter ``use_2to3`` to True, but
-the Setuptools project strongly recommends instead developing a unified codebase
-using `six <https://pypi.org/project/six/>`_,
-`future <https://pypi.org/project/future/>`_, or another compatibility
-library.
-
-
-Using 2to3
-==========
-
-Setuptools attempts to make the porting process easier by automatically
-running
-2to3 as a part of running tests. To do so, you need to configure the
-setup.py so that you can run the unit tests with ``python setup.py test``.
-
-See :ref:`test` for more information on this.
-
-Once you have the tests running under Python 2, you can add the use_2to3
-keyword parameters to setup(), and start running the tests under Python 3.
-The test command will now first run the build command during which the code
-will be converted with 2to3, and the tests will then be run from the build
-directory, as opposed from the source directory as is normally done.
-
-Setuptools will convert all Python files, and also all doctests in Python
-files. However, if you have doctests located in separate text files, these
-will not automatically be converted. By adding them to the
-``convert_2to3_doctests`` keyword parameter Setuptools will convert them as
-well.
-
-By default, the conversion uses all fixers in the ``lib2to3.fixers`` package.
-To use additional fixers, the parameter ``use_2to3_fixers`` can be set
-to a list of names of packages containing fixers. To exclude fixers, the
-parameter ``use_2to3_exclude_fixers`` can be set to fixer names to be
-skipped.
-
-An example setup.py might look something like this::
-
- from setuptools import setup
-
- setup(
- name='your.module',
- version='1.0',
- description='This is your awesome module',
- author='You',
- author_email='your@email',
- package_dir={'': 'src'},
- packages=['your', 'you.module'],
- test_suite='your.module.tests',
- use_2to3=True,
- convert_2to3_doctests=['src/your/module/README.txt'],
- use_2to3_fixers=['your.fixers'],
- use_2to3_exclude_fixers=['lib2to3.fixes.fix_import'],
- )
-
-Differential conversion
------------------------
-
-Note that a file will only be copied and converted during the build process
-if the source file has been changed. If you add a file to the doctests
-that should be converted, it will not be converted the next time you run
-the tests, since it hasn't been modified. You need to remove it from the
-build directory. Also if you run the build, install or test commands before
-adding the use_2to3 parameter, you will have to remove the build directory
-before you run the test command, as the files otherwise will seem updated,
-and no conversion will happen.
-
-In general, if code doesn't seem to be converted, deleting the build directory
-and trying again is a good safeguard against the build directory getting
-"out of sync" with the source directory.
-
-Distributing Python 3 modules
-=============================
-
-You can distribute your modules with Python 3 support in different ways. A
-normal source distribution will work, but can be slow in installing, as the
-2to3 process will be run during the install. But you can also distribute
-the module in binary format, such as a binary egg. That egg will contain the
-already converted code, and hence no 2to3 conversion is needed during install.
-
-Advanced features
-=================
-
-If you don't want to run the 2to3 conversion on the doctests in Python files,
-you can turn that off by setting ``setuptools.use_2to3_on_doctests = False``.
diff --git a/docs/references/keywords.rst b/docs/references/keywords.rst
index 619b2d14..c26b9d49 100644
--- a/docs/references/keywords.rst
+++ b/docs/references/keywords.rst
@@ -330,21 +330,6 @@ Keywords
mess with it. For more details on how this argument works, see the section
below on :ref:`Automatic Resource Extraction`.
-``use_2to3``
- Convert the source code from Python 2 to Python 3 with 2to3 during the
- build process. See :doc:`../deprecated/python3` for more details.
-
-``convert_2to3_doctests``
- List of doctest source files that need to be converted with 2to3.
- See :doc:`../deprecated/python3` for more details.
-
-``use_2to3_fixers``
- A list of modules to search for additional fixers to be used during
- the 2to3 conversion. See :doc:`../deprecated/python3` for more details.
-
-``use_2to3_exclude_fixers``
- List of fixer names to be skipped.
-
``project_urls``
An arbitrary map of URL names to hyperlinks, allowing more extensible
documentation of where various resources can be found than the simple
diff --git a/docs/userguide/declarative_config.rst b/docs/userguide/declarative_config.rst
index 3b72611c..c50fcf6d 100644
--- a/docs/userguide/declarative_config.rst
+++ b/docs/userguide/declarative_config.rst
@@ -211,10 +211,6 @@ install_requires list-semi
extras_require section [#opt-2]_
python_requires str
entry_points file:, section 51.0.0
-use_2to3 bool
-use_2to3_fixers list-comma
-use_2to3_exclude_fixers list-comma
-convert_2to3_doctests list-comma
scripts list-comma
eager_resources list-comma
dependency_links list-comma
diff --git a/docs/userguide/development_mode.rst b/docs/userguide/development_mode.rst
index 3c477ec1..90bc5676 100644
--- a/docs/userguide/development_mode.rst
+++ b/docs/userguide/development_mode.rst
@@ -28,14 +28,6 @@ Python's ``site-packages`` directory, it will also update the
``easy-install.pth`` file to include your project's source code, thereby making
it available on ``sys.path`` for all programs using that Python installation.
-If you have enabled the ``use_2to3`` flag, then of course the ``.egg-link``
-will not link directly to your source code when run under Python 3, since
-that source code would be made for Python 2 and not work under Python 3.
-Instead the ``setup.py develop`` will build Python 3 code under the ``build``
-directory, and link there. This means that after doing code changes you will
-have to run ``setup.py build`` before these changes are picked up by your
-Python 3 installation.
-
In addition, the ``develop`` command creates wrapper scripts in the target
script directory that will run your in-development scripts after ensuring that
all your ``install_requires`` packages are available on ``sys.path``.
diff --git a/docs/userguide/keywords.rst b/docs/userguide/keywords.rst
index 268e4f42..5388ffea 100644
--- a/docs/userguide/keywords.rst
+++ b/docs/userguide/keywords.rst
@@ -157,18 +157,6 @@ unless you need the associated ``setuptools`` feature.
mess with it. For more details on how this argument works, see the section
below on :ref:`Automatic Resource Extraction`.
-``use_2to3``
- Convert the source code from Python 2 to Python 3 with 2to3 during the
- build process. See :doc:`../deprecated/python3` for more details.
-
-``convert_2to3_doctests``
- List of doctest source files that need to be converted with 2to3.
- See :doc:`../deprecated/python3` for more details.
-
-``use_2to3_fixers``
- A list of modules to search for additional fixers to be used during
- the 2to3 conversion. See :doc:`../deprecated/python3` for more details.
-
``project_urls``
An arbitrary map of URL names to hyperlinks, allowing more extensible
documentation of where various resources can be found than the simple
diff --git a/pytest.ini b/pytest.ini
index 307c5533..eebb212f 100644
--- a/pytest.ini
+++ b/pytest.ini
@@ -26,6 +26,3 @@ filterwarnings=
ignore:Parent module 'setuptools' not found while handling absolute import:RuntimeWarning
# Suppress use of bytes for filenames on Windows until fixed #2016
ignore:The Windows bytes API has been deprecated:DeprecationWarning
- # https://github.com/pypa/setuptools/issues/2081
- ignore:lib2to3 package is deprecated:PendingDeprecationWarning
- ignore:lib2to3 package is deprecated:DeprecationWarning
diff --git a/setup.cfg b/setup.cfg
index b1afa54f..f99259a5 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -106,7 +106,6 @@ distutils.commands =
setuptools.finalize_distribution_options =
parent_finalize = setuptools.dist:_Distribution.finalize_options
keywords = setuptools.dist:Distribution._finalize_setup_keywords
- 2to3_doctests = setuptools.dist:Distribution._finalize_2to3_doctests
distutils.setup_keywords =
eager_resources = setuptools.dist:assert_string_list
namespace_packages = setuptools.dist:check_nsp
@@ -125,10 +124,6 @@ distutils.setup_keywords =
dependency_links = setuptools.dist:assert_string_list
test_loader = setuptools.dist:check_importable
test_runner = setuptools.dist:check_importable
- use_2to3 = setuptools.dist:assert_bool
- convert_2to3_doctests = setuptools.dist:assert_string_list
- use_2to3_fixers = setuptools.dist:assert_string_list
- use_2to3_exclude_fixers = setuptools.dist:assert_string_list
egg_info.writers =
PKG-INFO = setuptools.command.egg_info:write_pkg_info
requires.txt = setuptools.command.egg_info:write_requirements
diff --git a/setuptools/__init__.py b/setuptools/__init__.py
index 4d9b8357..9d6f0bc0 100644
--- a/setuptools/__init__.py
+++ b/setuptools/__init__.py
@@ -21,21 +21,20 @@ from . import monkey
__all__ = [
- 'setup', 'Distribution', 'Command', 'Extension', 'Require',
+ 'setup',
+ 'Distribution',
+ 'Command',
+ 'Extension',
+ 'Require',
'SetuptoolsDeprecationWarning',
- 'find_packages', 'find_namespace_packages',
+ 'find_packages',
+ 'find_namespace_packages',
]
__version__ = setuptools.version.__version__
bootstrap_install_from = None
-# If we run 2to3 on .py files, should we also convert docstrings?
-# Default: yes; assume that we can detect doctests reliably
-run_2to3_on_doctests = True
-# Standard package names for fixer packages
-lib2to3_fixer_packages = ['lib2to3.fixes']
-
class PackageFinder:
"""
@@ -60,10 +59,13 @@ class PackageFinder:
shell style wildcard patterns just like 'exclude'.
"""
- return list(cls._find_packages_iter(
- convert_path(where),
- cls._build_filter('ez_setup', '*__pycache__', *exclude),
- cls._build_filter(*include)))
+ return list(
+ cls._find_packages_iter(
+ convert_path(where),
+ cls._build_filter('ez_setup', '*__pycache__', *exclude),
+ cls._build_filter(*include),
+ )
+ )
@classmethod
def _find_packages_iter(cls, where, exclude, include):
@@ -82,7 +84,7 @@ class PackageFinder:
package = rel_path.replace(os.path.sep, '.')
# Skip directory trees that are not valid packages
- if ('.' in dir or not cls._looks_like_package(full_path)):
+ if '.' in dir or not cls._looks_like_package(full_path):
continue
# Should this package be included?
@@ -125,12 +127,10 @@ def _install_setup_requires(attrs):
A minimal version of a distribution for supporting the
fetch_build_eggs interface.
"""
+
def __init__(self, attrs):
_incl = 'dependency_links', 'setup_requires'
- filtered = {
- k: attrs[k]
- for k in set(_incl) & set(attrs)
- }
+ filtered = {k: attrs[k] for k in set(_incl) & set(attrs)}
distutils.core.Distribution.__init__(self, filtered)
def finalize_options(self):
@@ -178,8 +178,9 @@ class Command(_Command):
setattr(self, option, default)
return default
elif not isinstance(val, str):
- raise DistutilsOptionError("'%s' must be a %s (got `%s`)"
- % (option, what, val))
+ raise DistutilsOptionError(
+ "'%s' must be a %s (got `%s`)" % (option, what, val)
+ )
return val
def ensure_string_list(self, option):
@@ -200,8 +201,8 @@ class Command(_Command):
ok = False
if not ok:
raise DistutilsOptionError(
- "'%s' must be a list of strings (got %r)"
- % (option, val))
+ "'%s' must be a list of strings (got %r)" % (option, val)
+ )
def reinitialize_command(self, command, reinit_subcommands=0, **kw):
cmd = _Command.reinitialize_command(self, command, reinit_subcommands)
diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py
index df6fd323..6a615433 100644
--- a/setuptools/command/build_py.py
+++ b/setuptools/command/build_py.py
@@ -10,20 +10,12 @@ import itertools
import stat
from setuptools.extern.more_itertools import unique_everseen
-try:
- from setuptools.lib2to3_ex import Mixin2to3
-except Exception:
-
- class Mixin2to3:
- def run_2to3(self, files, doctests=True):
- "do nothing"
-
def make_writable(target):
os.chmod(target, os.stat(target).st_mode | stat.S_IWRITE)
-class build_py(orig.build_py, Mixin2to3):
+class build_py(orig.build_py):
"""Enhanced 'build_py' command that includes data files with packages
The data files are specified via a 'package_data' argument to 'setup()'.
@@ -36,12 +28,10 @@ class build_py(orig.build_py, Mixin2to3):
def finalize_options(self):
orig.build_py.finalize_options(self)
self.package_data = self.distribution.package_data
- self.exclude_package_data = (self.distribution.exclude_package_data or
- {})
+ self.exclude_package_data = self.distribution.exclude_package_data or {}
if 'data_files' in self.__dict__:
del self.__dict__['data_files']
self.__updated_files = []
- self.__doctests_2to3 = []
def run(self):
"""Build modules, packages, and copy data files to build directory"""
@@ -55,10 +45,6 @@ class build_py(orig.build_py, Mixin2to3):
self.build_packages()
self.build_package_data()
- self.run_2to3(self.__updated_files, False)
- self.run_2to3(self.__updated_files, True)
- self.run_2to3(self.__doctests_2to3, True)
-
# Only compile actual .py files, using our base class' idea of what our
# output files are.
self.byte_compile(orig.build_py.get_outputs(self, include_bytecode=0))
@@ -71,8 +57,7 @@ class build_py(orig.build_py, Mixin2to3):
return orig.build_py.__getattr__(self, attr)
def build_module(self, module, module_file, package):
- outfile, copied = orig.build_py.build_module(self, module, module_file,
- package)
+ outfile, copied = orig.build_py.build_module(self, module, module_file, package)
if copied:
self.__updated_files.append(outfile)
return outfile, copied
@@ -123,9 +108,6 @@ class build_py(orig.build_py, Mixin2to3):
outf, copied = self.copy_file(srcfile, target)
make_writable(target)
srcfile = os.path.abspath(srcfile)
- if (copied and
- srcfile in self.distribution.convert_2to3_doctests):
- self.__doctests_2to3.append(outf)
def analyze_manifest(self):
self.manifest_files = mf = {}
@@ -202,18 +184,11 @@ class build_py(orig.build_py, Mixin2to3):
package,
src_dir,
)
- match_groups = (
- fnmatch.filter(files, pattern)
- for pattern in patterns
- )
+ match_groups = (fnmatch.filter(files, pattern) for pattern in patterns)
# flatten the groups of matches into an iterable of matches
matches = itertools.chain.from_iterable(match_groups)
bad = set(matches)
- keepers = (
- fn
- for fn in files
- if fn not in bad
- )
+ keepers = (fn for fn in files if fn not in bad)
# ditch dupes
return list(unique_everseen(keepers))
@@ -241,12 +216,17 @@ def assert_relative(path):
return path
from distutils.errors import DistutilsSetupError
- msg = textwrap.dedent("""
+ msg = (
+ textwrap.dedent(
+ """
Error: setup script specifies an absolute path:
%s
setup() arguments must *always* be /-separated paths relative to the
setup.py directory, *never* absolute paths.
- """).lstrip() % path
+ """
+ ).lstrip()
+ % path
+ )
raise DistutilsSetupError(msg)
diff --git a/setuptools/command/develop.py b/setuptools/command/develop.py
index faf8c988..24fb0a7c 100644
--- a/setuptools/command/develop.py
+++ b/setuptools/command/develop.py
@@ -63,7 +63,8 @@ class develop(namespaces.DevelopInstaller, easy_install):
target = pkg_resources.normalize_path(self.egg_base)
egg_path = pkg_resources.normalize_path(
- os.path.join(self.install_dir, self.egg_path))
+ os.path.join(self.install_dir, self.egg_path)
+ )
if egg_path != target:
raise DistutilsOptionError(
"--egg-path must be a relative path from the install"
@@ -74,7 +75,7 @@ class develop(namespaces.DevelopInstaller, easy_install):
self.dist = pkg_resources.Distribution(
target,
pkg_resources.PathMetadata(target, os.path.abspath(ei.egg_info)),
- project_name=ei.egg_name
+ project_name=ei.egg_name,
)
self.setup_path = self._resolve_setup_path(
@@ -99,41 +100,18 @@ class develop(namespaces.DevelopInstaller, easy_install):
if resolved != pkg_resources.normalize_path(os.curdir):
raise DistutilsOptionError(
"Can't get a consistent path to setup script from"
- " installation directory", resolved,
- pkg_resources.normalize_path(os.curdir))
+ " installation directory",
+ resolved,
+ pkg_resources.normalize_path(os.curdir),
+ )
return path_to_setup
def install_for_development(self):
- if getattr(self.distribution, 'use_2to3', False):
- # If we run 2to3 we can not do this inplace:
-
- # Ensure metadata is up-to-date
- self.reinitialize_command('build_py', inplace=0)
- self.run_command('build_py')
- bpy_cmd = self.get_finalized_command("build_py")
- build_path = pkg_resources.normalize_path(bpy_cmd.build_lib)
-
- # Build extensions
- self.reinitialize_command('egg_info', egg_base=build_path)
- self.run_command('egg_info')
-
- self.reinitialize_command('build_ext', inplace=0)
- self.run_command('build_ext')
-
- # Fixup egg-link and easy-install.pth
- ei_cmd = self.get_finalized_command("egg_info")
- self.egg_path = build_path
- self.dist.location = build_path
- # XXX
- self.dist._provider = pkg_resources.PathMetadata(
- build_path, ei_cmd.egg_info)
- else:
- # Without 2to3 inplace works fine:
- self.run_command('egg_info')
+ self.run_command('egg_info')
- # Build extensions in-place
- self.reinitialize_command('build_ext', inplace=1)
- self.run_command('build_ext')
+ # Build extensions in-place
+ self.reinitialize_command('build_ext', inplace=1)
+ self.run_command('build_ext')
if setuptools.bootstrap_install_from:
self.easy_install(setuptools.bootstrap_install_from)
@@ -156,8 +134,7 @@ class develop(namespaces.DevelopInstaller, easy_install):
egg_link_file = open(self.egg_link)
contents = [line.rstrip() for line in egg_link_file]
egg_link_file.close()
- if contents not in ([self.egg_path],
- [self.egg_path, self.setup_path]):
+ if contents not in ([self.egg_path], [self.egg_path, self.setup_path]):
log.warn("Link points to %s: uninstall aborted", contents)
return
if not self.dry_run:
diff --git a/setuptools/command/test.py b/setuptools/command/test.py
index de4f3d11..5e1ef57e 100644
--- a/setuptools/command/test.py
+++ b/setuptools/command/test.py
@@ -8,15 +8,22 @@ from distutils.errors import DistutilsError, DistutilsOptionError
from distutils import log
from unittest import TestLoader
-from pkg_resources import (resource_listdir, resource_exists, normalize_path,
- working_set, _namespace_packages, evaluate_marker,
- add_activation_listener, require, EntryPoint)
+from pkg_resources import (
+ resource_listdir,
+ resource_exists,
+ normalize_path,
+ working_set,
+ _namespace_packages,
+ evaluate_marker,
+ add_activation_listener,
+ require,
+ EntryPoint,
+)
from setuptools import Command
from setuptools.extern.more_itertools import unique_everseen
class ScanningLoader(TestLoader):
-
def __init__(self):
TestLoader.__init__(self)
self._visited = set()
@@ -73,8 +80,11 @@ class test(Command):
user_options = [
('test-module=', 'm', "Run 'test_suite' in specified module"),
- ('test-suite=', 's',
- "Run single test, case or suite (e.g. 'module.test_suite')"),
+ (
+ 'test-suite=',
+ 's',
+ "Run single test, case or suite (e.g. 'module.test_suite')",
+ ),
('test-runner=', 'r', "Test runner to use"),
]
@@ -124,30 +134,11 @@ class test(Command):
@contextlib.contextmanager
def project_on_sys_path(self, include_dists=[]):
- with_2to3 = getattr(self.distribution, 'use_2to3', False)
-
- if with_2to3:
- # If we run 2to3 we can not do this inplace:
+ self.run_command('egg_info')
- # Ensure metadata is up-to-date
- self.reinitialize_command('build_py', inplace=0)
- self.run_command('build_py')
- bpy_cmd = self.get_finalized_command("build_py")
- build_path = normalize_path(bpy_cmd.build_lib)
-
- # Build extensions
- self.reinitialize_command('egg_info', egg_base=build_path)
- self.run_command('egg_info')
-
- self.reinitialize_command('build_ext', inplace=0)
- self.run_command('build_ext')
- else:
- # Without 2to3 inplace works fine:
- self.run_command('egg_info')
-
- # Build extensions in-place
- self.reinitialize_command('build_ext', inplace=1)
- self.run_command('build_ext')
+ # Build extensions in-place
+ self.reinitialize_command('build_ext', inplace=1)
+ self.run_command('build_ext')
ei_cmd = self.get_finalized_command("egg_info")
@@ -203,7 +194,8 @@ class test(Command):
ir_d = dist.fetch_build_eggs(dist.install_requires)
tr_d = dist.fetch_build_eggs(dist.tests_require or [])
er_d = dist.fetch_build_eggs(
- v for k, v in dist.extras_require.items()
+ v
+ for k, v in dist.extras_require.items()
if k.startswith(':') and evaluate_marker(k[1:])
)
return itertools.chain(ir_d, tr_d, er_d)
@@ -232,23 +224,10 @@ class test(Command):
self.run_tests()
def run_tests(self):
- # Purge modules under test from sys.modules. The test loader will
- # re-import them from the build location. Required when 2to3 is used
- # with namespace packages.
- if getattr(self.distribution, 'use_2to3', False):
- module = self.test_suite.split('.')[0]
- if module in _namespace_packages:
- del_modules = []
- if module in sys.modules:
- del_modules.append(module)
- module += '.'
- for name in sys.modules:
- if name.startswith(module):
- del_modules.append(name)
- list(map(sys.modules.__delitem__, del_modules))
-
test = unittest.main(
- None, None, self._argv,
+ None,
+ None,
+ self._argv,
testLoader=self._resolve_as_ep(self.test_loader),
testRunner=self._resolve_as_ep(self.test_runner),
exit=False,
diff --git a/setuptools/config.py b/setuptools/config.py
index 7ab6bfd7..e3e44c25 100644
--- a/setuptools/config.py
+++ b/setuptools/config.py
@@ -21,6 +21,7 @@ class StaticModule:
"""
Attempt to load the module by the name
"""
+
def __init__(self, name):
spec = importlib.util.find_spec(name)
with open(spec.origin) as strm:
@@ -56,8 +57,7 @@ def patch_path(path):
sys.path.remove(path)
-def read_configuration(
- filepath, find_others=False, ignore_option_errors=False):
+def read_configuration(filepath, find_others=False, ignore_option_errors=False):
"""Read given configuration file and returns options from it as a dict.
:param str|unicode filepath: Path to configuration file
@@ -78,8 +78,7 @@ def read_configuration(
filepath = os.path.abspath(filepath)
if not os.path.isfile(filepath):
- raise DistutilsFileError(
- 'Configuration file %s does not exist.' % filepath)
+ raise DistutilsFileError('Configuration file %s does not exist.' % filepath)
current_directory = os.getcwd()
os.chdir(os.path.dirname(filepath))
@@ -94,8 +93,8 @@ def read_configuration(
_Distribution.parse_config_files(dist, filenames=filenames)
handlers = parse_configuration(
- dist, dist.command_options,
- ignore_option_errors=ignore_option_errors)
+ dist, dist.command_options, ignore_option_errors=ignore_option_errors
+ )
finally:
os.chdir(current_directory)
@@ -133,8 +132,7 @@ def configuration_to_dict(handlers):
return config_dict
-def parse_configuration(
- distribution, command_options, ignore_option_errors=False):
+def parse_configuration(distribution, command_options, ignore_option_errors=False):
"""Performs additional parsing of configuration options
for a distribution.
@@ -148,13 +146,15 @@ def parse_configuration(
If False exceptions are propagated as expected.
:rtype: list
"""
- options = ConfigOptionsHandler(
- distribution, command_options, ignore_option_errors)
+ options = ConfigOptionsHandler(distribution, command_options, ignore_option_errors)
options.parse()
meta = ConfigMetadataHandler(
- distribution.metadata, command_options, ignore_option_errors,
- distribution.package_dir)
+ distribution.metadata,
+ command_options,
+ ignore_option_errors,
+ distribution.package_dir,
+ )
meta.parse()
return meta, options
@@ -196,7 +196,8 @@ class ConfigHandler:
def parsers(self):
"""Metadata item name to parser function mapping."""
raise NotImplementedError(
- '%s must provide .parsers property' % self.__class__.__name__)
+ '%s must provide .parsers property' % self.__class__.__name__
+ )
def __setitem__(self, option_name, value):
unknown = tuple()
@@ -297,7 +298,8 @@ class ConfigHandler:
key, sep, val = line.partition(separator)
if sep != separator:
raise DistutilsOptionError(
- 'Unable to parse option value to dict: %s' % value)
+ 'Unable to parse option value to dict: %s' % value
+ )
result[key.strip()] = val.strip()
return result
@@ -323,13 +325,16 @@ class ConfigHandler:
:param key:
:rtype: callable
"""
+
def parser(value):
exclude_directive = 'file:'
if value.startswith(exclude_directive):
raise ValueError(
'Only strings are accepted for the {0} field, '
- 'files are not accepted'.format(key))
+ 'files are not accepted'.format(key)
+ )
return value
+
return parser
@classmethod
@@ -354,20 +359,18 @@ class ConfigHandler:
if not value.startswith(include_directive):
return value
- spec = value[len(include_directive):]
+ spec = value[len(include_directive) :]
filepaths = (os.path.abspath(path.strip()) for path in spec.split(','))
return '\n'.join(
cls._read_file(path)
for path in filepaths
- if (cls._assert_local(path) or True)
- and os.path.isfile(path)
+ if (cls._assert_local(path) or True) and os.path.isfile(path)
)
@staticmethod
def _assert_local(filepath):
if not filepath.startswith(os.getcwd()):
- raise DistutilsOptionError(
- '`file:` directive can not access %s' % filepath)
+ raise DistutilsOptionError('`file:` directive can not access %s' % filepath)
@staticmethod
def _read_file(filepath):
@@ -429,6 +432,7 @@ class ConfigHandler:
:param parse_methods:
:rtype: callable
"""
+
def parse(value):
parsed = value
@@ -482,22 +486,25 @@ class ConfigHandler:
self,
# Dots in section names are translated into dunderscores.
('parse_section%s' % method_postfix).replace('.', '__'),
- None)
+ None,
+ )
if section_parser_method is None:
raise DistutilsOptionError(
- 'Unsupported distribution option section: [%s.%s]' % (
- self.section_prefix, section_name))
+ 'Unsupported distribution option section: [%s.%s]'
+ % (self.section_prefix, section_name)
+ )
section_parser_method(section_options)
def _deprecated_config_handler(self, func, msg, warning_class):
- """ this function will wrap around parameters that are deprecated
+ """this function will wrap around parameters that are deprecated
:param msg: deprecation message
:param warning_class: class of warning exception to be raised
:param func: function to be wrapped around
"""
+
@wraps(func)
def config_handler(*args, **kwargs):
warnings.warn(msg, warning_class)
@@ -523,10 +530,12 @@ class ConfigMetadataHandler(ConfigHandler):
"""
- def __init__(self, target_obj, options, ignore_option_errors=False,
- package_dir=None):
- super(ConfigMetadataHandler, self).__init__(target_obj, options,
- ignore_option_errors)
+ def __init__(
+ self, target_obj, options, ignore_option_errors=False, package_dir=None
+ ):
+ super(ConfigMetadataHandler, self).__init__(
+ target_obj, options, ignore_option_errors
+ )
self.package_dir = package_dir
@property
@@ -545,7 +554,8 @@ class ConfigMetadataHandler(ConfigHandler):
parse_list,
"The requires parameter is deprecated, please use "
"install_requires for runtime dependencies.",
- DeprecationWarning),
+ DeprecationWarning,
+ ),
'obsoletes': parse_list,
'classifiers': self._get_parser_compound(parse_file, parse_list),
'license': exclude_files_parser('license'),
@@ -553,7 +563,8 @@ class ConfigMetadataHandler(ConfigHandler):
exclude_files_parser('license_file'),
"The license_file parameter is deprecated, "
"use license_files instead.",
- DeprecationWarning),
+ DeprecationWarning,
+ ),
'license_files': parse_list,
'description': parse_file,
'long_description': parse_file,
@@ -612,12 +623,8 @@ class ConfigOptionsHandler(ConfigHandler):
return {
'zip_safe': parse_bool,
- 'use_2to3': parse_bool,
'include_package_data': parse_bool,
'package_dir': parse_dict,
- 'use_2to3_fixers': parse_list,
- 'use_2to3_exclude_fixers': parse_list,
- 'convert_2to3_doctests': parse_list,
'scripts': parse_list,
'eager_resources': parse_list,
'dependency_links': parse_list,
@@ -635,17 +642,14 @@ class ConfigOptionsHandler(ConfigHandler):
def _parse_cmdclass(self, value):
def resolve_class(qualified_class_name):
idx = qualified_class_name.rfind('.')
- class_name = qualified_class_name[idx+1:]
+ class_name = qualified_class_name[idx + 1 :]
pkg_name = qualified_class_name[:idx]
module = __import__(pkg_name)
return getattr(module, class_name)
- return {
- k: resolve_class(v)
- for k, v in self._parse_dict(value).items()
- }
+ return {k: resolve_class(v) for k, v in self._parse_dict(value).items()}
def _parse_packages(self, value):
"""Parses `packages` option value.
@@ -663,7 +667,8 @@ class ConfigOptionsHandler(ConfigHandler):
# Read function arguments from a dedicated section.
find_kwargs = self.parse_section_packages__find(
- self.sections.get('packages.find', {}))
+ self.sections.get('packages.find', {})
+ )
if findns:
from setuptools import find_namespace_packages as find_packages
@@ -679,13 +684,13 @@ class ConfigOptionsHandler(ConfigHandler):
:param dict section_options:
"""
- section_data = self._parse_section_to_dict(
- section_options, self._parse_list)
+ section_data = self._parse_section_to_dict(section_options, self._parse_list)
valid_keys = ['where', 'include', 'exclude']
find_kwargs = dict(
- [(k, v) for k, v in section_data.items() if k in valid_keys and v])
+ [(k, v) for k, v in section_data.items() if k in valid_keys and v]
+ )
where = find_kwargs.get('where')
if where is not None:
@@ -723,8 +728,7 @@ class ConfigOptionsHandler(ConfigHandler):
:param dict section_options:
"""
- self['exclude_package_data'] = self._parse_package_data(
- section_options)
+ self['exclude_package_data'] = self._parse_package_data(section_options)
def parse_section_extras_require(self, section_options):
"""Parses `extras_require` configuration file section.
@@ -733,7 +737,8 @@ class ConfigOptionsHandler(ConfigHandler):
"""
parse_list = partial(self._parse_list, separator=';')
self['extras_require'] = self._parse_section_to_dict(
- section_options, parse_list)
+ section_options, parse_list
+ )
def parse_section_data_files(self, section_options):
"""Parses `data_files` configuration file section.
diff --git a/setuptools/dist.py b/setuptools/dist.py
index df071c16..eec0b27e 100644
--- a/setuptools/dist.py
+++ b/setuptools/dist.py
@@ -65,9 +65,7 @@ def rfc822_unescape(content: str) -> str:
lines = content.splitlines()
if len(lines) == 1:
return lines[0].lstrip()
- return '\n'.join(
- (lines[0].lstrip(),
- textwrap.dedent('\n'.join(lines[1:]))))
+ return '\n'.join((lines[0].lstrip(), textwrap.dedent('\n'.join(lines[1:]))))
def _read_field_from_msg(msg: "Message", field: str) -> Optional[str]:
@@ -157,8 +155,7 @@ def single_line(val):
# Based on Python 3.5 version
def write_pkg_file(self, file): # noqa: C901 # is too complex (14) # FIXME
- """Write the PKG-INFO format data to a file object.
- """
+ """Write the PKG-INFO format data to a file object."""
version = self.get_metadata_version()
def write_field(key, value):
@@ -209,10 +206,7 @@ def write_pkg_file(self, file): # noqa: C901 # is too complex (14) # FIXME
# PEP 566
if self.long_description_content_type:
- write_field(
- 'Description-Content-Type',
- self.long_description_content_type
- )
+ write_field('Description-Content-Type', self.long_description_content_type)
if self.provides_extras:
for extra in self.provides_extras:
write_field('Provides-Extra', extra)
@@ -231,8 +225,7 @@ def check_importable(dist, attr, value):
assert not ep.extras
except (TypeError, ValueError, AttributeError, AssertionError) as e:
raise DistutilsSetupError(
- "%r must be importable 'module:attrs' string (got %r)"
- % (attr, value)
+ "%r must be importable 'module:attrs' string (got %r)" % (attr, value)
) from e
@@ -257,14 +250,16 @@ def check_nsp(dist, attr, value):
for nsp in ns_packages:
if not dist.has_contents_for(nsp):
raise DistutilsSetupError(
- "Distribution contains no modules or packages for " +
- "namespace package %r" % nsp
+ "Distribution contains no modules or packages for "
+ + "namespace package %r" % nsp
)
parent, sep, child = nsp.rpartition('.')
if parent and parent not in ns_packages:
distutils.log.warn(
"WARNING: %r is declared as a package namespace, but %r"
- " is not: please correct this in setup.py", nsp, parent
+ " is not: please correct this in setup.py",
+ nsp,
+ parent,
)
@@ -305,9 +300,7 @@ def check_requirements(dist, attr, value):
"{attr!r} must be a string or list of strings "
"containing valid project/version requirement specifiers; {error}"
)
- raise DistutilsSetupError(
- tmpl.format(attr=attr, error=error)
- ) from error
+ raise DistutilsSetupError(tmpl.format(attr=attr, error=error)) from error
def check_specifier(dist, attr, value):
@@ -316,12 +309,9 @@ def check_specifier(dist, attr, value):
packaging.specifiers.SpecifierSet(value)
except (packaging.specifiers.InvalidSpecifier, AttributeError) as error:
tmpl = (
- "{attr!r} must be a string "
- "containing valid version specifiers; {error}"
+ "{attr!r} must be a string " "containing valid version specifiers; {error}"
)
- raise DistutilsSetupError(
- tmpl.format(attr=attr, error=error)
- ) from error
+ raise DistutilsSetupError(tmpl.format(attr=attr, error=error)) from error
def check_entry_points(dist, attr, value):
@@ -342,12 +332,12 @@ def check_package_data(dist, attr, value):
if not isinstance(value, dict):
raise DistutilsSetupError(
"{!r} must be a dictionary mapping package names to lists of "
- "string wildcard patterns".format(attr))
+ "string wildcard patterns".format(attr)
+ )
for k, v in value.items():
if not isinstance(k, str):
raise DistutilsSetupError(
- "keys of {!r} dict must be strings (got {!r})"
- .format(attr, k)
+ "keys of {!r} dict must be strings (got {!r})".format(attr, k)
)
assert_string_list(dist, 'values of {!r} dict'.format(attr), v)
@@ -357,7 +347,8 @@ def check_packages(dist, attr, value):
if not re.match(r'\w+(\.\w+)*', pkgname):
distutils.log.warn(
"WARNING: %r not a valid package name; please use only "
- ".-separated package names in setup.py", pkgname
+ ".-separated package names in setup.py",
+ pkgname,
)
@@ -452,15 +443,20 @@ class Distribution(_Distribution):
self.setup_requires = attrs.pop('setup_requires', [])
for ep in pkg_resources.iter_entry_points('distutils.setup_keywords'):
vars(self).setdefault(ep.name, None)
- _Distribution.__init__(self, {
- k: v for k, v in attrs.items()
- if k not in self._DISTUTILS_UNSUPPORTED_METADATA
- })
+ _Distribution.__init__(
+ self,
+ {
+ k: v
+ for k, v in attrs.items()
+ if k not in self._DISTUTILS_UNSUPPORTED_METADATA
+ },
+ )
self._set_metadata_defaults(attrs)
self.metadata.version = self._normalize_version(
- self._validate_version(self.metadata.version))
+ self._validate_version(self.metadata.version)
+ )
self._finalize_requires()
def _set_metadata_defaults(self, attrs):
@@ -596,7 +592,8 @@ class Distribution(_Distribution):
patterns = ('LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*')
self.metadata.license_files = list(
- unique_everseen(self._expand_patterns(patterns)))
+ unique_everseen(self._expand_patterns(patterns))
+ )
@staticmethod
def _expand_patterns(patterns):
@@ -610,8 +607,7 @@ class Distribution(_Distribution):
path
for pattern in patterns
for path in sorted(iglob(pattern))
- if not path.endswith('~')
- and os.path.isfile(path)
+ if not path.endswith('~') and os.path.isfile(path)
)
# FIXME: 'Distribution._parse_config_files' is too complex (14)
@@ -624,12 +620,25 @@ class Distribution(_Distribution):
from configparser import ConfigParser
# Ignore install directory options if we have a venv
- ignore_options = [] if sys.prefix == sys.base_prefix else [
- 'install-base', 'install-platbase', 'install-lib',
- 'install-platlib', 'install-purelib', 'install-headers',
- 'install-scripts', 'install-data', 'prefix', 'exec-prefix',
- 'home', 'user', 'root',
- ]
+ ignore_options = (
+ []
+ if sys.prefix == sys.base_prefix
+ else [
+ 'install-base',
+ 'install-platbase',
+ 'install-lib',
+ 'install-platlib',
+ 'install-purelib',
+ 'install-headers',
+ 'install-scripts',
+ 'install-data',
+ 'prefix',
+ 'exec-prefix',
+ 'home',
+ 'user',
+ 'root',
+ ]
+ )
ignore_options = frozenset(ignore_options)
@@ -683,21 +692,26 @@ class Distribution(_Distribution):
def warn_dash_deprecation(self, opt, section):
if section in (
- 'options.extras_require', 'options.data_files',
+ 'options.extras_require',
+ 'options.data_files',
):
return opt
underscore_opt = opt.replace('-', '_')
commands = distutils.command.__all__ + self._setuptools_commands()
- if (not section.startswith('options') and section != 'metadata'
- and section not in commands):
+ if (
+ not section.startswith('options')
+ and section != 'metadata'
+ and section not in commands
+ ):
return underscore_opt
if '-' in opt:
warnings.warn(
"Usage of dash-separated '%s' will not be supported in future "
"versions. Please use the underscore name '%s' instead"
- % (opt, underscore_opt))
+ % (opt, underscore_opt)
+ )
return underscore_opt
def _setuptools_commands(self):
@@ -741,11 +755,9 @@ class Distribution(_Distribution):
self.announce(" setting options for '%s' command:" % command_name)
for (option, (source, value)) in option_dict.items():
if DEBUG:
- self.announce(" %s = %s (from %s)" % (option, value,
- source))
+ self.announce(" %s = %s (from %s)" % (option, value, source))
try:
- bool_opts = [translate_longopt(o)
- for o in command_obj.boolean_options]
+ bool_opts = [translate_longopt(o) for o in command_obj.boolean_options]
except AttributeError:
bool_opts = []
try:
@@ -764,7 +776,8 @@ class Distribution(_Distribution):
else:
raise DistutilsOptionError(
"error in %s: command '%s' has no such option '%s'"
- % (source, command_name, option))
+ % (source, command_name, option)
+ )
except ValueError as e:
raise DistutilsOptionError(e) from e
@@ -775,8 +788,9 @@ class Distribution(_Distribution):
"""
self._parse_config_files(filenames=filenames)
- parse_configuration(self, self.command_options,
- ignore_option_errors=ignore_option_errors)
+ parse_configuration(
+ self, self.command_options, ignore_option_errors=ignore_option_errors
+ )
self._finalize_requires()
self._finalize_license_files()
@@ -802,6 +816,7 @@ class Distribution(_Distribution):
def by_order(hook):
return getattr(hook, 'order', 0)
+
eps = map(lambda e: e.load(), pkg_resources.iter_entry_points(group))
for ep in sorted(eps, key=by_order):
ep(self)
@@ -813,16 +828,6 @@ class Distribution(_Distribution):
ep.require(installer=self.fetch_build_egg)
ep.load()(self, ep.name, value)
- def _finalize_2to3_doctests(self):
- if getattr(self, 'convert_2to3_doctests', None):
- # XXX may convert to set here when we can rely on set being builtin
- self.convert_2to3_doctests = [
- os.path.abspath(p)
- for p in self.convert_2to3_doctests
- ]
- else:
- self.convert_2to3_doctests = []
-
def get_egg_cache_dir(self):
egg_cache_dir = os.path.join(os.curdir, '.eggs')
if not os.path.exists(egg_cache_dir):
@@ -830,10 +835,14 @@ class Distribution(_Distribution):
windows_support.hide_file(egg_cache_dir)
readme_txt_filename = os.path.join(egg_cache_dir, 'README.txt')
with open(readme_txt_filename, 'w') as f:
- f.write('This directory contains eggs that were downloaded '
- 'by setuptools to build, test, and run plug-ins.\n\n')
- f.write('This directory caches those eggs to prevent '
- 'repeated downloads.\n\n')
+ f.write(
+ 'This directory contains eggs that were downloaded '
+ 'by setuptools to build, test, and run plug-ins.\n\n'
+ )
+ f.write(
+ 'This directory caches those eggs to prevent '
+ 'repeated downloads.\n\n'
+ )
f.write('However, it is safe to delete this directory.\n\n')
return egg_cache_dir
@@ -841,6 +850,7 @@ class Distribution(_Distribution):
def fetch_build_egg(self, req):
"""Fetch an egg needed for building"""
from setuptools.installer import fetch_build_egg
+
return fetch_build_egg(self, req)
def get_command_class(self, command):
@@ -900,19 +910,18 @@ class Distribution(_Distribution):
pfx = package + '.'
if self.packages:
self.packages = [
- p for p in self.packages
- if p != package and not p.startswith(pfx)
+ p for p in self.packages if p != package and not p.startswith(pfx)
]
if self.py_modules:
self.py_modules = [
- p for p in self.py_modules
- if p != package and not p.startswith(pfx)
+ p for p in self.py_modules if p != package and not p.startswith(pfx)
]
if self.ext_modules:
self.ext_modules = [
- p for p in self.ext_modules
+ p
+ for p in self.ext_modules
if p.name != package and not p.name.startswith(pfx)
]
@@ -934,9 +943,7 @@ class Distribution(_Distribution):
try:
old = getattr(self, name)
except AttributeError as e:
- raise DistutilsSetupError(
- "%s: No such distribution setting" % name
- ) from e
+ raise DistutilsSetupError("%s: No such distribution setting" % name) from e
if old is not None and not isinstance(old, sequence):
raise DistutilsSetupError(
name + ": this setting cannot be changed via include/exclude"
@@ -948,15 +955,11 @@ class Distribution(_Distribution):
"""Handle 'include()' for list/tuple attrs without a special handler"""
if not isinstance(value, sequence):
- raise DistutilsSetupError(
- "%s: setting must be a list (%r)" % (name, value)
- )
+ raise DistutilsSetupError("%s: setting must be a list (%r)" % (name, value))
try:
old = getattr(self, name)
except AttributeError as e:
- raise DistutilsSetupError(
- "%s: No such distribution setting" % name
- ) from e
+ raise DistutilsSetupError("%s: No such distribution setting" % name) from e
if old is None:
setattr(self, name, value)
elif not isinstance(old, sequence):
@@ -1009,6 +1012,7 @@ class Distribution(_Distribution):
src, alias = aliases[command]
del aliases[command] # ensure each alias can expand only once!
import shlex
+
args[:1] = shlex.split(alias, True)
command = args[0]
@@ -1108,12 +1112,14 @@ class Distribution(_Distribution):
line_buffering = sys.stdout.line_buffering
sys.stdout = io.TextIOWrapper(
- sys.stdout.detach(), 'utf-8', errors, newline, line_buffering)
+ sys.stdout.detach(), 'utf-8', errors, newline, line_buffering
+ )
try:
return _Distribution.handle_display_options(self, option_order)
finally:
sys.stdout = io.TextIOWrapper(
- sys.stdout.detach(), encoding, errors, newline, line_buffering)
+ sys.stdout.detach(), encoding, errors, newline, line_buffering
+ )
class DistDeprecationWarning(SetuptoolsDeprecationWarning):
diff --git a/setuptools/lib2to3_ex.py b/setuptools/lib2to3_ex.py
deleted file mode 100644
index c176abf6..00000000
--- a/setuptools/lib2to3_ex.py
+++ /dev/null
@@ -1,68 +0,0 @@
-"""
-Customized Mixin2to3 support:
-
- - adds support for converting doctests
-"""
-
-import warnings
-from distutils.util import Mixin2to3 as _Mixin2to3
-from distutils import log
-from lib2to3.refactor import RefactoringTool, get_fixers_from_package
-
-import setuptools
-from ._deprecation_warning import SetuptoolsDeprecationWarning
-
-
-class DistutilsRefactoringTool(RefactoringTool):
- def log_error(self, msg, *args, **kw):
- log.error(msg, *args)
-
- def log_message(self, msg, *args):
- log.info(msg, *args)
-
- def log_debug(self, msg, *args):
- log.debug(msg, *args)
-
-
-class Mixin2to3(_Mixin2to3):
- def run_2to3(self, files, doctests=False):
- # See of the distribution option has been set, otherwise check the
- # setuptools default.
- if self.distribution.use_2to3 is not True:
- return
- if not files:
- return
-
- warnings.warn(
- "2to3 support is deprecated. If the project still "
- "requires Python 2 support, please migrate to "
- "a single-codebase solution or employ an "
- "independent conversion process.",
- SetuptoolsDeprecationWarning)
- log.info("Fixing " + " ".join(files))
- self.__build_fixer_names()
- self.__exclude_fixers()
- if doctests:
- if setuptools.run_2to3_on_doctests:
- r = DistutilsRefactoringTool(self.fixer_names)
- r.refactor(files, write=True, doctests_only=True)
- else:
- _Mixin2to3.run_2to3(self, files)
-
- def __build_fixer_names(self):
- if self.fixer_names:
- return
- self.fixer_names = []
- for p in setuptools.lib2to3_fixer_packages:
- self.fixer_names.extend(get_fixers_from_package(p))
- if self.distribution.use_2to3_fixers is not None:
- for p in self.distribution.use_2to3_fixers:
- self.fixer_names.extend(get_fixers_from_package(p))
-
- def __exclude_fixers(self):
- excluded_fixers = getattr(self, 'exclude_fixers', [])
- if self.distribution.use_2to3_exclude_fixers is not None:
- excluded_fixers.extend(self.distribution.use_2to3_exclude_fixers)
- for fixer_name in excluded_fixers:
- if fixer_name in self.fixer_names:
- self.fixer_names.remove(fixer_name)
diff --git a/setuptools/sandbox.py b/setuptools/sandbox.py
index 91b960d8..034fc80d 100644
--- a/setuptools/sandbox.py
+++ b/setuptools/sandbox.py
@@ -26,7 +26,10 @@ _open = open
__all__ = [
- "AbstractSandbox", "DirectorySandbox", "SandboxViolation", "run_setup",
+ "AbstractSandbox",
+ "DirectorySandbox",
+ "SandboxViolation",
+ "run_setup",
]
@@ -106,6 +109,7 @@ class UnpickleableException(Exception):
except Exception:
# get UnpickleableException inside the sandbox
from setuptools.sandbox import UnpickleableException as cls
+
return cls.dump(cls, cls(repr(exc)))
@@ -154,7 +158,8 @@ def save_modules():
sys.modules.update(saved)
# remove any modules imported since
del_modules = (
- mod_name for mod_name in sys.modules
+ mod_name
+ for mod_name in sys.modules
if mod_name not in saved
# exclude any encodings modules. See #285
and not mod_name.startswith('encodings.')
@@ -265,7 +270,8 @@ class AbstractSandbox:
def __init__(self):
self._attrs = [
- name for name in dir(_os)
+ name
+ for name in dir(_os)
if not name.startswith('_') and hasattr(self, name)
]
@@ -320,9 +326,25 @@ class AbstractSandbox:
_file = _mk_single_path_wrapper('file', _file)
_open = _mk_single_path_wrapper('open', _open)
for name in [
- "stat", "listdir", "chdir", "open", "chmod", "chown", "mkdir",
- "remove", "unlink", "rmdir", "utime", "lchown", "chroot", "lstat",
- "startfile", "mkfifo", "mknod", "pathconf", "access"
+ "stat",
+ "listdir",
+ "chdir",
+ "open",
+ "chmod",
+ "chown",
+ "mkdir",
+ "remove",
+ "unlink",
+ "rmdir",
+ "utime",
+ "lchown",
+ "chroot",
+ "lstat",
+ "startfile",
+ "mkfifo",
+ "mknod",
+ "pathconf",
+ "access",
]:
if hasattr(_os, name):
locals()[name] = _mk_single_path_wrapper(name)
@@ -373,7 +395,7 @@ class AbstractSandbox:
"""Called for path pairs like rename, link, and symlink operations"""
return (
self._remap_input(operation + '-from', src, *args, **kw),
- self._remap_input(operation + '-to', dst, *args, **kw)
+ self._remap_input(operation + '-to', dst, *args, **kw),
)
@@ -386,28 +408,38 @@ else:
class DirectorySandbox(AbstractSandbox):
"""Restrict operations to a single subdirectory - pseudo-chroot"""
- write_ops = dict.fromkeys([
- "open", "chmod", "chown", "mkdir", "remove", "unlink", "rmdir",
- "utime", "lchown", "chroot", "mkfifo", "mknod", "tempnam",
- ])
+ write_ops = dict.fromkeys(
+ [
+ "open",
+ "chmod",
+ "chown",
+ "mkdir",
+ "remove",
+ "unlink",
+ "rmdir",
+ "utime",
+ "lchown",
+ "chroot",
+ "mkfifo",
+ "mknod",
+ "tempnam",
+ ]
+ )
- _exception_patterns = [
- # Allow lib2to3 to attempt to save a pickled grammar object (#121)
- r'.*lib2to3.*\.pickle$',
- ]
+ _exception_patterns = []
"exempt writing to paths that match the pattern"
def __init__(self, sandbox, exceptions=_EXCEPTIONS):
self._sandbox = os.path.normcase(os.path.realpath(sandbox))
self._prefix = os.path.join(self._sandbox, '')
self._exceptions = [
- os.path.normcase(os.path.realpath(path))
- for path in exceptions
+ os.path.normcase(os.path.realpath(path)) for path in exceptions
]
AbstractSandbox.__init__(self)
def _violation(self, operation, *args, **kw):
from setuptools.sandbox import SandboxViolation
+
raise SandboxViolation(operation, args, kw)
if _file:
@@ -440,12 +472,10 @@ class DirectorySandbox(AbstractSandbox):
def _exempted(self, filepath):
start_matches = (
- filepath.startswith(exception)
- for exception in self._exceptions
+ filepath.startswith(exception) for exception in self._exceptions
)
pattern_matches = (
- re.match(pattern, filepath)
- for pattern in self._exception_patterns
+ re.match(pattern, filepath) for pattern in self._exception_patterns
)
candidates = itertools.chain(start_matches, pattern_matches)
return any(candidates)
@@ -470,16 +500,19 @@ class DirectorySandbox(AbstractSandbox):
WRITE_FLAGS = functools.reduce(
- operator.or_, [
- getattr(_os, a, 0) for a in
- "O_WRONLY O_RDWR O_APPEND O_CREAT O_TRUNC O_TEMPORARY".split()]
+ operator.or_,
+ [
+ getattr(_os, a, 0)
+ for a in "O_WRONLY O_RDWR O_APPEND O_CREAT O_TRUNC O_TEMPORARY".split()
+ ],
)
class SandboxViolation(DistutilsError):
"""A setup script attempted to modify the filesystem outside the sandbox"""
- tmpl = textwrap.dedent("""
+ tmpl = textwrap.dedent(
+ """
SandboxViolation: {cmd}{args!r} {kwargs}
The package setup script has attempted to modify files on your system
@@ -489,7 +522,8 @@ class SandboxViolation(DistutilsError):
support alternate installation locations even if you run its setup
script by hand. Please inform the package's author and the EasyInstall
maintainers to find out if a fix or workaround is available.
- """).lstrip()
+ """
+ ).lstrip()
def __str__(self):
cmd, args, kwargs = self.args
diff --git a/setuptools/tests/__init__.py b/setuptools/tests/__init__.py
index a7a2112f..564adf2b 100644
--- a/setuptools/tests/__init__.py
+++ b/setuptools/tests/__init__.py
@@ -3,11 +3,8 @@ import locale
import pytest
-__all__ = ['fail_on_ascii', 'ack_2to3']
+__all__ = ['fail_on_ascii']
is_ascii = locale.getpreferredencoding() == 'ANSI_X3.4-1968'
fail_on_ascii = pytest.mark.xfail(is_ascii, reason="Test fails in this locale")
-
-
-ack_2to3 = pytest.mark.filterwarnings('ignore:2to3 support is deprecated')
diff --git a/setuptools/tests/test_config.py b/setuptools/tests/test_config.py
index ec65250e..005742e4 100644
--- a/setuptools/tests/test_config.py
+++ b/setuptools/tests/test_config.py
@@ -30,14 +30,11 @@ def make_package_dir(name, base_dir, ns=False):
def fake_env(
- tmpdir, setup_cfg, setup_py=None,
- encoding='ascii', package_path='fake_package'):
+ tmpdir, setup_cfg, setup_py=None, encoding='ascii', package_path='fake_package'
+):
if setup_py is None:
- setup_py = (
- 'from setuptools import setup\n'
- 'setup()\n'
- )
+ setup_py = 'from setuptools import setup\n' 'setup()\n'
tmpdir.join('setup.py').write(setup_py)
config = tmpdir.join('setup.cfg')
@@ -78,7 +75,6 @@ def test_parsers_implemented():
class TestConfigurationReader:
-
def test_basic(self, tmpdir):
_, config = fake_env(
tmpdir,
@@ -87,7 +83,7 @@ class TestConfigurationReader:
'keywords = one, two\n'
'\n'
'[options]\n'
- 'scripts = bin/a.py, bin/b.py\n'
+ 'scripts = bin/a.py, bin/b.py\n',
)
config_dict = read_configuration('%s' % config)
assert config_dict['metadata']['version'] == '10.1.1'
@@ -101,15 +97,12 @@ class TestConfigurationReader:
def test_ignore_errors(self, tmpdir):
_, config = fake_env(
tmpdir,
- '[metadata]\n'
- 'version = attr: none.VERSION\n'
- 'keywords = one, two\n'
+ '[metadata]\n' 'version = attr: none.VERSION\n' 'keywords = one, two\n',
)
with pytest.raises(ImportError):
read_configuration('%s' % config)
- config_dict = read_configuration(
- '%s' % config, ignore_option_errors=True)
+ config_dict = read_configuration('%s' % config, ignore_option_errors=True)
assert config_dict['metadata']['keywords'] == ['one', 'two']
assert 'version' not in config_dict['metadata']
@@ -118,7 +111,6 @@ class TestConfigurationReader:
class TestMetadata:
-
def test_basic(self, tmpdir):
fake_env(
@@ -133,7 +125,7 @@ class TestMetadata:
'provides = package, package.sub\n'
'license = otherlic\n'
'download_url = http://test.test.com/test/\n'
- 'maintainer_email = test@test.com\n'
+ 'maintainer_email = test@test.com\n',
)
tmpdir.join('README').write('readme contents\nline2')
@@ -160,12 +152,14 @@ class TestMetadata:
def test_license_cfg(self, tmpdir):
fake_env(
tmpdir,
- DALS("""
+ DALS(
+ """
[metadata]
name=foo
version=0.0.1
license=Apache 2.0
- """)
+ """
+ ),
)
with get_dist(tmpdir) as dist:
@@ -179,9 +173,7 @@ class TestMetadata:
fake_env(
tmpdir,
- '[metadata]\n'
- 'long_description = file: README.rst, CHANGES.rst\n'
- '\n'
+ '[metadata]\n' 'long_description = file: README.rst, CHANGES.rst\n' '\n',
)
tmpdir.join('README.rst').write('readme contents\nline2')
@@ -189,17 +181,12 @@ class TestMetadata:
with get_dist(tmpdir) as dist:
assert dist.metadata.long_description == (
- 'readme contents\nline2\n'
- 'changelog contents\nand stuff'
+ 'readme contents\nline2\n' 'changelog contents\nand stuff'
)
def test_file_sandboxed(self, tmpdir):
- fake_env(
- tmpdir,
- '[metadata]\n'
- 'long_description = file: ../../README\n'
- )
+ fake_env(tmpdir, '[metadata]\n' 'long_description = file: ../../README\n')
with get_dist(tmpdir, parse=False) as dist:
with pytest.raises(DistutilsOptionError):
@@ -216,7 +203,7 @@ class TestMetadata:
'platform = a, b\n'
'classifier =\n'
' Framework :: Django\n'
- ' Programming Language :: Python :: 3.5\n'
+ ' Programming Language :: Python :: 3.5\n',
)
with get_dist(tmpdir) as dist:
@@ -241,7 +228,7 @@ class TestMetadata:
' two\n'
'classifiers =\n'
' Framework :: Django\n'
- ' Programming Language :: Python :: 3.5\n'
+ ' Programming Language :: Python :: 3.5\n',
)
with get_dist(tmpdir) as dist:
metadata = dist.metadata
@@ -258,7 +245,7 @@ class TestMetadata:
'[metadata]\n'
'project_urls =\n'
' Link One = https://example.com/one/\n'
- ' Link Two = https://example.com/two/\n'
+ ' Link Two = https://example.com/two/\n',
)
with get_dist(tmpdir) as dist:
metadata = dist.metadata
@@ -270,9 +257,7 @@ class TestMetadata:
def test_version(self, tmpdir):
package_dir, config = fake_env(
- tmpdir,
- '[metadata]\n'
- 'version = attr: fake_package.VERSION\n'
+ tmpdir, '[metadata]\n' 'version = attr: fake_package.VERSION\n'
)
sub_a = package_dir.mkdir('subpkg_a')
@@ -282,37 +267,28 @@ class TestMetadata:
sub_b = package_dir.mkdir('subpkg_b')
sub_b.join('__init__.py').write('')
sub_b.join('mod.py').write(
- 'import third_party_module\n'
- 'VERSION = (2016, 11, 26)'
+ 'import third_party_module\n' 'VERSION = (2016, 11, 26)'
)
with get_dist(tmpdir) as dist:
assert dist.metadata.version == '1.2.3'
- config.write(
- '[metadata]\n'
- 'version = attr: fake_package.get_version\n'
- )
+ config.write('[metadata]\n' 'version = attr: fake_package.get_version\n')
with get_dist(tmpdir) as dist:
assert dist.metadata.version == '3.4.5.dev'
- config.write(
- '[metadata]\n'
- 'version = attr: fake_package.VERSION_MAJOR\n'
- )
+ config.write('[metadata]\n' 'version = attr: fake_package.VERSION_MAJOR\n')
with get_dist(tmpdir) as dist:
assert dist.metadata.version == '1'
config.write(
- '[metadata]\n'
- 'version = attr: fake_package.subpkg_a.mod.VERSION\n'
+ '[metadata]\n' 'version = attr: fake_package.subpkg_a.mod.VERSION\n'
)
with get_dist(tmpdir) as dist:
assert dist.metadata.version == '2016.11.26'
config.write(
- '[metadata]\n'
- 'version = attr: fake_package.subpkg_b.mod.VERSION\n'
+ '[metadata]\n' 'version = attr: fake_package.subpkg_b.mod.VERSION\n'
)
with get_dist(tmpdir) as dist:
assert dist.metadata.version == '2016.11.26'
@@ -320,9 +296,7 @@ class TestMetadata:
def test_version_file(self, tmpdir):
_, config = fake_env(
- tmpdir,
- '[metadata]\n'
- 'version = file: fake_package/version.txt\n'
+ tmpdir, '[metadata]\n' 'version = file: fake_package/version.txt\n'
)
tmpdir.join('fake_package', 'version.txt').write('1.2.3\n')
@@ -343,7 +317,7 @@ class TestMetadata:
'[options]\n'
'package_dir =\n'
' = src\n',
- package_path='src/fake_package_simple'
+ package_path='src/fake_package_simple',
)
with get_dist(tmpdir) as dist:
@@ -358,7 +332,7 @@ class TestMetadata:
'[options]\n'
'package_dir =\n'
' fake_package_rename = fake_dir\n',
- package_path='fake_dir'
+ package_path='fake_dir',
)
with get_dist(tmpdir) as dist:
@@ -373,7 +347,7 @@ class TestMetadata:
'[options]\n'
'package_dir =\n'
' fake_package_complex = src/fake_dir\n',
- package_path='src/fake_dir'
+ package_path='src/fake_dir',
)
with get_dist(tmpdir) as dist:
@@ -381,39 +355,28 @@ class TestMetadata:
def test_unknown_meta_item(self, tmpdir):
- fake_env(
- tmpdir,
- '[metadata]\n'
- 'name = fake_name\n'
- 'unknown = some\n'
- )
+ fake_env(tmpdir, '[metadata]\n' 'name = fake_name\n' 'unknown = some\n')
with get_dist(tmpdir, parse=False) as dist:
dist.parse_config_files() # Skip unknown.
def test_usupported_section(self, tmpdir):
- fake_env(
- tmpdir,
- '[metadata.some]\n'
- 'key = val\n'
- )
+ fake_env(tmpdir, '[metadata.some]\n' 'key = val\n')
with get_dist(tmpdir, parse=False) as dist:
with pytest.raises(DistutilsOptionError):
dist.parse_config_files()
def test_classifiers(self, tmpdir):
- expected = set([
- 'Framework :: Django',
- 'Programming Language :: Python :: 3',
- 'Programming Language :: Python :: 3.5',
- ])
+ expected = set(
+ [
+ 'Framework :: Django',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.5',
+ ]
+ )
# From file.
- _, config = fake_env(
- tmpdir,
- '[metadata]\n'
- 'classifiers = file: classifiers\n'
- )
+ _, config = fake_env(tmpdir, '[metadata]\n' 'classifiers = file: classifiers\n')
tmpdir.join('classifiers').write(
'Framework :: Django\n'
@@ -441,7 +404,7 @@ class TestMetadata:
'[metadata]\n'
'version = 10.1.1\n'
'description = Some description\n'
- 'requires = some, requirement\n'
+ 'requires = some, requirement\n',
)
with pytest.deprecated_call():
@@ -453,41 +416,26 @@ class TestMetadata:
assert metadata.requires == ['some', 'requirement']
def test_interpolation(self, tmpdir):
- fake_env(
- tmpdir,
- '[metadata]\n'
- 'description = %(message)s\n'
- )
+ fake_env(tmpdir, '[metadata]\n' 'description = %(message)s\n')
with pytest.raises(configparser.InterpolationMissingOptionError):
with get_dist(tmpdir):
pass
def test_non_ascii_1(self, tmpdir):
- fake_env(
- tmpdir,
- '[metadata]\n'
- 'description = éàïôñ\n',
- encoding='utf-8'
- )
+ fake_env(tmpdir, '[metadata]\n' 'description = éàïôñ\n', encoding='utf-8')
with get_dist(tmpdir):
pass
def test_non_ascii_3(self, tmpdir):
- fake_env(
- tmpdir,
- '\n'
- '# -*- coding: invalid\n'
- )
+ fake_env(tmpdir, '\n' '# -*- coding: invalid\n')
with get_dist(tmpdir):
pass
def test_non_ascii_4(self, tmpdir):
fake_env(
tmpdir,
- '# -*- coding: utf-8\n'
- '[metadata]\n'
- 'description = éàïôñ\n',
- encoding='utf-8'
+ '# -*- coding: utf-8\n' '[metadata]\n' 'description = éàïôñ\n',
+ encoding='utf-8',
)
with get_dist(tmpdir) as dist:
assert dist.metadata.description == 'éàïôñ'
@@ -501,7 +449,7 @@ class TestMetadata:
'# vim: set fileencoding=iso-8859-15 :\n'
'[metadata]\n'
'description = éàïôñ\n',
- encoding='iso-8859-15'
+ encoding='iso-8859-15',
)
with pytest.raises(UnicodeDecodeError):
with get_dist(tmpdir):
@@ -514,11 +462,13 @@ class TestMetadata:
tmpdir,
'[metadata]\n'
'author-email = test@test.com\n'
- 'maintainer_email = foo@foo.com\n'
- )
- msg = ("Usage of dash-separated 'author-email' will not be supported "
- "in future versions. "
- "Please use the underscore name 'author_email' instead")
+ 'maintainer_email = foo@foo.com\n',
+ )
+ msg = (
+ "Usage of dash-separated 'author-email' will not be supported "
+ "in future versions. "
+ "Please use the underscore name 'author_email' instead"
+ )
with pytest.warns(UserWarning, match=msg):
with get_dist(tmpdir) as dist:
metadata = dist.metadata
@@ -530,14 +480,13 @@ class TestMetadata:
# remove this test and the method make_option_lowercase() in setuptools.dist
# when no longer needed
fake_env(
- tmpdir,
- '[metadata]\n'
- 'Name = foo\n'
- 'description = Some description\n'
+ tmpdir, '[metadata]\n' 'Name = foo\n' 'description = Some description\n'
+ )
+ msg = (
+ "Usage of uppercase key 'Name' in 'metadata' will be deprecated in "
+ "future versions. "
+ "Please use lowercase 'name' instead"
)
- msg = ("Usage of uppercase key 'Name' in 'metadata' will be deprecated in "
- "future versions. "
- "Please use lowercase 'name' instead")
with pytest.warns(UserWarning, match=msg):
with get_dist(tmpdir) as dist:
metadata = dist.metadata
@@ -547,21 +496,16 @@ class TestMetadata:
class TestOptions:
-
def test_basic(self, tmpdir):
fake_env(
tmpdir,
'[options]\n'
'zip_safe = True\n'
- 'use_2to3 = 1\n'
'include_package_data = yes\n'
'package_dir = b=c, =src\n'
'packages = pack_a, pack_b.subpack\n'
'namespace_packages = pack1, pack2\n'
- 'use_2to3_fixers = your.fixers, or.here\n'
- 'use_2to3_exclude_fixers = one.here, two.there\n'
- 'convert_2to3_doctests = src/tests/one.txt, src/two.txt\n'
'scripts = bin/one.py, bin/two.py\n'
'eager_resources = bin/one.py, bin/two.py\n'
'install_requires = docutils>=0.3; pack ==1.1, ==1.3; hey\n'
@@ -570,34 +514,24 @@ class TestOptions:
'dependency_links = http://some.com/here/1, '
'http://some.com/there/2\n'
'python_requires = >=1.0, !=2.8\n'
- 'py_modules = module1, module2\n'
+ 'py_modules = module1, module2\n',
)
with get_dist(tmpdir) as dist:
assert dist.zip_safe
- assert dist.use_2to3
assert dist.include_package_data
assert dist.package_dir == {'': 'src', 'b': 'c'}
assert dist.packages == ['pack_a', 'pack_b.subpack']
assert dist.namespace_packages == ['pack1', 'pack2']
- assert dist.use_2to3_fixers == ['your.fixers', 'or.here']
- assert dist.use_2to3_exclude_fixers == ['one.here', 'two.there']
- assert dist.convert_2to3_doctests == ([
- 'src/tests/one.txt', 'src/two.txt'])
assert dist.scripts == ['bin/one.py', 'bin/two.py']
- assert dist.dependency_links == ([
- 'http://some.com/here/1',
- 'http://some.com/there/2'
- ])
- assert dist.install_requires == ([
- 'docutils>=0.3',
- 'pack==1.1,==1.3',
- 'hey'
- ])
- assert dist.setup_requires == ([
- 'docutils>=0.3',
- 'spack ==1.1, ==1.3',
- 'there'
- ])
+ assert dist.dependency_links == (
+ ['http://some.com/here/1', 'http://some.com/there/2']
+ )
+ assert dist.install_requires == (
+ ['docutils>=0.3', 'pack==1.1,==1.3', 'hey']
+ )
+ assert dist.setup_requires == (
+ ['docutils>=0.3', 'spack ==1.1, ==1.3', 'there']
+ )
assert dist.tests_require == ['mock==0.7.2', 'pytest']
assert dist.python_requires == '>=1.0, !=2.8'
assert dist.py_modules == ['module1', 'module2']
@@ -615,15 +549,6 @@ class TestOptions:
'namespace_packages = \n'
' pack1\n'
' pack2\n'
- 'use_2to3_fixers = \n'
- ' your.fixers\n'
- ' or.here\n'
- 'use_2to3_exclude_fixers = \n'
- ' one.here\n'
- ' two.there\n'
- 'convert_2to3_doctests = \n'
- ' src/tests/one.txt\n'
- ' src/two.txt\n'
'scripts = \n'
' bin/one.py\n'
' bin/two.py\n'
@@ -643,39 +568,26 @@ class TestOptions:
' there\n'
'dependency_links = \n'
' http://some.com/here/1\n'
- ' http://some.com/there/2\n'
+ ' http://some.com/there/2\n',
)
with get_dist(tmpdir) as dist:
assert dist.package_dir == {'': 'src', 'b': 'c'}
assert dist.packages == ['pack_a', 'pack_b.subpack']
assert dist.namespace_packages == ['pack1', 'pack2']
- assert dist.use_2to3_fixers == ['your.fixers', 'or.here']
- assert dist.use_2to3_exclude_fixers == ['one.here', 'two.there']
- assert dist.convert_2to3_doctests == (
- ['src/tests/one.txt', 'src/two.txt'])
assert dist.scripts == ['bin/one.py', 'bin/two.py']
- assert dist.dependency_links == ([
- 'http://some.com/here/1',
- 'http://some.com/there/2'
- ])
- assert dist.install_requires == ([
- 'docutils>=0.3',
- 'pack==1.1,==1.3',
- 'hey'
- ])
- assert dist.setup_requires == ([
- 'docutils>=0.3',
- 'spack ==1.1, ==1.3',
- 'there'
- ])
+ assert dist.dependency_links == (
+ ['http://some.com/here/1', 'http://some.com/there/2']
+ )
+ assert dist.install_requires == (
+ ['docutils>=0.3', 'pack==1.1,==1.3', 'hey']
+ )
+ assert dist.setup_requires == (
+ ['docutils>=0.3', 'spack ==1.1, ==1.3', 'there']
+ )
assert dist.tests_require == ['mock==0.7.2', 'pytest']
def test_package_dir_fail(self, tmpdir):
- fake_env(
- tmpdir,
- '[options]\n'
- 'package_dir = a b\n'
- )
+ fake_env(tmpdir, '[options]\n' 'package_dir = a b\n')
with get_dist(tmpdir, parse=False) as dist:
with pytest.raises(DistutilsOptionError):
dist.parse_config_files()
@@ -689,7 +601,7 @@ class TestOptions:
'\n'
'[options.exclude_package_data]\n'
'* = fake1.txt, fake2.txt\n'
- 'hello = *.dat\n'
+ 'hello = *.dat\n',
)
with get_dist(tmpdir) as dist:
@@ -703,29 +615,21 @@ class TestOptions:
}
def test_packages(self, tmpdir):
- fake_env(
- tmpdir,
- '[options]\n'
- 'packages = find:\n'
- )
+ fake_env(tmpdir, '[options]\n' 'packages = find:\n')
with get_dist(tmpdir) as dist:
assert dist.packages == ['fake_package']
def test_find_directive(self, tmpdir):
- dir_package, config = fake_env(
- tmpdir,
- '[options]\n'
- 'packages = find:\n'
- )
+ dir_package, config = fake_env(tmpdir, '[options]\n' 'packages = find:\n')
dir_sub_one, _ = make_package_dir('sub_one', dir_package)
dir_sub_two, _ = make_package_dir('sub_two', dir_package)
with get_dist(tmpdir) as dist:
- assert set(dist.packages) == set([
- 'fake_package', 'fake_package.sub_two', 'fake_package.sub_one'
- ])
+ assert set(dist.packages) == set(
+ ['fake_package', 'fake_package.sub_two', 'fake_package.sub_one']
+ )
config.write(
'[options]\n'
@@ -749,14 +653,11 @@ class TestOptions:
' fake_package.sub_one\n'
)
with get_dist(tmpdir) as dist:
- assert set(dist.packages) == set(
- ['fake_package', 'fake_package.sub_two'])
+ assert set(dist.packages) == set(['fake_package', 'fake_package.sub_two'])
def test_find_namespace_directive(self, tmpdir):
dir_package, config = fake_env(
- tmpdir,
- '[options]\n'
- 'packages = find_namespace:\n'
+ tmpdir, '[options]\n' 'packages = find_namespace:\n'
)
dir_sub_one, _ = make_package_dir('sub_one', dir_package)
@@ -764,7 +665,9 @@ class TestOptions:
with get_dist(tmpdir) as dist:
assert set(dist.packages) == {
- 'fake_package', 'fake_package.sub_two', 'fake_package.sub_one'
+ 'fake_package',
+ 'fake_package.sub_two',
+ 'fake_package.sub_one',
}
config.write(
@@ -789,9 +692,7 @@ class TestOptions:
' fake_package.sub_one\n'
)
with get_dist(tmpdir) as dist:
- assert set(dist.packages) == {
- 'fake_package', 'fake_package.sub_two'
- }
+ assert set(dist.packages) == {'fake_package', 'fake_package.sub_two'}
def test_extras_require(self, tmpdir):
fake_env(
@@ -800,29 +701,21 @@ class TestOptions:
'pdf = ReportLab>=1.2; RXP\n'
'rest = \n'
' docutils>=0.3\n'
- ' pack ==1.1, ==1.3\n'
+ ' pack ==1.1, ==1.3\n',
)
with get_dist(tmpdir) as dist:
assert dist.extras_require == {
'pdf': ['ReportLab>=1.2', 'RXP'],
- 'rest': ['docutils>=0.3', 'pack==1.1,==1.3']
+ 'rest': ['docutils>=0.3', 'pack==1.1,==1.3'],
}
assert dist.metadata.provides_extras == set(['pdf', 'rest'])
def test_dash_preserved_extras_require(self, tmpdir):
- fake_env(
- tmpdir,
- '[options.extras_require]\n'
- 'foo-a = foo\n'
- 'foo_b = test\n'
- )
+ fake_env(tmpdir, '[options.extras_require]\n' 'foo-a = foo\n' 'foo_b = test\n')
with get_dist(tmpdir) as dist:
- assert dist.extras_require == {
- 'foo-a': ['foo'],
- 'foo_b': ['test']
- }
+ assert dist.extras_require == {'foo-a': ['foo'], 'foo_b': ['test']}
def test_entry_points(self, tmpdir):
_, config = fake_env(
@@ -830,7 +723,7 @@ class TestOptions:
'[options.entry_points]\n'
'group1 = point1 = pack.module:func, '
'.point2 = pack.module2:func_rest [rest]\n'
- 'group2 = point3 = pack.module:func2\n'
+ 'group2 = point3 = pack.module:func2\n',
)
with get_dist(tmpdir) as dist:
@@ -839,7 +732,7 @@ class TestOptions:
'point1 = pack.module:func',
'.point2 = pack.module2:func_rest [rest]',
],
- 'group2': ['point3 = pack.module:func2']
+ 'group2': ['point3 = pack.module:func2'],
}
expected = (
@@ -850,10 +743,7 @@ class TestOptions:
tmpdir.join('entry_points').write(expected)
# From file.
- config.write(
- '[options]\n'
- 'entry_points = file: entry_points\n'
- )
+ config.write('[options]\n' 'entry_points = file: entry_points\n')
with get_dist(tmpdir) as dist:
assert dist.entry_points == expected
@@ -864,7 +754,7 @@ class TestOptions:
'[options.entry_points]\n'
'GROUP1 = point1 = pack.module:func, '
'.point2 = pack.module2:func_rest [rest]\n'
- 'group2 = point3 = pack.module:func2\n'
+ 'group2 = point3 = pack.module:func2\n',
)
with get_dist(tmpdir) as dist:
@@ -873,7 +763,7 @@ class TestOptions:
'point1 = pack.module:func',
'.point2 = pack.module2:func_rest [rest]',
],
- 'group2': ['point3 = pack.module:func2']
+ 'group2': ['point3 = pack.module:func2'],
}
def test_data_files(self, tmpdir):
@@ -883,7 +773,7 @@ class TestOptions:
'cfg =\n'
' a/b.conf\n'
' c/d.conf\n'
- 'data = e/f.dat, g/h.dat\n'
+ 'data = e/f.dat, g/h.dat\n',
)
with get_dist(tmpdir) as dist:
@@ -931,10 +821,12 @@ class TestOptions:
def test_python_requires_simple(self, tmpdir):
fake_env(
tmpdir,
- DALS("""
+ DALS(
+ """
[options]
python_requires=>=2.7
- """),
+ """
+ ),
)
with get_dist(tmpdir) as dist:
dist.parse_config_files()
@@ -942,10 +834,12 @@ class TestOptions:
def test_python_requires_compound(self, tmpdir):
fake_env(
tmpdir,
- DALS("""
+ DALS(
+ """
[options]
python_requires=>=2.7,!=3.0.*
- """),
+ """
+ ),
)
with get_dist(tmpdir) as dist:
dist.parse_config_files()
@@ -953,10 +847,12 @@ class TestOptions:
def test_python_requires_invalid(self, tmpdir):
fake_env(
tmpdir,
- DALS("""
+ DALS(
+ """
[options]
python_requires=invalid
- """),
+ """
+ ),
)
with pytest.raises(Exception):
with get_dist(tmpdir) as dist:
@@ -974,9 +870,7 @@ class TestOptions:
fake_env(
tmpdir,
- '[options]\n'
- 'cmdclass =\n'
- ' customcmd = custom_build.CustomCmd\n'
+ '[options]\n' 'cmdclass =\n' ' customcmd = custom_build.CustomCmd\n',
)
with get_dist(tmpdir) as dist:
@@ -1000,24 +894,23 @@ class TestExternalSetters:
def _fake_distribution_init(self, dist, attrs):
saved_dist_init(dist, attrs)
# see self._DISTUTUILS_UNSUPPORTED_METADATA
- setattr(dist.metadata, 'long_description_content_type',
- 'text/something')
+ setattr(dist.metadata, 'long_description_content_type', 'text/something')
# Test overwrite setup() args
- setattr(dist.metadata, 'project_urls', {
- 'Link One': 'https://example.com/one/',
- 'Link Two': 'https://example.com/two/',
- })
+ setattr(
+ dist.metadata,
+ 'project_urls',
+ {
+ 'Link One': 'https://example.com/one/',
+ 'Link Two': 'https://example.com/two/',
+ },
+ )
return None
@patch.object(_Distribution, '__init__', autospec=True)
def test_external_setters(self, mock_parent_init, tmpdir):
mock_parent_init.side_effect = self._fake_distribution_init
- dist = Distribution(attrs={
- 'project_urls': {
- 'will_be': 'ignored'
- }
- })
+ dist = Distribution(attrs={'project_urls': {'will_be': 'ignored'}})
assert dist.metadata.long_description_content_type == 'text/something'
assert dist.metadata.project_urls == {
diff --git a/setuptools/tests/test_develop.py b/setuptools/tests/test_develop.py
index df8db4e2..3c2d924c 100644
--- a/setuptools/tests/test_develop.py
+++ b/setuptools/tests/test_develop.py
@@ -16,7 +16,6 @@ import pytest
from setuptools.command.develop import develop
from setuptools.dist import Distribution
-from setuptools.tests import ack_2to3
from . import contexts
from . import namespaces
@@ -25,7 +24,6 @@ from setuptools import setup
setup(name='foo',
packages=['foo'],
- use_2to3=True,
)
"""
@@ -62,43 +60,6 @@ class TestDevelop:
in_virtualenv = hasattr(sys, 'real_prefix')
in_venv = hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix
- @pytest.mark.skipif(
- in_virtualenv or in_venv,
- reason="Cannot run when invoked in a virtualenv or venv")
- @ack_2to3
- def test_2to3_user_mode(self, test_env):
- settings = dict(
- name='foo',
- packages=['foo'],
- use_2to3=True,
- version='0.0',
- )
- dist = Distribution(settings)
- dist.script_name = 'setup.py'
- cmd = develop(dist)
- cmd.user = 1
- cmd.ensure_finalized()
- cmd.install_dir = site.USER_SITE
- cmd.user = 1
- with contexts.quiet():
- cmd.run()
-
- # let's see if we got our egg link at the right place
- content = os.listdir(site.USER_SITE)
- content.sort()
- assert content == ['easy-install.pth', 'foo.egg-link']
-
- # Check that we are using the right code.
- fn = os.path.join(site.USER_SITE, 'foo.egg-link')
- with io.open(fn) as egg_link_file:
- path = egg_link_file.read().split()[0].strip()
- fn = os.path.join(path, 'foo', '__init__.py')
- with io.open(fn) as init_file:
- init = init_file.read().strip()
-
- expected = 'print("foo")'
- assert init == expected
-
def test_console_scripts(self, tmpdir):
"""
Test that console scripts are installed and that they reference
@@ -106,7 +67,8 @@ class TestDevelop:
"""
pytest.skip(
"TODO: needs a fixture to cause 'develop' "
- "to be invoked without mutating environment.")
+ "to be invoked without mutating environment."
+ )
settings = dict(
name='foo',
packages=['foo'],
@@ -132,6 +94,7 @@ class TestResolver:
of what _resolve_setup_path is intending to do. Come up with
more meaningful cases that look like real-world scenarios.
"""
+
def test_resolve_setup_path_cwd(self):
assert develop._resolve_setup_path('.', '.', '.') == '.'
@@ -143,7 +106,6 @@ class TestResolver:
class TestNamespaces:
-
@staticmethod
def install_develop(src_dir, target):
@@ -151,7 +113,8 @@ class TestNamespaces:
sys.executable,
'setup.py',
'develop',
- '--install-dir', str(target),
+ '--install-dir',
+ str(target),
]
with src_dir.as_cwd():
with test.test.paths_on_pythonpath([str(target)]):
@@ -182,14 +145,16 @@ class TestNamespaces:
'pip',
'install',
str(pkg_A),
- '-t', str(target),
+ '-t',
+ str(target),
]
subprocess.check_call(install_cmd)
self.install_develop(pkg_B, target)
namespaces.make_site_dir(target)
try_import = [
sys.executable,
- '-c', 'import myns.pkgA; import myns.pkgB',
+ '-c',
+ 'import myns.pkgA; import myns.pkgB',
]
with test.test.paths_on_pythonpath([str(target)]):
subprocess.check_call(try_import)
@@ -197,7 +162,8 @@ class TestNamespaces:
# additionally ensure that pkg_resources import works
pkg_resources_imp = [
sys.executable,
- '-c', 'import pkg_resources',
+ '-c',
+ 'import pkg_resources',
]
with test.test.paths_on_pythonpath([str(target)]):
subprocess.check_call(pkg_resources_imp)
@@ -206,12 +172,16 @@ class TestNamespaces:
def install_workaround(site_packages):
site_packages.mkdir(parents=True)
sc = site_packages / 'sitecustomize.py'
- sc.write_text(textwrap.dedent("""
+ sc.write_text(
+ textwrap.dedent(
+ """
import site
import pathlib
here = pathlib.Path(__file__).parent
site.addsitedir(str(here))
- """).lstrip())
+ """
+ ).lstrip()
+ )
@pytest.mark.xfail(
platform.python_implementation() == 'PyPy',
@@ -228,8 +198,7 @@ class TestNamespaces:
site_packages = prefix / next(
pathlib.Path(path).relative_to(sys.prefix)
for path in sys.path
- if 'site-packages' in path
- and path.startswith(sys.prefix)
+ if 'site-packages' in path and path.startswith(sys.prefix)
)
# install the workaround
@@ -238,11 +207,13 @@ class TestNamespaces:
env = dict(os.environ, PYTHONPATH=str(site_packages))
cmd = [
sys.executable,
- '-m', 'pip',
+ '-m',
+ 'pip',
'install',
'--editable',
str(sample_project),
- '--prefix', str(prefix),
+ '--prefix',
+ str(prefix),
'--no-build-isolation',
]
subprocess.check_call(cmd, env=env)
diff --git a/setuptools/tests/test_test.py b/setuptools/tests/test_test.py
index 180562e2..4e7193c8 100644
--- a/setuptools/tests/test_test.py
+++ b/setuptools/tests/test_test.py
@@ -6,12 +6,12 @@ import pytest
from setuptools.command.test import test
from setuptools.dist import Distribution
-from setuptools.tests import ack_2to3
from .textwrap import DALS
-SETUP_PY = DALS("""
+SETUP_PY = DALS(
+ """
from setuptools import setup
setup(name='foo',
@@ -19,9 +19,11 @@ SETUP_PY = DALS("""
namespace_packages=['name'],
test_suite='name.space.tests.test_suite',
)
- """)
+ """
+)
-NS_INIT = DALS("""
+NS_INIT = DALS(
+ """
# -*- coding: Latin-1 -*-
# Söme Arbiträry Ünicode to test Distribute Issüé 310
try:
@@ -29,17 +31,20 @@ NS_INIT = DALS("""
except ImportError:
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
- """)
+ """
+)
-TEST_PY = DALS("""
+TEST_PY = DALS(
+ """
import unittest
class TestTest(unittest.TestCase):
def test_test(self):
- print "Foo" # Should fail under Python 3 unless 2to3 is used
+ print "Foo" # Should fail under Python 3
test_suite = unittest.makeSuite(TestTest)
- """)
+ """
+)
@pytest.fixture
@@ -70,25 +75,6 @@ def quiet_log():
log.set_verbosity(0)
-@pytest.mark.usefixtures('sample_test', 'quiet_log')
-@ack_2to3
-def test_test(capfd):
- params = dict(
- name='foo',
- packages=['name', 'name.space', 'name.space.tests'],
- namespace_packages=['name'],
- test_suite='name.space.tests.test_suite',
- use_2to3=True,
- )
- dist = Distribution(params)
- dist.script_name = 'setup.py'
- cmd = test(dist)
- cmd.ensure_finalized()
- cmd.run()
- out, err = capfd.readouterr()
- assert out == 'Foo\n'
-
-
@pytest.mark.usefixtures('tmpdir_cwd', 'quiet_log')
def test_tests_are_run_once(capfd):
params = dict(
@@ -104,13 +90,16 @@ def test_tests_are_run_once(capfd):
with open('dummy/__init__.py', 'wt'):
pass
with open('dummy/test_dummy.py', 'wt') as f:
- f.write(DALS(
- """
+ f.write(
+ DALS(
+ """
import unittest
class TestTest(unittest.TestCase):
def test_test(self):
print('Foo')
- """))
+ """
+ )
+ )
dist = Distribution(params)
dist.script_name = 'setup.py'
cmd = test(dist)
@@ -118,54 +107,3 @@ def test_tests_are_run_once(capfd):
cmd.run()
out, err = capfd.readouterr()
assert out == 'Foo\n'
-
-
-@pytest.mark.usefixtures('sample_test')
-@ack_2to3
-def test_warns_deprecation(capfd):
- params = dict(
- name='foo',
- packages=['name', 'name.space', 'name.space.tests'],
- namespace_packages=['name'],
- test_suite='name.space.tests.test_suite',
- use_2to3=True
- )
- dist = Distribution(params)
- dist.script_name = 'setup.py'
- cmd = test(dist)
- cmd.ensure_finalized()
- cmd.announce = mock.Mock()
- cmd.run()
- capfd.readouterr()
- msg = (
- "WARNING: Testing via this command is deprecated and will be "
- "removed in a future version. Users looking for a generic test "
- "entry point independent of test runner are encouraged to use "
- "tox."
- )
- cmd.announce.assert_any_call(msg, log.WARN)
-
-
-@pytest.mark.usefixtures('sample_test')
-@ack_2to3
-def test_deprecation_stderr(capfd):
- params = dict(
- name='foo',
- packages=['name', 'name.space', 'name.space.tests'],
- namespace_packages=['name'],
- test_suite='name.space.tests.test_suite',
- use_2to3=True
- )
- dist = Distribution(params)
- dist.script_name = 'setup.py'
- cmd = test(dist)
- cmd.ensure_finalized()
- cmd.run()
- out, err = capfd.readouterr()
- msg = (
- "WARNING: Testing via this command is deprecated and will be "
- "removed in a future version. Users looking for a generic test "
- "entry point independent of test runner are encouraged to use "
- "tox.\n"
- )
- assert msg in err