|
| 1 | +# Investigation: Python Version Selection Issue |
| 2 | + |
| 3 | +## Issue Summary |
| 4 | +User reports that Dependabot ignores `requires-python` in `pyproject.toml` and uses Python 3.13/3.14 instead of the minimum specified version (e.g., 3.9). |
| 5 | + |
| 6 | +## Investigation Results |
| 7 | + |
| 8 | +### Current Behavior (Verified in dependabot-core) |
| 9 | + |
| 10 | +The code in `python/lib/dependabot/python/language_version_manager.rb` **correctly** selects the lowest compatible Python version: |
| 11 | + |
| 12 | +1. **Test Case 1**: `requires-python = ">= 3.9, <3.13"` |
| 13 | + - ✅ Selects Python 3.9.24 (lowest compatible) |
| 14 | + |
| 15 | +2. **Test Case 2**: No `requires-python` specified |
| 16 | + - ✅ Selects Python 3.14.0 (latest/default) |
| 17 | + |
| 18 | +3. **Test Case 3**: Poetry format `python = "^3.10"` |
| 19 | + - ✅ Selects Python 3.10.19 (lowest compatible) |
| 20 | + |
| 21 | +### Code Logic |
| 22 | + |
| 23 | +File: `python/lib/dependabot/python/language_version_manager.rb` |
| 24 | + |
| 25 | +```ruby |
| 26 | +# Line 105: Find first (lowest) matching version |
| 27 | +version = Language::PRE_INSTALLED_PYTHON_VERSIONS.find { |v| requirement.satisfied_by?(v) } |
| 28 | +``` |
| 29 | + |
| 30 | +Since `PRE_INSTALLED_PYTHON_VERSIONS` is sorted in ascending order (from `language.rb` line 30), `.find` returns the **lowest** matching version. |
| 31 | + |
| 32 | +### Priority Order of Version Sources |
| 33 | + |
| 34 | +From `python/lib/dependabot/python/file_parser/python_requirement_parser.rb` lines 27-36: |
| 35 | + |
| 36 | +1. Pipfile (`python_version` or `python_full_version`) |
| 37 | +2. **pyproject.toml** (`[project] requires-python` or `[tool.poetry.dependencies] python`) |
| 38 | +3. pip-compile header |
| 39 | +4. `.python-version` file |
| 40 | +5. `runtime.txt` |
| 41 | +6. `setup.py` (`python_requires`) |
| 42 | + |
| 43 | +### Paradox in User Report |
| 44 | + |
| 45 | +The user states that adding `.python-version` **fixes** the issue. However: |
| 46 | +- `.python-version` has **lower priority** than `pyproject.toml` |
| 47 | +- If `pyproject.toml` was being read correctly, `.python-version` would be ignored |
| 48 | +- This suggests `pyproject.toml` might not be fetched/parsed in their scenario |
| 49 | + |
| 50 | +## Possible Causes |
| 51 | + |
| 52 | +### 1. Issue Already Fixed |
| 53 | +The issue may have been fixed in a recent commit. The current codebase works correctly. |
| 54 | + |
| 55 | +### 2. Issue in dependabot-api (Not in dependabot-core) |
| 56 | +The problem might be in how dependabot-api: |
| 57 | +- Fetches dependency files |
| 58 | +- Passes configuration to dependabot-core |
| 59 | +- Handles pyproject.toml files |
| 60 | + |
| 61 | +### 3. File Fetching Issue |
| 62 | +In certain repository configurations, `pyproject.toml` might not be fetched or passed to the FileParser. |
| 63 | + |
| 64 | +### 4. Parsing Error |
| 65 | +A malformed `pyproject.toml` might cause silent parsing failure, falling back to default (latest) Python version. |
| 66 | + |
| 67 | +## Recommendations |
| 68 | + |
| 69 | +### For Users (Immediate) |
| 70 | +1. **Workaround**: Add `.python-version` file with desired version |
| 71 | +2. **Verify**: Check that `pyproject.toml` has correct TOML syntax |
| 72 | +3. **Check**: Ensure `requires-python` is under `[project]` section (PEP 621 format) |
| 73 | + |
| 74 | +### For Developers (Short Term) |
| 75 | +1. **Add Error Logging**: Log when `pyproject.toml` parsing fails |
| 76 | +2. **Add Warning**: Warn when falling back to default Python version |
| 77 | +3. **Improve Documentation**: Document Python version selection behavior |
| 78 | + |
| 79 | +### For Developers (Long Term - Feature Request) |
| 80 | +Add explicit `python-version` configuration to `dependabot.yml`: |
| 81 | + |
| 82 | +```yaml |
| 83 | +version: 2 |
| 84 | +updates: |
| 85 | + - package-ecosystem: "pip" |
| 86 | + directory: "/" |
| 87 | + schedule: |
| 88 | + interval: "weekly" |
| 89 | + python-version: "3.9" # Explicit version control |
| 90 | +``` |
| 91 | +
|
| 92 | +**Note**: This requires changes in both dependabot-api and the configuration schema, which are outside the scope of dependabot-core. |
| 93 | +
|
| 94 | +## Tests Added |
| 95 | +
|
| 96 | +Added comprehensive tests in `python/spec/dependabot/python/file_parser/python_requirement_parser_spec.rb`: |
| 97 | +- Test for PEP 621 `requires-python` field |
| 98 | +- Test for Poetry `python` dependency |
| 99 | +- Test for projects without Python version specified |
| 100 | + |
| 101 | +All tests pass, confirming current behavior is correct. |
| 102 | + |
| 103 | +## Conclusion |
| 104 | + |
| 105 | +**The reported issue does NOT exist in the current dependabot-core codebase.** |
| 106 | + |
| 107 | +The issue is likely: |
| 108 | +1. Already fixed in main branch |
| 109 | +2. In dependabot-api (not dependabot-core) |
| 110 | +3. Related to specific repository configurations not covered by current tests |
| 111 | + |
| 112 | +Further investigation would require: |
| 113 | +- Access to dependabot-api repository |
| 114 | +- Specific example repository exhibiting the issue |
| 115 | +- Production logs showing incorrect Python version selection |
0 commit comments