Skip to content

fix(universal_converter): auto-register Pydantic/dataclass types in DictSource path (ITL-446)#213

Merged
eywalker merged 9 commits into
mainfrom
eywalker/itl-446-pydantic-dataclass-instances-on-dictsource-need-auto
Jul 7, 2026
Merged

fix(universal_converter): auto-register Pydantic/dataclass types in DictSource path (ITL-446)#213
eywalker merged 9 commits into
mainfrom
eywalker/itl-446-pydantic-dataclass-instances-on-dictsource-need-auto

Conversation

@kurodo3

@kurodo3 kurodo3 Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Added self.ensure_types_registered_for_schemas(python_schema) in UniversalTypeConverter.python_dicts_to_arrow_table immediately before converting the Python schema to Arrow. This auto-registers Pydantic BaseModel subclasses and @dataclass column types encountered through DictSource without requiring prior function-pod registration.
  • Registration is idempotent, thread-safe, and a no-op for primitives and already-registered types — no change to the function-pod eager-registration path.
  • Added 4 tests covering: Pydantic no-prior-registration, dataclass no-prior-registration, idempotency, and pod-registration-not-broken.

Test Plan

  • uv run pytest tests/test_core/sources/test_dict_source_auto_registration.py -v — all 4 new tests pass
  • uv run pytest tests/ -x -q — 4144 passed, 0 failures, no regressions

Fixes ITL-446

kurodo3 Bot and others added 6 commits July 7, 2026 05:55
…L-446)

Removed unused pytest import and replaced meaningless 'pod is not None' assertion
with assertion that verifies the pod was constructed with the expected output schema.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ython_dicts_to_arrow_table (ITL-446)

Calls ensure_types_registered_for_schemas before converting Python schema to Arrow schema,
enabling DictSource to automatically register Pydantic/dataclass column types without requiring
manual pre-registration via a function pod. The method is idempotent and thread-safe, making
it safe to call here.

Also fixes a test bug where _Sensor was defined as a local class inside test_pod_registration_not_broken,
causing get_type_hints to fail due to local scope resolution issues. Moved _Sensor to module-level
definition like other test fixtures (_Point, _Measurement).
…ing and fix test comment (ITL-446)

- Expanded python_dicts_to_arrow_table docstring to clarify auto-registration of
  Pydantic BaseModel and @DataClass types, including the idempotent nature of
  registration when arrow_schema is None
- Updated test_dict_source_auto_registration.py comment block to reflect that
  classes are defined at module level for type hints resolution, with emphasis
  on idempotent registration behavior

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@codecov

codecov Bot commented Jul 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a DictSource failure mode where Pydantic BaseModel subclasses and @dataclass instances appearing as column values could raise an “Unsupported Python type” error because their types were not registered in the semantic type registry. The fix mirrors the existing function-pod eager-registration behavior by ensuring discovered schema types are registered during Python-dict → Arrow conversion.

Changes:

  • Auto-register schema types in UniversalTypeConverter.python_dicts_to_arrow_table before deriving an Arrow schema from a Python schema.
  • Add a focused test suite covering Pydantic/dataclass “no prior registration”, idempotency, and “pod registration not broken”.
  • Add design/spec + implementation plan documentation for the change.

Reviewed changes

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

File Description
src/orcapod/semantic_types/universal_converter.py Registers schema types before Python-schema → Arrow-schema conversion in the arrow_schema is None path.
tests/test_core/sources/test_dict_source_auto_registration.py Adds 4 tests validating DictSource auto-registration and compatibility with pod eager-registration.
superpowers/specs/2026-07-07-dict-source-auto-registration-design.md Design note describing the rationale and intended behavior.
superpowers/plans/2026-07-07-dict-source-auto-registration.md Step-by-step implementation plan and verification checklist.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +956 to +957
arrow_schema: Optional Arrow schema. When provided the Python schema
is derived from it; no type registration is performed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch — the previous docstring conflated two distinct cases. Fixed in d4efa1c: the arrow_schema entry now explicitly documents both sub-cases:

  • python_schema omitted → Python schema is derived from arrow_schema; no type registration.
  • python_schema supplied → both schemas used as-is with a compatibility warning; no type registration in either case.

@kurodo3

kurodo3 Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

Review round 1 — changes made

1 comment addressed (commit d4efa1c):

  • Copilot: arrow_schema docstring inaccuracy — the previous text said "When provided the Python schema is derived from it", which was only accurate when python_schema is omitted. When both parameters are supplied the code keeps both as-is and logs a compatibility warning; python_schema is never overwritten. The docstring now documents both sub-cases explicitly, matching the actual control flow.

This uses the main conversion logic and caches results for performance.
When deriving the Arrow schema from a Python schema (i.e. when
``arrow_schema`` is ``None``), Pydantic ``BaseModel`` subclasses and
``@dataclass`` types found in the schema are automatically registered

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This makes is sound specific to these but in reality this is for any factory-based logical type, and thus not fundamentally limited to Dataclass or Pydantic

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good point — fixed in 3fd784b. Both the docstring intro and the inline code comment now refer to "any type that has a registered factory in the semantic-type system" rather than naming Pydantic/dataclass specifically. Pydantic and @dataclass are still mentioned in the inline comment as examples, but the framing makes clear they are not the only cases.

@kurodo3

kurodo3 Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

Review round 2 — changes made

1 comment addressed (commit 3fd784b):

  • eywalker: language too specific to Pydantic/dataclass — both the docstring intro paragraph and the inline code comment previously named Pydantic BaseModel subclasses and @dataclass as the types that get auto-registered. The reviewer correctly noted that ensure_types_registered_for_schemas dispatches via MRO to any registered factory, not just those two. Both locations now read "any type that has a registered factory in the semantic-type system", with Pydantic and @dataclass demoted to parenthetical examples in the inline comment.

@eywalker eywalker merged commit 54dedcd into main Jul 7, 2026
11 checks passed
@eywalker eywalker deleted the eywalker/itl-446-pydantic-dataclass-instances-on-dictsource-need-auto branch July 7, 2026 16:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants