up
This commit is contained in:
@@ -2,37 +2,38 @@
|
||||
|
||||
Create a distribution's .egg-info directory and contents"""
|
||||
|
||||
from distutils.filelist import FileList as _FileList
|
||||
from distutils.errors import DistutilsInternalError
|
||||
from distutils.util import convert_path
|
||||
from distutils import log
|
||||
import distutils.errors
|
||||
import distutils.filelist
|
||||
import functools
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import io
|
||||
import warnings
|
||||
import time
|
||||
from collections.abc import Callable
|
||||
import collections
|
||||
|
||||
import packaging
|
||||
import packaging.requirements
|
||||
import packaging.version
|
||||
from .._importlib import metadata
|
||||
from .. import _entry_points
|
||||
|
||||
import setuptools.unicode_utils as unicode_utils
|
||||
from setuptools import Command
|
||||
from setuptools.command import bdist_egg
|
||||
from setuptools.command.sdist import sdist, walk_revctrl
|
||||
from setuptools.command.sdist import sdist
|
||||
from setuptools.command.sdist import walk_revctrl
|
||||
from setuptools.command.setopt import edit_config
|
||||
from setuptools.command import bdist_egg
|
||||
from pkg_resources import (
|
||||
Requirement, safe_name, parse_version,
|
||||
safe_version, to_filename)
|
||||
import setuptools.unicode_utils as unicode_utils
|
||||
from setuptools.glob import glob
|
||||
|
||||
from .. import _entry_points, _normalization
|
||||
from .._importlib import metadata
|
||||
from ..warnings import SetuptoolsDeprecationWarning
|
||||
from . import _requirestxt
|
||||
|
||||
import distutils.errors
|
||||
import distutils.filelist
|
||||
from distutils import log
|
||||
from distutils.errors import DistutilsInternalError
|
||||
from distutils.filelist import FileList as _FileList
|
||||
from distutils.util import convert_path
|
||||
|
||||
PY_MAJOR = f'{sys.version_info.major}.{sys.version_info.minor}'
|
||||
from setuptools.extern import packaging
|
||||
from setuptools.extern.jaraco.text import yield_lines
|
||||
from setuptools import SetuptoolsDeprecationWarning
|
||||
|
||||
|
||||
def translate_pattern(glob): # noqa: C901 # is too complex (14) # FIXME
|
||||
@@ -48,7 +49,7 @@ def translate_pattern(glob): # noqa: C901 # is too complex (14) # FIXME
|
||||
chunks = glob.split(os.path.sep)
|
||||
|
||||
sep = re.escape(os.sep)
|
||||
valid_char = f'[^{sep}]'
|
||||
valid_char = '[^%s]' % (sep,)
|
||||
|
||||
for c, chunk in enumerate(chunks):
|
||||
last_chunk = c == len(chunks) - 1
|
||||
@@ -60,7 +61,7 @@ def translate_pattern(glob): # noqa: C901 # is too complex (14) # FIXME
|
||||
pat += '.*'
|
||||
else:
|
||||
# Match '(name/)*'
|
||||
pat += f'(?:{valid_char}+{sep})*'
|
||||
pat += '(?:%s+%s)*' % (valid_char, sep)
|
||||
continue # Break here as the whole path component has been handled
|
||||
|
||||
# Find any special characters in the remainder
|
||||
@@ -93,7 +94,7 @@ def translate_pattern(glob): # noqa: C901 # is too complex (14) # FIXME
|
||||
pat += re.escape(char)
|
||||
else:
|
||||
# Grab the insides of the [brackets]
|
||||
inner = chunk[i + 1 : inner_i]
|
||||
inner = chunk[i + 1:inner_i]
|
||||
char_class = ''
|
||||
|
||||
# Class negation
|
||||
@@ -102,7 +103,7 @@ def translate_pattern(glob): # noqa: C901 # is too complex (14) # FIXME
|
||||
inner = inner[1:]
|
||||
|
||||
char_class += re.escape(inner)
|
||||
pat += f'[{char_class}]'
|
||||
pat += '[%s]' % (char_class,)
|
||||
|
||||
# Skip to the end ]
|
||||
i = inner_i
|
||||
@@ -124,11 +125,10 @@ class InfoCommon:
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return _normalization.safe_name(self.distribution.get_name())
|
||||
return safe_name(self.distribution.get_name())
|
||||
|
||||
def tagged_version(self):
|
||||
tagged = self._maybe_tag(self.distribution.get_version())
|
||||
return _normalization.safe_version(tagged)
|
||||
return safe_version(self._maybe_tag(self.distribution.get_version()))
|
||||
|
||||
def _maybe_tag(self, version):
|
||||
"""
|
||||
@@ -136,8 +136,7 @@ class InfoCommon:
|
||||
in which case the version string already contains all tags.
|
||||
"""
|
||||
return (
|
||||
version
|
||||
if self.vtags and self._already_tagged(version)
|
||||
version if self.vtags and self._already_tagged(version)
|
||||
else version + self.vtags
|
||||
)
|
||||
|
||||
@@ -149,19 +148,15 @@ class InfoCommon:
|
||||
def _safe_tags(self) -> str:
|
||||
# To implement this we can rely on `safe_version` pretending to be version 0
|
||||
# followed by tags. Then we simply discard the starting 0 (fake version number)
|
||||
try:
|
||||
return _normalization.safe_version(f"0{self.vtags}")[1:]
|
||||
except packaging.version.InvalidVersion:
|
||||
return _normalization.safe_name(self.vtags.replace(' ', '.'))
|
||||
return safe_version(f"0{self.vtags}")[1:]
|
||||
|
||||
def tags(self) -> str:
|
||||
version = ''
|
||||
if self.tag_build:
|
||||
version += self.tag_build
|
||||
if self.tag_date:
|
||||
version += time.strftime("%Y%m%d")
|
||||
version += time.strftime("-%Y%m%d")
|
||||
return version
|
||||
|
||||
vtags = property(tags)
|
||||
|
||||
|
||||
@@ -169,12 +164,8 @@ class egg_info(InfoCommon, Command):
|
||||
description = "create a distribution's .egg-info directory"
|
||||
|
||||
user_options = [
|
||||
(
|
||||
'egg-base=',
|
||||
'e',
|
||||
"directory containing .egg-info directories"
|
||||
" [default: top of the source tree]",
|
||||
),
|
||||
('egg-base=', 'e', "directory containing .egg-info directories"
|
||||
" (default: top of the source tree)"),
|
||||
('tag-date', 'd', "Add date stamp (e.g. 20050528) to version number"),
|
||||
('tag-build=', 'b', "Specify explicit tag to add to version number"),
|
||||
('no-date', 'D', "Don't include date stamp [default]"),
|
||||
@@ -190,48 +181,51 @@ class egg_info(InfoCommon, Command):
|
||||
self.egg_name = None
|
||||
self.egg_info = None
|
||||
self.egg_version = None
|
||||
self.broken_egg_info = False
|
||||
self.ignore_egg_info_in_manifest = False
|
||||
|
||||
####################################
|
||||
# allow the 'tag_svn_revision' to be detected and
|
||||
# set, supporting sdists built on older Setuptools.
|
||||
@property
|
||||
def tag_svn_revision(self) -> None:
|
||||
def tag_svn_revision(self):
|
||||
pass
|
||||
|
||||
@tag_svn_revision.setter
|
||||
def tag_svn_revision(self, value):
|
||||
pass
|
||||
|
||||
####################################
|
||||
|
||||
def save_version_info(self, filename) -> None:
|
||||
def save_version_info(self, filename):
|
||||
"""
|
||||
Materialize the value of date into the
|
||||
build tag. Install build keys in a deterministic order
|
||||
to avoid arbitrary reordering on subsequent builds.
|
||||
"""
|
||||
egg_info = collections.OrderedDict()
|
||||
# follow the order these keys would have been added
|
||||
# when PYTHONHASHSEED=0
|
||||
egg_info = dict(tag_build=self.tags(), tag_date=0)
|
||||
egg_info['tag_build'] = self.tags()
|
||||
egg_info['tag_date'] = 0
|
||||
edit_config(filename, dict(egg_info=egg_info))
|
||||
|
||||
def finalize_options(self) -> None:
|
||||
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 = packaging.version.Version(self.egg_version)
|
||||
parsed_version = parse_version(self.egg_version)
|
||||
|
||||
try:
|
||||
is_version = isinstance(parsed_version, packaging.version.Version)
|
||||
spec = "%s==%s" if is_version else "%s===%s"
|
||||
packaging.requirements.Requirement(spec % (self.egg_name, self.egg_version))
|
||||
Requirement(spec % (self.egg_name, self.egg_version))
|
||||
except ValueError as e:
|
||||
raise distutils.errors.DistutilsOptionError(
|
||||
f"Invalid distribution name or version syntax: {self.egg_name}-{self.egg_version}"
|
||||
"Invalid distribution name or version syntax: %s-%s" %
|
||||
(self.egg_name, self.egg_version)
|
||||
) from e
|
||||
|
||||
if self.egg_base is None:
|
||||
@@ -239,20 +233,28 @@ class egg_info(InfoCommon, Command):
|
||||
self.egg_base = (dirs or {}).get('', os.curdir)
|
||||
|
||||
self.ensure_dirname('egg_base')
|
||||
self.egg_info = _normalization.filename_component(self.egg_name) + '.egg-info'
|
||||
self.egg_info = to_filename(self.egg_name) + '.egg-info'
|
||||
if self.egg_base != os.curdir:
|
||||
self.egg_info = os.path.join(self.egg_base, self.egg_info)
|
||||
if '-' in self.egg_name:
|
||||
self.check_broken_egg_info()
|
||||
|
||||
# Set package version for the benefit of dumber commands
|
||||
# (e.g. sdist, bdist_wininst, etc.)
|
||||
#
|
||||
self.distribution.metadata.version = self.egg_version
|
||||
|
||||
def _get_egg_basename(self, py_version=PY_MAJOR, platform=None):
|
||||
"""Compute filename of the output egg. Private API."""
|
||||
return _egg_basename(self.egg_name, self.egg_version, py_version, platform)
|
||||
# If we bootstrapped around the lack of a PKG-INFO, as might be the
|
||||
# case in a fresh checkout, make sure that any special tags get added
|
||||
# to the version info
|
||||
#
|
||||
pd = self.distribution._patched_dist
|
||||
if pd is not None and pd.key == self.egg_name.lower():
|
||||
pd._version = self.egg_version
|
||||
pd._parsed_version = parse_version(self.egg_version)
|
||||
self.distribution._patched_dist = None
|
||||
|
||||
def write_or_delete_file(self, what, filename, data, force: bool = False) -> None:
|
||||
def write_or_delete_file(self, what, filename, data, force=False):
|
||||
"""Write `data` to `filename` or delete if empty
|
||||
|
||||
If `data` is non-empty, this routine is the same as ``write_file()``.
|
||||
@@ -265,12 +267,14 @@ class egg_info(InfoCommon, Command):
|
||||
self.write_file(what, filename, data)
|
||||
elif os.path.exists(filename):
|
||||
if data is None and not force:
|
||||
log.warn("%s not set in setup(), but %s exists", what, filename)
|
||||
log.warn(
|
||||
"%s not set in setup(), but %s exists", what, filename
|
||||
)
|
||||
return
|
||||
else:
|
||||
self.delete_file(filename)
|
||||
|
||||
def write_file(self, what, filename, data) -> None:
|
||||
def write_file(self, what, filename, data):
|
||||
"""Write `data` to `filename` (if not a dry run) after announcing it
|
||||
|
||||
`what` is used in a log message to identify what is being written
|
||||
@@ -283,24 +287,16 @@ class egg_info(InfoCommon, Command):
|
||||
f.write(data)
|
||||
f.close()
|
||||
|
||||
def delete_file(self, filename) -> None:
|
||||
def delete_file(self, filename):
|
||||
"""Delete `filename` (if not a dry run) after announcing it"""
|
||||
log.info("deleting %s", filename)
|
||||
if not self.dry_run:
|
||||
os.unlink(filename)
|
||||
|
||||
def run(self) -> None:
|
||||
# Pre-load to avoid iterating over entry-points while an empty .egg-info
|
||||
# exists in sys.path. See pypa/pyproject-hooks#206
|
||||
writers = list(metadata.entry_points(group='egg_info.writers'))
|
||||
|
||||
def run(self):
|
||||
self.mkpath(self.egg_info)
|
||||
try:
|
||||
os.utime(self.egg_info, None)
|
||||
except OSError as e:
|
||||
msg = f"Cannot update time stamp of directory '{self.egg_info}'"
|
||||
raise distutils.errors.DistutilsFileError(msg) from e
|
||||
for ep in writers:
|
||||
os.utime(self.egg_info, None)
|
||||
for ep in metadata.entry_points(group='egg_info.writers'):
|
||||
writer = ep.load()
|
||||
writer(self, ep.name, os.path.join(self.egg_info, ep.name))
|
||||
|
||||
@@ -311,7 +307,7 @@ class egg_info(InfoCommon, Command):
|
||||
|
||||
self.find_sources()
|
||||
|
||||
def find_sources(self) -> None:
|
||||
def find_sources(self):
|
||||
"""Generate SOURCES.txt manifest file"""
|
||||
manifest_filename = os.path.join(self.egg_info, "SOURCES.txt")
|
||||
mm = manifest_maker(self.distribution)
|
||||
@@ -320,17 +316,30 @@ class egg_info(InfoCommon, Command):
|
||||
mm.run()
|
||||
self.filelist = mm.filelist
|
||||
|
||||
def check_broken_egg_info(self):
|
||||
bei = self.egg_name + '.egg-info'
|
||||
if self.egg_base != os.curdir:
|
||||
bei = os.path.join(self.egg_base, bei)
|
||||
if os.path.exists(bei):
|
||||
log.warn(
|
||||
"-" * 78 + '\n'
|
||||
"Note: Your current .egg-info directory has a '-' in its name;"
|
||||
'\nthis will not work correctly with "setup.py develop".\n\n'
|
||||
'Please rename %s to %s to correct this problem.\n' + '-' * 78,
|
||||
bei, self.egg_info
|
||||
)
|
||||
self.broken_egg_info = self.egg_info
|
||||
self.egg_info = bei # make it work for now
|
||||
|
||||
|
||||
class FileList(_FileList):
|
||||
# Implementations of the various MANIFEST.in commands
|
||||
|
||||
def __init__(
|
||||
self, warn=None, debug_print=None, ignore_egg_info_dir: bool = False
|
||||
) -> None:
|
||||
def __init__(self, warn=None, debug_print=None, ignore_egg_info_dir=False):
|
||||
super().__init__(warn, debug_print)
|
||||
self.ignore_egg_info_dir = ignore_egg_info_dir
|
||||
|
||||
def process_template_line(self, line) -> None:
|
||||
def process_template_line(self, line):
|
||||
# Parse the line: split it up, make sure the right number of words
|
||||
# is there, and return the relevant words. 'action' is always
|
||||
# defined: it's the first word of the line. Which of the other
|
||||
@@ -338,34 +347,37 @@ class FileList(_FileList):
|
||||
# patterns, (dir and patterns), or (dir_pattern).
|
||||
(action, patterns, dir, dir_pattern) = self._parse_template_line(line)
|
||||
|
||||
action_map: dict[str, Callable] = {
|
||||
action_map = {
|
||||
'include': self.include,
|
||||
'exclude': self.exclude,
|
||||
'global-include': self.global_include,
|
||||
'global-exclude': self.global_exclude,
|
||||
'recursive-include': functools.partial(
|
||||
self.recursive_include,
|
||||
dir,
|
||||
self.recursive_include, dir,
|
||||
),
|
||||
'recursive-exclude': functools.partial(
|
||||
self.recursive_exclude,
|
||||
dir,
|
||||
self.recursive_exclude, dir,
|
||||
),
|
||||
'graft': self.graft,
|
||||
'prune': self.prune,
|
||||
}
|
||||
log_map = {
|
||||
'include': "warning: no files found matching '%s'",
|
||||
'exclude': ("warning: no previously-included files found matching '%s'"),
|
||||
'exclude': (
|
||||
"warning: no previously-included files found "
|
||||
"matching '%s'"
|
||||
),
|
||||
'global-include': (
|
||||
"warning: no files found matching '%s' anywhere in distribution"
|
||||
"warning: no files found matching '%s' "
|
||||
"anywhere in distribution"
|
||||
),
|
||||
'global-exclude': (
|
||||
"warning: no previously-included files matching "
|
||||
"'%s' found anywhere in distribution"
|
||||
),
|
||||
'recursive-include': (
|
||||
"warning: no files found matching '%s' under directory '%s'"
|
||||
"warning: no files found matching '%s' "
|
||||
"under directory '%s'"
|
||||
),
|
||||
'recursive-exclude': (
|
||||
"warning: no previously-included files matching "
|
||||
@@ -378,8 +390,10 @@ class FileList(_FileList):
|
||||
try:
|
||||
process_action = action_map[action]
|
||||
except KeyError:
|
||||
msg = f"Invalid MANIFEST.in: unknown action {action!r} in {line!r}"
|
||||
raise DistutilsInternalError(msg) from None
|
||||
raise DistutilsInternalError(
|
||||
"this cannot happen: invalid action '{action!s}'".
|
||||
format(action=action),
|
||||
)
|
||||
|
||||
# OK, now we know that the action is valid and we have the
|
||||
# right number of words on the line for that action -- so we
|
||||
@@ -388,12 +402,14 @@ class FileList(_FileList):
|
||||
action_is_recursive = action.startswith('recursive-')
|
||||
if action in {'graft', 'prune'}:
|
||||
patterns = [dir_pattern]
|
||||
extra_log_args = (dir,) if action_is_recursive else ()
|
||||
extra_log_args = (dir, ) if action_is_recursive else ()
|
||||
log_tmpl = log_map[action]
|
||||
|
||||
self.debug_print(
|
||||
' '.join(
|
||||
[action] + ([dir] if action_is_recursive else []) + patterns,
|
||||
[action] +
|
||||
([dir] if action_is_recursive else []) +
|
||||
patterns,
|
||||
)
|
||||
)
|
||||
for pattern in patterns:
|
||||
@@ -429,7 +445,8 @@ class FileList(_FileList):
|
||||
Include all files anywhere in 'dir/' that match the pattern.
|
||||
"""
|
||||
full_pattern = os.path.join(dir, '**', pattern)
|
||||
found = [f for f in glob(full_pattern, recursive=True) if not os.path.isdir(f)]
|
||||
found = [f for f in glob(full_pattern, recursive=True)
|
||||
if not os.path.isdir(f)]
|
||||
self.extend(found)
|
||||
return bool(found)
|
||||
|
||||
@@ -474,7 +491,7 @@ class FileList(_FileList):
|
||||
match = translate_pattern(os.path.join('**', pattern))
|
||||
return self._remove_files(match.match)
|
||||
|
||||
def append(self, item) -> None:
|
||||
def append(self, item):
|
||||
if item.endswith('\r'): # Fix older sdists built on Windows
|
||||
item = item[:-1]
|
||||
path = convert_path(item)
|
||||
@@ -482,7 +499,7 @@ class FileList(_FileList):
|
||||
if self._safe_path(path):
|
||||
self.files.append(path)
|
||||
|
||||
def extend(self, paths) -> None:
|
||||
def extend(self, paths):
|
||||
self.files.extend(filter(self._safe_path, paths))
|
||||
|
||||
def _repair(self):
|
||||
@@ -501,7 +518,7 @@ class FileList(_FileList):
|
||||
# To avoid accidental trans-codings errors, first to unicode
|
||||
u_path = unicode_utils.filesys_decode(path)
|
||||
if u_path is None:
|
||||
log.warn(f"'{path}' in unexpected encoding -- skipping")
|
||||
log.warn("'%s' in unexpected encoding -- skipping" % path)
|
||||
return False
|
||||
|
||||
# Must ensure utf-8 encodability
|
||||
@@ -526,17 +543,17 @@ class FileList(_FileList):
|
||||
class manifest_maker(sdist):
|
||||
template = "MANIFEST.in"
|
||||
|
||||
def initialize_options(self) -> None:
|
||||
self.use_defaults = True
|
||||
self.prune = True
|
||||
self.manifest_only = True
|
||||
self.force_manifest = True
|
||||
def initialize_options(self):
|
||||
self.use_defaults = 1
|
||||
self.prune = 1
|
||||
self.manifest_only = 1
|
||||
self.force_manifest = 1
|
||||
self.ignore_egg_info_dir = False
|
||||
|
||||
def finalize_options(self) -> None:
|
||||
def finalize_options(self):
|
||||
pass
|
||||
|
||||
def run(self) -> None:
|
||||
def run(self):
|
||||
self.filelist = FileList(ignore_egg_info_dir=self.ignore_egg_info_dir)
|
||||
if not os.path.exists(self.manifest):
|
||||
self.write_manifest() # it must exist so it'll get in the list
|
||||
@@ -544,7 +561,6 @@ class manifest_maker(sdist):
|
||||
if os.path.exists(self.template):
|
||||
self.read_template()
|
||||
self.add_license_files()
|
||||
self._add_referenced_files()
|
||||
self.prune_file_list()
|
||||
self.filelist.sort()
|
||||
self.filelist.remove_duplicates()
|
||||
@@ -554,7 +570,7 @@ class manifest_maker(sdist):
|
||||
path = unicode_utils.filesys_decode(path)
|
||||
return path.replace(os.sep, '/')
|
||||
|
||||
def write_manifest(self) -> None:
|
||||
def write_manifest(self):
|
||||
"""
|
||||
Write the file list in 'self.filelist' to the manifest file
|
||||
named by 'self.manifest'.
|
||||
@@ -563,10 +579,10 @@ class manifest_maker(sdist):
|
||||
|
||||
# Now _repairs should encodability, but not unicode
|
||||
files = [self._manifest_normalize(f) for f in self.filelist.files]
|
||||
msg = f"writing manifest file '{self.manifest}'"
|
||||
msg = "writing manifest file '%s'" % self.manifest
|
||||
self.execute(write_file, (self.manifest, files), msg)
|
||||
|
||||
def warn(self, msg) -> None:
|
||||
def warn(self, msg):
|
||||
if not self._should_suppress_warning(msg):
|
||||
sdist.warn(self, msg)
|
||||
|
||||
@@ -577,7 +593,7 @@ class manifest_maker(sdist):
|
||||
"""
|
||||
return re.match(r"standard file .*not found", msg)
|
||||
|
||||
def add_defaults(self) -> None:
|
||||
def add_defaults(self):
|
||||
sdist.add_defaults(self)
|
||||
self.filelist.append(self.template)
|
||||
self.filelist.append(self.manifest)
|
||||
@@ -595,19 +611,21 @@ class manifest_maker(sdist):
|
||||
ei_cmd = self.get_finalized_command('egg_info')
|
||||
self.filelist.graft(ei_cmd.egg_info)
|
||||
|
||||
def add_license_files(self) -> None:
|
||||
def add_license_files(self):
|
||||
license_files = self.distribution.metadata.license_files or []
|
||||
for lf in license_files:
|
||||
log.info("adding license file '%s'", lf)
|
||||
pass
|
||||
self.filelist.extend(license_files)
|
||||
|
||||
def _add_referenced_files(self):
|
||||
"""Add files referenced by the config (e.g. `file:` directive) to filelist"""
|
||||
referenced = getattr(self.distribution, '_referenced_files', [])
|
||||
# ^-- fallback if dist comes from distutils or is a custom class
|
||||
for rf in referenced:
|
||||
log.debug("adding file referenced by config '%s'", rf)
|
||||
self.filelist.extend(referenced)
|
||||
def prune_file_list(self):
|
||||
build = self.get_finalized_command('build')
|
||||
base_dir = self.distribution.get_fullname()
|
||||
self.filelist.prune(build.build_base)
|
||||
self.filelist.prune(base_dir)
|
||||
sep = re.escape(os.sep)
|
||||
self.filelist.exclude_pattern(r'(^|' + sep + r')(RCS|CVS|\.svn)' + sep,
|
||||
is_regex=1)
|
||||
|
||||
def _safe_data_files(self, build_py):
|
||||
"""
|
||||
@@ -622,19 +640,16 @@ class manifest_maker(sdist):
|
||||
if hasattr(build_py, 'get_data_files_without_manifest'):
|
||||
return build_py.get_data_files_without_manifest()
|
||||
|
||||
SetuptoolsDeprecationWarning.emit(
|
||||
"`build_py` command does not inherit from setuptools' `build_py`.",
|
||||
"""
|
||||
Custom 'build_py' does not implement 'get_data_files_without_manifest'.
|
||||
Please extend command classes from setuptools instead of distutils.
|
||||
""",
|
||||
see_url="https://peps.python.org/pep-0632/",
|
||||
# due_date not defined yet, old projects might still do it?
|
||||
warnings.warn(
|
||||
"Custom 'build_py' does not implement "
|
||||
"'get_data_files_without_manifest'.\nPlease extend command classes"
|
||||
" from setuptools instead of distutils.",
|
||||
SetuptoolsDeprecationWarning
|
||||
)
|
||||
return build_py.get_data_files()
|
||||
|
||||
|
||||
def write_file(filename, contents) -> None:
|
||||
def write_file(filename, contents):
|
||||
"""Create a file with the specified name and write 'contents' (a
|
||||
sequence of strings without line terminators) to it.
|
||||
"""
|
||||
@@ -647,7 +662,7 @@ def write_file(filename, contents) -> None:
|
||||
f.write(contents)
|
||||
|
||||
|
||||
def write_pkg_info(cmd, basename, filename) -> None:
|
||||
def write_pkg_info(cmd, basename, filename):
|
||||
log.info("writing %s", filename)
|
||||
if not cmd.dry_run:
|
||||
metadata = cmd.distribution.metadata
|
||||
@@ -666,33 +681,55 @@ def write_pkg_info(cmd, basename, filename) -> None:
|
||||
bdist_egg.write_safety_flag(cmd.egg_info, safe)
|
||||
|
||||
|
||||
def warn_depends_obsolete(cmd, basename, filename) -> None:
|
||||
"""
|
||||
Unused: left to avoid errors when updating (from source) from <= 67.8.
|
||||
Old installations have a .dist-info directory with the entry-point
|
||||
``depends.txt = setuptools.command.egg_info:warn_depends_obsolete``.
|
||||
This may trigger errors when running the first egg_info in build_meta.
|
||||
TODO: Remove this function in a version sufficiently > 68.
|
||||
"""
|
||||
def warn_depends_obsolete(cmd, basename, filename):
|
||||
if os.path.exists(filename):
|
||||
log.warn(
|
||||
"WARNING: 'depends.txt' is not used by setuptools 0.6!\n"
|
||||
"Use the install_requires/extras_require setup() args instead."
|
||||
)
|
||||
|
||||
|
||||
# Export API used in entry_points
|
||||
write_requirements = _requirestxt.write_requirements
|
||||
write_setup_requirements = _requirestxt.write_setup_requirements
|
||||
def _write_requirements(stream, reqs):
|
||||
lines = yield_lines(reqs or ())
|
||||
|
||||
def append_cr(line):
|
||||
return line + '\n'
|
||||
lines = map(append_cr, lines)
|
||||
stream.writelines(lines)
|
||||
|
||||
|
||||
def write_toplevel_names(cmd, basename, filename) -> None:
|
||||
pkgs = dict.fromkeys([
|
||||
k.split('.', 1)[0] for k in cmd.distribution.iter_distribution_names()
|
||||
])
|
||||
def write_requirements(cmd, basename, filename):
|
||||
dist = cmd.distribution
|
||||
data = io.StringIO()
|
||||
_write_requirements(data, dist.install_requires)
|
||||
extras_require = dist.extras_require or {}
|
||||
for extra in sorted(extras_require):
|
||||
data.write('\n[{extra}]\n'.format(**vars()))
|
||||
_write_requirements(data, extras_require[extra])
|
||||
cmd.write_or_delete_file("requirements", filename, data.getvalue())
|
||||
|
||||
|
||||
def write_setup_requirements(cmd, basename, filename):
|
||||
data = io.StringIO()
|
||||
_write_requirements(data, cmd.distribution.setup_requires)
|
||||
cmd.write_or_delete_file("setup-requirements", filename, data.getvalue())
|
||||
|
||||
|
||||
def write_toplevel_names(cmd, basename, filename):
|
||||
pkgs = dict.fromkeys(
|
||||
[
|
||||
k.split('.', 1)[0]
|
||||
for k in cmd.distribution.iter_distribution_names()
|
||||
]
|
||||
)
|
||||
cmd.write_file("top-level names", filename, '\n'.join(sorted(pkgs)) + '\n')
|
||||
|
||||
|
||||
def overwrite_arg(cmd, basename, filename) -> None:
|
||||
def overwrite_arg(cmd, basename, filename):
|
||||
write_arg(cmd, basename, filename, True)
|
||||
|
||||
|
||||
def write_arg(cmd, basename, filename, force: bool = False) -> None:
|
||||
def write_arg(cmd, basename, filename, force=False):
|
||||
argname = os.path.splitext(basename)[0]
|
||||
value = getattr(cmd.distribution, argname, None)
|
||||
if value is not None:
|
||||
@@ -700,20 +737,26 @@ def write_arg(cmd, basename, filename, force: bool = False) -> None:
|
||||
cmd.write_or_delete_file(argname, filename, value, force)
|
||||
|
||||
|
||||
def write_entries(cmd, basename, filename) -> None:
|
||||
def write_entries(cmd, basename, filename):
|
||||
eps = _entry_points.load(cmd.distribution.entry_points)
|
||||
defn = _entry_points.render(eps)
|
||||
cmd.write_or_delete_file('entry points', filename, defn, True)
|
||||
|
||||
|
||||
def _egg_basename(egg_name, egg_version, py_version=None, platform=None):
|
||||
"""Compute filename of the output egg. Private API."""
|
||||
name = _normalization.filename_component(egg_name)
|
||||
version = _normalization.filename_component(egg_version)
|
||||
egg = f"{name}-{version}-py{py_version or PY_MAJOR}"
|
||||
if platform:
|
||||
egg += f"-{platform}"
|
||||
return egg
|
||||
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.", EggInfoDeprecationWarning)
|
||||
if os.path.exists('PKG-INFO'):
|
||||
with io.open('PKG-INFO') as f:
|
||||
for line in f:
|
||||
match = re.match(r"Version:.*-r(\d+)\s*$", line)
|
||||
if match:
|
||||
return int(match.group(1))
|
||||
return 0
|
||||
|
||||
|
||||
class EggInfoDeprecationWarning(SetuptoolsDeprecationWarning):
|
||||
|
||||
Reference in New Issue
Block a user