Skip to content

Dynamic strategy for subclasses #434

@AdrianSosic

Description

@AdrianSosic
  • cattrs version: latest unreleased version (before 23.2)
  • Python version: 3.8.6
  • Operating System: macOS

Description

(copied from #312)

Hi guys 👋 It's great that the subclass feature is finally coming in the next release. I've been hoping for it for quite a while, it allows me to get rid of some manual workarounds 👍

I do have one question, though. I'm currently playing around with it and trying to incorporate it into our codebase. In most places, it worked out-of-the-box, but I encountered problems with one of my class hierarchies. When I looked a bit deeper, I suddenly understood what is the problem: the subclass tree is constructed during the call of include_subclasses and not at the time of structuring. This differs from my manual workaround, in which the lookup was done inside the hook itself. The logic was as roughly as follows:

def structure_base(val: dict, _) -> _T:
    _type = val["type"]
    cls = next((cl for cl in get_subclasses(base) if cl.__name__ == _type), None)
    if cls is None:
        raise ValueError(f"Unknown subclass {_type}.")
    return cattrs.structure_attrs_fromdict(val, cls)

where get_subclasses builds the subclass tree similar to your code.

The fact that the classes are collected in include_subclasses causes a problem to me in that no subclasses can be added later on. Do you see any solution to this problem?

I can imagine at least two use cases where a delayed lookup would be necessary:

  1. (My situation) You have a base class Base defined in base.py and would like to activate the subclass strategy for it (probably in that same file). However, several of its subclasses are defined in different files, e.g. subclass1.py, subclass2.py and so on. In this case, it's not obvious where you would even activate the strategy.
  2. (More generally) You do not own all the subclasses yourself, i.e. some user of your package extends the subclass tree by adding their own subclass implementations.

Maybe I'm even misusing the feature, but then I'd be also happy about getting your input :D

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions