Skip to content

Update BaseModelWithContext with extra=forbid and fix tests#13457

Open
erlenlh wants to merge 2 commits into
mainfrom
update-base-model-with-context-support
Open

Update BaseModelWithContext with extra=forbid and fix tests#13457
erlenlh wants to merge 2 commits into
mainfrom
update-base-model-with-context-support

Conversation

@erlenlh
Copy link
Copy Markdown
Contributor

@erlenlh erlenlh commented Apr 30, 2026

Issue
Resolves #13444

Approach
Add extra=forbid flag to BaseModelWithContextSupport. Deal with downstream effect, adding to models or removing from tests where it seems fit.

(Screenshot of new behavior in GUI if applicable)

  • PR title captures the intent of the changes, and is fitting for release notes.
  • Added appropriate release note label
  • Commit history is consistent and clean, in line with the contribution guidelines.
  • Make sure unit tests pass locally after every commit (git rebase -i main --exec 'just rapid-tests')

When applicable

  • When there are user facing changes: Updated documentation
  • New behavior or changes to existing untested code: Ensured that unit tests are added (See Ground Rules).
  • Large PR: Prepare changes in small commits for more convenient review
  • Bug fix: Add regression test for the bug
  • Bug fix: Add backport label to latest release (format: 'backport release-branch-name')

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

This PR tightens Pydantic validation for ERT models by making BaseModelWithContextSupport forbid unknown fields, then adjusts affected run-model construction and unit tests to comply (issue #13444).

Changes:

  • Configure BaseModelWithContextSupport to use extra="forbid" (and update downstream call sites/tests impacted by stricter validation).
  • Update run-model serialization roundtrip tests to avoid validating computed/serialized-only fields.
  • Adjust Everest/ManualUpdate run-model construction/config so instantiation works under extra="forbid".

Reviewed changes

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

Show a summary per file
File Description
src/ert/base_model_context.py Makes context-enabled Pydantic base model forbid extra fields (and also enables arbitrary types).
src/ert/run_models/everest_run_model.py Adds fields to EverestRunModelConfig to satisfy stricter model validation; introduces optimization_callback handling as a config field.
src/ert/run_models/model_factory.py Stops passing observations into ManualUpdateConfig (now forbidden as an extra field).
tests/ert/unit_tests/run_models/test_experiment_serialization.py Excludes experiment_type from dumped payload when re-validating runmodels (to avoid extra="forbid" failures).
tests/ert/unit_tests/ensemble_evaluator/conftest.py Removes unsupported job_script argument from QueueConfig fixture construction.

Comment thread src/ert/run_models/everest_run_model.py Outdated
Comment thread src/ert/base_model_context.py Outdated
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 4, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.50%. Comparing base (3d0f102) to head (08882b1).
⚠️ Report is 4 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #13457      +/-   ##
==========================================
- Coverage   89.54%   89.50%   -0.05%     
==========================================
  Files         464      464              
  Lines       32778    32783       +5     
==========================================
- Hits        29351    29342       -9     
- Misses       3427     3441      +14     
Flag Coverage Δ
cli-tests 35.77% <64.28%> (+<0.01%) ⬆️
fuzz 43.95% <78.57%> (+<0.01%) ⬆️
gui-tests 59.82% <85.71%> (+<0.01%) ⬆️
performance-and-unit-tests 77.98% <100.00%> (-0.11%) ⬇️
test 45.41% <78.57%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/ert/base_model_context.py 100.00% <100.00%> (ø)
src/ert/run_models/everest_run_model.py 91.70% <100.00%> (+0.01%) ⬆️
src/ert/run_models/model_factory.py 97.72% <100.00%> (+0.03%) ⬆️
src/ert/run_models/run_model.py 92.25% <100.00%> (ø)
src/ert/run_models/run_model_configs.py 100.00% <100.00%> (ø)

... and 7 files with indirect coverage changes

@erlenlh erlenlh force-pushed the update-base-model-with-context-support branch from 74d18a9 to e138a24 Compare May 4, 2026 13:02
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 4, 2026

Merging this PR will not alter performance

✅ 36 untouched benchmarks


Comparing update-base-model-with-context-support (dcf4875) with main (7aa972d)

Open in CodSpeed

@erlenlh erlenlh force-pushed the update-base-model-with-context-support branch 2 times, most recently from dda17fb to dcf4875 Compare May 5, 2026 07:21
Comment thread src/ert/run_models/model_factory.py
Comment thread src/ert/run_models/everest_run_model.py Outdated
experiment_name: str
target_ensemble: str

controls: Annotated[list[ControlConfig], AfterValidator(unique_items)]
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 is a bit puzzling. How this could have worked in the first place?

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.

Not sure! Like we discussed, the values are definately used/assigned further below in the return cls(.... Seems like they should also exist here

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.

@oyvindeide wrote:

No, controls are parameters, those are not being used, and should not be in the constructor (nor the cls), there is no self.controls

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.

Ah great, thanks for clearing that up!

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.

assuming this holds for the other additions i made as well? objective_names, objective_functions, optimization_callback



class RunModel(RunModelConfig, ABC):
status_queue: queue.SimpleQueue[StatusEvents] = Field(exclude=True, repr=False)
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 can go back to be just a regular class attribute as before.

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.

I think it needs to stay as a field. Mypy is complaining about it if we keep is at attribute with strict pydantic settings.

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.

bilde

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.

What kind of events are consumed in status_queue? The downside is that this would do validation on each processing of a new event, which might just fine though.

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.

Image Image

running times on main and this seem identical, tested couple of times. UI also seems responsive 👍

ert_templates=config.ert_templates,
shape_registry=config.shape_registry,
)
return ManualUpdateEnIF(**runmodel_config.model_dump(), status_queue=status_queue)
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 should be tested. At least if parameters are propagated correctly.

Comment thread src/ert/run_models/run_model.py Outdated


class RunModelConfig(BaseModelWithContextSupport):
model_config = ConfigDict(arbitrary_types_allowed=True, extra="forbid")
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.

let's check if this is required.

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.

It seems to be needed, due to adding "status_queue" as a field to the runmodel.

hooked_workflows=config.hooked_workflows,
log_path=config.analysis_config.log_path,
ert_templates=config.ert_templates,
observations=config.observation_declarations,
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.

let's double-check if obs are not needed here.

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.

As far as i can tell, only observations from prior is used. Checked with Håvard, and he agrees

@erlenlh erlenlh force-pushed the update-base-model-with-context-support branch from dcf4875 to 85a3b11 Compare May 22, 2026 12:36
@erlenlh erlenlh force-pushed the update-base-model-with-context-support branch from 85a3b11 to 08882b1 Compare May 26, 2026 08:27
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.

Update BaseModelWithContextSupport to extra="forbid"

4 participants