3

I want to dynamically create child classes at startup with the type() function. Everything works as expected. I know this isn't great, but I am bound to a framework and have to do it this way. The other option is to generate source code...

Functional equivalent to my code:

class BaseEntity:
    id: str


def make_new_entity(name: str, attrs: dict) -> type:
    return type('RuntimeEntity', (BaseEntity,), attrs)


RuntimeEntity: ??? = make_new_entity('RuntimeEntity', {'id': 'entity.RuntimeEntity'})

Is there a way to provide a bound to the returned type? Basically the equivalent of

E = TypeVar('E', bound='BaseEntity')

I have also looked at the types module.

Thanks for any help!

1 Answer 1

3

typing.Type lets you specify that the value should be an actual type, rather than an instance of that type.

from typing import Type

class BaseEntity:
    id: str


def make_new_entity(name: str, attrs: dict) -> Type[BaseEntity]:
    return type('RuntimeEntity', (BaseEntity,), attrs)


RuntimeEntity: Type[BaseEntity] = make_new_entity('RuntimeEntity', {'id':     'entity.RuntimeEntity'})

A value of type Type[BaseEntity] can be BaseEntity itself, or any class that inherits from BaseEntity. (The term to describe this is covariance. If Type were invariant, Type[BaseEntity] would accept BaseEntity itself only.)

Sign up to request clarification or add additional context in comments.

3 Comments

That's great, thank you! I tried that, but got confused as PyCharm says "Expected type 'Type[BaseEntity]', got 'type' instead". IntelliSense works on the instance though. Probably a bug or impossible to lint.
It's even worse in the dict I'm putting it in: "Expected type Dict[str, Type[BaseEntity]], got Dict[str, type]" instead
I don't get any error with mypy on the code shown.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.