diff --git a/.github/workflows/message-codegen.yml b/.github/workflows/message-codegen.yml new file mode 100644 index 00000000000..c86d4ea9ce1 --- /dev/null +++ b/.github/workflows/message-codegen.yml @@ -0,0 +1,41 @@ +name: message-codegen +# CI integration check for the CDR message codegen layer. It runs the one test +# file under dimos/message_codegen/ against the published dimos-cdrgen library, +# on Linux and macOS, in a clean virtualenv without the dimOS dev environment. + +on: + pull_request: + paths: + - dimos/message_codegen/** + - native/cpp/include/dimos/native/cdr_codec.hpp + - docs/development/message-source-packages.md + - pyproject.toml + - uv.lock + - .github/workflows/message-codegen.yml + workflow_dispatch: + +permissions: + contents: read + +jobs: + integration: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-14] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v7 + - uses: astral-sh/setup-uv@v10.0.1 + - name: Install published generator and consumer test tools + run: | + uv venv .venv --python 3.12 + uv pip install --python .venv/bin/python 'dimos-cdrgen==0.1.0' numpy build pytest pytest-asyncio pytest-env + - name: Verify SDK discovery and installed Python consumer without pip + run: | + .venv/bin/python -c 'import importlib.util; assert importlib.util.find_spec("pip") is None' + .venv/bin/python -m pytest --noconftest -o addopts='' -o 'markers=native_e2e: compiled native consumer acceptance' --strict-markers -m 'not native_e2e' -q dimos/message_codegen/test_integration.py + - name: Verify compiled C++ consumer + run: | + .venv/bin/python -m pytest --noconftest -o addopts='' -o 'markers=native_e2e: compiled native consumer acceptance' --strict-markers -m native_e2e -q dimos/message_codegen/test_integration.py + .venv/bin/python -c 'import importlib.util; assert importlib.util.find_spec("pip") is None; assert importlib.util.find_spec("catkin_pkg") is None' diff --git a/dimos/hardware/sensors/lidar/fastlio2/cpp/flake.lock b/dimos/hardware/sensors/lidar/fastlio2/cpp/flake.lock index c22b1b2c472..2040cc8f566 100644 --- a/dimos/hardware/sensors/lidar/fastlio2/cpp/flake.lock +++ b/dimos/hardware/sensors/lidar/fastlio2/cpp/flake.lock @@ -28,11 +28,11 @@ }, "locked": { "dir": "native/cpp", - "lastModified": 1791386052, - "narHash": "sha256-MeVxI5e13wh7jQ0g2tnaLpiyDaQQMfqEAC7qrXopHY4=", + "lastModified": 1792452883, + "narHash": "sha256-7HWaDC9KHTTpMr3bQTqAc6B7RuVq+dSrT58XWKM7hBc=", "owner": "dimensionalOS", "repo": "dimos", - "rev": "87c0c26b40e8a5aeb9d9d346104b49d5fb02696a", + "rev": "502b697763f8aef12f073900a948e66eeb4b8b1e", "type": "github" }, "original": { diff --git a/dimos/message_codegen/native_build.py b/dimos/message_codegen/native_build.py new file mode 100644 index 00000000000..71044c0636e --- /dev/null +++ b/dimos/message_codegen/native_build.py @@ -0,0 +1,35 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Add DimOS SDK discovery to the published CDR generator toolchain.""" + +from importlib.util import find_spec +import json +from pathlib import Path + +from dimos_cdrgen.native_build import write_cmake_toolchain as library_toolchain + + +def write_cmake_toolchain(prefix: Path, destination: Path) -> Path: + """Export the library toolchain and retain optional DimOS SDK discovery.""" + result = library_toolchain(prefix, destination) + spec = find_spec("dimos") + if spec is not None and spec.submodule_search_locations: + package = Path(next(iter(spec.submodule_search_locations))) + for sdk in [package / "_native/cpp", package.parent / "native/cpp"]: + if (sdk / "dimos_nativeConfig.cmake").is_file(): + with result.open("a") as output: + output.write("list(APPEND CMAKE_PREFIX_PATH " + json.dumps(str(sdk)) + ")\n") + break + return result diff --git a/dimos/message_codegen/test_integration.py b/dimos/message_codegen/test_integration.py new file mode 100644 index 00000000000..cbef553c448 --- /dev/null +++ b/dimos/message_codegen/test_integration.py @@ -0,0 +1,194 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Verify the DimOS adapter and one installed consumer of published cdrgen.""" + +import json +import os +from pathlib import Path +import subprocess +import sys +from types import SimpleNamespace + +from dimos_cdrgen.generate import generate +import pytest + +from dimos.message_codegen import native_build + + +def run(*command: str, cwd: Path) -> None: + subprocess.run(command, cwd=cwd, check=True, capture_output=True, text=True) + + +@pytest.mark.parametrize("layout", ["installed", "checkout", "absent"]) +def test_sdk_discovery(tmp_path: Path, monkeypatch: pytest.MonkeyPatch, layout: str) -> None: + prefix = tmp_path / "prefix" + prefix.mkdir() + (prefix / "native-prefixes.json").write_text(json.dumps([str(prefix)])) + (prefix / "native-target.json").write_text('{"values": {}, "toolchain_sha256": null}') + package = tmp_path / "dimos" + sdk = package / "_native/cpp" if layout == "installed" else tmp_path / "native/cpp" + if layout != "absent": + sdk.mkdir(parents=True) + (sdk / "dimos_nativeConfig.cmake").write_text("") + monkeypatch.setattr( + native_build, + "find_spec", + lambda _: SimpleNamespace(submodule_search_locations=[str(package)]), + ) + toolchain = native_build.write_cmake_toolchain(prefix, tmp_path / "toolchain.cmake") + text = toolchain.read_text() + assert str(prefix) in text + sdk_lines = [ + line for line in text.splitlines() if line.startswith("list(APPEND CMAKE_PREFIX_PATH") + ] + assert sdk_lines == ([] if layout == "absent" else [f'list(APPEND CMAKE_PREFIX_PATH "{sdk}")']) + + +def test_installed_message_consumer(tmp_path: Path) -> None: + project = tmp_path / "consumer" + source = project / "interfaces/consumer_msgs/msg/Tick.msg" + source.parent.mkdir(parents=True) + source.write_text("int32 value\n") + (project / "pyproject.toml").write_text("""[build-system] +requires = ["setuptools>=77", "wheel", "dimos-cdrgen==0.1.0"] +build-backend = "setuptools.build_meta" +[project] +name = "dimos-cdr-consumer" +version = "0.1.0" +dependencies = ["dimos-cdrgen==0.1.0"] +[tool.dimos.messages] +source = "interfaces" +""") + (project / "setup.py").write_text( + "from pathlib import Path\nfrom setuptools import setup\n" + "from dimos_cdrgen.source_package import setup_arguments\n" + "setup(**setup_arguments(Path(__file__).resolve().parent))\n" + ) + run(sys.executable, "-m", "build", "--no-isolation", cwd=project) + wheel = next((project / "dist").glob("*.whl")) + installed = tmp_path / "installed" + run( + "uv", + "pip", + "install", + "--python", + sys.executable, + "--no-deps", + "--target", + str(installed), + str(wheel), + cwd=tmp_path, + ) + run( + sys.executable, + "-I", + "-c", + f"""import sys +sys.path.insert(0, {str(installed)!r}) +import pickle +from dimos_cdr_consumer.consumer_msgs.msg import Tick +from dimos_cdrgen.registry import decode, encode +value = Tick(value=17) +assert encode(value) == bytes.fromhex("0001000011000000") +assert type(decode(encode(value), Tick)) is Tick +assert type(pickle.loads(pickle.dumps(value))) is Tick +assert decode(encode(value), Tick).value == 17 +""", + cwd=tmp_path, + ) + + +@pytest.fixture(scope="session") +def native_build_python(tmp_path_factory: pytest.TempPathFactory) -> Path: + # Native generator prerequisites are build tools, isolated from DimOS runtime deps. + # In particular, cdrgen0.1.0's PyYAML pin must not downgrade the runtime lock. + environment = tmp_path_factory.mktemp("cdr-native-toolchain") / "venv" + run("uv", "venv", "--python", sys.executable, str(environment), cwd=environment.parent) + python = environment / ("Scripts/python.exe" if os.name == "nt" else "bin/python") + offline_args = ("--offline",) if os.environ.get("DIMOS_OFFLINE") == "1" else () + run( + "uv", + "pip", + "install", + *offline_args, + "--python", + str(python), + "dimos-cdrgen[native]==0.1.0", + cwd=environment.parent, + ) + return python + + +@pytest.mark.native_e2e +def test_cpp_consumer_uses_dimos_header(tmp_path: Path, native_build_python: Path) -> None: + source = tmp_path / "interfaces/consumer_msgs/msg/Tick.msg" + source.parent.mkdir(parents=True) + source.write_text("int32 value\n") + generated = tmp_path / "generated" + generate( + [source.parents[2]], generated, ["consumer_msgs/msg/Tick"], "dimos_consumer", shared=True + ) + prefix_file = tmp_path / "native-prefix.txt" + run( + str(native_build_python), + "-c", + """import json +import os +from pathlib import Path +import sys +from dimos_cdrgen.native_build import prepare_cpp +sources = {name: Path(path) for name, path in json.loads(os.environ.get("DIMOS_NATIVE_SOURCE_DIRS", "{}")).items()} +prefix = prepare_cpp( + Path(sys.argv[1]), cache=Path(sys.argv[2]), + offline=os.environ.get("DIMOS_OFFLINE") == "1", source_dirs=sources or None, +) +Path(sys.argv[3]).write_text(str(prefix)) +""", + str(generated), + os.environ.get("DIMOS_NATIVE_TEST_CACHE", str(tmp_path / "native-cache")), + str(prefix_file), + cwd=tmp_path, + ) + prefix = Path(prefix_file.read_text()) + toolchain = native_build.write_cmake_toolchain(prefix, tmp_path / "toolchain.cmake") + include = Path(__file__).resolve().parents[2] / "native/cpp/include" + (tmp_path / "CMakeLists.txt").write_text(f'''cmake_minimum_required(VERSION 3.20) +project(dimos_cdr_consumer LANGUAGES CXX) +find_package(dimos_consumer CONFIG REQUIRED) +add_executable(consumer main.cpp) +target_compile_features(consumer PRIVATE cxx_std_17) +target_include_directories(consumer PRIVATE "{include}") +target_link_libraries(consumer PRIVATE dimos_consumer::messages) +''') + (tmp_path / "main.cpp").write_text("""#include +#include +#include +int main() { + const std::vector expected{0, 1, 0, 0, 17, 0, 0, 0}; + auto value = dimos::native::cdr_decode(expected); + return value.value == 17 && dimos::native::cdr_encode(value) == expected ? 0 : 1; +} +""") + run( + "cmake", + "-S", + str(tmp_path), + "-B", + str(tmp_path / "build"), + f"-DCMAKE_TOOLCHAIN_FILE={toolchain}", + cwd=tmp_path, + ) + run("cmake", "--build", str(tmp_path / "build"), "--parallel", "2", cwd=tmp_path) + run(str(tmp_path / "build/consumer"), cwd=tmp_path) diff --git a/dimos/simulation/habitat/nix/flake.lock b/dimos/simulation/habitat/nix/flake.lock index c13ac1a8111..eb23bbff5a6 100644 --- a/dimos/simulation/habitat/nix/flake.lock +++ b/dimos/simulation/habitat/nix/flake.lock @@ -11,11 +11,11 @@ }, "locked": { "dir": "native/cpp", - "lastModified": 1791386052, - "narHash": "sha256-MeVxI5e13wh7jQ0g2tnaLpiyDaQQMfqEAC7qrXopHY4=", + "lastModified": 1792452883, + "narHash": "sha256-7HWaDC9KHTTpMr3bQTqAc6B7RuVq+dSrT58XWKM7hBc=", "owner": "dimensionalOS", "repo": "dimos", - "rev": "87c0c26b40e8a5aeb9d9d346104b49d5fb02696a", + "rev": "502b697763f8aef12f073900a948e66eeb4b8b1e", "type": "github" }, "original": { diff --git a/docs/development/message-source-packages.md b/docs/development/message-source-packages.md new file mode 100644 index 00000000000..6d20d3f04ae --- /dev/null +++ b/docs/development/message-source-packages.md @@ -0,0 +1,58 @@ +# CDR generation in dimOS + +> **WIP: CDR migration.** This page documents the generator integration in +> [the first stack layer (#4247)](https://github.com/dimensionalOS/dimos/pull/4247), +> not a complete CDR message/runtime workflow on `main`. The generator dependency, +> dimOS adapters and verification commands below are implemented in this layer. +> Built-in message packaging depends on +> [the second layer (#4366)](https://github.com/dimensionalOS/dimos/pull/4366); +> the runtime encoding switch and CDR recording/viewer flows belong to later layers. +> Installing this layer alone does not switch the existing dimOS runtime to CDR. + +dimOS uses the published `dimos-cdrgen==0.1.0` package directly. Its parser, +generators, ownership checks, codecs and native build recipes live in the +[independent library](https://github.com/TomCC7/dimos-cdrgen). +See its [Python, C++ and Rust guides](https://tomcc7.github.io/dimos-cdrgen/) +for message package configuration and supported schema features. + +Install `dimos-cdrgen==0.1.0` in both the build and runtime dependencies of +message packages. Import its APIs directly: + +```python +from dimos_cdrgen.registry import decode, encode +from dimos_cdrgen.source_package import setup_arguments +``` + +There is no dimOS compatibility distribution. Existing consumers of +`dimos_message_build` or generic `dimos.message_codegen` APIs must change their +imports and dependency declarations to `dimos_cdrgen` and `dimos-cdrgen`. + +dimOS retains two adapters: + +- `dimos.message_codegen.native_build.write_cmake_toolchain` adds SDK discovery + for installed `dimos/_native/cpp` and source-checkout `native/cpp` layouts. + Import other build functions directly from `dimos_cdrgen.native_build`. +- `dimos/native/cdr_codec.hpp` exposes the library codec under `dimos::native` + for dimOS C++ consumers. + +This first stack layer does not switch runtime transports or supply built-in +message catalogs. Those remain separate PRs. + +## Verify the integration + +Use a Python environment with the published generator and test tools: + +```sh +uv pip install 'dimos-cdrgen[native]==0.1.0' numpy build pytest pytest-asyncio pytest-env +python -m pytest --noconftest -o addopts='' \ + -o 'markers=native_e2e: compiled native consumer acceptance' \ + -q dimos/message_codegen/test_integration.py +``` + +The tests check SDK discovery, an installed message wheel built from a source +distribution, Python type identity and the dimOS C++ header against literal CDR +bytes. Native verification needs CMake and a C++17 compiler. It prepares pinned +native dependencies in a temporary cache; use `DIMOS_NATIVE_TEST_CACHE` to reuse +a writable cache, or `DIMOS_NATIVE_SOURCE_DIRS` with `DIMOS_OFFLINE=1` for +pre-fetched source directories. Generic generator regression tests stay in the +library repository. diff --git a/examples/native-modules/cpp/flake.lock b/examples/native-modules/cpp/flake.lock index 9a9ad728e16..dbb19175ad5 100644 --- a/examples/native-modules/cpp/flake.lock +++ b/examples/native-modules/cpp/flake.lock @@ -28,11 +28,11 @@ }, "locked": { "dir": "native/cpp", - "lastModified": 1791386052, - "narHash": "sha256-MeVxI5e13wh7jQ0g2tnaLpiyDaQQMfqEAC7qrXopHY4=", + "lastModified": 1792452883, + "narHash": "sha256-7HWaDC9KHTTpMr3bQTqAc6B7RuVq+dSrT58XWKM7hBc=", "owner": "dimensionalOS", "repo": "dimos", - "rev": "87c0c26b40e8a5aeb9d9d346104b49d5fb02696a", + "rev": "502b697763f8aef12f073900a948e66eeb4b8b1e", "type": "github" }, "original": { diff --git a/native/cpp/include/dimos/native/cdr_codec.hpp b/native/cpp/include/dimos/native/cdr_codec.hpp new file mode 100644 index 00000000000..373034d9327 --- /dev/null +++ b/native/cpp/include/dimos/native/cdr_codec.hpp @@ -0,0 +1,11 @@ +// Copyright 2026 Dimensional Inc. +// SPDX-License-Identifier: Apache-2.0 +#pragma once + +#include + +namespace dimos::native { +using dimos::cdr::cdr_callbacks; +using dimos::cdr::cdr_encode; +using dimos::cdr::cdr_decode; +} // namespace dimos::native diff --git a/pyproject.toml b/pyproject.toml index 05c7a8a2431..dd1fda7677f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -426,6 +426,8 @@ project-deps = [ ] tests = [ + "dimos-cdrgen==0.1.0", + "build>=1.2.2", # Test runner "pytest==8.3.5", "pytest-asyncio==1.4.0", @@ -483,6 +485,7 @@ browser-tests = [ # Lint / format / type-check tooling for the dedicated `lint` CI job. lint = [ + "dimos-cdrgen==0.1.0", # Lint / format / type-check "ruff==0.14.3", "mypy==1.19.0", @@ -537,7 +540,7 @@ dev = [ required-version = ">=0.9.25" default-groups = ["tests"] exclude-newer = "7 days" -exclude-newer-package = { dimos-viewer = false, dimos-lcm = false, lcm = false, roboplan = false, md-babel-py = false, can-motor-control = false, edgetam-dimos = false, dim-odom = false, eclipse-zenoh = false } +exclude-newer-package = { dimos-cdrgen = false, dimos-viewer = false, dimos-lcm = false, lcm = false, roboplan = false, md-babel-py = false, can-motor-control = false, edgetam-dimos = false, dim-odom = false, eclipse-zenoh = false } constraint-dependencies = [ # TODO(PY311): drop this fork. onnxruntime(-gpu) 1.24 dropped cp310 # wheels, so 3.10 environments resolve 1.23.x (matching what a 3.10 diff --git a/uv.lock b/uv.lock index 220d8482b56..199d9a88263 100644 --- a/uv.lock +++ b/uv.lock @@ -36,14 +36,15 @@ exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for exclude-newer-span = "P7D" [options.exclude-newer-package] -dimos-viewer = false +can-motor-control = false +dim-odom = false +dimos-cdrgen = false dimos-lcm = false -lcm = false -edgetam-dimos = false +dimos-viewer = false eclipse-zenoh = false -can-motor-control = false +edgetam-dimos = false +lcm = false md-babel-py = false -dim-odom = false roboplan = false [manifest] @@ -2326,6 +2327,7 @@ lint = [ { name = "chromadb" }, { name = "deptry" }, { name = "dimos", extra = ["visualization", "web", "webrtc"] }, + { name = "dimos-cdrgen" }, { name = "einops" }, { name = "gdown" }, { name = "googlemaps" }, @@ -2394,12 +2396,14 @@ project-deps = [ { name = "xacro" }, ] tests = [ + { name = "build" }, { name = "can-motor-control" }, { name = "chromadb" }, { name = "click" }, { name = "coacd" }, { name = "coverage" }, { name = "dimos", extra = ["apriltag", "cpu", "drone", "learning", "mapping", "visualization", "web", "webrtc"] }, + { name = "dimos-cdrgen" }, { name = "einops" }, { name = "gdown" }, { name = "googlemaps" }, @@ -2450,6 +2454,7 @@ tests = [ { name = "xacro" }, ] tests-self-hosted = [ + { name = "build" }, { name = "can-motor-control" }, { name = "chromadb" }, { name = "click" }, @@ -2457,6 +2462,7 @@ tests-self-hosted = [ { name = "coverage" }, { name = "dim-odom" }, { name = "dimos", extra = ["apriltag", "cpu", "drone", "learning", "manipulation", "mapping", "misc", "unitree", "visualization", "web", "webrtc"] }, + { name = "dimos-cdrgen" }, { name = "einops" }, { name = "gdown" }, { name = "googlemaps" }, @@ -2681,6 +2687,7 @@ lint = [ { name = "chromadb", specifier = ">=1.0.0" }, { name = "deptry", specifier = "==0.25.1" }, { name = "dimos", extras = ["web", "visualization", "webrtc"] }, + { name = "dimos-cdrgen", specifier = "==0.1.0" }, { name = "einops", specifier = ">=0.8.1" }, { name = "gdown", specifier = "==6.0.0" }, { name = "googlemaps", specifier = ">=4.10.0" }, @@ -2748,6 +2755,7 @@ project-deps = [ { name = "xacro" }, ] tests = [ + { name = "build", specifier = ">=1.2.2" }, { name = "can-motor-control", specifier = ">=0.0.8" }, { name = "chromadb", specifier = ">=1.0.0" }, { name = "click", specifier = ">=8.3" }, @@ -2755,6 +2763,7 @@ tests = [ { name = "coverage", specifier = ">=7.0" }, { name = "dimos", extras = ["apriltag", "mapping", "drone", "cpu", "learning"] }, { name = "dimos", extras = ["web", "visualization", "webrtc"] }, + { name = "dimos-cdrgen", specifier = "==0.1.0" }, { name = "einops", specifier = ">=0.8.1" }, { name = "gdown", specifier = "==6.0.0" }, { name = "googlemaps", specifier = ">=4.10.0" }, @@ -2805,6 +2814,7 @@ tests = [ { name = "xacro" }, ] tests-self-hosted = [ + { name = "build", specifier = ">=1.2.2" }, { name = "can-motor-control", specifier = ">=0.0.8" }, { name = "chromadb", specifier = ">=1.0.0" }, { name = "click", specifier = ">=8.3" }, @@ -2814,6 +2824,7 @@ tests-self-hosted = [ { name = "dimos", extras = ["apriltag", "mapping", "drone", "cpu", "learning"] }, { name = "dimos", extras = ["manipulation", "misc", "unitree"] }, { name = "dimos", extras = ["web", "visualization", "webrtc"] }, + { name = "dimos-cdrgen", specifier = "==0.1.0" }, { name = "einops", specifier = ">=0.8.1" }, { name = "gdown", specifier = "==6.0.0" }, { name = "googlemaps", specifier = ">=4.10.0" }, @@ -2866,6 +2877,23 @@ tests-self-hosted = [ { name = "xacro" }, ] +[[package]] +name = "dimos-cdrgen" +version = "0.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "empy" }, + { name = "lark" }, + { name = "rosbags" }, + { name = "setuptools" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "wheel" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/1a/31327fa4bb2a240783d0b41e315be2a4485eabf07ab032f49c6328f5f51b/dimos_cdrgen-0.1.0.tar.gz", hash = "sha256:69ea4955e64a769d56d4bd5e0fff44c98f96c29c5608125cd011cef2740624f0", size = 75010, upload-time = "2026-10-15T05:00:09.663Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a3/9c/086701c3249ed2caabe83cea008c3e08bd6063c48a1df852fbca6aadff50/dimos_cdrgen-0.1.0-py3-none-any.whl", hash = "sha256:6731e8900f7e61af419b8c77599587f32677c9d64f27ac15f5e78be4b76bc011", size = 70183, upload-time = "2026-10-15T05:00:08.098Z" }, +] + [[package]] name = "dimos-lcm" version = "0.1.6" @@ -3092,6 +3120,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b5/96/625e035f3433071c91de07e66265a261be7bb708367f785000f93d7a992a/embreex-4.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:6c092ee1adf5c48b7430c7ae3902943863745e54b4aef4327ecb3473e0a299d7", size = 13119305, upload-time = "2026-04-22T19:46:59.329Z" }, ] +[[package]] +name = "empy" +version = "4.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c1/0a/c500fc4c8f48cac08b76b8987070b178f0549534584ac1f414066700a3f9/empy-4.2.tar.gz", hash = "sha256:86f15e1da9743e79a2e9b2cbacf1a13d0b7fb1835b6254eb253c978b72287f4f", size = 166069, upload-time = "2024-08-25T23:32:09.946Z" } + [[package]] name = "etils" version = "1.13.0" @@ -4961,6 +4995,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d9/8d/00df0c44b728119fe770e0526f850b0a9201f23bf4276568aef5b372982e/lap-0.5.12-cp312-cp312-win_arm64.whl", hash = "sha256:83e507f6def40244da3e03c71f1b1f54ceab3978cde72a84b84caadd8728977e", size = 1466243, upload-time = "2024-11-30T01:26:43.202Z" }, ] +[[package]] +name = "lark" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/af/60/bc7622aefb2aee1c0b4ba23c1446d3e30225c8770b38d7aedbfb65ca9d5a/lark-1.2.2.tar.gz", hash = "sha256:ca807d0162cd16cef15a8feecb862d7319e7a09bdb13aef927968e45040fed80", size = 252132, upload-time = "2024-08-13T19:49:00.652Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/00/d90b10b962b4277f5e64a78b6609968859ff86889f5b898c1a778c06ec00/lark-1.2.2-py3-none-any.whl", hash = "sha256:c2276486b02f0f1b90be155f2c8ba4a8e194d42775786db622faccd652d8e80c", size = 111036, upload-time = "2024-08-13T19:48:58.603Z" }, +] + [[package]] name = "lazy-loader" version = "0.5" @@ -9303,6 +9346,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/75/35/130469d1901da2b3a5a377539b4ffcd8a5c983f1c9e3ba5ffdd8d71ae314/rope-1.14.0-py3-none-any.whl", hash = "sha256:00a7ea8c0c376fc0b053b2f2f8ef3bfb8b50fecf1ebf3eb80e4f8bd7f1941918", size = 207143, upload-time = "2025-07-12T17:46:05.928Z" }, ] +[[package]] +name = "rosbags" +version = "0.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "lz4" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "ruamel-yaml" }, + { name = "typing-extensions" }, + { name = "zstandard" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f3/2f/b6d11cc9fac4003b284e2c152b5c34ca5b6d26caf5f6979118e2d588a0d7/rosbags-0.11.0.tar.gz", hash = "sha256:e73bbe79a15d7f539653375278ffca6c48e56b5c2ada4a4531de0b17737cbc46", size = 254438, upload-time = "2025-10-15T09:49:54.453Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/13/75/b66d992a87539cd9e0070bca6ba49694b9258a4f9bc905d0576354d7864a/rosbags-0.11.0-py3-none-any.whl", hash = "sha256:2ce27d8dc37f554f10bf5962f665331ce16f43aba304c6c233eb15fab05b61ab", size = 137920, upload-time = "2025-10-15T09:49:50.329Z" }, +] + [[package]] name = "rpds-py" version = "0.30.0" @@ -9383,6 +9443,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3f/50/0a9e7e7afe7339bd5e36911f0ceb15fed51945836ed803ae5afd661057fd/rtree-1.4.1-py3-none-win_arm64.whl", hash = "sha256:3d46f55729b28138e897ffef32f7ce93ac335cb67f9120125ad3742a220800f0", size = 355253, upload-time = "2025-08-13T19:32:00.296Z" }, ] +[[package]] +name = "ruamel-yaml" +version = "0.19.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/3b/ebda527b56beb90cb7652cb1c7e4f91f48649fbcd8d2eb2fb6e77cd3329b/ruamel_yaml-0.19.1.tar.gz", hash = "sha256:53eb66cd27849eff968ebf8f0bf61f46cdac2da1d1f3576dd4ccee9b25c31993", size = 142709, upload-time = "2026-01-02T16:50:31.84Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b8/0c/51f6841f1d84f404f92463fc2b1ba0da357ca1e3db6b7fbda26956c3b82a/ruamel_yaml-0.19.1-py3-none-any.whl", hash = "sha256:27592957fedf6e0b62f281e96effd28043345e0e66001f97683aa9a40c667c93", size = 118102, upload-time = "2026-01-02T16:50:29.201Z" }, +] + [[package]] name = "ruff" version = "0.14.3" @@ -11360,6 +11429,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8e/93/af1d6ccb69ab6b5a00e03fa0cefa563f9862412667776ea15dd4eece3a90/whatthepatch-1.0.7-py3-none-any.whl", hash = "sha256:1b6f655fd31091c001c209529dfaabbabdbad438f5de14e3951266ea0fc6e7ed", size = 11964, upload-time = "2024-11-16T17:21:20.761Z" }, ] +[[package]] +name = "wheel" +version = "0.48.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d0/20/50ed6bdf27dec98b568a8ae25dc599f35baa3d9709f9e83fd1edb56b9a90/wheel-0.48.0.tar.gz", hash = "sha256:94800765601e9171bf5d58d066e640662842bcedcbab982b2c90787a2c987322", size = 66471, upload-time = "2026-08-11T22:02:27.327Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2e/29/69cfbb602cd91690c55d38ba9fe53e6a7e76a6fa647bf38f19c138d25449/wheel-0.48.0-py3-none-any.whl", hash = "sha256:3217dcc807155e45db462d7ef2431f5ddda0d7273b700d05a67b271ceb1287ab", size = 33320, upload-time = "2026-08-11T22:02:26.1Z" }, +] + [[package]] name = "winrt-runtime" version = "3.2.1"