Showing content from http://mail.python.org/pipermail/python-dev/attachments/20160905/03d9ad4d/attachment-0001.html below:
<div dir="ltr"><div class="gmail_default" style="font-family:verdana,sans-serif">I would take the opposite approach from Greg Ewing, namely that the annotation is not a permission of values but a starting point for the type inferencer; and the type checker/inferencer can complain if there's an inconsistency (for some definition of "inconsistency", which is not defined in the PEP). In most cases, this distinction doesn't matter, but it does affect what kinds of errors or warnings are generated.<br></div><div class="gmail_default" style="font-family:verdana,sans-serif"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif">But ... perhaps people are overthinking these things? If we go back to the example without variable annotation:</div><div class="gmail_default" style="font-family:verdana,sans-serif"> </div><div class="gmail_default"><span style="font-family:arial,sans-serif;font-size:12.8px">  </span><font face="verdana, sans-serif"><span style="font-size:12.8px">def bar()->Optional[int]: ...</span><br></font></div><div class="gmail_default"><font face="verdana, sans-serif"><span style="font-size:12.8px"><br></span></font></div><div class="gmail_default"><font face="verdana, sans-serif">  def foo():</font></div><div class="gmail_default"><font face="verdana, sans-serif">   x = bar()</font></div><div class="gmail_default"><font face="verdana, sans-serif">   if x is None:</font></div><div class="gmail_default"><font face="verdana, sans-serif">    return -1</font></div><div class="gmail_default"><font face="verdana, sans-serif">   return x</font></div><div class="gmail_default" style="font-family:verdana,sans-serif"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif">then a straightforward flow-tracing type inferencer can *infer* all the annotations in foo:</div><div class="gmail_default" style="font-family:verdana,sans-serif"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif">  def foo() -> int:  # *not* Optional[int] - see below</div><div class="gmail_default" style="font-family:verdana,sans-serif">   x:Optional[int] = bar()  # derived from definition of bar</div><div class="gmail_default" style="font-family:verdana,sans-serif">   if x is None:  # consistent with x:Optional[int]</div><div class="gmail_default" style="font-family:verdana,sans-serif">    return -1  # implies return type of foo</div><div class="gmail_default" style="font-family:verdana,sans-serif">   return x  # implies return type of foo as Union[int, None] minus None, that is: int</div><div class="gmail_default" style="font-family:verdana,sans-serif"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif">That is, the type annotations add no information in this example, but might be useful to a human. Perhaps they wouldn't show in the source code at all, but would instead be put into a database, for use by development tools - for example, <a href="http://www.kythe.io/docs/kythe-overview.html" class="m_-7640408120673576725cremed cremed" target="_blank">Kythe</a>-flavored tools, where the type data (and other usage information) are used for code search, editing, refactoring, etc. (Or the type information could be kept in a .pyi stub file, with an automated "merge" tool putting them into the .py file as desired.)</div><div class="gmail_default" style="font-family:verdana,sans-serif"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif">On the other hand, a non-flow-tracing inferencer would derive 'def foo() -> Optional[int]' ... it would be a <i>design choice</i> of the type checker/inferencer as to whether that's an error, a warning, or silently allowed ... I can see arguments for all of these choices.</div><div class="gmail_default" style="font-family:verdana,sans-serif"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif">In most cases, there's seldom any need for the programmer to add annotations to local variables. Global variables and class/instance attributes, however, can benefit from annotation.</div><div class="gmail_default" style="font-family:verdana,sans-serif"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif">(As to my credentials, which some people seem to crave: I worked on an earlier version of Google's Python type inferencer (<i>pytype</i>) and I'm currently working on <i>pykythe </i>(to be open-sourced), which takes the function-level information and propagates it to the local variables, then adds that information (together with call graph information) to a Kythe database.)</div><div class="gmail_default" style="font-family:verdana,sans-serif"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif"><br></div><div class="gmail_extra"><br><div class="gmail_quote">On 5 September 2016 at 15:16, Greg Ewing <span dir="ltr"><<a href="mailto:greg.ewing@canterbury.ac.nz" class="m_-7640408120673576725cremed cremed" target="_blank">greg.ewing@canterbury.ac.nz</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>Mark Shannon wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Unless of course, others may have a different idea of what the "type of a variable" means.<br>
To me, it means it means that for all assignments `var = expr`<br>
the type of `expr` must be a subtype of the variable,<br>
and for all uses of var, the type of the use is the same as the type of the variable.<br>
</blockquote>
<br></span>
I think it means that, at any given point in time, the<br>
value of the variable is of the type of the variable or<br>
some subtype thereof. That interpretation leaves the<br>
type checker free to make more precise inferences if<br>
it can. For example, in...<span><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  def foo()->int:<br>
    x:Optional[int] = bar()<br>
    if x is None:<br>
      return -1<br>
    return x<br>
</blockquote>
<br></span>
...the type checker could notice that, on the branch<br>
containing 'return x', the value of x must be of type<br>
int, so the code is okay.<span class="m_-7640408120673576725HOEnZb"><font color="#888888"><br>
<br>
-- <br>
Greg</font></span><div class="m_-7640408120673576725HOEnZb"><div class="m_-7640408120673576725h5"><br>
<br>
______________________________<wbr>_________________<br>
Python-Dev mailing list<br>
<a href="mailto:Python-Dev@python.org" class="m_-7640408120673576725cremed cremed" target="_blank">Python-Dev@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-dev" rel="noreferrer" class="m_-7640408120673576725cremed cremed" target="_blank">https://mail.python.org/mailma<wbr>n/listinfo/python-dev</a><br>
Unsubscribe: <a href="https://mail.python.org/mailman/options/python-dev/pludemann%40google.com" rel="noreferrer" class="m_-7640408120673576725cremed cremed" target="_blank">https://mail.python.org/mailma<wbr>n/options/python-dev/pludemann<wbr>%40google.com</a><br>
</div></div></blockquote></div><br></div></div>
RetroSearch is an open source project built by @garambo
| Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4