diff --git a/pyproject.toml b/pyproject.toml index 38b1b5825..2c538d024 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,7 +67,7 @@ dependencies = [ "einops>=0.8.0,<0.9.0", # Config & Hub - "draccus==0.10.0", # TODO: Relax version constraint + "draccus>=0.11.6,<0.12.0", "huggingface-hub>=1.0.0,<2.0.0", "requests>=2.32.0,<3.0.0", diff --git a/src/lerobot/configs/policies.py b/src/lerobot/configs/policies.py index 4da0fb9e8..faf3633f0 100644 --- a/src/lerobot/configs/policies.py +++ b/src/lerobot/configs/policies.py @@ -163,8 +163,10 @@ class PreTrainedConfig(draccus.ChoiceRegistry, HubMixin, abc.ABC): # type: igno return None def _save_pretrained(self, save_directory: Path) -> None: - with open(save_directory / CONFIG_NAME, "w") as f, draccus.config_type("json"): - draccus.dump(self, f, indent=4) + # Encode against the base class so draccus includes the choice "type" key, + # which `from_pretrained` needs to resolve the concrete subclass. + with open(save_directory / CONFIG_NAME, "w") as f: + json.dump(draccus.encode(self, PreTrainedConfig), f, indent=4) @classmethod def from_pretrained( diff --git a/src/lerobot/configs/rewards.py b/src/lerobot/configs/rewards.py index 92490bc9f..48a8d3d21 100644 --- a/src/lerobot/configs/rewards.py +++ b/src/lerobot/configs/rewards.py @@ -103,8 +103,10 @@ class RewardModelConfig(draccus.ChoiceRegistry, HubMixin, abc.ABC): pass def _save_pretrained(self, save_directory: Path) -> None: - with open(save_directory / CONFIG_NAME, "w") as f, draccus.config_type("json"): - draccus.dump(self, f, indent=4) + # Encode against the base class so draccus includes the choice "type" key, + # which `from_pretrained` needs to resolve the concrete subclass. + with open(save_directory / CONFIG_NAME, "w") as f: + json.dump(draccus.encode(self, RewardModelConfig), f, indent=4) @classmethod def from_pretrained( diff --git a/src/lerobot/rl/algorithms/configs.py b/src/lerobot/rl/algorithms/configs.py index 9448afeb3..48a033312 100644 --- a/src/lerobot/rl/algorithms/configs.py +++ b/src/lerobot/rl/algorithms/configs.py @@ -16,6 +16,7 @@ from __future__ import annotations import abc import builtins +import json import logging import os from dataclasses import dataclass, field @@ -78,8 +79,10 @@ class RLAlgorithmConfig(draccus.ChoiceRegistry, HubMixin, abc.ABC): def _save_pretrained(self, save_directory: Path) -> None: """Serialize this config as ``config.json`` inside ``save_directory``.""" - with open(save_directory / CONFIG_NAME, "w") as f, draccus.config_type("json"): - draccus.dump(self, f, indent=4) + # Encode against the base class so draccus includes the choice "type" key, + # which `from_pretrained` needs to resolve the concrete subclass. + with open(save_directory / CONFIG_NAME, "w") as f: + json.dump(draccus.encode(self, RLAlgorithmConfig), f, indent=4) @classmethod def from_pretrained( diff --git a/uv.lock b/uv.lock index a7055011e..f60ba17a9 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 2 requires-python = ">=3.12" resolution-markers = [ "(python_full_version >= '3.15' and platform_machine == 'AMD64' and sys_platform == 'linux') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'linux')", @@ -1359,18 +1359,17 @@ sdist = { url = "https://files.pythonhosted.org/packages/a2/55/8f8cab2afd404cf57 [[package]] name = "draccus" -version = "0.10.0" +version = "0.11.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mergedeep" }, { name = "pyyaml" }, - { name = "pyyaml-include" }, { name = "toml" }, { name = "typing-inspect" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4e/e2/f5012fda17ee5d1eaf3481b6ca3e11dffa5348e5e08ab745538fdc8041bb/draccus-0.10.0.tar.gz", hash = "sha256:8dd08304219becdcd66cd16058ba98e9c3e6b7bfe48ccb9579dae39f8d37ae19", size = 62243, upload-time = "2025-02-05T07:27:48.182Z" } +sdist = { url = "https://files.pythonhosted.org/packages/df/b0/cc399719e0cf6fea451f155798e19ea8c5e9c838b701d1565f29ea626c18/draccus-0.11.6.tar.gz", hash = "sha256:d134f576a1f4febd93c6b200df7f92e5febffe9efdc0a5f381bf50c2e0568a39", size = 67940, upload-time = "2026-06-12T13:21:19.999Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c4/9a/a83083b230d352ee5d205757b74006dbe084448ca45e3bc5ca99215b1e55/draccus-0.10.0-py3-none-any.whl", hash = "sha256:90243418ae0e9271c390a59cafb6acfd37001193696ed36fcc8525f791a83282", size = 71783, upload-time = "2025-02-05T07:27:46.1Z" }, + { url = "https://files.pythonhosted.org/packages/18/f1/d56bef4563d1cfaf55dd58de298a456587b9fe0a85dabb55768d44ace8f7/draccus-0.11.6-py3-none-any.whl", hash = "sha256:1cf3f37c64766e0f17d757099b388e762f1d22c772cc2376b4e366b515fb5737", size = 85449, upload-time = "2026-06-12T13:21:18.83Z" }, ] [[package]] @@ -3289,7 +3288,7 @@ requires-dist = [ { name = "deepdiff", marker = "extra == 'deepdiff-dep'", specifier = ">=7.0.1,<9.0.0" }, { name = "diffusers", marker = "extra == 'diffusers-dep'", specifier = ">=0.38.0,<0.40.0" }, { name = "dm-tree", marker = "extra == 'groot'", specifier = ">=0.1.8,<1.0.0" }, - { name = "draccus", specifier = "==0.10.0" }, + { name = "draccus", specifier = ">=0.11.6,<0.12.0" }, { name = "dynamixel-sdk", marker = "extra == 'dynamixel'", specifier = ">=3.7.31,<3.9.0" }, { name = "einops", specifier = ">=0.8.0,<0.9.0" }, { name = "faker", marker = "extra == 'sarm'", specifier = ">=33.0.0,<35.0.0" }, @@ -5636,18 +5635,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, ] -[[package]] -name = "pyyaml-include" -version = "1.4.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pyyaml" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/7f/be/2d07ad85e3d593d69640876a8686eae2c533db8cb7bf298d25c421b4d2d5/pyyaml-include-1.4.1.tar.gz", hash = "sha256:1a96e33a99a3e56235f5221273832464025f02ff3d8539309a3bf00dec624471", size = 20592, upload-time = "2024-03-25T14:56:43.748Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d5/ca/6a2cc3a73170d10b5af1f1613baa2ed1f8f46f62dd0bfab2bffd2c2fe260/pyyaml_include-1.4.1-py3-none-any.whl", hash = "sha256:323c7f3a19c82fbc4d73abbaab7ef4f793e146a13383866831631b26ccc7fb00", size = 19079, upload-time = "2024-03-25T14:56:41.274Z" }, -] - [[package]] name = "pyzmq" version = "27.1.0"