Skip to content

Commit fc64400

Browse files
Make NullContext an alias of ContextBase
1 parent 97cea7b commit fc64400

File tree

4 files changed

+21
-15
lines changed

4 files changed

+21
-15
lines changed

ccflow/base.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,9 @@ class ContextBase(ResultBase):
829829

830830
@model_validator(mode="wrap")
831831
def _context_validator(cls, v, handler, info):
832+
if v is None:
833+
return handler({})
834+
832835
# Add deepcopy for v2 because it doesn't support copy_on_model_validation
833836
v = copy.deepcopy(v)
834837

ccflow/context.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,8 @@
9090

9191
_SEPARATOR = ","
9292

93-
94-
class NullContext(ContextBase):
95-
"""A Null Context that is used when no context is provided."""
96-
97-
@model_validator(mode="wrap")
98-
def _validate_none(cls, v, handler, info):
99-
v = v or {}
100-
return handler(v)
101-
93+
# Starting 0.8.0 Nullcontext is an alias to ContextBase
94+
NullContext = ContextBase
10295

10396
C = TypeVar("C", bound=Hashable)
10497

ccflow/tests/test_callable.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
CallableModelGenericType,
1212
ContextBase,
1313
ContextType,
14+
DateContext,
1415
Flow,
1516
GenericResult,
1617
GraphDepList,
@@ -50,6 +51,12 @@ def __call__(self, context: MyContext) -> MyResult:
5051
return MyResult(x=self.i, y=context.a)
5152

5253

54+
class MyCallableNullContext(CallableModel):
55+
@Flow.call
56+
def __call__(self, context: NullContext) -> MyResult:
57+
return MyResult(x=1, y="default")
58+
59+
5360
class MyCallableOptionalContext(CallableModel):
5461
@Flow.call
5562
def __call__(self, context: Optional[MyContext] = None) -> MyResult:
@@ -152,7 +159,7 @@ class BadModelMismatchedContextAndCall(CallableModel):
152159

153160
@property
154161
def context_type(self):
155-
return NullContext
162+
return DateContext
156163

157164
@property
158165
def result_type(self):
@@ -163,7 +170,7 @@ def __call__(self, context: MyContext) -> MyResult:
163170
return context
164171

165172

166-
class BadModelGenericMismatchedContextAndCall(CallableModelGenericType[NullContext, MyResult]):
173+
class BadModelGenericMismatchedContextAndCall(CallableModelGenericType[DateContext, MyResult]):
167174
"""Model with mismatched context_type and __call__ annotation"""
168175

169176
@Flow.call
@@ -405,6 +412,11 @@ def test_signature(self):
405412
self.assertRaises(TypeError, m, context, a="foo")
406413
self.assertRaises(TypeError, m, context=context, a="foo")
407414

415+
def test_nullable_context(self):
416+
m = MyCallableNullContext()
417+
context = MyContext(a="foo")
418+
self.assertEqual(m(context=context), m(None))
419+
408420
def test_signature_optional_context(self):
409421
m = MyCallableOptionalContext()
410422
context = MyContext(a="foo")
@@ -460,7 +472,7 @@ def test_types(self):
460472
error = "__call__ method must take a single argument, named 'context'"
461473
self.assertRaisesRegex(ValueError, error, BadModelDoubleContextArg)
462474

463-
error = "The context_type <class 'ccflow.context.NullContext'> must match the type of the context accepted by __call__ <class 'ccflow.tests.test_callable.MyContext'>"
475+
error = "The context_type <class 'ccflow.context.DateContext'> must match the type of the context accepted by __call__ <class 'ccflow.tests.test_callable.MyContext'>"
464476
self.assertRaisesRegex(ValueError, error, BadModelMismatchedContextAndCall)
465477

466478
error = "The result_type <class 'ccflow.result.generic.GenericResult'> must match the return type of __call__ <class 'ccflow.tests.test_callable.MyResult'>"
@@ -642,7 +654,7 @@ def __call__(self, context: NullContext) -> GenericResult[float]:
642654
MyCallable()
643655

644656
def test_types_generic(self):
645-
error = "Context type annotation <class 'ccflow.tests.test_callable.MyContext'> on __call__ does not match context_type <class 'ccflow.context.NullContext'> defined by CallableModelGenericType"
657+
error = "Context type annotation <class 'ccflow.tests.test_callable.MyContext'> on __call__ does not match context_type <class 'ccflow.context.DateContext'> defined by CallableModelGenericType"
646658
self.assertRaisesRegex(TypeError, error, BadModelGenericMismatchedContextAndCall)
647659

648660
error = "Return type annotation <class 'ccflow.tests.test_callable.MyResult'> on __call__ does not match result_type <class 'ccflow.result.generic.GenericResult'> defined by CallableModelGenericType"

ccflow/tests/test_context.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,6 @@ def setUp(self):
228228
for name, obj in inspect.getmembers(ctx, inspect.isclass)
229229
if obj.__module__ == ctx.__name__ and issubclass(obj, ContextBase) and not getattr(obj, "__deprecated__", False)
230230
}
231-
# TODO - remove NullContext until we fix the inheritance
232-
self.classes.pop("NullContext")
233231

234232
def test_field_ordering(self):
235233
"""Test that complex contexts have fields in the same order as the basic contexts they are composed of."""

0 commit comments

Comments
 (0)