[Python-ideas] PEP 484 (Type Hints) -- first draft round
Steven D'Aprano
steve at pearwood.info
Mon Jan 19 02:58:39 CET 2015
On Sun, Jan 18, 2015 at 05:24:51PM -0500, Cem Karan wrote:
> def foo(a: {Type(int), Doc("some doc")}, b):
> pass
I dislike this, because there is too much in the function signature. I
could live with this:
def foo(a:int, b): pass
or *possibly* this:
def foo(a:"some doc", b): pass
but not both together. Combining the two doesn't look too bad for a toy
example like made-up "foo", but think about a real-world example:
# from the statistics module
def median_grouped(
data: {Type(Iterable[Real]), Doc("grouped continuous data")},
interval: {Type(Real), Doc("class interval")} = 1
) -> {Type(Real), Doc(
"50th percentile (median) of grouped continuous data")}:
pass
That may be machine-readable, but it is too complicated for me to read,
and I wrote it! And that's only a simple function with a mere two
parameters and simple one-liner docs.
Having written that, I still need to write a doc string, and almost
certainly I have to duplicate the annotation docs inside the docstring.
So it isn't really saving me much, if anything, over this:
@Doc({"data": "grouped continuous data",
"interval": "class interval",
"return": "50th percentile (median) of grouped continuous data"
})
def median_grouped(data:Iterable[Real], interval:Type(Real)=1)->Real:
pass
It's not *ideal* to have to duplicate the parameter names in the
decorator, but except in the most trivial toy cases, I can't have it
all:
- type annotations
- and document annotations
- without being too verbose or complex
- and still easy to read and write and maintain
Something has to give, and since type-hinting is deemed to be the
primary use for annotations, it has to be the document annotations. You
can still have both type-hints and docs, you just can't use annotations
for them both. (But see below.)
- If you want to use annotations for documentation, then you
cannot use them for type-hints at the same time;
- if you want to use annotations for type-hints, then you
need another method of dealing with the documentation.
Since you almost certainly will need to write a docstring anyway, the
best solution in my mind is to move the documentation into the
docstring:
def median_grouped(data:Iterable[Real], interval:Type(Real)=1)->Real:
"""Return the 50th percentile (median) of grouped continuous data.
:param a: grouped continuous data
:param interval: class interval
more documentation and docstrings follows...
"""
> With annotations, the documentation lives with the argument. If
> typing rules all, then you might accidentally have the following:
>
> def foo(a: int, b):
> """
> :param a: some doc
> :type a: str <- Whoops! Type conflict!
> """
> pass
And that is best solved by having your linter understand the convention
for docstrings and flag the error.
> I'm arguing that with annotations we can put a lot more information in
> about a given function argument/return value than just typing.
Of course you can. But I think you shouldn't.
You are absolutely free to disagree. Remember, use of the type-checker
is optional, and the type-checker itself will be a third-party tool.
Tools actually. I expect there will be much competition to develop the
best, most powerful type-checker.
There is nothing stopping people (including yourself) writing a
type-checker which supports your multiple-annotations-in-a-set idea. If
it proves itself as a viable, and popular, alternative, then you can
come back and try to convince Guido to give it his blessing as
officially sanctioned (at which point all the other type-checkers will
have to support sets of annotations as well).
I *do* believe that it is technically possible to have the type-checker
support your {Type(...), Spam(...)} idea, but I *don't* believe that it
will be practical or popular. I think it is a case of YAGNI combined
with EIYDNIYSDI (Even If You Do Need It You Shouldn't Do It). But I
might be wrong, and I encourage you to prove me wrong the only way that
really matters: with working code that gets used in the real world.
--
Steven
More information about the Python-ideas
mailing list