Skip to content

Cyclic dependency when finding subclasses across modules #281

@kdkavanagh

Description

@kdkavanagh

Say I have a base class in one file, and a specialization in another

# base.py
@dataclass
class MyBase():
      class Config(BaseConfig):
        discriminator = Discriminator(
            field="config_type",
            include_subtypes=True,
        )

# sub.py
@dataclass
class SubType(MyBase):
  config_type = "SubType"

In order for mashumaro to discover that SubType is a possible subclass to deserialize to, it must have first imported sub.py. But of course sub.py depends on base.py to pick up the base class definition. This creates a cyclic dependency which I've only been able to solve thusfar by first explicitly importing MyBase and SubType in the __init__.py before doing anything with mashumaro (w/ lazy_compilation) set to true.

A more ergonomic solution would be to define a function (subclass of Discriminator, maybe?) where I can explicitly enumerate all possible subtypes I want to support:

# base.py
@dataclass
class MyBase():
      class Config(BaseConfig):
        discriminator = Discriminator(
            field="config_type",
            include_subtypes=True,
        )
        def get_subtypes() -> Iterable[type]:
           from sub import SubType
           yield SubType


It might be tempting to just include a subtype_list: list[type] attr on Discriminator, but I dont think that'd solve the cyclic import challenge unless used with field(default_factory: get_subtypes), so really would just be an indirection

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions