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 | ncogh...@gmail.com | Brisbane, Australia --------------------------------------------------------------- _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com