[Python-Dev] PEP 246, redux

Phillip J. Eby pje at telecommunity.com
Thu Jan 13 00:09:31 CET 2005


At 04:07 PM 1/12/05 -0600, Ian Bicking wrote:
>It also seems quite reasonable and unambiguous that a path object could be 
>adapted to a IReadableFile by opening the file at the given path.

Not if you think of adaptation as an "as-a" relationship, like using a 
screwdriver "as a" hammer (really an IPounderOfNails, or some such).  It 
makes no sense to use a path "as a" readable file, so this particular 
adaptation is bogus.


>The problem is with the first example, where two seemingly innocuous 
>adapters (string->path, path->IReadableFile) allow a new adaptation that 
>could cause all sorts of problems (string->IReadableFile).

Two problems with this thought:

1) path->IReadableFile is bogus

2) even if you had path->IReadableFile, you're not broken unless you extend 
transitivity to pass through concrete target types (which I really don't 
recommend)


>Ideally, if I had code that was looking for a file object and I wanted to 
>accept filenames, I'd want to try to adapt to file, and if that failed I'd 
>try to adapt to the path object and then from there to the file object.

There are two reasonable ways to accomplish this.  You can have code that 
expects an open stream -- in which case what's the harm in wrapping 
"open()" arount the value you pass if you want it to be opened?  OR, you 
can have code that expects an "openable stream", in which case you can pass 
it any of these:

1. an already-open stream (that then adapts to an object with a trivial 
'open()' method),
2. a path object that implements "openable stream"
3. a string that adapts to "openable stream" by conversion to a path object

The only thing you can't implicitly pass in that case is a 
string-to-be-a-StringIO; you have to explicitly make it a StringIO.

In *either* case, you can have a string adapt to either a path object or to 
a StringIO; you just can't have both then come back to a common interface.



>As I think these things through, I'm realizing that registered adaptators 
>really should be 100% accurate (i.e., no information loss, complete 
>substitutability), because a registered adapter that seems pragmatically 
>useful in one place could mess up unrelated code, since registered 
>adapters have global effects.  Perhaps transitivity seems dangerous 
>because that has the potential to dramatically increase the global effects 
>of those registered adapters.

However, if you:

1) have transitivity only for interface-to-interface relationships 
(allowing only one class-to-interface link at the start of the path), and

2) use adaptation only for "as a" relationships, not to represent 
operations on objects

you avoid these problems.  For example, avoiding the one adapter you 
presented that's not "as a", the adapter diamond becomes a triangle.

The longer the discussion goes on, however, the more I realize that like 
the internet, transitivity depends on the continued goodwill of your 
neighbors, and it only takes one fool to ruin things for a lot of 
people.  On the other hand, I also hate the idea of having to kludge 
workarounds like the one James Knight was doing, in order to get a simple 
adaptation to work.



More information about the Python-Dev mailing list