python / python/mypy

Using `Never` as return type for `__new__` results in classmethods not being recognised. Inferred type for class is `Callable[[], NoReturn]`.

Open
#16,981 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Python
Stars
20.6k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

Bug Report

If the classmethod __new__ of a class is marked as returning Never, Mypy does not recognise the existence of attributes for the class (whose type it believes to be Callable[[], NoReturn]).

To Reproduce

from typing import Never, Self

class A:
    x: int

    @classmethod
    def _new(cls, x: int) -> Self:
        instance = super().__new__(cls)
        instance.x = x
        return instance

    def __new__(cls) -> Never:
        raise TypeError("Class 'A' should not be instanced directly.")

a = A._new(10) # Mypy Error: attr-defined
# "Callable[[], NoReturn]" has no attribute "_new"

Gist URL: https://gist.github.com/mypy-play/b40fec12cb83d7683c6832320aecc4d8
Playground URL: https://mypy-play.net/?mypy=latest&python=3.12&gist=b40fec12cb83d7683c6832320aecc4d8

from typing import ClassVar, Never

class A:
    attr: ClassVar[int] = 20

    def __new__(cls) -> Never:
        raise TypeError("Class 'A' should not be instanced directly.")

a = A.attr # Mypy Error: attr-defined
# "Callable[[], NoReturn]" has no attribute "attr"

Gist URL: https://gist.github.com/mypy-play/46b45241159045b55d7dfd9d871280f1
Playground URL: https://mypy-play.net/?mypy=latest&python=3.12&gist=46b45241159045b55d7dfd9d871280f1

Expected Behavior

I expect Mypy to recognise that the classmethod A._new() can be called to produce an instance of A, or that A has a class attribute attr.

Actual Behavior

Mypy does not recognise that classmethod A._new() exists, nor that the class attribute A.attr exists.

Your Environment

  • Mypy version used: 1.7.1 (checked with 1.8.0 on playground)
  • Mypy command-line flags: --strict
  • Python version used: 3.12

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce both examples from the issue with mypy 1.8.0 or later, using --strict and Python 3.12, and compare them with the linked playgrounds. Trace the handling of a class whose new returns Never; done means A._new() and A.attr are recognized without attr-defined errors.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.