Detect conflicting directory names across Python's sys.path that shadow installed packages
Project description
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
Project details
Release history Release notifications | RSS feed
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 detect_shadowed_modules-0.2.0.tar.gz.
File metadata
- Download URL: detect_shadowed_modules-0.2.0.tar.gz
- Upload date:
- Size: 6.0 kB
- Tags: Source
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fc2da1821421c570cf532023950701b14baf7aa41bb508c88b1882576af3f7c7
|
|
| MD5 |
114ba4fa6b3a25fa69b9c08538b184ff
|
|
| BLAKE2b-256 |
5cd7a2b3b428a0421668882c1fdee86c98e71fb89b14978ca242a1023ba17c2a
|
File details
Details for the file detect_shadowed_modules-0.2.0-py3-none-any.whl.
File metadata
- Download URL: detect_shadowed_modules-0.2.0-py3-none-any.whl
- Upload date:
- Size: 7.6 kB
- Tags: Python 3
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
323b016577d8b523b9de2ea9d1a32c0ada5992d25410f6600cc8bb38ffa5aa4f
|
|
| MD5 |
528d264dc87a722c4a68952672bbbfb4
|
|
| BLAKE2b-256 |
73fe68534d512a772e67970262a85738421603422f27346a3ed8b4b78b39bc02
|