[Python-Dev] PEP 246, redux
Clark C. Evans
cce at clarkevans.com
Wed Jan 12 23:54:46 CET 2005
On Wed, Jan 12, 2005 at 04:07:37PM -0600, Ian Bicking wrote:
| A two-step adaptation encodes specific intention that it seems transitive
| adaption would be blind to.
Exactly. Nice example Ian. To parrot your example a bit more
concretely, the problem happens when you get two different
adaptation paths.
String -> PathName -> File
String -> StringIO -> File
Originally, Python may ship with the String->StringIO and
StringIO->File adapters pre-loaded, and if my code was reliant upon
this transitive chain, the following will work just wonderfully,
def parse(file: File):
...
parse("helloworld")
by parsing "helloworld" content via a StringIO intermediate object. But
then, let's say a new component "pathutils" registers another adapter pair:
String->PathName and PathName->File
This ambiguity causes a few problems:
- How does one determine which adapter path to use?
- If a different path is picked, what sort of subtle bugs occur?
- If the default path isn't what you want, how do you specify
the other path?
I think Phillip's suggestion is the only resonable one here, ambiguous
cases are an error; ask the user to register the adapter they need, or
do a specific cast when calling parse().
| 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.
I think this isn't all that useful; it's unrealistic to assume that
adapters are always perfect. If transitive adaptation is even
permitted, it should be unambiguous. Demanding that adaption is
100% perfect is a matter of perspective. I think String->StringIO
and StringIO->File are perfectly pure.
| Perhaps transitivity seems dangerous because that has the potential to
| dramatically increase the global effects of those registered adapters.
I'd prefer,
1. adaptation to _not_ be transitive (be explicit)
2. a simple mechanism for a user to register an explicit
adaptation path from a source to a destination:
adapt.path(String,PathName,File)
to go from String->File, using PathName as an intermediate.
3. an error message, AdaptationError, to list all possible
adaptation paths:
Could not convert 'String' object to 'File' beacuse
there is not a suitable adapter. Please consider an
explicit conversion, or register a composite adapter
with one of the following paths:
adapt.path(String,PathName,File)
adapt.path(String,StringIO,File)
3. raise an exception when _registering_ a 'path' which would
conflict with any existing adapter:
"Could not complete adapt.path(String,PathName,File)
since an existing direct adapter from String to Path
already exists."
"Could not complete adapt.path(String,PathName,File)
since an existing path String->StringIO->File is
already registered".
I'd rather have the latter error occur when "importing" modules
rather than at run-time. This way, the exception is pinned on
the correct library developer.
Best,
Clark
More information about the Python-Dev
mailing list