Skip to content

Incremental parsing crash with inline dynamic enum.Enum construction #16163

Closed
@PeterJCLaw

Description

@PeterJCLaw

Crash Report

Given two files:

# the_class.py
import enum

class TheClass:
    def __init__(self) -> None:
        names = ['foo']

        # Note: the enum must be dynamic for the bug to reproduce. Replacing the
        # dict comprehension with a literal causes the issue to go away.
        pyenum = enum.Enum('Blah', {  # type: ignore[misc]
            x.upper(): x
            for x in names
        })

        # Note: the enum type must then be exposed somehow as a member of the
        # type. This doesn't need to be direct -- the original code was
        #
        #   self.enum_type = strawberry.enum(pyenum)
        #
        # however the enum type seems to need to be somewhere public.
        self.enum_type = pyenum
# usage.py
from .the_class import TheClass
print(TheClass)

arranged

$ tree
.
└── pkg
    ├── __init__.py   # empty
    ├── the_class.py
    └── usage.py

Traceback

Traceback (most recent call last):
  File "/home/peter/thread/styleme/venv/bin/mypy", line 8, in <module>
    sys.exit(console_entry())
             ^^^^^^^^^^^^^^^
  File "/home/peter/thread/styleme/venv/lib/python3.11/site-packages/mypy/__main__.py", line 15, in console_entry
    main()
  File "mypy/main.py", line 94, in main
  File "mypy/main.py", line 173, in run_build
  File "mypy/build.py", line 195, in build
  File "mypy/build.py", line 268, in _build
  File "mypy/build.py", line 2927, in dispatch
  File "mypy/build.py", line 3318, in process_graph
  File "mypy/build.py", line 3399, in process_fresh_modules
  File "mypy/build.py", line 2114, in fix_cross_refs
  File "mypy/fixup.py", line 52, in fixup_module
  File "mypy/fixup.py", line 135, in visit_symbol_table
  File "mypy/fixup.py", line 72, in visit_type_info
  File "mypy/fixup.py", line 137, in visit_symbol_table
  File "mypy/nodes.py", line 1038, in accept
  File "mypy/fixup.py", line 193, in visit_var
  File "mypy/types.py", line 1923, in accept
  File "mypy/fixup.py", line 247, in visit_callable_type
  File "mypy/types.py", line 1414, in accept
  File "mypy/fixup.py", line 212, in visit_instance
  File "mypy/fixup.py", line 349, in lookup_fully_qualified_typeinfo
  File "mypy/lookup.py", line 49, in lookup_fully_qualified
AssertionError: Cannot find component 'pyenum' for 'pkg.the_class.TheClass.pyenum'

To Reproduce

The typecheck passes, however subsequent typechecks where the usages of TheClass have changed will crash. Cases where mypy also re-parses the_class.py seem to work ok, presumably due to the types not being looked up in the cache.

rm -rf .mypy_cache/ && mypy . && echo "# change to force re-check" >> pkg/usage.py && mypy .

Your Environment

  • Mypy version used: mypy 1.5.1 (compiled: yes)
  • Mypy command-line flags: none
  • Mypy configuration options from mypy.ini (and other config files): none
  • Python version used: Python 3.11.5
  • Operating system and version: Ubuntu 22.04.3 LTS

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions