agronholm / typeguard

Run-time type checker for Python
Other
1.52k stars 114 forks source link

anyio can't be imported #397

Closed jolaf closed 1 year ago

jolaf commented 1 year ago

Things to check first

Typeguard version

4.1.3

Python version

3.10.12

What happened?

Ubuntu 22.04.3 Python 3.10.12:

Traceback (most recent call last):
  File "/tmp/test.py", line 4, in <module>
    import_module('anyio')
  File "/usr/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "/home/jolaf/.local/lib/python3.10/site-packages/typeguard/_importhook.py", line 98, in exec_module
    super().exec_module(module)
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/home/jolaf/.local/lib/python3.10/site-packages/anyio/__init__.py", line 101, in <module>
    from ._core._fileio import AsyncFile, Path, open_file, wrap_file
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "/home/jolaf/.local/lib/python3.10/site-packages/typeguard/_importhook.py", line 98, in exec_module
    super().exec_module(module)
  File "<frozen importlib._bootstrap_external>", line 879, in exec_module
  File "<frozen importlib._bootstrap_external>", line 1017, in get_code
  File "/home/jolaf/.local/lib/python3.10/site-packages/typeguard/_importhook.py", line 87, in source_to_code
    return _call_with_frames_removed(
  File "/home/jolaf/.local/lib/python3.10/site-packages/typeguard/_importhook.py", line 47, in _call_with_frames_removed
    return f(*args, **kwargs)
TypeError: required field "slice" missing from Subscript

Windows 10 Python 3.11.5:

Traceback (most recent call last):
  File "C:\Temp\test.py", line 4, in <module>
    import_module('anyio')
  File "C:\Python311\Lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
  File "C:\Python311\Lib\site-packages\typeguard\_importhook.py", line 98, in exec_module
    super().exec_module(module)
  File "<frozen importlib._bootstrap_external>", line 940, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "C:\Python311\Lib\site-packages\anyio\__init__.py", line 21, in <module>
    from ._core._fileio import AsyncFile as AsyncFile
  File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
  File "C:\Python311\Lib\site-packages\typeguard\_importhook.py", line 98, in exec_module
    super().exec_module(module)
  File "<frozen importlib._bootstrap_external>", line 936, in exec_module
  File "<frozen importlib._bootstrap_external>", line 1074, in get_code
  File "C:\Python311\Lib\site-packages\typeguard\_importhook.py", line 75, in source_to_code
    tree = TypeguardTransformer().visit(tree)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python311\Lib\ast.py", line 418, in visit
    return visitor(node)
           ^^^^^^^^^^^^^
  File "C:\Python311\Lib\site-packages\typeguard\_transformer.py", line 612, in visit_Module
    self.generic_visit(node)
  File "C:\Python311\Lib\site-packages\typeguard\_transformer.py", line 508, in generic_visit
    node = super().generic_visit(node)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python311\Lib\ast.py", line 494, in generic_visit
    value = self.visit(value)
            ^^^^^^^^^^^^^^^^^
  File "C:\Python311\Lib\ast.py", line 418, in visit
    return visitor(node)
           ^^^^^^^^^^^^^
  File "C:\Python311\Lib\site-packages\typeguard\_transformer.py", line 657, in visit_ClassDef
    self.generic_visit(node)
  File "C:\Python311\Lib\site-packages\typeguard\_transformer.py", line 508, in generic_visit
    node = super().generic_visit(node)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python311\Lib\ast.py", line 494, in generic_visit
    value = self.visit(value)
            ^^^^^^^^^^^^^^^^^
  File "C:\Python311\Lib\ast.py", line 418, in visit
    return visitor(node)
           ^^^^^^^^^^^^^
  File "C:\Python311\Lib\site-packages\typeguard\_transformer.py", line 923, in visit_AsyncFunctionDef
    return self.visit_FunctionDef(node)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python311\Lib\site-packages\typeguard\_transformer.py", line 735, in visit_FunctionDef
    annotation = self._convert_annotation(deepcopy(arg.annotation))
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python311\Lib\site-packages\typeguard\_transformer.py", line 596, in _convert_annotation
    new_annotation = cast(expr, AnnotationTransformer(self).visit(annotation))
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python311\Lib\site-packages\typeguard\_transformer.py", line 353, in visit
    new_node = super().visit(node)
               ^^^^^^^^^^^^^^^^^^^
  File "C:\Python311\Lib\ast.py", line 418, in visit
    return visitor(node)
           ^^^^^^^^^^^^^
  File "C:\Python311\Lib\site-packages\typeguard\_transformer.py", line 380, in visit_BinOp
    if self._memo.name_matches(node.left, *anytype_names):
                               ^^^^^^^^^
AttributeError: 'BinOp' object has no attribute 'left'

How can we reproduce the bug?

test.py:

from importlib import import_module
from typeguard import install_import_hook
with install_import_hook(('anyio',)):
    import_module('anyio')
$ pip install anyio
$ python3 test.py
agronholm commented 1 year ago

I'm hoping this can be narrowed down to a specific annotation.

jolaf commented 1 year ago

It's not annotation, it crashes at from ._core._fileio import AsyncFile, Path, open_file, wrap_file

agronholm commented 1 year ago

Then it's some annotation in the anyio._core._fileio module that's causing this.

jolaf commented 1 year ago

Added a different crash on the same test on latest Python on Windows.

jolaf commented 1 year ago

I'm not sure I now have the time to dig in other people's code.

agronholm commented 1 year ago

The second one was fixed in 041b0e3f.

agronholm commented 1 year ago

If I install typeguard from master, I don't see this crash, at least against the latest AnyIO.

jolaf commented 1 year ago

I've just tried with the current master, the first crash is still there.

Can it be a version of Python is important?

agronholm commented 1 year ago

I tried with 3.10.12, and didn't experience the crash.

agronholm commented 1 year ago

Maybe you could try to nuke your __pycache__ and try again?

jolaf commented 1 year ago

I'm definitely running on master, latest commit is 6e96b75.

jolaf commented 1 year ago

I run straight from src directory in my working copy.

agronholm commented 1 year ago

Ok, so if you create a new virtualenv and install both packages, and run your test script (named test.py here):

python3.10 -m venv venv
venv/bin/pip install anyio git+https://github.com/agronholm/typeguard.git
venv/bin/python test.py

What happens? I get no errors.

jolaf commented 1 year ago

Oh, it turned out I didn't have the latest anyio. On latest one there's no crash indeed. For me, crash happens on anyio==3.6.2.

agronholm commented 1 year ago

Yes, I can reproduce it too on 3.6.2. I will investigate this. But to fix your immediate problem, can you upgrade? The problem doesn't occur on 3.7.1 either.

jolaf commented 1 year ago

Thank you very much!

Yes, upgrading helps.

agronholm commented 1 year ago

Found the offending annotation: Union[Iterable[ReadableBuffer], Iterable[str]]. The first union element does it, and it has to be in a union to trigger the problem.

agronholm commented 1 year ago

I have a failing unit test for this now.

jolaf commented 1 year ago

Thanks!