Hey all,
Happy New Year! Just wanted to spread the word that there is now a new
trove classifier <https://github.com/pypa/trove-classifiers/pull/88> for
stub-only distributions, "Typing :: Stubs Only".
The difference between "Typing :: Typed" and "Typing :: Stubs Only" is that
"Typing :: Typed" should be used for distributions with runtime code,
whereas "Typing :: Stubs Only" should be used for distributions that
provide "*-stubs" packages for another package.
I'm not sure what the process is to have this deployed in Warehouse, so I
don't know when it will be usable.
Best,
Ethan
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?