User Safety: safe

Summary

pip install -e . installs the local source tree of a project in editable (a.k.a. develop) mode.
It tells pip to:

  • Read the pyproject.toml/setup.cfg/setup.py in the current directory.
  • Build a wheel in a temporary location.
  • Add a .pth entry (or an egg-link) so that the interpreter imports the package directly from the source directory.

The result is not a regular “download‑and‑install” of a pre‑built wheel; it is a live link to the source code.

Root Cause

Editable installs rely on setuptools’ develop mode:

  • pip invokes setup.py develop (or the equivalent PEP 517 hook) which creates an egg‑link file pointing to the project folder.
  • The package’s __init__ is loaded from the working directory, so any changes to the source are immediately reflected without reinstalling.

Without the -e flag pip would copy the built files into the environment, breaking the live‑link behavior.

Why This Happens in Real Systems

  • Rapid iteration – developers need to test changes without rebuilding wheels each time.
  • Monorepos / multi‑module projects – several local packages can be linked together while still being resolved as normal dependencies.
  • Legacy tooling – many older projects still use setup.py develop because the alternative (editable pyproject.toml support) arrived later.

Real-World Impact

  • Pros
    • Immediate feedback loop for developers.
    • No need to reinstall after every code change.
  • Cons
    • Editable installs can hide version‑drift problems that appear in production (where the code is frozen in a wheel).
    • They write files outside the virtual environment (.pth/egg-link), which may confuse debugging tools.
    • Offline builds become harder because the source tree is required at runtime.

Example or Code (if necessary and relevant)

# Editable install from a local checkout
pip install -e .

# Editable install directly from a Git URL (no manual clone needed)
pip install -e git+https://github.com/user/repo.git#egg=repo

How Senior Engineers Fix It

  • Prefer non‑editable builds for reproducibility:
    pip wheel . -w dist/          # Build a wheel once
    pip install --no-index --find-links=dist/ repo_name
  • Generate a lock file (pip freeze > requirements.txt or use pip-tools, uv, poetry) after the editable install, then install from that file on offline machines.
  • Use PEP 660 editable wheels (supported by modern pip) when editable mode is necessary: ensure pyproject.toml declares editable = true under [project] or use pip install -e . with a recent pip (>=22.0).
  • Avoid the cache for offline packaging: pip download -r requirements.txt --dest wheels/ followed by pip install --no-index --find-links wheels/ -r requirements.txt.

Why Juniors Miss It

  • They assume pip install -e . simply “installs the repo” like a normal wheel, overlooking the link‑only nature of the operation.
  • They often forget that editable installs do not freeze dependencies; the generated lock file still points to the live environment’s resolver.
  • Lack of familiarity with the PEP 517/518 build backend flow leads them to treat pyproject.toml as a plain requirements list, missing the need to invoke the build system (setuptools, flit, poetry, …).

Key takeaways

  • -e creates a live link to the source, not a detached wheel.
  • For offline or reproducible builds, build wheels once and install from a local directory or a requirements lock file.
  • Modern pip supports PEP 660 editable wheels; use them instead of the legacy setup.py develop when possible.

Leave a Comment