«Отсутствует оператор возврата» в простой условной структуре - PullRequest
0 голосов
/ 05 марта 2020

Тип возврата функции ниже зависит от аргумента, переданного path: если это None, функция возвращает строку, если это строка, функция возвращает None, и во всех других возможных случаях , функция не возвращается вообще. Тем не менее, mypy сообщает

ошибка: отсутствует оператор возврата

Чего мне здесь не хватает?

import json
from typing import Optional

def to_json(data: dict, path: Optional[str] = None) -> Optional[str]:
    if path is None:
        return json.dumps(data)
    elif isinstance(path, str):
        with open(path, 'w') as file:
            json.dump(data, file)
    else:
        raise TypeError('Unsupported type for ``path``.')

Ответы [ 4 ]

2 голосов
/ 05 марта 2020

mypy предупреждает об отсутствующих типах возврата по умолчанию, поэтому вы можете явно отключить его:

$ mypy --no-warn-no-return spam.py

или отключить конкретную проверку только для конкретной строки:

def to_json(data: Dict, path: Optional[str] = None) -> Optional[str]:  # type: ignore[return]
    ...

Однако ваша функция имеет разные типы возврата в зависимости от входа. Я бы добавил перегруженную подпись для обработки:

from typing import Dict, Optional, overload

# when path is provided, the function returns
@overload
def to_json(data: Dict, path: str) -> str: ...

# when path is not provided, the function returns None
@overload
def to_json(data: Dict) -> None: ...

# your actual impl
def to_json(data, path=None):
    if path is None:
        ...
1 голос
/ 05 марта 2020

неявное возвращение чего-либо из всех веток приводит к сбою анализа stati c: это рассматривается как упущение (и считается плохой практикой).

Просто сделайте return None явным в else часть (не нужно, где вы используете исключение)

elif isinstance(path, str):
    with open(path, 'w') as file:
        json.dump(data, file)
    return None
1 голос
/ 05 марта 2020

Перво-наперво, ваш код действителен python. Я полагаю, что mypy, похоже, настроен в соответствии с PEP8 рекомендациями для возвратов, но более строг в этом отношении, поскольку он должен обеспечивать проверку типов. Соответствующий раздел:

Будьте последовательны в выражениях возврата. Либо все операторы возврата в функции должны возвращать выражение, либо ни один из них не должен. Если какой-либо оператор return возвращает выражение, любые операторы return, для которых не возвращено значение, должны явно указать это как return None, и в конце функции должен присутствовать явный оператор return (если он достижим).

Да:

def foo(x):
    if x >= 0:
        return math.sqrt(x)
    else:
        return None

Нет:

def foo(x):
    if x >= 0:
        return math.sqrt(x)

Так что, для своего кода, просто укажите явно return None во всех ветвях, где вы больше ничего не возвращаете .

0 голосов
/ 05 марта 2020

Просто добавьте return None к коду или return -1 или любой другой вид возврата в конце кода.

...