[bumpversion]
-current_version = 47.2.0
+current_version = 47.3.1
commit = True
tag = True
+v47.3.1
+-------
+
+* #1973: Removed ``pkg_resources.py31compat.makedirs`` in favor of the stdlib. Use ``os.makedirs()`` instead.
+* #2198: Restore ``__requires__`` directive in easy-install wrapper scripts.
+
+
+v47.3.0
+-------
+
+* #2197: Console script wrapper for editable installs now has a unified template and honors importlib_metadata if present for faster script execution on older Pythons.
+* #2195: Fix broken entry points generated by easy-install (pip editable installs).
+
+
v47.2.0
-------
except ImportError:
importlib_machinery = None
-from . import py31compat
from pkg_resources.extern import appdirs
from pkg_resources.extern import packaging
__import__('pkg_resources.extern.packaging.version')
def ensure_directory(path):
"""Ensure that the parent directory of `path` exists"""
dirname = os.path.dirname(path)
- py31compat.makedirs(dirname, exist_ok=True)
+ os.makedirs(dirname, exist_ok=True)
def _bypass_ensure_directory(path):
+++ /dev/null
-import os
-import errno
-import sys
-
-from .extern import six
-
-
-def _makedirs_31(path, exist_ok=False):
- try:
- os.makedirs(path)
- except OSError as exc:
- if not exist_ok or exc.errno != errno.EEXIST:
- raise
-
-
-# rely on compatibility behavior until mode considerations
-# and exists_ok considerations are disentangled.
-# See https://github.com/pypa/setuptools/pull/1083#issuecomment-315168663
-needs_makedirs = (
- six.PY2 or
- (3, 4) <= sys.version_info < (3, 4, 1)
-)
-makedirs = _makedirs_31 if needs_makedirs else os.makedirs
[metadata]
name = setuptools
-version = 47.2.0
+version = 47.3.1
description = Easily download, build, install, upgrade, and uninstall Python packages
author = Python Packaging Authority
author_email = distutils-sig@python.org
from setuptools.py31compat import TemporaryDirectory
from pkg_resources import parse_requirements
-from pkg_resources.py31compat import makedirs
__all__ = ['get_requires_for_build_sdist',
'get_requires_for_build_wheel',
result_directory = os.path.abspath(result_directory)
# Build in a temporary directory, then copy to the target.
- makedirs(result_directory, exist_ok=True)
+ os.makedirs(result_directory, exist_ok=True)
with TemporaryDirectory(dir=result_directory) as tmp_dist_dir:
sys.argv = (sys.argv[:1] + setup_command +
['--dist-dir', tmp_dist_dir] +
Distribution, PathMetadata, EggMetadata, WorkingSet, DistributionNotFound,
VersionConflict, DEVELOP_DIST,
)
-import pkg_resources.py31compat
+import pkg_resources
__metaclass__ = type
if ok_exists:
os.unlink(ok_file)
dirname = os.path.dirname(ok_file)
- pkg_resources.py31compat.makedirs(dirname, exist_ok=True)
+ os.makedirs(dirname, exist_ok=True)
f = open(pth_file, 'w')
except (OSError, IOError):
self.cant_write_to_target()
gui apps.
"""
- if sys.version_info >= (3, 8):
- template = textwrap.dedent(r"""
- # EASY-INSTALL-ENTRY-SCRIPT: %(spec)r,%(group)r,%(name)r
- import re
- import sys
+ template = textwrap.dedent(r"""
+ # EASY-INSTALL-ENTRY-SCRIPT: %(spec)r,%(group)r,%(name)r
+ import re
+ import sys
+
+ # for compatibility with easy_install; see #2198
+ __requires__ = %(spec)r
+
+ try:
from importlib.metadata import distribution
+ except ImportError:
+ try:
+ from importlib_metadata import distribution
+ except ImportError:
+ from pkg_resources import load_entry_point
- if __name__ == '__main__':
- sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
- for entry_point in distribution(%(spec)r).entry_points:
- if entry_point.group == %(group)r and entry_point.name == %(name)r:
- sys.exit(entry_point.load()())
- """).lstrip() # noqa: E501
- else:
- template = textwrap.dedent(r"""
- # EASY-INSTALL-ENTRY-SCRIPT: %(spec)r,%(group)r,%(name)r
- __requires__ = %(spec)r
- import re
- import sys
- from pkg_resources import load_entry_point
-
- if __name__ == '__main__':
- sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
- sys.exit(
- load_entry_point(%(spec)r, %(group)r, %(name)r)()
- )
- """).lstrip() # noqa: E501
+
+ def importlib_load_entry_point(spec, group, name):
+ dist_name, _, _ = spec.partition('==')
+ matches = (
+ entry_point
+ for entry_point in distribution(dist_name).entry_points
+ if entry_point.group == group and entry_point.name == name
+ )
+ return next(matches).load()
+
+
+ globals().setdefault('load_entry_point', importlib_load_entry_point)
+
+
+ if __name__ == '__main__':
+ sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
+ sys.exit(load_entry_point(%(spec)r, %(group)r, %(name)r)())
+ """).lstrip()
command_spec_class = CommandSpec
def parse_requirement_arg(spec):
try:
return Requirement.parse(spec)
- except ValueError:
+ except ValueError as e:
raise DistutilsError(
"Not a URL, existing file, or requirement spec: %r" % (spec,)
- )
+ ) from e
def parse_bdist_wininst(name):
if warning:
self.warn(warning, msg)
else:
- raise DistutilsError('%s %s' % (url, msg))
+ raise DistutilsError('%s %s' % (url, msg)) from v
except urllib.error.HTTPError as v:
return v
except urllib.error.URLError as v:
self.warn(warning, v.reason)
else:
raise DistutilsError("Download error for %s: %s"
- % (url, v.reason))
+ % (url, v.reason)) from v
except http_client.BadStatusLine as v:
if warning:
self.warn(warning, v.line)
'%s returned a bad status line. The server might be '
'down, %s' %
(url, v.line)
- )
+ ) from v
except (http_client.HTTPException, socket.error) as v:
if warning:
self.warn(warning, v)
else:
raise DistutilsError("Download error for %s: %s"
- % (url, v))
+ % (url, v)) from v
def _download_url(self, scheme, url, tmpdir):
# Determine download filename
from setuptools.extern import six
from setuptools.extern.six.moves import builtins, map
-import pkg_resources.py31compat
+import pkg_resources
from distutils.errors import DistutilsError
from pkg_resources import working_set
"""
Monkey-patch tempfile.tempdir with replacement, ensuring it exists
"""
- pkg_resources.py31compat.makedirs(replacement, exist_ok=True)
+ os.makedirs(replacement, exist_ok=True)
saved = tempfile.tempdir
import os
-import pkg_resources.py31compat
-
-
def build_files(file_defs, prefix=""):
"""
Build a set of files/directories, as described by the
for name, contents in file_defs.items():
full_name = os.path.join(prefix, name)
if isinstance(contents, dict):
- pkg_resources.py31compat.makedirs(full_name, exist_ok=True)
+ os.makedirs(full_name, exist_ok=True)
build_files(contents, prefix=full_name)
else:
if isinstance(contents, bytes):
from distutils import log
from distutils.errors import DistutilsTemplateError
-import pkg_resources.py31compat
from setuptools.command.egg_info import FileList, egg_info, translate_pattern
from setuptools.dist import Distribution
from setuptools.extern import six
for file in files:
file = os.path.join(self.temp_dir, file)
dirname, basename = os.path.split(file)
- pkg_resources.py31compat.makedirs(dirname, exist_ok=True)
+ os.makedirs(dirname, exist_ok=True)
open(file, 'w').close()
def test_process_template_line(self):