How to do type checking with Python set?

I am reading the typing code of the module, as well as looking at mypy to understand how it performs type checking. Unfortunately for me, mypy creates a very smart tree with typed expressions that I still don't understand, and all this is based on static analysis.

I would like to implement a type checking system that is dynamic (without static analysis) in Python. Assuming the type checking function is called check_type , I want to do the following:

 >>> import typing >>> >>> check_type(1, int) True >>> check_type(1, float) False >>> check_type([1], typing.List[int]) True >>> check_type([1], typing.List[float]) False >>> check_type([1], typing.List[typing.Any]) True >>> check_type((1,), typing.Tuple[int]) True 

I was thinking of recreating an object type from its value, for example:

 >>> get_type([1]) typing.List<~T>[int] 

But this does not work with issubclass :

 >>> issubclass(typing.List[int], typing.List[typing.Any]) False 

I don’t see an easy way to check types in Python without taking a lot of things about the internal elements of the typing stdlib module (e.g. access to __args__ or __tuple_params__ ).

How can I correctly implement the check_type function, which works for the cases listed above? I am using Python 2.7.

+5
source share
1 answer

You can easily get very limited functionality that works correctly for the simple examples presented in your question:

 import mypy.api def check_type(value, typ): program_text = 'from typing import *; v: {} = {}'.format(typ, repr(value)) normal_report, error_report, exit_code = mypy.api.run(['-c', program_text]) return exit_code == 0 int_ = 1 str_ = 'a' list_str_ = ['a'] list_int_ = [1] tuple_int_ = (1,) assert check_type(int_, 'int') assert not check_type(str_, 'int') assert check_type(list_int_, 'List[int]') assert not check_type(list_str_, 'List[int]') assert check_type(list_int_, 'List[Any]') assert check_type(tuple_int_, 'Tuple[int]') 

You can even do some more advanced things (for example, refer to types that correspond to the classes defined in your program) by expanding this code a bit so that mypy can parse all of your source code, not just the current line.

Alternatively, you can look at enforce or typeguard .

+1
source

All Articles