I have a class with some fields being Optional. Some uses of that class don't require those fields to be present, but others do. Is there a way to get mypy to diagnose those misuses?
Example:
import attr
from typing import *
@attr.s(auto_attribs=True, frozen=True)
class Point:
x : int
y : Optional[int] = None
def get_x(s : Point) -> int:
return s.x
def get_y(s : Point) -> int:
assert s.y is not None
return s.y
def get_y_from_x(x : int) -> int:
return get_y(Point(x=x)) # <== oops
This program is mypy-clean, despite get_y_from_x
passing get_y
a Point
whose y
is None
. This will assert at runtime.
Without the assert
, mypy correctly complains about the incompatible return type - that get_y
returns an Optional[int]
when it claims to return an int
.
Basically my question boils down to: is there a way for mypy to be able to diagnose the line marked oops
above?
I suppose the right way to phrase this question is: get_y
currently is annotated to say that s
is a Point
. But that's not entirely true, it's really a particular kind of Point
where s.y
is an int
. Is that expressible?