Skip to content

Skip recursive map_object for scalars with no range#173

Merged
amc-corey-cox merged 2 commits intomainfrom
issue172
Mar 30, 2026
Merged

Skip recursive map_object for scalars with no range#173
amc-corey-cox merged 2 commits intomainfrom
issue172

Conversation

@matentzn
Copy link
Copy Markdown
Contributor

Fixes #172

When a slot has range=None and no any_of enums, _map_value_by_range now returns scalar values directly instead of recursing into map_object with None as the source type. This eliminates spurious "Unexpected: ... for type None" warnings.

When a slot has `range=None` and no `any_of` enums, `_map_value_by_range` now returns scalar values directly instead of recursing into `map_object` with `None` as the source type. This eliminates spurious "Unexpected: ... for type None" warnings.
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

Adjusts ObjectTransformer._map_value_by_range to avoid pointless recursion when the source slot has no declared range, reducing noisy “Unexpected …” warnings during normal transforms (Fixes #172).

Changes:

  • Add a fast-path return for scalar values when source_class_slot.range is None/"Any" and there are no any_of enums.
  • Prevents map_object(..., source_type=None, ...) being called for scalar values in that case.
Comments suppressed due to low confidence (1)

src/linkml_map/transformer/object_transformer.py:606

  • The new early-return only skips recursion when v itself is a scalar. For multivalued slots with range None/"Any" (e.g., v is a list of strings/ints), this still recurses into map_object for each element and will continue emitting the same spurious "Unexpected" warnings. Consider extending the guard to also return the collection unchanged when v is a list/dict whose elements/values are all scalars (i.e., nothing nested to recurse into).
            # No range and no any_of enums: nothing to recurse into for scalars
            if not isinstance(v, (dict, list)):
                return v

        if source_class_slot.multivalued:
            if isinstance(v, list):
                return [self.map_object(v1, source_class_slot_range, target_range) for v1 in v]
            elif isinstance(v, dict):

@matentzn
Copy link
Copy Markdown
Contributor Author

@amc-corey-cox this works for me but I am not 100% certain of the side effects. As far as I can see, the only consequence is avoiding an unnecessary warning to be printed.

Extend the no-range scalar short-circuit to also handle lists of
scalars. Without this, multivalued scalar slots with no explicit
range fall through to map_object, which logs spurious "Unexpected"
warnings for each element.

Add regression tests asserting both scalar and multivalued scalar
slots with no range produce correct output without warnings.
Copy link
Copy Markdown
Contributor

@amc-corey-cox amc-corey-cox left a comment

Choose a reason for hiding this comment

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

This looks good to me. Nice work! Thanks @matentzn

@amc-corey-cox amc-corey-cox merged commit 5cca0f9 into main Mar 30, 2026
12 checks passed
@amc-corey-cox amc-corey-cox deleted the issue172 branch March 30, 2026 13:52
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.

map_object emits spurious "Unexpected" warnings for slots with range=None

3 participants