[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 
that problem).

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 
they *require*.

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 mailing list