Reputation: 383
I am working on Python code where the domain logic makes it natural to have a class with an optional field of a second class, which itself has an optional field of a third class. Boiling it down to a minimum working example, this is what I mean:
class C:
def __init__(self, number: int) -> None:
self.number = number
class B:
def __init__(self, c: C | None) -> None:
self.c = c
class A:
def __init__(self, b: B | None) -> None:
self.b = b
At some point in our code, we are receiving an object a
of class A
where we know that the field a.b
is not None
and furthermore that that the nested field a.b.c
is not None
. Of course, mypy does not know this and sensibly informs us that we might be doing something stupid:
# Here is an object where it is guaranteed that we won't encounter None values
a = A( B( C(1337) ) )
print(a.b.c.number) # mypy sensibly returns two errors:
# Item "None" of "B | None" has no attribute "c"
# Item "None" of "C | Any | None" has no attribute "number"
# This satisfies mypy:
assert (a.b is not None) and (a.b.c is not None)
print(a.b.c.number)
This assert
statement works perfectly well, but it looks cumbersome when our fields names are longer and the nesting goes deeper. Is there a neater and shorter way to satisfy mypy?
Upvotes: 0
Views: 111