Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot determine type of function with too many redefinitions #9721

Open
DiegoBaldassarMilleuno opened this issue Jan 17, 2025 · 1 comment
Labels
addressed in next version Issue is fixed and will appear in next published version bug Something isn't working

Comments

@DiegoBaldassarMilleuno
Copy link

Describe the bug
If a function is (re)defined 17 or more times through a decorator and is invoked between the first and the last definition, pyright reports Type of "f" could not be determined because it refers to itself

Code or Screenshots

The following is a minimized version of a (believe it or not) real-world case, from a Jupyter notebook.
Note that reportRedeclaration is disabled globally, otherwise all definitions save for the last one would report an error.

Code spoiler
# pyright: reportRedeclaration=none
# mypy: disable-error-code="no-redef"

from collections.abc import Callable

def decorator(func: Callable[[], None]) -> Callable[[], None]:
    return func

@decorator
def f() -> None: return None  # 1

@decorator
def f() -> None: return None  # 2

@decorator
def f() -> None: return None  # 3

@decorator
def f() -> None: return None  # 4

@decorator
def f() -> None: return None  # 5

@decorator
def f() -> None: return None  # 6

@decorator
def f() -> None: return None  # 7

@decorator
def f() -> None: return None  # 8

f()  # Type of "f" could not be determined because it refers to itself [reportGeneralTypeIssues]

@decorator
def f() -> None: return None  # 9

@decorator
def f() -> None: return None  # 10

@decorator
def f() -> None: return None  # 11

@decorator
def f() -> None: return None  # 12

@decorator
def f() -> None: return None  # 13

@decorator
def f() -> None: return None  # 14

@decorator
def f() -> None: return None  # 15

@decorator
def f() -> None: return None  # 16

@decorator
def f() -> None: return None  # 17

A few notes:

  • The error occurs as long as the call to f is anywhere after the first definition and before the last one; calling f after the last definition is ok
  • Removing the last decorator makes the error disappear; removing any other is inconsequential.
  • Adding f: Callable[[], None] before the first definition is also inconsequential.
  • Could not replicate the same behavior in mypy, even with many more redefinitions
  • This seems to be introduced in version 1.1.386

I suppose this is simply encountering some internal limits of pyright, but I thought it'd be better to let you know just in case, because this behavior seems slightly weird.

VS Code extension or command-line
Python version: 3.13.1
Pyright version: from 1.1.386 to 1.1.392; 1.1.385 reports no errors

@DiegoBaldassarMilleuno DiegoBaldassarMilleuno added the bug Something isn't working label Jan 17, 2025
erictraut added a commit that referenced this issue Jan 17, 2025
…on" error under certain circumstances when the number of declarations for a symbol exceeds the internal threshold of 16. This addresses #9721.
erictraut added a commit that referenced this issue Jan 17, 2025
…on" error under certain circumstances when the number of declarations for a symbol exceeds the internal threshold of 16. This addresses #9721. (#9722)
@erictraut
Copy link
Collaborator

Thanks for the bug report — including the clear repro steps and version analysis.

This is caused by a performance optimization I added in 1.1.386. When pyright encounters a symbol with more than 16 type declarations (as in your example), it falls back on a cheaper but less-robust mechanism for evaluating its type. Prior to this optimization, there were cases that resulted in pathological slow-downs and hangs.

An unanticipated side effect of the less-robust mechanism is that it can result in false positive detection of recursive type definitions under a rare set of circumstances, which explains the error you're seeing here.

To address the bug, I considered simply increasing the threshold from 16 to 32, but this isn't very satisfying because it would simply move the point where the bug occurs. I decided instead to suppress any recursive type definition errors in this case. This will be included in the next release.

@erictraut erictraut added the addressed in next version Issue is fixed and will appear in next published version label Jan 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addressed in next version Issue is fixed and will appear in next published version bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants