Open this lesson in your favourite AI. It'll walk you through the why, explain the demo, and quiz you on the try-it list.
Python's import system is the single most-asked source of confusion. from mypkg import x works locally but not in CI; python -m mypkg works but python mypkg/__main__.py fails. The reason: sys.path is a list of directories Python searches for packages, and the rules for what's on sys.path differ between python script.py and python -m mypkg. Knowing this saves you from the classic 'works on my machine' Python failure mode.
When Python executes import mypkg, it walks sys.path in order — a list of directory strings — and returns the first match. What goes on sys.path depends critically on how the interpreter was launched: running python script.py prepends the script's directory, while python -m mypkg prepends the current working directory, which means the same import mypkg statement can succeed or fail depending purely on invocation style. An editable install (pip install -e .) adds your project root to site-packages via a .pth file, making imports work identically regardless of where you run from — which is why editable mode is the correct development pattern for any project that's also a package.
src/ directory). Try running cli.py three ways: directly, with -m, and after editable install. Note which works.print(__name__) at module top. Note when it prints __main__ vs mypkg.cli — that's the source of the if __name__ == "__main__" idiom.from . import other) and run with both python and python -m. The script form fails with ImportError.python -c "import sys; print('\n'.join(sys.path))". Memorize the order: script dir / cwd, PYTHONPATH, site-packages.Use these three in order. Each builds on the one before.
In one paragraph, explain the difference between `python script.py` and `python -m package.module` — and why one works and the other often doesn't.
Walk me through how Python builds `sys.path` at startup, and the order it searches. Where does PYTHONPATH fit, and what about site-packages?
I'm getting a confusing 'cannot import name' error in production but not in dev. Give me a systematic debugging playbook — `python -v`, `pip show`, `find . -name __init__.py`, namespace packages.
# project layout:
# myproj/
# src/
# mypkg/
# __init__.py
# cli.py
# pyproject.toml
# inside cli.py:
import sys
print("sys.path:", sys.path)
# 1) running as script (BAD — not what you want):
$ cd myproj/src/mypkg && python cli.py
sys.path: ['/.../myproj/src/mypkg', ...]
# note: the SCRIPT DIR is on sys.path. Sibling files import-able by name.
# 2) running as module (GOOD):
$ cd myproj && python -m mypkg.cli
sys.path: ['/.../myproj', ...]
# note: CWD is on sys.path. Imports use the package layout.
# 3) editable install (BEST for dev):
$ uv pip install -e .
$ python -m mypkg.cli # works from anywherepython3 main.py