Uh oh!
There was an error while loading. Please reload this page.
Make Mapping covariant in keys (too). - #273
Conversation
ilevkivskyi
commented
Aug 31, 2016
@gvanrossum deffun(m: Mapping[float, Any]):
returnm[0.1]
classStrangeMap(Mapping[int, Any]):
def__getitem__(self, item):
returnitem<<5fun(StrangeMap())If Of course this example is a bit artificial, but I think there are realistic examples just going the same way. |
gvanrossum
commented
Aug 31, 2016
@JukkaL What do you think? On Wed, Aug 31, 2016 at 11:56 AM, Ivan Levkivskyi notifications@github.com
--Guido van Rossum (python.org/~guido) |
JukkaL
commented
Aug 31, 2016
As discussed in python/typeshed#510, this is clearly unsafe, but maybe the cases where the unsafety might manifest itself are more common that I originally thought :-( Making it covariant in the value type should be less of a problem. We could use a separate type variable |
gvanrossum
commented
Sep 2, 2016
OK, I'll close this for now, leaving Mapping covariant in the value but not in the type. (Alas, mypy doesn't understand that union yet, so get() still requires |
Prometheus3375
commented
Feb 21, 2021
>>>issubclass(int, float)
False>>>isinstance(1, float)
False |
gvanrossum
commented
Feb 22, 2021
But it is in for static type checkers, and this is specified by PEP 484. |
rhshadrach
commented
Mar 30, 2021
Is the only issue making Mapping covariant in the key with int/float? For example, I expect Tangential question - is the covariance/contravariance specified by a PEP? I couldn't find anything other than PEP 484 which says:
which seems to indicate Mapping should be covariant in the key (but is slightly ambiguous, I suppose). If I've captured the objections to making Mapping covariant in the key, then my take is that not making Mapping covariant in the key is foregoing a generally useful feature in good code for oddities some might experience in not-so-good code. But I suspect I may be missing some cases. |
Whole-type variance is not fine-grained enough to describe the relation here. Indexing is actually contravariant, setting is covariant as are other operations. The variance of the type, as it appears on a function, depends entirely on how the object is used. This is also related to python/typeshed#7121 and python/typeshed#7015 where methods are contravariant, but the type is covariant. There is no way to describe this with Python's type system, as it stands. |
bcmills
commented
Jul 10, 2026
Given that |
See python/typeshed#510