Consider I have a python class that has a attributes (i.e. a dataclass, pydantic, attrs, django model, ...) that consist of a union, i.e. None and and a state. Now I have a complex checking function that checks some values.
If I use this checking function, I want to tell the type checker, that some of my class attributes are narrowed.
For instance see this simplified example:
import dataclasses
from typing import TypeGuard
@dataclasses.dataclass
class SomeDataClass:
state: tuple[int, int] | None
name: str
# Assume many more data attributes
class SomeDataClassWithSetState(SomeDataClass):
state: tuple[int, int]
def complex_check(data: SomeDataClass) -> TypeGuard[SomeDataClassWithSetState]:
# Assume some complex checks here, for simplicity it is only:
return data.state is not None and data.name.startswith("SPECIAL")
def get_sum(data: SomeDataClass) -> int:
if complex_check(data):
return data.state[0] + data.state[1]
return 0
As seen it is possible to do this with subclasses, which for various reason is not an option for me:
- it introduces a lot of duplication
- some possible libraries used for dataclasses are not happy with being subclasses without side condition
- there could be some Metaclass or
__subclasses__
magic that handles all subclass specially, i.e. creating database for the dataclasses
So is there an option to type narrow a(n) attribute(s) of a class without introducing a solely new class, as proposed here?
typing.TypeGuard
, which relies on two distinct types to be useful. It is not entirely clear, what your actual goal is, but my guess is thatTypeGuard
is not the way to get there. Based on your example, is your goal to have a type-safe way to assume theSomeDataClass.state
attribute is atuple
(and notNone
) in theget_sum
function? – Zebadacomplex_check
function is intended to be used everyhwhere in the code and I don't wantassert data.state is not None
calls in all the if branches, because this has already been verified bycomplex_check
. I only need the type checker to understand this. Also it is just a simple example, thecomplex_check
function could check a number of arguments, that could be potentially type narrowed. – Herbertherbicide