-
-
Notifications
You must be signed in to change notification settings - Fork 59
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
First of all, thanks for the package, been using it for 5 years already as it simplifies my code bases quite a bit.
🐛 Bug report
A custom class instantiator, added with parser.add_instantiator(...)
, does not run when the class objects are added via nested dependency injection. See the provided code and below explanations. I am using version 4.32.1
, but from the change logs it doesn't seem that this has been fixed.
Case 1 (instantiator runs)
The instantiator runs if we do not use nesting. For example see Case 1 in the below, which executes the custom instantiator correctly.
Case 2 (instantiator does not run)
In case 2, the objects of Dependency
class are provided via nested dependency injection. In this case, the custom instantiator is not run.
To reproduce
from typing import Iterable, Callable, Type, Any, Dict
import jsonargparse
from jsonargparse._util import ClassType
class Dependency():
def __init__(self, val: int, val2: float = 0.2):
self.val = val
self.val2 = val2
class Runner():
def __init__(self, dependency: Callable[[Iterable], Dependency]):
self.dependency = dependency(self)
class Wrapper():
def __init__(self, runner: Runner):
self.runner = runner
class CustomDependencyInstantiator():
"""
A custom instantiator to be used in jsonargparse.
Allows settings some default values based on the dynamically provided arguments.
"""
def __call__(self, class_type: Type[ClassType], *args, **scheduler_kwargs) -> ClassType:
runner = args[0]
# TODO: Do something with the scheduler_kwargs using the arguments
# This does not run when using dependency injection
print('Running instantiator')
return class_type(1, **scheduler_kwargs)
if __name__ == '__main__':
#
# Case 1: Using dependency injection without nesting, runs custom instantiator
#
config = {
"dependency": {
"val2": 0.3,
}
}
parser = jsonargparse.ArgumentParser()
parser.add_class_arguments(Runner)
parser.add_instantiator(CustomDependencyInstantiator(), Dependency, subclasses=True)
config = parser.parse_object(config)
config = parser.instantiate_classes(config)
wrapper = Runner(dependency=config.dependency)
#
# Case 2: Using dependency injection with nesting, does not run custom instantiator
#
config = {
"runner": {
"dependency": {
"val2": 0.3,
}
}
}
parser = jsonargparse.ArgumentParser()
parser.add_class_arguments(Wrapper)
parser.add_instantiator(CustomDependencyInstantiator(), Dependency, subclasses=True)
config = parser.parse_object(config)
config = parser.instantiate_classes(config)
wrapper = Wrapper(runner=config.runner)
Expected behavior
The custom instantiator runs even when using nested dependency injection.
Environment
- jsonargparse version: 4.32.1
- Python version: 3.10
- How jsonargparse was installed:
pip install jsonargparse[signatures]==4.32.1
in a conda environment - OS: linux pop-os 6.9.3
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working