How to impose typing.Union on one of its subtypes in Python?

Im using Python 3.6.1, mypy and input module. I created two custom types Fooand Barthen used them in the dict that I am returning from the function. A tiger is described as a mapping strin Unionfrom Fooand Bar. Then I want to use the values ​​from this dict in a function that calls only one argument each:

from typing import Dict, Union, NewType

Foo = NewType("Foo", str)
Bar = NewType("Bar", int)

def get_data() -> Dict[str, Union[Foo, Bar]]:
    return {"foo": Foo("one"), "bar": Bar(2)}

def process(foo_value: Foo, bar_value: Bar) -> None:
    pass

d = get_data()

I tried using the as-is values:

process(d["foo"], d["bar"])
# typing-union.py:15: error: Argument 1 to "process" has incompatible type "Union[Foo, Bar]"; expected "Foo"
# typing-union.py:15: error: Argument 2 to "process" has incompatible type "Union[Foo, Bar]"; expected "Bar"

Or using types:

process(Foo(d["foo"]), Bar(d["bar"]))
# typing-union.py:20: error: Argument 1 to "Foo" has incompatible type "Union[Foo, Bar]"; expected "str"
# typing-union.py:20: error: Argument 1 to "Bar" has incompatible type "Union[Foo, Bar]"; expected "int"

How to make Unionone of your subtypes?

+4
source share
2 answers

You will need to use cast():

process(cast(Foo, d["foo"]), cast(Bar, d["bar"]))

Casts PEP 484:

: , , .

, . , named tuple, :

from typing import Dict, Union, NewType, NamedTuple

Foo = NewType("Foo", str)
Bar = NewType("Bar", int)

class FooBarData(NamedTuple):
    foo: Foo
    bar: Bar

def get_data() -> FooBarData:
    return FooBarData(foo=Foo("one"), bar=Bar(2))

hinter , :

d = get_data()
process(d.foo, d.bar)
+3

, , , , , , :

dict, TypedDict, mypy ( github repo) , , pypi.

TypedDict, mypy_extensions pypi, pip install mypy_extensions.

TypedDict dict:

from mypy_extensions import TypedDict

Foo = NewType("Foo", str)
Bar = NewType("Bar", int)

FooBarData = TypedDict('FooBarData', {
    'foo': Foo,
    'bar': Bar,
})

FooBarData, Python 3.6 +:

from mypy_extensions import TypedDict

Foo = NewType("Foo", str)
Bar = NewType("Bar", int)

class FooBarData(TypedDict):
    foo: Foo
    bar: Bar

, dict . , TypedDict , NamedTuple , TypedDict , , TypedDicts TypeDicts,

+1

Source: https://habr.com/ru/post/1680031/


All Articles