diff --git a/pyproject.toml b/pyproject.toml index 95e707656..bfb24f9c8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,14 @@ +# Installing the project installs its dependencies and nothing else: +# `pip install -e ".[dev]"` gives a contributor every tool the tests use. +# scripts/ and tests/ run from the checkout, so no package is built from them. +[build-system] +requires = ["setuptools>=61"] +build-backend = "setuptools.build_meta" + +[tool.setuptools] +packages = [] +py-modules = [] + [project] name = "retrobios" version = "1.0.0" diff --git a/tests/test_audit_regressions.py b/tests/test_audit_regressions.py index e6f95068d..3b2bfa674 100644 --- a/tests/test_audit_regressions.py +++ b/tests/test_audit_regressions.py @@ -2725,6 +2725,34 @@ class DeclaredDependenciesMatchTheDocumentedWorkflows(unittest.TestCase): ) +class TheProjectInstallsWithPip(unittest.TestCase): + """pyproject declared a dev extra that pip could not install: without a + [build-system] and an explicit module list, setuptools' flat-layout + discovery found scripts/ and tests/ and refused to build.""" + + def test_setuptools_discovers_nothing_to_package(self): + import importlib.util # noqa: PLC0415 + + if importlib.util.find_spec("setuptools") is None: + self.skipTest("setuptools is not installed") + program = ( + "from setuptools.dist import Distribution\n" + "from setuptools.config.pyprojecttoml import apply_configuration\n" + "dist = apply_configuration(Distribution(), 'pyproject.toml')\n" + "dist.set_defaults()\n" + "print(sorted(dist.packages or []), sorted(dist.py_modules or []))\n" + ) + done = subprocess.run([sys.executable, "-c", program], cwd=ROOT, + capture_output=True, text=True, check=False) + self.assertEqual(done.returncode, 0, done.stderr[-2000:]) + self.assertEqual(done.stdout.strip(), "[] []") + import tomllib # noqa: PLC0415 + + with (ROOT / "pyproject.toml").open("rb") as handle: + build = tomllib.load(handle)["build-system"] + self.assertEqual(build["build-backend"], "setuptools.build_meta") + + class ACheckThatCannotAnswerDoesNotPass(unittest.TestCase): """Exiting zero says the question was answered and the answer was yes. diff --git a/wiki/testing-guide.md b/wiki/testing-guide.md index d2c28dbc0..43640fc57 100644 --- a/wiki/testing-guide.md +++ b/wiki/testing-guide.md @@ -39,8 +39,9 @@ tests are reported as skipped, so install them before a pull request (`pip install "jsonschema[format-nongpl]" markdown`). The installer's full-screen tests drive `install.py --tui` on a pseudo-terminal and read the screen back with `pyte`, and fuzz the key decoder with `hypothesis`: both skip -without them (`pip install pyte hypothesis`). No test framework beyond the -standard library `unittest` module. +without them (`pip install pyte hypothesis`). `pip install -e ".[dev]"` from the +checkout installs all of these at once, from the `dev` extra of `pyproject.toml`. +No test framework beyond the standard library `unittest` module. ## Modules at a glance