Skip to content

feature request (/doc?): make use of providers from base class less confusing #367

@shaunc

Description

@shaunc

Version 1

Here is what I aspire to do:

class A(containers.DeclarativeContainer):
    a = providers.Dependency(str)
    c = providers.Dependency(str)

@containers.copy(A)
class B(A):
    b = providers.Callable(lambda a: f"b_{a}", A.a.provided)
    c = b.provided[0]

print(B(a="a").c())  # f? no: Dependency not defined

So base class A sets up some dependencies. Subclass B provides a provider that depends on one of them, and provides the other. Unfortunately that version doesn't work.

Version 2

Without the copy still doesn't work, though traceback looks different:

class A(containers.DeclarativeContainer):
    a = providers.Dependency(str)
    c = providers.Dependency(str)

# @containers.copy(A)
class B(A):
    b = providers.Callable(lambda a: f"b_{a}", A.a.provided)
    c = b.provided[0]

print(B(a="a").c())  # Dependency not defined

Version 3

If I copy a explicitly, but still leave off the copy, still doesn't work:

class A(containers.DeclarativeContainer):
    a = providers.Dependency(str)
    c = providers.Dependency(str)

# @containers.copy(A)
class B(A):
    a = providers.Dependency(str)
    b = providers.Callable(lambda a: f"b_{a}", a.provided)
    c = b.provided[0]

print(B(a="a").c())  # f? -- Dependency is not defined

Version 4

Finally, with copy of a and copy, will work:

class A(containers.DeclarativeContainer):
    a = providers.Dependency(str)
    c = providers.Dependency(str)

@containers.copy(A)
class B(A):
    a = providers.Dependency(str)
    b = providers.Callable(lambda a: f"b_{a}", a.provided)
    c = b.provided[0]

print(B(a="a").c())  # f

However

However, it isn't ideal to have to explicitly copy parts of the base class in the derived class. For more complex examples I find I have to copy up whole subgraphs, which isn't DRY -- after all the point of factoring out some definitions into a mixin is so that you can use them as a single source of authority.

So the feature request is for the first version to work: if I write A.a in class B which derives from A, then a reference to A.a should be automatically put into B (unless it is explicitly declared). That way, if, e.g. I decide to change the name of a in the base class, I'll "fail fast" -- I won't be able to load the code.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions