<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Aug 15, 2014 at 7:46 PM, Ethan Furman <span dir="ltr"><<a href="mailto:ethan@stoneleaf.us" target="_blank">ethan@stoneleaf.us</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Sounds like what we *really* need is a decorator that will parse the docstring and fill in the annotations automatically.  :)</blockquote>
</div><br>While it may be contrary to the TOOWTDI principle, but I think decorator- and annotations-based type specifications can co-exist.  I have been using the following decorator for about a year</div><div class="gmail_extra">
<br></div><div class="gmail_extra"><div class="gmail_extra">def returns(type):</div><div class="gmail_extra">    """emulate -> attribute setting in python 2"""</div><div class="gmail_extra">
<br></div><div class="gmail_extra">    def decorator(func):</div><div class="gmail_extra">        func.__dict__.setdefault('__attributes__', {})['return'] = type</div><div class="gmail_extra">        return func</div>
<div class="gmail_extra"><br></div><div class="gmail_extra">    return decorator</div></div><div class="gmail_extra"><br></div><div class="gmail_extra">and I often find code that uses for example @returns(int) more readable than the code that uses .. -> int:</div>
<div class="gmail_extra"><br></div><div class="gmail_extra">The advantage of argument annotations over any decorator-based solution is avoidance of repetition, but I often miss K&R-style declarations in C.  Probably because</div>
<div class="gmail_extra"><br></div><div class="gmail_extra">int</div><div class="gmail_extra">copy(from, to)</div><div class="gmail_extra">char *from; </div><div class="gmail_extra">char *to;</div><div class="gmail_extra">
{..}</div><div class="gmail_extra"><br></div><div class="gmail_extra">looks more "pythonic" than</div><div class="gmail_extra"><br></div><div class="gmail_extra"><div class="gmail_extra">int</div><div class="gmail_extra">
copy(char *from, char *to)</div><div class="gmail_extra">{}</div><div class="gmail_extra"><br></div><div class="gmail_extra">In python, what is more readable:</div><div class="gmail_extra"><br></div><div class="gmail_extra">
def copy(from:Sequence, to:MutableSequence):</div><div class="gmail_extra">       ..</div><div class="gmail_extra"><br></div><div class="gmail_extra">or</div><div class="gmail_extra"><br></div><div class="gmail_extra">@arg_types(from=Sequence, to=MutableSequence)</div>
<div class="gmail_extra">def copy(from, to):<br></div><div class="gmail_extra">    ..</div><div class="gmail_extra"><br></div><div class="gmail_extra">or</div><div class="gmail_extra"><br></div><div class="gmail_extra"><div class="gmail_extra">
def copy(from, to):<br></div><div class="gmail_extra">    ..</div><div><br></div><div>set_arg_types(copy, from=Sequence, to=MutableSequence)</div><div><br></div><div>?</div><div><br></div><div><br></div></div><div class="gmail_extra">
I believe that having type specifications out of the way in the last variant more than outweighs the need to repeat the names of arguments.</div><div class="gmail_extra"><br></div><div class="gmail_extra">Even the repetition  can be avoided if we do something like</div>
<div class="gmail_extra"><br></div><div class="gmail_extra"><div class="gmail_extra">@arg_types(Sequence, MutableSequence)</div><div class="gmail_extra">def copy(from, to):<br></div><div class="gmail_extra">    ..</div><div class="gmail_extra">
<br></div><div class="gmail_extra">but this is still more intrusive than the after-body variant where function name repetition is unavoidable and argument names repetition improves readability.</div><div class="gmail_extra">
<br></div><div class="gmail_extra">I can imagine cases where having type specifications follow each argument is helpful.  For example</div><div class="gmail_extra"><br></div><div class="gmail_extra">def configure(d:Drawing, c:Configuration):</div>
<div class="gmail_extra">   d.background = c.get_parameter('background')</div><div class="gmail_extra">   d.height = c.get_parameter('height')</div><div class="gmail_extra">   ..</div><div class="gmail_extra">
<br></div><div class="gmail_extra">It really depends on the problem at hand and on the coding style whether you may want type specification before or within the function declaration or out of the way in docstring, after the function body or in a separate "stubs" file altogether.</div>
<div class="gmail_extra"><br></div><div class="gmail_extra">If Python gets an official standard for specifying types in function attributes, it should not be hard to standardize docstring and decorator alternatives as well.  As a bonus, these alternatives will be immediately available to 2.x users.</div>
</div></div></div>