Skip to content

NoReturn on __new__ and __init__ disables accessing @classmethods and ClassVars directly from the class #14044

Open

Description

@bzoracler

Bug Report

Annotating __new__(...) -> typing.NoReturn or __init__(...) -> typing.NoReturn causes false positives when accessing @classmethods and typing.ClassVar-annotated attributes.

To Reproduce

from typing import NoReturn, Any, ClassVar

class A:
    attr: ClassVar[str] = ""
    def __init__(cls, *args: Any, **kwargs: Any) -> NoReturn:
        raise RuntimeError
    @classmethod
    def f(cls) -> None:
        pass

class B:
    attr: ClassVar[str] = ""
    @classmethod
    def f(cls) -> None:
        pass

Expected Behavior

No issues on any of the following:

A.f()
A.attr
B.f()
B.attr

Actual Behavior

A.f()  # mypy: "Callable[[VarArg(Any), KwArg(Any)], NoReturn]" has no attribute "f"  [attr-defined]
A.attr  # mypy: "Callable[[VarArg(Any), KwArg(Any)], NoReturn]" has no attribute "attr"  [attr-defined]
B.f()
B.attr

Your Environment

  • Mypy version used: 0.990 and master branch of https://mypy-play.net/
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files): None
  • Python version used: 3.10

Activity

  1. dmcooke commented on Nov 23, 2022

    @dmcooke

    Just hit this bug. It's not just @classmethod or ClassVar: it'll complain about class decorators, ordinary methods, and staticmethod's. Using reveal_type, it appears that mypy thinks that A is a function (a Callable[..., NoReturn]),
    and has lost all information about A being a class.

  2. fofoni commented on Nov 1, 2023

    @fofoni

    Just hit this too.

    Using reveal_type, it appears that mypy thinks that A is a function (a Callable[..., NoReturn]), and has lost all information about A being a class.

    Actually, this is apparently not related to this bug:

    class B:
        pass
    reveal_type(B)  # Revealed type is "def () -> __main__.B"

    Anyway, I can confirm that this bug still exists on mypy 1.6.1 and currently on mypy master branch, and occurs both on Python 3.11 and Python 3.12. I can also confirm that pyright doesn't have this bug (i.e. it allows __init__(self) -> NoReturn and then accessing classmethods).

  3. lkct commented on Dec 22, 2023

    @lkct

    Also hit this. I confirm this bug still persists in 1.7.1 and the master branch, on python versions 3.8 through 3.12.

    Is anyone looking into this issue? I find it useful sometimes to define a class that does not instantiate while keeping ClassVars and classmethods available.

  4. henzef commented on Mar 19, 2024

    @henzef

    This is most likely caused by #11216 / #10342 / #13480. Maybe @BvB93 has an idea how to fix it?

  5. BvB93 commented on Mar 20, 2024

    @BvB93
    Contributor

    I'm afraid not. My familiarity with mypy's internals is limited, even more so here as this concerns 2.5 year old PRs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions