[Python-ideas] Check type hints in stack trace printing

Jacco van Dorp j.van.dorp at deonet.nl
Wed Jun 20 06:13:06 EDT 2018


2018-06-20 11:43 GMT+02:00 Daniel Sánchez Fábregas
<daniel.sanchez.fabregas at xunta.gal>:
>
> El 14/06/18 a las 14:37, Steven D'Aprano escribió:
>> On Thu, Jun 14, 2018 at 01:03:37PM +0200, Daniel Sánchez Fábregas wrote:
>>> My idea consist in:
>>> Adding a method to perform type checking in traceback objects
>>> When printing stack traces search for mistyped arguments and warn about
>>> them to the user.
>> Can you give a concrete example of how this would work?
>>
> Example on how this should work from the user point of view:
>
> ~~~ python
>
> def one(arg: str) -> str:
>     return two(arg) + "1"
> def two(arg: str) -> str:
>     return three(arg) * 2
> def three(arg: str) -> str:
>     return "{}({}) ".format(arg, len(arg))
>
> print(one("test"))
> print(one(0))
>
> ~~~
>
> Intended output:
>
> ~~~
>
> test(4) test(4) 1
> Traceback (most recent call last):
>   File "test.py", line 9, in <module>
>     print(one(0))
>   Warning: TypeMistmatch argument 'arg' of type 'int' is declared as 'str'
>   File "test.py", line 2, in one
>     return two(arg) + "1"
>   Warning: TypeMistmatch argument 'arg' of type 'int' is declared as 'str'
>   File "test.py", line 4, in two
>     return three(arg) * 2
>   Warning: TypeMistmatch argument 'arg' of type 'int' is declared as 'str'
>   File "test.py", line 6, in three
>     return "{}({}) ".format(arg, len(arg))
> TypeError: object of type 'int' has no len()
>
> ~~~
>
> How could it be achieved? I don't know enough python to answer this. I
> suppose that it could be done.
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/

Looks like you could do this with a decorator, I think

def type_check_on_traceback(func):
    ann = typing.get_type_hints(func)
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except:
            for key, value in kwargs.items():
                if key in ann and not isinstance(value, ann[key]):
                    # emit warning
            raise
    return func

would be close, give or take some special cases. Not entirely sure how
this'd work with Optional[whatever] types, so you'd have to test that.

This takes a limitation on not checking the *args, but if you put some
effort in, the inspect module can probably let you check those too.


More information about the Python-ideas mailing list