This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: MappingProxyType accepts string
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.9
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: andymaier, rhettinger
Priority: normal Keywords:

Created on 2021-04-13 08:11 by andymaier, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (3)
msg390935 - (view) Author: Andy Maier (andymaier) * Date: 2021-04-13 08:11
MappingProxyType objects can currently be initialized from a string object. Given is purpose, I think this is a bug and should result in TypeError being raised.

Example code (on CPython 3.9.1):

>>> from types import MappingProxyType
>>> mp = MappingProxyType('abc')
>>> list(mp)
['a', 'b', 'c']
>>> mp.items()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'items'

Other invalid input types are properly checked:

>>> mp = MappingProxyType(42)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: mappingproxy() argument must be a mapping, not int

>>> mp = MappingProxyType(['a'])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: mappingproxy() argument must be a mapping, not list

>>> mp = MappingProxyType(('a',))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: mappingproxy() argument must be a mapping, not tuple
msg391027 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2021-04-14 03:09
This isn't a bug because the MappingProxy doesn't promise to do early detection and because it can't really be accomplished cleanly.

Perfect detection of non-mappings isn't possible.  Some easy, minimal checks are made for early detection using PyMapping_Check, PyList_Check, and PyTuple_Check.  Anything that gets past those checks will just need to be duck-typed downstream when it is used.

We could add a few other specific exclusions but that isn't a general solution and it slows down instantiation.  Further it could break code that is intended to work (subclasses of str that mapping methods) or that just happen to work:

    >>> from types import MappingProxyType
    >>> mp = MappingProxyType('abc')
    >>> mp[0]
    'a'
msg391036 - (view) Author: Andy Maier (andymaier) * Date: 2021-04-14 05:48
I accept that the issue was closed, but wanted to document some things:

1. The dict class manages very well to detect that a string is invalid input:

>>> d = dict('abc')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: dictionary update sequence element #0 has length 1; 2 is required

2. When initialized with strings, it looses some of its dictionary methods, but does a quite reasonable job in pointing that out in the error message:

>>> mp = MappingProxyType('abc')
>>> mp.items()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'items'
History
Date User Action Args
2022-04-11 14:59:44adminsetgithub: 87994
2021-04-14 05:48:35andymaiersetmessages: + msg391036
2021-04-14 03:09:09rhettingersetstatus: open -> closed

nosy: + rhettinger
messages: + msg391027

resolution: not a bug
stage: resolved
2021-04-13 08:12:25andymaiersettype: behavior
2021-04-13 08:11:21andymaiercreate