From e71e1e10947657bfb57883466a286a37b0427e62 Mon Sep 17 00:00:00 2001 From: yuxuan-z Date: Sat, 20 Dec 2025 02:40:22 +0800 Subject: [PATCH 1/2] use pre-commit for unified formatting --- .gitignore | 1 + .pre-commit-config.yaml | 11 +++++++++++ pyproject.toml | 11 +++++------ 3 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 .pre-commit-config.yaml diff --git a/.gitignore b/.gitignore index c4c3f3dd7..3c72fcea4 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ wheels/ .installed.cfg *.egg MANIFEST +*.lock # Virtual environments venv/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..6e5671abd --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,11 @@ +repos: + - repo: https://github.com/pycqa/isort + rev: "7.0.0" + hooks: + - id: isort + args: ["--profile", "black"] + + - repo: https://github.com/psf/black + rev: "25.12.0" + hooks: + - id: black diff --git a/pyproject.toml b/pyproject.toml index 8bf564feb..5b4399116 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,10 +8,8 @@ dynamic = ["version"] description = "Open-source implementation of AlphaEvolve" readme = "README.md" requires-python = ">=3.10" -license = {text = "Apache-2.0"} -authors = [ - {name = "codelion"} -] +license = { text = "Apache-2.0" } +authors = [{ name = "codelion" }] dependencies = [ "openai>=1.0.0", "pyyaml>=6.0", @@ -28,6 +26,7 @@ dev = [ "isort>=5.10.0", "mypy>=0.950", "requests>=2.28.0", + "pre-commit>=4.5.1", ] [tool.black] @@ -52,7 +51,7 @@ openevolve-run = "openevolve.cli:main" [tool.pytest.ini_options] markers = [ "slow: marks tests as slow (deselect with '-m \"not slow\"')", - "integration: marks tests as integration tests requiring external services" + "integration: marks tests as integration tests requiring external services", ] addopts = "--strict-markers" @@ -63,4 +62,4 @@ include = ["openevolve*"] openevolve = ["prompts/defaults/*.txt", "prompts/defaults/*.json"] [tool.setuptools.dynamic] -version = {attr = "openevolve._version.__version__"} +version = { attr = "openevolve._version.__version__" } From aff8ba7d5a12c0f2a436473349ab69ed5ad83ba5 Mon Sep 17 00:00:00 2001 From: yuxuan-z Date: Sat, 20 Dec 2025 03:14:58 +0800 Subject: [PATCH 2/2] simplify Config.from_dict with dacite --- openevolve/config.py | 45 ++++++++++---------------------------------- pyproject.toml | 1 + 2 files changed, 11 insertions(+), 35 deletions(-) diff --git a/openevolve/config.py b/openevolve/config.py index b0b50c79e..e01db8697 100644 --- a/openevolve/config.py +++ b/openevolve/config.py @@ -8,6 +8,7 @@ from pathlib import Path from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Union +import dacite import yaml if TYPE_CHECKING: @@ -418,46 +419,20 @@ def from_yaml(cls, path: Union[str, Path]) -> "Config": @classmethod def from_dict(cls, config_dict: Dict[str, Any]) -> "Config": - """Create configuration from a dictionary""" - # Handle nested configurations - config = Config() - - # Update top-level fields - for key, value in config_dict.items(): - if key not in ["llm", "prompt", "database", "evaluator", "evolution_trace"] and hasattr( - config, key - ): - setattr(config, key, value) - - # Update nested configs - if "llm" in config_dict: - llm_dict = config_dict["llm"] - if "models" in llm_dict: - llm_dict["models"] = [LLMModelConfig(**m) for m in llm_dict["models"]] - if "evaluator_models" in llm_dict: - llm_dict["evaluator_models"] = [ - LLMModelConfig(**m) for m in llm_dict["evaluator_models"] - ] - config.llm = LLMConfig(**llm_dict) - if "prompt" in config_dict: - config.prompt = PromptConfig(**config_dict["prompt"]) - if "database" in config_dict: - config.database = DatabaseConfig(**config_dict["database"]) - - # Ensure database inherits the random seed if not explicitly set - if config.database.random_seed is None and config.random_seed is not None: - config.database.random_seed = config.random_seed - if "evaluator" in config_dict: - config.evaluator = EvaluatorConfig(**config_dict["evaluator"]) - if "evolution_trace" in config_dict: - config.evolution_trace = EvolutionTraceConfig(**config_dict["evolution_trace"]) if "diff_pattern" in config_dict: - # Validate it's a valid regex try: re.compile(config_dict["diff_pattern"]) except re.error as e: raise ValueError(f"Invalid regex pattern in diff_pattern: {e}") - config.diff_pattern = config_dict["diff_pattern"] + + config: Config = dacite.from_dict( + data_class=cls, + data=config_dict, + config=dacite.Config(cast=[List, Union], forward_references={"LLMInterface": Any}), + ) + + if config.database.random_seed is None and config.random_seed is not None: + config.database.random_seed = config.random_seed return config diff --git a/pyproject.toml b/pyproject.toml index 5b4399116..f95cd439c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,6 +16,7 @@ dependencies = [ "numpy>=1.22.0", "tqdm>=4.64.0", "flask", + "dacite>=1.9.2", ] [project.optional-dependencies]