Skip to content

Commit

Permalink
chore: Add ruff lint configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
jpmckinney committed Sep 16, 2024
1 parent 982b764 commit 0b3c2c3
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 87 deletions.
29 changes: 8 additions & 21 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,32 +49,19 @@ target-version = "py310"
[tool.ruff.lint]
select = ["ALL"]
ignore = [
"ANN", "COM", "EM",
# https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules
"W191", "D206", "Q000", "Q001", "Q002", "Q003", "ISC001",
"D203", "D212", # incompatible rules
"D200", # documentation preferences
"C901", "PLR091", # complexity preferences
"D100", "D104", # docstrings
"ARG001", "ARG002", # unused arguments (callbacks)
"PYI024", # Python 3.10 has no generic namedtuples
"ANN", "C901", "COM812", "D203", "D212", "D415", "EM", "PERF203", "PLR091", "Q000",
"D100", "D104",
"D200", # https://github.com/astral-sh/ruff/issues/6269
"PYI024", # 3.11+
]

[tool.ruff.lint.flake8-builtins]
builtins-ignorelist = ["copyright"]

[tool.ruff.lint.per-file-ignores]
"docs/conf.py" = ["INP001"] # no __init__.py file
"docs/conf.py" = ["D100", "INP001"]
"tests/*" = [
"D", # docstring
"ARG001", # unused pytest fixture
"FBT003", # boolean positional value
"PLR2004", # unnamed constant value
"PT004", # fixture naming convention
"S101", # assert
"TRY002", # raise
]
"tests/fixtures/*" = [
"INP001", # no __init__.py file
"T201", # print
"ARG001", "D", "FBT003", "INP001", "PLR2004", "S", "TRY003",
]
"tests/fixtures/*" = ["T201"] # print
"yapw/clients.py" = ["ARG002"] # pika
64 changes: 16 additions & 48 deletions yapw/clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,7 @@ def publish(
# By adding our own handlers, SIGINT never reaches asyncio.
# https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.add_signal_handler
def add_signal_handlers(self, handler: Callable[..., object]) -> None:
"""
Add handlers for the SIGTERM and SIGINT signals, if the current thread is the main thread.
"""
"""Add handlers for the SIGTERM and SIGINT signals, if the current thread is the main thread."""
if threading.current_thread() is threading.main_thread():
self.add_signal_handler(signal.SIGTERM, handler)
self.add_signal_handler(signal.SIGINT, handler)
Expand All @@ -188,29 +186,21 @@ def add_signal_handler(self, signalnum: int, handler: Callable[..., object]) ->
raise NotImplementedError

def interrupt(self) -> None:
"""
Override this method in subclasses to shut down gracefully (e.g. wait for threads to terminate).
"""
"""Override this method in subclasses to shut down gracefully (e.g. wait for threads to terminate)."""

@property
def state(self): # type: ignore[no-untyped-def] # anonymous class
"""
A named tuple of attributes that can be used within threads.
"""
"""A named tuple of attributes that can be used within threads."""
# Don't pass `self` to the callback, to prevent use of unsafe attributes and mutation of safe attributes.
cls = namedtuple("State", self.__safe__) # type: ignore[misc] # python/mypy#848 "just never will happen"
return cls(**{attr: getattr(self, attr) for attr in self.__safe__})


class Blocking(Base[pika.BlockingConnection]):
"""
Uses Pika's :class:`BlockingConnection adapter<pika.adapters.blocking_connection.BlockingConnection>`.
"""
"""Uses Pika's :class:`BlockingConnection adapter<pika.adapters.blocking_connection.BlockingConnection>`."""

def __init__(self, **kwargs: Any):
"""
Connect to RabbitMQ, create a channel, set the prefetch count, and declare an exchange.
"""
"""Connect to RabbitMQ, create a channel, set the prefetch count, and declare an exchange."""
super().__init__(**kwargs)

#: The connection.
Expand Down Expand Up @@ -306,9 +296,7 @@ def channel_cancel_callback(self, method: pika.spec.Basic.Cancel) -> Any:
self.channel.stop_consuming(self.consumer_tag)

def add_signal_handler(self, signalnum: int, handler: Callable[..., object]) -> None:
"""
Add a handler for a signal.
"""
"""Add a handler for a signal."""
signal.signal(signalnum, handler)

def _on_signal_callback(self, signalnum: int, frame: FrameType | None) -> None:
Expand All @@ -318,15 +306,11 @@ def _on_signal_callback(self, signalnum: int, frame: FrameType | None) -> None:
self.interrupt()

def interrupt(self) -> None:
"""
Cancel the consumer, which causes the threads to terminate and the connection to close.
"""
"""Cancel the consumer, which causes the threads to terminate and the connection to close."""
self.channel.stop_consuming(self.consumer_tag)

def close(self) -> None:
"""
Close the connection: for example, after sending messages from a simple publisher.
"""
"""Close the connection: for example, after sending messages from a simple publisher."""
self.connection.close()


Expand Down Expand Up @@ -362,9 +346,7 @@ class Async(Base[AsyncioConnection]):
RECONNECT_DELAY = 15

def __init__(self, **kwargs: Any):
"""
Initialize the client's state.
"""
"""Initialize the client's state."""
super().__init__(**kwargs)

#: The thread pool executor.
Expand All @@ -376,23 +358,17 @@ def __init__(self, **kwargs: Any):

@property
def thread_name_infix(self) -> str:
"""
Return the exchange name to use as part of the thread name.
"""
"""Return the exchange name to use as part of the thread name."""
return self.exchange

def start(self) -> None:
"""
:meth:`Connect<yapw.clients.Async.connect>` to RabbitMQ, add signal handlers, and start the IO loop.
"""
""":meth:`Connect<yapw.clients.Async.connect>` to RabbitMQ, add signal handlers, and start the IO loop."""
self.connect()
self.add_signal_handlers(self._on_signal_callback)
self.connection.ioloop.run_forever()

def connect(self) -> None:
"""
Connect to RabbitMQ, create a channel, set the prefetch count, and declare an exchange.
"""
"""Connect to RabbitMQ, create a channel, set the prefetch count, and declare an exchange."""
self.connection = AsyncioConnection(
self.parameters,
on_open_callback=self.connection_open_callback,
Expand Down Expand Up @@ -421,9 +397,7 @@ def connection_unblocked_callback(self, connection: pika.connection.Connection,
self.blocked = False

def reconnect(self) -> None:
"""
Reconnect to RabbitMQ, unless a signal was received while the timer was running. If so, stop the IO loop.
"""
"""Reconnect to RabbitMQ, unless a signal was received while the timer was running. If so, stop the IO loop."""
if self.stopping:
self.connection.ioloop.stop()
else:
Expand Down Expand Up @@ -461,9 +435,7 @@ def connection_close_callback(self, connection: pika.connection.Connection, reas
self.reset()

def add_signal_handler(self, signalnum: int, handler: Callable[..., object]) -> None:
"""
Add a handler for a signal.
"""
"""Add a handler for a signal."""
self.connection.ioloop.add_signal_handler(signalnum, partial(handler, signalnum=signalnum))

def _on_signal_callback(self, signalnum: int) -> None:
Expand Down Expand Up @@ -600,9 +572,7 @@ def __init__(

@property
def thread_name_infix(self) -> str:
"""
Return the queue name to use as part of the thread name.
"""
"""Return the queue name to use as part of the thread name."""
return self.queue

def exchange_ready(self) -> None:
Expand Down Expand Up @@ -661,6 +631,4 @@ def channel_cancel_callback(self, method: Any) -> Any: # https://github.com/qub
self.connection.ioloop.call_later(0, self.channel.close)

def channel_consumeok_callback(self, method: pika.frame.Method[pika.spec.Basic.ConsumeOk]) -> None:
"""
Override this method in subclasses to perform any other work, once the consumer is started.
"""
"""Override this method in subclasses to perform any other work, once the consumer is started."""
8 changes: 2 additions & 6 deletions yapw/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,7 @@ def discard(
properties: pika.BasicProperties,
body: bytes,
) -> None:
"""
If the ``callback`` function raises an exception, nack the message, without requeueing.
"""
"""If the ``callback`` function raises an exception, nack the message, without requeueing."""

def errback(_exception: Exception) -> None:
logger.exception("Unhandled exception when consuming %r, discarding message", body)
Expand All @@ -135,9 +133,7 @@ def requeue(
properties: pika.BasicProperties,
body: bytes,
) -> None:
"""
If the ``callback`` function raises an exception, nack the message, requeueing it unless it was redelivered.
"""
"""If the ``callback`` function raises an exception, nack the message, requeueing it unless it was redelivered."""

def errback(_exception: Exception) -> None:
requeue = not method.redelivered
Expand Down
4 changes: 1 addition & 3 deletions yapw/methods.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
"""
Functions for calling channel methods from a consumer callback running in another thread.
"""
"""Functions for calling channel methods from a consumer callback running in another thread."""

import functools
import logging
Expand Down
12 changes: 3 additions & 9 deletions yapw/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@
if sys.version_info >= (3, 11):

class State(NamedTuple, Generic[T]):
"""
Attributes that can be used safely in consumer callbacks.
"""
"""Attributes that can be used safely in consumer callbacks."""

#: A function to format the routing key.
format_routing_key: Callable[[str], str]
Expand All @@ -34,9 +32,7 @@ class State(NamedTuple, Generic[T]):
else:

class State(NamedTuple):
"""
Attributes that can be used safely in consumer callbacks.
"""
"""Attributes that can be used safely in consumer callbacks."""

#: A function to format the routing key.
format_routing_key: Callable[[str], str]
Expand All @@ -55,9 +51,7 @@ class State(NamedTuple):


class PublishKeywords(TypedDict, total=False):
"""
Keyword arguments for ``basic_publish``.
"""
"""Keyword arguments for ``basic_publish``."""

#: The exchange to publish to.
exchange: str
Expand Down

0 comments on commit 0b3c2c3

Please sign in to comment.