Skip to content

Commit a65ca2b

Browse files
authored
Merge pull request #360 from yuxuan-z19/zyx-dacite
Refactor: Simplify `Config.from_dict` with `dacite` and integrate pre-commit
2 parents 8233687 + aff8ba7 commit a65ca2b

File tree

4 files changed

+28
-41
lines changed

4 files changed

+28
-41
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ wheels/
2424
.installed.cfg
2525
*.egg
2626
MANIFEST
27+
*.lock
2728

2829
# Virtual environments
2930
venv/

.pre-commit-config.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
repos:
2+
- repo: https://github.com/pycqa/isort
3+
rev: "7.0.0"
4+
hooks:
5+
- id: isort
6+
args: ["--profile", "black"]
7+
8+
- repo: https://github.com/psf/black
9+
rev: "25.12.0"
10+
hooks:
11+
- id: black

openevolve/config.py

Lines changed: 10 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from pathlib import Path
99
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Union
1010

11+
import dacite
1112
import yaml
1213

1314
if TYPE_CHECKING:
@@ -418,46 +419,20 @@ def from_yaml(cls, path: Union[str, Path]) -> "Config":
418419

419420
@classmethod
420421
def from_dict(cls, config_dict: Dict[str, Any]) -> "Config":
421-
"""Create configuration from a dictionary"""
422-
# Handle nested configurations
423-
config = Config()
424-
425-
# Update top-level fields
426-
for key, value in config_dict.items():
427-
if key not in ["llm", "prompt", "database", "evaluator", "evolution_trace"] and hasattr(
428-
config, key
429-
):
430-
setattr(config, key, value)
431-
432-
# Update nested configs
433-
if "llm" in config_dict:
434-
llm_dict = config_dict["llm"]
435-
if "models" in llm_dict:
436-
llm_dict["models"] = [LLMModelConfig(**m) for m in llm_dict["models"]]
437-
if "evaluator_models" in llm_dict:
438-
llm_dict["evaluator_models"] = [
439-
LLMModelConfig(**m) for m in llm_dict["evaluator_models"]
440-
]
441-
config.llm = LLMConfig(**llm_dict)
442-
if "prompt" in config_dict:
443-
config.prompt = PromptConfig(**config_dict["prompt"])
444-
if "database" in config_dict:
445-
config.database = DatabaseConfig(**config_dict["database"])
446-
447-
# Ensure database inherits the random seed if not explicitly set
448-
if config.database.random_seed is None and config.random_seed is not None:
449-
config.database.random_seed = config.random_seed
450-
if "evaluator" in config_dict:
451-
config.evaluator = EvaluatorConfig(**config_dict["evaluator"])
452-
if "evolution_trace" in config_dict:
453-
config.evolution_trace = EvolutionTraceConfig(**config_dict["evolution_trace"])
454422
if "diff_pattern" in config_dict:
455-
# Validate it's a valid regex
456423
try:
457424
re.compile(config_dict["diff_pattern"])
458425
except re.error as e:
459426
raise ValueError(f"Invalid regex pattern in diff_pattern: {e}")
460-
config.diff_pattern = config_dict["diff_pattern"]
427+
428+
config: Config = dacite.from_dict(
429+
data_class=cls,
430+
data=config_dict,
431+
config=dacite.Config(cast=[List, Union], forward_references={"LLMInterface": Any}),
432+
)
433+
434+
if config.database.random_seed is None and config.random_seed is not None:
435+
config.database.random_seed = config.random_seed
461436

462437
return config
463438

pyproject.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,15 @@ dynamic = ["version"]
88
description = "Open-source implementation of AlphaEvolve"
99
readme = "README.md"
1010
requires-python = ">=3.10"
11-
license = {text = "Apache-2.0"}
12-
authors = [
13-
{name = "codelion"}
14-
]
11+
license = { text = "Apache-2.0" }
12+
authors = [{ name = "codelion" }]
1513
dependencies = [
1614
"openai>=1.0.0",
1715
"pyyaml>=6.0",
1816
"numpy>=1.22.0",
1917
"tqdm>=4.64.0",
2018
"flask",
19+
"dacite>=1.9.2",
2120
]
2221

2322
[project.optional-dependencies]
@@ -28,6 +27,7 @@ dev = [
2827
"isort>=5.10.0",
2928
"mypy>=0.950",
3029
"requests>=2.28.0",
30+
"pre-commit>=4.5.1",
3131
]
3232

3333
[tool.black]
@@ -52,7 +52,7 @@ openevolve-run = "openevolve.cli:main"
5252
[tool.pytest.ini_options]
5353
markers = [
5454
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
55-
"integration: marks tests as integration tests requiring external services"
55+
"integration: marks tests as integration tests requiring external services",
5656
]
5757
addopts = "--strict-markers"
5858

@@ -63,4 +63,4 @@ include = ["openevolve*"]
6363
openevolve = ["prompts/defaults/*.txt", "prompts/defaults/*.json"]
6464

6565
[tool.setuptools.dynamic]
66-
version = {attr = "openevolve._version.__version__"}
66+
version = { attr = "openevolve._version.__version__" }

0 commit comments

Comments
 (0)