Skip to content

Commit

Permalink
Update python minimum to 3.10, remove pkg_resources (#184)
Browse files Browse the repository at this point in the history
Remove pkg_resources dependency, and update minimum required python
to 3.10 so that we get the stable API for importlib.metadata.

Update CI to reflect new minimum version and run pyupgrade/ruff safe
fixes for migrating to the new minimum support level.

Fixes #180.

Co-authored-by: Nicholas Devenish <[email protected]>
  • Loading branch information
rtuck99 and ndevenish authored Oct 30, 2024
1 parent 5872b45 commit 281dd60
Show file tree
Hide file tree
Showing 17 changed files with 108 additions and 91 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
python-version: ["3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -57,9 +57,9 @@ jobs:
permissions:
id-token: write
steps:
- uses: actions/download-artifact@v4
with:
- uses: actions/download-artifact@v4
with:
name: artifact
path: dist
- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@ec4db0b4ddc65acdf4bff5fa45ac92d78b56bdf0
- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@ec4db0b4ddc65acdf4bff5fa45ac92d78b56bdf0
6 changes: 1 addition & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,11 @@ classifiers = [
"Intended Audience :: Developers",
"License :: OSI Approved :: BSD License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Operating System :: OS Independent",
"Topic :: Software Development :: Libraries :: Python Modules",
]
license = { text = "BSD-3-Clause" }
requires-python = ">=3.8"
requires-python = ">=3.10"
dependencies = ["bidict", "pika", "setuptools", "stomp-py>=7"]

[project.urls]
Expand Down
4 changes: 2 additions & 2 deletions src/workflows/contrib/status_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import curses
import threading
import time
from typing import Any, Dict
from typing import Any

import workflows.transport
from workflows.services.common_service import CommonService
Expand All @@ -19,7 +19,7 @@ class Monitor: # pragma: no cover
shutdown = False
"""Set to true to end the main loop and shut down the service monitor."""

cards: Dict[Any, Any] = {}
cards: dict[Any, Any] = {}
"""Register card shown for seen services"""

border_chars = ()
Expand Down
3 changes: 2 additions & 1 deletion src/workflows/recipe/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from __future__ import annotations

import functools
from typing import Any, Callable
from collections.abc import Callable
from typing import Any

from workflows.recipe.recipe import Recipe
from workflows.recipe.validate import validate_recipe
Expand Down
4 changes: 2 additions & 2 deletions src/workflows/recipe/recipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import copy
import json
import string
from typing import Any, Dict
from typing import Any

import workflows

Expand All @@ -15,7 +15,7 @@ class Recipe:
A recipe describes how all involved services are connected together, how
data should be passed and how errors should be handled."""

recipe: Dict[Any, Any] = {}
recipe: dict[Any, Any] = {}
"""The processing recipe is encoded in this dictionary."""
# TODO: Describe format

Expand Down
3 changes: 2 additions & 1 deletion src/workflows/recipe/wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import logging
import time
from typing import Any, Callable
from collections.abc import Callable
from typing import Any

import workflows.recipe

Expand Down
7 changes: 2 additions & 5 deletions src/workflows/services/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

import pkg_resources
from importlib.metadata import entry_points


def lookup(service: str):
Expand All @@ -25,10 +25,7 @@ def get_known_services():
setattr(
get_known_services,
"cache",
{
e.name: e.load
for e in pkg_resources.iter_entry_points("workflows.services")
},
{e.name: e.load for e in entry_points(group="workflows.services")},
)
register = get_known_services.cache.copy()
return register
4 changes: 2 additions & 2 deletions src/workflows/services/common_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import queue
import threading
import time
from typing import Any, Dict
from typing import Any

import workflows
import workflows.logging
Expand Down Expand Up @@ -128,7 +128,7 @@ def in_shutdown(self):

# Any keyword arguments set on service invocation

start_kwargs: Dict[Any, Any] = {}
start_kwargs: dict[Any, Any] = {}

# Not so overrideable functions ---------------------------------------------

Expand Down
14 changes: 5 additions & 9 deletions src/workflows/transport/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@

import argparse
import optparse
from typing import TYPE_CHECKING, Type

import pkg_resources
from importlib.metadata import entry_points
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from .common_transport import CommonTransport

default_transport = "PikaTransport"


def lookup(transport: str) -> Type[CommonTransport]:
def lookup(transport: str) -> type[CommonTransport]:
"""Get a transport layer class based on its name."""
return get_known_transports().get(
transport, get_known_transports()[default_transport]
Expand Down Expand Up @@ -55,15 +54,12 @@ def add_command_line_options(
transport().add_command_line_options(parser)


def get_known_transports() -> dict[str, Type[CommonTransport]]:
def get_known_transports() -> dict[str, type[CommonTransport]]:
"""Return a dictionary of all known transport mechanisms."""
if not hasattr(get_known_transports, "cache"):
setattr(
get_known_transports,
"cache",
{
e.name: e.load()
for e in pkg_resources.iter_entry_points("workflows.transport")
},
{e.name: e.load() for e in entry_points(group="workflows.transport")},
)
return get_known_transports.cache.copy() # type: ignore
23 changes: 12 additions & 11 deletions src/workflows/transport/common_transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import decimal
import logging
from typing import Any, Callable, Dict, Mapping, NamedTuple, Optional, Set, Type
from collections.abc import Callable, Mapping
from typing import Any, NamedTuple

import workflows
from workflows.transport import middleware
Expand All @@ -20,9 +21,9 @@ class CommonTransport:
subscriptions and transactions."""

__callback_interceptor = None
__subscriptions: Dict[int, Dict[str, Any]] = {}
__subscriptions: dict[int, dict[str, Any]] = {}
__subscription_id: int = 0
__transactions: Set[int] = set()
__transactions: set[int] = set()
__transaction_id: int = 0

log = logging.getLogger("workflows.transport")
Expand All @@ -32,14 +33,14 @@ class CommonTransport:
#

def __init__(
self, middleware: list[Type[middleware.BaseTransportMiddleware]] = None
self, middleware: list[type[middleware.BaseTransportMiddleware]] = None
):
if middleware is None:
self.middleware = []
else:
self.middleware = middleware

def add_middleware(self, middleware: Type[middleware.BaseTransportMiddleware]):
def add_middleware(self, middleware: type[middleware.BaseTransportMiddleware]):
self.middleware.insert(0, middleware)

@classmethod
Expand Down Expand Up @@ -99,7 +100,7 @@ def mangled_callback(header, message):

@middleware.wrap
def subscribe_temporary(
self, channel_hint: Optional[str], callback: MessageCallback, **kwargs
self, channel_hint: str | None, callback: MessageCallback, **kwargs
) -> TemporarySubscription:
"""Listen to a new queue that is specifically created for this connection,
and has a limited lifetime. Notify for messages via callback function.
Expand Down Expand Up @@ -320,7 +321,7 @@ def broadcast_status(self, status: dict) -> None:
raise NotImplementedError

@middleware.wrap
def ack(self, message, subscription_id: Optional[int] = None, **kwargs):
def ack(self, message, subscription_id: int | None = None, **kwargs):
"""Acknowledge receipt of a message. This only makes sense when the
'acknowledgement' flag was set for the relevant subscription.
:param message: ID of the message to be acknowledged, OR a dictionary
Expand Down Expand Up @@ -351,7 +352,7 @@ def ack(self, message, subscription_id: Optional[int] = None, **kwargs):
self._ack(message_id, subscription_id=subscription_id, **kwargs)

@middleware.wrap
def nack(self, message, subscription_id: Optional[int] = None, **kwargs):
def nack(self, message, subscription_id: int | None = None, **kwargs):
"""Reject receipt of a message. This only makes sense when the
'acknowledgement' flag was set for the relevant subscription.
:param message: ID of the message to be rejected, OR a dictionary
Expand Down Expand Up @@ -380,7 +381,7 @@ def nack(self, message, subscription_id: Optional[int] = None, **kwargs):
self._nack(message_id, subscription_id=subscription_id, **kwargs)

@middleware.wrap
def transaction_begin(self, subscription_id: Optional[int] = None, **kwargs) -> int:
def transaction_begin(self, subscription_id: int | None = None, **kwargs) -> int:
"""Start a new transaction.
:param **kwargs: Further parameters for the transport layer.
:return: A transaction ID that can be passed to other functions.
Expand Down Expand Up @@ -462,7 +463,7 @@ def _subscribe_broadcast(self, sub_id: int, channel, callback, **kwargs):
def _subscribe_temporary(
self,
sub_id: int,
channel_hint: Optional[str],
channel_hint: str | None,
callback: MessageCallback,
**kwargs,
) -> str:
Expand Down Expand Up @@ -530,7 +531,7 @@ def _nack(self, message_id, subscription_id, **kwargs):
raise NotImplementedError("Transport interface not implemented")

def _transaction_begin(
self, transaction_id: int, *, subscription_id: Optional[int] = None, **kwargs
self, transaction_id: int, *, subscription_id: int | None = None, **kwargs
) -> None:
"""Start a new transaction.
:param transaction_id: ID for this transaction in the transport layer.
Expand Down
17 changes: 9 additions & 8 deletions src/workflows/transport/middleware/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import inspect
import logging
import time
from typing import TYPE_CHECKING, Callable, Optional
from collections.abc import Callable
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from workflows.transport.common_transport import (
Expand Down Expand Up @@ -36,7 +37,7 @@ def subscribe(self, call_next: Callable, channel, callback, **kwargs) -> int:
def subscribe_temporary(
self,
call_next: Callable,
channel_hint: Optional[str],
channel_hint: str | None,
callback: MessageCallback,
**kwargs,
) -> TemporarySubscription:
Expand Down Expand Up @@ -74,7 +75,7 @@ def ack(
self,
call_next: Callable,
message,
subscription_id: Optional[int] = None,
subscription_id: int | None = None,
**kwargs,
):
call_next(message, subscription_id=subscription_id, **kwargs)
Expand All @@ -83,13 +84,13 @@ def nack(
self,
call_next: Callable,
message,
subscription_id: Optional[int] = None,
subscription_id: int | None = None,
**kwargs,
):
call_next(message, subscription_id=subscription_id, **kwargs)

def transaction_begin(
self, call_next: Callable, subscription_id: Optional[int] = None, **kwargs
self, call_next: Callable, subscription_id: int | None = None, **kwargs
) -> int:
return call_next(subscription_id=subscription_id, **kwargs)

Expand Down Expand Up @@ -136,7 +137,7 @@ def ack(
self,
call_next: Callable,
message,
subscription_id: Optional[int] = None,
subscription_id: int | None = None,
**kwargs,
):
call_next(message, subscription_id=subscription_id, **kwargs)
Expand All @@ -147,7 +148,7 @@ def nack(
self,
call_next: Callable,
message,
subscription_id: Optional[int] = None,
subscription_id: int | None = None,
**kwargs,
):
call_next(message, subscription_id=subscription_id, **kwargs)
Expand Down Expand Up @@ -195,7 +196,7 @@ def wrapped_callback(header, message):
def subscribe_temporary(
self,
call_next: Callable,
channel_hint: Optional[str],
channel_hint: str | None,
callback: MessageCallback,
**kwargs,
) -> TemporarySubscription:
Expand Down
8 changes: 4 additions & 4 deletions src/workflows/transport/middleware/prometheus.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import functools
import time
from typing import Callable, Optional
from collections.abc import Callable

from prometheus_client import Counter, Gauge, Histogram

Expand Down Expand Up @@ -100,7 +100,7 @@ def wrapped_callback(header, message):
def subscribe_temporary(
self,
call_next: Callable,
channel_hint: Optional[str],
channel_hint: str | None,
callback: MessageCallback,
**kwargs,
) -> TemporarySubscription:
Expand Down Expand Up @@ -155,7 +155,7 @@ def ack(
self,
call_next: Callable,
message,
subscription_id: Optional[int] = None,
subscription_id: int | None = None,
**kwargs,
):
ACKS.labels(source=self.source).inc()
Expand All @@ -165,7 +165,7 @@ def nack(
self,
call_next: Callable,
message,
subscription_id: Optional[int] = None,
subscription_id: int | None = None,
**kwargs,
):
NACKS.labels(source=self.source).inc()
Expand Down
Loading

0 comments on commit 281dd60

Please sign in to comment.