I really like the `NotType` idea. I've seen several real-life use-cases when I needed it. I would love to help on the PEP's draft. Drop me a line if you wish! чт, 23 дек. 2021 г. в 16:48, James H-B <gobot1234yt@gmail.com>:
Hi,
I'd like to write a PEP for a new typing construct: NotType which, would be equivalent to any type but x. There has been an issue open on the typing repo for quite some time about this ( https://github.com/python/typing/issues/801). After the recent-ish proposal for an IntersectionType, this would be a nice-to-have feature as it would complete the set theory operations for typed Python. I'd also like to propose implementing type.__invert__ to make this work, so it has built-in syntax like intersection and union as this is the closest thing to a not operator.
Usecases:
Something that takes any non-empty string ```py def fn(x: str & ~Literal[""]): ... ``` This also has nice integration with PEP 675 where the type of a Literal str is important. If you’d want to call this from any str you’d need a type guard. ```py def guard(x: str) -> TypeGuard[str & ~Literal[“”]]: return isinstance(x, str) and x != “” # or maybe bool(x) although this is probably much harder to implement ```
Something that takes any value but None ```py def fn(x: ~Literal[None]): ... ```
Something that requires not an integer ```py def not_an_int(x: Any) -> TypeGuard[~int]: ... ``` This also allows for narrowing in the negative case which is another requested feature (https://github.com/python/typing/issues/926) ```py @overload def is_none(value: None) -> Literal[True]: ... @overload def is_none(value: ~Literal[None]) -> Literal[False]: ... def is_none(value: Any) -> bool: return value is None
def func(value: Optional[str]): if is_none(value): reveal_type(value) # None else: reveal_type(value) # str ``` Currently this isn’t the case ```py def is_none(value: Any) -> TypeGuard[None]: return value is None
def func(value: Optional[str]): if is_none(value): reveal_type(value) # None else: reveal_type(value) # str | None ```
Overloading operators more correctly, more easily ```py @overload def __eq__(self, other: ~Self) -> Literal[False]: ... @overload def __eq__(self, other: Self) -> bool: ... def __eq__(self, other: object) -> bool: return isinstance(other, self.__class__) and ... ```
Something fun ```py reveal_type(~~str) # str ```
A few questions: Can you see any issues here? Do you have ideas for use cases I haven't thought of? Does anybody want to be a co-author on this? _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: n.a.sobolev@gmail.com