summaryrefslogtreecommitdiff
path: root/setuptools/command
diff options
context:
space:
mode:
Diffstat (limited to 'setuptools/command')
-rw-r--r--setuptools/command/__init__.py3
-rw-r--r--[-rwxr-xr-x]setuptools/command/alias.py0
-rw-r--r--setuptools/command/bdist_egg.py13
-rw-r--r--[-rwxr-xr-x]setuptools/command/bdist_rpm.py0
-rw-r--r--[-rwxr-xr-x]setuptools/command/bdist_wininst.py0
-rw-r--r--setuptools/command/build_clib.py61
-rw-r--r--setuptools/command/build_ext.py19
-rw-r--r--[-rwxr-xr-x]setuptools/command/develop.py27
-rw-r--r--[-rwxr-xr-x]setuptools/command/easy_install.py92
-rw-r--r--[-rwxr-xr-x]setuptools/command/egg_info.py40
-rw-r--r--setuptools/command/install.py2
-rw-r--r--[-rwxr-xr-x]setuptools/command/install_egg_info.py0
-rw-r--r--setuptools/command/install_lib.py7
-rw-r--r--[-rwxr-xr-x]setuptools/command/install_scripts.py7
-rw-r--r--setuptools/command/py36compat.py2
-rw-r--r--[-rwxr-xr-x]setuptools/command/register.py22
-rw-r--r--[-rwxr-xr-x]setuptools/command/rotate.py0
-rw-r--r--[-rwxr-xr-x]setuptools/command/saveopts.py0
-rw-r--r--[-rwxr-xr-x]setuptools/command/sdist.py72
-rw-r--r--[-rwxr-xr-x]setuptools/command/setopt.py0
-rw-r--r--setuptools/command/test.py18
-rw-r--r--setuptools/command/upload.py52
-rw-r--r--setuptools/command/upload_docs.py10
23 files changed, 263 insertions, 184 deletions
diff --git a/setuptools/command/__init__.py b/setuptools/command/__init__.py
index fe619e2e..743f5588 100644
--- a/setuptools/command/__init__.py
+++ b/setuptools/command/__init__.py
@@ -2,8 +2,7 @@ __all__ = [
'alias', 'bdist_egg', 'bdist_rpm', 'build_ext', 'build_py', 'develop',
'easy_install', 'egg_info', 'install', 'install_lib', 'rotate', 'saveopts',
'sdist', 'setopt', 'test', 'install_egg_info', 'install_scripts',
- 'register', 'bdist_wininst', 'upload_docs', 'upload', 'build_clib',
- 'dist_info',
+ 'bdist_wininst', 'upload_docs', 'build_clib', 'dist_info',
]
from distutils.command.bdist import bdist
diff --git a/setuptools/command/alias.py b/setuptools/command/alias.py
index 4532b1cc..4532b1cc 100755..100644
--- a/setuptools/command/alias.py
+++ b/setuptools/command/alias.py
diff --git a/setuptools/command/bdist_egg.py b/setuptools/command/bdist_egg.py
index 14530729..1b28d4c9 100644
--- a/setuptools/command/bdist_egg.py
+++ b/setuptools/command/bdist_egg.py
@@ -11,13 +11,14 @@ import os
import re
import textwrap
import marshal
+import warnings
from setuptools.extern import six
from pkg_resources import get_build_platform, Distribution, ensure_directory
from pkg_resources import EntryPoint
from setuptools.extension import Library
-from setuptools import Command
+from setuptools import Command, SetuptoolsDeprecationWarning
try:
# Python 2.7 or >=3.2
@@ -278,13 +279,19 @@ class bdist_egg(Command):
if ep is None:
return 'w' # not an eggsecutable, do it the usual way.
+ warnings.warn(
+ "Eggsecutables are deprecated and will be removed in a future "
+ "version.",
+ SetuptoolsDeprecationWarning
+ )
+
if not ep.attrs or ep.extras:
raise DistutilsSetupError(
"eggsecutable entry point (%r) cannot have 'extras' "
"or refer to a module" % (ep,)
)
- pyver = sys.version[:3]
+ pyver = '{}.{}'.format(*sys.version_info)
pkg = ep.module_name
full = '.'.join(ep.attrs)
base = ep.attrs[0]
@@ -411,7 +418,7 @@ def scan_module(egg_dir, base, name, stubs):
return True # Extension module
pkg = base[len(egg_dir) + 1:].replace(os.sep, '.')
module = pkg + (pkg and '.' or '') + os.path.splitext(name)[0]
- if sys.version_info.major == 2:
+ if six.PY2:
skip = 8 # skip magic & date
elif sys.version_info < (3, 7):
skip = 12 # skip magic & date & file size
diff --git a/setuptools/command/bdist_rpm.py b/setuptools/command/bdist_rpm.py
index 70730927..70730927 100755..100644
--- a/setuptools/command/bdist_rpm.py
+++ b/setuptools/command/bdist_rpm.py
diff --git a/setuptools/command/bdist_wininst.py b/setuptools/command/bdist_wininst.py
index 073de97b..073de97b 100755..100644
--- a/setuptools/command/bdist_wininst.py
+++ b/setuptools/command/bdist_wininst.py
diff --git a/setuptools/command/build_clib.py b/setuptools/command/build_clib.py
index 09caff6f..67ce2444 100644
--- a/setuptools/command/build_clib.py
+++ b/setuptools/command/build_clib.py
@@ -25,9 +25,9 @@ class build_clib(orig.build_clib):
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)
@@ -38,9 +38,9 @@ class build_clib(orig.build_clib):
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.
@@ -48,9 +48,9 @@ class build_clib(orig.build_clib):
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.
@@ -60,39 +60,42 @@ class build_clib(orig.build_clib):
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
+ )
diff --git a/setuptools/command/build_ext.py b/setuptools/command/build_ext.py
index 60a8a32f..03b6f346 100644
--- a/setuptools/command/build_ext.py
+++ b/setuptools/command/build_ext.py
@@ -1,7 +1,6 @@
import os
import sys
import itertools
-import imp
from distutils.command.build_ext import build_ext as _du_build_ext
from distutils.file_util import copy_file
from distutils.ccompiler import new_compiler
@@ -12,6 +11,14 @@ from distutils import log
from setuptools.extension import Library
from setuptools.extern import six
+if six.PY2:
+ import imp
+
+ EXTENSION_SUFFIXES = [
+ s for s, _, tp in imp.get_suffixes() if tp == imp.C_EXTENSION]
+else:
+ from importlib.machinery import EXTENSION_SUFFIXES
+
try:
# Attempt to use Cython for building extensions, if available
from Cython.Distutils.build_ext import build_ext as _build_ext
@@ -23,7 +30,7 @@ except ImportError:
# 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):
@@ -59,12 +66,14 @@ elif os.name != 'nt':
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 the file extension for an abi3-compliant Extension()"""
- for suffix, _, _ in (s for s in imp.get_suffixes() if s[2] == imp.C_EXTENSION):
+ for suffix in EXTENSION_SUFFIXES:
if '.abi3' in suffix: # Unix
return suffix
elif suffix == '.pyd': # Windows
@@ -107,7 +116,7 @@ class build_ext(_build_ext):
if fullname in self.ext_map:
ext = self.ext_map[fullname]
use_abi3 = (
- six.PY3
+ not six.PY2
and getattr(ext, 'py_limited_api')
and get_abi3_suffix()
)
diff --git a/setuptools/command/develop.py b/setuptools/command/develop.py
index fdc9fc43..b5619246 100755..100644
--- a/setuptools/command/develop.py
+++ b/setuptools/command/develop.py
@@ -7,7 +7,7 @@ import io
from setuptools.extern import six
-from pkg_resources import Distribution, PathMetadata, normalize_path
+import pkg_resources
from setuptools.command.easy_install import easy_install
from setuptools import namespaces
import setuptools
@@ -65,9 +65,9 @@ class develop(namespaces.DevelopInstaller, easy_install):
if self.egg_path is None:
self.egg_path = os.path.abspath(ei.egg_base)
- target = normalize_path(self.egg_base)
- egg_path = normalize_path(os.path.join(self.install_dir,
- self.egg_path))
+ target = pkg_resources.normalize_path(self.egg_base)
+ egg_path = pkg_resources.normalize_path(
+ os.path.join(self.install_dir, self.egg_path))
if egg_path != target:
raise DistutilsOptionError(
"--egg-path must be a relative path from the install"
@@ -75,9 +75,9 @@ class develop(namespaces.DevelopInstaller, easy_install):
)
# Make a distribution for the package's source
- self.dist = Distribution(
+ self.dist = pkg_resources.Distribution(
target,
- PathMetadata(target, os.path.abspath(ei.egg_info)),
+ pkg_resources.PathMetadata(target, os.path.abspath(ei.egg_info)),
project_name=ei.egg_name
)
@@ -97,24 +97,25 @@ class develop(namespaces.DevelopInstaller, easy_install):
path_to_setup = egg_base.replace(os.sep, '/').rstrip('/')
if path_to_setup != os.curdir:
path_to_setup = '../' * (path_to_setup.count('/') + 1)
- resolved = normalize_path(
+ resolved = pkg_resources.normalize_path(
os.path.join(install_dir, egg_path, path_to_setup)
)
- if resolved != normalize_path(os.curdir):
+ if resolved != pkg_resources.normalize_path(os.curdir):
raise DistutilsOptionError(
"Can't get a consistent path to setup script from"
- " installation directory", resolved, normalize_path(os.curdir))
+ " installation directory", resolved,
+ pkg_resources.normalize_path(os.curdir))
return path_to_setup
def install_for_development(self):
- if six.PY3 and getattr(self.distribution, 'use_2to3', False):
+ if not six.PY2 and getattr(self.distribution, 'use_2to3', False):
# If we run 2to3 we can not do this inplace:
# Ensure metadata is up-to-date
self.reinitialize_command('build_py', inplace=0)
self.run_command('build_py')
bpy_cmd = self.get_finalized_command("build_py")
- build_path = normalize_path(bpy_cmd.build_lib)
+ build_path = pkg_resources.normalize_path(bpy_cmd.build_lib)
# Build extensions
self.reinitialize_command('egg_info', egg_base=build_path)
@@ -128,7 +129,8 @@ class develop(namespaces.DevelopInstaller, easy_install):
self.egg_path = build_path
self.dist.location = build_path
# XXX
- self.dist._provider = PathMetadata(build_path, ei_cmd.egg_info)
+ self.dist._provider = pkg_resources.PathMetadata(
+ build_path, ei_cmd.egg_info)
else:
# Without 2to3 inplace works fine:
self.run_command('egg_info')
@@ -200,6 +202,7 @@ class VersionlessRequirement:
name as the 'requirement' so that scripts will work across
multiple versions.
+ >>> from pkg_resources import Distribution
>>> dist = Distribution(project_name='foo', version='1.0')
>>> str(dist.as_requirement())
'foo==1.0'
diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py
index 5b65b95d..64ff0457 100755..100644
--- a/setuptools/command/easy_install.py
+++ b/setuptools/command/easy_install.py
@@ -40,8 +40,11 @@ import subprocess
import shlex
import io
+
from sysconfig import get_config_vars, get_path
+from setuptools import SetuptoolsDeprecationWarning
+
from setuptools.extern import six
from setuptools.extern.six.moves import configparser, map
@@ -96,7 +99,7 @@ def samefile(p1, p2):
if six.PY2:
- def _to_ascii(s):
+ def _to_bytes(s):
return s
def isascii(s):
@@ -107,8 +110,8 @@ if six.PY2:
return False
else:
- def _to_ascii(s):
- return s.encode('ascii')
+ def _to_bytes(s):
+ return s.encode('utf8')
def isascii(s):
try:
@@ -118,7 +121,8 @@ else:
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):
@@ -153,19 +157,16 @@ 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
@@ -238,7 +239,7 @@ class easy_install(Command):
"""
Render the Setuptools version and installation details, then exit.
"""
- ver = sys.version[:3]
+ ver = '{}.{}'.format(*sys.version_info)
dist = get_distribution('setuptools')
tmpl = 'setuptools {dist.version} from {dist.location} (Python {ver})'
print(tmpl.format(**locals()))
@@ -269,6 +270,9 @@ class easy_install(Command):
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()
@@ -407,7 +411,13 @@ class easy_install(Command):
]
self._expand_attrs(dirs)
- def run(self):
+ def run(self, show_deprecation=True):
+ if show_deprecation:
+ self.announce(
+ "WARNING: The easy_install command is deprecated "
+ "and will be removed in a future version.",
+ log.WARN,
+ )
if self.verbose != self.distribution.verbose:
log.set_verbosity(self.verbose)
try:
@@ -475,8 +485,9 @@ class easy_install(Command):
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:
@@ -504,13 +515,13 @@ class easy_install(Command):
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
@@ -526,7 +537,7 @@ class easy_install(Command):
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,)
@@ -638,7 +649,7 @@ class easy_install(Command):
@contextlib.contextmanager
def _tmpdir(self):
- tmpdir = tempfile.mkdtemp(prefix=six.u("easy_install-"))
+ tmpdir = tempfile.mkdtemp(prefix=u"easy_install-")
try:
# cast to str as workaround for #709 and #710 and #712
yield str(tmpdir)
@@ -811,7 +822,7 @@ class easy_install(Command):
if is_script:
body = self._load_template(dev_path) % locals()
script_text = ScriptWriter.get_header(script_text) + body
- self.write_script(script_name, _to_ascii(script_text), 'b')
+ self.write_script(script_name, _to_bytes(script_text), 'b')
@staticmethod
def _load_template(dev_path):
@@ -1090,13 +1101,13 @@ class easy_install(Command):
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"""
@@ -1121,7 +1132,7 @@ class easy_install(Command):
%(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)
@@ -1183,8 +1194,7 @@ class easy_install(Command):
# to the setup.cfg file.
ei_opts = self.distribution.get_option_dict('easy_install').copy()
fetch_directives = (
- 'find_links', 'site_dirs', 'index_url', 'optimize',
- 'site_dirs', 'allow_hosts',
+ 'find_links', 'site_dirs', 'index_url', 'optimize', 'allow_hosts',
)
fetch_options = {}
for key, val in ei_opts.items():
@@ -1305,11 +1315,8 @@ class easy_install(Command):
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"""
@@ -1415,7 +1422,7 @@ def get_site_dirs():
os.path.join(
prefix,
"lib",
- "python" + sys.version[:3],
+ "python{}.{}".format(*sys.version_info),
"site-packages",
),
os.path.join(prefix, "lib", "site-python"),
@@ -1436,7 +1443,7 @@ def get_site_dirs():
home,
'Library',
'Python',
- sys.version[:3],
+ '{}.{}'.format(*sys.version_info),
'site-packages',
)
sitedirs.append(home_sp)
@@ -1565,7 +1572,7 @@ def get_exe_prefixes(exe_filename):
continue
if parts[0].upper() in ('PURELIB', 'PLATLIB'):
contents = z.read(name)
- if six.PY3:
+ if not six.PY2:
contents = contents.decode()
for pth in yield_lines(contents):
pth = pth.strip().replace('\\', '/')
@@ -2083,7 +2090,7 @@ class ScriptWriter:
@classmethod
def get_script_args(cls, dist, executable=None, wininst=False):
# for backward compatibility
- warnings.warn("Use get_args", DeprecationWarning)
+ warnings.warn("Use get_args", EasyInstallDeprecationWarning)
writer = (WindowsScriptWriter if wininst else ScriptWriter).best()
header = cls.get_script_header("", executable, wininst)
return writer.get_args(dist, header)
@@ -2091,12 +2098,11 @@ class ScriptWriter:
@classmethod
def get_script_header(cls, script_text, executable=None, wininst=False):
# for backward compatibility
- warnings.warn("Use get_header", DeprecationWarning)
+ warnings.warn(
+ "Use get_header", EasyInstallDeprecationWarning, stacklevel=2)
if wininst:
executable = "python.exe"
- cmd = cls.command_spec_class.best().from_param(executable)
- cmd.install_options(script_text)
- return cmd.as_header()
+ return cls.get_header(script_text, executable)
@classmethod
def get_args(cls, dist, header=None):
@@ -2128,7 +2134,7 @@ class ScriptWriter:
@classmethod
def get_writer(cls, force_windows):
# for backward compatibility
- warnings.warn("Use best", DeprecationWarning)
+ warnings.warn("Use best", EasyInstallDeprecationWarning)
return WindowsScriptWriter.best() if force_windows else cls.best()
@classmethod
@@ -2160,7 +2166,7 @@ class WindowsScriptWriter(ScriptWriter):
@classmethod
def get_writer(cls):
# for backward compatibility
- warnings.warn("Use best", DeprecationWarning)
+ warnings.warn("Use best", EasyInstallDeprecationWarning)
return cls.best()
@classmethod
@@ -2341,3 +2347,9 @@ def _patch_usage():
yield
finally:
distutils.core.gen_usage = saved
+
+
+class EasyInstallDeprecationWarning(SetuptoolsDeprecationWarning):
+ """
+ Warning for EasyInstall deprecations, bypassing suppression.
+ """
diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py
index 5fd6c888..7fa89541 100755..100644
--- a/setuptools/command/egg_info.py
+++ b/setuptools/command/egg_info.py
@@ -31,6 +31,7 @@ import setuptools.unicode_utils as unicode_utils
from setuptools.glob import glob
from setuptools.extern import packaging
+from setuptools import SetuptoolsDeprecationWarning
def translate_pattern(glob):
@@ -113,7 +114,7 @@ def translate_pattern(glob):
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:
@@ -160,7 +161,9 @@ class egg_info(InfoCommon, Command):
def initialize_options(self):
self.egg_base = None
+ self.egg_name = None
self.egg_info = None
+ self.egg_version = None
self.broken_egg_info = False
####################################
@@ -188,15 +191,13 @@ class egg_info(InfoCommon, Command):
egg_info['tag_date'] = 0
edit_config(filename, dict(egg_info=egg_info))
- @property
- def egg_name(self):
- return self.name
-
- @property
- def egg_version(self):
- return self.tagged_version()
-
def finalize_options(self):
+ # Note: we need to capture the current value returned
+ # by `self.tagged_version()`, so we can later update
+ # `self.distribution.metadata.version` without
+ # repercussions.
+ self.egg_name = self.name
+ self.egg_version = self.tagged_version()
parsed_version = parse_version(self.egg_version)
try:
@@ -266,7 +267,7 @@ class egg_info(InfoCommon, Command):
to the file.
"""
log.info("writing %s to %s", what, filename)
- if six.PY3:
+ if not six.PY2:
data = data.encode("utf-8")
if not self.dry_run:
f = open(filename, 'wb')
@@ -281,6 +282,7 @@ class egg_info(InfoCommon, Command):
def run(self):
self.mkpath(self.egg_info)
+ os.utime(self.egg_info, None)
installer = self.distribution.fetch_build_egg
for ep in iter_entry_points('egg_info.writers'):
ep.require(installer=installer)
@@ -567,6 +569,7 @@ class manifest_maker(sdist):
def add_defaults(self):
sdist.add_defaults(self)
+ self.check_license()
self.filelist.append(self.template)
self.filelist.append(self.manifest)
rcfiles = list(walk_revctrl())
@@ -574,6 +577,12 @@ class manifest_maker(sdist):
self.filelist.extend(rcfiles)
elif os.path.exists(self.manifest):
self.read_manifest()
+
+ if os.path.exists("setup.py"):
+ # setup.py should be included by default, even if it's not
+ # the script called to create the sdist
+ self.filelist.append("setup.py")
+
ei_cmd = self.get_finalized_command('egg_info')
self.filelist.graft(ei_cmd.egg_info)
@@ -629,7 +638,9 @@ def warn_depends_obsolete(cmd, basename, filename):
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)
@@ -695,7 +706,8 @@ def get_pkg_info_revision():
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.", DeprecationWarning)
+ 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:
@@ -703,3 +715,7 @@ def get_pkg_info_revision():
if match:
return int(match.group(1))
return 0
+
+
+class EggInfoDeprecationWarning(SetuptoolsDeprecationWarning):
+ """Deprecated behavior warning for EggInfo, bypassing suppression."""
diff --git a/setuptools/command/install.py b/setuptools/command/install.py
index 31a5ddb5..72b9a3e4 100644
--- a/setuptools/command/install.py
+++ b/setuptools/command/install.py
@@ -114,7 +114,7 @@ class install(orig.install):
args.insert(0, setuptools.bootstrap_install_from)
cmd.args = args
- cmd.run()
+ cmd.run(show_deprecation=False)
setuptools.bootstrap_install_from = None
diff --git a/setuptools/command/install_egg_info.py b/setuptools/command/install_egg_info.py
index edc4718b..edc4718b 100755..100644
--- a/setuptools/command/install_egg_info.py
+++ b/setuptools/command/install_egg_info.py
diff --git a/setuptools/command/install_lib.py b/setuptools/command/install_lib.py
index 2b31c3e3..2e9d8757 100644
--- a/setuptools/command/install_lib.py
+++ b/setuptools/command/install_lib.py
@@ -1,5 +1,5 @@
import os
-import imp
+import sys
from itertools import product, starmap
import distutils.command.install_lib as orig
@@ -74,10 +74,11 @@ class install_lib(orig.install_lib):
yield '__init__.pyc'
yield '__init__.pyo'
- if not hasattr(imp, 'get_tag'):
+ if not hasattr(sys, 'implementation'):
return
- base = os.path.join('__pycache__', '__init__.' + imp.get_tag())
+ base = os.path.join(
+ '__pycache__', '__init__.' + sys.implementation.cache_tag)
yield base + '.pyc'
yield base + '.pyo'
yield base + '.opt-1.pyc'
diff --git a/setuptools/command/install_scripts.py b/setuptools/command/install_scripts.py
index 16234273..8c9a15e2 100755..100644
--- a/setuptools/command/install_scripts.py
+++ b/setuptools/command/install_scripts.py
@@ -32,8 +32,11 @@ class install_scripts(orig.install_scripts):
)
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"
diff --git a/setuptools/command/py36compat.py b/setuptools/command/py36compat.py
index 61063e75..28860558 100644
--- a/setuptools/command/py36compat.py
+++ b/setuptools/command/py36compat.py
@@ -132,5 +132,5 @@ class sdist_add_defaults:
if hasattr(sdist.sdist, '_add_defaults_standards'):
# disable the functionality already available upstream
- class sdist_add_defaults:
+ class sdist_add_defaults: # noqa
pass
diff --git a/setuptools/command/register.py b/setuptools/command/register.py
index 98bc0156..b8266b9a 100755..100644
--- a/setuptools/command/register.py
+++ b/setuptools/command/register.py
@@ -1,18 +1,18 @@
from distutils import log
import distutils.command.register as orig
+from setuptools.errors import RemovedCommandError
+
class register(orig.register):
- __doc__ = orig.register.__doc__
+ """Formerly used to register packages on PyPI."""
def run(self):
- try:
- # Make sure that we are using valid current name/version info
- self.run_command('egg_info')
- orig.register.run(self)
- finally:
- self.announce(
- "WARNING: Registering is deprecated, use twine to "
- "upload instead (https://pypi.org/p/twine/)",
- log.WARN
- )
+ msg = (
+ "The register command has been removed, use twine to upload "
+ + "instead (https://pypi.org/p/twine)"
+ )
+
+ self.announce("ERROR: " + msg, log.ERROR)
+
+ raise RemovedCommandError(msg)
diff --git a/setuptools/command/rotate.py b/setuptools/command/rotate.py
index b89353f5..b89353f5 100755..100644
--- a/setuptools/command/rotate.py
+++ b/setuptools/command/rotate.py
diff --git a/setuptools/command/saveopts.py b/setuptools/command/saveopts.py
index 611cec55..611cec55 100755..100644
--- a/setuptools/command/saveopts.py
+++ b/setuptools/command/saveopts.py
diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py
index bcfae4d8..8c3438ea 100755..100644
--- a/setuptools/command/sdist.py
+++ b/setuptools/command/sdist.py
@@ -5,7 +5,7 @@ import sys
import io
import contextlib
-from setuptools.extern import six
+from setuptools.extern import six, ordered_set
from .py36compat import sdist_add_defaults
@@ -121,19 +121,40 @@ class sdist(sdist_add_defaults, orig.sdist):
if has_leaky_handle:
read_template = __read_template_hack
+ def _add_defaults_optional(self):
+ if six.PY2:
+ sdist_add_defaults._add_defaults_optional(self)
+ else:
+ super()._add_defaults_optional()
+ if os.path.isfile('pyproject.toml'):
+ self.filelist.append('pyproject.toml')
+
def _add_defaults_python(self):
"""getting python files"""
if self.distribution.has_pure_modules():
build_py = self.get_finalized_command('build_py')
self.filelist.extend(build_py.get_source_files())
- # This functionality is incompatible with include_package_data, and
- # will in fact create an infinite recursion if include_package_data
- # is True. Use of include_package_data will imply that
- # distutils-style automatic handling of package_data is disabled
- if not self.distribution.include_package_data:
- for _, src_dir, _, filenames in build_py.data_files:
- self.filelist.extend([os.path.join(src_dir, filename)
- for filename in filenames])
+ self._add_data_files(self._safe_data_files(build_py))
+
+ def _safe_data_files(self, build_py):
+ """
+ Extracting data_files from build_py is known to cause
+ infinite recursion errors when `include_package_data`
+ is enabled, so suppress it in that case.
+ """
+ if self.distribution.include_package_data:
+ return ()
+ return build_py.data_files
+
+ def _add_data_files(self, data_files):
+ """
+ Add data files as found in build_py.data_files.
+ """
+ self.filelist.extend(
+ os.path.join(src_dir, name)
+ for _, src_dir, _, filenames in data_files
+ for name in filenames
+ )
def _add_defaults_data_files(self):
try:
@@ -186,7 +207,7 @@ class sdist(sdist_add_defaults, orig.sdist):
manifest = open(self.manifest, 'rb')
for line in manifest:
# The manifest must contain UTF-8. See #303.
- if six.PY3:
+ if not six.PY2:
try:
line = line.decode('UTF-8')
except UnicodeDecodeError:
@@ -198,3 +219,34 @@ class sdist(sdist_add_defaults, orig.sdist):
continue
self.filelist.append(line)
manifest.close()
+
+ def check_license(self):
+ """Checks if license_file' or 'license_files' is configured and adds any
+ valid paths to 'self.filelist'.
+ """
+
+ files = ordered_set.OrderedSet()
+
+ opts = self.distribution.get_option_dict('metadata')
+
+ # ignore the source of the value
+ _, license_file = opts.get('license_file', (None, None))
+
+ if license_file is None:
+ log.debug("'license_file' option was not specified")
+ else:
+ files.add(license_file)
+
+ try:
+ files.update(self.distribution.metadata.license_files)
+ except TypeError:
+ log.warn("warning: 'license_files' option is malformed")
+
+ for f in files:
+ if not os.path.exists(f):
+ log.warn(
+ "warning: Failed to find the configured license file '%s'",
+ f)
+ files.remove(f)
+
+ self.filelist.extend(files)
diff --git a/setuptools/command/setopt.py b/setuptools/command/setopt.py
index 7e57cc02..7e57cc02 100755..100644
--- a/setuptools/command/setopt.py
+++ b/setuptools/command/setopt.py
diff --git a/setuptools/command/test.py b/setuptools/command/test.py
index dde0118c..2d83967d 100644
--- a/setuptools/command/test.py
+++ b/setuptools/command/test.py
@@ -15,6 +15,7 @@ from pkg_resources import (resource_listdir, resource_exists, normalize_path,
working_set, _namespace_packages, evaluate_marker,
add_activation_listener, require, EntryPoint)
from setuptools import Command
+from .build_py import _unique_everseen
__metaclass__ = type
@@ -73,7 +74,7 @@ class NonDataProperty:
class test(Command):
"""Command to run unit tests after in-place build"""
- description = "run unit tests after in-place build"
+ description = "run unit tests after in-place build (deprecated)"
user_options = [
('test-module=', 'm', "Run 'test_suite' in specified module"),
@@ -128,7 +129,8 @@ class test(Command):
@contextlib.contextmanager
def project_on_sys_path(self, include_dists=[]):
- with_2to3 = six.PY3 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:
@@ -186,7 +188,7 @@ class test(Command):
orig_pythonpath = os.environ.get('PYTHONPATH', nothing)
current_pythonpath = os.environ.get('PYTHONPATH', '')
try:
- prefix = os.pathsep.join(paths)
+ prefix = os.pathsep.join(_unique_everseen(paths))
to_join = filter(None, [prefix, current_pythonpath])
new_path = os.pathsep.join(to_join)
if new_path:
@@ -213,6 +215,14 @@ class test(Command):
return itertools.chain(ir_d, tr_d, er_d)
def run(self):
+ self.announce(
+ "WARNING: Testing via this command is deprecated and will be "
+ "removed in a future version. Users looking for a generic test "
+ "entry point independent of test runner are encouraged to use "
+ "tox.",
+ log.WARN,
+ )
+
installed_dists = self.install_dists(self.distribution)
cmd = ' '.join(self._argv)
@@ -231,7 +241,7 @@ class test(Command):
# Purge modules under test from sys.modules. The test loader will
# re-import them from the build location. Required when 2to3 is used
# with namespace packages.
- if six.PY3 and getattr(self.distribution, 'use_2to3', False):
+ if not six.PY2 and getattr(self.distribution, 'use_2to3', False):
module = self.test_suite.split('.')[0]
if module in _namespace_packages:
del_modules = []
diff --git a/setuptools/command/upload.py b/setuptools/command/upload.py
index 72f24d8f..ec7f81e2 100644
--- a/setuptools/command/upload.py
+++ b/setuptools/command/upload.py
@@ -1,53 +1,17 @@
-import getpass
from distutils import log
from distutils.command import upload as orig
+from setuptools.errors import RemovedCommandError
+
class upload(orig.upload):
- """
- Override default upload behavior to obtain password
- in a variety of different ways.
- """
+ """Formerly used to upload packages to PyPI."""
def run(self):
- try:
- orig.upload.run(self)
- finally:
- self.announce(
- "WARNING: Uploading via this command is deprecated, use twine "
- "to upload instead (https://pypi.org/p/twine/)",
- log.WARN
- )
-
- def finalize_options(self):
- orig.upload.finalize_options(self)
- self.username = (
- self.username or
- getpass.getuser()
+ msg = (
+ "The upload command has been removed, use twine to upload "
+ + "instead (https://pypi.org/p/twine)"
)
- # Attempt to obtain password. Short circuit evaluation at the first
- # sign of success.
- self.password = (
- self.password or
- self._load_password_from_keyring() or
- self._prompt_for_password()
- )
-
- def _load_password_from_keyring(self):
- """
- Attempt to load password from keyring. Suppress Exceptions.
- """
- try:
- keyring = __import__('keyring')
- return keyring.get_password(self.repository, self.username)
- except Exception:
- pass
- def _prompt_for_password(self):
- """
- Prompt for a password on the tty. Suppress Exceptions.
- """
- try:
- return getpass.getpass()
- except (Exception, KeyboardInterrupt):
- pass
+ self.announce("ERROR: " + msg, log.ERROR)
+ raise RemovedCommandError(msg)
diff --git a/setuptools/command/upload_docs.py b/setuptools/command/upload_docs.py
index 07aa564a..0351da77 100644
--- a/setuptools/command/upload_docs.py
+++ b/setuptools/command/upload_docs.py
@@ -24,7 +24,7 @@ from .upload import upload
def _encode(s):
- errors = 'surrogateescape' if six.PY3 else 'strict'
+ errors = 'strict' if six.PY2 else 'surrogateescape'
return s.encode('utf-8', errors)
@@ -127,8 +127,8 @@ class upload_docs(upload):
"""
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(
@@ -138,7 +138,7 @@ class upload_docs(upload):
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):
@@ -153,7 +153,7 @@ class upload_docs(upload):
# set up the authentication
credentials = _encode(self.username + ':' + self.password)
credentials = standard_b64encode(credentials)
- if six.PY3:
+ if not six.PY2:
credentials = credentials.decode('ascii')
auth = "Basic " + credentials