mirror of
https://github.com/Comfy-Org/ComfyUI-Manager.git
synced 2025-12-16 18:02:58 +08:00
Add comprehensive pip dependency conflict resolution framework as draft implementation. This is self-contained and does not affect existing ComfyUI Manager functionality. Key components: - pip_util.py with PipBatch class for policy-driven package management - Lazy-loaded policy system supporting base + user overrides - Multi-stage policy execution (uninstall → apply_first_match → apply_all_matches → restore) - Conditional policies based on platform, installed packages, and ComfyUI version - Comprehensive test suite covering edge cases, workflows, and platform scenarios - Design and implementation documentation Policy capabilities (draft): - Package replacement (e.g., PIL → Pillow, opencv-python → opencv-contrib-python) - Version pinning to prevent dependency conflicts - Dependency protection during installations - Platform-specific handling (Linux/Windows, GPU detection) - Pre-removal and post-restoration workflows Testing infrastructure: - Pytest-based test suite with isolated environments - Dependency analysis tools for conflict detection - Coverage for policy priority, edge cases, and environment recovery Status: Draft implementation complete, integration with manager workflows pending.
262 lines
7.1 KiB
Markdown
262 lines
7.1 KiB
Markdown
# pip_util Test Package Dependency Analysis
|
|
|
|
Real dependency analysis using `pip install --dry-run` to verify meaningful test scenarios.
|
|
|
|
## Analysis Date
|
|
|
|
Generated: 2025-10-01
|
|
Tool: `pip install --dry-run --ignore-installed`
|
|
|
|
## Test Scenarios with Real Dependencies
|
|
|
|
### Scenario 1: Dependency Version Protection (requests + urllib3)
|
|
|
|
**Purpose**: Verify pin_dependencies prevents unwanted upgrades
|
|
|
|
**Initial Environment**:
|
|
```
|
|
urllib3==1.26.15
|
|
certifi==2023.7.22
|
|
charset-normalizer==3.2.0
|
|
```
|
|
|
|
**Without pin** (`pip install requests`):
|
|
```bash
|
|
Would install:
|
|
certifi-2025.8.3 # UPGRADED from 2023.7.22 (+2 years)
|
|
charset-normalizer-3.4.3 # UPGRADED from 3.2.0 (minor)
|
|
idna-3.10 # NEW dependency
|
|
requests-2.32.5 # NEW package
|
|
urllib3-2.5.0 # UPGRADED from 1.26.15 (MAJOR 1.x→2.x!)
|
|
```
|
|
|
|
**With pin** (`pip install requests urllib3==1.26.15 certifi==2023.7.22 charset-normalizer==3.2.0`):
|
|
```bash
|
|
Would install:
|
|
idna-3.10 # NEW dependency (required by requests)
|
|
requests-2.32.5 # NEW package
|
|
|
|
# Pinned packages stay at old versions:
|
|
urllib3==1.26.15 ✅ PROTECTED (prevented 1.x→2.x jump)
|
|
certifi==2023.7.22 ✅ PROTECTED
|
|
charset-normalizer==3.2.0 ✅ PROTECTED
|
|
```
|
|
|
|
**Key Finding**:
|
|
- `urllib3` 1.26.15 → 2.5.0 is a **MAJOR version jump** (breaking changes!)
|
|
- requests accepts both: `urllib3<3,>=1.21.1` (compatible with 1.x and 2.x)
|
|
- Pin successfully prevents unwanted major upgrade
|
|
|
|
---
|
|
|
|
### Scenario 2: Package with Dependency (python-dateutil + six)
|
|
|
|
**Purpose**: Verify pin_dependencies with dependency chain
|
|
|
|
**Analysis**:
|
|
```bash
|
|
$ pip install --dry-run python-dateutil
|
|
|
|
Would install:
|
|
python-dateutil-2.9.0.post0
|
|
six-1.17.0 # DEPENDENCY
|
|
```
|
|
|
|
**Initial Environment**:
|
|
```
|
|
six==1.16.0 # Older version
|
|
```
|
|
|
|
**Without pin** (`pip install python-dateutil`):
|
|
```bash
|
|
Would install:
|
|
python-dateutil-2.9.0.post0
|
|
six-1.17.0 # UPGRADED from 1.16.0
|
|
```
|
|
|
|
**With pin** (`pip install python-dateutil six==1.16.0`):
|
|
```bash
|
|
Would install:
|
|
python-dateutil-2.9.0.post0
|
|
|
|
# Pinned package:
|
|
six==1.16.0 ✅ PROTECTED
|
|
```
|
|
|
|
---
|
|
|
|
### Scenario 3: Package Deletion and Restore (six)
|
|
|
|
**Purpose**: Verify restore policy reinstalls deleted packages
|
|
|
|
**Initial Environment**:
|
|
```
|
|
six==1.16.0
|
|
attrs==23.1.0
|
|
packaging==23.1
|
|
```
|
|
|
|
**Action Sequence**:
|
|
1. Delete six: `pip uninstall -y six`
|
|
2. Verify deletion: `pip freeze | grep six` (empty)
|
|
3. Restore: `batch.ensure_installed()` → `pip install six==1.16.0`
|
|
|
|
**Expected Result**:
|
|
```
|
|
six==1.16.0 # ✅ RESTORED
|
|
```
|
|
|
|
---
|
|
|
|
### Scenario 4: Version Change and Restore (urllib3)
|
|
|
|
**Purpose**: Verify restore policy reverts version changes
|
|
|
|
**Initial Environment**:
|
|
```
|
|
urllib3==1.26.15
|
|
```
|
|
|
|
**Action Sequence**:
|
|
1. Upgrade: `pip install urllib3==2.5.0`
|
|
2. Verify change: `pip freeze | grep urllib3` → `urllib3==2.5.0`
|
|
3. Restore: `batch.ensure_installed()` → `pip install urllib3==1.26.15`
|
|
|
|
**Expected Result**:
|
|
```
|
|
urllib3==1.26.15 # ✅ RESTORED (downgraded from 2.5.0)
|
|
```
|
|
|
|
**Key Finding**:
|
|
- Downgrade from 2.x to 1.x requires explicit version specification
|
|
- pip allows downgrades with `pip install urllib3==1.26.15`
|
|
|
|
---
|
|
|
|
## Rejected Scenarios
|
|
|
|
### click + colorama (NO REAL DEPENDENCY)
|
|
|
|
**Analysis**:
|
|
```bash
|
|
$ pip install --dry-run click
|
|
Would install: click-8.3.0
|
|
|
|
$ pip install --dry-run click colorama==0.4.6
|
|
Would install: click-8.3.0 # colorama not installed!
|
|
```
|
|
|
|
**Finding**: click has **NO direct dependency** on colorama
|
|
- colorama is **optional** and platform-specific (Windows only)
|
|
- Not a good test case for dependency protection
|
|
|
|
**Recommendation**: Use python-dateutil + six instead
|
|
|
|
---
|
|
|
|
## Package Size Verification
|
|
|
|
```bash
|
|
Package Size Version Purpose
|
|
-------------------------------------------------------
|
|
urllib3 ~140KB 1.26.15 Protected dependency
|
|
certifi ~158KB 2023.7.22 SSL certificates
|
|
charset-normalizer ~46KB 3.2.0 Charset detection
|
|
idna ~69KB 3.10 NEW dep from requests
|
|
requests ~100KB 2.32.5 Main package to install
|
|
six ~11KB 1.16.0 Restore test
|
|
python-dateutil ~280KB 2.9.0 Depends on six
|
|
attrs ~61KB 23.1.0 Bystander
|
|
packaging ~48KB 23.1 Bystander
|
|
-------------------------------------------------------
|
|
Total ~913KB (< 1MB) ✅ All lightweight
|
|
```
|
|
|
|
---
|
|
|
|
## Dependency Graph
|
|
|
|
```
|
|
requests 2.32.5
|
|
├── charset_normalizer<4,>=2 (have: 3.2.0)
|
|
├── idna<4,>=2.5 (need: 3.10) ← NEW
|
|
├── urllib3<3,>=1.21.1 (have: 1.26.15, latest: 2.5.0)
|
|
└── certifi>=2017.4.17 (have: 2023.7.22, latest: 2025.8.3)
|
|
|
|
python-dateutil 2.9.0
|
|
└── six>=1.5 (have: 1.16.0, latest: 1.17.0)
|
|
```
|
|
|
|
---
|
|
|
|
## Version Compatibility Matrix
|
|
|
|
| Package | Old Version | Latest | Spec | Compatible? |
|
|
|---------|------------|--------|------|-------------|
|
|
| urllib3 | 1.26.15 | 2.5.0 | <3,>=1.21.1 | ✅ Both work |
|
|
| certifi | 2023.7.22 | 2025.8.3 | >=2017.4.17 | ✅ Both work |
|
|
| charset-normalizer | 3.2.0 | 3.4.3 | <4,>=2 | ✅ Both work |
|
|
| six | 1.16.0 | 1.17.0 | >=1.5 | ✅ Both work |
|
|
| idna | (none) | 3.10 | <4,>=2.5 | ⚠️ Must install |
|
|
|
|
---
|
|
|
|
## Test Data Justification
|
|
|
|
### Why urllib3 1.26.15?
|
|
1. **Real world scenario**: Many projects pin urllib3<2 to avoid breaking changes
|
|
2. **Meaningful test**: 1.26.15 → 2.5.0 is a major version jump (API changes)
|
|
3. **Compatibility**: requests accepts both 1.x and 2.x (good for testing)
|
|
|
|
### Why certifi 2023.7.22?
|
|
1. **Real world scenario**: Older environment with outdated SSL certificates
|
|
2. **Meaningful test**: 2-year version gap (2023 → 2025)
|
|
3. **Safety**: Still compatible with requests
|
|
|
|
### Why six 1.16.0?
|
|
1. **Lightweight**: Only 11KB
|
|
2. **Real dependency**: python-dateutil actually depends on it
|
|
3. **Stable**: six is mature and rarely changes
|
|
|
|
---
|
|
|
|
## Recommendations for Test Implementation
|
|
|
|
### ✅ Keep These Scenarios:
|
|
1. **requests + urllib3 pin** - Real major version protection
|
|
2. **python-dateutil + six** - Real dependency chain
|
|
3. **six deletion/restore** - Real package management
|
|
4. **urllib3 version change** - Real downgrade scenario
|
|
|
|
### ❌ Remove These Scenarios:
|
|
1. **click + colorama** - No real dependency (colorama is optional/Windows-only)
|
|
|
|
### 📝 Update Required Files:
|
|
1. `requirements-test-base.txt` - Add idna (new dependency from requests)
|
|
2. `TEST_SCENARIOS.md` - Update with real dependency analysis
|
|
3. `test_dependency_protection.py` - Remove click-colorama test
|
|
4. `pip_util.design.en.md` - Update examples with verified dependencies
|
|
|
|
---
|
|
|
|
## Validation Commands
|
|
|
|
Run these to verify analysis:
|
|
|
|
```bash
|
|
# Check current environment
|
|
./test_venv/bin/pip freeze
|
|
|
|
# Simulate requests installation without pin
|
|
./test_venv/bin/pip install --dry-run requests
|
|
|
|
# Simulate requests installation with pin
|
|
./test_venv/bin/pip install --dry-run requests urllib3==1.26.15 certifi==2023.7.22 charset-normalizer==3.2.0
|
|
|
|
# Check python-dateutil dependencies
|
|
./test_venv/bin/pip install --dry-run python-dateutil
|
|
|
|
# Verify urllib3 version availability
|
|
./test_venv/bin/pip index versions urllib3 | head -20
|
|
```
|