Skip to content

chore: bump minimum Python to 3.10#2260

Open
Borda wants to merge 50 commits into
developfrom
bump/py3.10
Open

chore: bump minimum Python to 3.10#2260
Borda wants to merge 50 commits into
developfrom
bump/py3.10

Conversation

@Borda
Copy link
Copy Markdown
Member

@Borda Borda commented May 20, 2026

This pull request updates the minimum supported Python version for the project from 3.9 to 3.10. The changes ensure consistency across documentation, configuration, and CI workflows, and remove references to Python 3.9 throughout the codebase.

Python version support updates:

  • Updated the minimum required Python version in pyproject.toml from 3.9 to 3.10, and removed Python 3.9 from the supported classifiers. [1] [2]
  • Changed the Python version matrix in the CI workflow (.github/workflows/ci-tests.yml) to start from 3.10 instead of 3.9.

Configuration and tooling updates:

  • Updated the Python version constraints for documentation dependencies to require Python >=3.10.
  • Set the target version for ruff (linter) to py310 instead of py39 in pyproject.toml.
  • Changed the python_version setting for mypy type checking from 3.9 to 3.10 in pyproject.toml.

  • Drop Python 3.9 from CI test matrix
  • requires-python = ">=3.10" in pyproject.toml
  • ruff target-version py39 → py310
  • mypy python_version 3.9 → 3.10
  • Remove Python 3.9 classifier

- Drop Python 3.9 from CI test matrix
- requires-python = ">=3.10" in pyproject.toml
- ruff target-version py39 → py310
- mypy python_version 3.9 → 3.10
- Remove Python 3.9 classifier

---
Co-authored-by: Claude Code <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 20, 2026 10:49
@Borda Borda requested a review from SkalskiP as a code owner May 20, 2026 10:49
Comment thread .github/workflows/ci-tests.yml
Co-authored-by: Jirka Borovec <6035284+Borda@users.noreply.github.com>
@Borda Borda added the enhancement New feature or request label May 20, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 20, 2026

Codecov Report

❌ Patch coverage is 80.01817% with 220 lines in your changes missing coverage. Please review.
✅ Project coverage is 79%. Comparing base (befdb7c) to head (e30da42).
⚠️ Report is 2 commits behind head on develop.

❌ Your patch check has failed because the patch coverage (80%) is below the target coverage (95%). You can increase the patch coverage or adjust the target coverage.
❌ Your project check has failed because the head coverage (79%) is below the target coverage (95%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files
@@           Coverage Diff            @@
##           develop   #2260    +/-   ##
========================================
+ Coverage       78%     79%    +1%     
========================================
  Files           66      67     +1     
  Lines         8410    8811   +401     
========================================
+ Hits          6552    6927   +375     
- Misses        1858    1884    +26     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request raises the project’s minimum supported Python version to 3.10 and aligns configuration/typing across the repo to use Python 3.10+ features and tooling settings.

Changes:

  • Bump requires-python to >=3.10 and update lint/type-checker target versions accordingly.
  • Drop Python 3.9 from CI and modernize type annotations (e.g., Optional[T]T | None, typing.Callablecollections.abc.Callable).
  • Update docs dependency markers to reflect the new minimum Python version.

Assessment (n/5):

  • Code quality: 4/5
  • Testing: 4/5
  • Docs: 3/5

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/metrics/conftest.py Updates type annotations to Python 3.10 union syntax.
src/supervision/dataset/formats/coco.py Replaces typing.Union with `
pyproject.toml Bumps minimum Python, updates classifiers and tool target versions (ruff/mypy), and adjusts docs dependency markers.
examples/heatmap_and_track/script.py Updates optional parameter typing to Python 3.10 union syntax.
examples/compact_mask/benchmark.py Switches Callable import to collections.abc for modern typing.
.github/workflows/ci-tests.yml Updates the CI Python matrix to reflect supported versions.

Borda and others added 11 commits May 20, 2026 12:53
Co-authored-by: Codex <codex@openai.com>
- Replace float arrays with explicit integer or float types, e.g., `dtype=int32` or `dtype=float32`.
- Improve type safety by adding explicit casting in key computations.
- Update Ruff ignore rules for additional per-file scenarios.
- Refactor imports for cleaner and more direct typing references.
- boxes.py: clip/pad/move/spread restore input-dtype-preserving behavior (was forcing float64/float32); revert doctests
- detection/core.py + key_points/core.py: restore __setitem__ runtime isinstance validation and list→ndarray coercion
- smoother.py: remove forced float32 on xyxy/confidence stacks; keep null-safety for confidence=None case; revert doctests
- metrics/detection.py: revert ConfusionMatrix matrix dtype int32→float64 default; revert doctests
- annotators/core.py: polygon cast int64→int32 (cv2 requires CV_32S); HeatMapAnnotator local mask float32→float64
- pyproject.toml: remove ANN (flake8-annotations) from lint.select and all ANN per-file-ignores — policy change unrelated to py3.10 compat

---
Co-authored-by: Claude Code <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 84 out of 85 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (2)

src/supervision/utils/conversion.py:71

  • Same as above: this wrapper should preserve the wrapped function’s metadata via @functools.wraps(image_processing_fun). Without it, the exported function’s docstring/signature become those of the wrapper, which can break documentation/introspection tooling.
    src/supervision/utils/conversion.py:105
  • This wrapper should preserve annotate_func metadata via @functools.wraps(annotate_func) for consistent introspection/docs. Currently the wrapper replaces the original function name/docstring/signature.

Comment thread src/supervision/utils/conversion.py Outdated
Comment thread src/supervision/draw/utils.py
Comment thread src/supervision/detection/tools/inference_slicer.py
Comment thread pyproject.toml
Copilot finished work on behalf of Borda May 20, 2026 17:00
Copilot finished work on behalf of Borda May 20, 2026 17:03
Borda and others added 20 commits May 21, 2026 14:47
[resolve #1] Review by @Copilot (PR #2260):
"_extract_class_names() removed isinstance(data, dict) guard; can raise AttributeError on malformed YAML"
Challenge: evidence=VALID (self-verified) suggestion=VALID resolution=as-suggested

- Restore isinstance(data, dict) check before .get("names") in yolo.py
- Fix pre-existing [no-any-return] mypy error in annotators/core.py:_load_icon

---
Co-authored-by: Claude Code <noreply@anthropic.com>
…on_size_category

[resolve #2] Review by @Copilot (PR #2260):
"isinstance(mask, CompactMask) check: both branches return get_mask_size_category(mask)"
Challenge: evidence=VALID (self-verified) suggestion=VALID resolution=as-suggested

---
Co-authored-by: Claude Code <noreply@anthropic.com>
- requires-python: ">=3.9" → ">=3.10"
- Remove Programming Language :: Python :: 3.9 classifier
- Drop "3.9" from CI test matrix in ci-tests.yml
- Tighten mkdocs-git-committers-plugin-2 env marker to python_version>='3.10'

---
Co-authored-by: Claude Code <noreply@anthropic.com>
---
Co-authored-by: Claude Code <noreply@anthropic.com>
…nt uint8 truncation

np.asarray(icon, dtype=np.uint8) would silently truncate 16-bit PNG icons;
cast() is a typing-only no-op that preserves source data unchanged.

[resolve #3] /review finding by foundry:challenger (report: .reports/review/2026-05-22T05-56-29Z/review-report.md)

---
Co-authored-by: Claude Code <noreply@anthropic.com>
…cs modules

- metrics/detection.py:749: .astype(np.float32, copy=False) for float64→float32 mismatch
- metrics/detection.py:763: fix variadic unpack type mismatch
- detection/core.py, converters.py, annotators/core.py, byte_tracker: wrap
  no-any-return sites with cast() to satisfy strict return-type checks

[resolve #2] /review finding by foundry:challenger (report: .reports/review/2026-05-22T05-56-29Z/review-report.md)

---
Co-authored-by: Claude Code <noreply@anthropic.com>
Co-authored-by: OpenAI Codex <codex@openai.com>
Precision, Recall, F1Score, MeanAverageRecall all raise ValueError when
predictions/targets.class_id is None or predictions.confidence is None.

[resolve #4] /review finding by foundry:qa-specialist (report: .reports/review/2026-05-22T05-56-29Z/review-report.md)

---
Co-authored-by: Claude Code <noreply@anthropic.com>
Co-authored-by: OpenAI Codex <codex@openai.com>
Keep isinstance(segmentation, dict) check (correct for COCO RLE format)
but guard against malformed dicts without 'counts' key — warn and skip.
Add tests for dict-RLE, polygon, and malformed-dict segmentation paths.

[resolve #5] /review finding by codex (report: .reports/review/2026-05-22T05-56-29Z/review-report.md)

---
Co-authored-by: Claude Code <noreply@anthropic.com>
Co-authored-by: OpenAI Codex <codex@openai.com>
…ng and edge cases

[resolve #6] /review finding by foundry:qa-specialist (report: .reports/review/2026-05-22T05-56-29Z/review-report.md)

---
Co-authored-by: Claude Code <noreply@anthropic.com>
Co-authored-by: OpenAI Codex <codex@openai.com>
[resolve #9] /review finding by codex (report: .reports/review/2026-05-22T05-56-29Z/review-report.md)

---
Co-authored-by: Claude Code <noreply@anthropic.com>
Co-authored-by: OpenAI Codex <codex@openai.com>
- Add 0.29.0 upcoming section with failure admonition block documenting Python 3.9 termination
- Update uv.lock to reflect py3.10 minimum (Python 3.9 deps removed from lock)

---
Co-authored-by: Claude Code <noreply@anthropic.com>
- Change per_class_ap50_95 field annotation float64 → float32
- Change _average_precisions_per_class return type and array init to float32
- Aligns code with 0.28.0 changelog claim (PR #2169) that metric arrays are float32

---
Co-authored-by: Claude Code <noreply@anthropic.com>
- Remove forced dtype=np.float64 in np.array copy — was silently doubling
  memory when callers passed float32 inputs
- Preserves input floating dtype; integer arrays still upcast naturally
- Update return annotation to npt.NDArray[np.number] and docstring

---
Co-authored-by: Claude Code <noreply@anthropic.com>
- Add match= parameter to all pytest.raises(ValueError/OSError) in test files
- Shorten over-long docstrings to stay within 88-char limit
- Rename one test function to fit line-length constraint
- Fix ruff-format whitespace in detection/core.py

---
Co-authored-by: Claude Code <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 92 out of 93 changed files in this pull request and generated 3 comments.

Comment thread pyproject.toml
Comment thread pyproject.toml
Comment thread docs/changelog.md Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 92 out of 93 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/supervision/detection/utils/internal.py:463

  • get_data_item() now declares it accepts list[bool] as an index, but the isinstance(index, list) branch treats the list elements as integer indices (value[i] for i in index). For boolean-mask lists this silently indexes with True/False (i.e., 1/0) rather than filtering, producing incorrect subsets (and potentially IndexError). Handle list[bool] explicitly (e.g., if index and isinstance(index[0], bool): ...) and keep the existing list[int] behavior separate; also consider the empty-list case.

Comment on lines 177 to +197
if len(targets) > 0:
if predictions.class_id is None or targets.class_id is None:
raise ValueError(
"Precision metric requires `class_id` on both predictions "
"and targets."
)
if len(predictions) == 0:
stats.append(
(
np.zeros((0, iou_thresholds.size), dtype=bool),
np.zeros((0,), dtype=np.float32),
np.zeros((0,), dtype=int),
targets.class_id,
np.zeros((0,), dtype=np.int32),
np.asarray(targets.class_id, dtype=np.int32),
)
)

else:
if predictions.confidence is None:
raise ValueError(
"Precision metric requires `confidence` on predictions."
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request has conflicts

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants