-
Following https://discuss.python.org/t/41483 where I couldn't find a viable solution (it would require typing features not yet implemented), I'm trying to find an alternative solution. TL;DR, The alternative I'm exploring is adding an extra type variable from typing_extensions import TypeVar
_NullT = TypeVar("_NullT", bound=bool, default=Literal[False])
class Field(Generic[_ST, _GT, _NullT]):
def __init__(self, null: _NullT = False):
...
class IntField(Field[int | float, int, _NullT]):
pass
f = IntField(null=True) In this example, _NullT = TypeVar("_NullT", Literal[False], Literal[True], default=Literal[False]) As I understand it, solving this type variable would result in either Code sample in pyright playground from typing import Any, Literal, Generic, overload
from typing_extensions import TypeVar
# __set__ value type
_ST = TypeVar("_ST", contravariant=True)
# __get__ return type
_GT = TypeVar("_GT", covariant=True)
_NullT = TypeVar("_NullT", Literal[True], Literal[False], default=Literal[False])
#_NullT = TypeVar("_NullT", bound=bool, default=Literal[False])
class Field(Generic[_ST, _GT, _NullT]):
def __init__(self, null: _NullT = False):
...
# Focusing on __get__ for now:
@overload
def __get__(self: Field[_ST, _GT, Literal[True]], instance: Model, owner: Any) -> _GT | None: ...
@overload
def __get__(self: Field[_ST, _GT, Literal[False]], instance: Model, owner: Any) -> _GT: ...
class IntField(Field[int | float, int, _NullT]):
pass
class Model:
f = IntField(null=True)
reveal_type(Model().f) Now something really weird is, with either the first or second With |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
python/mypy#10207 (comment) gives a nice solution, but it would be even better if inferred without any |
Beta Was this translation helpful? Give feedback.
Looks like a bug in pyright. You're doing something very unusual here — using literal types as value constraints. Pyright's constraint solver includes some heuristics about when to retain literals and when to widen the type to non-literals. I'm guessing that those heuristics are failing in this case. Please file a bug, and I'll investigate further.