<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Jan 16, 2015 at 9:49 PM, Steven D'Aprano <span dir="ltr"><<a href="mailto:steve@pearwood.info" target="_blank">steve@pearwood.info</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
On Fri, Jan 16, 2015 at 09:17:36AM -0800, Guido van Rossum wrote:<br>
<br>
> Type Definition Syntax<br>
> ======================<br>
[...]<br>
<span class="">> An optional type is also automatically assumed when the default value is<br>
> ``None``, for example::<br>
><br>
>   def handle_employee(e: Employee = None): ...<br>
><br>
> This is equivalent to::<br>
><br>
>   def handle_employee(e: Optional[Employee] = None): ...<br>
><br>
> .. FIXME: Is this really a good idea?<br>
<br>
</span>I think it is. It seems to me to be a form of type inference: you are<br>
declaring that e is an Employee, but inferring that it could also be<br>
None. Either the type system reports this as an error, or it infers that<br>
the type is intended to be optional. Given how common it is for<br>
arguments to be "X or None" having shorthand for that is a good thing.<br></blockquote><div><br></div><div>Agreed. I'm removing the FIXME. <br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">
> Platform-specific type checking<br>
> -------------------------------<br>
><br>
> In some cases the typing information will depend on the platform that<br>
> the program is being executed on.  To enable specifying those<br>
> differences, simple conditionals can be used::<br>
<br>
</span>Since CPython isn't going to do type-checking itself, instead it<br>
will leave it up to external tools. Given that, I<br>
assume that you are specifying the minimum requirements for such a<br>
tool, rather than a declaration of what some specific tool will do.<br>
Correct?<br></blockquote><div><br></div><div>Yes. A type checker is an immensely complex tool, and there are many gray areas where the PEP just can't hope to be rigorous. In the end the use of the type checker is meant as a linter, not as the rigorous definition of the language (which can do things no type checker can understand).<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Hence, type-checkers should be able to deal with "simple conditionals"<br>
as in the examples given, and are not required to emulate a full Python<br>
interpreter in order to make sense of arbitrarily complex conditionals<br>
like:<br>
<br>
    if (PY2 and WINDOWS) or (PY3 and POSIX): ...<br></blockquote><div><br></div><div>That already feels too complex -- not because the checker couldn't figure out the value, but because I don't want to support complex expressions in other places (before you know it, you're using conditionals in argument annotations, and I really don't want to go there).<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
But a sophisticated type-checker may offer more than the minimum.<br>
Is this correct?<br></blockquote><div><br></div><div>Sure.<br> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
There are a number of places where the PEP mentions "the type checker",<br>
e.g. the next paragraph. I think the PEP should clarify what exactly is<br>
meant by that.<span class=""><br></span></blockquote><div><br></div><div>You're right. There's some language in the "Usage Patterns" sections but it makes more sense to explain this upfront. (Also that section hints at runtime checking, which really should be considered quite out of scope.)<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">
> Arbitrary literals defined in the form of ``NAME = True`` will also be<br>
> accepted by the type checker to differentiate type resolution::<br>
<br>
</span>As above. How arbitrary are the literals? Only bool flags? If so, the<br>
PEP should say "Boolean literals" rather than "arbitrary literals".<span class=""><br></span></blockquote><div><br></div><div>Agreed. I think we need to work with Jukka on a spec of what the minimum complexity is that the checker should support for this purpose (even though in other contexts it of course must  understand non-constant expressions, since it must type-check them :-).<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">
<br>
<br>
> Compatibility with other uses of function annotations<br>
> -----------------------------------------------------<br>
><br>
> A number of existing or potential use cases for function annotations<br>
> exist, which are incompatible with type hinting.  These may confuse a<br>
> static type checker.  However, since type hinting annotations have no<br>
> run time behavior (other than evaluation of the annotation expression<br>
> and storing annotations in the ``__annotations__`` attribute of the<br>
> function object), this does not make the program incorrect -- it just<br>
> makes it issue warnings when a static analyzer is used.<br>
<br>
</span>I understood from early discussions that type checking would only be<br>
enabled if you imported `typing`. If so, then the easy way to disable<br>
type checks for a whole module was not to import anything from `typing`.<span class=""><br></span></blockquote><div><br></div><div>I changed my mind about that (and I don't think mypy has ever strictly followed this rule). The reason is that it's quite sensible to use built-in types (e.g. int) and user-defined classes as type annotations and expect the checker to do its thing. It's only when you need things like generic classes, unions etc. that you must import typing.<br></div><div> </div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">
> To mark portions of the program that should not be covered by type<br>
> hinting, use the following:<br>
><br>
> * a ``@no_type_checks`` decorator on classes and functions<br>
><br>
> * a ``# type: ignore`` comment on arbitrary lines<br>
><br>
> .. FIXME: should we have a module-wide comment as well?<br>
<br>
</span>Rather than have to comment each and every line, can we marking entire<br>
sections with a directive?<br>
<br>
# type: off<br>
...<br>
...<br>
# type: on<br>
...<br>
<br>
<br>
This will still allow `type: ignore` if you want to skip a single line,<br>
and allow module-wide control by simply starting your module with<br>
`type: off` and not turning it back on.<br></blockquote><div><br></div><div>We don't have the definitive design. See <a href="https://github.com/ambv/typehinting/issues/16">https://github.com/ambv/typehinting/issues/16</a> and <a href="https://github.com/ambv/typehinting/issues/35">https://github.com/ambv/typehinting/issues/35</a> .<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Where will the @no_type_checks decorator live? In the typing module or<br>
as a builtin?<br></blockquote><div><br></div><div>In the typing module.<br> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
I see from below that directives of the form `type: spam` are allowed.<br>
That could clash with `type: ignore` etc. Although it is not PEP 8<br>
compliant, people might have classes called "ignore", "on", "off". How<br>
about we require keywords to the type directive to have a leading +<br>
sign?<br>
<br>
# type: +ignore   # Keyword "ignore", don't type check this line.<br>
# type: ignore  # Declare the type is class "ignore".<br></blockquote><div><br></div><div>I'm not keen on the special meaning of +. We might using "# typing: ..." for directives, or we might just use some all_caps names, e.g. "# type: IGNORE".<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Otherwise there is going to be the risk of clashes.<span class=""><br></span></blockquote><div><br></div><div>I think the risk of clashes can be made sufficiently low that we can say "tough luck".<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">
<br>
<br>
> Type Hints on Local and Global Variables<br>
> ========================================<br>
><br>
> No first-class syntax support for explicitly marking variables as being<br>
> of a specific type is added by this PEP.  To help with type inference in<br>
> complex cases, a comment of the following format may be used::<br>
><br>
>   x = []   # type: List[Employee]<br>
<br>
</span>Without the type declaration, x would be inferred to be of type<br>
List[Any]. Is that correct? Perhaps that should go into the PEP.<br></blockquote><div><br></div><div>Correct. (What else could it be? Although I think that if x has been given a type earlier, the [] is checked against that type.)<br><br></div><div>If you think the PEP is insufficiently clear, could you submit a PR? (BTW, to anyone else considering PRs against the GitHub repo, please create a regular issue when you want to change the proposed behavior or syntax. PRs are good for clarifications, typos etc.)<br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">
> In the case where type information for a local variable is needed before<br>
> if was declared, an ``Undefined`` placeholder might be used::<br>
</span>^^^^^<br>
<br>
Typo, should read "it was declared".<span class=""><font color="#888888"><br></font></span></blockquote><div><br></div><div>Will fix. (I also think it should be "it is declared".)<br><br></div></div>-- <br><div class="gmail_signature">--Guido van Rossum (<a href="http://python.org/~guido">python.org/~guido</a>)</div>
</div></div>