Skip to content

Python .gitignore

Generate a Python .gitignore — covers __pycache__, .pyc files, virtual environments (venv, .venv, env), pytest cache, mypy cache, ruff cache, build artifacts, and .python-version. VS Code, macOS, and Windows files preselected.

A ready-to-use Python .gitignore. Excludes __pycache__/, *.pyc, virtual environments (venv/, .venv/), pytest/mypy/ruff caches, build artifacts (dist/, *.egg-info/), and .python-version. Tick more boxes if your repo also uses Java, Node, or other tools.

Languages

Operating systems

Editors

Tools

Pick at least one template

Download
 

A Python project’s .gitignore covers a few categories of files Git should never track: compiled bytecode, virtual environments, packaging artifacts, test caches, and tooling output. The list above is a known-good set; this page explains each entry.

Compiled bytecode

__pycache__/
*.py[cod]
*$py.class

When Python imports a module, it compiles .py to .pyc bytecode and caches it. The __pycache__ directory holds these caches. They’re regenerated automatically and are tied to the specific Python interpreter version — committing them is pure noise.

The [cod] is a glob character class that matches .pyc, .pyo (older optimized bytecode), or .pyd (Windows compiled extensions on some Python versions).

Virtual environments

.venv/
venv/
env/
ENV/

A virtual environment is a directory containing a Python interpreter and an isolated set of installed packages. It’s huge (tens of MB to gigabytes), platform-specific (Windows vs Linux paths inside differ), and reproducible from requirements.txt or pyproject.toml — no reason to commit.

.venv/ is the most common modern name (PEP 405 implicit, used by VS Code’s Python extension by default). venv/ and env/ are common older conventions. List several in the ignore file because no project-wide convention has fully won.

Distribution and build artifacts

build/
dist/
*.egg-info/
*.egg
.eggs/

Generated by python setup.py build, python setup.py sdist, python -m build, and pip’s local builds. They contain metadata and tarballs derived from your source — recomputable, never edited by hand.

*.egg-info/ is the common gotcha. After running pip install -e . (editable install), you get your_package.egg-info/ in your working tree. Don’t commit it.

Test and lint caches

.pytest_cache/
.mypy_cache/
.ruff_cache/
.coverage
htmlcov/
.tox/
.nox/

Each Python tool has a cache directory:

  • pytest caches collection state in .pytest_cache/ for faster reruns.
  • mypy caches type-check results.
  • ruff caches lint results.
  • coverage writes .coverage (binary) and htmlcov/ (HTML report).
  • tox and nox create per-environment dirs.

All regenerable, all platform-specific.

Jupyter notebooks

.ipynb_checkpoints/

Jupyter writes auto-saved versions of notebooks here. Generated automatically; never useful to commit.

For the notebook files themselves (*.ipynb), the convention is project-dependent. Some teams commit notebooks (data-science workflows); some don’t (regular software projects); some commit them after stripping outputs (using nbstripout or similar).

Environment files

.env
.env.local
.env.*.local

Project-level .env files often hold secrets — database URLs with passwords, API keys, etc. Never commit. Provide a .env.example that documents which variables are needed (no secret values) and commit that instead.

IDE and OS files

.idea/
.vscode/
.DS_Store
Thumbs.db
*.swp

Same as the general gitignore generator page — these are independent of Python.

Modern Python tooling

Newer tools may add their own cache directories:

.pdm-python
.python-version          # if using pyenv-virtualenv
__pypackages__/          # PEP 582 (rare)
.poetry/
poetry.lock              # contentious — see below

poetry.lock is the lockfile equivalent of requirements.txt. Do commit it for applications (you want reproducibility); don’t commit it for libraries you’re publishing (downstream applications need to resolve their own constraints). Same rule as Cargo.lock for Rust.

Common pitfalls

  • Ignoring *.py. Don’t. That’s your source code.
  • Forgetting .env. The single most common cause of leaked credentials in Python projects. Add .env to .gitignore before the first commit.
  • Committing __pycache__ once and not realizing it. Once tracked, .gitignore doesn’t untrack. Run git rm -rf --cached __pycache__ then commit.
  • Ignoring *.egg-info but committing it once. Same problem; same fix.
  • Forgetting platform-specific virtual env paths. A .venv on Linux and a .venv on Windows have different binary contents but the same directory name; one ignore pattern covers both.
  • Forgetting pyvenv.cfg when ignoring venv — it lives at the venv root and matches venv/pyvenv.cfg, which the directory-level ignore covers, but standalone pyvenv.cfg files outside a venv directory don’t get ignored.

For other stacks, see Node.js, Java, Go, Rust, .NET, Ruby, or the general .gitignore generator.