[Python-Dev] operator.is*Type

Fuzzyman fuzzyman at voidspace.org.uk
Wed Feb 22 13:18:09 CET 2006

Raymond Hettinger wrote:
>> >>> from operator import isSequenceType, isMappingType
>> >>> class anything(object):
>> ...     def __getitem__(self, index):
>> ...         pass
>> ...
>> >>> something = anything()
>> >>> isMappingType(something)
>> True
>> >>> isSequenceType(something)
>> True
>> I suggest we either deprecate these functions as worthless, *or* we
>> define the protocols slightly more clearly for user defined classes.
> They are not worthless.  They do a damned good job of differentiating 
> anything that CAN be differentiated.
But as far as I can tell (and I may be wrong), they only work if the 
object is a subclass of a built in type, otherwise they're broken. So 
you'd have to do a type check as well, unless you document that an API 
call *only* works with a builtin type or subclass.

In which case - an isinstance call does the same, with the advantage of 
not being broken if the object is a user-defined class.

At the very least the function would be better renamed 
``MightBeMappingType``  ;-)

> Your example simply highlights the consequences of one of Python's 
> most basic, original design choices (using getitem for both sequences 
> and mappings).  That choice is now so fundamental to the language that 
> it cannot possibly change. Get used to it.
I have no problem with it - it's useful.

> In your example, the results are correct.  The "anything" class can be 
> viewed as either a sequence or a mapping.
But in practise an object is *unlikely* to be both. (Although 
conceivable a mapping container *could* implement integer indexing an 
thus be both - but *very* rare). Therefore the current behaviour is not 
really useful in any conceivable situation - not that I can think of anyway.

> In this and other posts, you seem to be focusing your design around 
> notions of strong typing and mandatory interfaces.  I would suggest 
> that that approach is futile unless you control all of the code being 
> run.
Not directly. I'm suggesting that the loosely defined protocol (used 
with duck typing) can be made quite a bit more useful by making the 
definition *slightly* more specific.

A preference for strong typing would require subclassing, surely ?

The approach I suggest would allow a *less* 'strongly typed' approach to 
code, because it establishes a convention to decide whether a user 
defined class supports the mapping and sequence protocols.

The simple alternative (which we took in ConfigObj) is to require a 
'strongly typed' interface, because there is currently no useful way to 
determine whether an object that implements __getitem__ supports mapping 
or sequence. (Other than *assuming* that a mapping container implements 
a random choice from the other common mapping methods.)

All the best,

> Raymond

More information about the Python-Dev mailing list