facebookresearch / hydra

Hydra is a framework for elegantly configuring complex applications
https://hydra.cc
MIT License
8.81k stars 635 forks source link

[Question] Specifying args which are Types with `instantiate` #2789

Open ammirato opened 1 year ago

ammirato commented 1 year ago

I'm trying write a yaml file to build a python object, which has an arg which is a dict where the keys are types and the values are anything.

Here's an example.

The class (in toy.py)

from typing import Dict, Type, Any, List
class MyClass:
    def __init__(self, paths: Dict[Any, Any]):
        self.paths = paths

The yaml (in ./config/toy.yaml) which does not do what I want

_target_: toy.MyClass
paths:
  pathlib.Path: 
    _target_: pathlib.Path
    _args_:
      - "/home/user"
  str: "/home/user"

A test/example:

import hydra
from omegaconf import OmegaConf
import pathlib
from toy import MyClass

expected_obj = MyClass(
    paths={
        pathlib.Path: pathlib.Path("/home/user"),
        str: "/home/user",
    }
)

config_filepath = "./config/toy.yaml"
config = OmegaConf.load(config_filepath)
obj = hydra.utils.instantiate(config)

print(f"Expected: {expected_obj.paths}")
print(f"Expected key types: {[type(k) for k in expected_obj.paths.keys()]}")

print(f"Hydra: {obj.paths}")
print(f"Hydra key types: {[type(k) for k in obj.paths.keys()]}")

Result of the test is

Expected: {<class 'pathlib.Path'>: PosixPath('/home/user'), <class 'str'>: '/home/user'}
Expected key types: [<class 'type'>, <class 'type'>]
Hydra: {'pathlib.Path': PosixPath('/home/user'), 'str': '/home/user'}
Hydra key types: [<class 'str'>, <class 'str'>]

How can I get the hydra obj to match?

odelalleau commented 1 year ago

This seems a bit tricky.... In such a case it may be easier to use a custom wrapper that takes as input a dictionary whose keys are strings, and transforms it into a dictionary whose keys are types. Then apply this wrapper on paths -- hopefully that would work.

ammirato commented 1 year ago

makes sense! I can see this working. instantiate is great, but I was hoping I would be able to use it to construct arbitrary python objects. Is that in the roadmap for hydra (or do you know of a third-party extension working on it)?