You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Error on dict construction from iterable items #9938
In this file, MyObject implements __iter__ to return a key/value pair such that a dict can be constructed from an iterable of MyObjects.
Note that python -m doctest dictable.py passes.
Expected Behavior
Mypy should honor dict's behavior to produce pairs from objects if they're iterable and accept any iterable of objects that when iterated on produce pairs of compatible types.
Actual Behavior
dictable.py:18: error: Argument 1 to "dict" has incompatible type "Tuple[MyObject, MyObject]"; expected "Iterable[Tuple[str, int]]"
Found 1 error in 1 file (checked 1 source file)
Your Environment
Mypy version used: 0.790
Mypy command-line flags: none
Mypy configuration options from mypy.ini (and other config files): none
Hi @jaraco, I think that's a reasonable error -- mypy doesn't keep track of the length of the sequence returned by __iter__(), since in most cases this is not statically known. Do you have a realistic use case?
I guess you could rewrite this as follows to help mypy along:
return dict((it, ord(it)) for it in items)
Or if you want MyObject to be in control, you could give it a helper method that returns a (self, ord(self)) tuple, and do something like
The real-world use-case is in how importlib.metadata exposes EntryPoint objects. I'd like for consumers of entry points to be able to call the API function importlib.metadata.entry_points()[group] and readily convert that into a lookup by name (by far the most common use-case). I'd like not to require every consumer to construct their own dict by name or have to import a helper to construct the dict by name.
The error emerged in pypa/twine#728 when attempting to demonstrate this more concise approach when switching from pkg_resources.
I think if I'd known this approach was effectively invalid, I'd probably have come up with a different design for querying entry points, something that involved custom containers that could give consumers a clean API with one import.
Given that the type system can't effectively honor this use-case, would you recommend to avoid the use case or to ignore it for mypy checks?
Activity
gvanrossum commentedon Jan 22, 2021
Hi @jaraco, I think that's a reasonable error -- mypy doesn't keep track of the length of the sequence returned by
__iter__(), since in most cases this is not statically known. Do you have a realistic use case?I guess you could rewrite this as follows to help mypy along:
Or if you want
MyObjectto be in control, you could give it a helper method that returns a(self, ord(self))tuple, and do something likeor
jaraco commentedon Jan 22, 2021
Hey Guido. Thanks for the quick response.
The real-world use-case is in how
importlib.metadataexposesEntryPointobjects. I'd like for consumers of entry points to be able to call the API functionimportlib.metadata.entry_points()[group]and readily convert that into a lookup by name (by far the most common use-case). I'd like not to require every consumer to construct their own dict by name or have to import a helper to construct the dict by name.The error emerged in pypa/twine#728 when attempting to demonstrate this more concise approach when switching from pkg_resources.
I think if I'd known this approach was effectively invalid, I'd probably have come up with a different design for querying entry points, something that involved custom containers that could give consumers a clean API with one import.
Given that the type system can't effectively honor this use-case, would you recommend to avoid the use case or to ignore it for mypy checks?