Skip to content

Add validation of parsed general input - #950

Merged
SAKavli merged 3 commits into
equinor:mainfrom
SAKavli:rework-base-input-validation
Aug 27, 2026
Merged

Add validation of parsed general input#950
SAKavli merged 3 commits into
equinor:mainfrom
SAKavli:rework-base-input-validation

Conversation

@SAKavli

@SAKavli SAKavli commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

The existing validation is validating the config dict generated by various steps when parsing the excel file to a config dict.

It makes sense to have a validation step earlier in the loop which validates the raw input from the excel file to give a more relevant exception feedback to unchanged values.

This validation should not edit any values, only validate the input - except for validation of existing files relative to the excel input_filename

@SAKavli SAKavli added this to SCOUT Aug 18, 2026
@SAKavli SAKavli moved this to In Progress in SCOUT Aug 18, 2026
@SAKavli
SAKavli force-pushed the rework-base-input-validation branch 5 times, most recently from c69b9cc to 44a9616 Compare August 19, 2026 09:44
Comment thread src/semeio/fmudesign/config_validation.py
@SAKavli SAKavli moved this from In Progress to Ready for Review in SCOUT Aug 19, 2026
@SAKavli
SAKavli requested a review from larsevj August 19, 2026 09:52
@larsevj
larsevj marked this pull request as ready for review August 19, 2026 09:55
@SAKavli

SAKavli commented Aug 19, 2026

Copy link
Copy Markdown
Contributor Author

I'm thinking the next step would be to create a class for GeneralInput to ease the validation and reduce the amount of dictionaries floating around.

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

Adds an early validation step for the “general input” sheet values parsed from Excel, aiming to produce more relevant validation errors before the config dict is further processed.

Changes:

  • Introduces validate_general_input and supporting validation/error types for raw general input.
  • Moves resolve_path into fmudesign.utils and updates Excel parsing to use it.
  • Updates tests: adds a dedicated general-input validation test suite and removes some seed-strategy tests from config validation.

Reviewed changes

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

Show a summary per file
File Description
tests/fmudesign/test_general_input_validation.py New test coverage for early/raw general input validation behavior.
tests/fmudesign/test_config_validation.py Removes seed-strategy validation tests that are now expected to be covered earlier.
src/semeio/fmudesign/utils.py Adds shared resolve_path helper (moved from _excel_to_dict).
src/semeio/fmudesign/general_input_validation.py New raw general input validator and related error types.
src/semeio/fmudesign/config_validation.py Simplifies validation/normalization logic (now relies more on earlier validation).
src/semeio/fmudesign/_excel_to_dict.py Invokes new validate_general_input after parsing the general input sheet.
Suppressed comments (2)

src/semeio/fmudesign/config_validation.py:43

  • validate_configuration no longer coerces/validates correlation_iterations (and distribution_seed) when provided. Since downstream code compares correlation_iterations > 0 and seeds numpy RNGs, leaving these as strings/floats can cause runtime TypeError even if earlier validation succeeded.
    key = "correlation_iterations"
    if key not in config:
        if verbosity > 0:
            print(f"{key!r} not set in general input sheet. Setting to default 0.")
            print("  - When set to 0, Iman Conover is used to induce correlations.")

tests/fmudesign/test_general_input_validation.py:299

  • Typo in test name: "sesntivity" -> "sensitivity".
def test_seed_strategy_does_not_raise_given_case_sesntivity(seed_strategy):
    _setup_and_validate_config({"seed_strategy": seed_strategy})

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/semeio/fmudesign/general_input_validation.py Outdated
Comment thread src/semeio/fmudesign/general_input_validation.py Outdated
Comment thread src/semeio/fmudesign/utils.py
Comment thread tests/fmudesign/test_general_input_validation.py Outdated
@SAKavli SAKavli self-assigned this Aug 19, 2026
@SAKavli
SAKavli force-pushed the rework-base-input-validation branch from 70460d0 to 20b8880 Compare August 19, 2026 10:55
Comment thread src/semeio/fmudesign/config_validation.py
@SAKavli SAKavli moved this from Ready for Review to In Progress in SCOUT Aug 20, 2026
@SAKavli
SAKavli force-pushed the rework-base-input-validation branch 10 times, most recently from a8b69d8 to eb3b4f8 Compare August 21, 2026 13:34

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

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

Comment thread src/semeio/fmudesign/general_input.py
@SAKavli
SAKavli force-pushed the rework-base-input-validation branch 2 times, most recently from 192b260 to 7129472 Compare August 25, 2026 13:44
@SAKavli

SAKavli commented Aug 25, 2026

Copy link
Copy Markdown
Contributor Author

I've reworked the approach quite a bit from previous feedback, ended up squashing the fixups as I didn't bother constantly rebasing 12 fixup commits 😅

@SAKavli
SAKavli requested a review from larsevj August 25, 2026 13:48
@SAKavli SAKavli moved this from Reviewed to Ready for Review in SCOUT Aug 25, 2026
@SAKavli SAKavli moved this from Ready for Review to In Progress in SCOUT Aug 26, 2026
@SAKavli
SAKavli force-pushed the rework-base-input-validation branch 2 times, most recently from c37da17 to 0824e23 Compare August 26, 2026 07:23
Comment thread src/semeio/fmudesign/general_input.py Outdated
Comment thread src/semeio/fmudesign/general_input.py Outdated

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

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

Suppressed comments (1)

src/semeio/fmudesign/utils.py:268

  • The documented fallback is not implemented: a missing reference ending in xlsx or csv reaches line 290 and raises ValueError instead of returning reference. Update the contract so callers know that unresolved file-like references raise.
def resolve_path(input_filename: str, reference: str | None) -> str | None:
    """The path `input_filename` is an Excel sheet, and `reference` is a cell
    value that *might* be a reference to another file. Resolve the path to
    `reference` and return. If no such file exists, return `reference`.
    """

Comment thread src/semeio/fmudesign/_excel_to_dict.py
@SAKavli SAKavli moved this from In Progress to Ready for Review in SCOUT Aug 26, 2026
Comment thread src/semeio/fmudesign/_excel_to_dict.py Outdated
Comment thread src/semeio/fmudesign/general_input.py Outdated
Comment thread src/semeio/fmudesign/general_input.py Outdated
Comment thread src/semeio/fmudesign/_excel_to_dict.py Outdated
Comment thread src/semeio/fmudesign/fmudesignrunner.py Outdated
@larsevj larsevj moved this from Ready for Review to Reviewed in SCOUT Aug 26, 2026
Creating new files quickly create circular dependencies with
_excel_to_dict.py.

Spreading these functions accross multiple files eases the dependency
problems.
@SAKavli

SAKavli commented Aug 26, 2026

Copy link
Copy Markdown
Contributor Author

The only issue I'm aware of now is the validation message of rms_seeds. The message is fine, but the error type is weird:

rms_seeds.function-after[validate_file(), lax-or-strict[lax=union[json-or-python[json=function-after[path_validator(), str],python=is-instance[Path]],function-after[path_validator(), str]],strict=json-or-python[json=function-after[path_validator(), str],python=is-instance[Path]]]]
  Path does not point to a file [type=path_not_file, input_value='defaultt', input_type=str]
rms_seeds.literal['default']
  Input should be 'default' [type=literal_error, input_value='defaultt', input_type=str]

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

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

Suppressed comments (1)

src/semeio/fmudesign/utils.py:268

  • The docstring still says an unresolved reference is returned, but a missing .csv/.xlsx reference reaches line 290 and raises ValueError. Document the extension-dependent behavior and exception so callers can rely on the actual contract.
def resolve_path(input_filename: str, reference: str | None) -> str | None:
    """The path `input_filename` is an Excel sheet, and `reference` is a cell
    value that *might* be a reference to another file. Resolve the path to
    `reference` and return. If no such file exists, return `reference`.
    """

Comment thread src/semeio/fmudesign/general_input.py Outdated
Comment thread src/semeio/fmudesign/_excel_to_dict.py Outdated
Comment thread tests/fmudesign/test_fmudesignrunner.py Outdated
Comment thread src/semeio/fmudesign/general_input.py

@field_serializer("rms_seeds", "background")
def serialize_paths(self, field: Path) -> str: # ruff: ignore[no-self-use]
return str(field)

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.

probably need an if check to only convert if is not None

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 call, also wrote test for this now.

Comment thread src/semeio/fmudesign/general_input.py Outdated
distribution_seed: NonNegativeInt | None
rms_seeds: FilePath | Literal["default"] | None
correlation_iterations: NonNegativeInt = 0
seed_strategy: SeedStrategy = SeedStrategy.JOINT

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.

Due to pydantics use_enum_values=True i think the default will differ from inputs, can set Field( default=SeedStrategy.JOINT, validate_default=True, )
to get the same behaviour in both cases.

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.

Also good call, wrote test for this as well.

@larsevj

larsevj commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

The only issue I'm aware of now is the validation message of rms_seeds. The message is fine, but the error type is weird:

rms_seeds.function-after[validate_file(), lax-or-strict[lax=union[json-or-python[json=function-after[path_validator(), str],python=is-instance[Path]],function-after[path_validator(), str]],strict=json-or-python[json=function-after[path_validator(), str],python=is-instance[Path]]]]
  Path does not point to a file [type=path_not_file, input_value='defaultt', input_type=str]
rms_seeds.literal['default']
  Input should be 'default' [type=literal_error, input_value='defaultt', input_type=str]

Should be fine for now.

@larsevj larsevj 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.

Very good! 💯

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

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants