Python - setuptools Silently Drops a Package Named scripts
A console entry point of mine failed with an error that made no sense, because the package it imports was sitting right there in the project:
ModuleNotFoundError: No module named 'scripts'
Three files reproduce it: an empty scripts/__init__.py, a scripts/seed.py defining main(), and a pyproject.toml.
[project]
name = "repro"
version = "0.1.0"
[build-system]
requires = ["setuptools>=82"]
build-backend = "setuptools.build_meta"
[project.scripts]
repro-seed = "scripts.seed:main"
Installing reports success, and the command it just installed doesn’t run:
$ pip install -e .
Successfully installed repro-0.1.0
$ repro-seed
ModuleNotFoundError: No module named 'scripts'
setuptools’ automatic discovery filtered the package out. Since 61.0.0 setuptools infers your project layout with no configuration, and its flat-layout finder keeps a list of directory names it won’t treat as packages. FlatLayoutPackageFinder._EXCLUDE holds scripts along with tests, docs, tools, examples, benchmarks, tasks, build, and dist, which the docs call reserved names, filtered out because they match conventions for code you don’t distribute.
The exclusion isn’t specific to editable installs or to pip. uv pip install -e . behaves the same, and a plain pip install . builds a wheel holding nothing but dist-info metadata.
import scripts keeps working from the project directory, which puts the current directory on sys.path, so the package imports fine in a shell and under pytest while failing everywhere else, which is the tell.
Declaring the package explicitly overrides discovery:
[tool.setuptools.packages.find]
include = ["scripts*"]
Renaming the directory works too. I went with ops, since a name setuptools reserves is a decent hint not to ship a package called scripts.