pruebauno at pruebauno at
Fri Nov 14 20:27:10 CET 2008

On Nov 14, 12:47 am, George Sakkis <george.sak... at> wrote:
> On Nov 13, 10:55 pm, Steven D'Aprano <st... at REMOVE-THIS-
>> wrote:
> > Take this example:
> > def foo(alist):
> >     alist.sort()
> >     alist.append(5)
> > The argument can be any object with sort and append methods (assumed to
> > act in place). But what happens if you pass it an object with a sort
> > method but no append? The exception doesn't occur until *after* the
> > object is sorted, which leaves it in an inconsistent state. This can be
> > undesirable: you might need the function foo to be atomic, either the
> > entire function succeeds, or none of it.
> In this example atomicity is not guaranteed even if alist is a builtin
> list (if it contains a complex number or other unorderable object),
> let alone if not isistance(alist, list). It gets worse: false
> positives are less likely for full-spelled methods with well-known
> names such as "sort" and "append"  (i.e. if hasattr(alist, 'append'),
> alist.append *probably* does what you think it does), but good luck
> with that when testing for __getitem__, __iter__ for more than one
> pass, __call__, and other special methods with ambiguous or undefined
> semantics.
> Let's face it, duck typing is great for small to medium complexity
> projects but it doesn't scale without additional support in the form
> of ABCs/interfaces, explicit type checking (at compile and/or run
> time), design by contract, etc. It must not be a coincidence that both
> Zope and Twisted had to come up with interfaces to manage their
> massive (for Python at least) complexity.
> George

What would be actually interesting would be an switch to the python
interpreter that internally annotated function parameters with how
they are used in the function and raised an exception as soon as the
function is called instead of later. Failing earlier rather than
later. Example:

def sub(x,y): some stuff
...print x[2]
...return y.strip().replace('a','b')

internally python generates:

def sub(x: must have getitem, y: must have strip and replace)

Error calling sub(x,y): y has to have strip() method.

More information about the Python-list mailing list