[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