summaryrefslogtreecommitdiff
path: root/setuptools/command
diff options
context:
space:
mode:
authorAnderson Bravalheri <andersonbravalheri@gmail.com>2022-05-05 19:34:46 +0100
committerAnderson Bravalheri <andersonbravalheri@gmail.com>2022-05-05 19:34:46 +0100
commit56a8b90551411024f792efe853c48de5e5097e59 (patch)
tree55a03b0be0b74d77f1366b8c588584db96af4701 /setuptools/command
parented5d4bf58c70d5b4ad7b8ad42b27599e6a24be13 (diff)
downloadpython-setuptools-git-56a8b90551411024f792efe853c48de5e5097e59.tar.gz
Warn about packages/modules included as package data
Diffstat (limited to 'setuptools/command')
-rw-r--r--setuptools/command/build_py.py56
1 files changed, 54 insertions, 2 deletions
diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py
index c3fdc092..ba7b7259 100644
--- a/setuptools/command/build_py.py
+++ b/setuptools/command/build_py.py
@@ -8,6 +8,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
@@ -129,6 +132,7 @@ class build_py(orig.build_py):
src_dirs[assert_relative(self.get_package_dir(package))] = package
self.run_command('egg_info')
+ checker = _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 +143,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 checker.is_module(f):
+ continue # it's a module, not data
+ else:
+ importable = checker.importable_item(src_dirs[d], f)
+ if importable:
+ checker.warn(importable)
mf.setdefault(src_dirs[d], []).append(path)
def get_data_files(self):
@@ -240,3 +249,46 @@ def assert_relative(path):
% path
)
raise DistutilsSetupError(msg)
+
+
+class _IncludePackageDataAbuse:
+ """Inform users that package or module is included as 'data file'"""
+
+ MESSAGE = """\
+ !!\n\n
+ ###################################
+ # Package/module would be ignored #
+ ###################################
+ Python recognizes {importable!r} as an importable package or module, however
+ it is included in the distribution as "data".
+ This behavior is likely to change in future versions of setuptools (and
+ therefore is considered deprecated).
+
+ Please make sure that {importable!r} is recognized as a package/module by using
+ setuptools' `packages` configuration field or the proper package discovery methods.
+
+ To find more information, look for "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_item(self, pkg, file):
+ path = Path(file)
+ parents = path.parent.parts
+ module = [path.stem] if tuple(path.suffixes) == (".py",) else []
+ parts = list(itertools.takewhile(str.isidentifier, [*parents, *module]))
+ if parts:
+ return ".".join([pkg, *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)