Imported Upstream version 39.1.0 upstream/39.1.0
authorDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 14 Jan 2019 01:42:12 +0000 (10:42 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 14 Jan 2019 01:42:12 +0000 (10:42 +0900)
22 files changed:
.codecov.yml [new file with mode: 0644]
.gitignore
.travis.yml
CHANGES.rst
appveyor.yml
docs/_templates/indexsidebar.html
docs/easy_install.txt
docs/python3.txt
docs/setuptools.txt
pkg_resources/__init__.py
setup.cfg
setup.py
setuptools/command/easy_install.py
setuptools/dist.py
setuptools/monkey.py
setuptools/package_index.py
setuptools/pep425tags.py
setuptools/tests/test_egg_info.py
setuptools/tests/test_packageindex.py
setuptools/tests/test_wheel.py
tests/requirements.txt
tox.ini

diff --git a/.codecov.yml b/.codecov.yml
new file mode 100644 (file)
index 0000000..69cb760
--- /dev/null
@@ -0,0 +1 @@
+comment: false
index 2e2f71b8f2815375cae233165f051fc917281a23..f5661164f75421fb2d43a4db35af25a954e67c33 100644 (file)
@@ -15,3 +15,4 @@ setuptools.egg-info
 *~
 .hg*
 .cache
+.pytest_cache/
index ffbd72a3d4d4fd1ef533d61f29b93f43ffb4f4ef..ced8fa6bcc7d2c4979bedde6ed70b5425d0ff03f 100644 (file)
@@ -23,6 +23,7 @@ jobs:
     python: *latest_py3
     install: skip
     script: skip
+    after_success: true
     before_deploy: python bootstrap.py
     deploy:
       provider: pypi
@@ -48,4 +49,31 @@ install:
 # update egg_info based on setup.py in checkout
 - python bootstrap.py
 
-script: tox
+script:
+  - |
+    ( # Run testsuite.
+      set -ex
+      case $TRAVIS_PYTHON_VERSION in
+      pypy*)
+        # Don't run coverage on pypy (too slow).
+        tox
+        ;;
+      *)
+        tox -- --cov
+        ;;
+      esac
+    )
+
+after_success:
+  - |
+    ( # Upload coverage data.
+      set -ex
+      case $TRAVIS_PYTHON_VERSION in
+      pypy*)
+        ;;
+        *)
+        export TRAVIS_JOB_NAME="${TRAVIS_PYTHON_VERSION} (LANG=$LANG)" CODECOV_ENV=TRAVIS_JOB_NAME
+        tox -e coverage,codecov
+        ;;
+      esac
+    )
index 05de76e50a57f838655fa42a194366fc27480060..d8b5b49147ad67db4a2eaf8901d4e2065ac68478 100644 (file)
@@ -1,3 +1,12 @@
+v39.1.0
+-------
+
+* #1340: Update all PyPI URLs to reflect the switch to the
+  new Warehouse codebase.
+* #1337: In ``pkg_resources``, now support loading resources
+  for modules loaded by the ``SourcelessFileLoader``.
+* #1332: Silence spurious wheel related warnings on Windows.
+
 v39.0.1
 -------
 
@@ -1802,7 +1811,7 @@ process to fail and PyPI uploads no longer accept files for 13.0.
 * Issue #313: Removed built-in support for subversion. Projects wishing to
   retain support for subversion will need to use a third party library. The
   extant implementation is being ported to `setuptools_svn
-  <https://pypi.python.org/pypi/setuptools_svn>`_.
+  <https://pypi.org/project/setuptools_svn/>`_.
 * Issue #315: Updated setuptools to hide its own loaded modules during
   installation of another package. This change will enable setuptools to
   upgrade (or downgrade) itself even when its own metadata and implementation
@@ -2307,7 +2316,7 @@ process to fail and PyPI uploads no longer accept files for 13.0.
 * Address security vulnerability in SSL match_hostname check as reported in
   Python #17997.
 * Prefer `backports.ssl_match_hostname
-  <https://pypi.python.org/pypi/backports.ssl_match_hostname>`_ for backport
+  <https://pypi.org/project/backports.ssl_match_hostname/>`_ for backport
   implementation if present.
 * Correct NameError in ``ssl_support`` module (``socket.error``).
 
index 7c61455ce636ffdb079f0c647c02046f0d248d58..ff7122b41fb17d4938b402c1e27617cea95f444a 100644 (file)
@@ -1,10 +1,13 @@
 environment:
 
-  APPVEYOR: true
+  APPVEYOR: True
+  CODECOV_ENV: APPVEYOR_JOB_NAME
 
   matrix:
-    - PYTHON: "C:\\Python35-x64"
-    - PYTHON: "C:\\Python27-x64"
+    - APPVEYOR_JOB_NAME: "python35-x64"
+      PYTHON: "C:\\Python35-x64"
+    - APPVEYOR_JOB_NAME: "python27-x64"
+      PYTHON: "C:\\Python27-x64"
 
 install:
   # symlink python from a directory with a space
@@ -20,6 +23,9 @@ cache:
 test_script:
   - "python bootstrap.py"
   - "python -m pip install tox"
-  - "tox"
+  - "tox -- --cov"
+
+after_test:
+    - tox -e coverage,codecov
 
 version: '{build}'
index 3b127602eceec77e341c325d496881e60484c570..80002d08711741ac3a87dd86dc0c92c3d5b34157 100644 (file)
@@ -1,7 +1,7 @@
 <h3>Download</h3>
 
 <p>Current version: <b>{{ version }}</b></p>
-<p>Get Setuptools from the <a href="https://pypi.python.org/pypi/setuptools"> Python Package Index</a>
+<p>Get Setuptools from the <a href="https://pypi.org/project/setuptools/"> Python Package Index</a>
 
 <h3>Questions? Suggestions? Contributions?</h3>
 
index 56b16672264c661a604dd83984de0c5180a5d15c..5c992343611386b10c1335c73d93cf32c515d4b1 100644 (file)
@@ -31,7 +31,7 @@ Using "Easy Install"
 Installing "Easy Install"
 -------------------------
 
-Please see the `setuptools PyPI page <https://pypi.python.org/pypi/setuptools>`_
+Please see the `setuptools PyPI page <https://pypi.org/project/setuptools/>`_
 for download links and basic installation instructions for each of the
 supported platforms.
 
@@ -831,7 +831,7 @@ Command-Line Options
 
 ``--index-url=URL, -i URL`` (New in 0.4a1; default changed in 0.6c7)
     Specifies the base URL of the Python Package Index.  The default is
-    https://pypi.python.org/simple if not specified.  When a package is requested
+    https://pypi.org/simple/ if not specified.  When a package is requested
     that is not locally available or linked from a ``--find-links`` download
     page, the package index will be searched for download pages for the needed
     package, and those download pages will be searched for links to download
@@ -1019,7 +1019,7 @@ that the User installation scheme alone does not provide, e.g. the ability to hi
 
 Please refer to the `virtualenv`_ documentation for more details.
 
-.. _virtualenv: https://pypi.python.org/pypi/virtualenv
+.. _virtualenv: https://pypi.org/project/virtualenv/
 
 
 
@@ -1620,4 +1620,3 @@ Future Plans
 * Signature checking?  SSL?  Ability to suppress PyPI search?
 * Display byte progress meter when downloading distributions and long pages?
 * Redirect stdout/stderr to log during run_setup?
-
index d550cb68c12e86439b97b68fe88b599e1dcba04a..c528fc3ced84e376618a4efd701211b67e583902 100644 (file)
@@ -10,8 +10,8 @@ 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 strongly recommends instead developing a unified codebase
-using `six <https://pypi.python.org/pypi/six>`_,
-`future <https://pypi.python.org/pypi/future>`_, or another compatibility
+using `six <https://pypi.org/project/six/>`_,
+`future <https://pypi.org/project/future/>`_, or another compatibility
 library.
 
 
index 65080a0b21393e81695004761ea75760f31f5ab8..e14d208881ddb8c3eb053d50a605d3cb60e2166a 100644 (file)
@@ -2277,7 +2277,7 @@ The ``upload`` command is implemented and `documented
 in distutils.
 
 Setuptools augments the ``upload`` command with support
-for `keyring <https://pypi.python.org/pypi/keyring>`_,
+for `keyring <https://pypi.org/project/keyring/>`_,
 allowing the password to be stored in a secure
 location and not in plaintext in the .pypirc file. To use
 keyring, first install keyring and set the password for
@@ -2671,8 +2671,8 @@ Adding Support for Revision Control Systems
 If the files you want to include in the source distribution are tracked using
 Git, Mercurial or SVN, you can use the following packages to achieve that:
 
-- Git and Mercurial: `setuptools_scm <https://pypi.python.org/pypi/setuptools_scm>`_
-- SVN: `setuptools_svn <https://pypi.python.org/pypi/setuptools_svn>`_
+- Git and Mercurial: `setuptools_scm <https://pypi.org/project/setuptools_scm/>`_
+- SVN: `setuptools_svn <https://pypi.org/project/setuptools_svn/>`_
 
 If you would like to create a plugin for ``setuptools`` to find files tracked
 by another revision control system, you can do so by adding an entry point to
index 8d95bd2912044ea80486f385d634376a244a0562..d5b0fe9828107129709e19f303d2a7ad4c725669 100644 (file)
@@ -1518,12 +1518,10 @@ class DefaultProvider(EggProvider):
 
     @classmethod
     def _register(cls):
-        loader_cls = getattr(
-            importlib_machinery,
-            'SourceFileLoader',
-            type(None),
-        )
-        register_loader_type(loader_cls, cls)
+        loader_names = 'SourceFileLoader', 'SourcelessFileLoader',
+        for name in loader_names:
+            loader_cls = getattr(importlib_machinery, name, type(None))
+            register_loader_type(loader_cls, cls)
 
 
 DefaultProvider._register()
index daec5c99f3c74283b95be21af24f40acff54867e..2c84f0b7631c3c60a0654ba2eb091281a04087d8 100755 (executable)
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 39.0.1
+current_version = 39.1.0
 commit = True
 tag = True
 
index 9ac05104d4348e6d2bc9e192a3ccde24c12aa46f..b08552d4376ae5737504fc5260afedf4ab9d6e04 100755 (executable)
--- a/setup.py
+++ b/setup.py
@@ -89,7 +89,7 @@ def pypi_link(pkg_filename):
 
 setup_params = dict(
     name="setuptools",
-    version="39.0.1",
+    version="39.1.0",
     description=(
         "Easily download, build, install, upgrade, and uninstall "
         "Python packages"
index a6f61436b73c744d05c40d68928afc067acc8ee5..85ee40f1d5cfbcdc7faeeffdea0ab6db76aee6fe 100755 (executable)
@@ -319,7 +319,7 @@ class easy_install(Command):
                     self.all_site_dirs.append(normalize_path(d))
         if not self.editable:
             self.check_site_dir()
-        self.index_url = self.index_url or "https://pypi.python.org/simple"
+        self.index_url = self.index_url or "https://pypi.org/simple/"
         self.shadow_path = self.all_site_dirs[:]
         for path_item in self.install_dir, normalize_path(self.script_dir):
             if path_item not in self.shadow_path:
index 284d922df528cb4daee397d912639c98420cdc56..321ab6b7d761e151e5148524766c15f52e381342 100644 (file)
@@ -123,15 +123,6 @@ def write_pkg_file(self, file):
             file.write('Provides-Extra: %s\n' % extra)
 
 
-# from Python 3.4
-def write_pkg_info(self, base_dir):
-    """Write the PKG-INFO file into the release tree.
-    """
-    with open(os.path.join(base_dir, 'PKG-INFO'), 'w',
-              encoding='UTF-8') as pkg_info:
-        self.write_pkg_file(pkg_info)
-
-
 sequence = tuple, list
 
 
index d9eb7d7b2946519137ec27ebf5dbf9e14ada6f81..08ed50d9ecd06de0136bad14a45e08624ba77f01 100644 (file)
@@ -87,7 +87,6 @@ def patch_all():
         distutils.config.PyPIRCCommand.DEFAULT_REPOSITORY = warehouse
 
     _patch_distribution_metadata_write_pkg_file()
-    _patch_distribution_metadata_write_pkg_info()
 
     # Install Distribution throughout the distutils
     for module in distutils.dist, distutils.core, distutils.cmd:
@@ -111,21 +110,6 @@ def _patch_distribution_metadata_write_pkg_file():
     )
 
 
-def _patch_distribution_metadata_write_pkg_info():
-    """
-    Workaround issue #197 - Python 3 prior to 3.2.2 uses an environment-local
-    encoding to save the pkg_info. Monkey-patch its write_pkg_info method to
-    correct this undesirable behavior.
-    """
-    environment_local = (3,) <= sys.version_info[:3] < (3, 2, 2)
-    if not environment_local:
-        return
-
-    distutils.dist.DistributionMetadata.write_pkg_info = (
-        setuptools.dist.write_pkg_info
-    )
-
-
 def patch_func(replacement, target_mod, func_name):
     """
     Patch func_name in target_mod with replacement
index 914b5e6159e7f6be0c1721299d5bcffd0f487c9b..b6407be304f9d18b562b30d5bf43d13b6127a68f 100755 (executable)
@@ -297,7 +297,7 @@ class PackageIndex(Environment):
     """A distribution index that scans web pages for download URLs"""
 
     def __init__(
-            self, index_url="https://pypi.python.org/simple", hosts=('*',),
+            self, index_url="https://pypi.org/simple/", hosts=('*',),
             ca_bundle=None, verify_ssl=True, *args, **kw
     ):
         Environment.__init__(self, *args, **kw)
index dfe55d587a870dda328796e2a72815763326e26c..3bdd3285a5b4bd0ba32a2b09bf9d6b54ad784168 100644 (file)
@@ -4,6 +4,7 @@
 from __future__ import absolute_import
 
 import distutils.util
+from distutils import log
 import platform
 import re
 import sys
@@ -69,8 +70,8 @@ def get_flag(var, fallback, expected=True, warn=True):
     val = get_config_var(var)
     if val is None:
         if warn:
-            warnings.warn("Config variable '{0}' is unset, Python ABI tag may "
-                          "be incorrect".format(var), RuntimeWarning, 2)
+            log.debug("Config variable '%s' is unset, Python ABI tag may "
+                      "be incorrect", var)
         return fallback()
     return val == expected
 
index d221167152e483cd0ebecb21070760d8487ff7b1..2a070debe0b93e3e1c0cc53e21f1b0ae69fa7963 100644 (file)
@@ -244,6 +244,18 @@ class TestEggInfo(object):
         pytz
         ''',
 
+        '''
+        install_requires_ordered
+
+        install_requires=["fake-factory>=1.12.3,!=2.0"]
+
+        [options]
+        install_requires =
+            fake-factory>=1.12.3,!=2.0
+
+        fake-factory!=2.0,>=1.12.3
+        ''',
+
         '''
         install_requires_with_marker
 
index 53e20d44c8863e317eda2b4884e09963ad5bcf35..63b9294610551446a58812a868a1b025c5f9471c 100644 (file)
@@ -265,11 +265,11 @@ class TestPyPIConfig:
         with pypirc.open('w') as strm:
             strm.write(DALS("""
                 [pypi]
-                repository=https://pypi.python.org
+                repository=https://pypi.org
                 username=jaraco
                 password=pity%
             """))
         cfg = setuptools.package_index.PyPIConfig()
-        cred = cfg.creds_by_repository['https://pypi.python.org']
+        cred = cfg.creds_by_repository['https://pypi.org']
         assert cred.username == 'jaraco'
         assert cred.password == 'pity%'
index b6be6f1f05a8fd55ce8e627ba841e4e86c84ee95..150ac4c1b5e6434284fb98394a3e72b7f180e30c 100644 (file)
@@ -92,39 +92,49 @@ def build_wheel(extra_file_defs=None, **kwargs):
         yield glob.glob(os.path.join(source_dir, 'dist', '*.whl'))[0]
 
 
-def tree(root):
-    def depth(path):
-        return len(path.split(os.path.sep))
-    def prefix(path_depth):
-        if not path_depth:
-            return ''
-        return '|  ' * (path_depth - 1) + '|-- '
-    lines = []
-    root_depth = depth(root)
+def tree_set(root):
+    contents = set()
     for dirpath, dirnames, filenames in os.walk(root):
-        dirnames.sort()
-        filenames.sort()
-        dir_depth = depth(dirpath) - root_depth
-        if dir_depth > 0:
-            lines.append('%s%s/' % (prefix(dir_depth - 1),
-                                    os.path.basename(dirpath)))
-        for f in filenames:
-            lines.append('%s%s' % (prefix(dir_depth), f))
-    return '\n'.join(lines) + '\n'
-
-
-def _check_wheel_install(filename, install_dir, install_tree,
+        for filename in filenames:
+            contents.add(os.path.join(os.path.relpath(dirpath, root),
+                                      filename))
+    return contents
+
+
+def flatten_tree(tree):
+    """Flatten nested dicts and lists into a full list of paths"""
+    output = set()
+    for node, contents in tree.items():
+        if isinstance(contents, dict):
+            contents = flatten_tree(contents)
+
+        for elem in contents:
+            if isinstance(elem, dict):
+                output |= {os.path.join(node, val)
+                           for val in flatten_tree(elem)}
+            else:
+                output.add(os.path.join(node, elem))
+    return output
+
+
+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}
+
+
+def _check_wheel_install(filename, install_dir, install_tree_includes,
                          project_name, version, requires_txt):
     w = Wheel(filename)
     egg_path = os.path.join(install_dir, w.egg_name())
     w.install_as_egg(egg_path)
-    if install_tree is not None:
-        install_tree = install_tree.format(
-            py_version=PY_MAJOR,
-            platform=get_platform(),
-            shlib_ext=get_config_var('EXT_SUFFIX') or get_config_var('SO')
-        )
-        assert install_tree == tree(install_dir)
+    if install_tree_includes is not None:
+        install_tree = format_install_tree(install_tree_includes)
+        exp = tree_set(install_dir)
+        assert install_tree.issubset(exp), (install_tree - exp)
+
     metadata = PathMetadata(egg_path, os.path.join(egg_path, 'EGG-INFO'))
     dist = Distribution.from_filename(egg_path, metadata=metadata)
     assert dist.project_name == project_name
@@ -157,20 +167,17 @@ WHEEL_INSTALL_TESTS = (
         setup_kwargs=dict(
             packages=['foo'],
         ),
-        install_tree=DALS(
-            '''
-            foo-1.0-py{py_version}.egg/
-            |-- EGG-INFO/
-            |  |-- DESCRIPTION.rst
-            |  |-- PKG-INFO
-            |  |-- RECORD
-            |  |-- WHEEL
-            |  |-- metadata.json
-            |  |-- top_level.txt
-            |-- foo/
-            |  |-- __init__.py
-            '''
-        ),
+        install_tree=flatten_tree({
+            'foo-1.0-py{py_version}.egg': {
+                'EGG-INFO': [
+                    'PKG-INFO',
+                    'RECORD',
+                    'WHEEL',
+                    'top_level.txt'
+                ],
+                'foo': ['__init__.py']
+            }
+        }),
     ),
 
     dict(
@@ -192,20 +199,19 @@ WHEEL_INSTALL_TESTS = (
         setup_kwargs=dict(
             data_files=[('data_dir', ['data.txt'])],
         ),
-        install_tree=DALS(
-            '''
-            foo-1.0-py{py_version}.egg/
-            |-- EGG-INFO/
-            |  |-- DESCRIPTION.rst
-            |  |-- PKG-INFO
-            |  |-- RECORD
-            |  |-- WHEEL
-            |  |-- metadata.json
-            |  |-- top_level.txt
-            |-- data_dir/
-            |  |-- data.txt
-            '''
-        ),
+        install_tree=flatten_tree({
+            'foo-1.0-py{py_version}.egg': {
+                'EGG-INFO': [
+                    'PKG-INFO',
+                    'RECORD',
+                    'WHEEL',
+                    'top_level.txt'
+                ],
+                'data_dir': [
+                    'data.txt'
+                ]
+            }
+        }),
     ),
 
     dict(
@@ -262,19 +268,17 @@ WHEEL_INSTALL_TESTS = (
                        sources=['extension.c'])
             ],
         ),
-        install_tree=DALS(
-            '''
-            foo-1.0-py{py_version}-{platform}.egg/
-            |-- extension{shlib_ext}
-            |-- EGG-INFO/
-            |  |-- DESCRIPTION.rst
-            |  |-- PKG-INFO
-            |  |-- RECORD
-            |  |-- WHEEL
-            |  |-- metadata.json
-            |  |-- top_level.txt
-            '''
-        ),
+        install_tree=flatten_tree({
+            'foo-1.0-py{py_version}-{platform}.egg': [
+                'extension{shlib_ext}',
+                {'EGG-INFO': [
+                    'PKG-INFO',
+                    'RECORD',
+                    'WHEEL',
+                    'top_level.txt',
+                ]},
+            ]
+        }),
     ),
 
     dict(
@@ -288,19 +292,17 @@ WHEEL_INSTALL_TESTS = (
         setup_kwargs=dict(
             headers=['header.h'],
         ),
-        install_tree=DALS(
-            '''
-            foo-1.0-py{py_version}.egg/
-            |-- header.h
-            |-- EGG-INFO/
-            |  |-- DESCRIPTION.rst
-            |  |-- PKG-INFO
-            |  |-- RECORD
-            |  |-- WHEEL
-            |  |-- metadata.json
-            |  |-- top_level.txt
-            '''
-        ),
+        install_tree=flatten_tree({
+            'foo-1.0-py{py_version}.egg': [
+                'header.h',
+                {'EGG-INFO': [
+                    'PKG-INFO',
+                    'RECORD',
+                    'WHEEL',
+                    'top_level.txt',
+                ]},
+            ]
+        }),
     ),
 
     dict(
@@ -322,38 +324,37 @@ WHEEL_INSTALL_TESTS = (
         setup_kwargs=dict(
             scripts=['script.py', 'script.sh'],
         ),
-        install_tree=DALS(
-            '''
-            foo-1.0-py{py_version}.egg/
-            |-- EGG-INFO/
-            |  |-- DESCRIPTION.rst
-            |  |-- PKG-INFO
-            |  |-- RECORD
-            |  |-- WHEEL
-            |  |-- metadata.json
-            |  |-- top_level.txt
-            |  |-- scripts/
-            |  |  |-- script.py
-            |  |  |-- script.sh
-            '''
-        ),
+        install_tree=flatten_tree({
+            'foo-1.0-py{py_version}.egg': {
+                'EGG-INFO': [
+                    'PKG-INFO',
+                    'RECORD',
+                    'WHEEL',
+                    'top_level.txt',
+                    {'scripts': [
+                        'script.py',
+                        'script.sh'
+                    ]}
+
+                ]
+            }
+        })
     ),
 
     dict(
         id='requires1',
         install_requires='foobar==2.0',
-        install_tree=DALS(
-            '''
-            foo-1.0-py{py_version}.egg/
-            |-- EGG-INFO/
-            |  |-- DESCRIPTION.rst
-            |  |-- PKG-INFO
-            |  |-- RECORD
-            |  |-- WHEEL
-            |  |-- metadata.json
-            |  |-- requires.txt
-            |  |-- top_level.txt
-            '''),
+        install_tree=flatten_tree({
+            'foo-1.0-py{py_version}.egg': {
+                'EGG-INFO': [
+                    'PKG-INFO',
+                    'RECORD',
+                    'WHEEL',
+                    'requires.txt',
+                    'top_level.txt',
+                ]
+            }
+        }),
         requires_txt=DALS(
             '''
             foobar==2.0
@@ -425,23 +426,22 @@ WHEEL_INSTALL_TESTS = (
             namespace_packages=['foo'],
             packages=['foo.bar'],
         ),
-        install_tree=DALS(
-            '''
-            foo-1.0-py{py_version}.egg/
-            |-- foo-1.0-py{py_version}-nspkg.pth
-            |-- EGG-INFO/
-            |  |-- DESCRIPTION.rst
-            |  |-- PKG-INFO
-            |  |-- RECORD
-            |  |-- WHEEL
-            |  |-- metadata.json
-            |  |-- namespace_packages.txt
-            |  |-- top_level.txt
-            |-- foo/
-            |  |-- __init__.py
-            |  |-- bar/
-            |  |  |-- __init__.py
-            '''),
+        install_tree=flatten_tree({
+            'foo-1.0-py{py_version}.egg': [
+                'foo-1.0-py{py_version}-nspkg.pth',
+                {'EGG-INFO': [
+                    'PKG-INFO',
+                    'RECORD',
+                    'WHEEL',
+                    'namespace_packages.txt',
+                    'top_level.txt',
+                ]},
+                {'foo': [
+                    '__init__.py',
+                    {'bar': ['__init__.py']},
+                ]},
+            ]
+        }),
     ),
 
     dict(
@@ -462,22 +462,22 @@ WHEEL_INSTALL_TESTS = (
             packages=['foo'],
             data_files=[('foo/data_dir', ['foo/data_dir/data.txt'])],
         ),
-        install_tree=DALS(
-            '''
-            foo-1.0-py{py_version}.egg/
-            |-- EGG-INFO/
-            |  |-- DESCRIPTION.rst
-            |  |-- PKG-INFO
-            |  |-- RECORD
-            |  |-- WHEEL
-            |  |-- metadata.json
-            |  |-- top_level.txt
-            |-- foo/
-            |  |-- __init__.py
-            |  |-- data_dir/
-            |  |  |-- data.txt
-            '''
-        ),
+        install_tree=flatten_tree({
+            'foo-1.0-py{py_version}.egg': {
+                'EGG-INFO': [
+                    'PKG-INFO',
+                    'RECORD',
+                    'WHEEL',
+                    'top_level.txt',
+                ],
+                'foo': [
+                    '__init__.py',
+                    {'data_dir': [
+                        'data.txt',
+                    ]}
+                ]
+            }
+        }),
     ),
 
 )
index 38b692471208811a00adf7f47d4df700af727520..fd826d0974bf084d7d2e8d48d01ad34d8b8ea968 100644 (file)
@@ -5,3 +5,5 @@ virtualenv>=13.0.0
 pytest-virtualenv>=1.2.7
 pytest>=3.0.2
 wheel
+coverage>=4.5.1
+pytest-cov>=2.5.1
diff --git a/tox.ini b/tox.ini
index 2f7d4dc81851fa7754b9dfe7cb752622c2c4fb45..a0c4cdf3000f4d10835aa11d4057112ff4551308 100644 (file)
--- a/tox.ini
+++ b/tox.ini
@@ -4,8 +4,38 @@
 #
 # export TOXENV='py27,py3{3,4,5,6},pypy,pypy3'
 
+[tox]
+envlist=python
+
 [testenv]
 deps=-rtests/requirements.txt
-passenv=APPDATA USERPROFILE HOMEDRIVE HOMEPATH windir APPVEYOR
-commands=py.test {posargs}
+setenv=COVERAGE_FILE={toxworkdir}/.coverage.{envname}
+# 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_*
+commands=pytest --cov-config={toxinidir}/tox.ini --cov-report= {posargs}
 usedevelop=True
+
+
+[testenv:coverage]
+description=Combine coverage data and create report
+deps=coverage
+skip_install=True
+changedir={toxworkdir}
+setenv=COVERAGE_FILE=.coverage
+commands=coverage erase
+         coverage combine
+         coverage {posargs:xml}
+
+[testenv:codecov]
+description=[Only run on CI]: Upload coverage data to codecov
+deps=codecov
+skip_install=True
+commands=codecov --file {toxworkdir}/coverage.xml
+
+[coverage:run]
+source=
+       pkg_resources
+       setuptools
+omit=
+       */_vendor/*