Just - Exact Type Matching
Just is an invariant type "wrapper", where Just[T] only accepts instances of T,
and rejects instances of any strict subtypes of T.
Note that e.g. Literal[""] and LiteralString are not a strict str subtypes,
and are therefore assignable to Just[str], but instances of class S(str): ...
are not assignable to Just[str].
Disallow passing bool as int:
import optype as op
def assert_int(x: op.Just[int]) -> int:
assert type(x) is int
return x
assert_int(42) # ok
assert_int(False) # rejected
Annotating a sentinel:
import optype as op
_DEFAULT = object()
def intmap(
value: int,
# same as `dict[int, int] | op.Just[object]`
mapping: dict[int, int] | op.JustObject = _DEFAULT,
/,
) -> int:
# same as `type(mapping) is object`
if isinstance(mapping, op.JustObject):
return value
return mapping[value]
intmap(1) # ok
intmap(1, {1: 42}) # ok
intmap(1, "some object") # rejected
Tip
The Just{Bytes,Int,Float,Complex,Date,Object} protocols are runtime-checkable,
so that instance(42, JustInt) is True and instance(bool(), JustInt) is False.
It's implemented through meta-classes, and type-checkers have no problem with it.
optype type |
accepts instances of |
|---|---|
Just[~T] |
T |
JustInt |
builtins.int |
JustFloat |
builtins.float |
JustComplex |
builtins.complex |
JustBytes |
builtins.bytes |
JustObject |
builtins.object |
JustDate |
datetime.date |