kopia lustrzana https://github.com/Yakifo/amqtt
more strict flake8. Fixed typos.
rodzic
2c1b425820
commit
613e77f6b4
|
@ -30,8 +30,8 @@ jobs:
|
|||
python -m pip install .
|
||||
- name: Lint with flake8 and black
|
||||
run: |
|
||||
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
|
||||
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=88 --statistics
|
||||
flake8 . --count --statistics --show-source --ignore=E501,W503,W605,E722
|
||||
flake8 . --count --statistics --exit-zero --max-complexity=10 --ignore=E501,W503
|
||||
black . --check
|
||||
- name: Test with pytest
|
||||
run: |
|
||||
|
|
|
@ -214,13 +214,13 @@ htmlhelp_basename = "aMQTTdoc"
|
|||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
# 'papersize': 'letterpaper',
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
# 'pointsize': '10pt',
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
# 'preamble': '',
|
||||
# Latex figure (float) alignment
|
||||
#'figure_align': 'htbp',
|
||||
# 'figure_align': 'htbp',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Copyright (c) 2015 Nicolas JOUANIN
|
||||
#
|
||||
# See the file license.txt for copying permission.
|
||||
import asyncio
|
||||
|
||||
import io
|
||||
from websockets.protocol import WebSocketCommonProtocol
|
||||
from websockets.exceptions import ConnectionClosed
|
||||
|
@ -13,19 +13,20 @@ class ReaderAdapter:
|
|||
"""
|
||||
Base class for all network protocol reader adapter.
|
||||
|
||||
Reader adapters are used to adapt read operations on the network depending on the protocol used
|
||||
Reader adapters are used to adapt read operations on the network depending on the
|
||||
protocol used
|
||||
"""
|
||||
|
||||
async def read(self, n=-1) -> bytes:
|
||||
"""
|
||||
Read up to n bytes. If n is not provided, or set to -1, read until EOF and return all read bytes.
|
||||
If the EOF was received and the internal buffer is empty, return an empty bytes object.
|
||||
:return: packet read as bytes data
|
||||
Read up to n bytes. If n is not provided, or set to -1, read until EOF and
|
||||
return all read bytes. If the EOF was received and the internal buffer is
|
||||
empty, return an empty bytes object. :return: packet read as bytes data
|
||||
"""
|
||||
|
||||
def feed_eof(self):
|
||||
"""
|
||||
Acknowleddge EOF
|
||||
Acknowledge EOF
|
||||
"""
|
||||
|
||||
|
||||
|
@ -33,7 +34,8 @@ class WriterAdapter:
|
|||
"""
|
||||
Base class for all network protocol writer adapter.
|
||||
|
||||
Writer adapters are used to adapt write operations on the network depending on the protocol used
|
||||
Writer adapters are used to adapt write operations on the network depending on
|
||||
the protocol used
|
||||
"""
|
||||
|
||||
def write(self, data):
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Copyright (c) 2015 Nicolas JOUANIN
|
||||
#
|
||||
# See the file license.txt for copying permission.
|
||||
from typing import Optional, Dict, Union
|
||||
from typing import Optional
|
||||
import logging
|
||||
import ssl
|
||||
import websockets
|
||||
|
@ -147,7 +147,7 @@ class Broker:
|
|||
MQTT 3.1.1 compliant broker implementation
|
||||
|
||||
:param config: Example Yaml config
|
||||
:param loop: asyncio loop to use. Defaults to ``asyncio.get_event_loop()`` if none is given
|
||||
:param loop: asyncio loop to use. Defaults to ``asyncio.get_event_loop()``.
|
||||
:param plugin_namespace: Plugin namespace to use when loading plugin entry_points. Defaults to ``hbmqtt.broker.plugins``
|
||||
|
||||
"""
|
||||
|
|
|
@ -200,7 +200,7 @@ class MQTTClient:
|
|||
while self.client_tasks:
|
||||
task = self.client_tasks.pop()
|
||||
task.cancel()
|
||||
except IndexError as err:
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
async def reconnect(self, cleansession=None):
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# Copyright (c) 2015 Nicolas JOUANIN
|
||||
#
|
||||
# See the file license.txt for copying permission.
|
||||
import asyncio
|
||||
from hbmqtt.mqtt.packet import CONNACK, MQTTPacket, MQTTFixedHeader, MQTTVariableHeader
|
||||
from hbmqtt.codecs import read_or_raise, bytes_to_int
|
||||
from hbmqtt.errors import HBMQTTException
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# Copyright (c) 2015 Nicolas JOUANIN
|
||||
#
|
||||
# See the file license.txt for copying permission.
|
||||
import asyncio
|
||||
|
||||
from hbmqtt.codecs import (
|
||||
bytes_to_int,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# Copyright (c) 2015 Nicolas JOUANIN
|
||||
#
|
||||
# See the file license.txt for copying permission.
|
||||
import asyncio
|
||||
from asyncio import futures, Queue
|
||||
from hbmqtt.mqtt.protocol.handler import ProtocolHandler
|
||||
from hbmqtt.mqtt.connack import (
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
# See the file license.txt for copying permission.
|
||||
import asyncio
|
||||
from asyncio import futures
|
||||
import sys
|
||||
from hbmqtt.mqtt.protocol.handler import ProtocolHandler, EVENT_MQTT_PACKET_RECEIVED
|
||||
from hbmqtt.mqtt.disconnect import DisconnectPacket
|
||||
from hbmqtt.mqtt.pingreq import PingReqPacket
|
||||
|
@ -120,7 +119,7 @@ class ClientProtocolHandler(ProtocolHandler):
|
|||
try:
|
||||
waiter = self._subscriptions_waiter.get(packet_id)
|
||||
waiter.set_result(suback.payload.return_codes)
|
||||
except KeyError as ke:
|
||||
except KeyError:
|
||||
self.logger.warning(
|
||||
"Received SUBACK for unknown pending subscription with Id: %s"
|
||||
% packet_id
|
||||
|
@ -144,7 +143,7 @@ class ClientProtocolHandler(ProtocolHandler):
|
|||
try:
|
||||
waiter = self._unsubscriptions_waiter.get(packet_id)
|
||||
waiter.set_result(None)
|
||||
except KeyError as ke:
|
||||
except KeyError:
|
||||
self.logger.warning(
|
||||
"Received UNSUBACK for unknown pending subscription with Id: %s"
|
||||
% packet_id
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
# Copyright (c) 2015 Nicolas JOUANIN
|
||||
#
|
||||
# See the file license.txt for copying permission.
|
||||
import asyncio
|
||||
|
||||
from hbmqtt.mqtt.packet import (
|
||||
MQTTPacket,
|
||||
MQTTFixedHeader,
|
||||
|
@ -25,9 +23,9 @@ class SubackPayload(MQTTPayload):
|
|||
RETURN_CODE_02 = 0x02
|
||||
RETURN_CODE_80 = 0x80
|
||||
|
||||
def __init__(self, return_codes=[]):
|
||||
def __init__(self, return_codes=None):
|
||||
super().__init__()
|
||||
self.return_codes = return_codes
|
||||
self.return_codes = return_codes or []
|
||||
|
||||
def __repr__(self):
|
||||
return type(self).__name__ + "(return_codes={0})".format(
|
||||
|
|
|
@ -25,9 +25,9 @@ class SubscribePayload(MQTTPayload):
|
|||
|
||||
__slots__ = ("topics",)
|
||||
|
||||
def __init__(self, topics=[]):
|
||||
def __init__(self, topics=None):
|
||||
super().__init__()
|
||||
self.topics = topics
|
||||
self.topics = topics or []
|
||||
|
||||
def to_bytes(
|
||||
self, fixed_header: MQTTFixedHeader, variable_header: MQTTVariableHeader
|
||||
|
@ -55,7 +55,7 @@ class SubscribePayload(MQTTPayload):
|
|||
qos = bytes_to_int(qos_byte)
|
||||
topics.append((topic, qos))
|
||||
read_bytes += 2 + len(topic.encode("utf-8")) + 1
|
||||
except NoDataException as exc:
|
||||
except NoDataException:
|
||||
break
|
||||
return cls(topics)
|
||||
|
||||
|
|
|
@ -19,9 +19,9 @@ class UnubscribePayload(MQTTPayload):
|
|||
|
||||
__slots__ = ("topics",)
|
||||
|
||||
def __init__(self, topics=[]):
|
||||
def __init__(self, topics=None):
|
||||
super().__init__()
|
||||
self.topics = topics
|
||||
self.topics = topics or []
|
||||
|
||||
def to_bytes(
|
||||
self, fixed_header: MQTTFixedHeader, variable_header: MQTTVariableHeader
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# See the file license.txt for copying permission.
|
||||
import logging
|
||||
import asyncio
|
||||
from passlib.apps import custom_app_context as pwd_context
|
||||
|
||||
|
||||
|
@ -55,7 +54,7 @@ class AnonymousAuthPlugin(BaseAuthPlugin):
|
|||
"Authentication failure: session has an empty username"
|
||||
)
|
||||
except KeyError:
|
||||
self.context.logger.warning("Session informations not available")
|
||||
self.context.logger.warning("Session information not available")
|
||||
authenticated = False
|
||||
return authenticated
|
||||
|
||||
|
@ -74,8 +73,8 @@ class FileAuthPlugin(BaseAuthPlugin):
|
|||
self.context.logger.debug(
|
||||
"Reading user database from %s" % password_file
|
||||
)
|
||||
for l in f:
|
||||
line = l.strip()
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line.startswith("#"): # Allow comments in files
|
||||
(username, pwd_hash) = line.split(sep=":", maxsplit=3)
|
||||
if username:
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
|
||||
import logging
|
||||
import asyncio
|
||||
from functools import partial
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import pkg_resources
|
|||
import logging
|
||||
import asyncio
|
||||
import copy
|
||||
import sys
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
|
@ -31,9 +30,9 @@ class BaseContext:
|
|||
|
||||
class PluginManager:
|
||||
"""
|
||||
Wraps setuptools Entry point mechanism to provide a basic plugin system.
|
||||
Plugins are loaded for a given namespace (group).
|
||||
This plugin manager uses coroutines to run plugin call asynchronously in an event queue
|
||||
Wraps setuptools Entry point mechanism to provide a basic plugin system. Plugins
|
||||
are loaded for a given namespace (group). This plugin manager uses coroutines to
|
||||
run plugin call asynchronously in an event queue
|
||||
"""
|
||||
|
||||
def __init__(self, namespace, context, loop=None):
|
||||
|
@ -95,7 +94,8 @@ class PluginManager:
|
|||
async def close(self):
|
||||
"""
|
||||
Free PluginManager resources and cancel pending event methods
|
||||
This method call a close() coroutine for each plugin, allowing plugins to close and free resources
|
||||
This method call a close() coroutine for each plugin, allowing plugins to close
|
||||
and free resources
|
||||
:return:
|
||||
"""
|
||||
await self.map_plugin_coro("close")
|
||||
|
@ -118,8 +118,8 @@ class PluginManager:
|
|||
Fire an event to plugins.
|
||||
PluginManager schedule async calls for each plugin on method called "on_" + event_name
|
||||
For example, on_connect will be called on event 'connect'
|
||||
Method calls are schedule in the asyn loop. wait parameter must be set to true to wait until all
|
||||
mehtods are completed.
|
||||
Method calls are schedule in the async loop. wait parameter must be set to true
|
||||
to wait until all methods are completed.
|
||||
:param event_name:
|
||||
:param args:
|
||||
:param kwargs:
|
||||
|
@ -159,7 +159,8 @@ class PluginManager:
|
|||
Schedule a given coroutine call for each plugin.
|
||||
The coro called get the Plugin instance as first argument of its method call
|
||||
:param coro: coro to call on each plugin
|
||||
:param filter_plugins: list of plugin names to filter (only plugin whose name is in filter are called).
|
||||
:param filter_plugins: list of plugin names to filter (only plugin whose name is
|
||||
in filter are called).
|
||||
None will call all plugins. [] will call None.
|
||||
:param args: arguments to pass to coro
|
||||
:param kwargs: arguments to pass to coro
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# Copyright (c) 2015 Nicolas JOUANIN
|
||||
#
|
||||
# See the file license.txt for copying permission.
|
||||
import asyncio
|
||||
import sqlite3
|
||||
import pickle
|
||||
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
#
|
||||
# See the file license.txt for copying permission.
|
||||
from datetime import datetime
|
||||
from collections import deque
|
||||
import asyncio
|
||||
|
||||
import hbmqtt
|
||||
from hbmqtt.mqtt.packet import PUBLISH
|
||||
from hbmqtt.codecs import int_to_bytes_str
|
||||
import asyncio
|
||||
import sys
|
||||
from collections import deque
|
||||
|
||||
|
||||
DOLLAR_SYS_ROOT = "$SYS/broker/"
|
||||
|
@ -69,7 +69,7 @@ class BrokerSysPlugin:
|
|||
sys_interval = int(self.context.config.get("sys_interval", 0))
|
||||
if sys_interval > 0:
|
||||
self.context.logger.debug(
|
||||
"Setup $SYS broadcasting every %d secondes" % sys_interval
|
||||
"Setup $SYS broadcasting every %d seconds" % sys_interval
|
||||
)
|
||||
self.sys_handle = self.context.loop.call_later(
|
||||
sys_interval, self.broadcast_dollar_sys_topics
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
import asyncio
|
||||
|
||||
|
||||
class BaseTopicPlugin:
|
||||
def __init__(self, context):
|
||||
self.context = context
|
||||
|
|
|
@ -129,13 +129,13 @@ async def do_pub(client, arguments):
|
|||
logger.info("%s Disconnected from broker" % client.client_id)
|
||||
except ConnectException as ce:
|
||||
logger.fatal("connection to '%s' failed: %r" % (arguments["--url"], ce))
|
||||
except asyncio.CancelledError as cae:
|
||||
logger.fatal("Publish canceled due to prvious error")
|
||||
except asyncio.CancelledError:
|
||||
logger.fatal("Publish canceled due to previous error")
|
||||
|
||||
|
||||
def main(*args, **kwargs):
|
||||
if sys.version_info[:2] < (3, 4):
|
||||
logger.fatal("Error: Python 3.4+ is required")
|
||||
if sys.version_info[:2] < (3, 6):
|
||||
logger.fatal("Error: Python 3.6+ is required")
|
||||
sys.exit(-1)
|
||||
|
||||
arguments = docopt(__doc__, version=hbmqtt.__version__)
|
||||
|
@ -148,7 +148,6 @@ def main(*args, **kwargs):
|
|||
level = logging.INFO
|
||||
logging.basicConfig(level=level, format=formatter)
|
||||
|
||||
config = None
|
||||
if arguments["-c"]:
|
||||
config = read_yaml_config(arguments["-c"])
|
||||
else:
|
||||
|
|
|
@ -106,17 +106,16 @@ async def do_sub(client, arguments):
|
|||
await client.disconnect()
|
||||
except ConnectException as ce:
|
||||
logger.fatal("connection to '%s' failed: %r" % (arguments["--url"], ce))
|
||||
except asyncio.CancelledError as cae:
|
||||
logger.fatal("Publish canceled due to prvious error")
|
||||
except asyncio.CancelledError:
|
||||
logger.fatal("Publish canceled due to previous error")
|
||||
|
||||
|
||||
def main(*args, **kwargs):
|
||||
if sys.version_info[:2] < (3, 4):
|
||||
logger.fatal("Error: Python 3.4+ is required")
|
||||
if sys.version_info[:2] < (3, 6):
|
||||
logger.fatal("Error: Python 3.6+ is required")
|
||||
sys.exit(-1)
|
||||
|
||||
arguments = docopt(__doc__, version=hbmqtt.__version__)
|
||||
# print(arguments)
|
||||
formatter = "[%(asctime)s] :: %(levelname)s - %(message)s"
|
||||
|
||||
if arguments["-d"]:
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
# Copyright (c) 2015 Nicolas JOUANIN
|
||||
#
|
||||
# See the file license.txt for copying permission.
|
||||
import sys
|
||||
import asyncio
|
||||
import logging
|
||||
import unittest
|
||||
from unittest.mock import patch, call, MagicMock
|
||||
from unittest.mock import call, MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
|
@ -20,7 +18,6 @@ from hbmqtt.broker import (
|
|||
EVENT_BROKER_CLIENT_SUBSCRIBED,
|
||||
EVENT_BROKER_CLIENT_UNSUBSCRIBED,
|
||||
EVENT_BROKER_MESSAGE_RECEIVED,
|
||||
Broker,
|
||||
)
|
||||
from hbmqtt.client import MQTTClient, ConnectException
|
||||
from hbmqtt.mqtt import (
|
||||
|
@ -432,8 +429,11 @@ async def test_client_subscribe_publish_dollar_topic_1(broker):
|
|||
message = None
|
||||
try:
|
||||
message = await sub_client.deliver_message(timeout=2)
|
||||
except Exception as e:
|
||||
except asyncio.TimeoutError:
|
||||
pass
|
||||
except RuntimeError as e:
|
||||
# The loop is closed with pending tasks. Needs fine tuning.
|
||||
log.warning(e)
|
||||
assert message is None
|
||||
await sub_client.disconnect()
|
||||
await asyncio.sleep(0.1)
|
||||
|
@ -455,8 +455,11 @@ async def test_client_subscribe_publish_dollar_topic_2(broker):
|
|||
message = None
|
||||
try:
|
||||
message = await sub_client.deliver_message(timeout=2)
|
||||
except Exception as e:
|
||||
except asyncio.TimeoutError:
|
||||
pass
|
||||
except RuntimeError as e:
|
||||
# The loop is closed with pending tasks. Needs fine tuning.
|
||||
log.warning(e)
|
||||
assert message is None
|
||||
await sub_client.disconnect()
|
||||
await asyncio.sleep(0.1)
|
||||
|
|
Ładowanie…
Reference in New Issue