detect-shadowed-modules
Detect conflicting directory names across Python's sys.path that may be shadowing your installed packages.
Problem
When Python imports a module, it searches directories in sys.path order. If the same directory name exists in multiple sys.path entries, only the first one is used—potentially shadowing packages you intended to import. This can lead to confusing import errors and unexpected behavior.
Example Conflict Scenario
sys.path = ['/project', '/usr/lib/python3/site-packages']
If both paths contain a requests/ directory:
/project/requests/← This shadows the real package/usr/lib/python3/site-packages/requests/
When you import requests, Python will use /project/requests/ instead of the installed package, which is likely not what you want!
Installation
uv add detect-shadowed-modules
Or, you can just use via uvx:
uvx detect-shadowed-modules@latest --help
Usage
Command Line
# Print conflicts to stdout with scanning progress
detect-shadowed-modules
# Quiet mode (conflicts only, no progress messages)
detect-shadowed-modules -q
# Output as JSON
detect-shadowed-modules --json
As a Python Module
import detect_shadowed_modules
# Find conflicts
conflicts = detect_shadowed_modules.find_conflicts()
# Generate a human-readable report
report = detect_shadowed_modules.format_report(conflicts)
print(report)
# Or get JSON output
json_output = detect_shadowed_modules.format_json(conflicts)
print(json_output)
Output Examples
Human-Readable Format
Conflicting directory names detected:
These directories exist in multiple sys.path locations. The first
location listed will shadow the others during import.
requests/
→ /home/user/myproject/requests (shadows others)
/usr/lib/python3/site-packages/requests [requests] (shadowed)
Searched directories (50 total):
/home/user/myproject [editable]
/home/user/.venv/lib/python3.13/site-packages
/usr/lib/python3/site-packages
...
JSON Format
{
"shadowed": [
{
"path": "/usr/lib/python3/site-packages/requests",
"shadowed_by": "/home/user/myproject/requests",
"owner": "requests"
}
],
"searched_paths": [
{
"path": "/home/user/myproject",
"editable": true
},
{
"path": "/home/user/.venv/lib/python3.13/site-packages",
"editable": false
},
{
"path": "/usr/lib/python3/site-packages",
"editable": false
}
]
}
How It Works
The tool scans all directories in sys.path and:
- Automatically detects editable packages installed via
uv(usinguv pip list -e) - Combines editable package paths with
sys.path(editable paths take precedence) - Identifies subdirectories in each path
- Detects when the same directory name appears in multiple locations
- Reports which packages are being shadowed and by what
- Attempts to identify the installed package that owns each directory
Excluded from scanning:
- Hidden directories (starting with
.) __pycache__directories- Package metadata directories (
.dist-info,.egg-info)
Debugging Import Issues
If you suspect a module is being imported from the wrong location, you can check where Python is actually loading it from:
python -c 'import <module>; print(<module>.__file__)'
For example:
python -c 'import requests; print(requests.__file__)'
# Output: /home/user/myproject/requests/__init__.py
This will show you the exact file path Python is using for the import, helping you confirm if shadowing is occurring.
Exit Codes
0: No conflicts found1: Conflicts detected
This makes it easy to use in CI/CD pipelines or pre-commit hooks.
MIT License
Metadata
Release files for detect-shadowed-modules 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| detect_shadowed_modules-0.2.0.tar.gz | 6.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| detect_shadowed_modules-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 13.6 kB
Release files / detect_shadowed_modules-0.2.0.tar.gz
| Download URL | detect_shadowed_modules-0.2.0.tar.gz |
|---|---|
| Size | 6.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fc2da1821421c570cf532023950701b14baf7aa41bb508c88b1882576af3f7c7
|
|
BLAKE2b-256 checksum How to use checksums |
5cd7a2b3b428a0421668882c1fdee86c98e71fb89b14978ca242a1023ba17c2a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / detect_shadowed_modules-0.2.0-py3-none-any.whl
| Download URL | detect_shadowed_modules-0.2.0-py3-none-any.whl |
|---|---|
| Size | 7.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
323b016577d8b523b9de2ea9d1a32c0ada5992d25410f6600cc8bb38ffa5aa4f
|
|
BLAKE2b-256 checksum How to use checksums |
73fe68534d512a772e67970262a85738421603422f27346a3ed8b4b78b39bc02
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for detect-shadowed-modules 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.