[Python-ideas] PEP 484 (Type Hints) -- first draft round

Steven D'Aprano steve at pearwood.info
Sat Jan 17 06:49:26 CET 2015


Very nice! Some comments/questions below.


On Fri, Jan 16, 2015 at 09:17:36AM -0800, Guido van Rossum wrote:

> Type Definition Syntax
> ======================
[...]
> An optional type is also automatically assumed when the default value is
> ``None``, for example::
> 
>   def handle_employee(e: Employee = None): ...
> 
> This is equivalent to::
> 
>   def handle_employee(e: Optional[Employee] = None): ...
> 
> .. FIXME: Is this really a good idea?

I think it is. It seems to me to be a form of type inference: you are 
declaring that e is an Employee, but inferring that it could also be 
None. Either the type system reports this as an error, or it infers that 
the type is intended to be optional. Given how common it is for 
arguments to be "X or None" having shorthand for that is a good thing.



> Platform-specific type checking
> -------------------------------
> 
> In some cases the typing information will depend on the platform that
> the program is being executed on.  To enable specifying those
> differences, simple conditionals can be used::

Since CPython isn't going to do type-checking itself, instead it 
will leave it up to external tools. Given that, I 
assume that you are specifying the minimum requirements for such a 
tool, rather than a declaration of what some specific tool will do. 
Correct?

Hence, type-checkers should be able to deal with "simple conditionals" 
as in the examples given, and are not required to emulate a full Python 
interpreter in order to make sense of arbitrarily complex conditionals 
like:

    if (PY2 and WINDOWS) or (PY3 and POSIX): ...

But a sophisticated type-checker may offer more than the minimum. 
Is this correct?

There are a number of places where the PEP mentions "the type checker", 
e.g. the next paragraph. I think the PEP should clarify what exactly is 
meant by that.

> Arbitrary literals defined in the form of ``NAME = True`` will also be
> accepted by the type checker to differentiate type resolution::

As above. How arbitrary are the literals? Only bool flags? If so, the 
PEP should say "Boolean literals" rather than "arbitrary literals".



> Compatibility with other uses of function annotations
> -----------------------------------------------------
> 
> A number of existing or potential use cases for function annotations
> exist, which are incompatible with type hinting.  These may confuse a
> static type checker.  However, since type hinting annotations have no
> run time behavior (other than evaluation of the annotation expression
> and storing annotations in the ``__annotations__`` attribute of the
> function object), this does not make the program incorrect -- it just
> makes it issue warnings when a static analyzer is used.

I understood from early discussions that type checking would only be 
enabled if you imported `typing`. If so, then the easy way to disable 
type checks for a whole module was not to import anything from `typing`. 



> To mark portions of the program that should not be covered by type
> hinting, use the following:
> 
> * a ``@no_type_checks`` decorator on classes and functions
> 
> * a ``# type: ignore`` comment on arbitrary lines
> 
> .. FIXME: should we have a module-wide comment as well?

Rather than have to comment each and every line, can we marking entire 
sections with a directive?

# type: off
...
...
# type: on
...


This will still allow `type: ignore` if you want to skip a single line, 
and allow module-wide control by simply starting your module with 
`type: off` and not turning it back on.

Where will the @no_type_checks decorator live? In the typing module or 
as a builtin?

I see from below that directives of the form `type: spam` are allowed. 
That could clash with `type: ignore` etc. Although it is not PEP 8 
compliant, people might have classes called "ignore", "on", "off". How 
about we require keywords to the type directive to have a leading + 
sign?

# type: +ignore   # Keyword "ignore", don't type check this line.
# type: ignore  # Declare the type is class "ignore".

Otherwise there is going to be the risk of clashes.



> Type Hints on Local and Global Variables
> ========================================
> 
> No first-class syntax support for explicitly marking variables as being
> of a specific type is added by this PEP.  To help with type inference in
> complex cases, a comment of the following format may be used::
> 
>   x = []   # type: List[Employee]

Without the type declaration, x would be inferred to be of type 
List[Any]. Is that correct? Perhaps that should go into the PEP.


> In the case where type information for a local variable is needed before
> if was declared, an ``Undefined`` placeholder might be used::
^^^^^

Typo, should read "it was declared".



-- 
Steven


More information about the Python-ideas mailing list