fix: use importlib.metadata for plugin discovery to support PEP 660 (#2687)

This commit is contained in:
Alexis Alva
2025-12-24 11:45:14 -03:00
committed by GitHub
parent a06f4b9140
commit 12043b3b5c
+20 -14
View File
@@ -14,8 +14,8 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import importlib import importlib
import importlib.metadata
import logging import logging
import pkgutil
from typing import Any from typing import Any
from draccus.choice_types import ChoiceRegistry from draccus.choice_types import ChoiceRegistry
@@ -132,24 +132,30 @@ def make_device_from_device_class(config: ChoiceRegistry) -> Any:
def register_third_party_plugins() -> None: def register_third_party_plugins() -> None:
""" """
Discover and import third-party lerobot_* plugins so they can register themselves. Discover and import third-party LeRobot plugins so they can register themselves.
Scans top-level modules on sys.path for packages starting with This function uses `importlib.metadata` to find packages installed in the environment
'lerobot_robot_', 'lerobot_camera_', 'lerobot_teleoperator_' or 'lerobot_policy_' and imports them. (including editable installs) starting with 'lerobot_robot_', 'lerobot_camera_',
'lerobot_teleoperator_', or 'lerobot_policy_' and imports them.
""" """
prefixes = ("lerobot_robot_", "lerobot_camera_", "lerobot_teleoperator_", "lerobot_policy_") prefixes = ("lerobot_robot_", "lerobot_camera_", "lerobot_teleoperator_", "lerobot_policy_")
imported: list[str] = [] imported: list[str] = []
failed: list[str] = [] failed: list[str] = []
for module_info in pkgutil.iter_modules(): def attempt_import(module_name: str):
name = module_info.name try:
if name.startswith(prefixes): importlib.import_module(module_name)
try: imported.append(module_name)
importlib.import_module(name) logging.info("Imported third-party plugin: %s", module_name)
imported.append(name) except Exception:
logging.info("Imported third-party plugin: %s", name) logging.exception("Could not import third-party plugin: %s", module_name)
except Exception: failed.append(module_name)
logging.exception("Could not import third-party plugin: %s", name)
failed.append(name) for dist in importlib.metadata.distributions():
dist_name = dist.metadata.get("Name")
if not dist_name:
continue
if dist_name.startswith(prefixes):
attempt_import(dist_name)
logging.debug("Third-party plugin import summary: imported=%s failed=%s", imported, failed) logging.debug("Third-party plugin import summary: imported=%s failed=%s", imported, failed)