[bumpversion]
-current_version = 45.1.0
+current_version = 45.2.0
commit = True
tag = True
--- /dev/null
+[flake8]
+exclude=
+ .tox
+ setuptools/_vendor,
+ pkg_resources/_vendor
+ignore =
+ # W503 violates spec https://github.com/PyCQA/pycodestyle/issues/513
+ W503
+ # W504 has issues https://github.com/OCA/maintainer-quality-tools/issues/545
+ W504
+ setuptools/site-patch.py F821
+ setuptools/py*compat.py F811
-name: Test suite
+name: >-
+ 👷
+ Test suite
on:
push:
jobs:
tests:
- name: 👷
+ name: >-
+ ${{ matrix.python-version }}
+ /
+ ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
# max-parallel: 5
matrix:
python-version:
- 3.8
+ - pypy3
- 3.7
- 3.6
- 3.5
- - 2.7
os:
- - ubuntu-18.04
+ - ubuntu-latest
- ubuntu-16.04
- macOS-latest
# - windows-2019
# - windows-2016
- env:
- - TOXENV: python
+
+ env:
+ NETWORK_REQUIRED: 1
+ TOX_PARALLEL_NO_SPINNER: 1
+ TOXENV: python
steps:
- uses: actions/checkout@master
- name: Set up Python ${{ matrix.python-version }}
- uses: actions/setup-python@v1
+ uses: actions/setup-python@v1.1.1
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Log Python version
+ run: >-
+ python --version
+ - name: Log Python location
+ run: >-
+ which python
+ - name: Log Python env
+ run: >-
+ python -m sysconfig
+ - name: Pip cache
+ uses: actions/cache@v1
with:
- version: ${{ matrix.python-version }}
+ path: ~/.cache/pip
+ key: ${{ runner.os }}-pip-${{ hashFiles('setup.cfg') }}
+ restore-keys: |
+ ${{ runner.os }}-pip-
+ ${{ runner.os }}-
- name: Upgrade pip/setuptools/wheel
run: >-
python
- name: Log installed dists
run: >-
python -m pip freeze --all
+ - name: Adjust TOXENV for PyPy
+ if: startsWith(matrix.python-version, 'pypy')
+ run: >-
+ echo "::set-env name=TOXENV::${{ matrix.python-version }}"
- name: Log env vars
run: >-
env
- env: ${{ matrix.env }}
- - name: Update egg_info based on setup.py in checkout
- run: >-
- python -m bootstrap
- env: ${{ matrix.env }}
- name: Verify that there's no cached Python modules in sources
if: >-
! startsWith(matrix.os, 'windows-')
! grep pyc setuptools.egg-info/SOURCES.txt
- name: 'Initialize tox envs: ${{ matrix.env.TOXENV }}'
- run: |
- python -m tox --parallel auto --notest --skip-missing-interpreters false
- env: ${{ matrix.env }}
+ run: >-
+ python -m
+ tox
+ --parallel auto
+ --notest
+ --skip-missing-interpreters false
- name: Test with tox
- run: |
- ${{ startsWith(matrix.os, 'windows-') && 'setx NETWORK_REQUIRED ' || 'export NETWORK_REQUIRED=' }}1
- python -m tox \
- --parallel 0 \
- -- \
+ run: >-
+ python -m
+ tox
+ --parallel auto
+ --
--cov
- env: ${{ matrix.env }}
python:
version: 3
- requirements_file: docs/requirements.txt
- pip_install: false
+ extra_requirements:
+ - docs
+ pip_install: true
- pip freeze --all
- env
-# update egg_info based on setup.py in checkout
-- python bootstrap.py
- "! grep pyc setuptools.egg-info/SOURCES.txt"
script:
+v45.2.0
+-------
+
+* #1905: Fixed defect in _imp, introduced in 41.6.0 when the 'tests' directory is not present.
+* #1941: Improve editable installs with PEP 518 build isolation:
+
+ * The ``--user`` option is now always available. A warning is issued if the user site directory is not available.
+ * The error shown when the install directory is not in ``PYTHONPATH`` has been turned into a warning.
+* #1981: Setuptools now declares its ``tests`` and ``docs`` dependencies in metadata (extras).
+* #1985: Add support for installing scripts in environments where bdist_wininst is missing (i.e. Python 3.9).
+* #1968: Add flake8-2020 to check for misuse of sys.version or sys.version_info.
+
+
v45.1.0
-------
- python -m pip install --disable-pip-version-check --upgrade pip setuptools wheel
- pip install --upgrade tox tox-venv virtualenv
- pip freeze --all
- - python bootstrap.py
- tox -- --cov
after_test:
--- /dev/null
+# Create the project in Azure with:
+# az devops project create --name $name --organization https://dev.azure.com/$org/ --visibility public
+# then configure the pipelines (through web UI)
+
+trigger:
+ branches:
+ include:
+ - '*'
+ tags:
+ include:
+ - '*'
+
+pool:
+ vmimage: 'Ubuntu-18.04'
+
+variables:
+- group: Azure secrets
+
+stages:
+- stage: Test
+ jobs:
+
+ - job: 'Test'
+ strategy:
+ matrix:
+ Python36:
+ python.version: '3.6'
+ Python38:
+ python.version: '3.8'
+ maxParallel: 4
+
+ steps:
+ - task: UsePythonVersion@0
+ inputs:
+ versionSpec: '$(python.version)'
+ architecture: 'x64'
+
+ - script: python -m pip install tox
+ displayName: 'Install tox'
+
+ - script: |
+ tox -- --junit-xml=test-results.xml
+ displayName: 'run tests'
+
+ - task: PublishTestResults@2
+ inputs:
+ testResultsFiles: '**/test-results.xml'
+ testRunTitle: 'Python $(python.version)'
+ condition: succeededOrFailed()
+
+- stage: Publish
+ dependsOn: Test
+ jobs:
+ - job: 'Publish'
+
+ steps:
+ - task: UsePythonVersion@0
+ inputs:
+ versionSpec: '3.8'
+ architecture: 'x64'
+
+ - script: python -m pip install tox
+ displayName: 'Install tox'
+
+ - script: |
+ tox -e release
+ env:
+ TWINE_PASSWORD: $(PyPI-token)
+ displayName: 'publish to PyPI'
+
+ condition: contains(variables['Build.SourceBranch'], 'tags')
entry_points = setuptools.dist:check_entry_points
[egg_info.writers]
+ PKG-INFO = setuptools.command.egg_info:write_pkg_info
dependency_links.txt = setuptools.command.egg_info:overwrite_arg
entry_points.txt = setuptools.command.egg_info:write_entries
requires.txt = setuptools.command.egg_info:write_requirements
if os.path.exists('setuptools.egg-info'):
return
print("adding minimal entry_points")
- build_egg_info()
+ add_minimal_info()
+ run_egg_info()
-def build_egg_info():
+def add_minimal_info():
"""
Build a minimal egg-info, enough to invoke egg_info
"""
cmd = [sys.executable, 'setup.py', 'egg_info']
print("Regenerating egg_info")
subprocess.check_call(cmd)
- print("...and again.")
- subprocess.check_call(cmd)
-
-
-def main():
- ensure_egg_info()
- run_egg_info()
-__name__ == '__main__' and main()
+__name__ == '__main__' and ensure_egg_info()
-# -*- coding: utf-8 -*-
-#
-# Setuptools documentation build configuration file, created by
-# sphinx-quickstart on Fri Jul 17 14:22:37 2009.
-#
-# This file is execfile()d with the current directory set to its containing dir.
-#
-# The contents of this file are pickled, so don't put values in the namespace
-# that aren't pickleable (module imports are okay, they're removed automatically).
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-
import subprocess
import sys
import os
# hack to run the bootstrap script so that jaraco.packaging.sphinx
# can invoke setup.py
'READTHEDOCS' in os.environ and subprocess.check_call(
- [sys.executable, 'bootstrap.py'],
+ [sys.executable, '-m', 'bootstrap'],
cwd=os.path.join(os.path.dirname(__file__), os.path.pardir),
)
-# -- General configuration -----------------------------------------------------
+# -- General configuration --
-# Add any Sphinx extension module names here, as strings. They can be extensions
-# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['jaraco.packaging.sphinx', 'rst.linker']
# Add any paths that contain templates here, relative to this directory.
# The master toctree document.
master_doc = 'index'
-# A list of glob-style patterns that should be excluded when looking for source files.
+# A list of glob-style patterns that should be excluded
+# when looking for source files.
exclude_patterns = ['requirements.txt']
# List of directories, relative to source directory, that shouldn't be searched
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
-# -- Options for HTML output ---------------------------------------------------
+# -- Options for HTML output --
# The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'.
html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
-html_sidebars = {'index': ['relations.html', 'sourcelink.html', 'indexsidebar.html', 'searchbox.html']}
+html_sidebars = {
+ 'index': [
+ 'relations.html', 'sourcelink.html', 'indexsidebar.html',
+ 'searchbox.html']}
# If false, no module index is generated.
html_use_modindex = False
# If false, no index is generated.
html_use_index = False
-# -- Options for LaTeX output --------------------------------------------------
+# -- Options for LaTeX output --
# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, documentclass [howto/manual]).
-latex_documents = [
- ('index', 'Setuptools.tex', 'Setuptools Documentation',
- 'The fellowship of the packaging', 'manual'),
-]
+# (source start file, target name, title, author,
+# documentclass [howto/manual]).
+latex_documents = [(
+ 'index', 'Setuptools.tex', 'Setuptools Documentation',
+ 'The fellowship of the packaging', 'manual',
+)]
link_files = {
'../CHANGES.rst': dict(
Testing
-------
-The primary tests are run using tox. To run the tests, first create the metadata
-needed to run the tests::
-
- $ python bootstrap.py
-
-Then make sure you have tox installed, and invoke it::
+The primary tests are run using tox. Make sure you have tox installed,
+and invoke it::
$ tox
+++ /dev/null
-sphinx!=1.8.0
-rst.linker>=1.9
-jaraco.packaging>=6.1
-
-setuptools>=34
def normalize_path(filename):
"""Normalize a file/dir name for comparison purposes"""
- return os.path.normcase(os.path.realpath(os.path.normpath(_cygwin_patch(filename))))
+ return os.path.normcase(os.path.realpath(os.path.normpath(
+ _cygwin_patch(filename))))
def _cygwin_patch(filename): # pragma: nocover
list(map(working_set.add_entry, sys.path))
globals().update(locals())
+
class PkgResourcesDeprecationWarning(Warning):
"""
Base class for warning about deprecations in ``pkg_resources``
except ImportError:
import mock
-from pkg_resources import DistInfoDistribution, Distribution, EggInfoDistribution
+from pkg_resources import (
+ DistInfoDistribution, Distribution, EggInfoDistribution,
+)
from setuptools.extern import six
from pkg_resources.extern.six.moves import map
from pkg_resources.extern.six import text_type, string_types
('dist-info', 'METADATA', DistInfoDistribution),
],
)
-def test_distribution_version_missing(tmpdir, suffix, expected_filename,
- expected_dist_type):
+def test_distribution_version_missing(
+ tmpdir, suffix, expected_filename, expected_dist_type):
"""
Test Distribution.version when the "Version" header is missing.
"""
from pkg_resources import (
parse_requirements, VersionConflict, parse_version,
Distribution, EntryPoint, Requirement, safe_version, safe_name,
- WorkingSet, PkgResourcesDeprecationWarning)
+ WorkingSet)
# from Python 3.6 docs.
ep.load(require=False)
-
class TestRequirements:
def testBasics(self):
r = Requirement.parse("Twisted>=1.2")
[pytest]
-addopts=--doctest-modules --doctest-glob=pkg_resources/api_tests.txt -r sxX
-norecursedirs=dist build *.egg setuptools/extern pkg_resources/extern pkg_resources/tests/data tools .*
-flake8-ignore =
- setuptools/site-patch.py F821
- setuptools/py*compat.py F811
+addopts=--doctest-modules --flake8 --doctest-glob=pkg_resources/api_tests.txt -r sxX
+norecursedirs=dist build *.egg setuptools/extern pkg_resources/extern pkg_resources/tests/data tools .* setuptools/_vendor pkg_resources/_vendor
doctest_optionflags=ELLIPSIS ALLOW_UNICODE
filterwarnings =
# https://github.com/pypa/setuptools/issues/1823
[metadata]
name = setuptools
-version = 45.1.0
+version = 45.2.0
description = Easily download, build, install, upgrade, and uninstall Python packages
author = Python Packaging Authority
author_email = distutils-sig@python.org
[options.extras_require]
ssl =
wincertstore==0.2; sys_platform=='win32'
+
certs =
certifi==2016.9.26
+
+tests =
+ mock
+ pytest-flake8
+ flake8-2020; python_version>="3.6"
+ virtualenv>=13.0.0
+ pytest-virtualenv>=1.2.7
+ pytest>=3.7
+ wheel
+ coverage>=4.5.1
+ pytest-cov>=2.5.1
+ paver; python_version>="3.6"
+ futures; python_version=="2.7"
+ pip>=19.1 # For proper file:// URLs support.
+
+docs =
+ sphinx
+ jaraco.packaging>=6.1
+ rst.linker>=1.9
"""Extensions to the 'distutils' for large or complex distributions"""
import os
-import sys
import functools
import distutils.core
import distutils.filelist
]
if PY3:
- __all__.append('find_namespace_packages')
+ __all__.append('find_namespace_packages')
__version__ = setuptools.version.__version__
find_packages = PackageFinder.find
if PY3:
- find_namespace_packages = PEP420PackageFinder.find
+ find_namespace_packages = PEP420PackageFinder.find
def _install_setup_requires(attrs):
_install_setup_requires(attrs)
return distutils.core.setup(**attrs)
+
setup.__doc__ = distutils.core.setup.__doc__
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)
PY_FROZEN = 7
+def find_spec(module, paths):
+ finder = (
+ importlib.machinery.PathFinder().find_spec
+ if isinstance(paths, list) else
+ importlib.util.find_spec
+ )
+ return finder(module, paths)
+
+
def find_module(module, paths=None):
"""Just like 'imp.find_module()', but with package support"""
- spec = importlib.util.find_spec(module, paths)
+ spec = find_spec(module, paths)
if spec is None:
raise ImportError("Can't find %s" % module)
if not spec.has_location and hasattr(spec, 'submodule_search_locations'):
def get_frozen_object(module, paths=None):
- spec = importlib.util.find_spec(module, paths)
+ spec = find_spec(module, paths)
if not spec:
raise ImportError("Can't find %s" % module)
return spec.loader.get_code(module)
def get_module(module, paths, info):
- spec = importlib.util.find_spec(module, paths)
+ spec = find_spec(module, paths)
if not spec:
raise ImportError("Can't find %s" % module)
return module_from_spec(spec)
return dst
-def unpack_archive(filename, extract_dir, progress_filter=default_filter,
+def unpack_archive(
+ filename, extract_dir, progress_filter=default_filter,
drivers=None):
"""Unpack `filename` to `extract_dir`, or raise ``UnrecognizedFormat``
# resolve any links and to extract the link targets as normal
# files
- while member is not None and (member.islnk() or member.issym()):
+ while member is not None and (
+ member.islnk() or member.issym()):
linkpath = member.linkname
if member.issym():
base = posixpath.dirname(member.name)
'__legacy__',
'SetupRequirementsError']
+
class SetupRequirementsError(BaseException):
def __init__(self, specifiers):
self.specifiers = specifiers
def get_requires_for_build_wheel(self, config_settings=None):
config_settings = self._fix_config(config_settings)
- return self._get_build_requires(config_settings, requirements=['wheel'])
+ return self._get_build_requires(
+ config_settings, requirements=['wheel'])
def get_requires_for_build_sdist(self, config_settings=None):
config_settings = self._fix_config(config_settings)
dist_infos = [f for f in os.listdir(dist_info_directory)
if f.endswith('.dist-info')]
- if (len(dist_infos) == 0 and
- len(_get_immediate_subdirectories(dist_info_directory)) == 1):
+ if (
+ len(dist_infos) == 0 and
+ len(_get_immediate_subdirectories(dist_info_directory)) == 1
+ ):
dist_info_directory = os.path.join(
dist_info_directory, os.listdir(dist_info_directory)[0])
config_settings["--global-option"])
self.run_setup()
- result_basename = _file_with_extension(tmp_dist_dir, result_extension)
+ result_basename = _file_with_extension(
+ tmp_dist_dir, result_extension)
result_path = os.path.join(result_directory, result_basename)
if os.path.exists(result_path):
# os.rename will fail overwriting on non-Unix.
return result_basename
-
def build_wheel(self, wheel_directory, config_settings=None,
metadata_directory=None):
return self._build_with_temp_dir(['bdist_wheel'], '.whl',
class _BuildMetaLegacyBackend(_BuildMetaBackend):
"""Compatibility backend for setuptools
- This is a version of setuptools.build_meta that endeavors to maintain backwards
- compatibility with pre-PEP 517 modes of invocation. It exists as a temporary
- bridge between the old packaging mechanism and the new packaging mechanism,
+ This is a version of setuptools.build_meta that endeavors
+ to maintain backwards
+ compatibility with pre-PEP 517 modes of invocation. It
+ exists as a temporary
+ bridge between the old packaging mechanism and the new
+ packaging mechanism,
and will eventually be removed.
"""
def run_setup(self, setup_script='setup.py'):
sys.path[:] = sys_path
sys.argv[0] = sys_argv_0
+
# The primary backend
_BACKEND = _BuildMetaBackend()
sources = build_info.get('sources')
if sources is None or not isinstance(sources, (list, tuple)):
raise DistutilsSetupError(
- "in 'libraries' option (library '%s'), "
- "'sources' must be present and must be "
- "a list of source filenames" % lib_name)
+ "in 'libraries' option (library '%s'), "
+ "'sources' must be present and must be "
+ "a list of source filenames" % lib_name)
sources = list(sources)
log.info("building '%s' library", lib_name)
obj_deps = build_info.get('obj_deps', dict())
if not isinstance(obj_deps, dict):
raise DistutilsSetupError(
- "in 'libraries' option (library '%s'), "
- "'obj_deps' must be a dictionary of "
- "type 'source: list'" % lib_name)
+ "in 'libraries' option (library '%s'), "
+ "'obj_deps' must be a dictionary of "
+ "type 'source: list'" % lib_name)
dependencies = []
# Get the global dependencies that are specified by the '' key.
global_deps = obj_deps.get('', list())
if not isinstance(global_deps, (list, tuple)):
raise DistutilsSetupError(
- "in 'libraries' option (library '%s'), "
- "'obj_deps' must be a dictionary of "
- "type 'source: list'" % lib_name)
+ "in 'libraries' option (library '%s'), "
+ "'obj_deps' must be a dictionary of "
+ "type 'source: list'" % lib_name)
# Build the list to be used by newer_pairwise_group
# each source will be auto-added to its dependencies.
extra_deps = obj_deps.get(source, list())
if not isinstance(extra_deps, (list, tuple)):
raise DistutilsSetupError(
- "in 'libraries' option (library '%s'), "
- "'obj_deps' must be a dictionary of "
- "type 'source: list'" % lib_name)
+ "in 'libraries' option (library '%s'), "
+ "'obj_deps' must be a dictionary of "
+ "type 'source: list'" % lib_name)
src_deps.extend(extra_deps)
dependencies.append(src_deps)
expected_objects = self.compiler.object_filenames(
- sources,
- output_dir=self.build_temp
- )
+ sources,
+ output_dir=self.build_temp,
+ )
- if newer_pairwise_group(dependencies, expected_objects) != ([], []):
+ if (
+ newer_pairwise_group(dependencies, expected_objects)
+ != ([], [])
+ ):
# First, compile the source code to object files in the library
# directory. (This should probably change to putting object
# files in a temporary build directory.)
macros = build_info.get('macros')
include_dirs = build_info.get('include_dirs')
cflags = build_info.get('cflags')
- objects = self.compiler.compile(
- sources,
- output_dir=self.build_temp,
- macros=macros,
- include_dirs=include_dirs,
- extra_postargs=cflags,
- debug=self.debug
- )
+ self.compiler.compile(
+ sources,
+ output_dir=self.build_temp,
+ macros=macros,
+ include_dirs=include_dirs,
+ extra_postargs=cflags,
+ debug=self.debug
+ )
# Now "link" the object files together into a static library.
# (On Unix at least, this isn't really linking -- it just
# builds an archive. Whatever.)
self.compiler.create_static_lib(
- expected_objects,
- lib_name,
- output_dir=self.build_clib,
- debug=self.debug
- )
+ expected_objects,
+ lib_name,
+ output_dir=self.build_clib,
+ debug=self.debug
+ )
if six.PY2:
import imp
- EXTENSION_SUFFIXES = [s for s, _, tp in imp.get_suffixes() if tp == imp.C_EXTENSION]
+ EXTENSION_SUFFIXES = [
+ s for s, _, tp in imp.get_suffixes() if tp == imp.C_EXTENSION]
else:
from importlib.machinery import EXTENSION_SUFFIXES
# make sure _config_vars is initialized
get_config_var("LDSHARED")
-from distutils.sysconfig import _config_vars as _CONFIG_VARS
+from distutils.sysconfig import _config_vars as _CONFIG_VARS # noqa
def _customize_compiler_for_shlib(compiler):
except ImportError:
pass
-if_dl = lambda s: s if have_rtld else ''
+
+def if_dl(s):
+ return s if have_rtld else ''
def get_abi3_suffix():
return False
-_one_liner = lambda text: textwrap.dedent(text).strip().replace('\n', '; ')
+def _one_liner(text):
+ return textwrap.dedent(text).strip().replace('\n', '; ')
class easy_install(Command):
"allow building eggs from local checkouts"),
('version', None, "print version information and exit"),
('no-find-links', None,
- "Don't load find-links defined in packages being installed")
+ "Don't load find-links defined in packages being installed"),
+ ('user', None, "install in user site-package '%s'" % site.USER_SITE)
]
boolean_options = [
'zip-ok', 'multi-version', 'exclude-scripts', 'upgrade', 'always-copy',
'editable',
- 'no-deps', 'local-snapshots-ok', 'version'
+ 'no-deps', 'local-snapshots-ok', 'version',
+ 'user'
]
- if site.ENABLE_USER_SITE:
- help_msg = "install in user site-package '%s'" % site.USER_SITE
- user_options.append(('user', None, help_msg))
- boolean_options.append('user')
-
negative_opt = {'always-unzip': 'zip-ok'}
create_index = PackageIndex
self.config_vars['userbase'] = self.install_userbase
self.config_vars['usersite'] = self.install_usersite
+ elif self.user:
+ log.warn("WARNING: The user site-packages directory is disabled.")
+
self._fix_install_dir_for_user_site()
self.expand_basedirs()
if show_deprecation:
self.announce(
"WARNING: The easy_install command is deprecated "
- "and will be removed in a future version."
- , log.WARN,
+ "and will be removed in a future version.",
+ log.WARN,
)
if self.verbose != self.distribution.verbose:
log.set_verbosity(self.verbose)
self.cant_write_to_target()
if not is_site_dir and not self.multi_version:
- # Can't install non-multi to non-site dir
- raise DistutilsError(self.no_default_version_msg())
+ # Can't install non-multi to non-site dir with easy_install
+ pythonpath = os.environ.get('PYTHONPATH', '')
+ log.warn(self.__no_default_msg, self.install_dir, pythonpath)
if is_site_dir:
if self.pth_file is None:
the distutils default setting) was:
%s
- """).lstrip()
+ """).lstrip() # noqa
__not_exists_id = textwrap.dedent("""
This directory does not currently exist. Please create it and try again, or
choose a different installation directory (using the -d or --install-dir
option).
- """).lstrip()
+ """).lstrip() # noqa
__access_msg = textwrap.dedent("""
Perhaps your account does not have write access to this directory? If the
https://setuptools.readthedocs.io/en/latest/easy_install.html
Please make the appropriate changes for your system and try again.
- """).lstrip()
+ """).lstrip() # noqa
def cant_write_to_target(self):
msg = self.__cant_write_msg % (sys.exc_info()[1], self.install_dir,)
pkg_resources.require("%(name)s") # latest installed version
pkg_resources.require("%(name)s==%(version)s") # this exact version
pkg_resources.require("%(name)s>=%(version)s") # this version or higher
- """).lstrip()
+ """).lstrip() # noqa
__id_warning = textwrap.dedent("""
Note also that the installation directory must be on sys.path at runtime for
this to work. (e.g. by being the application's script directory, by being on
PYTHONPATH, or by being added to sys.path by your code.)
- """)
+ """) # noqa
def installation_report(self, req, dist, what="Installed"):
"""Helpful installation message for display to package users"""
%(python)s setup.py develop
See the setuptools documentation for the "develop" command for more info.
- """).lstrip()
+ """).lstrip() # noqa
def report_editable(self, spec, setup_script):
dirname = os.path.dirname(setup_script)
https://setuptools.readthedocs.io/en/latest/easy_install.html#custom-installation-locations
- Please make the appropriate changes for your system and try again.""").lstrip()
-
- def no_default_version_msg(self):
- template = self.__no_default_msg
- return template % (self.install_dir, os.environ.get('PYTHONPATH', ''))
+ Please make the appropriate changes for your system and try again.
+ """).strip()
def install_site_py(self):
"""Make sure there's a site.py in the target dir, if needed"""
@classmethod
def get_script_header(cls, script_text, executable=None, wininst=False):
# for backward compatibility
- warnings.warn("Use get_header", EasyInstallDeprecationWarning, stacklevel=2)
+ warnings.warn(
+ "Use get_header", EasyInstallDeprecationWarning, stacklevel=2)
if wininst:
executable = "python.exe"
return cls.get_header(script_text, executable)
finally:
distutils.core.gen_usage = saved
+
class EasyInstallDeprecationWarning(SetuptoolsDeprecationWarning):
- """Class for warning about deprecations in EasyInstall in SetupTools. Not ignored by default, unlike DeprecationWarning."""
-
+ """
+ Warning for EasyInstall deprecations, bypassing suppression.
+ """
from setuptools.extern import packaging
from setuptools import SetuptoolsDeprecationWarning
+
def translate_pattern(glob):
"""
Translate a file path glob like '*.txt' in to a regular expression.
pat += sep
pat += r'\Z'
- return re.compile(pat, flags=re.MULTILINE|re.DOTALL)
+ return re.compile(pat, flags=re.MULTILINE | re.DOTALL)
class InfoCommon:
def _write_requirements(stream, reqs):
lines = yield_lines(reqs or ())
- append_cr = lambda line: line + '\n'
+
+ def append_cr(line):
+ return line + '\n'
lines = map(append_cr, lines)
stream.writelines(lines)
Get a -r### off of PKG-INFO Version in case this is an sdist of
a subversion revision.
"""
- warnings.warn("get_pkg_info_revision is deprecated.", EggInfoDeprecationWarning)
+ warnings.warn(
+ "get_pkg_info_revision is deprecated.", EggInfoDeprecationWarning)
if os.path.exists('PKG-INFO'):
with io.open('PKG-INFO') as f:
for line in f:
class EggInfoDeprecationWarning(SetuptoolsDeprecationWarning):
- """Class for warning about deprecations in eggInfo in setupTools. Not ignored by default, unlike DeprecationWarning."""
+ """Deprecated behavior warning for EggInfo, bypassing suppression."""
if not hasattr(sys, 'implementation'):
return
- base = os.path.join('__pycache__', '__init__.' + sys.implementation.cache_tag)
+ base = os.path.join(
+ '__pycache__', '__init__.' + sys.implementation.cache_tag)
yield base + '.pyc'
yield base + '.pyo'
yield base + '.opt-1.pyc'
)
bs_cmd = self.get_finalized_command('build_scripts')
exec_param = getattr(bs_cmd, 'executable', None)
- bw_cmd = self.get_finalized_command("bdist_wininst")
- is_wininst = getattr(bw_cmd, '_is_running', False)
+ try:
+ bw_cmd = self.get_finalized_command("bdist_wininst")
+ is_wininst = getattr(bw_cmd, '_is_running', False)
+ except ImportError:
+ is_wininst = False
writer = ei.ScriptWriter
if is_wininst:
exec_param = "python.exe"
if hasattr(sdist.sdist, '_add_defaults_standards'):
# disable the functionality already available upstream
- class sdist_add_defaults:
+ class sdist_add_defaults: # noqa
pass
@contextlib.contextmanager
def project_on_sys_path(self, include_dists=[]):
- with_2to3 = not six.PY2 and getattr(self.distribution, 'use_2to3', False)
+ with_2to3 = not six.PY2 and getattr(
+ self.distribution, 'use_2to3', False)
if with_2to3:
# If we run 2to3 we can not do this inplace:
"""
Build up the MIME payload for the POST data
"""
- boundary = b'--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
- sep_boundary = b'\n--' + boundary
+ boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
+ sep_boundary = b'\n--' + boundary.encode('ascii')
end_boundary = sep_boundary + b'--'
end_items = end_boundary, b"\n",
builder = functools.partial(
part_groups = map(builder, data.items())
parts = itertools.chain.from_iterable(part_groups)
body_items = itertools.chain(parts, end_items)
- content_type = 'multipart/form-data; boundary=%s' % boundary.decode('ascii')
+ content_type = 'multipart/form-data; boundary=%s' % boundary
return b''.join(body_items), content_type
def upload_file(self, filename):
from distutils.dep_util import newer_group
+
# yes, this is was almost entirely copy-pasted from
# 'newer_pairwise()', this is just another convenience
# function.
of 'newer_group()'.
"""
if len(sources_groups) != len(targets):
- raise ValueError("'sources_group' and 'targets' must be the same length")
+ raise ValueError(
+ "'sources_group' and 'targets' must be the same length")
# build a pair of lists (sources_groups, targets) where source is newer
n_sources = []
if self.download_url:
write_field('Download-URL', self.download_url)
for project_url in self.project_urls.items():
- write_field('Project-URL', '%s, %s' % project_url)
+ write_field('Project-URL', '%s, %s' % project_url)
long_desc = rfc822_escape(self.get_long_description())
write_field('Description', long_desc)
dist.announce(
'WARNING: The pip package is not available, falling back '
'to EasyInstall for handling setup_requires/test_requires; '
- 'this is deprecated and will be removed in a future version.'
- , log.WARN
+ 'this is deprecated and will be removed in a future version.',
+ log.WARN
)
return _legacy_fetch_build_egg(dist, req)
# Warn if wheel is not.
# Except for VS15+, VC version is aligned with VS version
self.vs_ver = self.vc_ver = (
- vc_ver or self._find_latest_available_vs_ver())
+ vc_ver or self._find_latest_available_vs_ver())
def _find_latest_available_vs_ver(self):
"""
arch_subdir = self.pi.target_dir(x64=True)
lib = join(self.si.WindowsSdkDir, 'lib')
libver = self._sdk_subdir
- return [join(lib, '%sum%s' % (libver , arch_subdir))]
+ return [join(lib, '%sum%s' % (libver, arch_subdir))]
@property
def OSIncludes(self):
libpath += [
ref,
join(self.si.WindowsSdkDir, 'UnionMetadata'),
- join(ref, 'Windows.Foundation.UniversalApiContract', '1.0.0.0'),
+ join(
+ ref, 'Windows.Foundation.UniversalApiContract', '1.0.0.0'),
join(ref, 'Windows.Foundation.FoundationContract', '1.0.0.0'),
- join(ref,'Windows.Networking.Connectivity.WwanContract',
- '1.0.0.0'),
- join(self.si.WindowsSdkDir, 'ExtensionSDKs', 'Microsoft.VCLibs',
- '%0.1f' % self.vs_ver, 'References', 'CommonConfiguration',
- 'neutral'),
+ join(
+ ref, 'Windows.Networking.Connectivity.WwanContract',
+ '1.0.0.0'),
+ join(
+ self.si.WindowsSdkDir, 'ExtensionSDKs', 'Microsoft.VCLibs',
+ '%0.1f' % self.vs_ver, 'References', 'CommonConfiguration',
+ 'neutral'),
]
return libpath
"p = os.path.join(%(root)s, *%(pth)r)",
"importlib = has_mfs and __import__('importlib.util')",
"has_mfs and __import__('importlib.machinery')",
- "m = has_mfs and "
+ (
+ "m = has_mfs and "
"sys.modules.setdefault(%(pkg)r, "
- "importlib.util.module_from_spec("
- "importlib.machinery.PathFinder.find_spec(%(pkg)r, "
- "[os.path.dirname(p)])))",
- "m = m or "
- "sys.modules.setdefault(%(pkg)r, types.ModuleType(%(pkg)r))",
+ "importlib.util.module_from_spec("
+ "importlib.machinery.PathFinder.find_spec(%(pkg)r, "
+ "[os.path.dirname(p)])))"
+ ),
+ (
+ "m = m or "
+ "sys.modules.setdefault(%(pkg)r, types.ModuleType(%(pkg)r))"
+ ),
"mp = (m or []) and m.__dict__.setdefault('__path__',[])",
"(p not in mp) and mp.append(p)",
)
_SOCKET_TIMEOUT = 15
_tmpl = "setuptools/{setuptools.__version__} Python-urllib/{py_major}"
-user_agent = _tmpl.format(py_major='{}.{}'.format(*sys.version_info), setuptools=setuptools)
+user_agent = _tmpl.format(
+ py_major='{}.{}'.format(*sys.version_info), setuptools=setuptools)
def parse_requirement_arg(spec):
# copy of urllib.parse._splituser from Python 3.8
def _splituser(host):
- """splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'."""
+ """splituser('user[:passwd]@host[:port]')
+ --> 'user[:passwd]', 'host[:port]'."""
user, delim, host = host.rpartition('@')
return (user if delim else None), host
if six.PY2:
- def get_all_headers(message, key):
+ def get_all_headers(message, key): # noqa
return message.getheaders(key)
from setuptools.extern.six.moves import builtins, map
import pkg_resources.py31compat
+from distutils.errors import DistutilsError
+from pkg_resources import working_set
if sys.platform.startswith('java'):
import org.python.modules.posix.PosixModule as _os
except NameError:
_file = None
_open = open
-from distutils.errors import DistutilsError
-from pkg_resources import working_set
__all__ = [
if hasattr(os, 'devnull'):
- _EXCEPTIONS = [os.devnull,]
+ _EXCEPTIONS = [os.devnull]
else:
_EXCEPTIONS = []
WRITE_FLAGS = functools.reduce(
- operator.or_, [getattr(_os, a, 0) for a in
+ operator.or_, [
+ getattr(_os, a, 0) for a in
"O_WRONLY O_RDWR O_APPEND O_CREAT O_TRUNC O_TEMPORARY".split()]
)
else:
raise ImportError("Couldn't find the real 'site' module")
- known_paths = dict([(makepath(item)[1], 1) for item in sys.path]) # 2.2 comp
+ # 2.2 comp
+ known_paths = dict([(
+ makepath(item)[1], 1) for item in sys.path]) # noqa
oldpos = getattr(sys, '__egginsert', 0) # save old insertion position
sys.__egginsert = 0 # and reset the current one
for item in PYTHONPATH:
- addsitedir(item)
+ addsitedir(item) # noqa
sys.__egginsert += oldpos # restore effective old position
- d, nd = makepath(stdpath[0])
+ d, nd = makepath(stdpath[0]) # noqa
insert_at = None
new_path = []
for item in sys.path:
- p, np = makepath(item)
+ p, np = makepath(item) # noqa
if np == nd and insert_at is None:
# We've hit the first 'system' path entry, so added entries go here
except AttributeError:
HTTPSHandler = HTTPSConnection = object
-is_available = ssl is not None and object not in (HTTPSHandler, HTTPSConnection)
+is_available = ssl is not None and object not in (
+ HTTPSHandler, HTTPSConnection)
try:
return dn.lower() == hostname.lower()
# RFC 6125, section 6.4.3, subitem 1.
- # The client SHOULD NOT attempt to match a presented identifier in which
- # the wildcard character comprises a label other than the left-most label.
+ # The client SHOULD NOT attempt to match a
+ # presented identifier in which the wildcard
+ # character comprises a label other than the
+ # left-most label.
if leftmost == '*':
# When '*' is a fragment by itself, it matches a non-empty dotless
# fragment.
return
dnsnames.append(value)
if len(dnsnames) > 1:
- raise CertificateError("hostname %r "
- "doesn't match either of %s"
+ raise CertificateError(
+ "hostname %r doesn't match either of %s"
% (hostname, ', '.join(map(repr, dnsnames))))
elif len(dnsnames) == 1:
- raise CertificateError("hostname %r "
- "doesn't match %r"
+ raise CertificateError(
+ "hostname %r doesn't match %r"
% (hostname, dnsnames[0]))
else:
- raise CertificateError("no appropriate commonName or "
+ raise CertificateError(
+ "no appropriate commonName or "
"subjectAltName fields were found")
def https_open(self, req):
return self.do_open(
- lambda host, **kw: VerifyingHTTPSConn(host, self.ca_bundle, **kw), req
+ lambda host, **kw: VerifyingHTTPSConn(host, self.ca_bundle, **kw),
+ req
)
__all__ = [
- 'fail_on_ascii', 'py2_only', 'py3_only'
+ 'fail_on_ascii', 'py2_only', 'py3_only'
]
--- /dev/null
+mock
+pytest-flake8
+flake8-2020; python_version>="3.6"
+virtualenv>=13.0.0
+pytest-virtualenv>=1.2.7
+pytest>=3.7
+wheel
+coverage>=4.5.1
+pytest-cov>=2.5.1
+paver; python_version>="3.6"
+futures; python_version=="2.7"
+pip>=19.1 # For proper file:// URLs support.
class TestBuildCLib:
@mock.patch(
- 'setuptools.command.build_clib.newer_pairwise_group'
- )
+ 'setuptools.command.build_clib.newer_pairwise_group')
def test_build_libraries(self, mock_newer):
dist = Distribution()
cmd = build_clib(dist)
self.env = env
self.backend_name = backend_name
+
class BuildBackend(BuildBackendBase):
"""PEP 517 Build Backend"""
)
with get_dist(tmpdir) as dist:
assert set(dist.packages) == set(
- ['fake_package', 'fake_package.sub_two'])
+ ['fake_package', 'fake_package.sub_two'])
@py2_only
def test_find_namespace_directive_fails_on_py2(self, tmpdir):
)
with get_dist(tmpdir) as dist:
assert set(dist.packages) == {
- 'fake_package', 'fake_package.sub_two'
+ 'fake_package', 'fake_package.sub_two'
}
def test_extras_require(self, tmpdir):
return None
@patch.object(_Distribution, '__init__', autospec=True)
- def test_external_setters(self, mock_parent_init, tmpdir):
+ def test_external_setters(self, mock_parent_init, tmpdir):
mock_parent_init.side_effect = self._fake_distribution_init
dist = Distribution(attrs={
dist.fetch_build_egg(r)
for r in reqs
]
- assert [dist.key for dist in resolved_dists if dist] == reqs
+ # noqa below because on Python 2 it causes flakes
+ assert [dist.key for dist in resolved_dists if dist] == reqs # noqa
def test_dist__get_unpatched_deprecated():
dist = Distribution(attrs)
assert dist.metadata.provides_extras == ['b', 'a']
-
+
CHECK_PACKAGE_DATA_TESTS = (
# Valid.
({
({
'hello': str('*.msg'),
}, (
- "\"values of 'package_data' dict\" must be a list of strings (got '*.msg')"
+ "\"values of 'package_data' dict\" "
+ "must be a list of strings (got '*.msg')"
)),
# Invalid value type (generators are single use)
({
)
-@pytest.mark.parametrize('package_data, expected_message', CHECK_PACKAGE_DATA_TESTS)
+@pytest.mark.parametrize(
+ 'package_data, expected_message', CHECK_PACKAGE_DATA_TESTS)
def test_check_package_data(package_data, expected_message):
if expected_message is None:
assert check_package_data(None, 'package_data', package_data) is None
else:
- with pytest.raises(DistutilsSetupError, match=re.escape(expected_message)):
+ with pytest.raises(
+ DistutilsSetupError, match=re.escape(expected_message)):
check_package_data(None, str('package_data'), package_data)
test_pkg = create_setup_requires_package(
temp_dir, setup_attrs=dict(version='attr: foobar.version'),
make_package=make_dependency_sdist,
- use_setup_cfg=use_setup_cfg+('version',),
+ use_setup_cfg=use_setup_cfg + ('version',),
)
test_setup_py = os.path.join(test_pkg, 'setup.py')
with contexts.quiet() as (stdout, stderr):
dep_url = path_to_url(dep_sdist, authority='localhost')
test_pkg = create_setup_requires_package(
temp_dir,
- 'python-xlib', '0.19', # Ignored (overriden by setup_attrs).
- setup_attrs=dict(setup_requires='dependency @ %s' % dep_url))
+ # Ignored (overriden by setup_attrs)
+ 'python-xlib', '0.19',
+ setup_attrs=dict(
+ setup_requires='dependency @ %s' % dep_url))
test_setup_py = os.path.join(test_pkg, 'setup.py')
run_setup(test_setup_py, [str('--version')])
assert len(mock_index.requests) == 0
dep_1_0_sdist = 'dep-1.0.tar.gz'
dep_1_0_url = path_to_url(str(tmpdir / dep_1_0_sdist))
dep_1_0_python_requires = '>=2.7'
- make_python_requires_sdist(str(tmpdir / dep_1_0_sdist), 'dep', '1.0', dep_1_0_python_requires)
+ make_python_requires_sdist(
+ str(tmpdir / dep_1_0_sdist), 'dep', '1.0', dep_1_0_python_requires)
dep_2_0_sdist = 'dep-2.0.tar.gz'
dep_2_0_url = path_to_url(str(tmpdir / dep_2_0_sdist))
- dep_2_0_python_requires = '!=' + '.'.join(map(str, sys.version_info[:2])) + '.*'
- make_python_requires_sdist(str(tmpdir / dep_2_0_sdist), 'dep', '2.0', dep_2_0_python_requires)
+ dep_2_0_python_requires = '!=' + '.'.join(
+ map(str, sys.version_info[:2])) + '.*'
+ make_python_requires_sdist(
+ str(tmpdir / dep_2_0_sdist), 'dep', '2.0', dep_2_0_python_requires)
index = tmpdir / 'index.html'
index.write_text(DALS(
'''
<a href="{dep_2_0_url}" data-requires-python="{dep_2_0_python_requires}">{dep_2_0_sdist}</a><br/>
</body>
</html>
- ''').format(
+ ''').format( # noqa
dep_1_0_url=dep_1_0_url,
dep_1_0_sdist=dep_1_0_sdist,
dep_1_0_python_requires=dep_1_0_python_requires,
with contexts.save_pkg_resources_state():
test_pkg = create_setup_requires_package(
str(tmpdir),
- 'python-xlib', '0.19', # Ignored (overriden by setup_attrs).
- setup_attrs=dict(setup_requires='dep', dependency_links=[index_url]))
+ 'python-xlib', '0.19', # Ignored (overriden by setup_attrs).
+ setup_attrs=dict(
+ setup_requires='dep', dependency_links=[index_url]))
test_setup_py = os.path.join(test_pkg, 'setup.py')
run_setup(test_setup_py, [str('--version')])
- eggs = list(map(str, pkg_resources.find_distributions(os.path.join(test_pkg, '.eggs'))))
+ eggs = list(map(str, pkg_resources.find_distributions(
+ os.path.join(test_pkg, '.eggs'))))
assert eggs == ['dep 1.0']
- @pytest.mark.parametrize('use_legacy_installer,with_dependency_links_in_setup_py',
- itertools.product((False, True), (False, True)))
- def test_setup_requires_with_find_links_in_setup_cfg(self, monkeypatch,
- use_legacy_installer,
- with_dependency_links_in_setup_py):
+ @pytest.mark.parametrize(
+ 'use_legacy_installer,with_dependency_links_in_setup_py',
+ itertools.product((False, True), (False, True)))
+ def test_setup_requires_with_find_links_in_setup_cfg(
+ self, monkeypatch, use_legacy_installer,
+ with_dependency_links_in_setup_py):
monkeypatch.setenv(str('PIP_RETRIES'), str('0'))
monkeypatch.setenv(str('PIP_TIMEOUT'), str('0'))
with contexts.save_pkg_resources_state():
with contexts.tempdir() as temp_dir:
- make_trivial_sdist(os.path.join(temp_dir, 'python-xlib-42.tar.gz'), 'python-xlib', '42')
+ make_trivial_sdist(
+ os.path.join(temp_dir, 'python-xlib-42.tar.gz'),
+ 'python-xlib',
+ '42')
test_pkg = os.path.join(temp_dir, 'test_pkg')
test_setup_py = os.path.join(test_pkg, 'setup.py')
test_setup_cfg = os.path.join(test_pkg, 'setup.cfg')
installer.fetch_build_egg = installer._legacy_fetch_build_egg
setup(setup_requires='python-xlib==42',
dependency_links={dependency_links!r})
- ''').format(use_legacy_installer=use_legacy_installer,
+ ''').format(use_legacy_installer=use_legacy_installer, # noqa
dependency_links=dependency_links))
with open(test_setup_cfg, 'w') as fp:
fp.write(DALS(
find_links=temp_dir))
run_setup(test_setup_py, [str('--version')])
- def test_setup_requires_with_transitive_extra_dependency(self, monkeypatch):
+ def test_setup_requires_with_transitive_extra_dependency(
+ self, monkeypatch):
# Use case: installing a package with a build dependency on
# an already installed `dep[extra]`, which in turn depends
# on `extra_dep` (whose is not already installed).
with contexts.save_pkg_resources_state():
with contexts.tempdir() as temp_dir:
# Create source distribution for `extra_dep`.
- make_trivial_sdist(os.path.join(temp_dir, 'extra_dep-1.0.tar.gz'), 'extra_dep', '1.0')
+ make_trivial_sdist(
+ os.path.join(temp_dir, 'extra_dep-1.0.tar.gz'),
+ 'extra_dep', '1.0')
# Create source tree for `dep`.
dep_pkg = os.path.join(temp_dir, 'dep')
os.mkdir(dep_pkg)
'setup.cfg': '',
}, prefix=dep_pkg)
# "Install" dep.
- run_setup(os.path.join(dep_pkg, 'setup.py'), [str('dist_info')])
+ run_setup(
+ os.path.join(dep_pkg, 'setup.py'), [str('dist_info')])
working_set.add_entry(dep_pkg)
# Create source tree for test package.
test_pkg = os.path.join(temp_dir, 'test_pkg')
test_setup_py = os.path.join(test_pkg, 'setup.py')
- test_setup_cfg = os.path.join(test_pkg, 'setup.cfg')
os.mkdir(test_pkg)
with open(test_setup_py, 'w') as fp:
fp.write(DALS(
def make_python_requires_sdist(dist_path, distname, version, python_requires):
make_sdist(dist_path, [
- ('setup.py', DALS("""\
- import setuptools
- setuptools.setup(
- name={name!r},
- version={version!r},
- python_requires={python_requires!r},
- )
- """).format(name=distname, version=version,
- python_requires=python_requires)),
- ('setup.cfg', ''),
+ (
+ 'setup.py',
+ DALS("""\
+ import setuptools
+ setuptools.setup(
+ name={name!r},
+ version={version!r},
+ python_requires={python_requires!r},
+ )
+ """).format(
+ name=distname, version=version,
+ python_requires=python_requires)),
+ ('setup.cfg', ''),
])
value = ';'.join(value)
section.append('%s: %s' % (name, value))
test_setup_cfg_contents = DALS(
- """
- [metadata]
- {metadata}
- [options]
- {options}
- """
- ).format(
- options='\n'.join(options),
- metadata='\n'.join(metadata),
- )
+ """
+ [metadata]
+ {metadata}
+ [options]
+ {options}
+ """
+ ).format(
+ options='\n'.join(options),
+ metadata='\n'.join(metadata),
+ )
else:
test_setup_cfg_contents = ''
with open(os.path.join(test_pkg, 'setup.cfg'), 'w') as f:
license_file = LICENSE
"""),
'LICENSE': "Test license"
- }, True), # with license
+ }, True), # with license
({
'setup.cfg': DALS("""
[metadata]
license_file = INVALID_LICENSE
"""),
'LICENSE': "Test license"
- }, False), # with an invalid license
+ }, False), # with an invalid license
({
'setup.cfg': DALS("""
"""),
'LICENSE': "Test license"
- }, False), # no license_file attribute
+ }, False), # no license_file attribute
({
'setup.cfg': DALS("""
[metadata]
"""),
'MANIFEST.in': "exclude LICENSE",
'LICENSE': "Test license"
- }, False) # license file is manually excluded
+ }, False) # license file is manually excluded
])
def test_setup_cfg_license_file(
self, tmpdir_cwd, env, files, license_in_sources):
assert 'LICENSE' in sources_text
else:
assert 'LICENSE' not in sources_text
- assert 'INVALID_LICENSE' not in sources_text # for invalid license test
+ # for invalid license test
+ assert 'INVALID_LICENSE' not in sources_text
@pytest.mark.parametrize("files, incl_licenses, excl_licenses", [
({
"""),
'LICENSE-ABC': "ABC license",
'LICENSE-XYZ': "XYZ license"
- }, ['LICENSE-ABC', 'LICENSE-XYZ'], []), # with licenses
+ }, ['LICENSE-ABC', 'LICENSE-XYZ'], []), # with licenses
({
'setup.cfg': DALS("""
[metadata]
"""),
'LICENSE-ABC': "ABC license",
'LICENSE-XYZ': "XYZ license"
- }, ['LICENSE-ABC', 'LICENSE-XYZ'], []), # with commas
+ }, ['LICENSE-ABC', 'LICENSE-XYZ'], []), # with commas
({
'setup.cfg': DALS("""
[metadata]
"""),
'LICENSE-ABC': "ABC license",
'LICENSE-XYZ': "XYZ license"
- }, ['LICENSE-ABC'], ['LICENSE-XYZ']), # with one license
+ }, ['LICENSE-ABC'], ['LICENSE-XYZ']), # with one license
({
'setup.cfg': DALS("""
[metadata]
"""),
'LICENSE-ABC': "ABC license",
'LICENSE-XYZ': "XYZ license"
- }, [], ['LICENSE-ABC', 'LICENSE-XYZ']), # empty
+ }, [], ['LICENSE-ABC', 'LICENSE-XYZ']), # empty
({
'setup.cfg': DALS("""
[metadata]
"""),
'LICENSE-ABC': "ABC license",
'LICENSE-XYZ': "XYZ license"
- }, ['LICENSE-XYZ'], ['LICENSE-ABC']), # on same line
+ }, ['LICENSE-XYZ'], ['LICENSE-ABC']), # on same line
({
'setup.cfg': DALS("""
[metadata]
INVALID_LICENSE
"""),
'LICENSE-ABC': "Test license"
- }, ['LICENSE-ABC'], ['INVALID_LICENSE']), # with an invalid license
+ }, ['LICENSE-ABC'], ['INVALID_LICENSE']), # with an invalid license
({
'setup.cfg': DALS("""
"""),
'LICENSE': "Test license"
- }, [], ['LICENSE']), # no license_files attribute
+ }, [], ['LICENSE']), # no license_files attribute
({
'setup.cfg': DALS("""
[metadata]
"""),
'MANIFEST.in': "exclude LICENSE",
'LICENSE': "Test license"
- }, [], ['LICENSE']), # license file is manually excluded
+ }, [], ['LICENSE']), # license file is manually excluded
({
'setup.cfg': DALS("""
[metadata]
'MANIFEST.in': "exclude LICENSE-XYZ",
'LICENSE-ABC': "ABC license",
'LICENSE-XYZ': "XYZ license"
- }, ['LICENSE-ABC'], ['LICENSE-XYZ']) # subset is manually excluded
+ }, ['LICENSE-ABC'], ['LICENSE-XYZ']) # subset is manually excluded
])
def test_setup_cfg_license_files(
self, tmpdir_cwd, env, files, incl_licenses, excl_licenses):
"""),
'LICENSE-ABC': "ABC license",
'LICENSE-XYZ': "XYZ license"
- }, [], ['LICENSE-ABC', 'LICENSE-XYZ']), # both empty
+ }, [], ['LICENSE-ABC', 'LICENSE-XYZ']), # both empty
({
'setup.cfg': DALS("""
[metadata]
"""),
'LICENSE-ABC': "ABC license",
'LICENSE-XYZ': "XYZ license"
- }, [], ['LICENSE-ABC', 'LICENSE-XYZ']), # license_file is still singular
+ # license_file is still singular
+ }, [], ['LICENSE-ABC', 'LICENSE-XYZ']),
({
'setup.cfg': DALS("""
[metadata]
'LICENSE-ABC': "ABC license",
'LICENSE-PQR': "PQR license",
'LICENSE-XYZ': "XYZ license"
- }, ['LICENSE-ABC', 'LICENSE-PQR', 'LICENSE-XYZ'], []), # combined
+ }, ['LICENSE-ABC', 'LICENSE-PQR', 'LICENSE-XYZ'], []), # combined
({
'setup.cfg': DALS("""
[metadata]
'LICENSE-ABC': "ABC license",
'LICENSE-PQR': "PQR license",
'LICENSE-XYZ': "XYZ license"
- }, ['LICENSE-ABC', 'LICENSE-PQR', 'LICENSE-XYZ'], []), # duplicate license
+ # duplicate license
+ }, ['LICENSE-ABC', 'LICENSE-PQR', 'LICENSE-XYZ'], []),
({
'setup.cfg': DALS("""
[metadata]
'LICENSE-ABC': "ABC license",
'LICENSE-PQR': "PQR license",
'LICENSE-XYZ': "XYZ license"
- }, ['LICENSE-ABC', 'LICENSE-XYZ'], ['LICENSE-PQR']), # combined subset
+ # combined subset
+ }, ['LICENSE-ABC', 'LICENSE-XYZ'], ['LICENSE-PQR']),
({
'setup.cfg': DALS("""
[metadata]
LICENSE-PQR
"""),
'LICENSE-PQR': "Test license"
- }, ['LICENSE-PQR'], ['LICENSE-ABC', 'LICENSE-XYZ']), # with invalid licenses
+ # with invalid licenses
+ }, ['LICENSE-PQR'], ['LICENSE-ABC', 'LICENSE-XYZ']),
({
'setup.cfg': DALS("""
[metadata]
'LICENSE-ABC': "ABC license",
'LICENSE-PQR': "PQR license",
'LICENSE-XYZ': "XYZ license"
- }, ['LICENSE-XYZ'], ['LICENSE-ABC', 'LICENSE-PQR']) # manually excluded
+ # manually excluded
+ }, ['LICENSE-XYZ'], ['LICENSE-ABC', 'LICENSE-PQR'])
])
def test_setup_cfg_license_file_license_files(
self, tmpdir_cwd, env, files, incl_licenses, excl_licenses):
assert not req.is_present()
assert not req.is_current()
+ @needs_bytecode
+ def test_require_present(self):
+ # In #1896, this test was failing for months with the only
+ # complaint coming from test runners (not end users).
+ # TODO: Evaluate if this code is needed at all.
req = Require('Tests', None, 'tests', homepage="http://example.com")
assert req.format is None
assert req.attribute is None
py_modules=['bar_et'], remove=['bar.ext'],
),
'baz': Feature(
- "baz", optional=False, packages=['pkg.baz'],
- scripts=['scripts/baz_it'],
- libraries=[('libfoo', 'foo/foofoo.c')]
- ),
+ "baz", optional=False, packages=['pkg.baz'],
+ scripts=['scripts/baz_it'],
+ libraries=[('libfoo', 'foo/foofoo.c')]
+ ),
'dwim': Feature("DWIM", available=False, remove='bazish'),
},
script_args=['--without-bar', 'install'],
from setuptools.dist import Distribution
from .textwrap import DALS
-from . import contexts
+
SETUP_PY = DALS("""
from setuptools import setup
import pytest_virtualenv
-from setuptools.extern import six
-
from .textwrap import DALS
from .test_easy_install import make_nspkg_sdist
+@pytest.fixture(autouse=True)
+def disable_requires_python(monkeypatch):
+ """
+ Disable Requires-Python on Python 2.7
+ """
+ if sys.version_info > (3,):
+ return
+
+ monkeypatch.setenv('PIP_IGNORE_REQUIRES_PYTHON', 'true')
+
+
@pytest.fixture(autouse=True)
def pytest_virtualenv_works(virtualenv):
"""
from urllib.request import urlopen
from urllib.error import URLError
except ImportError:
- from urllib2 import urlopen, URLError # Python 2.7 compat
+ from urllib2 import urlopen, URLError # Python 2.7 compat
try:
urlopen('https://pypi.org', timeout=1)
)).format(tmpdir=tmpdir))
assert tmpdir.join('success').check()
+
def test_test_command_install_requirements(virtualenv, tmpdir):
# Ensure pip/wheel packages are installed.
- virtualenv.run("python -c \"__import__('pkg_resources').require(['pip', 'wheel'])\"")
+ virtualenv.run(
+ "python -c \"__import__('pkg_resources').require(['pip', 'wheel'])\"")
_check_test_command_install_requirements(virtualenv, tmpdir)
-def test_test_command_install_requirements_when_using_easy_install(bare_virtualenv, tmpdir):
+
+def test_test_command_install_requirements_when_using_easy_install(
+ bare_virtualenv, tmpdir):
_check_test_command_install_requirements(bare_virtualenv, tmpdir)
def format_install_tree(tree):
- return {x.format(
- py_version=PY_MAJOR,
- platform=get_platform(),
- shlib_ext=get_config_var('EXT_SUFFIX') or get_config_var('SO'))
- for x in tree}
+ return {
+ x.format(
+ py_version=PY_MAJOR,
+ platform=get_platform(),
+ shlib_ext=get_config_var('EXT_SUFFIX') or get_config_var('SO'))
+ for x in tree}
def _check_wheel_install(filename, install_dir, install_tree_includes,
id='empty_namespace_package',
file_defs={
'foobar': {
- '__init__.py': "__import__('pkg_resources').declare_namespace(__name__)",
+ '__init__.py':
+ "__import__('pkg_resources').declare_namespace(__name__)",
},
},
setup_kwargs=dict(
for t in parse_tag('cp36-cp36m-manylinux1_x86_64'):
yield t
monkeypatch.setattr('setuptools.wheel.sys_tags', sys_tags)
- assert Wheel('onnxruntime-0.1.2-cp36-cp36m-manylinux1_x86_64.whl').is_compatible()
+ assert Wheel(
+ 'onnxruntime-0.1.2-cp36-cp36m-manylinux1_x86_64.whl').is_compatible()
def is_compatible(self):
'''Is the wheel is compatible with the current platform?'''
- supported_tags = set((t.interpreter, t.abi, t.platform) for t in sys_tags())
+ supported_tags = set(
+ (t.interpreter, t.abi, t.platform) for t in sys_tags())
return next((True for t in self.tags() if t in supported_tags), False)
def egg_name(self):
+++ /dev/null
-mock
-pytest-flake8
-virtualenv>=13.0.0
-pytest-virtualenv>=1.2.7
-pytest>=3.7
-wheel
-coverage>=4.5.1
-pytest-cov>=2.5.1
-paver; python_version>="3.6"
-futures; python_version=="2.7"
-pip>=19.1 # For proper file:// URLs support.
import os
import subprocess
import sys
+import re
def remove_setuptools():
subprocess.check_call(cmd, cwd='.tox')
-def pip(args):
- # Honor requires-python when installing test suite dependencies
- if any('-r' in arg for arg in args):
- os.environ['PIP_IGNORE_REQUIRES_PYTHON'] = '0'
+def bootstrap():
+ print("Running bootstrap")
+ cmd = [sys.executable, '-m', 'bootstrap']
+ subprocess.check_call(cmd)
- # When installing '.', remove setuptools
- '.' in args and remove_setuptools()
- cmd = [sys.executable, '-m', 'pip'] + args
- subprocess.check_call(cmd)
+def is_install_self(args):
+ """
+ Do the args represent an install of .?
+ """
+ def strip_extras(arg):
+ match = re.match(r'(.*)?\[.*\]$', arg)
+ return match.group(1) if match else arg
+
+ return (
+ 'install' in args
+ and any(
+ arg in ['.', os.getcwd()]
+ for arg in map(strip_extras, args)
+ )
+ )
+
+
+def pip(*args):
+ cmd = [sys.executable, '-m', 'pip'] + list(args)
+ return subprocess.check_call(cmd)
+
+
+def test_dependencies():
+ from ConfigParser import ConfigParser
+
+ def clean(dep):
+ spec, _, _ = dep.partition('#')
+ return spec.strip()
+
+ parser = ConfigParser()
+ parser.read('setup.cfg')
+ raw = parser.get('options.extras_require', 'tests').split('\n')
+ return filter(None, map(clean, raw))
+
+
+def disable_python_requires():
+ """
+ On Python 2, install the dependencies that are selective
+ on Python version while honoring REQUIRES_PYTHON, then
+ disable REQUIRES_PYTHON so that pip can install this
+ checkout of setuptools.
+ """
+ pip('install', *test_dependencies())
+ os.environ['PIP_IGNORE_REQUIRES_PYTHON'] = 'true'
+
+
+def run(args):
+ os.environ['PIP_USE_PEP517'] = 'true'
+
+ if is_install_self(args):
+ remove_setuptools()
+ bootstrap()
+ sys.version_info > (3,) or disable_python_requires()
+
+ pip(*args)
if __name__ == '__main__':
- pip(sys.argv[1:])
+ run(sys.argv[1:])
-# Note: Run "python bootstrap.py" before running Tox, to generate metadata.
-#
# To run Tox against all supported Python interpreters, you can set:
#
-# export TOXENV='py27,py3{5,6,7,8},pypy,pypy3'
+# export TOXENV='py3{5,6,7,8},pypy,pypy3'
[tox]
envlist=python
pip = python {toxinidir}/tools/tox_pip.py
[testenv]
-deps=-r{toxinidir}/tests/requirements.txt
pip_version = pip
install_command = {[helpers]pip} install {opts} {packages}
list_dependencies_command = {[helpers]pip} freeze --all
setenv =
COVERAGE_FILE={toxworkdir}/.coverage.{envname}
- py27: PIP_IGNORE_REQUIRES_PYTHON=true
# TODO: The passed environment variables came from copying other tox.ini files
# These should probably be individually annotated to explain what needs them.
passenv=APPDATA HOMEDRIVE HOMEPATH windir APPVEYOR APPVEYOR_* CI CODECOV_* TRAVIS TRAVIS_* NETWORK_REQUIRED
commands=pytest --cov-config={toxinidir}/tox.ini --cov-report= {posargs}
usedevelop=True
+extras =
+ tests
[testenv:coverage]
commands=codecov -X gcov --file {toxworkdir}/coverage.xml
[testenv:docs]
-deps = -r{toxinidir}/docs/requirements.txt
-skip_install=True
+extras =
+ docs
+ testing
+changedir = docs
commands =
- python {toxinidir}/bootstrap.py
- sphinx-build -W -b html -d {envtmpdir}/doctrees docs docs/build/html
- sphinx-build -W -b man -d {envtmpdir}/doctrees docs docs/build/man
+ python -m sphinx . {toxinidir}/build/html
[coverage:run]
source=