From 8a7a47b2c551de9ce3a6d0b66df0c6eda8b4cf3b Mon Sep 17 00:00:00 2001 From: Flummy1 <82732824+Flummy1@users.noreply.github.com> Date: Tue, 30 Jun 2026 14:07:16 +0300 Subject: [PATCH] chore: fix ruff and mypy strict checks --- .gitattributes | 8 ++++ funpaybotengine/client/bot.py | 7 +++- .../exceptions/method_exceptions.py | 39 +++++++++---------- funpaybotengine/methods/__init__.py | 2 +- funpaybotengine/methods/raise_offers.py | 6 +-- funpaybotengine/methods/refund.py | 4 +- funpaybotengine/methods/save_offer_fields.py | 23 +++++------ funpaybotengine/runner/event_collector.py | 6 ++- funpaybotengine/runner/runner.py | 18 ++++----- funpaybotengine/types/__init__.py | 2 +- funpaybotengine/types/calc.py | 3 +- funpaybotengine/types/offers.py | 3 +- funpaybotengine/types/pages/__init__.py | 2 +- 13 files changed, 69 insertions(+), 54 deletions(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..94c0ef5 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,8 @@ +* text=auto + +*.py text eol=lf +*.toml text eol=lf +*.yaml text eol=lf +*.yml text eol=lf +*.md text eol=lf +Makefile text eol=lf diff --git a/funpaybotengine/client/bot.py b/funpaybotengine/client/bot.py index c8d902a..1189fe6 100644 --- a/funpaybotengine/client/bot.py +++ b/funpaybotengine/client/bot.py @@ -25,9 +25,9 @@ TransactionFilter, OrderPreviewsBatch, PrivateChatPreview, + RaiseOffersResponse, TransactionPreviewsBatch, CurrentlyViewingOfferInfo, - RaiseOffersResponse ) from funpaybotengine.utils import ( random_runner_tag, @@ -466,6 +466,8 @@ async def calc_lots(self, subcategory_id: int, price: float) -> CalcResult: async def logout(self) -> bool: if self._logout_token is None: await self.update() + if self._logout_token is None: + raise BotNotInitializedError(self) return (await Logout(logout_token=self._logout_token).execute(self)).response_obj @@ -602,7 +604,8 @@ async def get_chat_messages( :param args: Tuple of (chat_id, after_message_id) - :returns: A dictionary [chat_id, list] or a list of up to 100 ``Message`` objects, sorted from oldest to newest. + :returns: A dictionary [chat_id, list] or a list of up to 100 ``Message`` objects, + sorted from oldest to newest. """ if not args and chat_id is None: raise ValueError('Either `chat_id` or `args` must be provided.') diff --git a/funpaybotengine/exceptions/method_exceptions.py b/funpaybotengine/exceptions/method_exceptions.py index a545c8b..4351fa9 100644 --- a/funpaybotengine/exceptions/method_exceptions.py +++ b/funpaybotengine/exceptions/method_exceptions.py @@ -1,20 +1,19 @@ -__all__ = [ - 'MethodError', - 'InvalidOfferFieldsError' -] - - -from .base import FunPayBotEngineError - - -class MethodError(FunPayBotEngineError): - ... - - -class InvalidOfferFieldsError(MethodError): - def __init__(self, message: str, fields: dict[str, str] | None = None): - self.message = message - self.fields = fields - - def __str__(self): - return self.message +from __future__ import annotations + + +__all__ = ['MethodError', 'InvalidOfferFieldsError'] + + +from .base import FunPayBotEngineError + + +class MethodError(FunPayBotEngineError): ... + + +class InvalidOfferFieldsError(MethodError): + def __init__(self, message: str, fields: dict[str, str] | None = None): + self.message = message + self.fields = fields + + def __str__(self) -> str: + return self.message diff --git a/funpaybotengine/methods/__init__.py b/funpaybotengine/methods/__init__.py index 2c8e77b..100dba8 100644 --- a/funpaybotengine/methods/__init__.py +++ b/funpaybotengine/methods/__init__.py @@ -28,8 +28,8 @@ from .get_settings_page import * from .save_offer_fields import * from .set_offers_hidden import * -from .get_sras_info_page import * from .get_my_offers_page import * +from .get_sras_info_page import * from .get_subcategory_page import * from .get_transactions_page import * from .update_notice_channel import * diff --git a/funpaybotengine/methods/raise_offers.py b/funpaybotengine/methods/raise_offers.py index df48303..5b4243c 100644 --- a/funpaybotengine/methods/raise_offers.py +++ b/funpaybotengine/methods/raise_offers.py @@ -4,7 +4,7 @@ __all__ = ('RaiseOffers',) import json -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, cast from collections.abc import Sequence from pydantic import Field @@ -12,8 +12,8 @@ from funpaybotengine.types.enums import Language from funpaybotengine.methods.base import FunPayMethod -from funpaybotengine.client.session.http_methods import HTTPMethod from funpaybotengine.types.common import RaiseOffersResponse +from funpaybotengine.client.session.http_methods import HTTPMethod if TYPE_CHECKING: @@ -47,4 +47,4 @@ def __init__( async def parse_result(self, response: RawResponse[bool]) -> dict[str, Any]: data = json.loads(response.raw_response) - return {'raw_source': response.raw_response} | data + return {'raw_source': response.raw_response} | cast(dict[str, Any], data) diff --git a/funpaybotengine/methods/refund.py b/funpaybotengine/methods/refund.py index fa43f11..d449622 100644 --- a/funpaybotengine/methods/refund.py +++ b/funpaybotengine/methods/refund.py @@ -42,11 +42,11 @@ def __init__(self, order_id: str, locale: Language | None = None): async def parse_result(self, response: RawResponse[Any]) -> bool: try: result = json.loads(response.raw_response) - except: + except json.decoder.JSONDecodeError: raise RefundError( order_id=self.order_id, message=f'Unable to refund order {self.order_id}', - ) + ) from None if result.get('error'): raise RefundError( diff --git a/funpaybotengine/methods/save_offer_fields.py b/funpaybotengine/methods/save_offer_fields.py index 5659182..f70f456 100644 --- a/funpaybotengine/methods/save_offer_fields.py +++ b/funpaybotengine/methods/save_offer_fields.py @@ -3,17 +3,17 @@ __all__ = ('SaveOfferFields',) -from typing import Any +import json +from typing import Any, cast from pydantic import BaseModel from funpayparsers.types import Language from funpayparsers.parsers import OfferFieldsParser -from funpaybotengine.exceptions.method_exceptions import InvalidOfferFieldsError from funpaybotengine.methods.base import FunPayMethod from funpaybotengine.types.offers import OfferFields from funpaybotengine.client.session import HTTPMethod, RawResponse -import json +from funpaybotengine.exceptions.method_exceptions import InvalidOfferFieldsError class SaveOfferFields(FunPayMethod[bool], BaseModel): @@ -43,27 +43,28 @@ def __init__( async def parse_result(self, response: RawResponse[Any]) -> bool | dict[str, Any]: try: - return json.loads(response.raw_response) + return cast(dict[str, Any], json.loads(response.raw_response)) except json.decoder.JSONDecodeError: return True async def transform_result( self, parsing_result: bool | dict[str, Any], - response: RawResponse[Any] + response: RawResponse[Any], ) -> bool: if isinstance(parsing_result, bool): return parsing_result - if not parsing_result.get('error'): return True error_msg = str(parsing_result.get('msg', '')) or str(parsing_result.get('error')) - fields: list[list[str, str]] = parsing_result.get('errors') - try: - fields_dict = {field: error for field, error in fields} - except Exception: - fields_dict = {} + raw_fields = parsing_result.get('errors') + fields_dict: dict[str, str] = {} + if isinstance(raw_fields, list): + for item in raw_fields: + if isinstance(item, list) and len(item) == 2: + field, error = item + fields_dict[str(field)] = str(error) raise InvalidOfferFieldsError(error_msg, fields_dict) diff --git a/funpaybotengine/runner/event_collector.py b/funpaybotengine/runner/event_collector.py index 9087b8f..21f4cc3 100644 --- a/funpaybotengine/runner/event_collector.py +++ b/funpaybotengine/runner/event_collector.py @@ -3,6 +3,7 @@ import time from typing import TYPE_CHECKING, Any, Type, Literal, TypeVar, cast from itertools import chain +from collections import ChainMap from collections.abc import Callable from funpaybotengine.types import PrivateChatPreview @@ -53,7 +54,6 @@ from funpaybotengine.storage.base import Storage from funpaybotengine.types.orders import OrderPreview from funpaybotengine.types.updates import RunnerResponse -from collections import ChainMap CHAT_EVENTS = ChatChangedEvent | NewMessageEvent @@ -103,6 +103,7 @@ async def inner(*args: Any, **kwargs: Any) -> Any: except UnexpectedHTTPStatusError: if not attempts: raise + return None return inner # type: ignore @@ -324,7 +325,8 @@ async def get_new_message_events(self, total: EventsPack) -> None: if from_id != 0: if from_id < message.id <= to_id: logger.debug( - 'New message in chat %r (%r): %r (from IDs difference: %r < %r <= %r).', + 'New message in chat %r (%r): %r ' + '(from IDs difference: %r < %r <= %r).', chat_event.chat_preview.username, chat_event.chat_preview.id, message.id, diff --git a/funpaybotengine/runner/runner.py b/funpaybotengine/runner/runner.py index e79bd85..0618891 100644 --- a/funpaybotengine/runner/runner.py +++ b/funpaybotengine/runner/runner.py @@ -9,7 +9,7 @@ import asyncio from typing import TYPE_CHECKING, Any from dataclasses import field, dataclass -from collections.abc import Iterator, AsyncGenerator +from collections.abc import Iterator, Sequence, AsyncGenerator from funpaybotengine.loggers import runner_logger from funpaybotengine.exceptions import UnauthorizedError, BotUnauthenticatedError @@ -41,7 +41,7 @@ def __getitem__(self, item: Any) -> Any: def __setitem__(self, item: Any, value: Any) -> None: self.data[item] = value - def __iter__(self) -> Iterator[RunnerEvent[Any]]: + def __iter__(self) -> Iterator[RunnerEvent[Any] | BotEngineEvent[Any]]: return iter(self.events) def get(self, value: str, fallback: Any = None) -> Any: @@ -60,7 +60,7 @@ async def listen( self, config: RunnerConfig | None = None, session_storage: Storage | None = None, - ) -> AsyncGenerator[tuple[RunnerEvent[Any], EventsStack], None]: + ) -> AsyncGenerator[tuple[RunnerEvent[Any] | BotEngineEvent[Any], EventsStack], None]: config = config or RunnerConfig() collector = EventCollector( self.bot, @@ -74,7 +74,7 @@ async def listen( sleep_time: float | None = None while True: start = time.time() - result: list[RunnerEvent[Any] | BotEngineEvent[Any]] = [] + result: Sequence[RunnerEvent[Any] | BotEngineEvent[Any]] = () try: result = await collector.get_events() @@ -82,7 +82,7 @@ async def listen( backoff.reset() runner_logger.info('Connection established. Continuing collecting events.') if config.on_unauthenticated_error_policy == 'event': - result.insert(0, BotAuthenticatedEvent(object=None)) + result = (BotAuthenticatedEvent(object=None), *result) except (BotUnauthenticatedError, UnauthorizedError) as e: runner_logger.warning( @@ -98,9 +98,9 @@ async def listen( 'Current attempt: %d. Delay: %f.', backoff.counter, backoff.current_delay ) if backoff.counter == 1 and config.on_unauthenticated_error_policy == 'event': - result = [ - BotUnauthenticatedEvent(object=None, delay=backoff.current_delay) - ] + result = ( + BotUnauthenticatedEvent(object=None, delay=backoff.current_delay), + ) elif config.on_unauthenticated_error_policy == 'stop': return @@ -116,7 +116,7 @@ async def listen( events_stack = EventsStack(events=()) if not backoff.counter: - result.insert(0, NewEventsPack(object=events_stack.id)) + result = (NewEventsPack(object=events_stack.id), *result) events_stack.events = tuple(result) for i in events_stack: diff --git a/funpaybotengine/types/__init__.py b/funpaybotengine/types/__init__.py index 0f13264..0cee384 100644 --- a/funpaybotengine/types/__init__.py +++ b/funpaybotengine/types/__init__.py @@ -3,6 +3,7 @@ from .base import * from .calc import * from .chat import * +from .sras import * from .enums import * from .common import * from .offers import * @@ -11,7 +12,6 @@ from .updates import * from .finances import * from .messages import * -from .sras import * from .settings import * from .categories import * from .common_page_elements import * diff --git a/funpaybotengine/types/calc.py b/funpaybotengine/types/calc.py index dd106e2..37a2594 100644 --- a/funpaybotengine/types/calc.py +++ b/funpaybotengine/types/calc.py @@ -16,7 +16,8 @@ class MethodResult(FunPayObject, BaseModel): """ - Represents a result of offer price calculation method (`lots/calc`) for a single payment method. + Represents a result of offer price calculation method (`lots/calc`) for a single + payment method. """ name: str = '' diff --git a/funpaybotengine/types/offers.py b/funpaybotengine/types/offers.py index 4e5ba75..a282226 100644 --- a/funpaybotengine/types/offers.py +++ b/funpaybotengine/types/offers.py @@ -126,7 +126,8 @@ def wrapper(*args: P.args, **kwargs: P.kwargs) -> Any: if not obj.is_common: raise RuntimeError( f'Instance of {obj.__class__.__name__} is not describing a common lot fields.\n' - f'Use {obj.__class__.__name__}.convert_to_common to convert it to common lot fields.', + f'Use {obj.__class__.__name__}.convert_to_common to convert it to common lot ' + 'fields.', ) return func(*args, **kwargs) diff --git a/funpaybotengine/types/pages/__init__.py b/funpaybotengine/types/pages/__init__.py index 9f7ec7b..21a833e 100644 --- a/funpaybotengine/types/pages/__init__.py +++ b/funpaybotengine/types/pages/__init__.py @@ -9,6 +9,6 @@ from .my_chips_page import * from .settings_page import * from .my_offers_page import * -from .subcategory_page import * from .sras_info_page import * +from .subcategory_page import * from .transactions_page import *