[Python-3000] Adaptation [was:Re: Iterators for dict keys, values, and items == annoying :)]
Walter Dörwald
walter at livinglogic.de
Sat Apr 1 22:25:29 CEST 2006
Alex Martelli wrote:
> [...]
> So, each entity which we can call a "registration of adaptation" (ROA for short) is a tuple ( (T, P), A) where:
> T is a type;
> P is a unique string identifying a protocol;
> A is a callable, such that, for any direct instance t of T
> (i.e., one such that type(t) is T), A(t) returns an object (often t itself, or a wrapper over t) which claims "I satisfy
> all the
> constraints which, together, make up protocol P". A(t) may also raise some exception, in which case the adaptation attempt
> fails and the exception propagates.
>
> [...]
> Here is a simple reference implementation of adaptation under all of these simplifying assumptions:
>
> _global_registry = {}
>
> def register_adapter(T, P, A, registry=_global_registry):
> registry[T, P] = A
>
> def adapt(t, P, registry=_global_registry):
> return registry[type(t), P]
>
> [...]
>
> a. protocols may be identified quite arbitrarily (e.g. by unique- strings), though specific formalizations are also
> perfectly possible and no doubt offer many advantages (partial error-checking, less indirectness, ...): there is no
> strict need to formalize interfaces or protocols in order to add protocol-adaptation to Python
>
> b. the possibility of supplying, consuming and adapting-to protocols becomes non-invasive thanks to registration
>
> In this simplified outline I've supported *only* registration as the one and only way to obtain adaptation -- conceptually,
> through the identity function, registration can indeed serve the purpose,
> although optimizations are quite obviously possible.
>
> [...]
I'm beginning to see your point. Suddenly several things in the stdlib look like they use (or could benefit from) some kind of
adaption:
The pickle protocol uses copy_reg.dispatch_table which adapts an object to the pickle protocol.
The copy module uses __copy__ and __deepcopy__ methods to adapt an object to the copy protocol.
The pprint module uses simple type checks (isinstance(foo, dict), isinstance(foo, tuple), isinstance(foo, list)) and a fall back
to the __repr__() method to adapt an object to some kind of pretty printing protocol.
There are probably other ad-hoc adaptions lurking in the stdlib.
IMHO there are two possible routes:
1) Identify all cases of adaption in the stdlib, implement a version of those modules that use the "real" adaption and see if
the result looks cleaner and more extensible.
2) Implement a self contained adaption module that only does adaption and nothing else and publish it in the cheeseshop. This
should be so simple that every other project that wants to use it, but doesn't want to depend on another package can simply
incorporate it. (I immediate recognized two spots in my own code, where I would use this adaption module).
At the minimum this module should support inheritance of the adapted type, so a simple dict won't work.
Defining an adaptor for the copy protocol might look like this:
@adaptor(Foo, "org.python.copy")
class CopyFoo:
def __init__(self, foo):
self.foo = foo
def copy(self):
...
def deepcopy(self, memo=None):
...
Would this be a useful application of class decorators?
Bye,
Walter Dörwald
More information about the Python-3000
mailing list