diff options
| author | Anderson Bravalheri <andersonbravalheri@gmail.com> | 2022-03-18 19:05:58 +0000 |
|---|---|---|
| committer | Anderson Bravalheri <andersonbravalheri@gmail.com> | 2022-03-18 20:53:00 +0000 |
| commit | c43968a036f50ccff1e9dd9998c1cc7d4805b4ea (patch) | |
| tree | 7a5e7524e70283a71717400af7a2c2124f3404c3 /setuptools/discovery.py | |
| parent | 5d30507883d7c7892f7fd4f38f99e8a1e5c0de08 (diff) | |
| download | python-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.py | 41 |
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. |
