Skip to content

[1.18 regression] RecursionError crash when checking code that imports htpy library #19836

@correctmost

Description

@correctmost

Crash Report

After upgrading from 1.17.1 to 1.18.1, I started seeing crashes when checking code that imports htpy.

The crash is already fixed on master, so I'm not sure if it will also be fixed for 1.18.x.

I bisected between v1.17.1 and v1.18.1:

The crash was fixed on master by ccd290c.

Traceback

When I use mypy from PyPI, I get a crash in Python:

Segmentation fault         (core dumped) mypy test.py

When I use a local installation, I get a RecursionError crash:

mypy-repro/.venv/lib/python3.13/site-packages/htpy/_types.py: error: INTERNAL ERROR -- Please try using mypy master on GitHub:
https://mypy.readthedocs.io/en/stable/common_issues.html#using-a-development-mypy-build
Please report a bug at https://github.com/python/mypy/issues
version: 1.18.1
Traceback (most recent call last):
  File "mypy-repro/.venv/bin/mypy", line 7, in <module>
    sys.exit(console_entry())
  File "mypy-repro/mypy/mypy/__main__.py", line 15, in console_entry
    main()
  File "mypy-repro/mypy/mypy/main.py", line 127, in main
    res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
  File "mypy-repro/mypy/mypy/main.py", line 211, in run_build
    res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
  File "mypy-repro/mypy/mypy/build.py", line 194, in build
    result = _build(
  File "mypy-repro/mypy/mypy/build.py", line 270, in _build
    graph = dispatch(sources, manager, stdout)
  File "mypy-repro/mypy/mypy/build.py", line 2976, in dispatch
    process_graph(graph, manager)
  File "mypy-repro/mypy/mypy/build.py", line 3397, in process_graph
    process_stale_scc(graph, scc, manager)
  File "mypy-repro/mypy/mypy/build.py", line 3502, in process_stale_scc
    graph[id].finish_passes()
  File "mypy-repro/mypy/mypy/build.py", line 2402, in finish_passes
    with self.wrap_context():
  File "/usr/lib/python3.13/contextlib.py", line 162, in __exit__
    self.gen.throw(value)
  File "mypy-repro/mypy/mypy/build.py", line 2087, in wrap_context
    yield
  File "mypy-repro/mypy/mypy/build.py", line 2424, in finish_passes
    self._patch_indirect_dependencies(self.type_checker().module_refs, all_types)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "mypy-repro/mypy/mypy/build.py", line 2457, in _patch_indirect_dependencies
    encountered = self.manager.indirection_detector.find_modules(types) | module_refs
                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^
  File "mypy-repro/mypy/mypy/indirection.py", line 36, in find_modules
    self._visit(typ)
    ~~~~~~~~~~~^^^^^
  File "mypy-repro/mypy/mypy/indirection.py", line 44, in _visit
    typ.accept(self)
    ~~~~~~~~~~^^^^^^
  File "mypy-repro/mypy/mypy/types.py", line 1657, in accept
    return visitor.visit_instance(self)
           ~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "mypy-repro/mypy/mypy/indirection.py", line 108, in visit_instance
    self._visit_type_tuple(t.args)
    ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
  File "mypy-repro/mypy/mypy/indirection.py", line 54, in _visit_type_tuple
    typ.accept(self)
    ~~~~~~~~~~^^^^^^
  File "mypy-repro/mypy/mypy/types.py", line 1657, in accept
    return visitor.visit_instance(self)
           ~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "mypy-repro/mypy/mypy/indirection.py", line 108, in visit_instance
    self._visit_type_tuple(t.args)
    ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
  File "mypy-repro/mypy/mypy/indirection.py", line 54, in _visit_type_tuple
    typ.accept(self)
    ~~~~~~~~~~^^^^^^
  File "mypy-repro/mypy/mypy/types.py", line 429, in accept
    return visitor.visit_type_alias_type(self)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "mypy-repro/mypy/mypy/indirection.py", line 152, in visit_type_alias_type
    self._visit(types.get_proper_type(t))
    ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^

  [...snip...]

  File "mypy-repro/mypy/mypy/indirection.py", line 44, in _visit
    typ.accept(self)
    ~~~~~~~~~~^^^^^^
  File "mypy-repro/mypy/mypy/types.py", line 3288, in accept
    return visitor.visit_union_type(self)
           ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "mypy-repro/mypy/mypy/indirection.py", line 143, in visit_union_type
    self._visit_type_list(t.items)
    ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
  File "mypy-repro/mypy/mypy/indirection.py", line 64, in _visit_type_list
    typ.accept(self)
    ~~~~~~~~~~^^^^^^
  File "mypy-repro/mypy/mypy/types.py", line 2239, in accept
    return visitor.visit_callable_type(self)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "mypy-repro/mypy/mypy/indirection.py", line 120, in visit_callable_type
    self._visit(t.ret_type)
    ~~~~~~~~~~~^^^^^^^^^^^^
  File "mypy-repro/mypy/mypy/indirection.py", line 44, in _visit
    typ.accept(self)
    ~~~~~~~~~~^^^^^^
  File "mypy-repro/mypy/mypy/types.py", line 429, in accept
    return visitor.visit_type_alias_type(self)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "mypy-repro/mypy/mypy/indirection.py", line 152, in visit_type_alias_type
    self._visit(types.get_proper_type(t))
                ~~~~~~~~~~~~~~~~~~~~~^^^
  File "mypy-repro/mypy/mypy/types.py", line 3531, in get_proper_type
    typ = typ._expand_once()
  File "mypy-repro/mypy/mypy/types.py", line 370, in _expand_once
    return self.alias.target.accept(InstantiateAliasVisitor(mapping))
           ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "mypy-repro/mypy/mypy/types.py", line 3288, in accept
    return visitor.visit_union_type(self)
           ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "mypy-repro/mypy/mypy/types.py", line 4263, in visit_union_type
    return TypeTranslator.visit_union_type(self, t)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
  File "mypy-repro/mypy/mypy/type_visitor.py", line 302, in visit_union_type
    self.translate_type_list(t.items),
    ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
  File "mypy-repro/mypy/mypy/type_visitor.py", line 312, in translate_type_list
    return [t.accept(self) for t in types]
            ~~~~~~~~^^^^^^
  File "mypy-repro/mypy/mypy/types.py", line 1657, in accept
    return visitor.visit_instance(self)
           ~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "mypy-repro/mypy/mypy/expandtype.py", line 215, in visit_instance
    args = self.expand_type_tuple_with_unpack(t.args)
  File "mypy-repro/mypy/mypy/expandtype.py", line 457, in expand_type_tuple_with_unpack
    items.append(item.accept(self))
                 ~~~~~~~~~~~^^^^^^
  File "mypy-repro/mypy/mypy/types.py", line 429, in accept
    return visitor.visit_type_alias_type(self)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
RecursionError: maximum recursion depth exceeded
mypy-repro/.venv/lib/python3.13/site-packages/htpy/_types.py: : note: use --pdb to drop into pdb

To Reproduce

# pip install htpy==25.8.1

import htpy

Your Environment

  • Mypy version used: 1.18.1
  • Mypy command-line flags: N/A
  • Mypy configuration options from mypy.ini (and other config files): N/A
  • Python version used: 3.13.7
  • Operating system and version: Arch Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions