Могу ли я иметь дополнительный параметр в классах данных, который опускается при преобразовании в dict? - PullRequest
0 голосов
/ 10 июля 2020

I wi sh для выполнения проверки типа stati c (pylance in vscode) в некоторых словарях. «Сложная» часть - это то, что я хочу, чтобы некоторые параметры были необязательными и вообще не отображались в словаре. Я пробовал использовать dataclasses и TypedDict, но пока безуспешно.

from typing import Optional, List
from dataclasses import dataclass, asdict


@dataclass
class SubOrder:
    name: str


@dataclass
class Order:
    name: str
    sub_orders: Optional[List[SubOrder]]


assert asdict(Order(name="Pizza")) == {"name": "Pizza"}
assert asdict(Order(name="Pizza", sub_orders=[SubOrder(name="Pasta")])) == {
    "name": "Pizza",
    "sub_orders": [{"name": "Pasta"}],
}

Это достижимо с dataclasses? Я просто хочу, чтобы мой stati c type checker (pylance / pyright) проверял мои словари, поэтому я использую dataclasses. Я тоже пробовал с TypedDict, но средства проверки типов, похоже, не ведут себя так, как я. Они всегда требуют, чтобы я установил sub_orders.

Следующий код проходит, но pylance недоволен отсутствием sub_orders.

from typing import Optional, List, TypedDict


class SubOrder(TypedDict):
    name: str


class Order(TypedDict):
    name: str
    sub_orders: Optional[List[SubOrder]]


assert Order(name="Pizza") == {"name": "Pizza"}
assert Order(name="Pizza", sub_orders=[SubOrder(name="Pasta")]) == {
    "name": "Pizza",
    "sub_orders": [{"name": "Pasta"}],
}

EDIT

Я добавил отчет об ошибке в pylance, так как это может быть ошибка в pylance / pyright

1 Ответ

0 голосов
/ 10 июля 2020
from dataclasses import asdict, dataclass
from typing import List, Optional

from validated_dc import ValidatedDC


@dataclass
class SubOrder(ValidatedDC):
    name: str


@dataclass
class Order(ValidatedDC):
    name: str
    sub_orders: Optional[List[SubOrder]] = None

    def as_dict(self):
        data = asdict(self)
        return {key: value for key, value in data.items() if value is not None}


data = {'name': 'pizza'}
order = Order(**data)
assert order.get_errors() is None
assert asdict(order) == {'name': 'pizza', 'sub_orders': None}
assert order.as_dict() == {'name': 'pizza'}

data = {'name': 'pizza', 'sub_orders': [{'name': 'pasta'}]}
order = Order(**data)
assert order.get_errors() is None
assert asdict(order) == {'name': 'pizza', 'sub_orders': [{'name': 'pasta'}]}
assert isinstance(order.sub_orders[0], SubOrder)

ПодтвержденоD C - https://github.com/EvgeniyBurdin/validated_dc

...