Initial Working $ref Keyword with: ForwardRef, Partial Root Ref and Recursive Ref
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
from jambo.parser import ObjectTypeParser, RefTypeParser
|
||||
|
||||
from typing_extensions import ForwardRef, get_type_hints
|
||||
|
||||
from unittest import TestCase
|
||||
|
||||
|
||||
@@ -25,6 +23,7 @@ class TestRefTypeParser(TestCase):
|
||||
"person",
|
||||
properties,
|
||||
context=properties,
|
||||
ref_cache={},
|
||||
required=True,
|
||||
)
|
||||
|
||||
@@ -46,38 +45,101 @@ class TestRefTypeParser(TestCase):
|
||||
"$ref": "#",
|
||||
},
|
||||
},
|
||||
"required": ["name", "age"],
|
||||
}
|
||||
|
||||
type_parsing, type_validator = ObjectTypeParser().from_properties(
|
||||
model, type_validator = ObjectTypeParser().from_properties(
|
||||
"person",
|
||||
properties,
|
||||
context=properties,
|
||||
ref_cache={},
|
||||
required=True,
|
||||
)
|
||||
type_parsing.update_forward_refs(person=type_parsing)
|
||||
|
||||
self.assertIsInstance(type_parsing, type)
|
||||
obj = model(
|
||||
name="John",
|
||||
age=30,
|
||||
emergency_contact=model(
|
||||
name="Jane",
|
||||
age=28,
|
||||
),
|
||||
)
|
||||
|
||||
type_hints = get_type_hints(type_parsing, globals(), locals())
|
||||
self.assertEqual(obj.name, "John")
|
||||
self.assertEqual(obj.age, 30)
|
||||
self.assertIsInstance(obj.emergency_contact, model)
|
||||
self.assertEqual(obj.emergency_contact.name, "Jane")
|
||||
self.assertEqual(obj.emergency_contact.age, 28)
|
||||
|
||||
self.assertIsInstance(type_hints["emergency_contact"], ForwardRef)
|
||||
def test_ref_type_parser_forward_ref_can_checks_validation(self):
|
||||
properties = {
|
||||
"title": "person",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"age": {"type": "integer"},
|
||||
"emergency_contact": {
|
||||
"$ref": "#",
|
||||
},
|
||||
},
|
||||
"required": ["name", "age"],
|
||||
}
|
||||
|
||||
"""
|
||||
This is a example of how to resolve ForwardRef in a dynamic model:
|
||||
```python
|
||||
from typing import get_type_hints
|
||||
|
||||
# Make sure your dynamic model has a name
|
||||
model = type_parsing
|
||||
model.update_forward_refs(person=model) # 👈 resolve the ForwardRef("person")
|
||||
|
||||
# Inject into globals manually
|
||||
globalns = globals().copy()
|
||||
globalns['person'] = model
|
||||
|
||||
# Now you can get the resolved hints
|
||||
type_hints = get_type_hints(model, globalns=globalns)
|
||||
```
|
||||
Use `TypeParserOptions.ref_cache` option to cache and resolve ForwardRefs
|
||||
inside the ObjectTypeParser.to_model method.
|
||||
"""
|
||||
model, type_validator = ObjectTypeParser().from_properties(
|
||||
"person",
|
||||
properties,
|
||||
context=properties,
|
||||
ref_cache={},
|
||||
required=True,
|
||||
)
|
||||
|
||||
# checks if when created via FowardRef the model is validated correctly.
|
||||
with self.assertRaises(ValueError):
|
||||
model(
|
||||
name="John",
|
||||
age=30,
|
||||
emergency_contact=model(
|
||||
name="Jane",
|
||||
),
|
||||
)
|
||||
|
||||
def test_ref_type_parser_with_ciclic_def(self):
|
||||
properties = {
|
||||
"title": "person",
|
||||
"$ref": "#/$defs/person",
|
||||
"$defs": {
|
||||
"person": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"age": {"type": "integer"},
|
||||
"emergency_contact": {
|
||||
"$ref": "#/$defs/person",
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
model, type_validator = RefTypeParser().from_properties(
|
||||
"person",
|
||||
properties,
|
||||
context=properties,
|
||||
ref_cache={},
|
||||
required=True,
|
||||
)
|
||||
|
||||
obj = model(
|
||||
name="John",
|
||||
age=30,
|
||||
emergency_contact=model(
|
||||
name="Jane",
|
||||
age=28,
|
||||
),
|
||||
)
|
||||
|
||||
self.assertEqual(obj.name, "John")
|
||||
self.assertEqual(obj.age, 30)
|
||||
self.assertIsInstance(obj.emergency_contact, model)
|
||||
self.assertEqual(obj.emergency_contact.name, "Jane")
|
||||
self.assertEqual(obj.emergency_contact.age, 28)
|
||||
|
||||
Reference in New Issue
Block a user