Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Python editable installation: source changes and metadata changes have different lifetimes

Last updated: 30 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

An editable installation connects an installed distribution to its working source so supported source changes can be observed without building a release wheel each time.

Download Python source kit

Operation contract

The fixture creates a fresh temporary installation target using the already tested build backend, installs one owned package in editable mode offline, and imports it in a fresh process. It edits the source and imports again in another fresh process. The changed result proves the source connection without pretending that an already imported module would automatically reload.

Failure and ownership boundary

The build uses the already recorded backend environment, so this is not a clean dependency-resolution test. New package files, entry points, metadata or compiled extensions may require rebuilding/reinstalling. Imported modules remain cached in a running process. The target is explicitly processed with site.addsitedir in the child to activate its editable import hooks; it is deleted with its owned temporary directory. The project environment is not modified. Python wheel installation: test the built artifact outside its source directory and Python import failures: module removal does not roll back every side effect cover other boundaries.

Tested environment

Dependency check: this program was executed on CPython 3.14.6 with setuptools==84.0.0, pip==26.1.2. Install these versions in a separate virtual environment. The download includes the recorded environment snapshot; no third-party package is part of the website runtime.

Working program

python
from pathlib import Path
import subprocess
import sys
import tempfile

with tempfile.TemporaryDirectory() as directory:
    owned = Path(directory); project = owned / "project"; target = owned / "installed"
    package = project / "src" / "aitrove_editable_receipt"; package.mkdir(parents=True)
    module = package / "__init__.py"
    module.write_text('def fee():\n    return 25\n', encoding="utf-8")
    (project / "pyproject.toml").write_text('[build-system]\nrequires = ["setuptools==84.0.0"]\nbuild-backend = "setuptools.build_meta"\n[project]\nname = "aitrove-editable-receipt"\nversion = "0.1.0"\n[tool.setuptools.packages.find]\nwhere = ["src"]\n', encoding="utf-8")
    subprocess.run([sys.executable, "-I", "-m", "pip", "install", "--no-index", "--no-deps", "--no-build-isolation", "--no-cache-dir", "--disable-pip-version-check", "--target", str(target), "-e", str(project)], check=True, capture_output=True, text=True, timeout=20)
    def installed_fee():
        result = subprocess.run([sys.executable, "-I", "-B", "-c", 'import site,sys; site.addsitedir(sys.argv[1]); import aitrove_editable_receipt; print(aitrove_editable_receipt.fee())', str(target)], cwd=owned, check=True, capture_output=True, text=True, timeout=5)
        return result.stdout.strip()
    print("first process:", installed_fee())
    module.write_text('def fee():\n    return 125\n', encoding="utf-8")
    print("fresh process after edit:", installed_fee())

Output

Output
first process: 25
fresh process after edit: 125

Costs and limits

The backend determines editable installation machinery and cost. Fresh process imports avoid stale module objects; the changed source size and disabled bytecode writes keep this fixture independent of timestamp-based bytecode reuse. This is one tested backend, not a guarantee for every build system.

Common Mistakes

  • Source editing does not automatically update a previously imported module object.
  • Editable development behavior does not prove release-wheel contents.

Connected lessons

Python wheel installation: test the built artifact outside its source directory, Python pyproject.toml: build a wheel and inspect its metadata, Python import failures: module removal does not roll back every side effect.

python
editable-installation
Storage details