#python #enums #pycharm #python-typing #python-dataclasses
#python #перечисления #pycharm #python-типизация #python-классы данных
Вопрос:
Я создаю класс данных в 3.8.8 для хранения результата от вызова REST API, и один из его атрибутов используется для хранения статуса HTTP-ответа:
from dataclasses import dataclass
from http import HTTPStatus
@dataclass
class APICallResult:
response_text: str
http_status: HTTPStatus
Когда я пытаюсь создать объект этого класса, как показано ниже:
result = APICallResult('foo', HTTPStatus.OK)
PyCharm 2020.3.3 просто выдает HTTPStatus.OK
ошибку:
Expected type 'HTTPStatus', got 'int' instead`.
Теперь мне интересно, для чего IntEnum
в этом случае нужна подсказка правильного типа? Я думаю Literal
, что здесь может быть неудобный вариант.
Комментарии:
1. Это кажется мне ошибкой в реализации анализа Pycharm (есть пара). Я бы ожидал, что то, что у вас уже есть, должно быть правильным.
2. @Carcigenicate Ах, я об этом не думал. Я попробовал использовать mypy, он не обнаружил никаких проблем с моим кодом.
Ответ №1:
HTTPStatus.OK
является членом HTTPStatus
подкласса IntEnum:
Подкласс enum.IntEnum, который определяет набор кодов состояния HTTP, фраз причины и длинных описаний, написанных на английском языке.
Ошибка, которую вы получаете, — это ошибка в PyCharm static type checker, если вы напишете подсказку типа атрибута, как в примере ниже, и протестируете ее с помощью mypy, вы увидите, что ошибки нет:
from dataclasses import dataclass
from http import HTTPStatus
from typing import Literal
@dataclass
class APICallResult:
response_text: str
http_status: Literal[HTTPStatus.OK]
result = APICallResult('foo', HTTPStatus.OK)
mypy выдает никаких предупреждений
Success: no issues found in 1 source file
Если вы попытаетесь аннотировать атрибут dataclass следующим образом:
from dataclasses import dataclass
from http import HTTPStatus
@dataclass
class APICallResult:
response_text: str
http_status: HTTPStatus.OK
result = APICallResult('foo', HTTPStatus.OK)
mypy выдает следующее предупреждение:
main.py:9: error: Invalid type: try using Literal[HTTPStatus.OK] instead? Found 1 error in 1 file (checked 1 source file)
Правила для аннотирования элемента Enum приведены в PEP 586 — Литеральные типы:
Допустимые параметры для литерала во время проверки типа
Литерал [Color.RED] # Предполагая, что Color — это некоторое перечисление
Комментарии:
1. Спасибо за подробный ответ! В моем эксперименте с mypy
http_status: HTTPStatus
работает для меня. Я неохотно используюLiteral
здесь, потому что API может возвращать другие коды состояния, отличныеHTTPStatus.OK
от .2. @JerryWang Я написал этот пост в спешке, я перепишу позже сегодня.