[Python-3000] PEP: Information Attributes

Raymond Hettinger python at rcn.com
Tue May 1 08:25:42 CEST 2007

Proto-PEP:  Information Attributes (First Draft)


Testing hasattr() is a broadly applicable and flexible technique that works well
whenever the presence of a method has an unambiguous interpretation
 (i.e. __hash__ for hashability, __iter__ for iterability, __len__ for sized
containers); however, there are other methods with ambiguous interpretations
that could be resolved by adding an information attribute.


Signal attributes are proposed as a lightweight alternative to abstract base
classes. The essential argument is that duck-typing works fairly well and
needs only minimal augmentation to address a small set of recurring
challenges.  In contrast, the ABC approach imposes an extensive javaesque
framework that cements APIs and limits flexibility.  Real world Python
programming experience has shown little day-to-day need for broad-sweeping API
definitions; instead, there seem to be only a handful of recurring issues that
can easily be addressed by a lightweight list of information attributes.

Use Cases with Ambiguous Interpretations

* The presence of a __getitem__ method is ambiguous in that it can be
  interpreted as either having sequence or mapping behavior.  The ambiguity is
  easily resolved with an attribute claiming either mapping behavior or
  sequence behavior.

* The presence of a rich comparison operator such as __lt__ is ambiguous in that
  it can return a vector or a scalar, the scalar may or may not be boolean,
  and it may be a NotImplemented instance.  Even the boolean case is ambigouus
  because __lt__ may imply a total ordering (as it does for numbers) or it may
  be a partial ordering (as it is for sets where __lt__ means a strict
  subset). That latter ambiguity (sortability) is easily resolved by an
  attribute indicating a total ordering.

* Some methods such as set.__add__ are too restrictive in that they preclude
  interaction with non-sets.  This makes it impossible to achieve set
  interoperability without subclassing from set (a choice which introduces
  other complications such as the inability to override set-to-set
  interactions).  This situation is easily resolved by an attribute like
  obj.__fake__=set which indicates that the object intends to be a set proxy.

* The __iter__ method doesn't tell you whether the object supports
  multiple iteration (such as with files) or single iteration (such as with lists).
  A __singleiterator__ attribute would clear-up the ambiguity.

* While you can test for the presence of a write() method, it would be
   helpful to have a __readonly__ information attribute for file-like objects,
   cursors, immutables, and whatnot.


The attribute approach is dynamic (doesn't require inheritance to work). It
doesn't require mucking with isinstance() or other existing mechanisms.
It restricts itself to making a limited, useful set of assertions rather than
broadly covering a whole API. It leaves the proven pythonic notion of
duck-typing as the rule rather than the exception. It resists the temptation
to freeze all of the key APIs in concrete.

More information about the Python-3000 mailing list