Hydra: [Bug] Instantiating objects and calling methods and functions CRASHES

Created on 8 Jul 2020  路  10Comments  路  Source: facebookresearch/hydra

馃悰 Bug

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".

To reproduce

* 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

models.py

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

Expected Behavior


The code in the docs for Hydra's class instantiation should work.

System information

  • Hydra Version : 1.0rc
  • Python version : 3.7
  • Virtual environment type and version : None
  • Operating system : Manjaro Linux

Additional context

Add any other context about the problem here.

bug

All 10 comments

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?

737 fixes this error (and introduces some changes)

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

omry picture omry  路  5Comments

Alexfinkelshtein picture Alexfinkelshtein  路  4Comments

lkhphuc picture lkhphuc  路  3Comments

omry picture omry  路  4Comments

jan-matthis picture jan-matthis  路  3Comments