2017-02-20 21 views
0

Функция attrgetter может возвращать разные типы на основе аргументов, которые вы им даете. Если вы передадите итерабельность с одним элементом, он вернет просто поле данного объекта; если вы передадите его итерабельным с несколькими элементами, он вернет кортеж этих полей объекта.Подсказки типа MyPy/python не улавливают вызываемую функцию, которая может возвращать несколько типов.

Однако при использовании типа подсказки + MyPy, это несоответствие не подобран MyPy (он не бросает никакие ошибки):

from operator import attrgetter 


class OneThing: 
    foobar = "hello" 
    fields = ['foobar'] 


class TwoThings: 
    foobar = "hello" 
    goodbye = "potatoes" 
    fields = ['foobar', 'goodbye'] 


def attrgettertest(thing) -> tuple: 
    return attrgetter(*thing.fields)(thing) 


def main(): 
    onething = OneThing() 
    twothings = TwoThings() 

    t1 = attrgettertest(onething) 
    t2 = attrgettertest(twothings) 

    print("Attrgettertest on 'onething' returned {} with type {}".format(
     t1, type(t1))) 
    print("Attrgettertest on 'twothings' returned {} with type {}".format(
     t2, type(t2))) 


if __name__ == "__main__": 
    main() 

И выход:

$ python attrgettrtest.py 
Attrgettertest on 'onething' returned hello with type <class 'str'> 
Attrgettertest on 'twothings' returned ('hello', 'potatoes') with type <class 'tuple'> 
$ mypy attrgettrtest.py 
$ 

Ожидаемый результат будет что-то вроде этого:

import random  

def test() -> tuple: 
    if random.choice([0, 1]): 
     return ("foo", "bar") 
    return "foo" 

if __name__ == "__main__": 
    for n in range(20): 
     print(test()) 

$ mypy test.py 
test.py:8: error: Incompatible return value type (got "str", expected Tuple[Any, ...]) 

Это ошибка в MyPy?

ответ

0

Кажется, что проблема здесь в том, что attrgetter имеет тип возврата Any, а mypy этого не понимает.

Я отправил это в mypy репо и получил следующие answer:

Я думаю, что проблема в том, что attrgetter имеет тип возвращаемого Any, так что ваш код проходит. В принципе, точная проверка типов будет сложной в таких случаях, однако есть новый флаг --warn-return-any, который выдаст предупреждения в таких ситуациях (он будет доступен в 0,480, см. PR #2854).