lidatong / dataclasses-json

Easily serialize Data Classes to and from JSON
MIT License
1.36k stars 154 forks source link

mypy can't determine correct type of SchemaType.loads #322

Open kjamieson opened 2 years ago

kjamieson commented 2 years ago

The signatures of the two loads overloads in SchemaF make it impossible for mypy to correctly determine which overload to apply to a call to loads() because the many argument is optional for both.

For example, the following code example:

from dataclasses import dataclass
from dataclasses_json import DataClassJsonMixin

@dataclass
class MyData(DataClassJsonMixin):
    data: str

m = MyData.schema().loads('')
m.data

Produces a mypy error when type-checking:

dataclasses-typing-test-bug.py:9: "List[Any]" has no attribute "data"  [attr-defined]                                                                                         

This can potentially be fixed by changing the List-returning overload to make the many keyword argument a non-optional typing.Literal[True] to indicate to mypy that the overload returning a List only applies when many=True:

        @typing.overload  # type: ignore
        def loads(self, json_data: JsonData,  # type: ignore
                  *, many: typing.Literal[True], partial: bool = None, unknown: str = None,
                  **kwargs) -> typing.List[A]:
            # ignore the mypy error of the decorator because mm does not define bytes as correct input data
            # mm has the wrong return type annotation (dict) so we can ignore the mypy error
            # for the return type overlap
            pass

        @typing.overload
        def loads(self, json_data: JsonData,
                  *, many: typing.Literal[False] = None, partial: bool = None, unknown: str = None,
                  **kwargs) -> A:
            pass
GodVenn commented 7 months ago

+1

D-X-Y commented 1 month ago

+1