Closed RandallPittmanOrSt closed 2 months ago
ruff is right, there's no ellipsis
; you probably meant Ellipsis
?
ruff is right, there's no
ellipsis
; you probably meantEllipsis
?
No, you can't use Ellipsis
in an annotation as it is a variable (according to both mypy and Pyright).
I'm basing my annotations on those of numpy.ndarray.__getitem__
: https://github.com/numpy/numpy/blob/64ee06a641f8bd087bd74712ef4b1cbd1241f08c/numpy/__init__.pyi#L1514
This is due to a historical hack in typeshed, where a fictitious type "builtins.ellipsis" is invented for static type checkers so that they are able to understand what the type of the Ellipsis
singleton is: https://github.com/python/typeshed/blob/fdce887b9479a4c8a69ea040145f276caa28ce0e/stdlib/builtins.pyi#L1834-L1850. It would be nice to remove this hack over at typeshed, but it might be difficult: some people (such as numpy, apparently) are using the hack in their annotations, so there are backwards compatibility implications; the "real" type of Ellipsis
is only exposed at runtime as types.EllipsisType
on Python 3.10+, while typeshed still supports Python 3.8; and some type checkers might also rely on builtins.ellipsis
being in the stub.
Ruff does not use typeshed's stubs for resolving builtin symbols at the moment, although we will do at some point. At that point, we might start understanding the fictious builtins.ellipsis
type in the same way that mypy and pyright do. Whether we do or don't, however, I'd encourage you to use types.EllipsisType
instead of builtins.ellipsis
if at all possible since, unlike builtins.ellipsis
, types.EllipsisType
actually exists at runtime.
@AlexWaygood You're totally right, I just discovered that. My mistake, thanks.
No need to apologise @RandallPittmanOrSt, this is a pretty obscure corner case! Happy to help :-)
I think I'll close this for now, though, since there's not much actionable for us here -- we're already working on using typeshed stubs for resolving builtin symbols 👍
Thanks again, @AlexWaygood. FFR, here's ~my workaround~ a modified version of typeshed's hack as a workaround:
mypy doesn't like overriding typeshed's ellipsis
hack, hence the if not TYPE_CHECKING
from typing import TYPE_CHECKING
import sys
if sys.version_info >= (3, 10):
from types import EllipsisType
ellipsis = EllipsisType
elif not TYPE_CHECKING:
class ellipsis: ...
In a type stub, the @type_check_only
decorator can be added to the ellipsis
class.
ellipsis
is a valid name in type signatures, but Ruff doesn't seem to have it its grammar.Example: