-
-
Notifications
You must be signed in to change notification settings - Fork 337
Description
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.