Skip to content

Support expr values in value_mappings#195

Open
amc-corey-cox wants to merge 9 commits intomainfrom
value-mapping-expr
Open

Support expr values in value_mappings#195
amc-corey-cox wants to merge 9 commits intomainfrom
value-mapping-expr

Conversation

@amc-corey-cox
Copy link
Copy Markdown
Contributor

Summary

  • Extend value_mappings so each KeyVal entry can use an expr field (evaluated against source bindings) instead of a literal value. Specifying both is an error.
  • Add _resolve_key_val method and lazy bindings init in the populated_from + value_mappings path
  • Add _expand_keyval_dicts preprocessing to handle ReferenceValidator normalization when KeyVal has more than two fields
  • Deprecate expression_to_value_mappings and expression_to_expression_mappings in the schema ahead of 1.0 removal

Closes #165

Test plan

  • Scaffold test: expr-valued mapping with uuid5() and source field bindings
  • Scaffold test: literal value mapping (backward compat)
  • Error test: both value and expr set raises
  • Edge case: no-match returns None
  • Full suite: 584 passed, 4 skipped

🤖 Generated with Claude Code

Extend value_mappings so each entry can use an expr field (evaluated
against source bindings) instead of a literal value. Deprecate
expression_to_value_mappings and expression_to_expression_mappings
ahead of 1.0 removal.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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

Extends the transformer spec and runtime to allow value_mappings entries to compute their mapped values via an expr (evaluated with source bindings), while preserving backward-compatible literal mappings and deprecating older expression-mapping fields.

Changes:

  • Add KeyVal.expr support and resolve mapped values via a new _resolve_key_val helper in the populated_from + value_mappings path.
  • Pre-expand shorthand dict[str, KeyVal] values (e.g., "A": Admin) prior to ReferenceValidator normalization to avoid normalization failures after KeyVal gains extra fields.
  • Add tests covering expr-valued mappings, literal backward compatibility, mutual-exclusion error, and no-match behavior.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tests/test_transformer/test_object_transformer_new.py Adds integration/unit tests for expr-valued and literal value_mappings, plus error/no-match cases.
src/linkml_map/transformer/transformer.py Adds preprocessing to expand shorthand KeyVal dict values before normalization.
src/linkml_map/transformer/object_transformer.py Resolves value_mappings outputs via literal value or evaluated expr, with lazy bindings init.
src/linkml_map/datamodel/transformer_model.yaml Adds KeyVal.expr and deprecates older expression-mapping fields in the schema.
src/linkml_map/datamodel/transformer_model.py Updates generated Pydantic models/metadata to reflect KeyVal.expr and deprecations.

Comment thread src/linkml_map/transformer/transformer.py Outdated
Comment thread src/linkml_map/transformer/object_transformer.py Outdated
Comment thread src/linkml_map/transformer/object_transformer.py Outdated
Comment thread src/linkml_map/datamodel/transformer_model.yaml Outdated
Comment thread src/linkml_map/datamodel/transformer_model.py Outdated
Unify expression evaluation: extract _eval_expr from _derive_from_expr
so _resolve_key_val shares the same eval path (including unrestricted_eval
fallback). Fix KeyVal bindings type signature to Bindings | None. Fix
double-space typo in deprecation message.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 8, 2026 15:36
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

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

Comment thread src/linkml_map/transformer/object_transformer.py Outdated
…g-expr

# Conflicts:
#	src/linkml_map/datamodel/transformer_model.py
#	src/linkml_map/transformer/object_transformer.py
After the _derive_slot extraction, bindings is always initialized
unconditionally in map_object, so the | None is no longer needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 8, 2026 19:45
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

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

Comment thread src/linkml_map/transformer/transformer.py Outdated
amc-corey-cox and others added 2 commits April 8, 2026 16:57
Instead of adding expr to KeyVal (which polluted the shared slot
namespace and required a ReferenceValidator shim), add a dedicated
expression_mappings field on ElementDerivation. KeyVal stays clean
(key + value only), the _expand_keyval_dicts shim is removed, and
the runtime handles expression_mappings as a fallback after
value_mappings in _derive_slot.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 8, 2026 21:59
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

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

Comment thread src/linkml_map/datamodel/transformer_model.yaml
Comment thread src/linkml_map/datamodel/transformer_model.yaml
YAML silently coerces unquoted true/false to booleans and bare
numbers to integers, causing silent lookup misses against the
stringified source value. Note this in value_mappings and
expression_mappings descriptions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@amc-corey-cox
Copy link
Copy Markdown
Contributor Author

Hold on deprecating expression_to_value_mappings

While reviewing issue #99 (scalar binning for enums), we found a compelling use case for expression_to_value_mappings on enum derivations.

The pattern: when a slot derivation routes a numeric (or string) value to a target enum via range: TargetEnum, the enum derivation needs a way to classify that value into a PV. expression_to_value_mappings fits naturally here — the keys are boolean expressions using value(), and the values are target PV names:

enum_derivations:
  BPCategoryEnum:
    expression_to_value_mappings:
      "value() <= 89": LOW
      "value() >= 90 and value() <= 119": NORMAL
      "value() >= 120 and value() <= 139": HIGH
      "value() >= 140": VERY_HIGH

This avoids the semantic overloading problem we'd have if we reused expression_mappings (which means something different on slot derivations).

expression_to_expression_mappings still has no compelling use case — we can proceed with deprecating that one. But expression_to_value_mappings should stay.

expression_to_value_mappings has a compelling use case on enum
derivations for scalar binning (issue #99). Remove the deprecation
and update the description to reflect the intended usage: boolean
expression keys evaluated with value() for classifying incoming
values into permissible values.

expression_to_expression_mappings remains deprecated.
Copilot AI review requested due to automatic review settings April 13, 2026 16:05
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

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

Comment thread src/linkml_map/datamodel/transformer_model.yaml
Comment thread src/linkml_map/transformer/object_transformer.py
When both tables contain the same key, value_mappings (literal)
should win. Locks in the documented fallthrough behavior.
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.

Extend value_mappings to support expr values

2 participants