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
wrong positional-or-keyword information in Mapping and MutableMapping #13432
There's two ways to fix this, but both of them would need to happen in CPython, not in typeshed:
We change the implementation of dict, so it accepts the keyword default parameter in addition to a positional one.
We change the implementation of Mapping so it no longer accepts default as a keyword parameter.
While 1. would be less disruptive, it will potentially add some small overhead to every dict.get call. But changing the API contract of an ABC is a breaking change (especially, because Mapping.get has a default implementation), even if that very same contract is violated in the standard library. So it would be more difficult to push through.
Prototyping the second change in typeshed would allow us to see if any of the projects we check with mypy_primer rely on the current definition of Mapping.get. A code search will probably not provide anything conclusive, since get is such a generic method name. Although in a quick and dirty search I found at least one instance where people relied on os.environ.get allowing a keyword default, which would be broken, if the default implementation of Mapping.get changed, unless os._Environ provided a new get implementation, which does accept keyword arguments.
If we can very quickly find one such instance in the standard library, there's a high likelihood there's thousands more in both the standard library and other people's code.
It probably makes sense for us to claim in typeshed that Mapping/MutableMapping use positional-only arguments, since that's what dict does and in practice it's by far the most common mapping type. I think we do something similar in a few other places already.
Reacted by Doug Hoskisson, Avasam, Shantanu, Sebastian Rittau and Akuli
I just found out that it's not only dict (by far the most common mapping type),
but also types.MappingProxyType.get also doesn't allow the default kwarg,
so it's also probably the 2nd most common mapping type.
As mentioned previously, we also usually shouldn't use Mapping in a argument positions and prefer protocols instead. (Same for Sequence.) Cf. PyCQA/flake8-pyi#525
Activity
Daverball commentedon Feb 1, 2025
Yes, that's because
dictviolates LSP, which is documented in the stubs:typeshed/stdlib/builtins.pyi
Lines 1125 to 1131 in c193cd2
There's two ways to fix this, but both of them would need to happen in CPython, not in typeshed:
dict, so it accepts the keyworddefaultparameter in addition to a positional one.Mappingso it no longer acceptsdefaultas a keyword parameter.While 1. would be less disruptive, it will potentially add some small overhead to every
dict.getcall. But changing the API contract of an ABC is a breaking change (especially, becauseMapping.gethas a default implementation), even if that very same contract is violated in the standard library. So it would be more difficult to push through.Prototyping the second change in typeshed would allow us to see if any of the projects we check with mypy_primer rely on the current definition of
Mapping.get. A code search will probably not provide anything conclusive, sincegetis such a generic method name. Although in a quick and dirty search I found at least one instance where people relied onos.environ.getallowing a keyworddefault, which would be broken, if the default implementation ofMapping.getchanged, unlessos._Environprovided a newgetimplementation, which does accept keyword arguments.If we can very quickly find one such instance in the standard library, there's a high likelihood there's thousands more in both the standard library and other people's code.
JelleZijlstra commentedon Feb 1, 2025
It probably makes sense for us to claim in typeshed that Mapping/MutableMapping use positional-only arguments, since that's what dict does and in practice it's by far the most common mapping type. I think we do something similar in a few other places already.
GastonAQS commentedon Oct 8, 2025
Hey guys, a bit of an old issue but I was reading it and if I'm not wrong the thing you want to try is this? In Mapping
I made all the overloads of get to accept positional parameters only. Maybe I'm missing the big picture
beauxq commentedon Nov 25, 2025
I just found out that it's not only
dict(by far the most common mapping type),but also
types.MappingProxyType.getalso doesn't allow thedefaultkwarg,so it's also probably the 2nd most common mapping type.
adamtheturtle commentedon Dec 2, 2025
See python/cpython#124675 which was closed as "not planned".
srittau commentedon Dec 2, 2025
As mentioned previously, we also usually shouldn't use
Mappingin a argument positions and prefer protocols instead. (Same forSequence.) Cf. PyCQA/flake8-pyi#525