The assertion at the end of the following code fails because there is no space between walk
and True
in the yaml:
import yaml
from pydantic import BaseModel, parse_obj_as
from typing import List
class path_cls (BaseModel):
path : str
walk : bool = False
other : bool = False
class myschema (BaseModel):
paths: List[path_cls]
ydata = yaml.safe_load("""\
---
paths:
- {path: .., walk:True }
- {path: ../../somefolder }
""")
data = parse_obj_as(myschema, ydata)
assert data.paths[0].walk
Since walk:True
represents a valid YAML scalar, and because walk
is an optional attribute in path_cls
, neither the parser nor the validator see a problem.
In my schema, there will never be a case where {key:value, scalar}
makes sense.
How do I get pydantic to recognize walk:True
as an error? And is there a general solution that would flag a bad mapping of any optional attribute?
You can configure pydantic to throw an error if the input data contains any unexpected fields (docs). If you write your code like this:
import yaml
from pydantic import BaseModel, ConfigDict
from typing import List
class path_cls(BaseModel):
model_config = ConfigDict(extra="forbid")
path: str
walk: bool = False
other: bool = False
class myschema(BaseModel):
paths: List[path_cls]
ydata = yaml.safe_load("""\
---
paths:
- {path: .., walk:True }
- {path: ../../somefolder }
""")
data = myschema.parse_obj(ydata)
print(data)
assert data.paths[0].walk
Then it will fail with:
pydantic_core._pydantic_core.ValidationError: 1 validation error for myschema
paths.0.walk:True
Extra inputs are not permitted [type=extra_forbidden, input_value=None, input_type=NoneType]
For further information visit https://errors.pydantic.dev/2.7/v/extra_forbidden