[Python-ideas] Proposal: Use mypy syntax for function annotations
Steven D'Aprano
steve at pearwood.info
Tue Aug 26 03:48:40 CEST 2014
On Mon, Aug 25, 2014 at 07:36:53PM -0400, Terry Reedy wrote:
> I am referring to the current stdlib runtime use of .__annotations__
> directly by inspect.getfullargspec and now inspect.signature and
> indirectly by Idle calltips.
>
> def f(n:[int, 'random non-type info'])->(int, 'more non-type info'): pass
> import inspect as ip
> print(ip.formatargspec(*ip.getfullargspec(f)))
> print(str(ip.signature(f)))
>
> (n: [<class 'int'>, 'random non-type info']) -> (<class 'int'>, 'more
> non-type info')
> (n:[<class 'int'>, 'random non-type info']) -> (<class 'int'>, 'more
> non-type info')
>
> (Idle currently displays the first, will change to the second. The
> display difference is more pronounced (now, at least) for C functions
> with .__text_signature__ from Argument Clinic.)
>
> To me, 'argument specification' and especially 'signature' imply
> arguments names and types, but not other stuff.
I don't think that's a useful defintion for Python.
There is no hard definition of "function signature" in computer science,
since different languages provide different information in the function
declaration. But here's a definition from the C++ world which seems to
capture the gist of it to me:
A function signature consists of the function prototype. What
it tells you is the general information about a function, its
name, parameters, what scope it is in, and other miscellaneous
information.
http://www.cs.unm.edu/~storm/C++/ProgrammingTerms/FunctionSignatures.html
To put it another way, it's anything in the function declaration apart
from the actual body of the function. In the case of Python, that
includes annotations, which currently have no official semantics, but
may include type hints, or documentation, or anything else.
> Certainly, name and type
> is all that is wanted for a tip on how to write a call. Extra stuff
> would typically be noise in this context -- especially for beginners.
I think that it is particularly for beginners that "extra stuff" in the
form of documentation could be useful. Don't think of "random non-type
info", as you state above, think of NON-random information about the
parameter. The most obvious example is documentation about what the
parameter represents.
Here's a hypothetical example of what I might have done had annotations
not been prohibited in the standard library:
print(inspect.signature(statistics.pvariance))
=> (data, mu:"pre-calculated mean of the data, if already known"=None)
So I think that there's no good reason to decide, ahead of time, that
the information in an annotation is "noise" in a tool-tip. I think the
tool-tip should show whatevr information the author of the function
thinks is important enough to go in the annotation.
(However, the tool-tip might choose to format it a bit more nicely than
it currently does. But that's a separate discussion.)
> >I can only assume that you are thinking of a situation where you are
> >introspecting some function/method of unknown origin and you are trying
> >to see if it has any annotations, in which case you are going to use
> >them for a locally-defined use (e.g. generate an HTML form -- contrived
> >example).
> >
> >It sounds as if you are worried about being passed a function that in
> >the past would not have any annotations (so you would just generate a
> >default form based on the argument names) but which now has been
> >annotated by a zealous programmer with type hints. And you are worried
> >that those type hints will confuse (perhaps crash) the form-generation
> >code.
>
> I am worried about annotations other than type hints. Compact type
> hints, especially for type-opaque parameter names, should improve the
> usefulness of call tips. Extra noise detracts.
Certainly "noise" detracts, but you have no reason to assume that
annotations can only be two things: type hints, or noise.
In fact, I would argue that for a beginner, type hints will often be
noise. Do you expect beginners to understand ABCs? If not, what are they
to make of something like this?
flatten(it:Iterable[Any])->Sequence[Any]
--
Steven
More information about the Python-ideas
mailing list