Scan and repair venv/virtualenv/conda/mamba/micromamba/miniforge environments with mixed conda/pip installs.
Project description
🩺 EnvRepair 
Fixing broken Python environments – safely, transparently, reproducibly
EnvRepair is a practical repair tool for the messy reality of Python environments:
Conda / Mamba / Micromamba mixed with pip, plus plain venv / virtualenv.
Instead of starting over (again), EnvRepair helps you understand what’s broken, why it’s broken, and fix it safely – with snapshots and rollback support, so you’re never locked in.
🤕 Why EnvRepair Exists
If you’ve ever seen things like:
- duplicate
.dist-infofolders - mysterious
.pydconflicts on Windows conda-metaJSON files that suddenly break tools like PyInstaller- environments that are “inconsistent” but still half-working
- pip + conda silently stepping on each other’s toes
…then EnvRepair is for you.
It doesn’t try to replace conda or pip.
It steps in after things already went wrong.
✨ What EnvRepair Can Do
🔍 Diagnose
- Detect duplicates and leftovers (
.dist-info, stale artifacts, some Windows.pydduplicates). - Find corrupted or incomplete
conda-metaentries. - Detect pip/conda case-sensitivity conflicts.
🛠️ Repair (carefully!)
- Repair mixed conda + pip installs using the right tool.
- Reinstall broken packages with source awareness.
- “Adopt” pip packages into conda where possible (
--adopt-pip). - Handle plain venv / virtualenv setups (pip-only mode).
🛟 Safety First
- Automatic rescue snapshots before any destructive action.
- Graceful recovery after
Ctrl+C. - Clear prompts instead of silent force-fixes.
🧰 Requirements
- Windows, Linux, or macOS.
mambain PATH for conda-style envs (preferred).conda/micromambaare supported when available.condais optional: mamba-only installs (e.g. Mambaforge/Miniforge variants) are supported.- Python available in the target environment.
🚀 Quick Start
All examples below use Windows
cmd.exesyntax (.batblocks).
Adjust paths/shells as needed for Linux/macOS.
Recommended first run (one-shot):
env-repair one-shot --env base -y
Basic scan (auto-discovers conda envs):
python env_repair.py
Install as a CLI (editable):
pip install -e .
env-repair --help
Install from local checkout (non-editable):
pip install .
🔁 Common Workflows
One-shot repair flow (recommended):
env-repair one-shot --env base -y
Fix base:
python env_repair.py --env base --fix
Fix a plain venv (pip-only):
python env_repair.py --env .venv --fix
Same via installed CLI:
env-repair --env base --fix
Adopt pip packages into conda (where possible):
python env_repair.py --env base --fix --adopt-pip
Verify imports (and fix what can be fixed):
python env_repair.py verify-imports --env base --full --fix
⏪ Rollback & Rebuild
Rollback to previous conda revision:
env-repair rollback --env base --to prev
Rollback without prompt:
env-repair rollback --env base --to prev -y
Rebuild into a new env (name):
env-repair rebuild --env base --to base-rebuilt --verify
Rebuild into a new env (path):
env-repair rebuild --env base --to C:\temp\base-rebuilt --verify
🧪 Advanced Diagnostics
Diagnose a ClobberError from a logfile:
env-repair diagnose-clobber --env base --logfile clobber.txt
Diagnose / fix “inconsistent” env:
env-repair diagnose-inconsistent --env base
env-repair fix-inconsistent --env base --level safe
Cache check / fix:
env-repair cache-check
env-repair cache-fix --level safe
SSL diagnosis:
env-repair diagnose-ssl --base
env-repair diagnose-ssl --env base
Create a conda-style snapshot (YAML):
python env_repair.py --env base --snapshot snapshots\base.yaml
Debug output:
python env_repair.py --env base --fix --adopt-pip --debug
🛟 Safety Net (Ctrl+C / Rescue)
- When you run with
--fix, EnvRepair creates a rescue snapshot under:.env_repair\snapshots\... - If you abort during a pip/mamba/conda step, EnvRepair will prompt:
rrestore from snapshotccontinue (skip)aabort (default)
- A
.env_repair\state.jsonfile records progress so you can inspect what happened and re-run later.
🔎 Import Verification (verify-imports)
EnvRepair can scan installed distributions and run python -c "import <name>" for their top-level modules.
Full scan + auto-fix (recommended when an env is “mostly working but randomly broken”):
python env_repair.py verify-imports --env base --full --fix --debug
Both --env placements are supported:
env-repair --env base verify-imports --full --fix
env-repair verify-imports --env base --full --fix
If you want the full sequence in one command (fix-inconsistent + scan/fix + verify-imports --fix):
env-repair one-shot --env base -y
Notes:
- Repairs use batched conda/mamba operations (no slow one-by-one reinstalls).
- If the solver fails for a specific package, EnvRepair retries the batch without the offending spec and remembers it in:
.env_repair\verify_imports_blacklist.json
- Platform-only modules are skipped (e.g.
shon Windows,ptyprocessmissingfcntlon Windows). - Import timeouts are reported separately (
[TIMEOUT]) and are not treated as hard failures in fix planning. - For local/manual installs from
direct_url=file://..., EnvRepair now probes conda/mamba search first; only packages without a conda candidate are skipped.
🧑💻 Development
Run tests:
python -m unittest discover -s tests -p "test_*.py"
Run integration tests (non-interactive):
python itest\scripts\run_itest.py --list
python itest\scripts\run_itest.py --scenario S01_DUP_DIST_INFO --summarize
JSON output:
python env_repair.py --env base --json
Release helper (patch bump in pyproject.toml):
python release.py
python release.py --sync
Sync conda recipe metadata from project version:
python tools\sync_versions.py
python tools\sync_versions.py --pypi-sdist --staged-recipes staged-recipes
📝 Notes
--adopt-pipinstalls only mapped PyPI packages.--adopt-pipis conda-only; for plain venvs it is ignored.- After successful adoption, env-repair uninstalls the pip version by default; use
--keep-pipto skip. - For alias-like mappings (e.g. pip
msgpack→ condamsgpack-python), pip is only removed if both versions match. - Channels are loaded from
.condarcfirst, thendefaultsandanacondaunless disabled. --debugprints the exact external command lines as[cmd] ...(mamba/conda/pip), and streams live output to keep long operations transparent.- If
condacore is broken after updates, env-repair can auto-repair it in two stages: core packages first, thenpython/menuinstwhen health remains degraded or mixed ABI.pydresidue is detected. - For automated runs (CI/itest), set
ENV_REPAIR_AUTO_YES=1to bypass interactive confirmation prompts. - On Windows,
duplicate-pydissues from mixed Python ABI residues are now cleaned directly by removing stale.pydfiles that do not match the active ABI tag.
Mini Troubleshooting
| Signal in output | Meaning | Recommended next step |
|---|---|---|
skip [installed from local file/path (direct_url=file://...)] |
Package was installed from a local/custom artifact and no conda candidate was found via search. | Keep as-is or reinstall manually from your local source if needed. |
[TIMEOUT] ... |
Import check exceeded the timeout window for this run. | Re-run verify-imports; timeout entries are informational and not auto-repair targets. |
skip [blacklisted for python X.Y ...] |
Previous solver run marked this package as incompatible for this Python version/channel set. | Re-run after channel/version changes, or remove the entry from .env_repair\verify_imports_blacklist.json to retry once. |
Solver hit pinned-python conflict; retrying without --force-reinstall... |
--force-reinstall could not satisfy pinned Python constraints. |
Usually safe to continue; env-repair already retries with upgrade-friendly solver behavior. |
Post-fix: all non-skipped imports OK. |
Automatic repair succeeded for everything that is auto-fixable. | Review skipped imports; handle only those manually if they matter for your workload. |
verify-imports auto-repair hints
- Missing private runtime modules are now mapped to the correct conda providers before regular fix planning:
_brotli->brotli-python_argon2_cffi_bindings->argon2-cffi-bindingspkg_resources->setuptools
- For Streamlit protobuf runtime/codegen mismatch (
_CheckCalledFromGeneratedFile), EnvRepair now schedules:protobuf>=4,<7alignmentstreamlit>=1.30upgrade/relink
- If
imblearnfails withfrom sklearn.base import clone, EnvRepair relinks the sklearn stack (numpy,scipy,scikit-learn) before relinkingimbalanced-learn. - If
sklearnstill fails in the same chain, EnvRepair also relinksnumpy+scipy+scikit-learn. - If
pyarrowreports DLL/procedure mismatch, EnvRepair relinkslibarrow+pyarrow. - If
pygithubfails in its import chain, EnvRepair relinksrequests+pynacl+pygithub. pkg_resourcesis treated as legacy and skipped to avoid pip/conda thrash loops.- For stubborn compiled/import-chain packages (
pyarrow,scikit-learn,imbalanced-learn,pygithub,streamlit), EnvRepair now performs a targeted pre-clean of stale site-packages artifacts before conda relink. - If
pyarrow,github, orstreamlitstill fail after conda repair, EnvRepair runs a last-chance pip wheel reinstall for exactly those imports and rechecks immediately. - For
pygithub, EnvRepair now performs a hard conda remove before reinstall when needed, to recover from partial module-tree loss (No module named 'github'). - For
pygithubfailures involvingnacl._sodiumDLL load issues, EnvRepair additionally relinkslibsodium+pynaclin the same repair batch. - Solver offender parsing accepts more libmamba output variants (
name =* * does not existandname ==x ... does not exist) to avoid false negatives in blacklist/retry logic.
📁 Files
env_repair.py– CLI shim (kept for convenience).env_repair/– actual implementation.docs/– design notes, feature specs, and roadmaps.
📦 Releases
PyPI releases are automated via GitHub Actions (Trusted Publishing) on tags:
vX.Y.Z→.github/workflows/release-pypi.yml
conda-forge publishing is done via a feedstock (standard conda-forge process). For details see:
docs/releasing.md
Local conda recipe (for testing) lives in:
conda.recipe/
❤️ Philosophy
EnvRepair is opinionated, but cautious.
It prefers understanding and repair over brute-force reinstallation.
If you’ve ever said “I’ll just recreate the environment…”
EnvRepair is here to save you that hour.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file env_repair-0.2.6.tar.gz.
File metadata
- Download URL: env_repair-0.2.6.tar.gz
- Upload date:
- Size: 71.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e09f536fbb3b250e1e12e3555ef2df1b0181f6efca57e654a1e13df50d40839f
|
|
| MD5 |
9b4a8751ecab738f992c6f67836f4ddd
|
|
| BLAKE2b-256 |
84c5e6363fe2f42d9fb35ffea08391c656b12551118089b204ac774dd99622b2
|
Provenance
The following attestation bundles were made for env_repair-0.2.6.tar.gz:
Publisher:
release-pypi.yml on noragen/env-repair
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
env_repair-0.2.6.tar.gz -
Subject digest:
e09f536fbb3b250e1e12e3555ef2df1b0181f6efca57e654a1e13df50d40839f - Sigstore transparency entry: 1005374847
- Sigstore integration time:
-
Permalink:
noragen/env-repair@a5766bc5a96d954c22b4832fa87568ea92e87683 -
Branch / Tag:
refs/tags/v0.2.6 - Owner: https://github.com/noragen
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@a5766bc5a96d954c22b4832fa87568ea92e87683 -
Trigger Event:
push
-
Statement type:
File details
Details for the file env_repair-0.2.6-py3-none-any.whl.
File metadata
- Download URL: env_repair-0.2.6-py3-none-any.whl
- Upload date:
- Size: 62.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0824ae985cb69931cae789762ada6aa82a54bbbb32cf1f38265636ad462b0282
|
|
| MD5 |
dd75326d4f1f7ba1dc37d7068065991c
|
|
| BLAKE2b-256 |
9e30afbfb4df525462a67f900c76e644bcf2257f9cb844f7ecb56717e7dc1e23
|
Provenance
The following attestation bundles were made for env_repair-0.2.6-py3-none-any.whl:
Publisher:
release-pypi.yml on noragen/env-repair
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
env_repair-0.2.6-py3-none-any.whl -
Subject digest:
0824ae985cb69931cae789762ada6aa82a54bbbb32cf1f38265636ad462b0282 - Sigstore transparency entry: 1005374848
- Sigstore integration time:
-
Permalink:
noragen/env-repair@a5766bc5a96d954c22b4832fa87568ea92e87683 -
Branch / Tag:
refs/tags/v0.2.6 - Owner: https://github.com/noragen
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@a5766bc5a96d954c22b4832fa87568ea92e87683 -
Trigger Event:
push
-
Statement type: