Python Typing: как заставить Type [C] работать с TypeVars и Generics? - PullRequest
0 голосов
/ 21 сентября 2018

Я пытаюсь выяснить, как заставить Python универсальную подсказку типов хорошо играть с аргументом конструктора Type [C].Рассмотрим следующий пример кода:

class Foo(object):
  fooval: str

  def __init__(self, val):
    self.fooval = val

class Bar(object):
  barval: str

  def __init__(self, val):
    self.barval = val

T = TypeVar('T', Foo, Bar)

class FooBarContainer(Generic[T]):
  child: T

  # Type[T] seems logical here, but that's not valid according to the docs
  def __init__(self, ctorable: Type[Union[Foo, Bar]], val):
    self.child = ctorable(val)

baz = FooBarContainer(Foo, val)
# This does not get flagged by type-checkers, but will obviously fail at runtime
failure = baz.child.barval

Попытка использовать тип [T] приводит к ошибке проверки типов:

Ожидаемый тип [T], получен тип [Foo]

Итак, цель здесь - выяснить, как заставить TypeVars работать с Type [C] от набора текста.Таким образом, статический анализ будет знать, что когда я вызываю конкретную функцию с определенным типом [T], я ожидаю получить T обратно.Кажется, я не могу найти никаких документов, которые бы мне здесь помогли.

Та же проблема возникает и при работе с функциями.Например, это допустимый синтаксис, но явно недопустимый с точки зрения ввода:

def initor(thing_type: Type[Union[Foo, Bar]], val) -> T:
  return thing_type(val)

1 Ответ

0 голосов
/ 22 сентября 2018

Можете ли вы уточнить, что вы подразумеваете под "Type [T] здесь кажется логичным, но это недопустимо в соответствии с документацией"?

В частности, на какие документы вы смотрите?Следующий код работает для меня, как и ожидалось, используя mypy 0.630:

class FooBarContainer(Generic[T]):
  child: T

  def __init__(self, ctorable: Type[T], val) -> None:
    self.child = ctorable(val)

val = 3
baz = FooBarContainer(Foo, val)

# Mypy reports a `"Foo" has no attribute "barval"` error
failure = baz.child.barval  

Если документы предполагают, что ctorable тип Type[T] не работает, их, вероятно, следует обновить.

...