Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve ellipsis type #686

Open
aaronmondal opened this issue Sep 15, 2023 · 4 comments
Open

Improve ellipsis type #686

aaronmondal opened this issue Sep 15, 2023 · 4 comments
Labels
topic: Static Typing Static typing.

Comments

@aaronmondal
Copy link
Contributor

aaronmondal commented Sep 15, 2023

The current ellipsis = TypeVar('ellipsis') doesn't behave well with typechecking. It's also unclear in the Markdown docs what ellipsis is supposed to be. It's kind of clear from the context, but not compatible with "real" python types:

from types import EllipsisType
from typing import Protocol, TypeVar

ellipsis = TypeVar('ellipsis')  # This is the current implementation.

class BadProto(Protocol):
    def f(self, ell: ellipsis) -> None: ...  # Error: TypeVar "ellipsis" appears onlly once in generic function signature


class GoodProto(Protocol):
    def f(self, ell: EllipsisType) -> None: ...  # Ok, no error raised.


def some_bad_operation(x: BadProto) -> None:
    x.f('hello')  # Problematic: doesn't raise a type error.

def some_good_operation(x: GoodProto) -> None:
    x.f('hello')  # Good, raises:
    # [Pyright] Argument of type "Literal['hello']" cannot be assigned to parameter "ell" of type "EllipsisType" in function "f"
    #   "Literal['hello']" is incompatible with "EllipsisType"

The downside of EllipsisType is that it's only available in Python 3.10 onwards. However, we have the following:

assert EllipsisType == type(...)
assert EllipsisType == type(Ellipsis)
assert EllipsisType != ...
assert EllipsisType != Ellipsis
assert ellipsis != Ellipsis  # with ellipsis = TypeVar('ellipsis')

It seems to me like it would make sense to change the current ellipsis = TypeVar('ellipsis') to one of the variants that works. I think it would also be a clarification in the documentation to change ellipsis to EllipsisType and maybe have a note somewhere that those using Python < 3.10 can use the equivalent type(...) or type(Ellipsis).

Potentially related to

@rgommers
Copy link
Member

Thanks @aaronmondal, that sounds like a useful improvement to me. EllipsisType seems clear enough, it seems unambiguous either way that it means the ... syntax (or the Ellipsis builtin works too, but I've never seen it used in real-world case).

@rgommers
Copy link
Member

and maybe have a note somewhere that those using Python < 3.10

A code comment should be fine I think - it doesn't seem desirable to include something like that in the html docs for the standard.

@rgommers rgommers added the topic: Static Typing Static typing. label Sep 15, 2023
@aaronmondal
Copy link
Contributor Author

aaronmondal commented Sep 15, 2023

@rgommers Cool, I'll send a PR soon 😊

@BvB93
Copy link
Contributor

BvB93 commented Sep 21, 2023

Prior to 3.10 you can always use builtins.ellipsis. It's a bit of a semi-private type-check only type (xref python/typeshed#7580), but it's fully functional otherwise and correctly type checks.

EDIT: types.EllipsisType is even defined as an builtins.ellipsis alias in typeshed, so it's not going anywhere any time soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: Static Typing Static typing.
Projects
None yet
Development

No branches or pull requests

3 participants