diff --git a/example.py b/example.py index 415fad6..8163c84 100644 --- a/example.py +++ b/example.py @@ -8,7 +8,7 @@ import trio from trio_paho_mqtt import AsyncClient -client_id = 'trio-paho-mqtt/' + str(uuid.uuid4()) +client_id = "trio-paho-mqtt/" + str(uuid.uuid4()) topic = client_id n_messages = 3 print("Using client_id / topic: " + client_id) @@ -32,7 +32,7 @@ async def test_write(client): Publishing asynchronously will cause this function to return almost immediately.""" now = time.time() print(f"> Publishing: {now} * 40000") - client.publish(topic, bytes(str(now), encoding='utf8') * 40000, qos=1) + client.publish(topic, bytes(str(now), encoding="utf8") * 40000, qos=1) print(f"publish took {time.time() - now} seconds") @@ -43,7 +43,7 @@ async def main(): # Wrap it to create an asyncronous version client = AsyncClient(sync_client, nursery) # Connect to the broker, and subscribe to the topic - client.connect('mqtt.eclipse.org', 1883, 60) + client.connect("mqtt.eclipse.org", 1883, 60) client.subscribe(topic) # Start the reader diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 0000000..72a0cfe --- /dev/null +++ b/mypy.ini @@ -0,0 +1,9 @@ +[mypy] +strict = true + +files = + ./trio_paho_mqtt/ + +# tests/, + + diff --git a/poetry.lock b/poetry.lock index 4f79644..d113fde 100644 --- a/poetry.lock +++ b/poetry.lock @@ -20,6 +20,28 @@ docs = ["furo", "sphinx", "zope-interface", "sphinx-notfound-page"] tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope-interface", "cloudpickle"] tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "cloudpickle"] +[[package]] +name = "black" +version = "22.6.0" +description = "The uncompromising code formatter." +category = "dev" +optional = false +python-versions = ">=3.6.2" + +[package.dependencies] +click = ">=8.0.0" +mypy-extensions = ">=0.4.3" +pathspec = ">=0.9.0" +platformdirs = ">=2" +tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""} +typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.7.4)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] + [[package]] name = "cffi" version = "1.15.1" @@ -31,6 +53,25 @@ python-versions = "*" [package.dependencies] pycparser = "*" +[[package]] +name = "click" +version = "8.1.3" +description = "Composable command line interface toolkit" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.5" +description = "Cross-platform colored terminal text." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + [[package]] name = "idna" version = "3.3" @@ -39,6 +80,46 @@ category = "main" optional = false python-versions = ">=3.5" +[[package]] +name = "isort" +version = "5.10.1" +description = "A Python utility / library to sort Python imports." +category = "dev" +optional = false +python-versions = ">=3.6.1,<4.0" + +[package.extras] +pipfile_deprecated_finder = ["pipreqs", "requirementslib"] +requirements_deprecated_finder = ["pipreqs", "pip-api"] +colors = ["colorama (>=0.4.3,<0.5.0)"] +plugins = ["setuptools"] + +[[package]] +name = "mypy" +version = "0.971" +description = "Optional static typing for Python" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +mypy-extensions = ">=0.4.3" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = ">=3.10" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +python2 = ["typed-ast (>=1.4.0,<2)"] +reports = ["lxml"] + +[[package]] +name = "mypy-extensions" +version = "0.4.3" +description = "Experimental type system extensions for programs checked with the mypy typechecker." +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "outcome" version = "1.2.0" @@ -61,6 +142,38 @@ python-versions = "*" [package.extras] proxy = ["pysocks"] +[[package]] +name = "paho-mqtt-stubs" +version = "0.1.0" +description = "Type stubs for the paho MQTT client library" +category = "dev" +optional = false +python-versions = ">=3.7,<4.0" + +[package.dependencies] +paho-mqtt = ">=1.6.1,<2.0.0" +typing-extensions = ">=3.10.0,<4.0.0" + +[[package]] +name = "pathspec" +version = "0.9.0" +description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + +[[package]] +name = "platformdirs" +version = "2.5.2" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)", "sphinx (>=4)"] +test = ["appdirs (==1.4.4)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)", "pytest (>=6)"] + [[package]] name = "pycparser" version = "2.21" @@ -85,6 +198,14 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +category = "dev" +optional = false +python-versions = ">=3.7" + [[package]] name = "trio" version = "0.21.0" @@ -102,21 +223,60 @@ outcome = "*" sniffio = "*" sortedcontainers = "*" +[[package]] +name = "trio-typing" +version = "0.7.0" +description = "Static type checking support for Trio and related projects" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +mypy-extensions = ">=0.4.2" +trio = ">=0.16.0" +typing-extensions = ">=3.7.4" + +[package.extras] +mypy = ["mypy (>=0.920)"] + +[[package]] +name = "typing-extensions" +version = "3.10.0.2" +description = "Backported and Experimental Type Hints for Python 3.5+" +category = "dev" +optional = false +python-versions = "*" + [metadata] lock-version = "1.1" python-versions = "^3.8" -content-hash = "e4288cd6d3001aff49f3fb888f566b4ca441c0a59ecf2effe14386368c2afc75" +content-hash = "7f776b468a61860673be03434d0be898d3a153f7afbf2928a3f538714a5da4f4" [metadata.files] async-generator = [] attrs = [] +black = [] cffi = [] +click = [] +colorama = [] idna = [ {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, ] +isort = [] +mypy = [] +mypy-extensions = [ + {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, + {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, +] outcome = [] paho-mqtt = [] +paho-mqtt-stubs = [] +pathspec = [ + {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, + {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, +] +platformdirs = [] pycparser = [ {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, @@ -126,4 +286,7 @@ sortedcontainers = [ {file = "sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"}, {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, ] +tomli = [] trio = [] +trio-typing = [] +typing-extensions = [] diff --git a/pyproject.toml b/pyproject.toml index 9d3843a..4f795aa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,13 @@ trio = "^0.21.0" paho-mqtt = "^1.6.1" +[tool.poetry.group.dev.dependencies] +mypy = "^0.971" +black = "^22.6.0" +isort = "^5.10.1" +paho-mqtt-stubs = "^0.1.0" +trio-typing = "^0.7.0" + [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" diff --git a/scripts-dev/lint.sh b/scripts-dev/lint.sh new file mode 100755 index 0000000..c42ec2c --- /dev/null +++ b/scripts-dev/lint.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +isort . +black . +mypy + diff --git a/trio_paho_mqtt/__init__.py b/trio_paho_mqtt/__init__.py index 5dfe0b8..4b4d976 100644 --- a/trio_paho_mqtt/__init__.py +++ b/trio_paho_mqtt/__init__.py @@ -1 +1,3 @@ -from .trio_paho_mqtt import AsyncClient +from .client import AsyncClient + +__all__ = ["AsyncClient"] diff --git a/trio_paho_mqtt/trio_paho_mqtt.py b/trio_paho_mqtt/client.py similarity index 94% rename from trio_paho_mqtt/trio_paho_mqtt.py rename to trio_paho_mqtt/client.py index 2b88ef0..3a00b51 100644 --- a/trio_paho_mqtt/trio_paho_mqtt.py +++ b/trio_paho_mqtt/client.py @@ -7,7 +7,9 @@ import trio class AsyncClient: - def __init__(self, sync_client: mqtt.Client, parent_nursery: trio.Nursery, max_buffer=100): + def __init__( + self, sync_client: mqtt.Client, parent_nursery: trio.Nursery, max_buffer=100 + ): self._client = sync_client self._nursery = parent_nursery @@ -28,7 +30,9 @@ class AsyncClient: self._client.on_socket_register_write = self._on_socket_register_write self._client.on_socket_unregister_write = self._on_socket_unregister_write - self._msg_send_channel, self._msg_receive_channel = trio.open_memory_channel(max_buffer) + self._msg_send_channel, self._msg_receive_channel = trio.open_memory_channel( + max_buffer + ) self.subscribe = self._client.subscribe self.publish = self._client.publish @@ -79,7 +83,9 @@ class AsyncClient: await trio.lowlevel.wait_writable(self.socket) self._client.loop_write() - def connect(self, host, port=1883, keepalive=60, bind_address="", bind_port=0, **kwargs): + def connect( + self, host, port=1883, keepalive=60, bind_address="", bind_port=0, **kwargs + ): self._start_all_loop() self._client.connect(host, port, keepalive, bind_address, bind_port, **kwargs) @@ -130,4 +136,3 @@ class AsyncClient: def _on_socket_unregister_write(self, client, userdata, sock): # finished large write - stop write loop self._event_large_write = trio.Event() -