[Python-Dev] Undocumented change / bug in Python3's PyMapping_Check
Nick Coghlan
ncoghlan at gmail.com
Wed May 6 16:59:30 CEST 2009
John Millikin wrote:
> In Python 2, PyMapping_Check will return 0 for list objects. In Python
> 3, it returns 1. Obviously, this makes it rather difficult to
> differentiate between mappings and other sized iterables. In addition,
> it differs from the behavior of the ``collections.Mapping`` ABC --
> isinstance([], collections.Mapping) returns False.
>
> I believe the new behavior is erroneous, but would like to confirm
> that before filing a bug.
It's not a bug.
PyMapping_Check just tells you if a type has an entry in the
tp_as_mapping->mp_subscript slot. In 2.x, it used to have an additional
condition that the tp_as_sequence->sq_slice slot be empty, but that has
gone away in Py3k because the sq_slice slot has been removed.
Even in 2.x that test wasn't a reliable way of telling if something was
a mapping or a sequence - it happened to get it right for lists and
tuples (since they define __getslice__ and __setslice__), but this is
not the case for new-style user defined sequences:
>>> from operator import isMappingType
>>> class MySeq(object):
... def __getitem__(self, idx):
... # Is this a mapping or an unsliceable sequence?
... return idx*2
...
>>> isMappingType(MySeq())
True
Using the new collections module ABCs to check for sequences and
mappings. That's what they're for, and they will give you a much more
reliable answer than the C level checks (which are really just an
implementation detail).
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
---------------------------------------------------------------
More information about the Python-Dev
mailing list