[Python-ideas] Proposal to extend PEP 484 (gradual typing) to support Python 2.7
Terry Reedy
tjreedy at udel.edu
Sat Jan 9 15:24:10 EST 2016
On 1/8/2016 6:04 PM, Guido van Rossum wrote:
> At Dropbox we're trying to be good citizens and we're working towards
> introducing gradual typing (PEP 484) into our Python code bases (several
> million lines of code). However, that code base is mostly still Python
> 2.7 and we believe that we should introduce gradual typing first and
> start working on conversion to Python 3 second (since having static
> types in the code can help a big refactoring like that).
>
> Since Python 2 doesn't support function annotations we've had to look
> for alternatives. We considered stub files, a magic codec, docstrings,
> and additional `# type:` comments. In the end we decided that `# type:`
> comments are the most robust approach. We've experimented a fair amount
> with this and we have a proposal for a standard.
>
> The proposal is very simple. Consider the following function with Python
> 3 annotations:
>
> def embezzle(self, account: str, funds: int = 1000000,
> *fake_receipts: str) -> None:
> """Embezzle funds from account using fake receipts."""
> <code goes here>
>
> An equivalent way to write this in Python 2 is the following:
>
> def embezzle(self, account, funds=1000000, *fake_receipts):
> # type: (str, int, *str) -> None
> """Embezzle funds from account using fake receipts."""
> <code goes here>
I find the this separate signature line to be at least as readable as
the intermixed 3.x version. I noticed the same thing as Lemburg (no
runtime .__annotations__ attributes, but am not sure whether adding them
in 2.x code is a good or bad thing.
> There are a few details to discuss:
>
> - Every argument must be accounted for, except 'self' (for instance
> methods) or 'cls' (for class methods). Also the return type is
> mandatory. If in Python 3 you would omit some argument or the return
> type, the Python 2 notation should use 'Any'.
>
> - If you're using names defined in the typing module, you must still
> import them! (There's a backport on PyPI.)
>
> - For `*args` and `**kwds`, put 1 or 2 starts in front of the
> corresponding type annotation. As with Python 3 annotations, the
> annotation here denotes the type of the individual argument values, not
> of the tuple/dict that you receive as the special argument value 'args'
> or 'kwds'.
>
> - The entire annotation must be one line. (However, see
> https://github.com/JukkaL/mypy/issues/1102.)
To me, really needed.
> We would like to propose this as a standard (either to be added to PEP
> 484 or as a new PEP) rather than making it a "proprietary" extension to
> mypy only, so that others in a similar situation can also benefit.
Since I am personally pretty much done with 2.x, the details do not
matter to me, but I think a suggested standard approach is a good idea.
I also think a new informational PEP, with a reference added to 484,
would be better. 'Type hints for 2.x and 2&3 code'
For a helpful tool, I would at least want something that added a
template comment, without dummy 'Any's to be erased, to each function.
# type: (, , *) ->
A GUI with suggestions from both type-inferencing and from a name ->
type dictionary would be even nicer. Name to type would work really
well for a project with consistent use of parameter names.
--
Terry Jan Reedy
More information about the Python-ideas
mailing list