[issue20189] inspect.Signature doesn't recognize all builtin types

Larry Hastings report at bugs.python.org
Thu Jan 23 23:16:24 CET 2014


Larry Hastings added the comment:

I'm happy to resolve it before checking in the patch.
A small delta like that doesn't need a full-on review.

If people said "eww" then I'll back it out.  Nobody said "eww"
to the "PyModuleDef *module" change (see below), and I'm not
here to pick a fight.

But let's talk about it a little!

--

First, the name *is* visible in Python, if you examine the unbound
version.

    >>> str(inspect.signature(_datetime.datetime.__dict__['now']))
    `(<type>, tz=None)`
    >>> help(_datetime.datetime.__dict__['now'])
    # ... shows help, including <type> parameter in the signature

The angle-brackets are Signature's way of denoting a positional-only
parameter, which it is.   That parameter isn't addressable by name.

(The ugly angle brackets are being addressed in another issue.)

--

Second, I'm surprised at the behavior of help.  I hadn't realized
that it showed you bound parameters for callables you passed in.

    >>> class C:
    ...   @classmethod
    ...   def wife(cls, a, b):
    ...     print(cls, a, b)
    ... 
    >>> help(C.wife)

That shows "cls" as part of the signature.  But inspect.signature
does not:

    >>> str(inspect.signature(C.wife))
    '(a, b)'

FWIW help on a callable bound using functools.partial shows you
help on the functools.partial class, so no guidance there.

(help() only goes one level deep on this by the way.  If you have
a types.MethodType which binds another types.MethodType, help
only peeks in the first one.  But now I'm just showing off.)

Anyway, I think it's odd, but I'm not here to change the behavior
of help.  I'll work on fixing help so it shows the already-bound
parameters.

--

Third, it's inconvenient to use "type" as an identifier in Python code,
because "type" is a Python builtin.  And it's impossible to use "class"
because it's a keyword.  So people use "cls" or "klass" according to
personal taste.

We don't have these restrictions in C.  So actually "class" would
work--except C++ uses "class" as a keyword.  Let's not go there.
But "type" works fine.

--

Fourth, I already called the first parameter "type" for __new__
calls, as that seemed to be the convention there.  It was just
class methods where I called it "cls".  But... __new__ *is* a
class method.  This is an artificial distinction.

At the very least, I want Argument Clinic to use one name
consistently.  If everyone would prefer "cls" I don't care all
that much.  But I think "type" is a better name.  (For one,
it's not misspelled.)

--

Fifth, up until Argument Clinic, most callables had "PyObject *self"
as their first parameter.  But module-level callables never actually
get a "self", there's no "self" to call them with.  They actually
take the module object.  Everybody called the first parameter
"self" because they copied-and-pasted it from other code, and everyone
ignores that parameter anyway.

I proposed generating "PyModuleDef *module" there instead, Guido said
"good idea!"  I see this as similar, though the degree of error is
not as large.

----------

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue20189>
_______________________________________


More information about the Python-bugs-list mailing list