Repository navigation
fix(datasets): normalize YOLO class IDs across class-name entry points - #1571
Merged
Borda merged 7 commits intoSep 30, 2026
Merged
Conversation
INo-xious
requested review from
Borda,
SkalskiP,
isaacrob and
probicheaux
as code owners
September 30, 2026 06:51
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Identical keys in a YAML names mapping can still silently overwrite a class name before duplicate-ID validation runs.
Review effort: Balanced
Findings: 1
What changed in this PR
This PR aligns YOLO class-name parsing across detection, pose, and the RFDETR facade, following the shared pose parser introduced in #1156.
Changes:
- Normalize numeric class IDs and reject collisions that remain visible after YAML loading.
- Reuse the parser in the facade and add entry-point tests.
- Document quoted numeric keys.
| File | Description |
|---|---|
tests/datasets/test_yolo.py |
Tests class ordering and invalid IDs across entry points. |
src/rfdetr/detr.py |
Uses the shared YOLO class parser. |
src/rfdetr/datasets/_keypoint_schema.py |
Normalizes IDs and checks for collisions. |
docs/learn/train/dataset-formats.md |
Documents numeric-key behavior. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| unique_sorted_keys = sorted(set(numeric_keys)) | ||
| if not unique_sorted_keys or unique_sorted_keys != list(range(len(unique_sorted_keys))) or non_numeric_keys: | ||
| sorted_ids = sorted(names_by_id) | ||
| if not sorted_ids or sorted_ids != list(range(len(sorted_ids))) or len(names_by_id) != len(names): |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #1571 +/- ##
=======================================
Coverage 90% 90%
=======================================
Files 137 138 +1
Lines 18254 18264 +10
=======================================
+ Hits 16421 16436 +15
+ Misses 1833 1828 -5 🚀 New features to boost your workflow:
|
…_keypoint_schema.py into a new _yolo_yaml.py module, since they parse generic YOLO data.yaml fields unrelated to keypoint schemas. yolo.py now imports both helpers from _yolo_yaml instead of _keypoint_schema; _keypoint_schema.py imports them back for its own infer_yolo_keypoint_schema use. Co-Authored-By: Claude Sonnet 5 <[email protected]>
…emoize YAML load Reword the ambiguous duplicate-key error message so it no longer implies the length check catches every duplicate-key case. Add an _ascii_digit_key helper (now in the relocated _yolo_yaml.py module) so non-ASCII digit YAML keys fall through to the existing length-mismatch error instead of raising a bare int() ValueError, and reuse it for the kpt_names key-0 lookup. Memoize _load_yaml_mapping by (resolved path, mtime_ns, size) so repeated data.yaml parses within one RFDETR.train() call reuse one parsed mapping; each caller gets a deep copy so mutation can never corrupt the cache. [resolve group] PR roboflow#1571 — items 1 3 5 8 --- Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
…are data-file lookup Embed the original inference exception text in both YOLO pose data-file wrapper messages so the real cause is visible directly in the raised ValueError, not only in __cause__. Add 12 parametrized edge-case class-ID keys (empty, non-integer, whitespace, negative, non-numeric, bool, non-ASCII digit variants) across all three entry points, and split the two branching test methods into six focused ones with no runtime if/else. Add a shared _yolo_data_file(dataset_dir) helper in yolo.py and route is_valid_yolo_dataset, RFDETR._yolo_data_file_path, and the build_roboflow_from_yolo fallback through it, keeping the divergent root/"data.yaml" fallback explicit. [resolve group] PR roboflow#1571 — items 2 6 7 11 --- Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Note that three-or-more-digit zero-padded keys in the dictionary names format collide under YAML 1.1 octal parsing (e.g. 010 and 008 both resolve to class 8); two-digit padding is unaffected. [resolve group] PR roboflow#1571 — items 9 --- Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
…normalization # Conflicts: # src/rfdetr/datasets/yolo.py # src/rfdetr/detr.py
Borda
approved these changes
Sep 30, 2026
Borda
added a commit
that referenced
this pull request
Oct 3, 2026
#1571) * fix(datasets): normalize YOLO class IDs across entry points * Move _load_yaml_mapping and _extract_yolo_class_names_from_data from _keypoint_schema.py into a new _yolo_yaml.py module, since they parse generic YOLO data.yaml fields unrelated to keypoint schemas. yolo.py now imports both helpers from _yolo_yaml instead of _keypoint_schema; _keypoint_schema.py imports them back for its own infer_yolo_keypoint_schema use. * keypoint-schema: normalize YOLO class-ID key parsing, reword error, memoize YAML load * entry-points: surface real pose errors, cover edge-case class IDs, share data-file lookup * docs: document the YAML octal-key collision for zero-padded class IDs --------- Co-authored-by: jirka <[email protected]> Co-authored-by: Claude Sonnet 5 <[email protected]> Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
YOLO names such as
{'0': 'cat', '1': 'dog'}pass numeric-ID validation but raiseKeyError during detection/pose loading. The facade separately sorts quoted IDs
lexicographically and raises TypeError for mixed integer/string keys. Normalize
keys once and use the same parser for facade class discovery.
Changes
IDs while preserving the contiguous zero-based requirement.
document quoted numeric keys.
Verification
uv run --no-sync pytest tests/datasets/test_yolo.py tests/datasets/test_keypoint_schema.py tests/datasets/test_coco.py -n 1 --timeout=120 --color=no -q): 268 passed.pre-commit run --all-files: passed, including mypy (UV_NO_SYNC=1).uv run --no-sync mkdocs build --verbose: passed with docs/plus installed.Related issues
No issue claimed. Follow-up to the shared YOLO detection/pose parser in merged
#1156; independent of the dataset-entry-point
candidate. No direct active duplicate found during the overlap review.