Python is DOOMED! Again!

MRAB python at mrabarnett.plus.com
Thu Jan 29 21:11:40 EST 2015


On 2015-01-29 23:25, Chris Kaynor wrote:
> On Thu, Jan 29, 2015 at 2:57 PM, BartC <bc at freeuk.com> wrote:
[snip]
>> Putting in hints, (as as I implemented them using primitive types),
>> meant that functions and code no longer worked in a generic (or
>> polymorphic) manner. Code also changes, but the type hints aren't
>> maintained. I understand the Python proposal allows type hints to
>> be a union of expected types, but that sounds complicated.
>
> Regarding the maintenance of type-hints, for people who heavily use
> them, I would imagine they will have a static checker setup which
> will regularly run and generally produce an error if the hints are
> not updated. Most other people will likely only lightly use the
> type-hints and may not use static checkers, and thus they probably
> will get out of sync. With such a feature, my main use case would be
> to aid IDEs in providing auto-complete, which I've done in the past
> by adding lines like "if 0: assert isinstance(variable, type)". Most
> of the functions I write do not have any such "hints" but instead
> I've only generally used it in cases where the type is pretty much
> fixed, but is a custom type with a more complicated API.
>
I suppose you could check what types the arguments are by running the
code and outputting the types supplied, and then run a script that uses
the info to modify the source, and then you can diff the result.

Here's a simple example I've come up with:


#! python3.4
# -*- coding: utf-8 -*-
import inspect

def check_hints(func):

     def wrapper(*args, **kwargs):
         sig = inspect.signature(func)
         print('file      :', inspect.getfile(func))
         print('function  :', func.__name__)
         print('line      :', inspect.getsourcelines(func)[1] + 1)

         args_given = list(args)
         kwargs_given = dict(kwargs)

         for name in sig.parameters:
             param = sig.parameters[name]
             if param.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD:
                 annotation = param.annotation
                 if args_given:
                     print('parameter : {} : {}'.format(name,
                       type(args_given.pop(0)).__name__))
                     if annotation != inspect.Parameter.empty:
                         print('annotation: {} : {}'.format(name,
                           annotation.__name__))
                 else:
                     try:
                         print('parameter : {} : {}'.format(name,
                           type(kwargs_given.pop(name)).__name__))
                         if annotation != inspect.Parameter.empty:
                             print('annotation: {} : {}'.format(name,
                               annotation.__name__))
                     except KeyError:
                         pass

         result = func(*args, **kwargs)

         print('return    : {}'.format(type(result).__name__))
         annotation = sig.return_annotation
         if annotation != inspect.Parameter.empty:
             print('annotation: {}'.format(annotation.__name__))

         print()

         return result

     return wrapper

@check_hints
def foo(arg1: int, arg2: str, arg3: float=2.0) -> int:
     pass

@check_hints
def bar(arg1, arg2, arg3=2.0):
     pass

foo(1, "bar")
foo("baz", 2, 3.0)

bar(1, "bar")
bar("baz", 2, 3.0)



More information about the Python-list mailing list