[build-system] requires = ["setuptools>=61", "wheel", "setuptools_scm>=8"] build-backend = "setuptools.build_meta" [project] name = "bumble" dynamic = ["version"] description = "Bluetooth Stack for Apps, Emulation, Test and Experimentation" readme = "README.md" license = "Apache-2.0" license-files = ["LICENSE"] authors = [{ name = "Google", email = "bumble-dev@google.com" }] requires-python = ">=3.10" dependencies = [ "aiohttp ~= 3.8; platform_system!='Emscripten'", "click >= 8.1.3; platform_system!='Emscripten'", "cryptography >= 44.0.3; platform_system!='Emscripten' and platform_system!='Android'", # Pyodide bundles a version of cryptography that is built for wasm, which may not match the # versions available on PyPI. Relax the version requirement since it's better than being # completely unable to import the package in case of version mismatch. "cryptography >= 39.0.0; platform_system=='Emscripten'", # Android wheels for cryptography are not yet available on PyPI, so chaquopy uses # the builds from https://chaquo.com/pypi-13.1/cryptography/. But these are not regually # updated. Relax the version requirement since it's better than being completely unable # to import the package in case of version mismatch. "cryptography >= 42.0.8; platform_system=='Android'", "grpcio >= 1.62.1; platform_system!='Emscripten'", "humanize >= 4.6.0; platform_system!='Emscripten'", "libusb1 >= 2.0.1; platform_system!='Emscripten'", "libusb-package == 1.0.26.1; platform_system!='Emscripten' and platform_system!='Android'", "platformdirs >= 3.10.0; platform_system!='Emscripten'", "prompt_toolkit >= 3.0.16; platform_system!='Emscripten'", "prettytable >= 3.6.0; platform_system!='Emscripten'", "protobuf >= 3.12.4; platform_system!='Emscripten'", "pyee >= 13.0.0", "pyserial-asyncio >= 0.5; platform_system!='Emscripten'", "pyserial >= 3.5; platform_system!='Emscripten'", "pyusb >= 1.2; platform_system!='Emscripten'", "tomli ~= 2.2.1; platform_system!='Emscripten' and python_version<'3.11'", "websockets >= 15.0.1; platform_system!='Emscripten'", ] [project.optional-dependencies] build = ["build >= 0.7"] test = [ "pytest >= 8.2", "pytest-asyncio >= 0.23.5", "pytest-html >= 3.2.0", "coverage >= 6.4", ] development = [ "black ~= 25.1", "bt-test-interfaces >= 0.0.6", "grpcio-tools >= 1.62.1", "invoke >= 1.7.3", "mobly >= 1.12.2", "mypy == 1.12.0", "nox >= 2022", "pylint == 3.3.1", "pyyaml >= 6.0", "ruff == 0.14.10", "types-appdirs >= 1.4.3", "types-invoke >= 1.7.3", "types-protobuf >= 4.21.0", ] avatar = [ "pandora-avatar == 0.0.10", "rootcanal == 1.11.1 ; python_version>='3.10'", ] pandora = ["bt-test-interfaces >= 0.0.6"] documentation = [ "mkdocs >= 1.6.0", "mkdocs-material >= 9.6", "mkdocstrings[python] >= 0.27.0", ] auracast = [ "lc3py >= 1.1.3; python_version>='3.10' and ((platform_system=='Linux' and platform_machine=='x86_64') or (platform_system=='Darwin' and platform_machine=='arm64'))", "sounddevice >= 0.5.1", ] [project.scripts] bumble-auracast = "bumble.apps.auracast:main" bumble-ble-rpa-tool = "bumble.apps.ble_rpa_tool:main" bumble-console = "bumble.apps.console:main" bumble-controller-info = "bumble.apps.controller_info:main" bumble-controller-loopback = "bumble.apps.controller_loopback:main" bumble-gatt-dump = "bumble.apps.gatt_dump:main" bumble-hci-bridge = "bumble.apps.hci_bridge:main" bumble-l2cap-bridge = "bumble.apps.l2cap_bridge:main" bumble-rfcomm-bridge = "bumble.apps.rfcomm_bridge:main" bumble-pair = "bumble.apps.pair:main" bumble-scan = "bumble.apps.scan:main" bumble-show = "bumble.apps.show:main" bumble-unbond = "bumble.apps.unbond:main" bumble-usb-probe = "bumble.apps.usb_probe:main" bumble-bench = "bumble.apps.bench:main" bumble-player = "bumble.apps.player.player:main" bumble-speaker = "bumble.apps.speaker.speaker:main" bumble-pandora-server = "bumble.apps.pandora_server:main" bumble-rtk-util = "bumble.tools.rtk_util:main" bumble-rtk-fw-download = "bumble.tools.rtk_fw_download:main" bumble-intel-util = "bumble.tools.intel_util:main" bumble-intel-fw-download = "bumble.tools.intel_fw_download:main" [project.urls] Homepage = "https://github.com/google/bumble" [tool.setuptools] packages = [ "bumble", "bumble.transport", "bumble.transport.grpc_protobuf", "bumble.drivers", "bumble.profiles", "bumble.apps", "bumble.pandora", "bumble.tools", ] [tool.setuptools.package-dir] "bumble" = "bumble" "bumble.apps" = "apps" "bumble.tools" = "tools" [tool.setuptools_scm] write_to = "bumble/_version.py" [tool.setuptools.package-data] "*" = ["*.pyi", "py.typed"] [tool.pytest.ini_options] pythonpath = "." testpaths = ["tests"] [tool.pylint.master] init-hook = 'import sys; sys.path.append(".")' ignore-paths = ['.*_pb2(_grpc)?.py'] [tool.pylint.messages_control] max-line-length = "88" disable = [ "broad-except", "fixme", "logging-fstring-interpolation", "logging-not-lazy", "no-member", # Temporary until pylint works better with class/method decorators "no-value-for-parameter", # Temporary until pylint works better with class/method decorators "missing-class-docstring", "missing-function-docstring", "missing-module-docstring", "too-few-public-methods", "too-many-arguments", "too-many-branches", "too-many-instance-attributes", "too-many-lines", "too-many-locals", "too-many-public-methods", "too-many-statements", ] [tool.pylint.main] ignore=["pandora", "mobly"] # FIXME: pylint does not support stubs yet [tool.pylint.typecheck] signature-mutators = "AsyncRunner.run_in_task" disable = "not-callable" [tool.black] skip-string-normalization = true extend-exclude = ''' ( .*_pb2(_grpc)?.py # exclude autogenerated Protocol Buffer files anywhere in the project ) ''' [tool.mypy] exclude = ['bumble/transport/grpc_protobuf', 'examples/mobly/bench'] [[tool.mypy.overrides]] module = "bumble.transport.grpc_protobuf.*" ignore_errors = true [[tool.mypy.overrides]] module = "aioconsole.*" ignore_missing_imports = true [[tool.mypy.overrides]] module = "construct.*" ignore_missing_imports = true [[tool.mypy.overrides]] module = "grpc.*" ignore_missing_imports = true [[tool.mypy.overrides]] module = "serial_asyncio.*" ignore_missing_imports = true [[tool.mypy.overrides]] module = "sounddevice.*" ignore_missing_imports = true [[tool.mypy.overrides]] module = "usb.*" ignore_missing_imports = true [[tool.mypy.overrides]] module = "usb1.*" ignore_missing_imports = true [tool.isort] profile = "black" skip = ["_version.py", "grpc_protobuf"] [tool.ruff] exclude = [ "bumble/transport/grpc_protobuf" ] [tool.ruff.lint] extend-select = ["UP"] [tool.ruff.format] quote-style = "preserve"