pydantic / pydantic-core

Core validation logic for pydantic written in rust
MIT License
1.45k stars 247 forks source link

Add fail-fast for dicts, model and dataclass #1543

Open uriyyo opened 1 week ago

uriyyo commented 1 week ago

Change Summary

Add fail-fast feature to:

Related issue number

1345

Checklist

uriyyo commented 1 week ago

please review

codecov[bot] commented 1 week ago

Codecov Report

Attention: Patch coverage is 94.44444% with 2 lines in your changes missing coverage. Please review.

Project coverage is 89.60%. Comparing base (ab503cb) to head (5dd9abd). Report is 230 commits behind head on main.

Files with missing lines Patch % Lines
src/validators/dict.rs 87.50% 1 Missing :warning:
src/validators/typed_dict.rs 88.88% 1 Missing :warning:
Additional details and impacted files ```diff @@ Coverage Diff @@ ## main #1543 +/- ## ========================================== - Coverage 90.21% 89.60% -0.61% ========================================== Files 106 112 +6 Lines 16339 17931 +1592 Branches 36 40 +4 ========================================== + Hits 14740 16067 +1327 - Misses 1592 1844 +252 - Partials 7 20 +13 ``` | [Files with missing lines](https://app.codecov.io/gh/pydantic/pydantic-core/pull/1543?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydantic) | Coverage Δ | | |---|---|---| | [python/pydantic\_core/core\_schema.py](https://app.codecov.io/gh/pydantic/pydantic-core/pull/1543?src=pr&el=tree&filepath=python%2Fpydantic_core%2Fcore_schema.py&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydantic#diff-cHl0aG9uL3B5ZGFudGljX2NvcmUvY29yZV9zY2hlbWEucHk=) | `94.86% <100.00%> (+0.10%)` | :arrow_up: | | [src/validators/dataclass.rs](https://app.codecov.io/gh/pydantic/pydantic-core/pull/1543?src=pr&el=tree&filepath=src%2Fvalidators%2Fdataclass.rs&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydantic#diff-c3JjL3ZhbGlkYXRvcnMvZGF0YWNsYXNzLnJz) | `89.31% <100.00%> (-9.07%)` | :arrow_down: | | [src/validators/model\_fields.rs](https://app.codecov.io/gh/pydantic/pydantic-core/pull/1543?src=pr&el=tree&filepath=src%2Fvalidators%2Fmodel_fields.rs&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydantic#diff-c3JjL3ZhbGlkYXRvcnMvbW9kZWxfZmllbGRzLnJz) | `95.18% <100.00%> (-1.29%)` | :arrow_down: | | [src/validators/dict.rs](https://app.codecov.io/gh/pydantic/pydantic-core/pull/1543?src=pr&el=tree&filepath=src%2Fvalidators%2Fdict.rs&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydantic#diff-c3JjL3ZhbGlkYXRvcnMvZGljdC5ycw==) | `96.84% <87.50%> (-0.04%)` | :arrow_down: | | [src/validators/typed\_dict.rs](https://app.codecov.io/gh/pydantic/pydantic-core/pull/1543?src=pr&el=tree&filepath=src%2Fvalidators%2Ftyped_dict.rs&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydantic#diff-c3JjL3ZhbGlkYXRvcnMvdHlwZWRfZGljdC5ycw==) | `89.66% <88.88%> (-2.39%)` | :arrow_down: | ... and [49 files with indirect coverage changes](https://app.codecov.io/gh/pydantic/pydantic-core/pull/1543/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydantic) ------ [Continue to review full report in Codecov by Sentry](https://app.codecov.io/gh/pydantic/pydantic-core/pull/1543?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydantic). > **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydantic) > `Δ = absolute (impact)`, `ø = not affected`, `? = missing data` > Powered by [Codecov](https://app.codecov.io/gh/pydantic/pydantic-core/pull/1543?dropdown=coverage&src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydantic). Last update [6472887...5dd9abd](https://app.codecov.io/gh/pydantic/pydantic-core/pull/1543?dropdown=coverage&src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydantic). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydantic).
codspeed-hq[bot] commented 1 week ago

CodSpeed Performance Report

Merging #1543 will not alter performance

Comparing uriyyo:more-fail-fast (5dd9abd) with main (6472887)

Summary

✅ 155 untouched benchmarks

uriyyo commented 1 week ago

After implementing this feature I thought maybe it's make sense to add kinda validation context structure to not duplicate fail-fast check logic, it can look like this:

struct ValidationContext {
    fail_fast: bool,
    errors: Vec<ValLineError>,
}

impl ValidationContext {
    fn new(fail_fast: bool) -> Self {
        Self {
            fail_fast,
            errors: Vec::new(),
        }
    }

    fn default() -> Self {
        return Self::new(false);
    }

    fn should_stop(self) -> bool {
        self.fail_fast && self.has_errors()
    }

    fn has_errors(self) -> bool {
        !self.errors.is_empty()
    }

    fn add_error(mut self, error: ValLineError) {
        self.errors.push(error);
    }
}