pschanely / CrossHair

An analysis tool for Python that blurs the line between testing and type systems.
Other
1.04k stars 49 forks source link

CrossHair dies on arguments with PEP604 Unions (e.g. "int|str") #161

Closed pschanely closed 2 years ago

pschanely commented 2 years ago

We expect a counterexample of "hi" here, but get an error instead.

There may be some related issues around these unions; note that typing_inspect does not yet understand them: https://github.com/ilevkivskyi/typing_inspect/pull/83

(ch_310) phillips-air:~ pschanely$ python -V
Python 3.10.0
(ch_310) phillips-air:~ pschanely$ cat foo.py
from typing import Union

def either(thing: (int|str)) -> (int|str):
    '''
    post: __return__ != "hi"
    '''
    return thing
(ch_310) phillips-air:~ pschanely$ crosshair check foo.py
Traceback (most recent call last):
  File "/Users/pschanely/miniconda3/envs/ch_310/bin/crosshair", line 33, in <module>
    sys.exit(load_entry_point('crosshair-tool', 'console_scripts', 'crosshair')())
  File "/Users/pschanely/proj/CrossHair/crosshair/main.py", line 658, in main
    sys.exit(unwalled_main(cmd_args))
  File "/Users/pschanely/proj/CrossHair/crosshair/main.py", line 608, in unwalled_main
    return check(args, options, sys.stdout, sys.stderr)
  File "/Users/pschanely/proj/CrossHair/crosshair/main.py", line 581, in check
    for message in run_checkables(analyze_any(entity, options)):
  File "/Users/pschanely/proj/CrossHair/crosshair/core.py", line 708, in run_checkables
    collector.extend(checkable.analyze())
  File "/Users/pschanely/proj/CrossHair/crosshair/core.py", line 639, in analyze
    analysis = analyze_calltree(options, conditions)
  File "/Users/pschanely/proj/CrossHair/crosshair/core.py", line 980, in analyze_calltree
    call_analysis = attempt_call(
  File "/Users/pschanely/proj/CrossHair/crosshair/core.py", line 1188, in attempt_call
    bound_args = gen_args(conditions.sig) if bound_args is None else bound_args
  File "/Users/pschanely/proj/CrossHair/crosshair/core.py", line 586, in gen_args
    value = proxy_for_type(param.annotation, smt_name, allow_subtypes)
  File "/Users/pschanely/proj/CrossHair/crosshair/core.py", line 549, in proxy_for_type
    return proxy_for_class(typ, varname)
  File "/Users/pschanely/proj/CrossHair/crosshair/core.py", line 388, in proxy_for_class
    data_members = get_type_hints(typ)
  File "/Users/pschanely/miniconda3/envs/ch_310/lib/python3.10/typing.py", line 1827, in get_type_hints
    raise TypeError('{!r} is not a module, class, method, '
TypeError: int | str is not a module, class, method, or function.
pschanely commented 2 years ago

Type unions are now supported! Example: https://crosshair-web.org/?crosshair=0.1&python=3.8&gist=51a25bf875d256fe7f7eba58e481cae3