pydantic / pydantic-core

Core validation logic for pydantic written in rust
MIT License
1.4k stars 235 forks source link

Add `patternProperty` validator #305

Open samuelcolvin opened 1 year ago

samuelcolvin commented 1 year ago

See https://github.com/pydantic/pydantic/discussions/3303.

We should allow the descriminator to be a regex or function.

nuno-andre commented 1 year ago

How would validators behave in this case? E.g.

class Model(BaseModel):
    prop_a: int

    class Config:
        extra_pattern = {r'^prop_': str}

    @validator(r'^prop_')
    def validate_props(cls, v) -> str:
        return v.upper()
samuelcolvin commented 1 year ago

I don't care about the python interface yet, let's work out how it should work in rust first.

I guess this should be added to TypedDictValidator.

I think the best solution would be to convert

https://github.com/pydantic/pydantic-core/blob/bcf799f0e8caa9774e839a2d8d30c7f4dd15852f/src/validators/typed_dict.rs#L36

Into

    patterns: Vec<PatternField>,

Where PatternField is

enum Pattern {
    Regex(Regex),
    Function(PyObject),
    All,
}

struct PatternField {
    descriminator: Pattern,
    validator: CombinedValidator,
}

Then

https://github.com/pydantic/pydantic-core/blob/bcf799f0e8caa9774e839a2d8d30c7f4dd15852f/src/validators/typed_dict.rs#L283

Becomes:

for pattern in self.patterns {
   if pattern.matches(value) {
        ...
  }
}

In python I guess patternProperties will have to be defined via config since we can't use attributes and annotations as we don't know what the key will be.

sydney-runkle commented 1 month ago

@samuelcolvin, is this still a relevant issue?