[Python-3000] Discussions with no PEPs
Phillip J. Eby
pje at telecommunity.com
Tue Mar 13 04:06:05 CET 2007
At 10:03 PM 3/12/2007 -0400, Benji York wrote:
>Phillip J. Eby wrote:
> > I posted here several months ago a short "Interface" class that
> > used generic functions for its base
>How could Python use generic functions to accomplish what the proposed
>ABCs aim to?
Which specific aim do you have in mind?
> By first implementing interfaces? Perhaps by implementing
>is_file() with a generic function individuals could add implementations
>for that return True?
In most cases, having such introspection functions is an attractive
nuisance. It's attractive in Python because it grows out of reusing
built-in types as syntactic shorthand, which is all very well and good
until you start trying to apply it to non-builtin types too.
I assert that an is_file(x) function that does something different
than isinstance(x,file) is a bad idea, because all of the use cases that
lead to somebody wanting to know this, are better satisfied by either:
1. simply trying to use the object as if it were a file (i.e., rely on the
caller to pass you the right type), or
2. defining a generic function for whatever it was you were going to *do*
with the file-like object, and leaving it to others to implement *that*
method (which can always call your 'file'-type implementation if it needs to).
The presence of an is_file() on the other hand, convinces people that it's
okay to write a bunch of if-then tests... which leads to broken and
non-extensible code like what is found in pydoc and epydoc, that won't work
properly with any Python objects whose existence the authors didn't anticipate.
I routinely have to reverse engineer Pydoc's oddities so that my objects
don't produce bizarre or misleading information in help() (and I recently
saw a blog post from Robert Brewer that indicates it's not just me who has
Now, in *theory* pydoc should be just dandy because it's full of calls to
'isroutine()' and 'ismethod()' and similar "abstract interface" stuff. In
*practice*, those calls occur in big if-then trees that it uses to decide,
based on what a thing *is*, how to document it.
What it *should* be doing instead, is invoking generics like
get_call_signature(), iter_members(), defined_by_module(), and so on.
Now, you could argue that the problem is that Python lacks ABCs or
well-defined interfaces for these things. But it wouldn't actually help
this problem at *all*.
See, just because you've defined an interface for how the calling signature
is stored in a function's attributes, doesn't mean that that's how every
object can (or even *should*) store its calling signature.
For example, calling a class usually ends up calling its __init__, but it
could also go to the metaclass' __call__. Pydoc just ignores the issue
altogether, because it assumes that 'isclass' and 'isroutine' (for example)
are mutually exclusive.
Meanwhile, just because you've defined interfaces about class or module
dictionaries, doesn't mean that everything you might wish to document,
wants to use a dictionary to define its members. Maybe its members are
*ordered*, for example!
Thus, the *right* way to do interfaces is not for component *providers* to
offer them, but rather for component *consumers* to define what interfaces
In other words, formalizing the interfaces provided by "classes",
"modules", "routines", etc., won't fix pydoc's problems in the slightest.
What's needed is not for the language to define interfaces for the things
to be used by pydoc, but rather for *pydoc* to define "documentable object"
interface(s), instead. (And provide implementations of these
interfaces/generics for the builtin types.)
Then, you could add documentation support to *any* object, instead of
having to put all sorts of phony attributes on your objects to trick Pydoc
into thinking they're sort of like some object type that pydoc knows
about. (And hoping that in the process you won't cause some *other*
library to decide to do something weird with your objects as a result of
having those phony attributes!)
In short, this is why I see the ABC and interface stuff as a non-solution
to the wrong problem. It's starting at the wrong end of the telescope, so
to speak, dealing in the minutiae of the solution domain (the language),
instead of in the big picture of the problem domain (what people want to
*do* with the language).
In short, the very idea of 'is_file()' is wrong, wrong, wrong. At least,
if your goal is to make libraries more robust and reusable. It leads
inevitably to the brokenness seen in Pydoc -- and the comparable brokenness
that existed in Zope prior to its replacing most introspection by
adaptation. (To be honest, I'm *assuming* that those broken bits went away
as soon as adaptation became the recommended option -- I don't know if it
really did or not, as I haven't done any real Zope work in a few years.)
More information about the Python-3000