Search code examples
pythonyamlpydantic

How do I get pydantic to report a violation if a YAML mapping to an optional attribute omits the space after the colon?


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?


Solution

  • 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