1

I have 3 classes:

@dataclass(frozen=True)
class Parent:
    field_a: int

@dataclass(frozen=True)
class Child(Parent):
    field_b: int

class Wrapper(NamedTuple):
    object_a: Dict[int, Parent]
    object_b: Dict[int, Parent]

According to this stackoverflow question, it looks like I should be able to replace instances of Parent with Child in Wrapper. However, when I'm writing a function like this:

def get_wrapper()->Wrapper:
    return Wrapper(object_a={1: Child(1,2)}, object_b={2: Child(2,3)})

pyre gives me something like "Expected Dict[int, Parent] for 1st parameter object_a to call Wrapper.__init__ but got Dict[int, Child]."

Could anyone explain why using a subclass doesn't work in this case, and how I can get around this?

EDIT: I seem to have oversimplified the problem in the example I gave. My get_wrapper function was actually doing something like this:

def get_child()->Child:
    return Child(1,2)
def get_wrapper()->Wrapper:
    child_a = get_child()
    child_b = get_child()
    return Wrapper(object_a={1: child_a}, object_b={2: child_b})

I fixed the type errors by changing the return type of get_child to be Parent.

clamchow
  • 31
  • 4

1 Answers1

0

While your question seems fragmented across multiple edits, this is what I ran against mypy 0.920 and pyre 0.9.8. None of the type checkers raised any error.

from dataclasses import dataclass
from typing import Dict, NamedTuple


@dataclass(frozen=True)
class Parent:
    field_a: int


@dataclass(frozen=True)
class Child(Parent):
    field_b: int


class Wrapper(NamedTuple):
    object_a: Dict[int, Parent]
    object_b: Dict[int, Parent]


def get_child() -> Child:
    return Child(1, 2)


def get_wrapper() -> Wrapper:
    child_a = get_child()
    child_b = get_child()
    return Wrapper(object_a={1: child_a}, object_b={2: child_b})


if __name__ == "__main__":
    get_wrapper()
Redowan Delowar
  • 1,580
  • 1
  • 14
  • 36