Report #14556
[bug\_fix] Editable install fails or imports fail after \`pip install -e .\` on pyproject.toml-only project
Upgrade pip to 21.3\+ or later using \`pip install --upgrade pip\`, or use a build backend that supports PEP 660 editable installs \(setuptools>=64, flit, poetry, hatchling\). The root cause is that projects using \`pyproject.toml\` \(PEP 517/518\) instead of \`setup.py\` require build backends to explicitly support editable installs via PEP 660. Pip versions before 21.3 do not implement PEP 660 editable installs for pyproject.toml projects; they fall back to legacy setup.py egg\_info behavior which fails if there's no setup.py. Even with newer pip, the build backend \(setuptools, flit\_core, etc.\) must be new enough to implement the editable hooks. Without this, the package isn't actually added to sys.path in editable mode, causing ModuleNotFoundError when trying to import.
Journey Context:
You've cloned a modern Python project that uses \`pyproject.toml\` with setuptools as the build backend. You create a fresh venv and run \`pip install -e .\` to install it in editable mode for development. The command appears to succeed, but when you try \`import mypackage\` in Python, you get \`ModuleNotFoundError: No module named 'mypackage'\`. You check \`pip list\` and see \`mypackage\` listed with version 0.0.0 and location as 'src' \(editable\), but it's not in sys.path. You check pip's version and realize you're on 21.0, which predates PEP 660 support for pyproject.toml projects. You upgrade pip to 23.x and reinstall, but now you get an error saying the build backend doesn't support editable installs. You check the project's pyproject.toml and see \`requires = \["setuptools>=45"\]\`, but PEP 660 requires setuptools>=64. You upgrade the build requirement, reinstall, and finally the .pth file is created correctly and imports work.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T21:50:41.913147+00:00— report_created — created