Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion t4_devkit/helper/rendering.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def __init__(self, t4: Tier4) -> None:
"""
self._t4 = t4
self._label2id: dict[str, int] = {
category.name: idx for idx, category in enumerate(self._t4.category)
category.name: category.index for category in self._t4.category
}

self._executor = concurrent.futures.ThreadPoolExecutor()
Expand Down
33 changes: 33 additions & 0 deletions t4_devkit/schema/compatibility.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""Compatibility helpers that abstract away differences between T4Dataset revisions."""

from __future__ import annotations

from t4_devkit.schema import Category


def fix_category_table(categories: list[Category]) -> list[Category]:
"""Fix unpopulated index fields in some T4Dataset revisions.

This function behaves differently in the below three cases:

- All `index` fields are set: the list is returned unmodified.
- All `index` fields are `None`: the position of each category in the list is used to compute
`index`. The resulting indices start at `0`.
- Some `index` fields are set and some are `None`: raise a `ValueError`.

Args:
categories (list[Category]): List of categories to fix.

Returns:
list[Category]: Fixed list of categories.

Raises:
ValueError: If the `index` field is set for some categories and `None` for others.
"""
if any(category.index is None for category in categories):
if not all(category.index is None for category in categories):
raise ValueError("Category index is not set for some categories.")

Copilot AI Jan 29, 2026

Copy link

Choose a reason for hiding this comment

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

The error message is generic and doesn't help users diagnose which categories have missing indices. Consider including details about which categories are affected, such as 'Category index is not set for some categories: [list of category names or positions]'.

Suggested change
raise ValueError("Category index is not set for some categories.")
missing_positions = [i for i, category in enumerate(categories) if category.index is None]
raise ValueError(
f"Category index is not set for some categories at positions: {missing_positions}"
)

Copilot uses AI. Check for mistakes.

for idx, category in enumerate(categories):
category.index = idx
Comment on lines +31 to +32

Copilot AI Jan 29, 2026

Copy link

Choose a reason for hiding this comment

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

The function mutates the Category objects in place, which may have unintended side effects if the same category objects are referenced elsewhere. Consider documenting this mutation behavior in the docstring or making the function create new Category instances to avoid side effects.

Copilot uses AI. Check for mistakes.
return categories
5 changes: 4 additions & 1 deletion t4_devkit/tier4.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from t4_devkit.dataclass import Box2D, Box3D, SemanticLabel, Shape, ShapeType
from t4_devkit.helper import RenderingHelper, TimeseriesHelper
from t4_devkit.schema import SchemaName, SensorModality, VisibilityLevel, build_schema
from t4_devkit.schema.compatibility import fix_category_table

if TYPE_CHECKING:
from t4_devkit.typing import CameraIntrinsicLike, Vector3
Expand Down Expand Up @@ -181,6 +182,8 @@ def __init__(
self.annotation_dir, SchemaName.CALIBRATED_SENSOR
)
self.category: list[Category] = load_table(self.annotation_dir, SchemaName.CATEGORY)
self.category = fix_category_table(self.category)

Copilot AI Jan 29, 2026

Copy link

Choose a reason for hiding this comment

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

The fix_category_table() function mutates the input list in place and then returns it. This creates ambiguity about whether a new list is being assigned or the existing list is being modified. Consider either making the function purely mutating (returning None) or purely functional (creating a new list), and update the calling code accordingly.

Suggested change
self.category = fix_category_table(self.category)
fix_category_table(self.category)

Copilot uses AI. Check for mistakes.

self.ego_pose: list[EgoPose] = load_table(self.annotation_dir, SchemaName.EGO_POSE)
self.instance: list[Instance] = load_table(self.annotation_dir, SchemaName.INSTANCE)
self.keypoint: list[Keypoint] = load_table(self.annotation_dir, SchemaName.KEYPOINT)
Expand Down Expand Up @@ -265,7 +268,7 @@ def __make_reverse_index__(self, verbose: bool) -> None:
}

self._label2id: dict[str, int] = {
category.name: idx for idx, category in enumerate(self.category)
category.name: category.index for category in self.category
}

# add shortcuts
Expand Down
Loading