summaryrefslogtreecommitdiff
path: root/setuptools/discovery.py
diff options
context:
space:
mode:
authorAnderson Bravalheri <andersonbravalheri@gmail.com>2022-03-18 19:05:58 +0000
committerAnderson Bravalheri <andersonbravalheri@gmail.com>2022-03-18 20:53:00 +0000
commitc43968a036f50ccff1e9dd9998c1cc7d4805b4ea (patch)
tree7a5e7524e70283a71717400af7a2c2124f3404c3 /setuptools/discovery.py
parent5d30507883d7c7892f7fd4f38f99e8a1e5c0de08 (diff)
downloadpython-setuptools-git-c43968a036f50ccff1e9dd9998c1cc7d4805b4ea.tar.gz
Prevent accidental multi-package dist with auto-discovery
As discussed in https://discuss.python.org/t/help-testing-experimental-features-in-setuptools/13821/41 automatically scanning all the directories might be very error-prone. One way of avoiding that is to error when multiple top-level packages are automatically discovered.
Diffstat (limited to 'setuptools/discovery.py')
-rw-r--r--setuptools/discovery.py41
1 files changed, 38 insertions, 3 deletions
diff --git a/setuptools/discovery.py b/setuptools/discovery.py
index e0c406e3..ae1dc165 100644
--- a/setuptools/discovery.py
+++ b/setuptools/discovery.py
@@ -336,18 +336,53 @@ class ConfigDiscovery:
if not os.path.isdir(src_dir):
return False
+ log.debug(f"`src-layout` detected -- analysing {src_dir}")
package_dir.setdefault("", os.path.basename(src_dir))
self.dist.packages = PEP420PackageFinder.find(src_dir)
self.dist.py_modules = ModuleFinder.find(src_dir)
- log.debug(f"`src-layout` detected -- analysing {src_dir}")
+ log.debug(f"discovered packages -- {self.dist.packages}")
+ log.debug(f"discovered py_modules -- {self.dist.py_modules}")
return True
def _analyse_flat_layout(self):
"""Try to find all packages and modules under the project root"""
+ log.debug(f"`flat-layout` detected -- analysing {self._root_dir}")
+ return self._analyse_flat_packages() or self._analyse_flat_modules()
+
+ def _analyse_flat_packages(self):
self.dist.packages = FlatLayoutPackageFinder.find(self._root_dir)
+ top_level = remove_nested_packages(remove_stubs(self.dist.packages))
+ log.debug(f"discovered packages -- {self.dist.packages}")
+ self._ensure_no_accidental_inclusion(top_level, "packages")
+ return bool(top_level)
+
+ def _analyse_flat_modules(self):
self.dist.py_modules = FlatLayoutModuleFinder.find(self._root_dir)
- log.debug(f"`flat-layout` detected -- analysing {self._root_dir}")
- return True
+ log.debug(f"discovered py_modules -- {self.dist.py_modules}")
+ self._ensure_no_accidental_inclusion(self.dist.py_modules, "modules")
+ return bool(self.dist.py_modules)
+
+ def _ensure_no_accidental_inclusion(self, detected: List[str], kind: str):
+ if len(detected) > 1:
+ from inspect import cleandoc
+ from setuptools.errors import PackageDiscoveryError
+
+ msg = f"""Multiple top-level {kind} discovered in a flat-layout: {detected}.
+
+ To avoid accidental inclusion of unwanted files or directories,
+ setuptools will not proceed with this build.
+
+ If you are trying to create a single distribution with multiple {kind}
+ on purpose, you should not rely on automatic discovery.
+ Instead, consider the following options:
+
+ 1. set up custom discovery (`find` directive with `include` or `exclude`)
+ 2. use a `src-layout`
+ 3. explicitly set `py_modules` or `packages` with a list of names
+
+ To find more information, look for "package discovery" on setuptools docs.
+ """
+ raise PackageDiscoveryError(cleandoc(msg))
def analyse_name(self):
"""The packages/modules are the essential contribution of the author.