Fix ruff lint findings across client, protocol, and tests
Resolve 51 findings from the I/RUF/BLE/TRY002/S110/PLR0402 rule set: - Sort imports and __all__ (I001, RUF022, PLR0402). The sys.path.insert calls in check_public_calls.py and tests/test_e2e.py still precede the openttd imports that depend on them. - Replace unused unpacked values with _ (RUF059) and annotate the two timetable lookup tables as ClassVar (RUF012). - Narrow the best-effort excepts in OpenTTDClient.quit and OpenTTDAdminClient.quit to (OSError, SocketClosed) and log at debug rather than swallowing silently (BLE001, S110). The test doubles now raise an OSError subclass so they still exercise that branch. - Narrow the gamescript JSON fallback to json.JSONDecodeError. The broad catch in receive_packet keeps a noqa: it guards untrusted wire data and must degrade to a no-op packet instead of killing the connection. - Use contextlib.suppress instead of try/except/pass in tests. ruff check . is clean, 102 tests pass, coverage stays at 100%. Co-Authored-By: Claude <[email protected]>
This commit is contained in:
+46
-17
@@ -1,18 +1,42 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import uuid
|
||||
import monocypher
|
||||
import os
|
||||
import hashlib
|
||||
from openttd_protocol.wire.write import write_init, write_string, write_uint8, write_uint16, write_uint32, write_presend, SEND_TCP_MTU
|
||||
import logging
|
||||
import os
|
||||
import uuid
|
||||
from typing import ClassVar
|
||||
|
||||
import monocypher
|
||||
from openttd_protocol.wire.exceptions import SocketClosed
|
||||
from openttd_protocol.wire.read import read_uint8, read_uint16
|
||||
from .protocol import (
|
||||
PacketGameType, OpenTTDProtocol, PacketAdminType, OpenTTDAdminProtocol, NetworkAuthenticationMethod,
|
||||
GameCommand, ModifyTimetableFlags, ModifyTimetableCtrlFlag,
|
||||
OrderType, OrderStopLocation, INVALID_VEH_ORDER_ID,
|
||||
write_varuint, read_varuint, write_varuint_signed, read_varuint_signed
|
||||
from openttd_protocol.wire.write import (
|
||||
SEND_TCP_MTU,
|
||||
write_init,
|
||||
write_presend,
|
||||
write_string,
|
||||
write_uint8,
|
||||
write_uint16,
|
||||
write_uint32,
|
||||
)
|
||||
|
||||
from .decorators import exclude_call_check
|
||||
from .protocol import (
|
||||
INVALID_VEH_ORDER_ID,
|
||||
GameCommand,
|
||||
ModifyTimetableCtrlFlag,
|
||||
ModifyTimetableFlags,
|
||||
NetworkAuthenticationMethod,
|
||||
OpenTTDAdminProtocol,
|
||||
OpenTTDProtocol,
|
||||
OrderStopLocation,
|
||||
OrderType,
|
||||
PacketAdminType,
|
||||
PacketGameType,
|
||||
read_varuint,
|
||||
read_varuint_signed,
|
||||
write_varuint,
|
||||
write_varuint_signed,
|
||||
)
|
||||
|
||||
|
||||
class OpenTTDClient:
|
||||
"""High-level OpenTTD client for easy integration."""
|
||||
@@ -261,8 +285,9 @@ class OpenTTDClient:
|
||||
try:
|
||||
d = write_init(PacketGameType.ClientQuit)
|
||||
await self._protocol.send_packet(write_presend(d, SEND_TCP_MTU))
|
||||
except Exception:
|
||||
pass
|
||||
except (OSError, SocketClosed) as e:
|
||||
# Best-effort courtesy packet: the socket may already be gone.
|
||||
self.log.debug(f"Could not send quit packet: {e}")
|
||||
self._transport.close()
|
||||
self.shutdown_event.set()
|
||||
|
||||
@@ -386,7 +411,7 @@ class OpenTTDClient:
|
||||
async def receive_ServerMapData(self, source, **kwargs): pass
|
||||
async def receive_ServerConfigurationUpdate(self, source, **kwargs): pass
|
||||
async def receive_ServerExternalChat(self, source, **kwargs): pass
|
||||
_TIMETABLE_FIELD_BY_FLAG = {
|
||||
_TIMETABLE_FIELD_BY_FLAG: ClassVar[dict[ModifyTimetableFlags, str]] = {
|
||||
ModifyTimetableFlags.WaitTime: "wait_time",
|
||||
ModifyTimetableFlags.TravelTime: "travel_time",
|
||||
ModifyTimetableFlags.TravelSpeed: "travel_speed",
|
||||
@@ -395,7 +420,10 @@ class OpenTTDClient:
|
||||
ModifyTimetableFlags.SetLeaveType: "leave_type",
|
||||
ModifyTimetableFlags.AssignSchedule: "assigned_schedule",
|
||||
}
|
||||
_TIMETABLE_BOOL_FLAGS = {ModifyTimetableFlags.SetWaitFixed, ModifyTimetableFlags.SetTravelFixed}
|
||||
_TIMETABLE_BOOL_FLAGS: ClassVar[set[ModifyTimetableFlags]] = {
|
||||
ModifyTimetableFlags.SetWaitFixed,
|
||||
ModifyTimetableFlags.SetTravelFixed,
|
||||
}
|
||||
|
||||
async def receive_ServerCommand(self, source, cmd, payload, **kwargs):
|
||||
if cmd == GameCommand.ChangeTimetable:
|
||||
@@ -512,8 +540,9 @@ class OpenTTDAdminClient:
|
||||
try:
|
||||
d = write_init(PacketAdminType.AdminQuit)
|
||||
await self._protocol.send_packet(write_presend(d, SEND_TCP_MTU))
|
||||
except Exception:
|
||||
pass
|
||||
except (OSError, SocketClosed) as e:
|
||||
# Best-effort courtesy packet: the socket may already be gone.
|
||||
self.log.debug(f"Could not send admin quit packet: {e}")
|
||||
self._transport.close()
|
||||
self.shutdown_event.set()
|
||||
|
||||
@@ -597,7 +626,7 @@ class OpenTTDAdminClient:
|
||||
Raises asyncio.TimeoutError if no reply arrives within `timeout`, ValueError on an error
|
||||
reply, and ConnectionError if the admin connection drops while waiting.
|
||||
"""
|
||||
from .protocol import AdminUpdateType, AdminUpdateFrequency
|
||||
from .protocol import AdminUpdateFrequency, AdminUpdateType
|
||||
if not self._gs_subscribed:
|
||||
await self.update_frequency(AdminUpdateType.Gamescript, AdminUpdateFrequency.Automatic)
|
||||
self._gs_subscribed = True
|
||||
|
||||
Reference in New Issue
Block a user