I currently have:
_T_OPT = TypeVar("_T_OPT", bound=Type) class UserInputOptional(Generic[_T_OPT]): def __class_getitem__(cls, key: _T_OPT) -> _T_OPT: if isinstance(key, tuple): raise TypeError("Must only provide a single type to Optional") return key
which is not valid for usage like (or any other generic alias):
__class_getitem__for figuring out type annotations, so it seems like I will have to settle for making this an alias of
Union, even if it may result in unwanted multiple arguments. Only other alternative I see is writing mypy plugin and that seems a bit much.
>>> T = TypeVar("T") >>> class Base(Generic[T]): ... __slots__ = ("__weakref__",) ... >>> Base[T] Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/lib/python3.6/typing.py", line 682, in inner return func(*args, **kwds) File "/usr/local/lib/python3.6/typing.py", line 1143, in __getitem__ orig_bases=self.__orig_bases__) File "/usr/local/lib/python3.6/typing.py", line 978, in __new__ self = super().__new__(cls, name, bases, namespace, _root=True) File "/usr/local/lib/python3.6/typing.py", line 137, in __new__ return super().__new__(cls, name, bases, namespace) File "/usr/local/lib/python3.6/abc.py", line 133, in __new__ cls = super().__new__(mcls, name, bases, namespace, **kwargs) TypeError: __weakref__ slot disallowed: either we already got one, or __itemsize__ != 0 >>> del Base.__slots__ >>> Base[T] __main__.Base[~T] >>> class Derived(Base[T]): ... __slots__ = () ... >>> Derived() <__main__.Derived object at 0x7fcb99be7888> >>> Derived().__dict__ Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Derived' object has no attribute '__dict__' >>>
bug.py:7: error: "AsyncContextManager[Any]" has no attribute "__enter__"; maybe "__aenter__"? bug.py:7: error: "AsyncContextManager[Any]" has no attribute "__exit__"; maybe "__aexit__"?
Hi all, I submitted a PR adding type hints to bidict, my bidirectional mapping library: jab/bidict#112
As I commented in the PR:
Doesn't have to block merging, but there are a few places where I used
# type: ignore internally that may actually be worth type checking. Maybe. (In many of these places though I suspect appeasing mypy would not be worth it, e.g.
_invcls.) Open to suggestions.
One thing I had trouble with was using
update(). For example, mypy rejects:
@_t.overload def update(self, **kw: VT) -> None: ... @_t.overload def update(self, map: _t.Mapping[KT, VT], **kw: VT) -> None: ... @_t.overload def update(self, col: IterItems[KT, VT], **kw: VT) -> None: ... def update(self, *args: MapOrIterItems[KT, VT], **kw: VT) -> None: # (implementation here)
I think this may be a current limitation in mypy, so I left those without the overloads. If someone wants to suggest an alternative, I'll be happy to take another look.
Would much appreciate another pair of eyes on this if anyone is interested. bidict poses some particularly interesting type hinting challenges, so maybe several would find it interesting to review. (For example, I hit https://bugs.python.org/issue41451 and https://github.com/python/typing/issues/548#issuecomment-621571821 while working on this.)
Maybe the best way to review is to start at https://github.com/jab/bidict/blob/dev/bidict/_abc.py and then follow the suggested code review path in the header comments, focusing on the type hints. Please comment (or just react to the PR with :eyes:) if you're interested in reviewing, and I'll wait for feedback before I merge.
Thanks in advance to anyone who can help this lonely solo-maintainer make bidict's first type hints as good as can be! :heart:
I want to define a
my function looks like -
def foo1(read: ReadClient, name: str) -> Any: def foo2(read: ReadClient, name: str, count: int) -> Any: def too1(write: WriteClient, name: str) -> Any: def too2(read: WriteClient, name: str, count: int) -> Any:
The function call will have the 1st positional argument as
WriteClient and it can variable args, kwargs.
I tried something like
Callable[[ReadClient, Any, ...], Any] Callable[[ReadClient, ...], Any]
but none of the above formats work
Hence I want to define
Callable somewhat like -
Callable[[ReadClient, *args: Any, **kwargs: Any], Any] Callable[[WriteClient, *args: Any, **kwargs: Any], Any]
I know the above format is incorrect, but is there a way to define a Callable where the first positional argument is ReadClient and it could take variable args/kwargs of Any type. Same would be true for WriteClient.
I tried using Protocol as -
class ReadCmdFunc(Protocol): def __call__(self, device: ReadClient, *args: Any, **kwargs: Any) -> Any: ... class WriteCmdFunc(Protocol): def __call__(self, device: WriteClient, *args: Any, **kwargs: Any) -> Any: ...
HOwever, mypy throws an error as -
Argument 1 has incompatible type "Callable[[WriteClient, str,], Any]"; expected "WriteCmdFunc"
WriteCmdFunc is defined exactly as in the
__call__ of WriteCmdFunc.
So not sure, what I am missing here.
I really appreciate your help.
mypyto solve a problem with nested overloades in our own plugin
dry-python/returns/@curry: python/mypy#9259 I would love to hear the feedback on it! :+1:
I get a certain errror
error: "Callable[..., Any]" has no attribute "for_platform" [attr-defined]
This error could be in any line in a file.
Is there a way to ignore this error from all the files using mypy config file where I say, if I get the above error in any files, just ignore it instead of having #type: ignore [attr-defined] in each file ?
Hi folks, trying to understand this result and how to fix it:
T = TypeVar('T') def f(a: T, b: T) -> T: ... reveal_type(f(1, '2')) # builtins.object*
T to be invariant and thus either
str. It seems that variance is taken from the function (contravariant arguments, covariant return) and
T's variance being ignored.
Can I force
T to be invariant here?
Abut not to restrict
Tto some pre-determined domain. It should just be some concrete type, though I could see inference selecting something like
Union[type(a), type(b)]. Definitely did not expect a generic catch-all like
Noneas default argument. I used
to avoid this problem. When mypy complained about the type
List[int]being wrong, I made it
def fn(Optional[List[int]] = None) -> None:But operations inside cannot be done with
Noneand mypy complains. How can I get around this? Can some one help me out?
This one has error.
from dataclasses import dataclass from typing import List, Optional class Example: lst: List[int] = None def __post__init__(self): if self.lst is None: self.lst = [1, 2, 3] def fn(self): if len(self.lst) < 2: print("Aww...") elif self.lst == 2: print("Yes") else: print("No")
This one has no error.
def fn(lst: Optional[List[int]] = None) -> None: if lst is None: lst = [1, 2, 3] if len(lst) < 2: print("Aww...") elif lst == 2: print("Yes") else: print("No")
I have no idea what I'm doing wrong..
Hi typing folks, the following code matches https://github.com/python/typeshed/blob/master/stdlib/3/typing.pyi#L452-L457 and yet mypy complains with a few hard-to-debug errors :
# mymapping_with_overload.py import typing as _t KT = _t.TypeVar('KT') VT = _t.TypeVar('VT') class MyMapping(_t.MutableMapping[KT, VT]): @_t.overload def update(self, arg: _t.Mapping[KT, VT], **kw: VT) -> None: ... @_t.overload def update(self, arg: _t.Iterable[_t.Tuple[KT, VT]], **kw: VT) -> None: ... @_t.overload def update(self, **kw: VT) -> None: ... def update(self, *args: _t.Union[_t.Mapping[KT, VT], _t.Iterable[_t.Tuple[KT, VT]]], **kw: VT) -> None: ... # implementation here (validate either 0 or 1 positional arg provided) # more methods defined here
➜ mypy mymapping_with_overload.py mymapping_with_overload.py:9: error: Signature of "update" incompatible with supertype "MutableMapping" mymapping_with_overload.py:15: error: Overloaded function implementation does not accept all possible arguments of signature 1 mymapping_with_overload.py:15: error: Overloaded function implementation does not accept all possible arguments of signature 2 Found 3 errors in 1 file (checked 1 source file)
Any ideas? Thanks for any help!
Hi @jab ,
Your code does not in fact match the typing.py code you linked, because the code you linked uses positional only arguments (python/mypy#2497), but your code allows keyword args(ie, one can do
map.update(arg=some_other_map)). You should add
__ to the name of the argument to make it positional only(look at the mypy issue I linked, also the typing.py code that you linked)
The last two errors also have to do with this difference. The overloaded signatures indicate one can do
map.update(arg=some_other_map), but that is in fact not allowed by the signature of the implementation, where keyword arguments must be of
VT type, not
__argon lines 10 and 12 was all it took to fix this! This seems unusually hard to debug and Google for. Could
mypygive users a more helpful error message here, given how rare it is that the problem is with the formal param name, not the actual type hints?
You're welcome @jab . From my experience, this is a problem with overloading in general, not this specific positional-only thing. In fact, if you remove the overloading and recreate the error, mypy gives a reasonable error message "unexpected keyword argument ..."
While I think error reporting for overloading can be improved, I think the mypy team has other priorities(by the look of their Github issues). I'd bet that they would be happy for a PR about it though.
FYI, I'm totally unaffiliated iwht the mypy team, I've just been following thir work kind of closely :)