@@ -304,6 +304,10 @@ def prop(self) -> bool:
304304def test_propertyinfo (mocker ):
305305 """Test out the PropertyInfo class."""
306306
307+ class MyModel (pydantic .BaseModel ):
308+ a : int
309+ b : str
310+
307311 class Example (lt .Thing ):
308312 intprop : int = lt .property (default = 0 )
309313 """A normal, simple, integer property."""
@@ -317,6 +321,17 @@ class Example(lt.Thing):
317321 tupleprop : tuple [int , str ] = lt .property (default = (42 , "the answer" ))
318322 """A tuple property, to check subscripted generics work."""
319323
324+ modelprop : MyModel = lt .property (default_factory = lambda : MyModel (a = 1 , b = "two" ))
325+ """A property typed as a model."""
326+
327+ rootmodelprop : pydantic .RootModel [int | None ] = lt .property (
328+ default_factory = lambda : pydantic .RootModel [int | None ](root = None )
329+ )
330+ """A very verbosely defined optional integer.
331+
332+ This tests a model that's also a subscripted generic.
333+ """
334+
320335 # We will break `badprop` by setting its model to something that's
321336 # neither the type nor a rootmodel.
322337 badprop = Example .badprop
@@ -373,6 +388,28 @@ class BadIntModel(pydantic.BaseModel):
373388 with pytest .raises (pydantic .ValidationError ):
374389 tupleprop .validate (val )
375390
391+ # Check validation for a model
392+ modelprop = example .properties ["modelprop" ]
393+ assert modelprop .validate (MyModel (a = 3 , b = "four" )) == MyModel (a = 3 , b = "four" )
394+ m = MyModel (a = 3 , b = "four" )
395+ assert modelprop .validate (m ) is m
396+ assert modelprop .validate ({"a" : 5 , "b" : "six" }) == MyModel (a = 5 , b = "six" )
397+ for invalid in [{"c" : 5 }, (4 , "f" ), None ]:
398+ with pytest .raises (pydantic .ValidationError ):
399+ modelprop .validate (invalid )
400+
401+ # Check again for an odd rootmodel
402+ rootmodelprop = example .properties ["rootmodelprop" ]
403+ m = rootmodelprop .validate (42 )
404+ assert isinstance (m , pydantic .RootModel )
405+ assert m .root == 42
406+ assert m == pydantic .RootModel [int | None ](root = 42 )
407+ assert rootmodelprop .validate (m ) is m # RootModel passes through
408+ assert rootmodelprop .validate (None ).root is None
409+ for invalid in ["seven" , {"root" : None }, 14.5 , pydantic .RootModel [int ](root = 0 )]:
410+ with pytest .raises (pydantic .ValidationError ):
411+ modelprop .validate (invalid )
412+
376413
377414def test_readonly_metadata ():
378415 """Check read-only data propagates to the Thing Description."""
0 commit comments