OiO.lk Blog python Generic TypeVar solution for class that produces another class that contains the original class
python

Generic TypeVar solution for class that produces another class that contains the original class


I’m trying to come up with a generic TypeVar solution to avoid having to create an ever expanding Uniontype annotation. Here’s a somewhat contrived MRE of what I have currently:

from __future__ import annotations

from typing import Union


class CreatedDetails:

    def __init__(self, creator: Union[Creator1, Creator2], new: bool) -> None:
        self.creator = creator
        self.new = new


class Creator1:

    def __init__(self) -> None:
        self.name = "creator1"

    def create(self) -> CreatedDetails:
        return CreatedDetails(creator=self, new=True)


class Creator2:

    def __init__(self) -> None:
        self.name = "creator2"

    def create(self) -> CreatedDetails:
        return CreatedDetails(creator=self, new=False)


creator1 = Creator1()

created = creator1.create()

created.creator.name

This plays nice and my type checker recognises everything:

However, this relies on me adding new Creator classes to the Ùnion type annotation.

I’ve tried using a generic TypeVar:

from __future__ import annotations

from typing import TypeVar

CreatorRecord = TypeVar("CreatorRecord")


class CreatedDetails:

    def __init__(self, creator: CreatorRecord, new: bool) -> None:
        self.creator = creator
        self.new = new


class Creator:
    pass


class Creator1(Creator):

    def __init__(self) -> None:
        self.foo = "foo"

    def create(self) -> CreatedDetails:
        return CreatedDetails(creator=self, new=True)


class Creator2(Creator):

    def __init__(self) -> None:
        self.bar = "bar"

    def create(self) -> CreatedDetails:
        return CreatedDetails(creator=self, new=False)


creator1 = Creator1()

created = creator1.create()

created.creator.foo
created.new

However, the type checker doesn’t fully recognise this:

Where am I going wrong?



You need to sign in to view this answers

Exit mobile version