简体   繁体   中英

mypy: Incompatible return value type

So, I have one dataclass as follows

@dataclass
class DataObj:
    """ DataObj creates an object for each record in data
    """
    name: str
    profit: int
    space: float

I have another container class that holds the objects of above class

class DataContainer:
    """ Data Container class holding objects of DataObj class
    """
    def __init__(self, data_tuple_list: List[Tuple[str, int, float]]) -> None:
        self.container = []
        for data_tuple in data_tuple_list:
            self.container.append(DataObj(*data_tuple))

    def __getitem__(self, n: int) -> Type[DataObj]:
        return self.container.__getitem__(n)

However, when I check the code using mypy, I get following error

error: Incompatible return value type (got "DataObj", expected "Type[DataObj]")
Found 1 error in 1 file (checked 1 source file)

My python version is 3.8.10 .

Question: How to fix the error.

EDIT

  1. If I use self.container: List[DataObj] = [] , I get error: Incompatible return value type (got "DataObj", expected "Type[DataObj]") Found 1 error in 1 file (checked 1 source file)
  2. If I use self.container: List[Type[DataObj]] = [] , I get error: Argument 1 to "append" of "list" has incompatible type "DataObj"; expected "Type[DataObj]" Found 1 error in 1 file (checked 1 source file) error: Argument 1 to "append" of "list" has incompatible type "DataObj"; expected "Type[DataObj]" Found 1 error in 1 file (checked 1 source file) .

It's possible that you didn't type hint your container as well ( self.container ) so mypy looks at it as a List[Any] and probably can't see that it only contains values of type DataObj so when you return something from the list, mypy can't be sure that it's something of type DataObj

Try:


class DataContainer:
    """ Data Container class holding objects of DataObj class
    """
    def __init__(self, data_tuple_list: List[Tuple[str, int, float]]) -> None:
        self.container: List[DataObj] = [
            DataObj(*data_tuple)
            for data_tuple in data_tuple_list
        ]

    def __getitem__(self, n: int) -> Type[DataObj]:
        return self.container[n]

EDIT

This is what I've tried and it worked for me:

from dataclasses import dataclass
from typing import List, Tuple


@dataclass
class DataObj:
    """ DataObj creates an object for each record in data
    """
    name: str
    profit: int
    space: float


class DataContainer:
    """ Data Container class holding objects of DataObj class
    """

    def __init__(self, data_tuple_list: List[Tuple[str, int, float]]) -> None:
        self.container = [
            DataObj(*data_tuple)
            for data_tuple in data_tuple_list
        ]

    def __getitem__(self, n: int) -> DataObj:
        return self.container[n]

if __name__ == '__main__':
    data_tuple_list_concrete = [
        ('test1', 1, 1.1),
        ('test2', 2, 2.2),
        ('test3', 3, 3.3),
        ('test4', 4, 4.4),
        ('test5', 5, 5.5),
    ]

    dc = DataContainer(data_tuple_list_concrete)
    print(dc[0])
    print(dc[1])
    print(dc[2])
    print(dc[3])
    print(dc[4])

"""
Output:

DataObj(name='test1', profit=1, space=1.1)
DataObj(name='test2', profit=2, space=2.2)
DataObj(name='test3', profit=3, space=3.3)
DataObj(name='test4', profit=4, space=4.4)
DataObj(name='test5', profit=5, space=5.5)
"""
$ mypy main.py
Success: no issues found in 1 source file

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM