[Python-Dev] inspect.py

Ka-Ping Yee ping@lfw.org
Wed, 3 Jan 2001 05:40:47 -0600 (CST)

Uh... hi.  <sheepish look>

I know i've all but dropped out of existence for a long time, what with
my simultaneous first stints as a grad student, a teaching assistant, and
a house cook (!) and all, but i didn't want to let this work go to waste.

Now that the holidays are here i can *finally* try to get some work done!

So, i've updated inspect.py in response to Barry's comments, and below is
my reply to this old thread.  I also wrote some regression tests.

I tried to submit inspect.py to SourceForge, but i got:


    Patch Uploaded ERROR - Submission failed PQsendQuery() -- query is
    too long.  Maximum length is 16382

Does anyone know what's going on with that?

Anyway, the latest module and regression tests are available at:


for your perusal.

On Thu, 26 Oct 2000 barry@wooz.org wrote:
> Some thoughts after an initial scan of inspect.py:
> - The doc strings for the is*() functions aren't accurate.
>   E.g. ismodule() says that it asks whether "the object is a module
>   with the __file__ special attribute", but that isn't really what it
>   tests!  Guido points out that builtin modules don't currently have
>   __file__ and besides, you're really testing that the type of the
>   object is ModuleType.

Perhaps a different wording would be better, but i should at least
clarify the intention: i wrote them that way because it seemed that
the current objects export an unofficial "interface" by means of the
special attributes they provide.  The purpose of the "is*()" functions
is to determine whether an object meets one of these interfaces.

A complete interface would provide (1) a type-checker, (2) a constructor,
and (3) the methods.  As for (2), we don't normally allow construction of
these things (except for wizards using the newmodule).  As for (3), i
suppose that one could further encapsulate these interfaces by providing
spelled-out methods like "def getcode(f): return f.func_code", but it
didn't seem worth the trouble.  So that left just (1), and i had the
other parts in mind while trying to describe (1).

The type-checkers aren't of much use unless they accurately reflect
the availability of the special attributes.  Do you see what i'm trying
to do?  Maybe you can suggest a better way of doing it... anyway, i've
tried to compromise in the docstrings as submitted.

> - Don't make the predicate in getmembers() default to "lambda x: 1"
>   Instead make the default None, and skip the predicate test if it is
>   None.

Okay, fine.

> - getdoc()'s docstring should describe the margin munging it does.

Okay, done.

> - findsource() seems off-by one, e.g.
>    >>> x = inspect.findsource(inspect.findsource)
>    >>> x[1]
>    138
>    but the function really stars on line 139.

138 was the intended result here.  Indeed the function starts
on line 139 if you start counting from 1.  The reason it returns
138 is that it's the index you would use for the array of lines
(thus x[0][x[1]] or file.readlines()[138] is the first line of
the function).

Which way makes more sense?  Should it be changed?

> - I notice that currentframe() still uses the try/except trick to get
>   the frame object.  It's much more efficient to provide a C
>   trampoline for getting that information.

Sure, if there's a faster way, that's fine.  It just wasn't
something i expected to be used really often, and i wanted to
write the module in pure Python so it could be easily maintained.

I added a line to clobber the pure-Python currentframe() with
sys._getframe() if it exists.

> - If this were included in the library, we might want to 2.0-ify it.

It currently doesn't rely on any 2.0 features, and it would be
kind of nice to have it still work with 1.5 (especially if it is
part of a drop-in documentation tool, as it is now, since it goes
with htmldoc).

-- ?!ng

"Computers are useless.  They can only give you answers."
    -- Pablo Picasso