diff --git a/examples/dataset/use_dataset_tools.py b/examples/dataset/use_dataset_tools.py index 55d87f4c1..4d7ba885f 100644 --- a/examples/dataset/use_dataset_tools.py +++ b/examples/dataset/use_dataset_tools.py @@ -31,12 +31,13 @@ import numpy as np from lerobot.datasets import ( LeRobotDataset, + add_features, delete_episodes, merge_datasets, + modify_features, remove_feature, split_dataset, ) -from lerobot.datasets.dataset_tools import add_features, modify_features def main(): diff --git a/examples/hil/hil_utils.py b/examples/hil/hil_utils.py index 45c16a1b7..0f433d83a 100644 --- a/examples/hil/hil_utils.py +++ b/examples/hil/hil_utils.py @@ -25,8 +25,6 @@ from lerobot.processor import ( RobotAction, RobotObservation, RobotProcessorPipeline, -) -from lerobot.processor.converters import ( observation_to_transition, robot_action_observation_to_transition, transition_to_observation, diff --git a/examples/phone_to_so100/evaluate.py b/examples/phone_to_so100/evaluate.py index b17e29d23..267e67c48 100644 --- a/examples/phone_to_so100/evaluate.py +++ b/examples/phone_to_so100/evaluate.py @@ -24,8 +24,6 @@ from lerobot.policies.act import ACTPolicy from lerobot.processor import ( RobotProcessorPipeline, make_default_teleop_action_processor, -) -from lerobot.processor.converters import ( observation_to_transition, robot_action_observation_to_transition, transition_to_observation, diff --git a/examples/phone_to_so100/record.py b/examples/phone_to_so100/record.py index 64d688bc9..6a8d38ec3 100644 --- a/examples/phone_to_so100/record.py +++ b/examples/phone_to_so100/record.py @@ -18,8 +18,8 @@ from lerobot.cameras.opencv import OpenCVCameraConfig from lerobot.common.control_utils import init_keyboard_listener from lerobot.datasets import LeRobotDataset, aggregate_pipeline_dataset_features, create_initial_features from lerobot.model.kinematics import RobotKinematics -from lerobot.processor import RobotProcessorPipeline -from lerobot.processor.converters import ( +from lerobot.processor import ( + RobotProcessorPipeline, observation_to_transition, robot_action_observation_to_transition, transition_to_observation, diff --git a/examples/phone_to_so100/replay.py b/examples/phone_to_so100/replay.py index 63d031b17..7a2cb340f 100644 --- a/examples/phone_to_so100/replay.py +++ b/examples/phone_to_so100/replay.py @@ -18,8 +18,8 @@ import time from lerobot.datasets import LeRobotDataset from lerobot.model.kinematics import RobotKinematics -from lerobot.processor import RobotProcessorPipeline -from lerobot.processor.converters import ( +from lerobot.processor import ( + RobotProcessorPipeline, robot_action_observation_to_transition, transition_to_robot_action, ) diff --git a/examples/phone_to_so100/teleoperate.py b/examples/phone_to_so100/teleoperate.py index 23bf5c16e..9065de4bb 100644 --- a/examples/phone_to_so100/teleoperate.py +++ b/examples/phone_to_so100/teleoperate.py @@ -16,8 +16,8 @@ import time from lerobot.model.kinematics import RobotKinematics -from lerobot.processor import RobotProcessorPipeline -from lerobot.processor.converters import ( +from lerobot.processor import ( + RobotProcessorPipeline, robot_action_observation_to_transition, transition_to_robot_action, ) diff --git a/examples/port_datasets/slurm_aggregate_shards.py b/examples/port_datasets/slurm_aggregate_shards.py index af5473c79..7730b552d 100644 --- a/examples/port_datasets/slurm_aggregate_shards.py +++ b/examples/port_datasets/slurm_aggregate_shards.py @@ -36,7 +36,7 @@ class AggregateDatasets(PipelineStep): def run(self, data=None, rank: int = 0, world_size: int = 1): import logging - from lerobot.datasets.aggregate import aggregate_datasets + from lerobot.datasets import aggregate_datasets from lerobot.utils.utils import init_logging init_logging() diff --git a/examples/port_datasets/slurm_upload.py b/examples/port_datasets/slurm_upload.py index d03fab0c4..b9f05c2db 100644 --- a/examples/port_datasets/slurm_upload.py +++ b/examples/port_datasets/slurm_upload.py @@ -26,8 +26,7 @@ from huggingface_hub import HfApi from huggingface_hub.constants import REPOCARD_NAME from port_droid import DROID_SHARDS -from lerobot.datasets import CODEBASE_VERSION, LeRobotDatasetMetadata -from lerobot.datasets.utils import create_lerobot_dataset_card +from lerobot.datasets import CODEBASE_VERSION, LeRobotDatasetMetadata, create_lerobot_dataset_card from lerobot.utils.utils import init_logging diff --git a/examples/rtc/eval_dataset.py b/examples/rtc/eval_dataset.py index cb6da431d..bacafead1 100644 --- a/examples/rtc/eval_dataset.py +++ b/examples/rtc/eval_dataset.py @@ -110,8 +110,7 @@ except ImportError: plt = None from lerobot.configs import DatasetConfig, PreTrainedConfig, RTCAttentionSchedule, parser -from lerobot.datasets import LeRobotDataset, LeRobotDatasetMetadata -from lerobot.datasets.factory import resolve_delta_timestamps +from lerobot.datasets import LeRobotDataset, LeRobotDatasetMetadata, resolve_delta_timestamps from lerobot.policies import get_policy_class, make_pre_post_processors from lerobot.policies.rtc import RTCConfig from lerobot.policies.rtc.debug_visualizer import RTCDebugVisualizer diff --git a/examples/rtc/eval_with_real_robot.py b/examples/rtc/eval_with_real_robot.py index e43eb12ab..66562749c 100644 --- a/examples/rtc/eval_with_real_robot.py +++ b/examples/rtc/eval_with_real_robot.py @@ -103,7 +103,7 @@ from torch import Tensor from lerobot.cameras.opencv import OpenCVCameraConfig # noqa: F401 from lerobot.cameras.realsense import RealSenseCameraConfig # noqa: F401 -from lerobot.cameras.zmq.configuration_zmq import ZMQCameraConfig # noqa: F401 +from lerobot.cameras.zmq import ZMQCameraConfig # noqa: F401 from lerobot.configs import PreTrainedConfig, RTCAttentionSchedule, parser from lerobot.policies import get_policy_class, make_pre_post_processors from lerobot.policies.rtc import ActionInterpolator, ActionQueue, LatencyTracker, RTCConfig @@ -112,11 +112,9 @@ from lerobot.processor import ( RelativeActionsProcessorStep, TransitionKey, create_transition, - to_relative_actions, -) -from lerobot.processor.factory import ( make_default_robot_action_processor, make_default_robot_observation_processor, + to_relative_actions, ) from lerobot.rl.process import ProcessSignalHandler from lerobot.robots import ( # noqa: F401 diff --git a/examples/so100_to_so100_EE/evaluate.py b/examples/so100_to_so100_EE/evaluate.py index 46eb6cffb..fb5204997 100644 --- a/examples/so100_to_so100_EE/evaluate.py +++ b/examples/so100_to_so100_EE/evaluate.py @@ -24,8 +24,6 @@ from lerobot.policies.act import ACTPolicy from lerobot.processor import ( RobotProcessorPipeline, make_default_teleop_action_processor, -) -from lerobot.processor.converters import ( observation_to_transition, robot_action_observation_to_transition, transition_to_observation, diff --git a/examples/so100_to_so100_EE/record.py b/examples/so100_to_so100_EE/record.py index 49de9d9e5..a7ac5bb80 100644 --- a/examples/so100_to_so100_EE/record.py +++ b/examples/so100_to_so100_EE/record.py @@ -19,8 +19,8 @@ from lerobot.cameras.opencv import OpenCVCameraConfig from lerobot.common.control_utils import init_keyboard_listener from lerobot.datasets import LeRobotDataset, aggregate_pipeline_dataset_features, create_initial_features from lerobot.model.kinematics import RobotKinematics -from lerobot.processor import RobotProcessorPipeline -from lerobot.processor.converters import ( +from lerobot.processor import ( + RobotProcessorPipeline, observation_to_transition, robot_action_observation_to_transition, transition_to_observation, diff --git a/examples/so100_to_so100_EE/replay.py b/examples/so100_to_so100_EE/replay.py index 61c58e847..24d6f26fb 100644 --- a/examples/so100_to_so100_EE/replay.py +++ b/examples/so100_to_so100_EE/replay.py @@ -19,8 +19,8 @@ import time from lerobot.datasets import LeRobotDataset from lerobot.model.kinematics import RobotKinematics -from lerobot.processor import RobotProcessorPipeline -from lerobot.processor.converters import ( +from lerobot.processor import ( + RobotProcessorPipeline, robot_action_observation_to_transition, transition_to_robot_action, ) diff --git a/examples/so100_to_so100_EE/teleoperate.py b/examples/so100_to_so100_EE/teleoperate.py index af21f079b..c0ff7482b 100644 --- a/examples/so100_to_so100_EE/teleoperate.py +++ b/examples/so100_to_so100_EE/teleoperate.py @@ -17,8 +17,8 @@ import time from lerobot.model.kinematics import RobotKinematics -from lerobot.processor import RobotProcessorPipeline -from lerobot.processor.converters import ( +from lerobot.processor import ( + RobotProcessorPipeline, robot_action_observation_to_transition, robot_action_to_transition, transition_to_robot_action, diff --git a/pyproject.toml b/pyproject.toml index 3e6834d74..3db911fb3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -184,7 +184,6 @@ groot = [ "lerobot[diffusers-dep]", "dm-tree>=0.1.8,<1.0.0", "timm>=1.0.0,<1.1.0", - "Pillow>=10.0.0,<13.0.0", "decord>=0.6.0,<1.0.0; (platform_machine == 'AMD64' or platform_machine == 'x86_64')", "ninja>=1.11.1,<2.0.0", "flash-attn>=2.5.9,<3.0.0 ; sys_platform != 'darwin'" @@ -223,13 +222,18 @@ all = [ # the loose scipy requirements from transitive deps like dm-control and metaworld. "scipy>=1.14.0,<2.0.0", "lerobot[dynamixel]", + "lerobot[feetech]", + "lerobot[damiao]", + "lerobot[robstride]", "lerobot[gamepad]", "lerobot[hopejr]", "lerobot[lekiwi]", + "lerobot[openarms]", "lerobot[reachy2]", "lerobot[kinematics]", "lerobot[intelrealsense]", "lerobot[diffusion]", + "lerobot[multi_task_dit]", "lerobot[wallx]", "lerobot[pi]", "lerobot[smolvla]", diff --git a/src/lerobot/__init__.py b/src/lerobot/__init__.py index 070d6d45e..df43e7172 100644 --- a/src/lerobot/__init__.py +++ b/src/lerobot/__init__.py @@ -33,4 +33,19 @@ are gated behind optional extras:: from lerobot.__version__ import __version__ -__all__ = ["__version__"] +# Maps optional extras to the CLI entry-points they unlock. +available_extras: dict[str, list[str]] = { + "dataset": ["lerobot-dataset-viz", "lerobot-imgtransform-viz", "lerobot-edit-dataset"], + "training": ["lerobot-train"], + "hardware": [ + "lerobot-calibrate", + "lerobot-find-port", + "lerobot-find-cameras", + "lerobot-find-joint-limits", + "lerobot-setup-motors", + ], + "core_scripts": ["lerobot-record", "lerobot-replay", "lerobot-teleoperate"], + "evaluation": ["lerobot-eval"], +} + +__all__ = ["__version__", "available_extras"] diff --git a/src/lerobot/data_processing/sarm_annotations/subtask_annotation.py b/src/lerobot/data_processing/sarm_annotations/subtask_annotation.py index 169485513..b26257d44 100644 --- a/src/lerobot/data_processing/sarm_annotations/subtask_annotation.py +++ b/src/lerobot/data_processing/sarm_annotations/subtask_annotation.py @@ -746,8 +746,7 @@ def save_annotations_to_dataset( dataset_path: Path, annotations: dict[int, SubtaskAnnotation], fps: int, prefix: str = "sparse" ): """Save annotations to LeRobot dataset parquet format.""" - from lerobot.datasets import load_episodes - from lerobot.datasets.utils import DEFAULT_EPISODES_PATH + from lerobot.datasets import DEFAULT_EPISODES_PATH, load_episodes episodes_dataset = load_episodes(dataset_path) if not episodes_dataset or len(episodes_dataset) == 0: diff --git a/src/lerobot/datasets/__init__.py b/src/lerobot/datasets/__init__.py index 81609eb55..6c42959a5 100644 --- a/src/lerobot/datasets/__init__.py +++ b/src/lerobot/datasets/__init__.py @@ -20,18 +20,21 @@ from lerobot.utils.import_utils import require_package require_package("datasets", extra="dataset") require_package("av", extra="dataset") -from .compute_stats import aggregate_stats, get_feature_stats +from .aggregate import aggregate_datasets +from .compute_stats import DEFAULT_QUANTILES, aggregate_stats, get_feature_stats from .dataset_metadata import CODEBASE_VERSION, LeRobotDatasetMetadata from .dataset_tools import ( + add_features, convert_image_to_video_dataset, delete_episodes, merge_datasets, + modify_features, modify_tasks, recompute_stats, remove_feature, split_dataset, ) -from .factory import make_dataset +from .factory import make_dataset, resolve_delta_timestamps from .image_writer import safe_stop_image_writer from .io_utils import load_episodes, write_stats from .lerobot_dataset import LeRobotDataset @@ -39,6 +42,7 @@ from .multi_dataset import MultiLeRobotDataset from .pipeline_features import aggregate_pipeline_dataset_features, create_initial_features from .sampler import EpisodeAwareSampler from .streaming_dataset import StreamingLeRobotDataset +from .utils import DEFAULT_EPISODES_PATH, create_lerobot_dataset_card from .video_utils import VideoEncodingManager # NOTE: Low-level I/O functions (cast_stats_to_numpy, get_parquet_file_size_in_mb, etc.) @@ -47,24 +51,31 @@ from .video_utils import VideoEncodingManager __all__ = [ "CODEBASE_VERSION", + "DEFAULT_EPISODES_PATH", + "DEFAULT_QUANTILES", "EpisodeAwareSampler", "LeRobotDataset", "LeRobotDatasetMetadata", "MultiLeRobotDataset", "StreamingLeRobotDataset", "VideoEncodingManager", + "add_features", + "aggregate_datasets", "aggregate_pipeline_dataset_features", "aggregate_stats", "convert_image_to_video_dataset", "create_initial_features", + "create_lerobot_dataset_card", "delete_episodes", "get_feature_stats", "load_episodes", "make_dataset", "merge_datasets", + "modify_features", "modify_tasks", "recompute_stats", "remove_feature", + "resolve_delta_timestamps", "safe_stop_image_writer", "split_dataset", "write_stats", diff --git a/src/lerobot/processor/__init__.py b/src/lerobot/processor/__init__.py index 20cdf310c..3688a4b8c 100644 --- a/src/lerobot/processor/__init__.py +++ b/src/lerobot/processor/__init__.py @@ -29,9 +29,14 @@ from .converters import ( create_transition, from_tensor_to_numpy, identity_transition, + observation_to_transition, policy_action_to_transition, + robot_action_observation_to_transition, + robot_action_to_transition, transition_to_batch, + transition_to_observation, transition_to_policy_action, + transition_to_robot_action, ) from .delta_action_processor import MapDeltaActionToRobotActionStep, MapTensorToDeltaActionDictStep from .device_processor import DeviceProcessorStep @@ -99,8 +104,13 @@ __all__ = [ "create_transition", "from_tensor_to_numpy", "identity_transition", + "observation_to_transition", "policy_action_to_transition", + "robot_action_observation_to_transition", + "robot_action_to_transition", + "transition_to_observation", "transition_to_policy_action", + "transition_to_robot_action", "DeviceProcessorStep", "DoneProcessorStep", "EnvAction", diff --git a/src/lerobot/scripts/augment_dataset_quantile_stats.py b/src/lerobot/scripts/augment_dataset_quantile_stats.py index a5b9edf63..4ee99a541 100644 --- a/src/lerobot/scripts/augment_dataset_quantile_stats.py +++ b/src/lerobot/scripts/augment_dataset_quantile_stats.py @@ -46,12 +46,12 @@ from tqdm import tqdm from lerobot.datasets import ( CODEBASE_VERSION, + DEFAULT_QUANTILES, LeRobotDataset, aggregate_stats, get_feature_stats, write_stats, ) -from lerobot.datasets.compute_stats import DEFAULT_QUANTILES from lerobot.utils.utils import init_logging diff --git a/src/lerobot/transport/__init__.py b/src/lerobot/transport/__init__.py index 355ad4cb9..71f125e7e 100644 --- a/src/lerobot/transport/__init__.py +++ b/src/lerobot/transport/__init__.py @@ -8,4 +8,8 @@ Available modules (import directly):: from lerobot.transport.utils import ... """ +from lerobot.utils.import_utils import require_package + +require_package("grpcio", extra="grpcio-dep", import_name="grpc") + __all__: list[str] = [] diff --git a/tests/test_available.py b/tests/test_available.py index dbfe86ace..7dd1cdacb 100644 --- a/tests/test_available.py +++ b/tests/test_available.py @@ -14,10 +14,49 @@ # See the License for the specific language governing permissions and # limitations under the License. +from unittest.mock import patch + +import pytest + import lerobot +from lerobot.utils.import_utils import _require_package_cache, require_package def test_version(): """Verify the package exposes a version string.""" assert isinstance(lerobot.__version__, str) assert len(lerobot.__version__) > 0 + + +def test_require_package_raises_when_missing(): + """require_package raises ImportError with install instructions when a package is missing.""" + with patch("lerobot.utils.import_utils.is_package_available", return_value=False): + # Clear the cache so the mock takes effect + _require_package_cache.clear() + try: + with pytest.raises(ImportError, match=r"pip install 'lerobot\[dataset\]'"): + require_package("datasets", extra="dataset") + finally: + _require_package_cache.clear() + + +def test_require_package_passes_when_available(): + """require_package does not raise when the package is installed.""" + with patch("lerobot.utils.import_utils.is_package_available", return_value=True): + _require_package_cache.clear() + try: + # Should not raise + require_package("datasets", extra="dataset") + finally: + _require_package_cache.clear() + + +def test_require_package_error_message_includes_uv(): + """Error message includes both pip and uv install commands.""" + with patch("lerobot.utils.import_utils.is_package_available", return_value=False): + _require_package_cache.clear() + try: + with pytest.raises(ImportError, match=r"uv pip install"): + require_package("grpcio", extra="async", import_name="grpc") + finally: + _require_package_cache.clear() diff --git a/uv.lock b/uv.lock index f7854e874..a596f0c95 100644 --- a/uv.lock +++ b/uv.lock @@ -829,7 +829,7 @@ name = "cuda-bindings" version = "12.9.4" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "cuda-pathfinder", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and sys_platform == 'linux'" }, + { name = "cuda-pathfinder", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and platform_machine != 's390x' and sys_platform == 'linux'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/a9/c1/dabe88f52c3e3760d861401bb994df08f672ec893b8f7592dc91626adcf3/cuda_bindings-12.9.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fda147a344e8eaeca0c6ff113d2851ffca8f7dfc0a6c932374ee5c47caa649c8", size = 12151019, upload-time = "2025-10-21T14:51:43.167Z" }, @@ -916,7 +916,7 @@ name = "decord" version = "0.6.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy", marker = "(platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l') or sys_platform != 'linux'" }, + { name = "numpy", marker = "(platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and platform_machine != 's390x') or (platform_machine != 's390x' and sys_platform != 'linux')" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/11/79/936af42edf90a7bd4e41a6cac89c913d4b47fa48a26b042d5129a9242ee3/decord-0.6.0-py3-none-manylinux2010_x86_64.whl", hash = "sha256:51997f20be8958e23b7c4061ba45d0efcd86bffd5fe81c695d0befee0d442976", size = 13602299, upload-time = "2021-06-14T21:30:55.486Z" }, @@ -2265,6 +2265,7 @@ all = [ { name = "pytest" }, { name = "pytest-cov" }, { name = "pytest-timeout" }, + { name = "python-can" }, { name = "pyzmq" }, { name = "qwen-vl-utils" }, { name = "reachy2-sdk" }, @@ -2383,7 +2384,6 @@ groot = [ { name = "flash-attn", marker = "sys_platform != 'darwin'" }, { name = "ninja" }, { name = "peft" }, - { name = "pillow" }, { name = "timm" }, { name = "transformers" }, ] @@ -2604,6 +2604,7 @@ requires-dist = [ { name = "lerobot", extras = ["build"], marker = "extra == 'all'" }, { name = "lerobot", extras = ["can-dep"], marker = "extra == 'damiao'" }, { name = "lerobot", extras = ["can-dep"], marker = "extra == 'robstride'" }, + { name = "lerobot", extras = ["damiao"], marker = "extra == 'all'" }, { name = "lerobot", extras = ["damiao"], marker = "extra == 'openarms'" }, { name = "lerobot", extras = ["dataset"], marker = "extra == 'all'" }, { name = "lerobot", extras = ["dataset"], marker = "extra == 'aloha'" }, @@ -2621,6 +2622,7 @@ requires-dist = [ { name = "lerobot", extras = ["diffusers-dep"], marker = "extra == 'multi-task-dit'" }, { name = "lerobot", extras = ["diffusion"], marker = "extra == 'all'" }, { name = "lerobot", extras = ["dynamixel"], marker = "extra == 'all'" }, + { name = "lerobot", extras = ["feetech"], marker = "extra == 'all'" }, { name = "lerobot", extras = ["feetech"], marker = "extra == 'hopejr'" }, { name = "lerobot", extras = ["feetech"], marker = "extra == 'lekiwi'" }, { name = "lerobot", extras = ["gamepad"], marker = "extra == 'all'" }, @@ -2641,6 +2643,8 @@ requires-dist = [ { name = "lerobot", extras = ["matplotlib-dep"], marker = "extra == 'sarm'" }, { name = "lerobot", extras = ["matplotlib-dep"], marker = "extra == 'unitree-g1'" }, { name = "lerobot", extras = ["metaworld"], marker = "extra == 'all'" }, + { name = "lerobot", extras = ["multi-task-dit"], marker = "extra == 'all'" }, + { name = "lerobot", extras = ["openarms"], marker = "extra == 'all'" }, { name = "lerobot", extras = ["peft"], marker = "extra == 'all'" }, { name = "lerobot", extras = ["peft"], marker = "extra == 'groot'" }, { name = "lerobot", extras = ["peft"], marker = "extra == 'wallx'" }, @@ -2656,6 +2660,7 @@ requires-dist = [ { name = "lerobot", extras = ["qwen-vl-utils-dep"], marker = "extra == 'sarm'" }, { name = "lerobot", extras = ["qwen-vl-utils-dep"], marker = "extra == 'wallx'" }, { name = "lerobot", extras = ["reachy2"], marker = "extra == 'all'" }, + { name = "lerobot", extras = ["robstride"], marker = "extra == 'all'" }, { name = "lerobot", extras = ["sarm"], marker = "extra == 'all'" }, { name = "lerobot", extras = ["scipy-dep"], marker = "extra == 'aloha'" }, { name = "lerobot", extras = ["scipy-dep"], marker = "extra == 'libero'" }, @@ -2702,7 +2707,6 @@ requires-dist = [ { name = "pandas", marker = "extra == 'video-benchmark'", specifier = ">=2.2.2,<2.4.0" }, { name = "peft", marker = "extra == 'peft-dep'", specifier = ">=0.18.0,<1.0.0" }, { name = "pillow", specifier = ">=10.0.0,<13.0.0" }, - { name = "pillow", marker = "extra == 'groot'", specifier = ">=10.0.0,<13.0.0" }, { name = "placo", marker = "extra == 'placo-dep'", specifier = ">=0.9.6,<0.9.17" }, { name = "pre-commit", marker = "extra == 'dev'", specifier = ">=3.7.0,<5.0.0" }, { name = "protobuf", marker = "extra == 'grpcio-dep'", specifier = ">=6.31.1,<6.32.0" }, @@ -3525,7 +3529,7 @@ name = "nvidia-cudnn-cu12" version = "9.10.2.21" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cublas-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and sys_platform == 'linux'" }, + { name = "nvidia-cublas-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and platform_machine != 's390x' and sys_platform == 'linux'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/ba/51/e123d997aa098c61d029f76663dedbfb9bc8dcf8c60cbd6adbe42f76d049/nvidia_cudnn_cu12-9.10.2.21-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:949452be657fa16687d0930933f032835951ef0892b37d2d53824d1a84dc97a8", size = 706758467, upload-time = "2025-06-06T21:54:08.597Z" }, @@ -3536,7 +3540,7 @@ name = "nvidia-cufft-cu12" version = "11.3.3.83" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-nvjitlink-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and sys_platform == 'linux'" }, + { name = "nvidia-nvjitlink-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and platform_machine != 's390x' and sys_platform == 'linux'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/1f/13/ee4e00f30e676b66ae65b4f08cb5bcbb8392c03f54f2d5413ea99a5d1c80/nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d2dd21ec0b88cf61b62e6b43564355e5222e4a3fb394cac0db101f2dd0d4f74", size = 193118695, upload-time = "2025-03-07T01:45:27.821Z" }, @@ -3563,9 +3567,9 @@ name = "nvidia-cusolver-cu12" version = "11.7.3.90" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cublas-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and sys_platform == 'linux'" }, - { name = "nvidia-cusparse-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and sys_platform == 'linux'" }, - { name = "nvidia-nvjitlink-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and sys_platform == 'linux'" }, + { name = "nvidia-cublas-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and platform_machine != 's390x' and sys_platform == 'linux'" }, + { name = "nvidia-cusparse-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and platform_machine != 's390x' and sys_platform == 'linux'" }, + { name = "nvidia-nvjitlink-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and platform_machine != 's390x' and sys_platform == 'linux'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/85/48/9a13d2975803e8cf2777d5ed57b87a0b6ca2cc795f9a4f59796a910bfb80/nvidia_cusolver_cu12-11.7.3.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:4376c11ad263152bd50ea295c05370360776f8c3427b30991df774f9fb26c450", size = 267506905, upload-time = "2025-03-07T01:47:16.273Z" }, @@ -3576,7 +3580,7 @@ name = "nvidia-cusparse-cu12" version = "12.5.8.93" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-nvjitlink-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and sys_platform == 'linux'" }, + { name = "nvidia-nvjitlink-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and platform_machine != 's390x' and sys_platform == 'linux'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/c2/f5/e1854cb2f2bcd4280c44736c93550cc300ff4b8c95ebe370d0aa7d2b473d/nvidia_cusparse_cu12-12.5.8.93-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1ec05d76bbbd8b61b06a80e1eaf8cf4959c3d4ce8e711b65ebd0443bb0ebb13b", size = 288216466, upload-time = "2025-03-07T01:48:13.779Z" }, @@ -4397,10 +4401,10 @@ name = "pyobjc-framework-applicationservices" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "sys_platform != 'emscripten' and sys_platform != 'linux'" }, - { name = "pyobjc-framework-cocoa", marker = "sys_platform != 'emscripten' and sys_platform != 'linux'" }, - { name = "pyobjc-framework-coretext", marker = "sys_platform != 'emscripten' and sys_platform != 'linux'" }, - { name = "pyobjc-framework-quartz", marker = "sys_platform != 'emscripten' and sys_platform != 'linux'" }, + { name = "pyobjc-core", marker = "(platform_machine != 's390x' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-framework-cocoa", marker = "(platform_machine != 's390x' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-framework-coretext", marker = "(platform_machine != 's390x' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-framework-quartz", marker = "(platform_machine != 's390x' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/be/6a/d4e613c8e926a5744fc47a9e9fea08384a510dc4f27d844f7ad7a2d793bd/pyobjc_framework_applicationservices-12.1.tar.gz", hash = "sha256:c06abb74f119bc27aeb41bf1aef8102c0ae1288aec1ac8665ea186a067a8945b", size = 103247, upload-time = "2025-11-14T10:08:52.18Z" } wheels = [ @@ -4416,7 +4420,7 @@ name = "pyobjc-framework-cocoa" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "sys_platform != 'emscripten' and sys_platform != 'linux'" }, + { name = "pyobjc-core", marker = "(platform_machine != 's390x' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/02/a3/16ca9a15e77c061a9250afbae2eae26f2e1579eb8ca9462ae2d2c71e1169/pyobjc_framework_cocoa-12.1.tar.gz", hash = "sha256:5556c87db95711b985d5efdaaf01c917ddd41d148b1e52a0c66b1a2e2c5c1640", size = 2772191, upload-time = "2025-11-14T10:13:02.069Z" } wheels = [ @@ -4432,9 +4436,9 @@ name = "pyobjc-framework-coretext" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "sys_platform != 'emscripten' and sys_platform != 'linux'" }, - { name = "pyobjc-framework-cocoa", marker = "sys_platform != 'emscripten' and sys_platform != 'linux'" }, - { name = "pyobjc-framework-quartz", marker = "sys_platform != 'emscripten' and sys_platform != 'linux'" }, + { name = "pyobjc-core", marker = "(platform_machine != 's390x' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-framework-cocoa", marker = "(platform_machine != 's390x' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-framework-quartz", marker = "(platform_machine != 's390x' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/29/da/682c9c92a39f713bd3c56e7375fa8f1b10ad558ecb075258ab6f1cdd4a6d/pyobjc_framework_coretext-12.1.tar.gz", hash = "sha256:e0adb717738fae395dc645c9e8a10bb5f6a4277e73cba8fa2a57f3b518e71da5", size = 90124, upload-time = "2025-11-14T10:14:38.596Z" } wheels = [ @@ -4450,8 +4454,8 @@ name = "pyobjc-framework-quartz" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "sys_platform != 'emscripten' and sys_platform != 'linux'" }, - { name = "pyobjc-framework-cocoa", marker = "sys_platform != 'emscripten' and sys_platform != 'linux'" }, + { name = "pyobjc-core", marker = "(platform_machine != 's390x' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-framework-cocoa", marker = "(platform_machine != 's390x' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/94/18/cc59f3d4355c9456fc945eae7fe8797003c4da99212dd531ad1b0de8a0c6/pyobjc_framework_quartz-12.1.tar.gz", hash = "sha256:27f782f3513ac88ec9b6c82d9767eef95a5cf4175ce88a1e5a65875fee799608", size = 3159099, upload-time = "2025-11-14T10:21:24.31Z" } wheels = [