diff options
| author | Anderson Bravalheri <andersonbravalheri@gmail.com> | 2022-05-19 10:48:10 +0100 |
|---|---|---|
| committer | Anderson Bravalheri <andersonbravalheri@gmail.com> | 2022-06-15 16:43:42 +0100 |
| commit | e36951eb0afaf61a845672d060324ab3e90190d1 (patch) | |
| tree | ee886414c04d6365c360c9d9f5dbda3fb6d34ecd /setuptools/command | |
| parent | 2bddfdffbcb2fc76092d2d6029669f1bb96a742a (diff) | |
| parent | 92ba2c8c4a34f40d480ee35509afc1a58f0a5f7a (diff) | |
| download | python-setuptools-git-e36951eb0afaf61a845672d060324ab3e90190d1.tar.gz | |
Merge branch 'upstream/main' into build-editable-aggregate
Diffstat (limited to 'setuptools/command')
| -rw-r--r-- | setuptools/command/build.py | 24 | ||||
| -rw-r--r-- | setuptools/command/build_py.py | 62 | ||||
| -rw-r--r-- | setuptools/command/dist_info.py | 3 |
3 files changed, 85 insertions, 4 deletions
diff --git a/setuptools/command/build.py b/setuptools/command/build.py new file mode 100644 index 00000000..12a43622 --- /dev/null +++ b/setuptools/command/build.py @@ -0,0 +1,24 @@ +from distutils.command.build import build as _build +import warnings + +from setuptools import SetuptoolsDeprecationWarning + + +_ORIGINAL_SUBCOMMANDS = {"build_py", "build_clib", "build_ext", "build_scripts"} + + +class build(_build): + # copy to avoid sharing the object with parent class + sub_commands = _build.sub_commands[:] + + def run(self): + subcommands = {cmd[0] for cmd in _build.sub_commands} + if subcommands - _ORIGINAL_SUBCOMMANDS: + msg = """ + It seems that you are using `distutils.command.build` to add + new subcommands. Using `distutils` directly is considered deprecated, + please use `setuptools.command.build`. + """ + warnings.warn(msg, SetuptoolsDeprecationWarning) + self.sub_commands = _build.sub_commands + super().run() diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index c3fdc092..2fced3d6 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -1,3 +1,4 @@ +from functools import partial from glob import glob from distutils.util import convert_path import distutils.command.build_py as orig @@ -8,6 +9,9 @@ import io import distutils.errors import itertools import stat +import warnings +from pathlib import Path +from setuptools._deprecation_warning import SetuptoolsDeprecationWarning from setuptools.extern.more_itertools import unique_everseen @@ -98,7 +102,7 @@ class build_py(orig.build_py): package, src_dir, ) - globs_expanded = map(glob, patterns) + globs_expanded = map(partial(glob, recursive=True), patterns) # flatten the expanded globs into an iterable of matches globs_matches = itertools.chain.from_iterable(globs_expanded) glob_files = filter(os.path.isfile, globs_matches) @@ -129,6 +133,7 @@ class build_py(orig.build_py): src_dirs[assert_relative(self.get_package_dir(package))] = package self.run_command('egg_info') + check = _IncludePackageDataAbuse() ei_cmd = self.get_finalized_command('egg_info') for path in ei_cmd.filelist.files: d, f = os.path.split(assert_relative(path)) @@ -139,8 +144,13 @@ class build_py(orig.build_py): d, df = os.path.split(d) f = os.path.join(df, f) if d in src_dirs: - if path.endswith('.py') and f == oldf: - continue # it's a module, not data + if f == oldf: + if check.is_module(f): + continue # it's a module, not data + else: + importable = check.importable_subpackage(src_dirs[d], f) + if importable: + check.warn(importable) mf.setdefault(src_dirs[d], []).append(path) def get_data_files(self): @@ -240,3 +250,49 @@ def assert_relative(path): % path ) raise DistutilsSetupError(msg) + + +class _IncludePackageDataAbuse: + """Inform users that package or module is included as 'data file'""" + + MESSAGE = """\ + Installing {importable!r} as data is deprecated, please list it in `packages`. + !!\n\n + ############################ + # Package would be ignored # + ############################ + Python recognizes {importable!r} as an importable package, + but it is not listed in the `packages` configuration of setuptools. + + {importable!r} has been automatically added to the distribution only + because it may contain data files, but this behavior is likely to change + in future versions of setuptools (and therefore is considered deprecated). + + Please make sure that {importable!r} is included as a package by using + the `packages` configuration field or the proper discovery methods + (for example by using `find_namespace_packages(...)`/`find_namespace:` + instead of `find_packages(...)`/`find:`). + + You can read more about "package discovery" and "data files" on setuptools + documentation page. + \n\n!! + """ + + def __init__(self): + self._already_warned = set() + + def is_module(self, file): + return file.endswith(".py") and file[:-len(".py")].isidentifier() + + def importable_subpackage(self, parent, file): + pkg = Path(file).parent + parts = list(itertools.takewhile(str.isidentifier, pkg.parts)) + if parts: + return ".".join([parent, *parts]) + return None + + def warn(self, importable): + if importable not in self._already_warned: + msg = textwrap.dedent(self.MESSAGE).format(importable=importable) + warnings.warn(msg, SetuptoolsDeprecationWarning, stacklevel=2) + self._already_warned.add(importable) diff --git a/setuptools/command/dist_info.py b/setuptools/command/dist_info.py index 8b8509f3..ca540ad1 100644 --- a/setuptools/command/dist_info.py +++ b/setuptools/command/dist_info.py @@ -54,7 +54,8 @@ def _version(version: str) -> str: try: return str(packaging.version.Version(v)).replace("-", "_") except packaging.version.InvalidVersion: - msg = f"""!!\n\n + msg = f"""Invalid version: {version!r}. + !!\n\n ################### # Invalid version # ################### |
