From 4fb3da761f77d3c996d638e90c38c8dbae1a67e8 Mon Sep 17 00:00:00 2001 From: "IQ.Lvbs CI [bot]" Date: Wed, 2 Sep 2026 15:53:36 -0500 Subject: [PATCH] IQ.Pilot Release Commit @ 717ce45 --- .../package_sources/iqdbc/pyproject.toml | 2 +- artifacts/package_sources/iqdbc/uv.lock | 146 +++++++++--------- iqpilot/cereal/messaging/messaging.h | 3 + iqpilot/cereal/messaging/socketmaster.cc | 10 +- iqpilot/cereal/services.py | 18 +++ iqpilot/selfdrive/iqlocd/atlas_loc_core.cc | 7 + iqpilot/selfdrive/iqlocd/tests/test_iqlocd.py | 13 +- iqpilot/system/manager/build.py | 55 ++++++- .../manager/test/test_services_registry.py | 45 ++++++ pyproject.toml | 8 +- uv.lock | 18 +-- 11 files changed, 230 insertions(+), 95 deletions(-) create mode 100644 iqpilot/system/manager/test/test_services_registry.py diff --git a/artifacts/package_sources/iqdbc/pyproject.toml b/artifacts/package_sources/iqdbc/pyproject.toml index c7d96b5ec..a1ef7bf27 100644 --- a/artifacts/package_sources/iqdbc/pyproject.toml +++ b/artifacts/package_sources/iqdbc/pyproject.toml @@ -28,7 +28,7 @@ testing = [ "pytest-mock", "pytest-randomly", # https://github.com/pytest-dev/pytest-xdist/pull/1229 - "pytest-xdist @ git+https://github.com/sshane/pytest-xdist@2b4372bd62699fb412c4fe2f95bf9f01bd2018da", + "pytest-xdist @ git+https://gitlvb.teallvbs.xyz/IQ.Lvbs/pytest-xdist.git@23461ed23bebd37e16e9fc9563a65c1655ba76f0", "pytest-subtests", "hypothesis==6.47.*", "parameterized>=0.8,<0.9", diff --git a/artifacts/package_sources/iqdbc/uv.lock b/artifacts/package_sources/iqdbc/uv.lock index 381b264d6..1ef50d998 100644 --- a/artifacts/package_sources/iqdbc/uv.lock +++ b/artifacts/package_sources/iqdbc/uv.lock @@ -346,6 +346,78 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d0/94/040a0d9c81f018c39bd887b7b825013b024deb0a6c795f9524797e2cd41b/inputs-0.5-py2.py3-none-any.whl", hash = "sha256:13f894564e52134cf1e3862b1811da034875eb1f2b62e6021e3776e9669a96ec", size = 33630, upload-time = "2018-10-05T22:38:28.28Z" }, ] +[[package]] +name = "iqdbc" +version = "0.2.1" +source = { editable = "." } +dependencies = [ + { name = "crcmod-plus" }, + { name = "numpy" }, + { name = "pycapnp" }, + { name = "pycryptodome" }, + { name = "scons" }, + { name = "tqdm" }, +] + +[package.optional-dependencies] +docs = [ + { name = "jinja2" }, +] +examples = [ + { name = "inputs" }, + { name = "matplotlib" }, +] +testing = [ + { name = "cffi" }, + { name = "codespell" }, + { name = "comma-car-segments" }, + { name = "cpplint" }, + { name = "gcovr" }, + { name = "hypothesis" }, + { name = "lefthook" }, + { name = "parameterized" }, + { name = "pytest" }, + { name = "pytest-coverage" }, + { name = "pytest-mock" }, + { name = "pytest-randomly" }, + { name = "pytest-subtests" }, + { name = "pytest-xdist" }, + { name = "ruff" }, + { name = "ty" }, + { name = "zstandard" }, +] + +[package.metadata] +requires-dist = [ + { name = "cffi", marker = "extra == 'testing'" }, + { name = "codespell", marker = "extra == 'testing'" }, + { name = "comma-car-segments", marker = "extra == 'testing'", url = "https://huggingface.co/datasets/commaai/commaCarSegments/resolve/main/dist/comma_car_segments-0.1.0-py3-none-any.whl" }, + { name = "cpplint", marker = "extra == 'testing'" }, + { name = "crcmod-plus" }, + { name = "gcovr", marker = "extra == 'testing'" }, + { name = "hypothesis", marker = "extra == 'testing'", specifier = "==6.47.*" }, + { name = "inputs", marker = "extra == 'examples'" }, + { name = "jinja2", marker = "extra == 'docs'" }, + { name = "lefthook", marker = "extra == 'testing'" }, + { name = "matplotlib", marker = "extra == 'examples'" }, + { name = "numpy" }, + { name = "parameterized", marker = "extra == 'testing'", specifier = ">=0.8,<0.9" }, + { name = "pycapnp", specifier = "==2.1.0" }, + { name = "pycryptodome" }, + { name = "pytest", marker = "extra == 'testing'", specifier = "==8.4.2" }, + { name = "pytest-coverage", marker = "extra == 'testing'" }, + { name = "pytest-mock", marker = "extra == 'testing'" }, + { name = "pytest-randomly", marker = "extra == 'testing'" }, + { name = "pytest-subtests", marker = "extra == 'testing'" }, + { name = "pytest-xdist", marker = "extra == 'testing'", git = "https://gitlvb.teallvbs.xyz/IQ.Lvbs/pytest-xdist.git?rev=23461ed23bebd37e16e9fc9563a65c1655ba76f0" }, + { name = "ruff", marker = "extra == 'testing'" }, + { name = "scons" }, + { name = "tqdm" }, + { name = "ty", marker = "extra == 'testing'" }, + { name = "zstandard", marker = "extra == 'testing'" }, +] +provides-extras = ["testing", "docs", "examples"] + [[package]] name = "jinja2" version = "3.1.6" @@ -557,78 +629,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/de/e5/b7d20451657664b07986c2f6e3be564433f5dcaf3482d68eaecd79afaf03/numpy-2.4.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:be71bf1edb48ebbbf7f6337b5bfd2f895d1902f6335a5830b20141fc126ffba0", size = 12502577, upload-time = "2026-01-31T23:13:07.08Z" }, ] -[[package]] -name = "iqdbc" -version = "0.2.1" -source = { editable = "." } -dependencies = [ - { name = "crcmod-plus" }, - { name = "numpy" }, - { name = "pycapnp" }, - { name = "pycryptodome" }, - { name = "scons" }, - { name = "tqdm" }, -] - -[package.optional-dependencies] -docs = [ - { name = "jinja2" }, -] -examples = [ - { name = "inputs" }, - { name = "matplotlib" }, -] -testing = [ - { name = "cffi" }, - { name = "codespell" }, - { name = "comma-car-segments" }, - { name = "cpplint" }, - { name = "gcovr" }, - { name = "hypothesis" }, - { name = "lefthook" }, - { name = "parameterized" }, - { name = "pytest" }, - { name = "pytest-coverage" }, - { name = "pytest-mock" }, - { name = "pytest-randomly" }, - { name = "pytest-subtests" }, - { name = "pytest-xdist" }, - { name = "ruff" }, - { name = "ty" }, - { name = "zstandard" }, -] - -[package.metadata] -requires-dist = [ - { name = "cffi", marker = "extra == 'testing'" }, - { name = "codespell", marker = "extra == 'testing'" }, - { name = "comma-car-segments", marker = "extra == 'testing'", url = "https://huggingface.co/datasets/commaai/commaCarSegments/resolve/main/dist/comma_car_segments-0.1.0-py3-none-any.whl" }, - { name = "cpplint", marker = "extra == 'testing'" }, - { name = "crcmod-plus" }, - { name = "gcovr", marker = "extra == 'testing'" }, - { name = "hypothesis", marker = "extra == 'testing'", specifier = "==6.47.*" }, - { name = "inputs", marker = "extra == 'examples'" }, - { name = "jinja2", marker = "extra == 'docs'" }, - { name = "lefthook", marker = "extra == 'testing'" }, - { name = "matplotlib", marker = "extra == 'examples'" }, - { name = "numpy" }, - { name = "parameterized", marker = "extra == 'testing'", specifier = ">=0.8,<0.9" }, - { name = "pycapnp", specifier = "==2.1.0" }, - { name = "pycryptodome" }, - { name = "pytest", marker = "extra == 'testing'", specifier = "==8.4.2" }, - { name = "pytest-coverage", marker = "extra == 'testing'" }, - { name = "pytest-mock", marker = "extra == 'testing'" }, - { name = "pytest-randomly", marker = "extra == 'testing'" }, - { name = "pytest-subtests", marker = "extra == 'testing'" }, - { name = "pytest-xdist", marker = "extra == 'testing'", git = "https://github.com/sshane/pytest-xdist?rev=2b4372bd62699fb412c4fe2f95bf9f01bd2018da" }, - { name = "ruff", marker = "extra == 'testing'" }, - { name = "scons" }, - { name = "tqdm" }, - { name = "ty", marker = "extra == 'testing'" }, - { name = "zstandard", marker = "extra == 'testing'" }, -] -provides-extras = ["testing", "docs", "examples"] - [[package]] name = "packaging" version = "26.0" @@ -865,7 +865,7 @@ wheels = [ [[package]] name = "pytest-xdist" version = "3.7.1.dev24+g2b4372bd6" -source = { git = "https://github.com/sshane/pytest-xdist?rev=2b4372bd62699fb412c4fe2f95bf9f01bd2018da#2b4372bd62699fb412c4fe2f95bf9f01bd2018da" } +source = { git = "https://gitlvb.teallvbs.xyz/IQ.Lvbs/pytest-xdist.git?rev=23461ed23bebd37e16e9fc9563a65c1655ba76f0#23461ed23bebd37e16e9fc9563a65c1655ba76f0" } dependencies = [ { name = "execnet" }, { name = "pytest" }, diff --git a/iqpilot/cereal/messaging/messaging.h b/iqpilot/cereal/messaging/messaging.h index fb9c261f2..ed9ac2bbd 100644 --- a/iqpilot/cereal/messaging/messaging.h +++ b/iqpilot/cereal/messaging/messaging.h @@ -12,6 +12,9 @@ #include "common/timing.h" #include "msgq/ipc.h" +const char *messaging_registry_tag(); +bool messaging_has_service(const char *name); + class SubMaster { public: SubMaster(const std::vector &service_list, const std::vector &poll = {}, diff --git a/iqpilot/cereal/messaging/socketmaster.cc b/iqpilot/cereal/messaging/socketmaster.cc index 50915472c..97fe09643 100644 --- a/iqpilot/cereal/messaging/socketmaster.cc +++ b/iqpilot/cereal/messaging/socketmaster.cc @@ -49,7 +49,7 @@ SubMaster::SubMaster(const std::vector &service_list, const std::v poller_ = Poller::create(); for (auto name : service_list) { if (services.count(std::string(name)) == 0) { - fprintf(stderr, "SubMaster: unknown service '%s', skipping subscription\n", name); + fprintf(stderr, "SubMaster: unknown service '%s' in %s, skipping subscription\n", name, SERVICES_REGISTRY_TAG); continue; } @@ -71,6 +71,14 @@ SubMaster::SubMaster(const std::vector &service_list, const std::v } } +const char *messaging_registry_tag() { + return SERVICES_REGISTRY_TAG; +} + +bool messaging_has_service(const char *name) { + return services.count(std::string(name)) != 0; +} + void SubMaster::update(int timeout) { for (auto &kv : messages_) kv.second->updated = false; diff --git a/iqpilot/cereal/services.py b/iqpilot/cereal/services.py index 4bca8a3e4..d5ff68dff 100755 --- a/iqpilot/cereal/services.py +++ b/iqpilot/cereal/services.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +import hashlib from enum import IntEnum from typing import Optional @@ -134,6 +135,22 @@ SERVICE_LIST = {name: Service(*vals) for idx, (name, vals) in enumerate(_services.items())} +REGISTRY_TAG_PREFIX = "IQ_SERVICES_REGISTRY:" + + +def registry_hash() -> str: + digest = hashlib.sha256() + for name in sorted(SERVICE_LIST): + v = SERVICE_LIST[name] + decimation = -1 if v.decimation is None else v.decimation + digest.update(f"{name}|{int(v.should_log)}|{v.frequency:f}|{decimation}|{int(v.queue_size)}\n".encode()) + return digest.hexdigest()[:16] + + +def registry_tag() -> str: + return REGISTRY_TAG_PREFIX + registry_hash() + + def build_header(): h = "" h += "/* THIS IS AN AUTOGENERATED FILE, PLEASE EDIT services.py */\n" @@ -151,6 +168,7 @@ def build_header(): h += ' { "%s", {"%s", %s, %f, %d, %d}},\n' % \ (k, k, should_log, v.frequency, decimation, v.queue_size) h += "};\n" + h += f'static const char SERVICES_REGISTRY_TAG[] = "{registry_tag()}";\n' h += "#endif\n" return h diff --git a/iqpilot/selfdrive/iqlocd/atlas_loc_core.cc b/iqpilot/selfdrive/iqlocd/atlas_loc_core.cc index 16b22a591..a315f17f5 100644 --- a/iqpilot/selfdrive/iqlocd/atlas_loc_core.cc +++ b/iqpilot/selfdrive/iqlocd/atlas_loc_core.cc @@ -734,6 +734,13 @@ int AtlasLocator::run() { const std::initializer_list service_list = {gps_location_socket, "cameraOdometry", "extrinsicsCalibration", "carState", "accelerometer", "gyroscope"}; + for (const char *service : service_list) { + if (!messaging_has_service(service)) { + LOGE("service '%s' is missing from the compiled service registry %s: stale build, rebuild required", service, messaging_registry_tag()); + return 2; + } + } + SubMaster sm(service_list, {}, nullptr, {gps_location_socket}); PubMaster pm({"iqLiveLocation"}); diff --git a/iqpilot/selfdrive/iqlocd/tests/test_iqlocd.py b/iqpilot/selfdrive/iqlocd/tests/test_iqlocd.py index b84b26da8..a9362a3f1 100644 --- a/iqpilot/selfdrive/iqlocd/tests/test_iqlocd.py +++ b/iqpilot/selfdrive/iqlocd/tests/test_iqlocd.py @@ -128,12 +128,13 @@ class TestIQLocdProc: if case in ("odometry_short", "odometry_empty", "odometry_nan", "odometry_nan_std"): msg = messaging.new_message("cameraOdometry") odo = msg.cameraOdometry - if case == "odometry_short": - odo.rot = [0.0] * 6; odo.trans = [0.0] * 6; odo.rotStd = [0.01] * 6; odo.transStd = [0.01] * 6 - elif case == "odometry_nan": - odo.rot = [float("nan"), 0.0, 0.0]; odo.trans = [0.0] * 3; odo.rotStd = [0.01] * 3; odo.transStd = [0.01] * 3 - elif case == "odometry_nan_std": - odo.rot = [0.0] * 3; odo.trans = [0.0] * 3; odo.rotStd = [float("nan"), 0.01, 0.01]; odo.transStd = [0.01] * 3 + shapes = { + "odometry_short": ([0.0] * 6, [0.0] * 6, [0.01] * 6, [0.01] * 6), + "odometry_nan": ([float("nan"), 0.0, 0.0], [0.0] * 3, [0.01] * 3, [0.01] * 3), + "odometry_nan_std": ([0.0] * 3, [0.0] * 3, [float("nan"), 0.01, 0.01], [0.01] * 3), + } + if case in shapes: + odo.rot, odo.trans, odo.rotStd, odo.transStd = shapes[case] elif case in ("calibration_short", "calibration_nan"): msg = messaging.new_message("extrinsicsCalibration") msg.extrinsicsCalibration.calStatus = "calibrated" diff --git a/iqpilot/system/manager/build.py b/iqpilot/system/manager/build.py index f05a87a22..ab624862d 100755 --- a/iqpilot/system/manager/build.py +++ b/iqpilot/system/manager/build.py @@ -51,7 +51,44 @@ class _SilentProgress: pass -def build(spinner, dirty: bool = False, minimal: bool = False, show_error_window: bool = True) -> None: +REGISTRY_ARTIFACTS = [ + "iqpilot/cereal/services.h", + "iqpilot/cereal/messaging/socketmaster.o", + "iqpilot/cereal/libsocketmaster.a", + "iqpilot/cereal/messaging/bridge", + "iqpilot/selfdrive/iqlocd/iqlocd", + "iqpilot/selfdrive/pandad/pandad", + "iqpilot/system/camerad/camerad", + "iqpilot/system/loggerd/loggerd", + "iqpilot/system/loggerd/encoderd", + "iqpilot/system/loggerd/bootlog", +] + + +def stale_registry_artifacts(basedir: str = BASEDIR) -> list[str]: + from iqpilot.cereal.services import REGISTRY_TAG_PREFIX, registry_tag + expected = registry_tag().encode() + prefix = REGISTRY_TAG_PREFIX.encode() + stale = [] + for rel in REGISTRY_ARTIFACTS: + path = os.path.join(basedir, rel) + if not os.path.isfile(path): + continue + with open(path, "rb") as f: + data = f.read() + if prefix in data and expected not in data: + stale.append(rel) + return stale + + +def purge_registry_artifacts(stale: list[str], basedir: str = BASEDIR) -> None: + for rel in set(stale) | set(REGISTRY_ARTIFACTS[:3]): + path = os.path.join(basedir, rel) + if os.path.isfile(path): + os.remove(path) + + +def build(spinner, dirty: bool = False, minimal: bool = False, show_error_window: bool = True, registry_retry: bool = False) -> None: env = os.environ.copy() env.pop('PWD', None) env['SCONS_PROGRESS'] = "1" @@ -110,6 +147,22 @@ def build(spinner, dirty: bool = False, minimal: bool = False, show_error_window t.wait_for_exit() exit(1) + stale = stale_registry_artifacts() + if stale and not registry_retry: + cloudlog.error(f"compiled service registry is stale in {', '.join(stale)}, rebuilding messaging") + purge_registry_artifacts(stale) + build(spinner, dirty, minimal, show_error_window, registry_retry=True) + return + if stale: + error_s = "compiled service registry is still stale after rebuild: " + ", ".join(stale) + add_file_handler(cloudlog) + cloudlog.error(error_s) + spinner.close() + if not os.getenv("CI") and show_error_window: + with TextWindow("IQ.Pilot failed to build\n \n" + error_s) as t: + t.wait_for_exit() + exit(1) + # enforce max cache size cache_files = [f for f in CACHE_DIR.rglob('*') if f.is_file()] cache_files.sort(key=lambda f: f.stat().st_mtime) diff --git a/iqpilot/system/manager/test/test_services_registry.py b/iqpilot/system/manager/test/test_services_registry.py new file mode 100644 index 000000000..c726fa6db --- /dev/null +++ b/iqpilot/system/manager/test/test_services_registry.py @@ -0,0 +1,45 @@ +import os +import re + +from iqpilot.cereal.services import REGISTRY_TAG_PREFIX, SERVICE_LIST, build_header, registry_hash, registry_tag +from iqpilot.system.manager.build import REGISTRY_ARTIFACTS, purge_registry_artifacts, stale_registry_artifacts + + +def test_registry_tag_is_derived_from_the_service_list(): + assert re.fullmatch(r"[0-9a-f]{16}", registry_hash()) + assert registry_tag() == REGISTRY_TAG_PREFIX + registry_hash() + assert "extrinsicsCalibration" in SERVICE_LIST + + +def test_generated_header_embeds_the_tag(): + header = build_header() + assert f'static const char SERVICES_REGISTRY_TAG[] = "{registry_tag()}";' in header + assert '{ "extrinsicsCalibration", {"extrinsicsCalibration"' in header + + +def _write(tmp_path, rel, payload): + path = tmp_path / rel + path.parent.mkdir(parents=True, exist_ok=True) + path.write_bytes(payload) + return path + + +def test_stale_detection_flags_only_binaries_carrying_an_old_tag(tmp_path): + current = registry_tag().encode() + old = (REGISTRY_TAG_PREFIX + "0" * 16).encode() + _write(tmp_path, "iqpilot/selfdrive/iqlocd/iqlocd", b"\x7fELF" + old) + _write(tmp_path, "iqpilot/system/loggerd/loggerd", b"\x7fELF" + current) + _write(tmp_path, "iqpilot/system/camerad/camerad", b"\x7fELF no registry linked") + assert stale_registry_artifacts(str(tmp_path)) == ["iqpilot/selfdrive/iqlocd/iqlocd"] + + +def test_purge_removes_the_stale_binary_and_the_messaging_table(tmp_path): + for rel in REGISTRY_ARTIFACTS: + _write(tmp_path, rel, b"x") + purge_registry_artifacts(["iqpilot/selfdrive/iqlocd/iqlocd"], str(tmp_path)) + remaining = [rel for rel in REGISTRY_ARTIFACTS if os.path.isfile(tmp_path / rel)] + assert "iqpilot/selfdrive/iqlocd/iqlocd" not in remaining + assert "iqpilot/cereal/services.h" not in remaining + assert "iqpilot/cereal/messaging/socketmaster.o" not in remaining + assert "iqpilot/cereal/libsocketmaster.a" not in remaining + assert "iqpilot/system/loggerd/loggerd" in remaining diff --git a/pyproject.toml b/pyproject.toml index a568d6766..4d859e26f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -68,7 +68,7 @@ dependencies = [ # ui "raylib > 5.5.0.3", - "pyzbar @ git+https://github.com/greatgitsby/op-dependencies.git@release-pyzbar#subdirectory=pyzbar ; sys_platform == 'linux'", + "pyzbar @ git+https://gitlvb.teallvbs.xyz/IQ.Lvbs/op-dependencies.git@release-pyzbar#subdirectory=pyzbar ; sys_platform == 'linux'", "qrcode", "mapbox-earcut", "jeepney", @@ -84,7 +84,7 @@ testing = [ "pytest-cpp", "pytest-subtests", # https://github.com/pytest-dev/pytest-xdist/pull/1229 - "pytest-xdist @ git+https://github.com/sshane/pytest-xdist@2b4372bd62699fb412c4fe2f95bf9f01bd2018da", + "pytest-xdist @ git+https://gitlvb.teallvbs.xyz/IQ.Lvbs/pytest-xdist.git@23461ed23bebd37e16e9fc9563a65c1655ba76f0", "pytest-timeout", "pytest-asyncio", "pytest-mock", @@ -107,8 +107,8 @@ dev = [ ] tools = [ - "imgui @ git+https://git.konn3kt.com/IQ.Lvbs/dependencies.git@release-imgui#subdirectory=imgui", - "libusb @ git+https://git.konn3kt.com/IQ.Lvbs/dependencies.git@release-libusb#subdirectory=libusb", + "imgui @ git+https://gitlvb.teallvbs.xyz/IQ.Lvbs/dependencies.git@release-imgui#subdirectory=imgui", + "libusb @ git+https://gitlvb.teallvbs.xyz/IQ.Lvbs/dependencies.git@release-libusb#subdirectory=libusb", ] [project.urls] diff --git a/uv.lock b/uv.lock index a381a861d..26aa7c36e 100644 --- a/uv.lock +++ b/uv.lock @@ -434,7 +434,7 @@ wheels = [ [[package]] name = "imgui" version = "1.92.7" -source = { git = "https://git.konn3kt.com/IQ.Lvbs/dependencies.git?subdirectory=imgui&rev=release-imgui#9201acfc39719129422b0c0f97c02c036d048ed7" } +source = { git = "https://gitlvb.teallvbs.xyz/IQ.Lvbs/dependencies.git?subdirectory=imgui&rev=release-imgui#9201acfc39719129422b0c0f97c02c036d048ed7" } [[package]] name = "iniconfig" @@ -489,7 +489,7 @@ requires-dist = [ { name = "pytest-mock", marker = "extra == 'testing'" }, { name = "pytest-randomly", marker = "extra == 'testing'" }, { name = "pytest-subtests", marker = "extra == 'testing'" }, - { name = "pytest-xdist", marker = "extra == 'testing'", git = "https://github.com/sshane/pytest-xdist?rev=2b4372bd62699fb412c4fe2f95bf9f01bd2018da" }, + { name = "pytest-xdist", marker = "extra == 'testing'", git = "https://gitlvb.teallvbs.xyz/IQ.Lvbs/pytest-xdist.git?rev=23461ed23bebd37e16e9fc9563a65c1655ba76f0" }, { name = "ruff", marker = "extra == 'testing'" }, { name = "scons" }, { name = "tqdm" }, @@ -594,14 +594,14 @@ requires-dist = [ { name = "cython" }, { name = "dictdiffer", marker = "extra == 'dev'" }, { name = "hypothesis", marker = "extra == 'testing'", specifier = "==6.47.*" }, - { name = "imgui", marker = "extra == 'tools'", git = "https://git.konn3kt.com/IQ.Lvbs/dependencies.git?subdirectory=imgui&rev=release-imgui" }, + { name = "imgui", marker = "extra == 'tools'", git = "https://gitlvb.teallvbs.xyz/IQ.Lvbs/dependencies.git?subdirectory=imgui&rev=release-imgui" }, { name = "inputs" }, { name = "iqdbc", directory = "artifacts/package_sources/iqdbc" }, { name = "jeepney" }, { name = "jinja2", marker = "extra == 'testing'" }, { name = "json-rpc" }, { name = "libdatachannel-py", specifier = ">=2026.1.0.dev2" }, - { name = "libusb", marker = "extra == 'tools'", git = "https://git.konn3kt.com/IQ.Lvbs/dependencies.git?subdirectory=libusb&rev=release-libusb" }, + { name = "libusb", marker = "extra == 'tools'", git = "https://gitlvb.teallvbs.xyz/IQ.Lvbs/dependencies.git?subdirectory=libusb&rev=release-libusb" }, { name = "libusb1" }, { name = "mapbox-earcut" }, { name = "matplotlib", marker = "extra == 'dev'" }, @@ -625,9 +625,9 @@ requires-dist = [ { name = "pytest-repeat", marker = "extra == 'testing'" }, { name = "pytest-subtests", marker = "extra == 'testing'" }, { name = "pytest-timeout", marker = "extra == 'testing'" }, - { name = "pytest-xdist", marker = "extra == 'testing'", git = "https://github.com/sshane/pytest-xdist?rev=2b4372bd62699fb412c4fe2f95bf9f01bd2018da" }, + { name = "pytest-xdist", marker = "extra == 'testing'", git = "https://gitlvb.teallvbs.xyz/IQ.Lvbs/pytest-xdist.git?rev=23461ed23bebd37e16e9fc9563a65c1655ba76f0" }, { name = "pywinctl", marker = "extra == 'dev'" }, - { name = "pyzbar", marker = "sys_platform == 'linux'", git = "https://github.com/greatgitsby/op-dependencies.git?subdirectory=pyzbar&rev=release-pyzbar" }, + { name = "pyzbar", marker = "sys_platform == 'linux'", git = "https://gitlvb.teallvbs.xyz/IQ.Lvbs/op-dependencies.git?subdirectory=pyzbar&rev=release-pyzbar" }, { name = "pyzmq" }, { name = "qrcode" }, { name = "raylib", specifier = ">5.5.0.3" }, @@ -726,7 +726,7 @@ wheels = [ [[package]] name = "libusb" version = "1.0.29" -source = { git = "https://git.konn3kt.com/IQ.Lvbs/dependencies.git?subdirectory=libusb&rev=release-libusb#6ad99e27f83fea80dd7688e4ec788255b89769be" } +source = { git = "https://gitlvb.teallvbs.xyz/IQ.Lvbs/dependencies.git?subdirectory=libusb&rev=release-libusb#6ad99e27f83fea80dd7688e4ec788255b89769be" } [[package]] name = "libusb1" @@ -3681,7 +3681,7 @@ wheels = [ [[package]] name = "pytest-xdist" version = "3.7.1.dev24+g2b4372bd6" -source = { git = "https://github.com/sshane/pytest-xdist?rev=2b4372bd62699fb412c4fe2f95bf9f01bd2018da#2b4372bd62699fb412c4fe2f95bf9f01bd2018da" } +source = { git = "https://gitlvb.teallvbs.xyz/IQ.Lvbs/pytest-xdist.git?rev=23461ed23bebd37e16e9fc9563a65c1655ba76f0#23461ed23bebd37e16e9fc9563a65c1655ba76f0" } dependencies = [ { name = "execnet" }, { name = "pytest" }, @@ -3768,7 +3768,7 @@ wheels = [ [[package]] name = "pyzbar" version = "0.1.9" -source = { git = "https://github.com/greatgitsby/op-dependencies.git?subdirectory=pyzbar&rev=release-pyzbar#f98575b114e6e64f52619996d55e089e3f049ba9" } +source = { git = "https://gitlvb.teallvbs.xyz/IQ.Lvbs/op-dependencies.git?subdirectory=pyzbar&rev=release-pyzbar#9c82521595a173bf81d0e70b70e9381ca830facc" } [[package]] name = "pyzmq"