diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 629238bdc..b38542516 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -1,4 +1,4 @@ -name: Check +name: check on: push: branches: @@ -27,3 +27,24 @@ jobs: - name: Run format check run: uv run ruff format --check + + lint: + runs-on: ubuntu-latest + name: lint + steps: + - name: Check out repository + uses: actions/checkout@v5 + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: "3.8" + + - name: Install uv + uses: astral-sh/setup-uv@v6 + + - name: Install the project + run: uv sync --dev + + - name: Run lint check + run: uv run ruff check diff --git a/nats-server/src/nats/server/__init__.py b/nats-server/src/nats/server/__init__.py index 7a50cab32..98f1bca31 100644 --- a/nats-server/src/nats/server/__init__.py +++ b/nats-server/src/nats/server/__init__.py @@ -24,7 +24,6 @@ import os import re import socket -import tempfile from typing import Self # Set up logging diff --git a/nats/examples/advanced.py b/nats/examples/advanced.py index 35e55401c..a525aff45 100644 --- a/nats/examples/advanced.py +++ b/nats/examples/advanced.py @@ -1,8 +1,9 @@ import asyncio -import nats from nats.errors import NoServersError, TimeoutError +import nats + async def main(): async def disconnected_cb(): diff --git a/nats/examples/basic.py b/nats/examples/basic.py index b2da95b7d..e1a97d134 100644 --- a/nats/examples/basic.py +++ b/nats/examples/basic.py @@ -1,9 +1,10 @@ import asyncio -import nats from common import args from nats.errors import TimeoutError +import nats + async def main(): arguments, _ = args.get_args("Run a basic example.") @@ -33,7 +34,7 @@ async def message_handler(msg): async for msg in sub.messages: print(f"Received a message on '{msg.subject} {msg.reply}': {msg.data.decode()}") await sub.unsubscribe() - except Exception as e: + except Exception: pass async def help_request(msg): diff --git a/nats/examples/clustered.py b/nats/examples/clustered.py index f68041808..013f81bfc 100644 --- a/nats/examples/clustered.py +++ b/nats/examples/clustered.py @@ -1,9 +1,10 @@ import asyncio from datetime import datetime -import nats from nats.aio.errors import ErrConnectionClosed, ErrNoServers, ErrTimeout +import nats + async def run(): # Setup pool of servers from a NATS cluster. @@ -66,7 +67,7 @@ async def subscribe_handler(msg): try: await nc.publish(f"help.{i}", b"A") await nc.flush(0.500) - except ErrConnectionClosed as e: + except ErrConnectionClosed: print("Connection closed prematurely.") break except ErrTimeout as e: diff --git a/nats/examples/connect.py b/nats/examples/connect.py index 9e2da3c44..d2a7d1140 100644 --- a/nats/examples/connect.py +++ b/nats/examples/connect.py @@ -1,8 +1,9 @@ import asyncio -import nats from common import args +import nats + async def main(): async def disconnected_cb(): diff --git a/nats/examples/context-manager.py b/nats/examples/context-manager.py index d7138faee..9e0a4cdc8 100644 --- a/nats/examples/context-manager.py +++ b/nats/examples/context-manager.py @@ -1,8 +1,9 @@ import asyncio -import nats from common import args +import nats + async def main(): is_done = asyncio.Future() diff --git a/nats/examples/jetstream.py b/nats/examples/jetstream.py index 63235b6f3..370a12368 100644 --- a/nats/examples/jetstream.py +++ b/nats/examples/jetstream.py @@ -1,8 +1,9 @@ import asyncio -import nats from nats.errors import TimeoutError +import nats + async def main(): nc = await nats.connect("localhost") diff --git a/nats/examples/micro/service.py b/nats/examples/micro/service.py index da4b88804..eaa311c38 100644 --- a/nats/examples/micro/service.py +++ b/nats/examples/micro/service.py @@ -2,9 +2,10 @@ import contextlib import signal -import nats import nats.micro +import nats + async def echo(req) -> None: """Echo the request data back to the client.""" diff --git a/nats/examples/publish.py b/nats/examples/publish.py index ad66da73b..f38128a14 100644 --- a/nats/examples/publish.py +++ b/nats/examples/publish.py @@ -1,8 +1,9 @@ import asyncio -import nats from common import args +import nats + async def main(): arguments, _ = args.get_args("Run a publish example.", "Usage: python examples/publish.py") diff --git a/nats/tests/test_client.py b/nats/tests/test_client.py index aff0dad1b..610e13591 100644 --- a/nats/tests/test_client.py +++ b/nats/tests/test_client.py @@ -8,10 +8,12 @@ import urllib from unittest import mock -import nats import nats.errors import pytest -from nats.aio.client import Client as NATS, ServerVersion, __version__ +from nats.aio.client import Client as NATS +from nats.aio.client import ServerVersion, __version__ + +import nats from tests.utils import ( ClusteringDiscoveryAuthTestCase, ClusteringTestCase, @@ -669,9 +671,9 @@ async def next_msg(): # FIXME: This message would be lost because cannot # reuse the future from the iterator that timed out. - await nc.publish(f"tests.2", b"bar") + await nc.publish("tests.2", b"bar") - await nc.publish(f"tests.3", b"bar") + await nc.publish("tests.3", b"bar") await nc.flush() # FIXME: this test is flaky @@ -717,8 +719,8 @@ async def test_subscribe_next_msg(self): await sub.next_msg(timeout=0.5) # Send again a couple of messages. - await nc.publish(f"tests.2", b"bar") - await nc.publish(f"tests.3", b"bar") + await nc.publish("tests.2", b"bar") + await nc.publish("tests.3", b"bar") await nc.flush() msg = await sub.next_msg() self.assertEqual("tests.2", msg.subject) @@ -2809,7 +2811,7 @@ async def test_drain_cancelled_errors_raised(self): async def cb(msg): await asyncio.sleep(20) - sub = await nc.subscribe(f"test.sub", cb=cb) + sub = await nc.subscribe("test.sub", cb=cb) await nc.publish("test.sub") await nc.publish("test.sub") await asyncio.sleep(0.1) diff --git a/nats/tests/test_client_async_await.py b/nats/tests/test_client_async_await.py index ec1047542..2b7c23f1b 100644 --- a/nats/tests/test_client_async_await.py +++ b/nats/tests/test_client_async_await.py @@ -2,6 +2,7 @@ from nats.aio.client import Client as NATS from nats.errors import SlowConsumerError, TimeoutError + from tests.utils import SingleServerTestCase, async_test diff --git a/nats/tests/test_client_nkeys.py b/nats/tests/test_client_nkeys.py index b7a6d10a5..84aa3319f 100644 --- a/nats/tests/test_client_nkeys.py +++ b/nats/tests/test_client_nkeys.py @@ -11,9 +11,11 @@ except ModuleNotFoundError: nkeys_installed = False -from nats.aio.client import Client as NATS, RawCredentials +from nats.aio.client import Client as NATS +from nats.aio.client import RawCredentials from nats.aio.errors import * from nats.errors import * + from tests.utils import ( NkeysServerTestCase, TrustedServerTestCase, diff --git a/nats/tests/test_client_v2.py b/nats/tests/test_client_v2.py index 54bf8cd4c..034ed7b91 100644 --- a/nats/tests/test_client_v2.py +++ b/nats/tests/test_client_v2.py @@ -1,7 +1,8 @@ import unittest -import nats from nats.aio.errors import * + +import nats from tests.utils import * diff --git a/nats/tests/test_client_websocket.py b/nats/tests/test_client_websocket.py index 654f3b0ca..aea4f253d 100644 --- a/nats/tests/test_client_websocket.py +++ b/nats/tests/test_client_websocket.py @@ -1,9 +1,10 @@ import asyncio import unittest -import nats import pytest from nats.aio.errors import * + +import nats from tests.utils import * try: diff --git a/nats/tests/test_compatibility.py b/nats/tests/test_compatibility.py index efdcc83a0..fee7e16a1 100644 --- a/nats/tests/test_compatibility.py +++ b/nats/tests/test_compatibility.py @@ -7,7 +7,6 @@ from typing import Any, Dict, List, Optional from unittest import TestCase, skipIf -import nats from nats.aio.subscription import Subscription from nats.micro.request import ServiceError from nats.micro.service import ( @@ -18,6 +17,8 @@ ServiceConfig, ) +import nats + from .utils import * try: diff --git a/nats/tests/test_js.py b/nats/tests/test_js.py index 983950228..2e7c23d8c 100644 --- a/nats/tests/test_js.py +++ b/nats/tests/test_js.py @@ -12,7 +12,6 @@ import uuid from hashlib import sha256 -import nats import nats.js.api import pytest from nats.aio.client import Client as NATS @@ -20,6 +19,8 @@ from nats.aio.msg import Msg from nats.errors import * from nats.js.errors import * + +import nats from tests.utils import * try: @@ -204,7 +205,7 @@ async def test_fetch_one(self): await js.add_stream(name="TEST1", subjects=["foo.1", "bar"]) - ack = await js.publish("foo.1", f"Hello from NATS!".encode()) + ack = await js.publish("foo.1", "Hello from NATS!".encode()) assert ack.stream == "TEST1" assert ack.seq == 1 @@ -267,7 +268,7 @@ async def test_fetch_one_wait_forever(self): await js.add_stream(name="TEST111", subjects=["foo.111"]) - ack = await js.publish("foo.111", f"Hello from NATS!".encode()) + ack = await js.publish("foo.111", "Hello from NATS!".encode()) assert ack.stream == "TEST111" assert ack.seq == 1 @@ -940,7 +941,7 @@ async def cb(msg): for msg in msgs: if msg.subject == "events.0": received.append((time.monotonic(), msg)) - except TimeoutError as err: + except TimeoutError: # There should be no timeout as redeliveries should happen faster. break @@ -2754,25 +2755,25 @@ async def error_handler(e): # Nothing from start with pytest.raises(KeyNotFoundError): - await kv.get(f"name") + await kv.get("name") # Simple Put - revision = await kv.put(f"name", b"alice") + revision = await kv.put("name", b"alice") assert revision == 1 # Simple Get - result = await kv.get(f"name") + result = await kv.get("name") assert result.revision == 1 assert result.value == b"alice" # Delete - ok = await kv.delete(f"name") + ok = await kv.delete("name") assert ok # Deleting then getting again should be a not found error still, # although internall this is a KeyDeletedError. with pytest.raises(KeyNotFoundError): - await kv.get(f"name") + await kv.get("name") # Recreate with different name. revision = await kv.create("name", b"bob") @@ -2953,25 +2954,25 @@ async def error_handler(e): # Nothing from start with pytest.raises(KeyNotFoundError): - await kv.get(f"name") + await kv.get("name") # Simple Put - revision = await kv.put(f"name", b"alice") + revision = await kv.put("name", b"alice") assert revision == 1 # Simple Get - result = await kv.get(f"name") + result = await kv.get("name") assert result.revision == 1 assert result.value == b"alice" # Delete - ok = await kv.delete(f"name") + ok = await kv.delete("name") assert ok # Deleting then getting again should be a not found error still, # although internall this is a KeyDeletedError. with pytest.raises(KeyNotFoundError): - await kv.get(f"name") + await kv.get("name") # Recreate with different name. revision = await kv.create("name", b"bob") @@ -3220,7 +3221,7 @@ async def error_handler(e): status = await kv.status() for i in range(0, 50): - await kv.put(f"age", f"{i}".encode()) + await kv.put("age", f"{i}".encode()) vl = await kv.history("age") assert len(vl) == 10 @@ -3317,7 +3318,7 @@ async def error_handler(e): for i in range(0, 10): await kv.delete(f"key-{i}") - await kv.put(f"key-last", b"101") + await kv.put("key-last", b"101") await kv.purge_deletes(olderthan=-1) await asyncio.sleep(0.5) @@ -3339,10 +3340,10 @@ async def error_handler(e): kv = await js.create_key_value(bucket="KVS2", history=10) - await kv.put("foo", f"a".encode()) - await kv.put("bar", f"a".encode()) - await kv.put("bar", f"b".encode()) - await kv.put("foo", f"b".encode()) + await kv.put("foo", "a".encode()) + await kv.put("bar", "a".encode()) + await kv.put("bar", "b".encode()) + await kv.put("foo", "b".encode()) await kv.delete("foo") await asyncio.sleep(0.2) await kv.delete("bar") @@ -3493,7 +3494,7 @@ async def error_handler(e): obs = await js.create_object_store(bucket="OBJS", description="testing") assert obs._name == "OBJS" - assert obs._stream == f"OBJ_OBJS" + assert obs._stream == "OBJ_OBJS" # Check defaults. status = await obs.status() diff --git a/nats/tests/test_micro_service.py b/nats/tests/test_micro_service.py index 6e079ab1b..2dc0212ce 100644 --- a/nats/tests/test_micro_service.py +++ b/nats/tests/test_micro_service.py @@ -1,11 +1,12 @@ import asyncio import random -import nats import nats.micro from nats.micro import * from nats.micro.request import * from nats.micro.service import * + +import nats from tests.utils import SingleServerTestCase, async_test diff --git a/nats/tests/test_parser.py b/nats/tests/test_parser.py index df638b639..7d83f1b1e 100644 --- a/nats/tests/test_parser.py +++ b/nats/tests/test_parser.py @@ -4,6 +4,7 @@ from nats.aio.client import Subscription from nats.errors import ProtocolError from nats.protocol.parser import * + from tests.utils import async_test diff --git a/pyproject.toml b/pyproject.toml index 4c175d257..3f14c62fe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,6 +26,13 @@ target-version = "py37" select = ["E", "F", "W", "I"] ignore = ["E501"] +[tool.ruff.lint.per-file-ignores] +"nats/examples/*" = ["E722", "F821", "F841", "I001", "W291"] +"nats/benchmark/*" = ["E722", "F403", "F405"] +"nats/tests/*" = ["F403", "F405", "F841", "E711", "E402", "I001", "E722", "F601", "E712", "F401"] +"nats/src/nats/micro/__init__.py" = ["F401"] +"nats/src/nats/nuid.py" = ["E741"] + [tool.ruff.format] quote-style = "double" indent-style = "space"