Skip to content

Conversation

@brimoor
Copy link
Contributor

@brimoor brimoor commented Nov 21, 2025

Release Notes

  • fixed a bug in foo.get_implied_field_kwargs() when parsing embedded documents with >=2 levels of nesting

Tested by

import fiftyone as fo
import fiftyone.core.odm as foo

value = [
    fo.DynamicEmbeddedDocument(animal=fo.Detection(label="cat", instance=fo.Instance())),
    fo.DynamicEmbeddedDocument(animal=fo.Detection(label="dog", instance=fo.Instance())),
]

# previously failed, now works
kwargs = foo.get_implied_field_kwargs(value, dynamic=True)

Summary by CodeRabbit

  • Improvements

    • More accurate display of embedded document types in field listings.
    • Improved initialization and recursive handling of nested embedded document fields for more consistent schema detection and faster lookups.
  • Tests

    • Added unit tests verifying dynamic embedded-list field schema behavior and correctness.

✏️ Tip: You can customize this high-level summary in your review settings.

@brimoor brimoor requested a review from a team as a code owner November 21, 2025 16:40
@brimoor brimoor added the bug Bug fixes label Nov 21, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 21, 2025

Walkthrough

This pull request normalizes embedded document field definitions and adjusts an embedded-list field string representation. It adds a helper _init_embedded_doc_fields() that recursively converts field["fields"] from a list into a dict keyed by field names and applies this normalization during embedding merge operations. Separately, EmbeddedDocumentListField.__str__ was changed to show the embedded document type class name for the second element in its printed pair instead of the inner field's class name.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Merge as embedding merge
participant Init as _init_embedded_doc_fields()
participant Acc as accumulator

Merge->>Init: receive new EmbeddedDocumentField (field)
note right of Init `#E8F5E9`: recursively traverse\nfield["fields"]
Init-->>Init: convert lists -> dict by field name\ninitialize nested EmbeddedDocumentField entries
Init-->>Merge: return normalized field (fields as dict)
Merge->>Acc: add/update normalized field in accumulator
Acc-->>Merge: updated accumulator state

mermaid
sequenceDiagram
participant StrCall as EmbeddedDocumentListField.str()
participant Field as self.field
participant DocType as self.field.document_type

StrCall->>Field: read inner field
Field->>DocType: obtain document_type
StrCall-->>StrCall: format pair using DocType class name (not Field class)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–25 minutes

  • Verify recursive termination and handling of empty or malformed fields in _init_embedded_doc_fields().
  • Confirm no other code paths expect field["fields"] to remain a list; search/verify call sites.
  • Inspect merge logic to ensure normalized dicts preserve ordering/semantics required elsewhere.
  • Validate the __str__ change for EmbeddedDocumentListField does not break logging/tests that assert exact string output.
  • Files/areas to pay extra attention to:
    • fiftyone/core/odm/utils.py (new helper and merge changes)
    • fiftyone/core/fields.py (string representation change)
    • tests/unittests/dataset_tests.py (new/duplicate tests for dynamic embedded lists)

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description is incomplete. It lacks the 'What changes are proposed' section and does not formally indicate whether this is a user-facing change per the template. Add a 'What changes are proposed' section explaining the fix, explicitly check the user-facing change checkbox, and add a 'How is this patch tested' section documenting the test approach.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main fix: recursive parsing of embedded document field kwargs.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bugfix/get-implied-field-kwargs

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2f7e0bb and 2e3dad4.

📒 Files selected for processing (1)
  • tests/unittests/dataset_tests.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
tests/unittests/dataset_tests.py (2)
fiftyone/core/dataset.py (2)
  • add_sample (3259-3294)
  • get_field_schema (1364-1423)
fiftyone/core/odm/mixins.py (1)
  • get_field_schema (208-275)
🪛 Pylint (4.0.3)
tests/unittests/dataset_tests.py

[convention] 6969-6969: Missing function or method docstring

(C0116)


[convention] 6969-6969: Method name "test_dynamic_embedded_list_fields" doesn't conform to 'a-z_$' pattern

(C0103)

🪛 Ruff (0.14.5)
tests/unittests/dataset_tests.py

6998-6998: Use a regular assert instead of unittest-style assertIn

Replace assertIn(...) with assert ...

(PT009)


6999-6999: Use a regular assert instead of unittest-style assertIn

Replace assertIn(...) with assert ...

(PT009)


7000-7000: Use a regular assert instead of unittest-style assertIn

Replace assertIn(...) with assert ...

(PT009)


7001-7001: Use a regular assert instead of unittest-style assertIn

Replace assertIn(...) with assert ...

(PT009)


7002-7002: Use a regular assert instead of unittest-style assertIn

Replace assertIn(...) with assert ...

(PT009)


7003-7003: Use a regular assert instead of unittest-style assertIn

Replace assertIn(...) with assert ...

(PT009)


7004-7004: Use a regular assert instead of unittest-style assertIn

Replace assertIn(...) with assert ...

(PT009)


7005-7005: Use a regular assert instead of unittest-style assertNotIn

Replace assertNotIn(...) with assert ...

(PT009)


7006-7006: Use a regular assert instead of unittest-style assertNotIn

Replace assertNotIn(...) with assert ...

(PT009)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: modified-files
  • GitHub Check: build
🔇 Additional comments (1)
tests/unittests/dataset_tests.py (1)

6968-7007: New regression test for nested dynamic embedded list fields is correct and well‑scoped

This test exercises the exact nested shape (list → DynamicEmbeddedDocumentDetectionInstance) that previously caused get_implied_field_kwargs(..., dynamic=True) to fail, and the assertions on both presence (test.animal.*, test.person.*, test.object) and absence (test.object.instance*) of flattened schema paths look correct. It’s consistent with existing dynamic‑field tests and should reliably prevent regressions in this area.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 68d1229 and 2f7e0bb.

📒 Files selected for processing (2)
  • fiftyone/core/fields.py (1 hunks)
  • fiftyone/core/odm/utils.py (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
fiftyone/core/odm/utils.py (1)
fiftyone/core/fields.py (1)
  • EmbeddedDocumentField (1775-2100)
🪛 Ruff (0.14.5)
fiftyone/core/odm/utils.py

534-534: Missing return type annotation for private function _init_embedded_doc_fields

Add return type annotation: None

(ANN202)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: modified-files
  • GitHub Check: build
🔇 Additional comments (2)
fiftyone/core/fields.py (1)

2133-2138: LGTM - Improved string representation clarity.

The change correctly displays the embedded document type class name instead of the field class name, making the string output more informative. Since EmbeddedDocumentListField always wraps an EmbeddedDocumentField that has a document_type attribute, this access is safe.

fiftyone/core/odm/utils.py (1)

514-517: LGTM - Core fix for recursive embedded document parsing.

This correctly initializes field["fields"] from list to dict before storing in fields_dict. This ensures that when line 531 recursively calls _merge_embedded_doc_fields(efield["fields"], field["fields"]), the first argument is a dict as expected, enabling proper handling of 2+ level nested embedded documents.

@exupero
Copy link
Contributor

exupero commented Nov 21, 2025

How difficult would it be to turn the test script in the PR description into an automated test that would protect against someone breaking this fix?

@brimoor brimoor requested a review from a team as a code owner November 21, 2025 22:18
@brimoor
Copy link
Contributor Author

brimoor commented Nov 21, 2025

How difficult would it be to turn the test script in the PR description into an automated test that would protect against someone breaking this fix?

done: 2e3dad4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Bug fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants