python / python/mypy

Decorating `__init__()` with a class decorator is not supported

Open
#18,513 2 comments 1 reaction 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

I want to define a decorator as a class to decorate another class's methods. However, when __init__() constructor is decorated with that class, mypy reports Unsupported decorated constructor type error.

(For reference) Stackoverflow question I posted: https://stackoverflow.com/questions/79374167/mypy-unsupported-decorated-constructor-type-error-when-decorating-init-w

To Reproduce

from types import MethodType
from typing import TypeVar, Callable, Type, ParamSpec, Generic

T = TypeVar("T")
P = ParamSpec("P")
R = TypeVar("R")

class method_decorator(Generic[P, R]):
    def __init__(self, method: Callable[P, R]):
        self.method = method

    def __get__(self, instance: T | None, cls: Type[T]) -> Callable[..., R]:
        return self if instance is None else MethodType(self, instance)

    def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R:
        return self.method(*args, **kwargs)

class Foo:
    @method_decorator # error: Unsupported decorated constructor type  [misc]
    def __init__(self, x: int):
        self.x = x

    @method_decorator
    def mul(self, a: int) -> int:
        return self.x * a

def gen_foo(x: int) -> Foo:
    return Foo(x) # error: Returning Any from function declared to return "Foo"  [no-any-return]

foo = gen_foo(2)
print(foo.mul(3))

Actual Behavior

$ uv run mypy --strict test.py
test.py:19: error: Unsupported decorated constructor type  [misc]
test.py:28: error: Returning Any from function declared to return "Foo"  [no-any-return]
Found 2 errors in 1 file (checked 1 source file)

Your Environment

  • Mypy version used: 1.13.0
  • Mypy command-line flags: --strict
  • Mypy configuration options from mypy.ini (and other config files): default
  • Python version used: 3.11.9

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

Start with the provided reproducer and run uv run mypy --strict test.py using the shown Python 3.11 environment. Trace how mypy handles the decorated __init__() constructor and compare it with the decorated mul() method. Done means the constructor no longer reports Unsupported decorated constructor type and gen_foo no longer returns Any under strict checking.

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
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.