dist: trusty
sudo: false
language: python
+python:
+- &latest_py2 2.7
+- 3.3
+- 3.4
+- 3.5
+- &latest_py3 3.6
+- nightly
+- pypy
+- pypy3
+
jobs:
fast_finish: true
include:
- - python: 2.6
- - python: &latest_py2 2.7
- - python: 3.3
- - python: 3.4
- - python: 3.5
- - python: &latest_py3 3.6
- - python: nightly
- - python: pypy
- - python: pypy3
- python: *latest_py3
env: LANG=C
- python: *latest_py2
+v37.0.0
+-------
+
+* #878: Drop support for Python 2.6. Python 2.6 users should
+ rely on 'setuptools < 37dev'.
+
v36.8.0
-------
for download links and basic installation instructions for each of the
supported platforms.
-You will need at least Python 2.6. An ``easy_install`` script will be
+You will need at least Python 3.3 or 2.7. An ``easy_install`` script will be
installed in the normal location for Python scripts on your platform.
Note that the instructions on the setuptools PyPI page assume that you are
directory (by default in the Python installation directory). It is recommended
for EasyInstall that you ensure this directory is in the PATH environment
variable. The easiest way to ensure the Scripts directory is in the PATH is
-to run ``Tools\Scripts\win_add2path.py`` from the Python directory (requires
-Python 2.6 or later).
+to run ``Tools\Scripts\win_add2path.py`` from the Python directory.
Note that instead of changing your ``PATH`` to include the Python scripts
directory, you can also retarget the installation location for scripts so they
`Use "virtualenv"`_
-.. [1] There are older ways to achieve custom installation using various ``easy_install`` and ``setup.py install`` options, combined with ``PYTHONPATH`` and/or ``PYTHONUSERBASE`` alterations, but all of these are effectively deprecated by the User scheme brought in by `PEP-370`_ in Python 2.6.
+.. [1] There are older ways to achieve custom installation using various ``easy_install`` and ``setup.py install`` options, combined with ``PYTHONPATH`` and/or ``PYTHONUSERBASE`` alterations, but all of these are effectively deprecated by the User scheme brought in by `PEP-370`_.
.. _PEP-370: http://www.python.org/dev/peps/pep-0370/
Use the "--user" option
~~~~~~~~~~~~~~~~~~~~~~~
-With Python 2.6 came the User scheme for installation, which means that all
-python distributions support an alternative install location that is specific to a user [2]_ [3]_.
+Python provides a User scheme for installation, which means that all
+python distributions support an alternative install location that is specific to a user [3]_.
The Default location for each OS is explained in the python documentation
for the ``site.USER_BASE`` variable. This mode of installation can be turned on by
specifying the ``--user`` option to ``setup.py install`` or ``easy_install``.
This approach serves the need to have a user-specific stash of packages.
-.. [2] Prior to Python2.6, Mac OS X offered a form of the User scheme. That is now subsumed into the User scheme introduced in Python 2.6.
.. [3] Prior to the User scheme, there was the Home scheme, which is still available, but requires more effort than the User scheme to get packages recognized.
Use the "--user" option and customize "PYTHONUSERBASE"
other metadata. (In fact, setuptools itself never generates
``.egg-info`` files, either; the support for using files was added so
that the requirement could easily be satisfied by other tools, such
-as the distutils in Python 2.5).
+as distutils).
In addition to the ``PKG-INFO`` file, an egg's metadata directory may
also include files and directories representing various forms of
The "markers" in a requirement are used to specify when a requirement
should be installed -- the requirement will be installed if the marker
evaluates as true in the current environment. For example, specifying
- ``argparse;python_version<"2.7"`` will not install in an Python 2.7 or 3.3
- environment, but will in a Python 2.6 environment.
+ ``argparse;python_version<"3.0"`` will not install in an Python 3
+ environment, but will in a Python 2 environment.
``Requirement`` Methods and Attributes
--------------------------------------
-----------------
``get_importer(path_item)``
- Retrieve a PEP 302 "importer" for the given path item (which need not
- actually be on ``sys.path``). This routine simulates the PEP 302 protocol
- for obtaining an "importer" object. It first checks for an importer for
- the path item in ``sys.path_importer_cache``, and if not found it calls
- each of the ``sys.path_hooks`` and caches the result if a good importer is
- found. If no importer is found, this routine returns an ``ImpWrapper``
- instance that wraps the builtin import machinery as a PEP 302-compliant
- "importer" object. This ``ImpWrapper`` is *not* cached; instead a new
- instance is returned each time.
-
- (Note: When run under Python 2.5, this function is simply an alias for
- ``pkgutil.get_importer()``, and instead of ``pkg_resources.ImpWrapper``
- instances, it may return ``pkgutil.ImpImporter`` instances.)
+ A deprecated alias for ``pkgutil.get_importer()``
File/Path Utilities
==================================================
``Setuptools`` is a collection of enhancements to the Python ``distutils``
-(for Python 2.6 and up) that allow developers to more easily build and
+that allow developers to more easily build and
distribute Python packages, especially ones that have dependencies on other
packages.
Use a platform-specific path separator (os.sep) for the path keys
for compatibility with pypy on Windows.
"""
- with ContextualZipFile(path) as zfile:
+ with zipfile.ZipFile(path) as zfile:
items = (
(
name.replace('/', os.sep),
return self[path].manifest
-class ContextualZipFile(zipfile.ZipFile):
- """
- Supplement ZipFile class to support context manager for Python 2.6
- """
-
- def __enter__(self):
- return self
-
- def __exit__(self, type, value, traceback):
- self.close()
-
- def __new__(cls, *args, **kwargs):
- """
- Construct a ZipFile or ContextualZipFile as appropriate
- """
- if hasattr(zipfile.ZipFile, '__exit__'):
- return zipfile.ZipFile(*args, **kwargs)
- return super(ContextualZipFile, cls).__new__(cls)
-
-
class ZipProvider(EggProvider):
"""Resource support for zips and eggs"""
return metadata
def _warn_on_replacement(self, metadata):
- # Python 2.6 and 3.2 compat for: replacement_char = '�'
+ # Python 2.7 compat for: replacement_char = '�'
replacement_char = b'\xef\xbf\xbd'.decode('utf-8')
if replacement_char in metadata:
tmpl = "{self.path} could not be properly decoded in UTF-8"
>>> em("sys_platform=='win32'") == (sys.platform=='win32')
True
- >>> em("python_version >= '2.6'")
+ >>> em("python_version >= '2.7'")
True
- >>> em("python_version > '2.5'")
+ >>> em("python_version > '2.6'")
True
>>> im("implementation_name=='cpython'")
"""Extras are also evaluated as markers at resolution time."""
ad = pkg_resources.Environment([])
ws = WorkingSet([])
- # Metadata needs to be native strings due to cStringIO behaviour in
- # 2.6, so use str().
Foo = Distribution.from_filename(
"/foo_dir/Foo-1.2.dist-info",
- metadata=Metadata(("METADATA", str("Provides-Extra: baz\n"
- "Requires-Dist: quux; extra=='baz'")))
+ metadata=Metadata(("METADATA", "Provides-Extra: baz\n"
+ "Requires-Dist: quux; extra=='baz'"))
)
ad.add(Foo)
assert list(ws.resolve(parse_requirements("Foo"), ad)) == [Foo]
"""Extras are also evaluated as markers at resolution time."""
ad = pkg_resources.Environment([])
ws = WorkingSet([])
- # Metadata needs to be native strings due to cStringIO behaviour in
- # 2.6, so use str().
Foo = Distribution.from_filename(
"/foo_dir/Foo-1.2.dist-info",
- metadata=Metadata(("METADATA", str("Provides-Extra: baz-lightyear\n"
- "Requires-Dist: quux; extra=='baz-lightyear'")))
+ metadata=Metadata(("METADATA", "Provides-Extra: baz-lightyear\n"
+ "Requires-Dist: quux; extra=='baz-lightyear'"))
)
ad.add(Foo)
assert list(ws.resolve(parse_requirements("Foo"), ad)) == [Foo]
def test_marker_evaluation_with_multiple_extras(self):
ad = pkg_resources.Environment([])
ws = WorkingSet([])
- # Metadata needs to be native strings due to cStringIO behaviour in
- # 2.6, so use str().
Foo = Distribution.from_filename(
"/foo_dir/Foo-1.2.dist-info",
- metadata=Metadata(("METADATA", str("Provides-Extra: baz\n"
+ metadata=Metadata(("METADATA", "Provides-Extra: baz\n"
"Requires-Dist: quux; extra=='baz'\n"
"Provides-Extra: bar\n"
- "Requires-Dist: fred; extra=='bar'\n")))
+ "Requires-Dist: fred; extra=='bar'\n"))
)
ad.add(Foo)
quux = Distribution.from_filename("/foo_dir/quux-1.0.dist-info")
def test_marker_evaluation_with_extras_loop(self):
ad = pkg_resources.Environment([])
ws = WorkingSet([])
- # Metadata needs to be native strings due to cStringIO behaviour in
- # 2.6, so use str().
a = Distribution.from_filename(
"/foo_dir/a-0.2.dist-info",
- metadata=Metadata(("METADATA", str("Requires-Dist: c[a]")))
+ metadata=Metadata(("METADATA", "Requires-Dist: c[a]"))
)
b = Distribution.from_filename(
"/foo_dir/b-0.3.dist-info",
- metadata=Metadata(("METADATA", str("Requires-Dist: c[b]")))
+ metadata=Metadata(("METADATA", "Requires-Dist: c[b]"))
)
c = Distribution.from_filename(
"/foo_dir/c-1.0.dist-info",
- metadata=Metadata(("METADATA", str("Provides-Extra: a\n"
+ metadata=Metadata(("METADATA", "Provides-Extra: a\n"
"Requires-Dist: b;extra=='a'\n"
"Provides-Extra: b\n"
- "Requires-Dist: foo;extra=='b'")))
+ "Requires-Dist: foo;extra=='b'"))
)
foo = Distribution.from_filename("/foo_dir/foo-0.1.dist-info")
for dist in (a, b, c, foo):
[bumpversion]
-current_version = 36.8.0
+current_version = 37.0.0
commit = True
tag = True
setup_params = dict(
name="setuptools",
- version="36.8.0",
+ version="37.0.0",
description="Easily download, build, install, upgrade, and uninstall "
"Python packages",
author="Python Packaging Authority",
License :: OSI Approved :: MIT License
Operating System :: OS Independent
Programming Language :: Python :: 2
- Programming Language :: Python :: 2.6
Programming Language :: Python :: 2.7
Programming Language :: Python :: 3
Programming Language :: Python :: 3.3
Topic :: System :: Systems Administration
Topic :: Utilities
""").strip().splitlines(),
- python_requires='>=2.6,!=3.0.*,!=3.1.*,!=3.2.*',
+ python_requires='>=2.7,!=3.0.*,!=3.1.*,!=3.2.*',
extras_require={
"ssl:sys_platform=='win32'": "wincertstore==0.2",
"certs": "certifi==2016.9.26",
import contextlib
from distutils.errors import DistutilsError
-from pkg_resources import ensure_directory, ContextualZipFile
+from pkg_resources import ensure_directory
__all__ = [
"unpack_archive", "unpack_zipfile", "unpack_tarfile", "default_filter",
if not zipfile.is_zipfile(filename):
raise UnrecognizedFormat("%s is not a zip file" % (filename,))
- with ContextualZipFile(filename) as z:
+ with zipfile.ZipFile(filename) as z:
for info in z.infolist():
name = info.filename
build tag. Install build keys in a deterministic order
to avoid arbitrary reordering on subsequent builds.
"""
- # python 2.6 compatibility
- odict = getattr(collections, 'OrderedDict', dict)
- egg_info = odict()
+ egg_info = collections.OrderedDict()
# follow the order these keys would have been added
# when PYTHONHASHSEED=0
egg_info['tag_build'] = self.tags()
for cmd_name in self.get_sub_commands():
self.run_command(cmd_name)
- # Call check_metadata only if no 'check' command
- # (distutils <= 2.6)
- import distutils.command
-
- if 'check' not in distutils.command.__all__:
- self.check_metadata()
-
self.make_distribution()
dist_files = getattr(self.distribution, 'dist_files', [])
import sys
import contextlib
import itertools
+import unittest
from distutils.errors import DistutilsError, DistutilsOptionError
from distutils import log
from unittest import TestLoader
working_set, _namespace_packages, evaluate_marker,
add_activation_listener, require, EntryPoint)
from setuptools import Command
-from setuptools.py31compat import unittest_main
class ScanningLoader(TestLoader):
del_modules.append(name)
list(map(sys.modules.__delitem__, del_modules))
- exit_kwarg = {} if sys.version_info < (2, 7) else {"exit": False}
- test = unittest_main(
+ test = unittest.main(
None, None, self._argv,
testLoader=self._resolve_as_ep(self.test_loader),
testRunner=self._resolve_as_ep(self.test_runner),
- **exit_kwarg
+ exit=False,
)
if not test.result.wasSuccessful():
msg = 'Test failed: %s' % test.result
import sys
from collections import defaultdict
from functools import partial
+from importlib import import_module
from distutils.errors import DistutilsOptionError, DistutilsFileError
-from setuptools.py26compat import import_module
from setuptools.extern.six import string_types
import platform
import types
import functools
+from importlib import import_module
import inspect
-from .py26compat import import_module
from setuptools.extern import six
import setuptools
from distutils import log
from distutils.errors import DistutilsError
from fnmatch import translate
-from setuptools.py26compat import strip_fragment
from setuptools.py27compat import get_all_headers
EGG_FRAGMENT = re.compile(r'^egg=([-A-Za-z0-9_.+!]+)$')
fp = None
try:
checker = HashChecker.from_url(url)
- fp = self.open_url(strip_fragment(url))
+ fp = self.open_url(url)
if isinstance(fp, urllib.error.HTTPError):
raise DistutilsError(
"Can't download %s: %s %s" % (url, fp.code, fp.msg)
+++ /dev/null
-"""
-Compatibility Support for Python 2.6 and earlier
-"""
-
-import sys
-
-try:
- from urllib.parse import splittag
-except ImportError:
- from urllib import splittag
-
-
-def strip_fragment(url):
- """
- In `Python 8280 <http://bugs.python.org/issue8280>`_, Python 2.7 and
- later was patched to disregard the fragment when making URL requests.
- Do the same for Python 2.6 and earlier.
- """
- url, fragment = splittag(url)
- return url
-
-
-if sys.version_info >= (2, 7):
- strip_fragment = lambda x: x
-
-try:
- from importlib import import_module
-except ImportError:
-
- def import_module(module_name):
- return __import__(module_name, fromlist=['__name__'])
-import sys
-import unittest
-
__all__ = ['get_config_vars', 'get_path']
try:
except OSError: # removal errors are not the only possible
pass
self.name = None
-
-
-unittest_main = unittest.main
-
-_PY31 = (3, 1) <= sys.version_info[:2] < (3, 2)
-if _PY31:
- # on Python 3.1, translate testRunner==None to TextTestRunner
- # for compatibility with Python 2.6, 2.7, and 3.2+
- def unittest_main(*args, **kwargs):
- if 'testRunner' in kwargs and kwargs['testRunner'] is None:
- kwargs['testRunner'] = unittest.TextTestRunner
- return unittest.main(*args, **kwargs)
mode = 'rb'
with open(filename, mode) as stream:
script = stream.read()
- # compile() function in Python 2.6 and 3.1 requires LF line endings.
- if sys.version_info[:2] < (2, 7) or sys.version_info[:2] >= (3, 0) and sys.version_info[:2] < (3, 2):
- script = script.replace(b'\r\n', b'\n')
- script = script.replace(b'\r', b'\n')
if locals is None:
locals = globals
code = compile(script, filename, 'exec')
+++ /dev/null
-import sys
-import tarfile
-import contextlib
-
-
-def _tarfile_open_ex(*args, **kwargs):
- """
- Extend result as a context manager.
- """
- return contextlib.closing(tarfile.open(*args, **kwargs))
-
-
-if sys.version_info[:2] < (2, 7) or (3, 0) <= sys.version_info[:2] < (3, 2):
- tarfile_open = _tarfile_open_ex
-else:
- tarfile_open = tarfile.open
import sys
import io
import subprocess
+import platform
from setuptools.extern import six
from setuptools.command import test
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,
+ @pytest.mark.skipif(
+ in_virtualenv or in_venv,
reason="Cannot run when invoked in a virtualenv or venv")
def test_2to3_user_mode(self, test_env):
settings = dict(
Test that console scripts are installed and that they reference
only the project by name and not the current version.
"""
- pytest.skip("TODO: needs a fixture to cause 'develop' "
+ pytest.skip(
+ "TODO: needs a fixture to cause 'develop' "
"to be invoked without mutating environment.")
settings = dict(
name='foo',
with test.test.paths_on_pythonpath([str(target)]):
subprocess.check_call(develop_cmd)
- @pytest.mark.skipif(bool(os.environ.get("APPVEYOR")),
- reason="https://github.com/pypa/setuptools/issues/851")
+ @pytest.mark.skipif(
+ bool(os.environ.get("APPVEYOR")),
+ reason="https://github.com/pypa/setuptools/issues/851",
+ )
+ @pytest.mark.skipif(
+ platform.python_implementation() == 'PyPy' and six.PY3,
+ reason="https://github.com/pypa/setuptools/issues/1202",
+ )
def test_namespace_package_importable(self, tmpdir):
"""
Installing two packages sharing the same namespace, one installed
install_cmd = [
sys.executable,
'-m',
- 'pip.__main__',
+ 'pip',
'install',
str(pkg_A),
'-t', str(target),
from setuptools.tests import fail_on_ascii
import pkg_resources
-from .py26compat import tarfile_open
from . import contexts
from .textwrap import DALS
# extracted path to sys.path so foo.bar v0.1 is importable
foobar_1_dir = os.path.join(temp_dir, 'foo.bar-0.1')
os.mkdir(foobar_1_dir)
- with tarfile_open(foobar_1_archive) as tf:
+ with tarfile.open(foobar_1_archive) as tf:
tf.extractall(foobar_1_dir)
sys.path.insert(1, foobar_1_dir)
listed in ``files`` as ``(filename, content)`` tuples.
"""
- with tarfile_open(dist_path, 'w:gz') as dist:
+ with tarfile.open(dist_path, 'w:gz') as dist:
for filename, content in files:
file_bytes = io.BytesIO(content.encode('utf-8'))
file_info = tarfile.TarInfo(name=filename)
+import sys
import ast
import os
import glob
import re
import stat
-import sys
from setuptools.command.egg_info import egg_info, manifest_maker
from setuptools.dist import Distribution
})
yield env
- dict_order_fails = pytest.mark.skipif(
- sys.version_info < (2, 7),
- reason="Intermittent failures on Python 2.6",
- )
-
- @dict_order_fails
def test_egg_info_save_version_info_setup_empty(self, tmpdir_cwd, env):
"""
When the egg_info section is empty or not present, running
flags = re.MULTILINE | re.DOTALL
assert re.search(pattern, content, flags)
- @dict_order_fails
def test_egg_info_save_version_info_setup_defaults(self, tmpdir_cwd, env):
"""
When running save_version_info on an existing setup.cfg
#
# To run Tox against all supported Python interpreters, you can set:
#
-# export TOXENV='py2{6,7},py3{3,4,5,6},pypy'
+# export TOXENV='py27,py3{3,4,5,6},pypy,pypy3'
[testenv]
deps=-rtests/requirements.txt