Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] mutable default is not allowed in @dataclass in python > 3.9. #2862

Closed
2 tasks done
ga92xug opened this issue Feb 29, 2024 · 2 comments
Closed
2 tasks done

[Bug] mutable default is not allowed in @dataclass in python > 3.9. #2862

ga92xug opened this issue Feb 29, 2024 · 2 comments
Labels
bug Something isn't working

Comments

@ga92xug
Copy link

ga92xug commented Feb 29, 2024

🐛 Bug

Description

mutable default is not allowed in @dataclass in python > 3.9. I would be happy to do a pull request.

Checklist

  • I checked on the latest version of Hydra
  • I created a minimal repro.

To reproduce

** Minimal Code/Config snippet to reproduce **
min.py

from typing import Optional
import hydra
from omegaconf import DictConfig 

@hydra.main(version_base="1.3", config_path=".", config_name="conf.yaml")
def main(cfg: DictConfig) -> Optional[float]:

    print(cfg.pretty())
    return None

if __name__ == "__main__":
    main()

conf.yaml

# @package hydra.sweeper
_target_: hydra_plugins.hydra_ax_sweeper.ax_sweeper.AxSweeper
max_batch_size: null
ax_config:
  max_trials: 10
  early_stop:
    minimize: true
    max_epochs_without_improvement: 10
    epsilon: 1.0e-05
  experiment:
    name: null
    objective_name: objective
    minimize: true
    parameter_constraints: null
    outcome_constraints: null
    status_quo: null
  client:
    verbose_logging: false
    random_seed: null
  is_noisy: true
  params: {}

** Stack trace/error message **

Traceback (most recent call last):
  File "/home/stefan/git/min_example_hydra_ax_bug/min.py", line 12, in <module>
    main()
  File "/home/stefan/anaconda3/envs/hydra_ax_bug_py_3_11/lib/python3.11/site-packages/hydra/main.py", line 94, in decorated_main
    _run_hydra(
  File "/home/stefan/anaconda3/envs/hydra_ax_bug_py_3_11/lib/python3.11/site-packages/hydra/_internal/utils.py", line 337, in _run_hydra
    search_path = create_automatic_config_search_path(
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/stefan/anaconda3/envs/hydra_ax_bug_py_3_11/lib/python3.11/site-packages/hydra/_internal/utils.py", line 190, in create_automatic_config_search_path
    return create_config_search_path(search_path_dir)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/stefan/anaconda3/envs/hydra_ax_bug_py_3_11/lib/python3.11/site-packages/hydra/_internal/utils.py", line 203, in create_config_search_path
    search_path_plugins = Plugins.instance().discover(SearchPathPlugin)
                          ^^^^^^^^^^^^^^^^^^
  File "/home/stefan/anaconda3/envs/hydra_ax_bug_py_3_11/lib/python3.11/site-packages/hydra/core/plugins.py", line 46, in instance
    ret = Singleton.instance(Plugins, *args, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/stefan/anaconda3/envs/hydra_ax_bug_py_3_11/lib/python3.11/site-packages/hydra/core/singleton.py", line 17, in instance
    return cls(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^
  File "/home/stefan/anaconda3/envs/hydra_ax_bug_py_3_11/lib/python3.11/site-packages/hydra/core/singleton.py", line 13, in __call__
    cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/stefan/anaconda3/envs/hydra_ax_bug_py_3_11/lib/python3.11/site-packages/hydra/core/plugins.py", line 54, in __init__
    self._initialize()
  File "/home/stefan/anaconda3/envs/hydra_ax_bug_py_3_11/lib/python3.11/site-packages/hydra/core/plugins.py", line 71, in _initialize
    scanned_plugins, self.stats = self._scan_all_plugins(modules=top_level)
                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/stefan/anaconda3/envs/hydra_ax_bug_py_3_11/lib/python3.11/site-packages/hydra/core/plugins.py", line 197, in _scan_all_plugins
    spec.loader.exec_module(loaded_mod)
  File "<frozen importlib._bootstrap_external>", line 940, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/home/stefan/anaconda3/envs/hydra_ax_bug_py_3_11/lib/python3.11/site-packages/hydra_plugins/hydra_ax_sweeper/ax_sweeper.py", line 8, in <module>
    from .config import AxConfig
  File "/home/stefan/anaconda3/envs/hydra_ax_bug_py_3_11/lib/python3.11/site-packages/hydra_plugins/hydra_ax_sweeper/config.py", line 44, in <module>
    @dataclass
     ^^^^^^^^^
  File "/home/stefan/anaconda3/envs/hydra_ax_bug_py_3_11/lib/python3.11/dataclasses.py", line 1230, in dataclass
    return wrap(cls)
           ^^^^^^^^^
  File "/home/stefan/anaconda3/envs/hydra_ax_bug_py_3_11/lib/python3.11/dataclasses.py", line 1220, in wrap
    return _process_class(cls, init, repr, eq, order, unsafe_hash,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/stefan/anaconda3/envs/hydra_ax_bug_py_3_11/lib/python3.11/dataclasses.py", line 958, in _process_class
    cls_fields.append(_get_field(cls, name, type, kw_only))
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/stefan/anaconda3/envs/hydra_ax_bug_py_3_11/lib/python3.11/dataclasses.py", line 815, in _get_field
    raise ValueError(f'mutable default {type(f.default)} for field '
ValueError: mutable default <class 'hydra_plugins.hydra_ax_sweeper.config.EarlyStopConfig'> for field early_stop is not allowed: use default_factory

Expected Behavior

System information

  • Hydra Version : 1.3.2
  • Python version : 3.11.8
  • Virtual environment type and version : conda
  • Operating system : ubuntu 22.04

Fix

config.py

# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
from dataclasses import dataclass, field
from typing import Any, Dict, List, Optional

from hydra.core.config_store import ConfigStore


@dataclass
class EarlyStopConfig:
    minimize: bool = True

    max_epochs_without_improvement: int = 10

    # An improvement larger than epsilon is considered significant
    epsilon: float = 0.00001


@dataclass
class ExperimentConfig:
    # Experiment name
    name: Optional[str] = None

    # Name of metric to optimize or null if you only return one metric
    objective_name: str = "objective"

    # Defaults to minimize, set to false to maximize
    minimize: bool = True

    # For the remaining parameters, refer the Ax documentation: https://ax.dev/api/core.html#experiment
    parameter_constraints: Optional[List[str]] = None
    outcome_constraints: Optional[List[str]] = None
    status_quo: Optional[Dict[str, Any]] = None


@dataclass
class ClientConfig:

    verbose_logging: bool = False

    # set random seed here to make Ax results reproducible
    random_seed: Optional[int] = None


@dataclass
class AxConfig:

    # max_trials is application-specific. Tune it for your use case
    max_trials: int = 10
    early_stop: EarlyStopConfig = field(default_factory=EarlyStopConfig)
    experiment: ExperimentConfig = field(default_factory=ExperimentConfig)
    client: ClientConfig = field(default_factory=ClientConfig)
    params: Dict[str, Any] = field(default_factory=dict)
    # is_noisy = True indicates measurements have unknown uncertainty
    # is_noisy = False indicates measurements have an uncertainty of zero
    is_noisy: bool = True


@dataclass
class AxSweeperConf:
    _target_: str = "hydra_plugins.hydra_ax_sweeper.ax_sweeper.AxSweeper"
    # Maximum number of trials to run in parallel
    max_batch_size: Optional[int] = None
    ax_config: AxConfig = field(default_factory=AxConfig)


ConfigStore.instance().store(
    group="hydra/sweeper", name="ax", node=AxSweeperConf, provider="ax_sweeper"
)
@ga92xug ga92xug added the bug Something isn't working label Feb 29, 2024
@Jasha10
Copy link
Collaborator

Jasha10 commented Feb 29, 2024

Possibly related: #2777

@ga92xug
Copy link
Author

ga92xug commented Mar 7, 2024

Ah yes that is right. Overlooked that. I will close that.

@ga92xug ga92xug closed this as completed Mar 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants