[PEAK] Some simple adaptation questions with PyProtocols

David Bolen db3l at fitlinxx.com
Sun Feb 29 01:10:31 EST 2004


> I'd ordinarily make __adapt__ a classmethod for this situation, so that it

> can be sensibly inherited by a subclass.

Good point.  I did originally try that but couldn't get __adapt__ to
be called.  In hindsight the problem was that I had the signature for
the method wrong, and not that it was a class method.  (I didn't
notice since I didn't get an exception calling __adapt__ rather than 
the same adaptation failure I got when I didn't have an __adapt defined)

> An instance of Protocol is a protocol.
> (...)
> 
> In some ways, it might have been better for me to make it work like this:
> 
> class ISomething:
>      __metaclass__ = Interface
> 
> Which then would've been 100% consistent terminology, but then lots of 
> people get scared by __metaclass__.

Thanks, that does help clarify it a bit for me though.

> 'advise()' is a convenience API for classes *and* modules.  You can also
do 
> 'moduleProvides'.
> 
> In addition, there's a 'classProvides' which has different meaning than 
> 'instancesProvide'.  So, there really can't be an assumption like what you

> describe.

Ok - perhaps another way to solve my point would be to have some
mechanism for specifying "the current class" to the instanceProvides
argument to advise?  My problem was mostly the inability to specify
(at a Python syntactical level) the current class as the protocol I
wanted to use as instanceProvides (or at least I couldn't figure out a
way to specify it).  Since advise() is already doing the necessary
magic to determine the class on which the declarations are being made,
if it had a way to indicate that class was also the protocol, I think
it would let me use it the way I had originally desired.

(Although your point below makes me think that not being able to do
this is as much a design feature as anything else)

> Essentially, PyProtocols doesn't have any convenience features for working

> with ABC-style interfaces in the way that you're doing.  The simplest 
> workaround for what you want to do is to define a metaclass for interfaces

> like this, that looks at your adaptation methods and makes the appropriate

> declareAdapter/etc. calls.  You could then reuse that metaclass for other 
> ABC-style interfaces.

I hadn't thought of that, but it makes sense.  The metaclass would
have access to the class being created, so would be able to indicate
the protocol properly in the declareAdapter calls.

> That's not really supported; advise() in a class can declare ways that the

> class can do adaptations to specified protocols, but it does *not* let you

> say anything about adapting *to* that class.

I think this gets to the root of the difficulties I was having, since
that's what I was trying to achieve.

>                                               There's no provision in the 
> API for it at all, and my expectation would always be that you'd do it
more 
> or less as you've done it above, with the personal difference that I'd 
> never be actually putting the behavior into the interface, and would 
> instead use separate functions.

I suppose what really led me down this road was having a group of
classes that I didn't see having the need for an independently defined
protocol.  The classes are mostly all basic 'value' objects
(fundamental types in my system) which seemed to lend themselves to
being their own protocols.  It seemed natural to me to permit them to
know their own adaptations to other basic types, although one of the
reasons for using PyProtocols was to enable later external adaptations.

> And you'll notice you can still use the PEP 246 approach.  It's just that 
> PyProtocols doesn't make your use case dramatically easier than PEP 246 
> provides for.  Much easier, yes, but not quite as easy as it is in the
case 
> where you keep implementation separate from interface.  :)

Fair enough. :-)

I didn't mind the internally supported adaptations being close to PEP
246, but wanted to leave the definitions in a state that would support
later external adaptations, so I couldn't just leave it in the
__adapt__ configuration, but at minimum wanted the object to be a
protocol in the sense if IOpenProtocol.  But doing that made it
difficult for me to internalize even the basic adaptations.  But I
think I understand why a lot better now, so thanks.

-- David



More information about the PEAK mailing list