Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize classes by adding __slots__ #102

Open
wants to merge 2 commits into
base: dev-2.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/code/polling/events.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
from glQiwiApi import QiwiWallet
from glQiwiApi.core.event_fetching import executor
from glQiwiApi.core.event_fetching.dispatcher import QiwiDispatcher
from glQiwiApi.core.event_fetching.executor import Context
from glQiwiApi.core.event_fetching.executor import HandlerContext
from glQiwiApi.qiwi.clients.wallet.types import Transaction

qiwi_dp = QiwiDispatcher()
wallet = QiwiWallet(api_access_token='token', phone_number='+phone number')


@qiwi_dp.transaction_handler()
async def handle_transaction(t: Transaction, ctx: Context):
async def handle_transaction(t: Transaction, ctx: HandlerContext):
"""Handle transaction here"""
ctx.wallet # this way you can use QiwiWallet instance to avoid global variables


async def on_startup(ctx: Context):
async def on_startup(ctx: HandlerContext):
ctx.wallet # do something here


async def on_shutdown(ctx: Context):
async def on_shutdown(ctx: HandlerContext):
pass


Expand Down
6 changes: 3 additions & 3 deletions docs/code/polling/qiwi.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from glQiwiApi import QiwiWallet
from glQiwiApi.core.event_fetching import executor
from glQiwiApi.core.event_fetching.dispatcher import QiwiDispatcher
from glQiwiApi.core.event_fetching.executor import Context
from glQiwiApi.core.event_fetching.executor import HandlerContext
from glQiwiApi.core.event_fetching.filters import ExceptionFilter
from glQiwiApi.qiwi.clients.wallet.types import Transaction
from glQiwiApi.qiwi.exceptions import QiwiAPIError
Expand All @@ -11,13 +11,13 @@


@qiwi_dp.transaction_handler()
async def handle_transaction(t: Transaction, ctx: Context):
async def handle_transaction(t: Transaction, ctx: HandlerContext):
"""Handle transaction here"""
ctx.wallet # this way you can use QiwiWallet instance to avoid global variables


@qiwi_dp.exception_handler(ExceptionFilter(QiwiAPIError))
async def handle_exception(err: QiwiAPIError, ctx: Context):
async def handle_exception(err: QiwiAPIError, ctx: HandlerContext):
pass


Expand Down
4 changes: 2 additions & 2 deletions docs/code/polling/with_aiogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from glQiwiApi import QiwiWallet
from glQiwiApi.core.event_fetching import executor
from glQiwiApi.core.event_fetching.dispatcher import QiwiDispatcher
from glQiwiApi.core.event_fetching.executor import Context
from glQiwiApi.core.event_fetching.executor import HandlerContext
from glQiwiApi.plugins import AiogramPollingPlugin
from glQiwiApi.qiwi.clients.wallet.types import Transaction

Expand All @@ -15,7 +15,7 @@


@qiwi_dp.transaction_handler()
async def handle_transaction(t: Transaction, ctx: Context):
async def handle_transaction(t: Transaction, ctx: HandlerContext):
"""Handle transaction here"""
ctx.wallet # this way you can use QiwiWallet instance to avoid global variables

Expand Down
7 changes: 5 additions & 2 deletions docs/code/polling/with_aiogram_non_blocking.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@

from glQiwiApi import QiwiWallet
from glQiwiApi.core.event_fetching.dispatcher import QiwiDispatcher
from glQiwiApi.core.event_fetching.executor import Context, start_non_blocking_qiwi_api_polling
from glQiwiApi.core.event_fetching.executor import (
HandlerContext,
start_non_blocking_qiwi_api_polling,
)
from glQiwiApi.qiwi.clients.wallet.types import Transaction

qiwi_dp = QiwiDispatcher()
Expand All @@ -14,7 +17,7 @@


@qiwi_dp.transaction_handler()
async def handle_transaction(t: Transaction, ctx: Context):
async def handle_transaction(t: Transaction, ctx: HandlerContext):
"""Handle transaction here"""


Expand Down
8 changes: 4 additions & 4 deletions docs/code/polling/without_globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from glQiwiApi import QiwiWrapper
from glQiwiApi.core.event_fetching import executor
from glQiwiApi.core.event_fetching.dispatcher import QiwiDispatcher
from glQiwiApi.core.event_fetching.executor import Context
from glQiwiApi.core.event_fetching.executor import HandlerContext
from glQiwiApi.plugins import AiogramPollingPlugin
from glQiwiApi.qiwi.clients.wallet.types import Transaction

Expand All @@ -20,16 +20,16 @@ async def aiogram_message_handler(msg: types.Message):
await msg.answer(text='Привет😇')


async def qiwi_transaction_handler(update: Transaction, ctx: Context):
async def qiwi_transaction_handler(update: Transaction, ctx: HandlerContext):
print(update)


def on_startup(ctx: Context) -> None:
def on_startup(ctx: HandlerContext) -> None:
logger.info('This message logged on startup')
register_handlers(ctx)


def register_handlers(ctx: Context):
def register_handlers(ctx: HandlerContext):
ctx['qiwi_dp'].transaction_handler()(qiwi_transaction_handler)
dispatcher = cast(Dispatcher, ctx['dp'])
dispatcher.register_message_handler(aiogram_message_handler)
Expand Down
4 changes: 2 additions & 2 deletions docs/code/webhooks/qiwi.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from glQiwiApi import QiwiWallet
from glQiwiApi.core.event_fetching.dispatcher import QiwiDispatcher
from glQiwiApi.core.event_fetching.executor import Context, configure_app_for_qiwi_webhooks
from glQiwiApi.core.event_fetching.executor import HandlerContext, configure_app_for_qiwi_webhooks
from glQiwiApi.core.event_fetching.webhooks.config import (
EncryptionConfig,
HookRegistrationConfig,
Expand All @@ -21,7 +21,7 @@


@qiwi_dp.bill_handler()
async def handle_webhook(webhook: BillWebhook, ctx: Context):
async def handle_webhook(webhook: BillWebhook, ctx: HandlerContext):
# handle bill
bill = webhook.bill

Expand Down
4 changes: 4 additions & 0 deletions glQiwiApi/core/abc/base_api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ class APIClientMeta(abc.ABCMeta):
I have to write this metaclass to avoid additional viscous boilerplate code.
"""

__slots__ = ()

def __new__(
mcs: Type[_C], name: str, bases: Tuple[Any, ...], attrs: Dict[str, Any], **kwargs: Any
) -> _C:
Expand Down Expand Up @@ -58,6 +60,8 @@ async def check_request_service_before_execute(self, *args: Any, **kw: Any) -> A


class BaseAPIClient(metaclass=APIClientMeta):
__slots__ = ('_request_service_factory', '_request_service')

def __init__(
self,
request_service_factory: Optional[RequestServiceFactoryType] = None,
Expand Down
2 changes: 2 additions & 0 deletions glQiwiApi/core/cache/cached_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@


class Payload:
__slots__ = ('headers', 'json', 'params', 'data')

def __init__(
self,
headers: Optional[Dict[Any, Any]] = None,
Expand Down
11 changes: 9 additions & 2 deletions glQiwiApi/core/cache/invalidation.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@


class CacheInvalidationStrategy(abc.ABC):
__slots__ = ()

@abc.abstractmethod
async def process_update(self, **kwargs: Any) -> None:
pass
Expand All @@ -35,6 +37,8 @@ def is_cache_disabled(self) -> bool:


class UnrealizedCacheInvalidationStrategy(CacheInvalidationStrategy):
__slots__ = ()

async def process_update(self, **kwargs: Any) -> None:
pass

Expand All @@ -47,6 +51,8 @@ def is_cache_disabled(self) -> bool:


class CacheInvalidationByTimerStrategy(CacheInvalidationStrategy):
__slots__ = ('_cache_time',)

def __init__(self, cache_time_in_seconds: Union[float, int] = INFINITE):
self._cache_time = cache_time_in_seconds

Expand All @@ -71,10 +77,11 @@ def _is_cache_expired(self, **kwargs: Dict[str, Union[Any, float]]) -> None:

class APIResponsesCacheInvalidationStrategy(CacheInvalidationByTimerStrategy):
_validation_criteria = ('params', 'json', 'data', 'headers')
__slots__ = ('_cant_be_cached',)

def __init__(self, cache_time_in_seconds: Union[float, int] = INFINITE):
super().__init__(cache_time_in_seconds)
self._uncached = ('https://api.qiwi.com/partner/bill', '/sinap/api/v2/terms/')
self._cant_be_cached = ('https://api.qiwi.com/partner/bill', '/sinap/api/v2/terms/')

@property
def is_cache_disabled(self) -> bool:
Expand All @@ -83,7 +90,7 @@ def is_cache_disabled(self) -> bool:
async def process_update(self, **kwargs: Any) -> None:
await super().process_update(**kwargs)
for key in kwargs.keys():
if any(key.startswith(coincidence) for coincidence in self._uncached):
if any(key.startswith(coincidence) for coincidence in self._cant_be_cached):
raise CacheValidationError()

async def check_is_contains_similar(self, storage: CacheStorage, item: Any) -> bool:
Expand Down
11 changes: 7 additions & 4 deletions glQiwiApi/core/cache/storage.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import abc
from typing import Any, Dict, List, Optional
import weakref
from typing import Any, Dict, List, MutableMapping, Optional

from glQiwiApi.core.cache.constants import VALUE_PLACEHOLDER
from glQiwiApi.core.cache.exceptions import CacheExpiredError, CacheValidationError
Expand All @@ -11,6 +12,8 @@


class CacheStorage(abc.ABC):
__slots__ = ('_invalidate_strategy',)

def __init__(self, invalidate_strategy: Optional[CacheInvalidationStrategy] = None):
if invalidate_strategy is None:
invalidate_strategy = UnrealizedCacheInvalidationStrategy()
Expand Down Expand Up @@ -48,11 +51,11 @@ def __setitem__(self, key: str, value: Any) -> Any:


class InMemoryCacheStorage(CacheStorage):
__slots__ = ('_data', '_invalidate_strategy')
__slots__ = ('_data',)

def __init__(self, invalidate_strategy: Optional[CacheInvalidationStrategy] = None):
CacheStorage.__init__(self, invalidate_strategy)
self._data: Dict[Any, Any] = {}
self._data: MutableMapping[Any, Any] = weakref.WeakValueDictionary()

async def clear(self) -> None:
await self._invalidate_strategy.process_delete()
Expand Down Expand Up @@ -87,4 +90,4 @@ async def contains_similar(self, item: Any) -> bool:
return await self._invalidate_strategy.check_is_contains_similar(self, item)

def __del__(self) -> None:
del self._data
self._data.clear()
Loading