PEP 246 revision

S?bastien Boisg?rault boisgera at gmail.com
Sun Mar 6 08:26:25 EST 2005


mlh at selje.idi.ntnu.no (Magnus Lie Hetland) wrote in message news:<slrnd2gask.733.mlh at selje.idi.ntnu.no>...
> In article <1109767002.529330.56850 at f14g2000cwb.googlegroups.com>,
> boisgera at gmail.com wrote:
> >
> >
> >I had a look at the new reference implementation of PEP 246
> >(Object Adaptation) and I feel uneasy with one specific point
> >of this new version. I don't fully understand why it checks
> >if *the type of* the protocol has a method "__adapt__":
> >
> >    ...
> >    # (c) then check if protocol.__adapt__ exists & likes obj
> >    adapt = getattr(type(protocol), '__adapt__', None)
> >    ...
> >
> >As a consequence of this change, you can't define a protocol
> >as a class that implements __adapt__ anymore.
> 
> How about an instance of such a class?
> 
> >    class Protocol(object):
> >        def __adapt__(self, obj):
> >            ...
> 
> If you instantiate this class, the object's type will have the
> __adapt__ attribute...
> 
> This is the way it works with other special methods (i.e.
> __foo__-methods) in Python, too. Instead of looking in the object (or
> class) in question, Python checks the *type* of the object (or class).
> That's the general rule -- no reason to make an exception here. (In
> fact, there is every reason *not* to make an exception, IMO.)

Agreed. Consistency matters. But precisely because Python looks 
in the type of the object (and not the object itself), I don't 
need to explicitely check the type myself: the code 
adapt = getattr(protocol, '__adapt__') will find the method
type(protocol).__adapt__ anyway. If it doesn't exist, it will
use protocol.__adapt__ instead (right ?). Finally, the code 
adapt = getattr(protocol, '__adapt__') would work:
    1. if protocol is the instance of a class that implements 
      __adapt__,
    2. if protocol is a class that implements __adapt__.

> A good example of why this makes sense is the __call__ method. 
> [...]

Agreed.

> So: The scenario needn't be as complex as in your example, as long as
> you use instances instead of classes as protocols.
> 
> (I guess the case could be made for using classes as protocols, but I
> suspect the case would be mainly syntactical...)

Agreed. But I'd like to use the classes directly :) ... and you're 
right it is mainly a matter of taste. I feel that a class *is* a 
kind of protocol ...

Have you read the BDFL's "Python Optional Typechecking Redux" ?
(http://www.artima.com/weblogs/viewpost.jsp?thread=89161)
It's usage of adapt assumes that "a class is a protocol", so I
guess that it does not work with the new version of PEP 246.

Quote:
"""
[...]
def foo(a: t1, b: t2) -> t3:
    "your code here"

This would be replaced by something like the following:

def foo__(a, b): # The original function
    "your code here"

def foo(a, b): # Typechecking wrapper
    a = __typecheck__(a, t1)
    b = __typecheck__(b, t2)
    r = foo__(a, b)
    r = __typecheck__(r, t3)
    return r
[...]

You can also implement duck typing as defined by adapt(), as follows:

from adaptation import adapt
def __typecheck__(x, T):
    if adapt(x, T) is not x:
        raise TypeError("...")
    return x
"""

Regards,

S.B.



More information about the Python-list mailing list