Skip to content

Commit

Permalink
Fix stuff found by pylint or ignore it locally
Browse files Browse the repository at this point in the history
  • Loading branch information
michael-k committed Jul 16, 2021
1 parent c0c0252 commit 4cc41bc
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 52 deletions.
1 change: 1 addition & 0 deletions doc/conf.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
#
# rohrpost documentation build configuration file, created by
# sphinx-quickstart on Sun Sep 10 11:38:15 2017.
Expand Down
17 changes: 0 additions & 17 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,5 @@ profile = "black"

[tool.pylint."messages control"]
disable = [
"access-member-before-definition",
"arguments-differ",
"arguments-renamed",
"attribute-defined-outside-init",
"import-outside-toplevel",
"inconsistent-return-statements",
"invalid-name",
"line-too-long",
"missing-docstring",
"missing-format-attribute",
"no-member",
"no-self-use",
"too-few-public-methods",
"too-many-ancestors",
"unnecessary-pass",
"unused-argument",
"unused-import",
"useless-super-delegation",
]
26 changes: 16 additions & 10 deletions rohrpost/main.py
Original file line number Diff line number Diff line change
@@ -1,46 +1,52 @@
import json
from functools import partial
from typing import Optional

from channels.generic.websocket import WebsocketConsumer

from . import handlers # noqa
from . import handlers # noqa: F401 # pylint: disable=unused-import
from .message import send_error
from .registry import HANDLERS

REQUIRED_FIELDS = ["type", "id"]


def handle_rohrpost_message(consumer: WebsocketConsumer, text_data: str) -> None:
def handle_rohrpost_message(
consumer: WebsocketConsumer, text_data: Optional[str]
) -> None:
"""
Handling of a rohrpost message will validate the required format:
A valid JSON object including at least an "id" and "type" field.
It then hands off further handling to the registered handler (if any).
"""
_send_error = partial(send_error, consumer=consumer, message_id=None, handler=None)
if not text_data:
return _send_error(error="Received empty message.")
_send_error(error="Received empty message.")
return

try:
request = json.loads(text_data) # type: dict
except (json.JSONDecodeError, TypeError) as e:
return _send_error(
error="Could not decode JSON message. Error: {}".format(str(e))
)
except (json.JSONDecodeError, TypeError) as exc:
_send_error(error="Could not decode JSON message. Error: {}".format(str(exc)))
return

if not isinstance(request, dict):
return _send_error(error="Expected a JSON object as message.")
_send_error(error="Expected a JSON object as message.")
return

for field in REQUIRED_FIELDS:
if field not in request:
return _send_error(error="Missing required field '{}'.".format(field))
_send_error(error="Missing required field '{}'.".format(field))
return

request_type = request["type"]
if request_type not in HANDLERS:
return send_error(
send_error(
consumer=consumer,
message_id=request["id"],
handler=request_type,
error="Unknown message type '{}'.".format(request_type),
)
return

HANDLERS[request_type](consumer=consumer, request=request)
23 changes: 11 additions & 12 deletions rohrpost/message.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json
import random
import uuid
from collections.abc import Collection, Mapping
from decimal import Decimal
from typing import Any, Dict, Union
Expand All @@ -12,18 +13,16 @@


class TolerantJSONEncoder(json.JSONEncoder):
def default(self, obj: Any) -> Any:
import uuid

if isinstance(obj, uuid.UUID):
return str(obj)
if isinstance(obj, Decimal):
return int(obj) if int(obj) == obj else float(obj)
if isinstance(obj, Mapping):
return dict(obj)
if isinstance(obj, Collection):
return list(obj)
return json.JSONEncoder.default(self, obj)
def default(self, o: Any) -> Any:
if isinstance(o, uuid.UUID):
return str(o)
if isinstance(o, Decimal):
return int(o) if int(o) == o else float(o)
if isinstance(o, Mapping):
return dict(o)
if isinstance(o, Collection):
return list(o)
return json.JSONEncoder.default(self, o)


def send_to_group(group_name: str, message: Union[str, dict]) -> None:
Expand Down
10 changes: 6 additions & 4 deletions rohrpost/mixins.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# pylint: disable=no-member,too-few-public-methods
import json
from typing import Sequence

Expand Down Expand Up @@ -32,7 +33,9 @@ def _get_push_data(
obj_data = {"id": self.pk} # type: ignore[attr-defined]
return obj_data

def _get_message_type(self, message_type: str) -> str:
def _get_message_type( # pylint: disable=no-self-use
self, message_type: str
) -> str:
return message_type

def _send_notify(
Expand Down Expand Up @@ -115,7 +118,8 @@ class NotifyOnChange(NotifyOnCreate, NotifyOnUpdate, NotifyOnDelete):
- As the result of '{class_name}-{pk}'.format(class_name=object.__class__.__name__.lower()
pk=object.pk) otherwise
The serialized object will be taken either from:
- The result of get_push_notification_data(updated_fields=None) if such a method exists, else
- The result of get_push_notification_data(updated_fields=None),
if such a method exists, else
- The result of serializer_class(self).data, if such an attribute exists, else
- {"id": self.pk}
The serialized object will also contain an 'updated_fields' attribute with a list *if*
Expand All @@ -134,5 +138,3 @@ class NotifyOnChange(NotifyOnCreate, NotifyOnUpdate, NotifyOnDelete):
}
}
"""

pass
8 changes: 4 additions & 4 deletions rohrpost/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ def update_registry(key: str, value: Callable) -> None:
name = name or func.__name__

if isinstance(name, list):
for n in name:
update_registry(n, func)
for _name in name:
update_registry(_name, func)
else:
update_registry(name, func)
return func
Expand All @@ -22,7 +22,7 @@ def update_registry(key: str, value: Callable) -> None:
def rohrpost_handler(
name: Union[str, List[str]] = ""
) -> Callable[[Callable], Callable]:
def wrap(f: Callable) -> Callable:
return _rohrpost_handler(f, name)
def wrap(func: Callable) -> Callable:
return _rohrpost_handler(func, name)

return wrap
6 changes: 3 additions & 3 deletions rohrpost/sync_consumer.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:
def connect(self) -> None:
self.accept()

def disconnect(self, close_code: Any) -> None:
def disconnect(self, code: Any) -> None:
for group_name in list(self._subscribed_groups):
self._subscribed_groups.remove(group_name)
async_to_sync(self.channel_layer.group_discard)( # type: ignore[no-untyped-call]
group_name, self.channel_name
)
super().disconnect(close_code)
super().disconnect(code)

def receive(self, text_data: str) -> None:
def receive(self, text_data: str = None, bytes_data: bytes = None) -> None:
handle_rohrpost_message(consumer=self, text_data=text_data)

def rohrpost_message(self, event: dict) -> None:
Expand Down
7 changes: 5 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# pylint: disable=too-few-public-methods,too-many-ancestors,unused-argument,useless-super-delegation
import pytest

from rohrpost.mixins import NotifyOnChange
Expand All @@ -10,9 +11,11 @@ def consumer():


class MockModel:
pk = None

def save(self, *args, **kwargs):
if not self.pk:
self.pk = 1
self.pk = 1 # pylint: disable=invalid-name
return self

def delete(self, *args, **kwargs):
Expand Down Expand Up @@ -46,7 +49,7 @@ class ModelWithAttrMixin:

class ModelWithMethodMixin:
def get_group_name(self, message_type):
return "method-example-{self.pk}".format(self=self)
return f"method-example-{self.pk}"


class ModelWithDataMixin:
Expand Down

0 comments on commit 4cc41bc

Please sign in to comment.