pyjedy
pyjedy

Reputation: 774

How to solve mypy error for @property with pydantic @computed_field?

I need to decorate @property with the @computed_field from pydantic (to automatically generate key-value pairs and include them in a FastAPI JSON Response). In the following example, mypy displays an error. If there is an error, how can I fix it? If everything is correct, how do I disable this mypy message?

from pydantic import BaseModel, computed_field

class MyClass(BaseModel):

    value1: str
    value2: str

    @computed_field
    @property
    def joined_values(self) -> str:
        return self.value1 + self.value2


obj = MyClass(value1="1", value2="2")
print(f"{obj.joined_values=}")  # obj.joined_values='12'

mypy error:

$ mypy . 
stackperflow_pydantic_property.py:25: error: Decorators on top of @property are not supported  [misc]
Found 1 error in 1 file (checked 2 source files)

versions:

$ python -V
Python 3.10.11

$ pip list
mypy                  1.7.1
pydantic              2.5.2

Upvotes: 3

Views: 1709

Answers (3)

Scott Gigante
Scott Gigante

Reputation: 1644

I solved this by implementing my own computed_field decorator wrapper:

from typing import Any, Callable, TypeVar

from pydantic import computed_field as _base_computed_field

SelfT = TypeVar("SelfT", bound=object)


def computed_field(func: Callable[[SelfT], Any], **kwargs: Any) -> property:
    return _base_computed_field(property(func), **kwargs)

which can be used as

from pydantic import BaseModel

class MyClass(BaseModel):

    value1: str
    value2: str

    @computed_field
    def joined_values(self) -> str:
        return self.value1 + self.value2

and yields no mypy errors.

Upvotes: 0

pmav99
pmav99

Reputation: 2057

Since https://github.com/python/mypy/issues/14461 got merged, it seems that the proper way to handle this on mypy is to add # type: ignore[prop-decorator] comment:

from pydantic import BaseModel, computed_field

class MyClass(BaseModel):

    value1: str
    value2: str

    @computed_field  # type: ignore[prop-decorator]
    @property
    def joined_values(self) -> str:
        return self.value1 + self.value2


obj = MyClass(value1="1", value2="2")
print(f"{obj.joined_values=}")  # obj.joined_values='12'

Upvotes: 0

M.O.
M.O.

Reputation: 3011

This is currently not supported by mypy, see the warning in the documentation.

Upvotes: 3

Related Questions