From 3c617f3a05a0bc3701655eaa5ad6b969660f5026 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Mon, 10 Aug 2026 09:44:01 -0700 Subject: [PATCH] replace submodules with packages --- .github/labeler.yaml | 2 +- .gitmodules | 15 -- SConstruct | 52 +++---- launch_chffrplus.sh | 7 +- msgq_repo | 1 - opendbc_repo | 1 - openpilot/cereal/SConscript | 8 +- openpilot/selfdrive/car/card.py | 1 + openpilot/selfdrive/pandad/SConscript | 3 + openpilot/selfdrive/pandad/panda.cc | 2 +- openpilot/selfdrive/pandad/panda.h | 4 +- openpilot/selfdrive/pandad/spi.cc | 2 +- .../test/process_replay/migration.py | 6 +- openpilot/selfdrive/test/scons_build_test.sh | 1 - openpilot/selfdrive/test/setup_device_ci.sh | 6 +- openpilot/system/webrtc/webrtcd.py | 4 +- openpilot/tools/cabana/SConscript | 5 +- openpilot/tools/cabana/panda.h | 4 +- openpilot/tools/jotpluggler/SConscript | 7 +- .../jotpluggler/generate_event_extractors.py | 9 +- openpilot/tools/jotpluggler/layout.cc | 2 +- openpilot/tools/jotpluggler/runtime.cc | 2 +- openpilot/tools/jotpluggler/sketch_layout.cc | 4 +- openpilot/tools/plotjuggler/juggle.py | 6 +- panda | 1 - pyproject.toml | 29 ++-- rednose_repo | 1 - site_scons/site_tools/cython.py | 61 ++++++++ teleoprtc_repo | 1 - tools/car_porting/README.md | 2 +- tools/car_porting/test_car_model.py | 2 +- tools/op.sh | 7 +- tools/release/build_release.sh | 16 +- tools/release/build_stripped.sh | 2 - uv.lock | 137 ++++-------------- 35 files changed, 179 insertions(+), 234 deletions(-) delete mode 160000 msgq_repo delete mode 160000 opendbc_repo delete mode 160000 panda delete mode 160000 rednose_repo create mode 100644 site_scons/site_tools/cython.py delete mode 160000 teleoprtc_repo diff --git a/.github/labeler.yaml b/.github/labeler.yaml index 2481a112ce0ff6..0f5d11182d2a97 100644 --- a/.github/labeler.yaml +++ b/.github/labeler.yaml @@ -4,7 +4,7 @@ CI / testing: car: - changed-files: - - any-glob-to-all-files: '{openpilot/selfdrive/car/**,opendbc_repo}' + - any-glob-to-all-files: 'openpilot/selfdrive/car/**' simulation: - changed-files: diff --git a/.gitmodules b/.gitmodules index ad6530de9ac910..904fee05d7cc16 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,18 +1,3 @@ -[submodule "panda"] - path = panda - url = ../../commaai/panda.git -[submodule "opendbc"] - path = opendbc_repo - url = ../../commaai/opendbc.git -[submodule "msgq"] - path = msgq_repo - url = ../../commaai/msgq.git -[submodule "rednose_repo"] - path = rednose_repo - url = ../../commaai/rednose.git -[submodule "teleoprtc_repo"] - path = teleoprtc_repo - url = ../../commaai/teleoprtc [submodule "tinygrad"] path = tinygrad_repo url = https://github.com/tinygrad/tinygrad.git diff --git a/SConstruct b/SConstruct index bb5c35feb785ff..589ca1cac12f30 100644 --- a/SConstruct +++ b/SConstruct @@ -7,6 +7,11 @@ import shlex import importlib import numpy as np +import msgq as msgq_package +import opendbc +import panda +import rednose as rednose_package + import SCons.Errors from SCons.Defaults import _stripixes @@ -27,20 +32,16 @@ AddOption('--minimal', default=(not COMMA_HARDWARE and not release), help='the minimum build to run openpilot. no tests, tools, etc.') -submodule_python_paths = [ +python_paths = [ Dir("#").abspath, - Dir("#msgq_repo").abspath, - Dir("#opendbc_repo").abspath, - Dir("#rednose_repo").abspath, - Dir("#teleoprtc_repo").abspath, Dir("#tinygrad_repo").abspath, ] -for p in reversed(submodule_python_paths): +for p in reversed(python_paths): if p not in sys.path: sys.path.insert(0, p) if external_pythonpath := os.environ.get("PYTHONPATH"): - submodule_python_paths += [p for p in external_pythonpath.split(os.pathsep) if p and p not in submodule_python_paths] + python_paths += [p for p in external_pythonpath.split(os.pathsep) if p and p not in python_paths] # Detect platform arch = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip() @@ -121,7 +122,7 @@ def _libflags(target, source, env, for_signature): env = Environment( ENV={ "PATH": os.environ['PATH'], - "PYTHONPATH": os.pathsep.join(submodule_python_paths), + "PYTHONPATH": os.pathsep.join(python_paths), "ACADOS_SOURCE_DIR": acados.DIR, "ACADOS_PYTHON_INTERFACE_PATH": acados.TEMPLATE_DIR, "TERA_PATH": acados.TERA_PATH @@ -144,10 +145,11 @@ env = Environment( CXXFLAGS=["-std=c++1z"], CPPPATH=[ "#openpilot", - "#msgq_repo", # #include "msgq/..." - "#opendbc_repo", # #include "opendbc/..." - "#rednose_repo", # #include "rednose/..." - "#rednose_repo/rednose", # #include "logger/..." (rednose package root) + msgq_package.INCLUDE_PATH, + opendbc.INCLUDE_PATH, + panda.INCLUDE_PATH, + rednose_package.INCLUDE_PATH, + os.path.dirname(rednose_package.__file__), # #include "logger/..." "#openpilot/cereal/gen/cpp", acados_include_dirs, [x.INCLUDE_DIR for x in pkgs], @@ -155,17 +157,15 @@ env = Environment( ], LIBPATH=[ "#openpilot/common", - "#msgq_repo", "#openpilot/selfdrive/pandad", - "#rednose_repo/rednose/helpers", [x.LIB_DIR for x in pkgs], ], RPATH=[ffmpeg.LIB_DIR] if ffmpeg_shared else [], CYTHONCFILESUFFIX=".cpp", COMPILATIONDB_USE_ABSPATH=True, - REDNOSE_ROOT="#rednose_repo", + REDNOSE_ROOT=rednose_package.INCLUDE_PATH, tools=["default", "cython", "compilation_db", "rednose_filter"], - toolpath=["#msgq_repo/site_scons/site_tools", "#rednose_repo/site_scons/site_tools"], + toolpath=[rednose_package.SCONS_TOOL_PATH], ) # SCons' Darwin linker tool doesn't define the variables used to expand RPATH. if arch == "Darwin": @@ -256,24 +256,20 @@ Import('_common') common = [_common, 'json11', 'zmq'] Export('common') -# Build messaging (cereal + msgq + socketmaster + their dependencies) -# Enable swaglog include in submodules -env_swaglog = env.Clone() -env_swaglog['CXXFLAGS'].append('-DSWAGLOG="\\"common/swaglog.h\\""') -SConscript(['msgq_repo/SConscript'], exports={'env': env_swaglog}) +# Build messaging (cereal + installed msgq + socketmaster) +msgq = File(msgq_package.LIB_PATH) +visionipc = File(msgq_package.VISIONIPC_LIB_PATH) +msgq_python = File(msgq_package.PYTHON_LIB_PATH) +Export('msgq', 'visionipc', 'msgq_python') SConscript(['openpilot/cereal/SConscript']) -Import('socketmaster', 'msgq') +Import('socketmaster') messaging = [socketmaster, msgq, 'capnp', 'kj',] Export('messaging') - -# Build other submodules -SConscript(['panda/SConscript']) - -# Build rednose library -SConscript(['rednose_repo/rednose/SConscript']) +rednose = File(rednose_package.LIB_PATH) +Export('rednose') # Build system services SConscript([ diff --git a/launch_chffrplus.sh b/launch_chffrplus.sh index 62ebffd27be189..6f7a893c64f460 100755 --- a/launch_chffrplus.sh +++ b/launch_chffrplus.sh @@ -70,12 +70,7 @@ function launch { ln -sfn $(pwd) /data/pythonpath export PYTHONPATH="$PWD" - # submodule package symlinks for PYTHONPATH imports on device. - # on PC these come from editable installs via pyproject.toml / uv. - ln -sfn msgq_repo/msgq msgq - ln -sfn opendbc_repo/opendbc opendbc - ln -sfn rednose_repo/rednose rednose - ln -sfn teleoprtc_repo/teleoprtc teleoprtc + # tinygrad remains vendored on device. ln -sfn tinygrad_repo/tinygrad tinygrad # hardware specific init diff --git a/msgq_repo b/msgq_repo deleted file mode 160000 index 0e266c1dbcf732..00000000000000 --- a/msgq_repo +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0e266c1dbcf7328beee3e57b4a8688555387c877 diff --git a/opendbc_repo b/opendbc_repo deleted file mode 160000 index 44f2987cb6ed28..00000000000000 --- a/opendbc_repo +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 44f2987cb6ed28f7dcd99d5930abf6c2917d8f60 diff --git a/openpilot/cereal/SConscript b/openpilot/cereal/SConscript index bee7620b1ee589..139201b708d690 100644 --- a/openpilot/cereal/SConscript +++ b/openpilot/cereal/SConscript @@ -1,3 +1,6 @@ +import os +import opendbc + Import('env', 'common', 'msgq') cereal_dir = Dir('.') @@ -5,11 +8,12 @@ gen_dir = Dir('gen') # Build cereal schema_files = ['log.capnp', 'deprecated.capnp', 'custom.capnp'] -car_capnp = '#opendbc_repo/opendbc/car/car.capnp' +car_schema_dir = os.path.join(os.path.dirname(opendbc.__file__), 'car') +car_capnp = os.path.join(car_schema_dir, 'car.capnp') all_output = schema_files + ['car.capnp'] env.Command([f'gen/cpp/{s}.c++' for s in all_output] + [f'gen/cpp/{s}.h' for s in all_output], schema_files + [car_capnp], - f"capnpc --src-prefix={cereal_dir.path} --src-prefix=opendbc_repo/opendbc/car --import-path=opendbc_repo/opendbc/car $SOURCES -o c++:{gen_dir.path}/cpp/") + f"capnpc --src-prefix={cereal_dir.path} --src-prefix={car_schema_dir} --import-path={car_schema_dir} $SOURCES -o c++:{gen_dir.path}/cpp/") cereal = env.Library('cereal', [f'gen/cpp/{s}.c++' for s in all_output]) diff --git a/openpilot/selfdrive/car/card.py b/openpilot/selfdrive/car/card.py index 86f8fbbde540c0..7c7b97b95f01cf 100755 --- a/openpilot/selfdrive/car/card.py +++ b/openpilot/selfdrive/car/card.py @@ -105,6 +105,7 @@ def __init__(self, CI=None, RI=None) -> None: # continue onto next fingerprinting step in pandad self.params.put_bool("FirmwareQueryDone", True, block=True) else: + assert RI is not None self.CI, self.CP = CI, CI.CP self.RI = RI diff --git a/openpilot/selfdrive/pandad/SConscript b/openpilot/selfdrive/pandad/SConscript index fd59db98537941..2b1ea5cf9a8d49 100644 --- a/openpilot/selfdrive/pandad/SConscript +++ b/openpilot/selfdrive/pandad/SConscript @@ -1,6 +1,9 @@ Import('env', 'arch', 'common', 'messaging') +import panda as panda_package + if arch != "Darwin": + env.Append(CXXFLAGS=['-DPANDA_FW_PATH=\\"%s\\"' % panda_package.FW_PATH]) libs = [common, messaging, 'pthread'] panda = env.Library('panda', ['panda.cc', 'spi.cc']) diff --git a/openpilot/selfdrive/pandad/panda.cc b/openpilot/selfdrive/pandad/panda.cc index d067a73107cd4a..9ab01b77fbcb85 100644 --- a/openpilot/selfdrive/pandad/panda.cc +++ b/openpilot/selfdrive/pandad/panda.cc @@ -116,7 +116,7 @@ std::optional Panda::get_serial() { bool Panda::up_to_date() { if (auto fw_sig = get_firmware_version()) { for (auto fn : { "panda.bin.signed", "panda_h7.bin.signed" }) { - auto content = util::read_file(std::string("../../../panda/board/obj/") + fn); + auto content = util::read_file(std::string(PANDA_FW_PATH) + fn); if (content.size() >= fw_sig->size() && memcmp(content.data() + content.size() - fw_sig->size(), fw_sig->data(), fw_sig->size()) == 0) { return true; diff --git a/openpilot/selfdrive/pandad/panda.h b/openpilot/selfdrive/pandad/panda.h index b0fb637b6b316f..ea31553e0b7c6a 100644 --- a/openpilot/selfdrive/pandad/panda.h +++ b/openpilot/selfdrive/pandad/panda.h @@ -11,8 +11,8 @@ #include "openpilot/cereal/gen/cpp/car.capnp.h" #include "openpilot/cereal/gen/cpp/log.capnp.h" -#include "panda/board/health.h" -#include "panda/board/can.h" +#include "panda/health.h" +#include "panda/can.h" #include "selfdrive/pandad/panda_comms.h" #define USB_TX_SOFT_LIMIT (0x100U) diff --git a/openpilot/selfdrive/pandad/spi.cc b/openpilot/selfdrive/pandad/spi.cc index 369032a53341d3..592d9cfbf3f96b 100644 --- a/openpilot/selfdrive/pandad/spi.cc +++ b/openpilot/selfdrive/pandad/spi.cc @@ -11,7 +11,7 @@ #include "common/util.h" #include "common/timing.h" #include "common/swaglog.h" -#include "panda/board/comms_definitions.h" +#include "panda/comms_definitions.h" #include "selfdrive/pandad/panda_comms.h" diff --git a/openpilot/selfdrive/test/process_replay/migration.py b/openpilot/selfdrive/test/process_replay/migration.py index 2fb8932abc207d..a24498f055d69c 100644 --- a/openpilot/selfdrive/test/process_replay/migration.py +++ b/openpilot/selfdrive/test/process_replay/migration.py @@ -8,7 +8,7 @@ from openpilot.cereal import messaging, log from opendbc.car.structs import car from opendbc.car.fingerprints import MIGRATION -from opendbc.car.toyota.values import EPS_SCALE, ToyotaSafetyFlags +from opendbc.car.toyota.values import CAR as TOYOTA, EPS_SCALE, ToyotaSafetyFlags from opendbc.car.ford.values import CAR as FORD, FordFlags, FordSafetyFlags from opendbc.car.hyundai.values import HyundaiSafetyFlags from opendbc.car.gm.values import GMSafetyFlags @@ -306,8 +306,8 @@ def migrate_carOutput(msgs): def migrate_pandaStates(msgs): # TODO: safety param migration should be handled automatically safety_param_migration = { - "TOYOTA_PRIUS": EPS_SCALE["TOYOTA_PRIUS"] | ToyotaSafetyFlags.STOCK_LONGITUDINAL, - "TOYOTA_RAV4": EPS_SCALE["TOYOTA_RAV4"] | ToyotaSafetyFlags.ALT_BRAKE, + "TOYOTA_PRIUS": EPS_SCALE[TOYOTA.TOYOTA_PRIUS] | ToyotaSafetyFlags.STOCK_LONGITUDINAL, + "TOYOTA_RAV4": EPS_SCALE[TOYOTA.TOYOTA_RAV4] | ToyotaSafetyFlags.ALT_BRAKE, "KIA_EV6": HyundaiSafetyFlags.EV_GAS | HyundaiSafetyFlags.CANFD_LKA_STEER_MSG, "CHEVROLET_VOLT": GMSafetyFlags.EV, "CHEVROLET_BOLT_EUV": GMSafetyFlags.EV | GMSafetyFlags.HW_CAM, diff --git a/openpilot/selfdrive/test/scons_build_test.sh b/openpilot/selfdrive/test/scons_build_test.sh index 6f6eafcad15f73..eae7752353dbe7 100755 --- a/openpilot/selfdrive/test/scons_build_test.sh +++ b/openpilot/selfdrive/test/scons_build_test.sh @@ -11,7 +11,6 @@ cd $BASEDIR # helpful commands: # scons -Q --tree=derived -cd $BASEDIR/opendbc_repo/ scons --clean scons --no-cache --random if ! scons -q; then diff --git a/openpilot/selfdrive/test/setup_device_ci.sh b/openpilot/selfdrive/test/setup_device_ci.sh index 60631ce037b8ea..a3a8ddea3053f0 100755 --- a/openpilot/selfdrive/test/setup_device_ci.sh +++ b/openpilot/selfdrive/test/setup_device_ci.sh @@ -145,12 +145,8 @@ else safe_checkout fi -# submodule package symlinks for PYTHONPATH imports on device (same as launch_chffrplus.sh) +# tinygrad remains vendored on device (same as launch_chffrplus.sh) cd $TEST_DIR -ln -sfn msgq_repo/msgq msgq -ln -sfn opendbc_repo/opendbc opendbc -ln -sfn rednose_repo/rednose rednose -ln -sfn teleoprtc_repo/teleoprtc teleoprtc ln -sfn tinygrad_repo/tinygrad tinygrad echo "$TEST_DIR synced with $GIT_COMMIT, t=$SECONDS" diff --git a/openpilot/system/webrtc/webrtcd.py b/openpilot/system/webrtc/webrtcd.py index 8e022eda1cbe2e..307b999f4d6931 100755 --- a/openpilot/system/webrtc/webrtcd.py +++ b/openpilot/system/webrtc/webrtcd.py @@ -272,7 +272,7 @@ async def stop(self): async def get_answer(self): return await self.stream.start() - def message_handler(self, message: bytes): + def message_handler(self, message: bytes | str): try: payload = json.loads(message) if isinstance(message, (bytes, str)) else None if isinstance(payload, dict): @@ -309,7 +309,7 @@ def message_handler(self, message: bytes): if msg_type not in self.incoming_bridge_services: return if self.incoming_bridge is not None: - self.incoming_bridge.send(message) + self.incoming_bridge.send(message.encode() if isinstance(message, str) else message) except Exception: self.logger.exception("Cereal incoming proxy failure") diff --git a/openpilot/tools/cabana/SConscript b/openpilot/tools/cabana/SConscript index 387129709e6321..0e25b1360a528c 100644 --- a/openpilot/tools/cabana/SConscript +++ b/openpilot/tools/cabana/SConscript @@ -4,6 +4,7 @@ import shutil import bootstrap_icons import libusb +import opendbc Import('env', 'arch', 'common', 'messaging', 'visionipc', 'cereal', 'replay_lib', 'ffmpeg_libs') @@ -74,7 +75,7 @@ cabana_env['CPPPATH'] += [libusb.INCLUDE_DIR] cabana_env['LIBPATH'] += [libusb.LIB_DIR] cabana_libs = [cereal, messaging, visionipc, replay_lib] + ffmpeg_libs + ['usb-1.0'] + base_libs -opendbc_path = '-DOPENDBC_FILE_PATH=\'"%s"\'' % (cabana_env.Dir("../../../opendbc_repo/opendbc/dbc").abspath) +opendbc_path = '-DOPENDBC_FILE_PATH=\'"%s"\'' % opendbc.DBC_PATH cabana_env['CXXFLAGS'] += [opendbc_path] # embed the bootstrap icons SVG into the binary @@ -126,4 +127,4 @@ output_json_file = 'openpilot/tools/cabana/dbc/car_fingerprint_to_dbc.json' generate_dbc = cabana_env.Command('#' + output_json_file, ['dbc/generate_dbc_json.py'], "python3 openpilot/tools/cabana/dbc/generate_dbc_json.py --out " + output_json_file) -cabana_env.Depends(generate_dbc, ["#openpilot/common", '#opendbc_repo', "#openpilot/cereal", "#msgq_repo"]) +cabana_env.Depends(generate_dbc, ["#openpilot/common", "#openpilot/cereal"]) diff --git a/openpilot/tools/cabana/panda.h b/openpilot/tools/cabana/panda.h index c99be1f5cfd953..dedbb2576f3b69 100644 --- a/openpilot/tools/cabana/panda.h +++ b/openpilot/tools/cabana/panda.h @@ -15,8 +15,8 @@ #include "openpilot/cereal/gen/cpp/car.capnp.h" #include "openpilot/cereal/gen/cpp/log.capnp.h" -#include "panda/board/health.h" -#include "panda/board/can.h" +#include "panda/health.h" +#include "panda/can.h" #define USB_TX_SOFT_LIMIT (0x100U) #define USBPACKET_MAX_SIZE (0x40) diff --git a/openpilot/tools/jotpluggler/SConscript b/openpilot/tools/jotpluggler/SConscript index bfe6e907427a6f..425ac42fafd55a 100644 --- a/openpilot/tools/jotpluggler/SConscript +++ b/openpilot/tools/jotpluggler/SConscript @@ -3,6 +3,7 @@ import subprocess import bootstrap_icons import imgui import libusb +import opendbc from opendbc import get_generated_dbcs from opendbc.car import Bus from opendbc.car.fingerprints import MIGRATION @@ -17,6 +18,7 @@ jot_env["CPPPATH"] += [imgui.INCLUDE_DIR, libusb.INCLUDE_DIR] jot_env["CXXFLAGS"] += [ "-DGLFW_INCLUDE_NONE", '-DJOTP_REPO_ROOT=\'"%s"\'' % os.path.realpath(BASEDIR), + '-DOPENDBC_DBC_PATH=\'"%s"\'' % opendbc.DBC_PATH, '-DBOOTSTRAP_ICONS_TTF=\'"%s"\'' % bootstrap_icons.TTF_PATH, ] @@ -85,6 +87,7 @@ def generate_event_extractors(target, source, env): "python3", "openpilot/tools/jotpluggler/generate_event_extractors.py", os.path.realpath(BASEDIR), + os.path.dirname(opendbc.__file__), str(target[0]), ]) return None @@ -95,8 +98,8 @@ event_extractors = jot_env.Command("generated_event_extractors.h", [ "generate_event_extractors.py", jot_env.Glob("#openpilot/cereal/*.capnp"), jot_env.Glob("#openpilot/cereal/include/*.capnp"), - "#opendbc_repo/opendbc/car/car.capnp", - "#opendbc_repo/opendbc/car/include/c++.capnp", + os.path.join(os.path.dirname(opendbc.__file__), "car", "car.capnp"), + os.path.join(os.path.dirname(opendbc.__file__), "car", "include", "c++.capnp"), ], generate_event_extractors, ) diff --git a/openpilot/tools/jotpluggler/generate_event_extractors.py b/openpilot/tools/jotpluggler/generate_event_extractors.py index a424ebc237b694..ad2570a15cae45 100644 --- a/openpilot/tools/jotpluggler/generate_event_extractors.py +++ b/openpilot/tools/jotpluggler/generate_event_extractors.py @@ -391,14 +391,15 @@ def generate(self): if __name__ == "__main__": - if len(sys.argv) != 3: - print(f"usage: {sys.argv[0]} ", file=sys.stderr) + if len(sys.argv) != 4: + print(f"usage: {sys.argv[0]} ", file=sys.stderr) sys.exit(2) repo_root = Path(sys.argv[1]).resolve() - output = Path(sys.argv[2]) + opendbc_root = Path(sys.argv[2]).resolve() + output = Path(sys.argv[3]) capnp.remove_import_hook() - log = capnp.load(str(repo_root / "openpilot" / "cereal" / "log.capnp"), imports=[str(repo_root / "opendbc_repo" / "opendbc" / "car")]) + log = capnp.load(str(repo_root / "openpilot" / "cereal" / "log.capnp"), imports=[str(opendbc_root / "car")]) generated = Generator(log.Event.schema).generate() output.parent.mkdir(parents=True, exist_ok=True) output.write_text(generated) diff --git a/openpilot/tools/jotpluggler/layout.cc b/openpilot/tools/jotpluggler/layout.cc index 6bc3a6168a4fc0..b9195a971f5e6e 100644 --- a/openpilot/tools/jotpluggler/layout.cc +++ b/openpilot/tools/jotpluggler/layout.cc @@ -276,7 +276,7 @@ std::string default_dbc_template() { DbcEditorSource resolve_dbc_editor_source(const std::string &dbc_name) { const fs::path generated_dbc_dir = repo_root() / "openpilot" / "tools" / "jotpluggler" / "generated_dbcs"; const std::array candidates = {{ - {.path = repo_root() / "opendbc_repo" / "opendbc" / "dbc" / (dbc_name + ".dbc"), .kind = DbcEditorState::SourceKind::Opendbc}, + {.path = fs::path(OPENDBC_DBC_PATH) / (dbc_name + ".dbc"), .kind = DbcEditorState::SourceKind::Opendbc}, {.path = generated_dbc_dir / (dbc_name + ".dbc"), .kind = DbcEditorState::SourceKind::Generated}, }}; for (const DbcEditorSource &candidate : candidates) { diff --git a/openpilot/tools/jotpluggler/runtime.cc b/openpilot/tools/jotpluggler/runtime.cc index d7d0fc79c4af19..50d378b153591f 100644 --- a/openpilot/tools/jotpluggler/runtime.cc +++ b/openpilot/tools/jotpluggler/runtime.cc @@ -8,7 +8,7 @@ #include "imgui_impl_opengl3_loader.h" #include "implot.h" #include "common/yuv.h" -#include "msgq_repo/msgq/ipc.h" +#include "msgq/ipc.h" #include "tools/replay/framereader.h" #include diff --git a/openpilot/tools/jotpluggler/sketch_layout.cc b/openpilot/tools/jotpluggler/sketch_layout.cc index 5440d9dd8deda3..a4e93ee57bb687 100644 --- a/openpilot/tools/jotpluggler/sketch_layout.cc +++ b/openpilot/tools/jotpluggler/sketch_layout.cc @@ -387,7 +387,7 @@ std::string detect_dbc_for_fingerprint(std::string_view car_fingerprint) { std::vector available_dbc_names_impl() { std::set names; for (const fs::path &dbc_dir : { - repo_root() / "opendbc_repo" / "opendbc" / "dbc", + fs::path(OPENDBC_DBC_PATH), repo_root() / "openpilot" / "tools" / "jotpluggler" / "generated_dbcs", }) { if (fs::exists(dbc_dir) && fs::is_directory(dbc_dir)) { @@ -409,7 +409,7 @@ std::vector available_dbc_names_impl() { fs::path resolve_dbc_path(const std::string &dbc_name) { for (const fs::path &candidate : { - repo_root() / "opendbc_repo" / "opendbc" / "dbc" / (dbc_name + ".dbc"), + fs::path(OPENDBC_DBC_PATH) / (dbc_name + ".dbc"), repo_root() / "openpilot" / "tools" / "jotpluggler" / "generated_dbcs" / (dbc_name + ".dbc"), }) { if (fs::exists(candidate)) return candidate; diff --git a/openpilot/tools/plotjuggler/juggle.py b/openpilot/tools/plotjuggler/juggle.py index 6ddbdbeb3ed48c..8ce58a501521b8 100755 --- a/openpilot/tools/plotjuggler/juggle.py +++ b/openpilot/tools/plotjuggler/juggle.py @@ -9,6 +9,7 @@ import requests import argparse from functools import partial +import opendbc from opendbc.car.fingerprints import MIGRATION from openpilot.common.basedir import BASEDIR from openpilot.common.swaglog import cloudlog @@ -95,8 +96,9 @@ def start_juggler(fn=None, dbc=None, layout=None, route_or_segment_name=None, pl with open(os.path.join(tmp_cereal, schema), "w") as dst: dst.write(contents) os.symlink(os.path.join(BASEDIR, "openpilot", "cereal", "include"), os.path.join(tmp_cereal, "include"), target_is_directory=True) - os.symlink(os.path.join(BASEDIR, "opendbc_repo", "opendbc", "car", "car.capnp"), os.path.join(tmp_cereal, "car.capnp")) - os.symlink(os.path.join(BASEDIR, "opendbc_repo", "opendbc"), os.path.join(schema_root, "opendbc"), target_is_directory=True) + opendbc_root = os.path.dirname(opendbc.__file__) + os.symlink(os.path.join(opendbc_root, "car", "car.capnp"), os.path.join(tmp_cereal, "car.capnp")) + os.symlink(opendbc_root, os.path.join(schema_root, "opendbc"), target_is_directory=True) env["BASEDIR"] = schema_root subprocess.call(cmd, shell=True, env=env, cwd=juggle_dir) diff --git a/panda b/panda deleted file mode 160000 index dd8a5b3df77706..00000000000000 --- a/panda +++ /dev/null @@ -1 +0,0 @@ -Subproject commit dd8a5b3df77706337a11555377e7180c5adc8726 diff --git a/pyproject.toml b/pyproject.toml index 78fb53ed1d7c25..52ecf971171c26 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,9 +22,17 @@ dependencies = [ # core "scons", + "Cython", "pycapnp==2.1.0", # 2.2 introduces a memory leak due to cyclic references "numpy >=2.0", + # comma Python packages + "msgq", + "opendbc", + "panda", + "rednose", + "teleoprtc", + # vendored native dependencies "comma-deps-capnproto", "comma-deps-acados", @@ -73,12 +81,7 @@ tools = [ #"metadrive-simulator @ git+https://github.com/commaai/metadrive.git@minimal ; (platform_machine != 'aarch64')", ] -submodules = [ - "msgq", - "opendbc", - "pandacan", - "rednose", - "teleoprtc", +tinygrad = [ "tinygrad", ] @@ -87,7 +90,7 @@ Homepage = "https://github.com/commaai/openpilot" [dependency-groups] standalone = [ - "openpilot[submodules]", + "openpilot[tinygrad]", ] [build-system] @@ -152,13 +155,13 @@ unresolved-attribute = "ignore" # many from capnp and Cython modules python-preference = "only-managed" default-groups = ["standalone"] override-dependencies = [ - "opendbc", # panda pins opendbc from git for standalone use; always use our submodule + "opendbc", # panda pins opendbc independently; always use openpilot's pinned revision ] [tool.uv.sources] -msgq = { path = "msgq_repo", editable = true } -opendbc = { path = "opendbc_repo", editable = true } -pandacan = { path = "panda", editable = true } -rednose = { path = "rednose_repo", editable = true } -teleoprtc = { path = "teleoprtc_repo", editable = true } +msgq = { git = "https://github.com/commaai/msgq.git", rev = "e6a46fbf54769293faecb7dc50cb3068d7f46e5d" } +opendbc = { git = "https://github.com/commaai/opendbc.git", rev = "b0685818f31df1e9d225ebc762087a8ebd563edb" } +panda = { git = "https://github.com/commaai/panda.git", rev = "c34a13f45401c5de1b32f9a5eb4db54ec5672bcf" } +rednose = { git = "https://github.com/commaai/rednose.git", rev = "9630580a2851e9d468a74a038779199d95b0dd4b" } +teleoprtc = { git = "https://github.com/commaai/teleoprtc.git", rev = "31db236a9ef820d7051ccd53488153cfbc84d3b9" } tinygrad = { path = "tinygrad_repo", editable = true } diff --git a/rednose_repo b/rednose_repo deleted file mode 160000 index 28d4a7f69e80e1..00000000000000 --- a/rednose_repo +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 28d4a7f69e80e1c3e0d24ca0733d7daeaeade3d0 diff --git a/site_scons/site_tools/cython.py b/site_scons/site_tools/cython.py new file mode 100644 index 00000000000000..514368d2c9d3ba --- /dev/null +++ b/site_scons/site_tools/cython.py @@ -0,0 +1,61 @@ +import re +import SCons +from SCons.Action import Action +from SCons.Scanner import Scanner + +pyx_from_import_re = re.compile(r'^from\s+(\S+)\s+cimport', re.M) +pyx_import_re = re.compile(r'^cimport\s+(\S+)', re.M) +cdef_import_re = re.compile(r'^cdef extern from\s+.(\S+).:', re.M) + + +def pyx_scan(node, env, path, arg=None): + contents = node.get_text_contents() + matches = pyx_from_import_re.findall(contents) + matches += pyx_import_re.findall(contents) + files = [m.replace('.', '/') + '.pxd' for m in matches] + files += [m.replace('.', '/') + '.pyx' for m in matches] + files += cdef_import_re.findall(contents) + cur_dir = str(node.get_dir()) + files = [cur_dir + f if f.startswith('/') else f for f in files] + files = [f for f in files if env.File(f).exists()] + return env.File(files) + + +pyxscanner = Scanner(function=pyx_scan, skeys=['.pyx', '.pxd'], recursive=True) +cythonAction = Action("$CYTHONCOM") + + +def create_builder(env): + try: + cython = env['BUILDERS']['Cython'] + except KeyError: + cython = SCons.Builder.Builder( + action=cythonAction, + emitter={}, + suffix=cython_suffix_emitter, + single_source=1, + ) + env.Append(SCANNERS=pyxscanner) + env['BUILDERS']['Cython'] = cython + return cython + + +def cython_suffix_emitter(env, source): + return "$CYTHONCFILESUFFIX" + + +def generate(env): + env["CYTHON"] = "cythonize" + env["CYTHONCOM"] = "$CYTHON $CYTHONFLAGS $SOURCE" + env["CYTHONCFILESUFFIX"] = ".cpp" + + c_file, _ = SCons.Tool.createCFileBuilders(env) + c_file.suffix['.pyx'] = cython_suffix_emitter + c_file.add_action('.pyx', cythonAction) + c_file.suffix['.py'] = cython_suffix_emitter + c_file.add_action('.py', cythonAction) + create_builder(env) + + +def exists(env): + return True diff --git a/teleoprtc_repo b/teleoprtc_repo deleted file mode 160000 index 31db236a9ef820..00000000000000 --- a/teleoprtc_repo +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 31db236a9ef820d7051ccd53488153cfbc84d3b9 diff --git a/tools/car_porting/README.md b/tools/car_porting/README.md index ef4c6ef80b79c4..dba094222d6851 100644 --- a/tools/car_porting/README.md +++ b/tools/car_porting/README.md @@ -52,7 +52,7 @@ FAIL: test_panda_safety_carstate (__main__.CarModelTestCase.test_panda_safety_ca Assert that panda safety matches openpilot's carState ---------------------------------------------------------------------- Traceback (most recent call last): - File "/home/batman/openpilot/opendbc_repo/opendbc/car/tests/test_models.py", line 440, in test_panda_safety_carstate + File "/home/batman/openpilot/.venv/lib/python3.12/site-packages/opendbc/car/tests/test_models.py", line 440, in test_panda_safety_carstate self.assertFalse(failed_checks, f"panda safety doesn't agree with CarState: {failed_checks}") AssertionError: {'gasPressed': 116} is not false : panda safety doesn't agree with CarState: {'gasPressed': 116} ``` diff --git a/tools/car_porting/test_car_model.py b/tools/car_porting/test_car_model.py index 3fb7ec9ae61eb5..b7d97880b62664 100755 --- a/tools/car_porting/test_car_model.py +++ b/tools/car_porting/test_car_model.py @@ -19,7 +19,7 @@ def create_test_models_suite(routes: list[CarTestRoute]) -> unittest.TestSuite: if __name__ == "__main__": parser = argparse.ArgumentParser(description="Test any route against common issues with a new car port. " + - "Uses opendbc_repo/opendbc/car/tests/test_models.py") + "Uses opendbc/car/tests/test_models.py") parser.add_argument("route_or_segment_name", help="Specify route to run tests on") parser.add_argument("--car", help="Specify car model for test route") args = parser.parse_args() diff --git a/tools/op.sh b/tools/op.sh index 3d7d17a76bb5e7..410e124dd33df1 100755 --- a/tools/op.sh +++ b/tools/op.sh @@ -197,16 +197,15 @@ EOF op_check_openpilot_dir op_check_os - # Submodules must be present before uv sync: pyproject path sources - # (pandacan, opendbc, msgq, ...) live in the submodule checkouts. - echo "Getting git submodules..." + # tinygrad remains a path dependency. + echo "Getting tinygrad..." st="$(date +%s)" if ! retry 3 git submodule update --jobs 4 --init --recursive; then echo -e " ↳ [${RED}✗${NC}] Getting git submodules failed!" return 1 fi et="$(date +%s)" - echo -e " ↳ [${GREEN}✔${NC}] Submodules installed successfully in $((et - st)) seconds." + echo -e " ↳ [${GREEN}✔${NC}] tinygrad installed successfully in $((et - st)) seconds." echo "Installing dependencies..." st="$(date +%s)" diff --git a/tools/release/build_release.sh b/tools/release/build_release.sh index 6657962ade71c1..c3f47a9cee0330 100755 --- a/tools/release/build_release.sh +++ b/tools/release/build_release.sh @@ -38,27 +38,15 @@ cp -pR --parents $(./tools/release/release_files.py) $BUILD_DIR/ # in the directory cd $BUILD_DIR -rm -f panda/board/obj/panda.bin.signed -rm -f panda/board/obj/panda_h7.bin.signed - VERSION=$(cat openpilot/common/version.h | awk -F[\"-] '{print $2}') echo "[-] committing version $VERSION T=$SECONDS" git add -f . git commit -a -m "openpilot v$VERSION release" -# Build and test before launch_chffrplus.sh creates the on-device package -# symlinks. SConstruct uses the same package roots for build subprocesses. -export PYTHONPATH="$BUILD_DIR:$BUILD_DIR/msgq_repo:$BUILD_DIR/opendbc_repo:$BUILD_DIR/rednose_repo:$BUILD_DIR/teleoprtc_repo:$BUILD_DIR/tinygrad_repo" +# Build and test before launch_chffrplus.sh creates the on-device tinygrad symlink. +export PYTHONPATH="$BUILD_DIR:$BUILD_DIR/tinygrad_repo" scons -if [ -z "$PANDA_DEBUG_BUILD" ]; then - # release panda fw - CERT=/data/pandaextra/certs/release RELEASE=1 scons panda/ -else - # build with ALLOW_DEBUG=1 to enable features like experimental longitudinal - scons panda/ -fi - # Ensure no submodules in release if test "$(git submodule--helper list | wc -l)" -gt "0"; then echo "submodules found:" diff --git a/tools/release/build_stripped.sh b/tools/release/build_stripped.sh index 0e957c92128f71..4fd224d0eab172 100755 --- a/tools/release/build_stripped.sh +++ b/tools/release/build_stripped.sh @@ -43,8 +43,6 @@ cd $SOURCE_DIR # in the directory cd $TARGET_DIR rm -rf .git/modules/ -rm -f panda/board/obj/panda.bin.signed - find openpilot/selfdrive/modeld/models -name '*.onnx' -size +95M -exec ./openpilot/common/file_chunker.py {} \; # include source commit hash and build date in commit diff --git a/uv.lock b/uv.lock index 5717d0a38d9c14..1b0ec59aadf69e 100644 --- a/uv.lock +++ b/uv.lock @@ -3,7 +3,7 @@ revision = 3 requires-python = ">=3.12.3, <3.13" [manifest] -overrides = [{ name = "opendbc", editable = "opendbc_repo" }] +overrides = [{ name = "opendbc", git = "https://github.com/commaai/opendbc.git?rev=b0685818f31df1e9d225ebc762087a8ebd563edb" }] [[package]] name = "certifi" @@ -495,21 +495,7 @@ wheels = [ [[package]] name = "msgq" version = "0.0.1" -source = { editable = "msgq_repo" } - -[package.metadata] -requires-dist = [ - { name = "codespell", marker = "extra == 'dev'" }, - { name = "cppcheck", marker = "extra == 'dev'" }, - { name = "cpplint", marker = "extra == 'dev'" }, - { name = "cython", marker = "extra == 'dev'" }, - { name = "lefthook", marker = "extra == 'dev'" }, - { name = "ruff", marker = "extra == 'dev'" }, - { name = "scons", marker = "extra == 'dev'" }, - { name = "setuptools", marker = "extra == 'dev'" }, - { name = "ty", marker = "extra == 'dev'" }, -] -provides-extras = ["dev"] +source = { git = "https://github.com/commaai/msgq.git?rev=e6a46fbf54769293faecb7dc50cb3068d7f46e5d#e6a46fbf54769293faecb7dc50cb3068d7f46e5d" } [[package]] name = "numpy" @@ -533,7 +519,7 @@ wheels = [ [[package]] name = "opendbc" version = "0.3.1" -source = { editable = "opendbc_repo" } +source = { git = "https://github.com/commaai/opendbc.git?rev=b0685818f31df1e9d225ebc762087a8ebd563edb#b0685818f31df1e9d225ebc762087a8ebd563edb" } dependencies = [ { name = "numpy" }, { name = "pycapnp" }, @@ -541,33 +527,6 @@ dependencies = [ { name = "tqdm" }, ] -[package.metadata] -requires-dist = [ - { name = "cffi", marker = "extra == 'testing'" }, - { name = "codespell", marker = "extra == 'testing'" }, - { name = "cpplint", marker = "extra == 'testing'" }, - { name = "gcovr", marker = "extra == 'testing'" }, - { name = "inputs", marker = "extra == 'examples'" }, - { name = "lefthook", marker = "extra == 'testing'" }, - { name = "numpy" }, - { name = "pycapnp" }, - { name = "pycryptodome" }, - { name = "ruff", marker = "extra == 'testing'" }, - { name = "tqdm" }, - { name = "tree-sitter", marker = "extra == 'testing'" }, - { name = "tree-sitter-c", marker = "extra == 'testing'" }, - { name = "ty", marker = "extra == 'testing'" }, - { name = "unittest-parallel", marker = "extra == 'testing'" }, - { name = "zstandard", marker = "extra == 'testing'" }, -] -provides-extras = ["testing", "examples"] - -[package.metadata.requires-dev] -testing = [ - { name = "comma-car-segments", url = "https://huggingface.co/datasets/commaai/commaCarSegments/resolve/main/dist/comma_car_segments-0.1.0-py3-none-any.whl" }, - { name = "cppcheck", git = "https://github.com/commaai/dependencies.git?subdirectory=cppcheck&rev=release-cppcheck" }, -] - [[package]] name = "openpilot" version = "0.1.0" @@ -582,37 +541,38 @@ dependencies = [ { name = "comma-deps-raylib" }, { name = "comma-deps-zeromq" }, { name = "comma-deps-zstd" }, + { name = "cython" }, { name = "inputs" }, { name = "jeepney" }, + { name = "msgq" }, { name = "numpy" }, + { name = "opendbc" }, + { name = "panda" }, { name = "pycapnp" }, { name = "pyjwt", extra = ["crypto"] }, { name = "pyzmq" }, + { name = "rednose" }, { name = "requests" }, { name = "scons" }, { name = "sentry-sdk" }, { name = "setproctitle" }, { name = "sounddevice" }, + { name = "teleoprtc" }, { name = "tqdm" }, { name = "websocket-client" }, { name = "zstandard" }, ] [package.optional-dependencies] -submodules = [ - { name = "msgq" }, - { name = "opendbc" }, - { name = "pandacan" }, - { name = "rednose" }, - { name = "teleoprtc" }, - { name = "tinygrad" }, -] testing = [ { name = "codespell" }, { name = "coverage" }, { name = "ruff" }, { name = "ty" }, ] +tinygrad = [ + { name = "tinygrad" }, +] tools = [ { name = "comma-deps-bootstrap-icons" }, { name = "comma-deps-imgui" }, @@ -623,7 +583,7 @@ tools = [ [package.dev-dependencies] standalone = [ - { name = "openpilot", extra = ["submodules"] }, + { name = "openpilot", extra = ["tinygrad"] }, ] [package.metadata] @@ -643,34 +603,35 @@ requires-dist = [ { name = "comma-deps-zeromq" }, { name = "comma-deps-zstd" }, { name = "coverage", marker = "extra == 'testing'" }, + { name = "cython" }, { name = "inputs" }, { name = "jeepney" }, { name = "matplotlib", marker = "extra == 'tools'" }, - { name = "msgq", marker = "extra == 'submodules'", editable = "msgq_repo" }, + { name = "msgq", git = "https://github.com/commaai/msgq.git?rev=e6a46fbf54769293faecb7dc50cb3068d7f46e5d" }, { name = "numpy", specifier = ">=2.0" }, - { name = "opendbc", marker = "extra == 'submodules'", editable = "opendbc_repo" }, - { name = "pandacan", marker = "extra == 'submodules'", editable = "panda" }, + { name = "opendbc", git = "https://github.com/commaai/opendbc.git?rev=b0685818f31df1e9d225ebc762087a8ebd563edb" }, + { name = "panda", git = "https://github.com/commaai/panda.git?rev=c34a13f45401c5de1b32f9a5eb4db54ec5672bcf" }, { name = "pycapnp", specifier = "==2.1.0" }, { name = "pyjwt", extras = ["crypto"] }, { name = "pyzmq" }, - { name = "rednose", marker = "extra == 'submodules'", editable = "rednose_repo" }, + { name = "rednose", git = "https://github.com/commaai/rednose.git?rev=9630580a2851e9d468a74a038779199d95b0dd4b" }, { name = "requests" }, { name = "ruff", marker = "extra == 'testing'" }, { name = "scons" }, { name = "sentry-sdk" }, { name = "setproctitle" }, { name = "sounddevice" }, - { name = "teleoprtc", marker = "extra == 'submodules'", editable = "teleoprtc_repo" }, - { name = "tinygrad", marker = "extra == 'submodules'", editable = "tinygrad_repo" }, + { name = "teleoprtc", git = "https://github.com/commaai/teleoprtc.git?rev=31db236a9ef820d7051ccd53488153cfbc84d3b9" }, + { name = "tinygrad", marker = "extra == 'tinygrad'", editable = "tinygrad_repo" }, { name = "tqdm" }, { name = "ty", marker = "extra == 'testing'" }, { name = "websocket-client" }, { name = "zstandard" }, ] -provides-extras = ["testing", "tools", "submodules"] +provides-extras = ["testing", "tools", "tinygrad"] [package.metadata.requires-dev] -standalone = [{ name = "openpilot", extras = ["submodules"] }] +standalone = [{ name = "openpilot", extras = ["tinygrad"] }] [[package]] name = "packaging" @@ -682,9 +643,9 @@ wheels = [ ] [[package]] -name = "pandacan" +name = "panda" version = "0.0.10" -source = { editable = "panda" } +source = { git = "https://github.com/commaai/panda.git?rev=c34a13f45401c5de1b32f9a5eb4db54ec5672bcf#c34a13f45401c5de1b32f9a5eb4db54ec5672bcf" } dependencies = [ { name = "libusb-package" }, { name = "libusb1" }, @@ -692,26 +653,6 @@ dependencies = [ { name = "spidev", marker = "sys_platform == 'linux'" }, ] -[package.metadata] -requires-dist = [ - { name = "cffi", marker = "extra == 'dev'" }, - { name = "cppcheck", marker = "extra == 'dev'", git = "https://github.com/commaai/dependencies.git?subdirectory=cppcheck&rev=release-cppcheck" }, - { name = "flaky", marker = "extra == 'dev'" }, - { name = "gcc-arm-none-eabi", marker = "extra == 'dev'", git = "https://github.com/commaai/dependencies.git?subdirectory=gcc-arm-none-eabi&rev=release-gcc-arm-none-eabi" }, - { name = "libusb-package" }, - { name = "libusb1" }, - { name = "opendbc", git = "https://github.com/commaai/opendbc.git?rev=master" }, - { name = "pytest", marker = "extra == 'dev'" }, - { name = "pytest-mock", marker = "extra == 'dev'" }, - { name = "pytest-timeout", marker = "extra == 'dev'" }, - { name = "pytest-xdist", marker = "extra == 'dev'" }, - { name = "ruff", marker = "extra == 'dev'" }, - { name = "scons", marker = "extra == 'dev'" }, - { name = "setuptools", marker = "extra == 'dev'" }, - { name = "spidev", marker = "sys_platform == 'linux'" }, -] -provides-extras = ["dev"] - [[package]] name = "pillow" version = "12.3.0" @@ -836,7 +777,7 @@ wheels = [ [[package]] name = "rednose" version = "0.0.1" -source = { editable = "rednose_repo" } +source = { git = "https://github.com/commaai/rednose.git?rev=9630580a2851e9d468a74a038779199d95b0dd4b#9630580a2851e9d468a74a038779199d95b0dd4b" } dependencies = [ { name = "cffi" }, { name = "comma-deps-eigen" }, @@ -847,21 +788,6 @@ dependencies = [ { name = "sympy" }, ] -[package.metadata] -requires-dist = [ - { name = "cffi" }, - { name = "comma-deps-eigen" }, - { name = "cython" }, - { name = "numpy" }, - { name = "ruff", marker = "extra == 'dev'" }, - { name = "scipy", marker = "extra == 'dev'" }, - { name = "scons" }, - { name = "setuptools" }, - { name = "sympy" }, - { name = "ty", marker = "extra == 'dev'" }, -] -provides-extras = ["dev"] - [[package]] name = "requests" version = "2.34.2" @@ -997,22 +923,11 @@ wheels = [ [[package]] name = "teleoprtc" version = "1.0.1" -source = { editable = "teleoprtc_repo" } +source = { git = "https://github.com/commaai/teleoprtc.git?rev=31db236a9ef820d7051ccd53488153cfbc84d3b9#31db236a9ef820d7051ccd53488153cfbc84d3b9" } dependencies = [ { name = "libdatachannel-py" }, ] -[package.metadata] -requires-dist = [ - { name = "libdatachannel-py", specifier = ">=2026.1.0.dev2" }, - { name = "parameterized", marker = "extra == 'dev'", specifier = ">=0.8" }, - { name = "pre-commit", marker = "extra == 'dev'" }, - { name = "pytest", marker = "extra == 'dev'" }, - { name = "pytest-asyncio", marker = "extra == 'dev'" }, - { name = "pytest-xdist", marker = "extra == 'dev'" }, -] -provides-extras = ["dev"] - [[package]] name = "tinygrad" version = "0.13.0"