Examples
Real-world dependency conflict scenarios demonstrating depwhy's analysis and fix suggestions.
Scenario 1: requests + urllib3 (Direct Pin Conflict)
A common conflict when pinning both requests and urllib3 to incompatible versions.
Input requirements.txt:
requests==2.28.0
urllib3==2.0.0
Command and output:
$ depwhy requirements.txt1 conflict(s) foundurllib3Problem: requests==2.28.0 requires urllib3>=1.21.1,<1.27, but you have urllib3==2.0.0 pinnedSolution: Remove your pin — use urllib3==1.26.18 (latest compatible)→ pip install urllib3==1.26.18Alternative: Upgrade requests to >=2.29.0 (loosens urllib3 upper bound)→ pip install requests==2.29.0
JSON output with --json:
{
"has_conflicts": true,
"analyzed_packages": 6,
"conflicts": [
{
"package": "urllib3",
"problem": "requests==2.28.0 requires urllib3>=1.21.1,<1.27, but you have urllib3==2.0.0 pinned",
"solution": {
"description": "Remove your pin — use urllib3==1.26.18 (latest compatible)",
"pip_command": "pip install urllib3==1.26.18",
"is_alternative": false
},
"alternative": {
"description": "Upgrade requests to >=2.29.0 (loosens urllib3 upper bound)",
"pip_command": "pip install requests==2.29.0",
"is_alternative": true
}
}
],
"warnings": []
}Scenario 2: ML Stack (numpy/scipy/scikit-learn)
A typical machine learning stack where an older numpy pin conflicts with scikit-learn.
Input requirements.txt:
numpy==1.21.0
scipy==1.10.0
scikit-learn==1.2.0
$ depwhy requirements.txt1 conflict(s) foundnumpyProblem: scikit-learn==1.2.0 requires numpy>=1.22.4, but you have numpy==1.21.0 pinnedSolution: Upgrade numpy to satisfy scikit-learn's constraint→ pip install numpy==1.22.4Alternative: Downgrade scikit-learn to a version compatible with numpy==1.21.0→ pip install scikit-learn==1.1.3
Scenario 3: Django + Celery + Kombu (Three-way Conflict)
A transitive conflict that surfaces through the Celery dependency chain.
Input requirements.txt:
django==4.1
celery==5.2.0
amqp==5.1.0
$ depwhy requirements.txt1 conflict(s) foundamqpProblem: kombu==5.2.4 requires amqp>=5.0.9,<5.1.0, but you have amqp==5.1.0 pinnedSolution: Downgrade amqp to satisfy kombu's constraint→ pip install amqp==5.0.9Alternative: Upgrade celery to >=5.3.0 (uses kombu>=5.3.0 which accepts amqp>=5.1)→ pip install celery==5.3.0
This is a transitive conflict — celery depends on kombu, which constrains amqp.
Scenario 4: Circular Dependencies
Two packages that depend on each other, with a conflict on a shared transitive dependency.
Input requirements.txt:
alpha==1.0.0
beta==1.0.0
$ depwhy requirements.txt1 conflict(s) foundshared-libProblem: alpha==1.0.0 requires shared-lib>=2.0.0,<3.0.0, but beta==1.0.0 requires shared-lib>=1.0.0,<2.0.0 — no version satisfies bothSolution: Upgrade beta to a version that accepts shared-lib>=2.0→ pip install beta==1.1.0Alternative: Downgrade alpha to a version that accepts shared-lib<2.0→ pip install alpha==0.9.0
depwhy handles circular dependencies gracefully — alpha depends on beta and vice versa, but the conflict is on their shared transitive dependency.
Scenario 5: No Conflicts (Clean Baseline)
When all dependencies are compatible, depwhy confirms a clean state.
Input requirements.txt:
flask==3.0.0
jinja2>=3.1.2
$ depwhy requirements.txt✓ No conflicts found
Scenario 6: Environment Marker Conflict (Windows-only)
A conflict that only manifests on a specific platform due to environment markers.
Input requirements.txt:
winapp==1.0.0
desktop-notify==1.0.0
$ depwhy requirements.txt --python-version 3.111 conflict(s) foundpywin32Problem: winapp==1.0.0 requires pywin32>=300,<304, but desktop-notify==1.0.0 requires pywin32>=304 — no version satisfies bothSolution: Upgrade winapp to a version with a looser pywin32 constraint→ pip install winapp==1.1.0Alternative: Downgrade desktop-notify to accept pywin32<304→ pip install desktop-notify==0.8.0
This conflict only appears on Windows. On macOS/Linux, the sys_platform == 'win32' markers exclude these dependencies entirely.