https://hydra.cc/docs/next/patterns/objects#instantiating-objects-and-calling-methods-and-functions
Following the 1.0rc instructions for object instantiation results in "ValueError: Input config does not have a cls field", followed by "UnboundLocalError: local variable 'cls' referenced before assignment".
* Minimal Code/Config snippet to reproduce *
pip install hydra-core --upgrade --pre
Basically copy pasted from the docs. All you have to do is make these files in the same dir, then run python main.py.
# config.yaml
myobject:
target: models.Foo
params:
x: 10
y: 20
myclassmethod:
target: models.Foo.class_method
params:
z: 5
mystaticmethod:
target: models.Foo.static_method
params:
z: 15
myfunction:
target: models.bar
params:
z: 15
```python
from typing import Any
class Foo:
def __init__(self, x: int, y: int) -> None:
self.x = x
self.y = y
@classmethod
def class_method(self, z: int) -> Any:
return self(z, 10)
@staticmethod
def static_method(z: int) -> int:
return z + 1
def bar(z: int) -> int:
return z + 2
```python
# main.py
import hydra
from models import Foo
@hydra.main(config_name="config.yaml")
def app(cfg):
foo1: Foo = hydra.utils.call(cfg.myobject) # Foo(10, 20)
print(Foo)
foo2: Foo = hydra.utils.call(cfg.myclassmethod) # Foo(5, 10)
print(Foo)
ret1: int = hydra.utils.call(cfg.mystaticmethod) # 16
print(ret1)
ret2: int = hydra.utils.call(cfg.myfunction) # 17
print(ret2)
if __name__ == "__main__":
app()
* Stack trace/error message *
Traceback (most recent call last):
File "/home/andrew/.miniconda3/envs/pt/lib/python3.7/site-packages/hydra/utils.py", line 29, in call
cls = _get_cls_name(config)
File "/home/andrew/.miniconda3/envs/pt/lib/python3.7/site-packages/hydra/_internal/utils.py", line 489, in _get_cls_name
raise ValueError("Input config does not have a cls field")
ValueError: Input config does not have a cls field
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "main.py", line 16, in <module>
app()
File "/home/andrew/.miniconda3/envs/pt/lib/python3.7/site-packages/hydra/main.py", line 37, in decorated_main
strict=strict,
File "/home/andrew/.miniconda3/envs/pt/lib/python3.7/site-packages/hydra/_internal/utils.py", line 253, in run_hydra
lambda: hydra.run(
File "/home/andrew/.miniconda3/envs/pt/lib/python3.7/site-packages/hydra/_internal/utils.py", line 185, in run_and_report
func()
File "/home/andrew/.miniconda3/envs/pt/lib/python3.7/site-packages/hydra/_internal/utils.py", line 256, in <lambda>
overrides=args.overrides,
File "/home/andrew/.miniconda3/envs/pt/lib/python3.7/site-packages/hydra/_internal/hydra.py", line 114, in run
job_subdir_key=None,
File "/home/andrew/.miniconda3/envs/pt/lib/python3.7/site-packages/hydra/core/utils.py", line 107, in run_job
ret.return_value = task_function(task_cfg)
File "main.py", line 6, in app
foo1: Foo = hydra.utils.call(cfg.myobject) # Foo(10, 20)
File "/home/andrew/.miniconda3/envs/pt/lib/python3.7/site-packages/hydra/utils.py", line 37, in call
log.error(f"Error instantiating '{cls}' : {e}")
UnboundLocalError: local variable 'cls' referenced before assignment
The code in the docs for Hydra's class instantiation should work.
Add any other context about the problem here.
The instructions on the rc are for master, unfortunately there is no official docs version for 1.0.0rc1 and there have been some changes.
try with cls.
This is going to change again soon (see #737).
Okay.
Replacing "target" with "cls" does not work, same error.
Please provide minimal repro instructions, including how you are installing.
@shagunsodhani, can you help with this one?
@omry okay, I updated with the pip install hydra-core --upgrade --pre command I used.
I could run the code by replacing target by cls in the config (as shown):
#config.yaml
myobject:
cls: models.Foo
params:
x: 10
y: 20
myclassmethod:
cls: models.Foo.class_method
params:
z: 5
mystaticmethod:
cls: models.Foo.static_method
params:
z: 15
myfunction:
cls: models.bar
params:
z: 15
Could you please try with this?
Huh, it works. My apologies, I must have tested incorrectly when I tried replacing target with cls the first time. Happy there's a solution now. Thanks guys!
thanks @andrewjong.
@shagunsodhani, can you try with a badly spelled cls to see that the error makes sense?
Yup. As misspelled cls will cause the problem. The right thing is to catch the ValueError: Input config does not have a cls field and pass it up. Will fix it with #737
Pass it up as in a HydraException.