ez-a-sync 0.32.29__cp310-cp310-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ez-a-sync might be problematic. Click here for more details.
- a_sync/ENVIRONMENT_VARIABLES.py +42 -0
- a_sync/__init__.pxd +2 -0
- a_sync/__init__.py +145 -0
- a_sync/_smart.c +22803 -0
- a_sync/_smart.cp310-win_amd64.pyd +0 -0
- a_sync/_smart.pxd +2 -0
- a_sync/_smart.pyi +202 -0
- a_sync/_smart.pyx +674 -0
- a_sync/_typing.py +258 -0
- a_sync/a_sync/__init__.py +60 -0
- a_sync/a_sync/_descriptor.c +20528 -0
- a_sync/a_sync/_descriptor.cp310-win_amd64.pyd +0 -0
- a_sync/a_sync/_descriptor.pyi +33 -0
- a_sync/a_sync/_descriptor.pyx +422 -0
- a_sync/a_sync/_flags.c +6074 -0
- a_sync/a_sync/_flags.cp310-win_amd64.pyd +0 -0
- a_sync/a_sync/_flags.pxd +3 -0
- a_sync/a_sync/_flags.pyx +92 -0
- a_sync/a_sync/_helpers.c +14521 -0
- a_sync/a_sync/_helpers.cp310-win_amd64.pyd +0 -0
- a_sync/a_sync/_helpers.pxd +3 -0
- a_sync/a_sync/_helpers.pyi +10 -0
- a_sync/a_sync/_helpers.pyx +167 -0
- a_sync/a_sync/_kwargs.c +12194 -0
- a_sync/a_sync/_kwargs.cp310-win_amd64.pyd +0 -0
- a_sync/a_sync/_kwargs.pxd +2 -0
- a_sync/a_sync/_kwargs.pyx +64 -0
- a_sync/a_sync/_meta.py +210 -0
- a_sync/a_sync/abstract.c +12411 -0
- a_sync/a_sync/abstract.cp310-win_amd64.pyd +0 -0
- a_sync/a_sync/abstract.pyi +141 -0
- a_sync/a_sync/abstract.pyx +221 -0
- a_sync/a_sync/base.c +14932 -0
- a_sync/a_sync/base.cp310-win_amd64.pyd +0 -0
- a_sync/a_sync/base.pyi +60 -0
- a_sync/a_sync/base.pyx +271 -0
- a_sync/a_sync/config.py +168 -0
- a_sync/a_sync/decorator.py +651 -0
- a_sync/a_sync/flags.c +5272 -0
- a_sync/a_sync/flags.cp310-win_amd64.pyd +0 -0
- a_sync/a_sync/flags.pxd +72 -0
- a_sync/a_sync/flags.pyi +74 -0
- a_sync/a_sync/flags.pyx +72 -0
- a_sync/a_sync/function.c +37846 -0
- a_sync/a_sync/function.cp310-win_amd64.pyd +0 -0
- a_sync/a_sync/function.pxd +28 -0
- a_sync/a_sync/function.pyi +571 -0
- a_sync/a_sync/function.pyx +1381 -0
- a_sync/a_sync/method.c +29774 -0
- a_sync/a_sync/method.cp310-win_amd64.pyd +0 -0
- a_sync/a_sync/method.pxd +9 -0
- a_sync/a_sync/method.pyi +525 -0
- a_sync/a_sync/method.pyx +1023 -0
- a_sync/a_sync/modifiers/__init__.pxd +1 -0
- a_sync/a_sync/modifiers/__init__.py +101 -0
- a_sync/a_sync/modifiers/cache/__init__.py +160 -0
- a_sync/a_sync/modifiers/cache/memory.py +165 -0
- a_sync/a_sync/modifiers/limiter.py +132 -0
- a_sync/a_sync/modifiers/manager.c +16149 -0
- a_sync/a_sync/modifiers/manager.cp310-win_amd64.pyd +0 -0
- a_sync/a_sync/modifiers/manager.pxd +5 -0
- a_sync/a_sync/modifiers/manager.pyi +219 -0
- a_sync/a_sync/modifiers/manager.pyx +299 -0
- a_sync/a_sync/modifiers/semaphores.py +173 -0
- a_sync/a_sync/property.c +27260 -0
- a_sync/a_sync/property.cp310-win_amd64.pyd +0 -0
- a_sync/a_sync/property.pyi +376 -0
- a_sync/a_sync/property.pyx +819 -0
- a_sync/a_sync/singleton.py +63 -0
- a_sync/aliases.py +3 -0
- a_sync/async_property/__init__.pxd +1 -0
- a_sync/async_property/__init__.py +1 -0
- a_sync/async_property/cached.c +20386 -0
- a_sync/async_property/cached.cp310-win_amd64.pyd +0 -0
- a_sync/async_property/cached.pxd +10 -0
- a_sync/async_property/cached.pyi +45 -0
- a_sync/async_property/cached.pyx +178 -0
- a_sync/async_property/proxy.c +34654 -0
- a_sync/async_property/proxy.cp310-win_amd64.pyd +0 -0
- a_sync/async_property/proxy.pxd +2 -0
- a_sync/async_property/proxy.pyi +124 -0
- a_sync/async_property/proxy.pyx +474 -0
- a_sync/asyncio/__init__.pxd +6 -0
- a_sync/asyncio/__init__.py +164 -0
- a_sync/asyncio/as_completed.c +18841 -0
- a_sync/asyncio/as_completed.cp310-win_amd64.pyd +0 -0
- a_sync/asyncio/as_completed.pxd +8 -0
- a_sync/asyncio/as_completed.pyi +109 -0
- a_sync/asyncio/as_completed.pyx +269 -0
- a_sync/asyncio/create_task.c +15902 -0
- a_sync/asyncio/create_task.cp310-win_amd64.pyd +0 -0
- a_sync/asyncio/create_task.pxd +2 -0
- a_sync/asyncio/create_task.pyi +51 -0
- a_sync/asyncio/create_task.pyx +271 -0
- a_sync/asyncio/gather.c +16679 -0
- a_sync/asyncio/gather.cp310-win_amd64.pyd +0 -0
- a_sync/asyncio/gather.pyi +107 -0
- a_sync/asyncio/gather.pyx +218 -0
- a_sync/asyncio/igather.c +12676 -0
- a_sync/asyncio/igather.cp310-win_amd64.pyd +0 -0
- a_sync/asyncio/igather.pxd +1 -0
- a_sync/asyncio/igather.pyi +7 -0
- a_sync/asyncio/igather.pyx +182 -0
- a_sync/asyncio/sleep.c +9593 -0
- a_sync/asyncio/sleep.cp310-win_amd64.pyd +0 -0
- a_sync/asyncio/sleep.pyi +14 -0
- a_sync/asyncio/sleep.pyx +49 -0
- a_sync/debugging.c +15362 -0
- a_sync/debugging.cp310-win_amd64.pyd +0 -0
- a_sync/debugging.pyi +76 -0
- a_sync/debugging.pyx +107 -0
- a_sync/exceptions.c +13312 -0
- a_sync/exceptions.cp310-win_amd64.pyd +0 -0
- a_sync/exceptions.pyi +376 -0
- a_sync/exceptions.pyx +446 -0
- a_sync/executor.py +619 -0
- a_sync/functools.c +12738 -0
- a_sync/functools.cp310-win_amd64.pyd +0 -0
- a_sync/functools.pxd +7 -0
- a_sync/functools.pyi +33 -0
- a_sync/functools.pyx +139 -0
- a_sync/future.py +1497 -0
- a_sync/iter.c +37271 -0
- a_sync/iter.cp310-win_amd64.pyd +0 -0
- a_sync/iter.pxd +11 -0
- a_sync/iter.pyi +370 -0
- a_sync/iter.pyx +981 -0
- a_sync/primitives/__init__.pxd +1 -0
- a_sync/primitives/__init__.py +53 -0
- a_sync/primitives/_debug.c +15757 -0
- a_sync/primitives/_debug.cp310-win_amd64.pyd +0 -0
- a_sync/primitives/_debug.pxd +12 -0
- a_sync/primitives/_debug.pyi +52 -0
- a_sync/primitives/_debug.pyx +223 -0
- a_sync/primitives/_loggable.c +11529 -0
- a_sync/primitives/_loggable.cp310-win_amd64.pyd +0 -0
- a_sync/primitives/_loggable.pxd +4 -0
- a_sync/primitives/_loggable.pyi +66 -0
- a_sync/primitives/_loggable.pyx +102 -0
- a_sync/primitives/locks/__init__.pxd +8 -0
- a_sync/primitives/locks/__init__.py +17 -0
- a_sync/primitives/locks/counter.c +17679 -0
- a_sync/primitives/locks/counter.cp310-win_amd64.pyd +0 -0
- a_sync/primitives/locks/counter.pxd +12 -0
- a_sync/primitives/locks/counter.pyi +151 -0
- a_sync/primitives/locks/counter.pyx +260 -0
- a_sync/primitives/locks/event.c +17063 -0
- a_sync/primitives/locks/event.cp310-win_amd64.pyd +0 -0
- a_sync/primitives/locks/event.pxd +22 -0
- a_sync/primitives/locks/event.pyi +43 -0
- a_sync/primitives/locks/event.pyx +185 -0
- a_sync/primitives/locks/prio_semaphore.c +25590 -0
- a_sync/primitives/locks/prio_semaphore.cp310-win_amd64.pyd +0 -0
- a_sync/primitives/locks/prio_semaphore.pxd +25 -0
- a_sync/primitives/locks/prio_semaphore.pyi +217 -0
- a_sync/primitives/locks/prio_semaphore.pyx +597 -0
- a_sync/primitives/locks/semaphore.c +26509 -0
- a_sync/primitives/locks/semaphore.cp310-win_amd64.pyd +0 -0
- a_sync/primitives/locks/semaphore.pxd +21 -0
- a_sync/primitives/locks/semaphore.pyi +197 -0
- a_sync/primitives/locks/semaphore.pyx +454 -0
- a_sync/primitives/queue.py +1022 -0
- a_sync/py.typed +0 -0
- a_sync/sphinx/__init__.py +3 -0
- a_sync/sphinx/ext.py +289 -0
- a_sync/task.py +932 -0
- a_sync/utils/__init__.py +105 -0
- a_sync/utils/iterators.py +297 -0
- a_sync/utils/repr.c +15799 -0
- a_sync/utils/repr.cp310-win_amd64.pyd +0 -0
- a_sync/utils/repr.pyi +2 -0
- a_sync/utils/repr.pyx +73 -0
- ez_a_sync-0.32.29.dist-info/METADATA +367 -0
- ez_a_sync-0.32.29.dist-info/RECORD +177 -0
- ez_a_sync-0.32.29.dist-info/WHEEL +5 -0
- ez_a_sync-0.32.29.dist-info/licenses/LICENSE.txt +17 -0
- ez_a_sync-0.32.29.dist-info/top_level.txt +1 -0
|
Binary file
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module provides an abstract base class for defining asynchronous and synchronous behavior.
|
|
3
|
+
|
|
4
|
+
The :class:`ASyncABC` class uses the :class:`ASyncMeta` metaclass to facilitate the creation of classes
|
|
5
|
+
that can operate in both asynchronous and synchronous contexts. It provides concrete methods to determine
|
|
6
|
+
the execution mode based on flags and keyword arguments.
|
|
7
|
+
|
|
8
|
+
Note: It is recommended to use :class:`ASyncGenericBase` for most use cases. This class
|
|
9
|
+
is intended for more custom implementations if necessary.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from a_sync._typing import *
|
|
13
|
+
import abc
|
|
14
|
+
import functools
|
|
15
|
+
import logging
|
|
16
|
+
from a_sync import exceptions as exceptions
|
|
17
|
+
from a_sync.a_sync import modifiers as modifiers
|
|
18
|
+
from a_sync.a_sync._meta import ASyncMeta as ASyncMeta
|
|
19
|
+
from a_sync.exceptions import NoFlagsFound as NoFlagsFound
|
|
20
|
+
|
|
21
|
+
logger: logging.Logger
|
|
22
|
+
|
|
23
|
+
class ASyncABC(metaclass=ASyncMeta):
|
|
24
|
+
"""Abstract Base Class for defining asynchronous and synchronous behavior.
|
|
25
|
+
|
|
26
|
+
This class provides methods to determine the execution mode based on flags and keyword arguments.
|
|
27
|
+
It is designed to be subclassed, allowing developers to create classes that can be used in both
|
|
28
|
+
synchronous and asynchronous contexts.
|
|
29
|
+
|
|
30
|
+
See Also:
|
|
31
|
+
- :class:`ASyncGenericBase`: A more user-friendly base class for creating dual-mode classes.
|
|
32
|
+
- :class:`ASyncMeta`: Metaclass that facilitates asynchronous capabilities in class attributes.
|
|
33
|
+
|
|
34
|
+
Examples:
|
|
35
|
+
To create a class that inherits from `ASyncABC`, you need to implement the abstract methods
|
|
36
|
+
and can override the concrete methods if needed.
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
class MyASyncClass(ASyncABC):
|
|
40
|
+
@property
|
|
41
|
+
def __a_sync_flag_name__(self) -> str:
|
|
42
|
+
return "sync"
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def __a_sync_flag_value__(self) -> bool:
|
|
46
|
+
return True
|
|
47
|
+
|
|
48
|
+
@classmethod
|
|
49
|
+
def __a_sync_default_mode__(cls) -> bool:
|
|
50
|
+
return False
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
In this example, `MyASyncClass` is a subclass of `ASyncABC` with custom implementations
|
|
54
|
+
for the required abstract methods.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
def __a_sync_should_await__(self, kwargs: dict) -> bool:
|
|
58
|
+
"""Determines if methods should be called asynchronously.
|
|
59
|
+
|
|
60
|
+
This method first checks the provided keyword arguments for flags
|
|
61
|
+
indicating the desired execution mode. If no flags are found, it
|
|
62
|
+
defaults to the instance's asynchronous flag.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
kwargs: A dictionary of keyword arguments to check for flags.
|
|
66
|
+
|
|
67
|
+
Examples:
|
|
68
|
+
>>> instance = MyASyncClass()
|
|
69
|
+
>>> instance.__a_sync_should_await__({'sync': True})
|
|
70
|
+
False
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
@functools.cached_property
|
|
74
|
+
def __a_sync_instance_should_await__(self) -> bool:
|
|
75
|
+
"""Indicates if the instance should default to asynchronous execution.
|
|
76
|
+
|
|
77
|
+
This property can be overridden if dynamic behavior is needed. For
|
|
78
|
+
instance, to allow hot-swapping of instance modes, redefine this as a
|
|
79
|
+
non-cached property.
|
|
80
|
+
|
|
81
|
+
Examples:
|
|
82
|
+
>>> instance = MyASyncClass()
|
|
83
|
+
>>> instance.__a_sync_instance_should_await__
|
|
84
|
+
True
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
@classmethod
|
|
88
|
+
def __a_sync_instance_will_be_sync__(cls, args: tuple, kwargs: dict) -> bool:
|
|
89
|
+
"""Determines if a new instance will be synchronous.
|
|
90
|
+
|
|
91
|
+
This method checks the constructor's signature against provided
|
|
92
|
+
keyword arguments to determine the execution mode for the new instance.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
args: A tuple of positional arguments for the instance.
|
|
96
|
+
kwargs: A dictionary of keyword arguments for the instance.
|
|
97
|
+
|
|
98
|
+
Examples:
|
|
99
|
+
>>> MyASyncClass.__a_sync_instance_will_be_sync__((), {'sync': True})
|
|
100
|
+
True
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
@property
|
|
104
|
+
def __a_sync_modifiers__(self) -> ModifierKwargs:
|
|
105
|
+
"""Retrieves modifiers for the instance.
|
|
106
|
+
|
|
107
|
+
This method should not be overridden. It returns the modifiers
|
|
108
|
+
associated with the instance, which are used to customize behavior.
|
|
109
|
+
|
|
110
|
+
Examples:
|
|
111
|
+
>>> instance = MyASyncClass()
|
|
112
|
+
>>> instance.__a_sync_modifiers__
|
|
113
|
+
{'cache_type': 'memory'}
|
|
114
|
+
"""
|
|
115
|
+
|
|
116
|
+
@property
|
|
117
|
+
@abc.abstractmethod
|
|
118
|
+
def __a_sync_flag_name__(self) -> str:
|
|
119
|
+
"""Abstract property for the flag name.
|
|
120
|
+
|
|
121
|
+
Subclasses must implement this property to return the name of the flag
|
|
122
|
+
used to determine execution mode.
|
|
123
|
+
"""
|
|
124
|
+
|
|
125
|
+
@property
|
|
126
|
+
@abc.abstractmethod
|
|
127
|
+
def __a_sync_flag_value__(self) -> bool:
|
|
128
|
+
"""Abstract property for the flag value.
|
|
129
|
+
|
|
130
|
+
Subclasses must implement this property to return the value of the flag
|
|
131
|
+
indicating the default execution mode.
|
|
132
|
+
"""
|
|
133
|
+
|
|
134
|
+
@classmethod
|
|
135
|
+
@abc.abstractmethod
|
|
136
|
+
def __a_sync_default_mode__(cls) -> bool:
|
|
137
|
+
"""Abstract class method for the default execution mode.
|
|
138
|
+
|
|
139
|
+
Subclasses must implement this method to return the default execution
|
|
140
|
+
mode (synchronous or asynchronous) for instances of the class.
|
|
141
|
+
"""
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module provides an abstract base class for defining asynchronous and synchronous behavior.
|
|
3
|
+
|
|
4
|
+
The :class:`ASyncABC` class uses the :class:`ASyncMeta` metaclass to facilitate the creation of classes
|
|
5
|
+
that can operate in both asynchronous and synchronous contexts. It provides concrete methods to determine
|
|
6
|
+
the execution mode based on flags and keyword arguments.
|
|
7
|
+
|
|
8
|
+
Note: It is recommended to use :class:`ASyncGenericBase` for most use cases. This class
|
|
9
|
+
is intended for more custom implementations if necessary.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from abc import abstractmethod
|
|
13
|
+
from logging import getLogger
|
|
14
|
+
from typing import Dict, Any, Tuple
|
|
15
|
+
|
|
16
|
+
from a_sync._typing import *
|
|
17
|
+
from a_sync.a_sync._kwargs cimport get_flag_name, is_sync
|
|
18
|
+
from a_sync.a_sync._flags cimport validate_and_negate_if_necessary
|
|
19
|
+
from a_sync.a_sync._meta import ASyncMeta
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
cdef struct ShouldAwaitCache:
|
|
23
|
+
bint is_cached
|
|
24
|
+
bint value
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
logger = getLogger(__name__)
|
|
28
|
+
|
|
29
|
+
cdef object _logger_is_enabled = logger.isEnabledFor
|
|
30
|
+
cdef object _logger_log = logger._log
|
|
31
|
+
cdef object DEBUG = 10
|
|
32
|
+
|
|
33
|
+
cdef inline void _log_debug(str msg, tuple args):
|
|
34
|
+
_logger_log(DEBUG, msg, args)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class ASyncABC(metaclass=ASyncMeta):
|
|
38
|
+
"""Abstract Base Class for defining asynchronous and synchronous behavior.
|
|
39
|
+
|
|
40
|
+
This class provides methods to determine the execution mode based on flags and keyword arguments.
|
|
41
|
+
It is designed to be subclassed, allowing developers to create classes that can be used in both
|
|
42
|
+
synchronous and asynchronous contexts.
|
|
43
|
+
|
|
44
|
+
See Also:
|
|
45
|
+
- :class:`ASyncGenericBase`: A more user-friendly base class for creating dual-mode classes.
|
|
46
|
+
- :class:`ASyncMeta`: Metaclass that facilitates asynchronous capabilities in class attributes.
|
|
47
|
+
|
|
48
|
+
Examples:
|
|
49
|
+
To create a class that inherits from `ASyncABC`, you need to implement the abstract methods
|
|
50
|
+
and can override the concrete methods if needed.
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
class MyASyncClass(ASyncABC):
|
|
54
|
+
@property
|
|
55
|
+
def __a_sync_flag_name__(self) -> str:
|
|
56
|
+
return "sync"
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def __a_sync_flag_value__(self) -> bool:
|
|
60
|
+
return True
|
|
61
|
+
|
|
62
|
+
@classmethod
|
|
63
|
+
def __a_sync_default_mode__(cls) -> bool:
|
|
64
|
+
return False
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
In this example, `MyASyncClass` is a subclass of `ASyncABC` with custom implementations
|
|
68
|
+
for the required abstract methods.
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
def __init__(self) -> None:
|
|
72
|
+
cdef ShouldAwaitCache cache
|
|
73
|
+
cache.is_cached = False
|
|
74
|
+
cache.value = False
|
|
75
|
+
self.__a_sync_should_await_cache__ = cache
|
|
76
|
+
|
|
77
|
+
##################################
|
|
78
|
+
# Concrete Methods (overridable) #
|
|
79
|
+
##################################
|
|
80
|
+
|
|
81
|
+
def __a_sync_should_await__(self, Dict[str, Any] kwargs) -> bint:
|
|
82
|
+
"""Determines if methods should be called asynchronously.
|
|
83
|
+
|
|
84
|
+
This method first checks the provided keyword arguments for flags
|
|
85
|
+
indicating the desired execution mode. If no flags are found, it
|
|
86
|
+
defaults to the instance's asynchronous flag.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
kwargs: A dictionary of keyword arguments to check for flags.
|
|
90
|
+
|
|
91
|
+
Examples:
|
|
92
|
+
>>> instance = MyASyncClass()
|
|
93
|
+
>>> instance.__a_sync_should_await__({'sync': True})
|
|
94
|
+
False
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
cdef str flag = get_flag_name(kwargs)
|
|
98
|
+
if flag:
|
|
99
|
+
return is_sync(flag, kwargs, pop_flag=True)
|
|
100
|
+
|
|
101
|
+
cdef ShouldAwaitCache cache
|
|
102
|
+
|
|
103
|
+
try:
|
|
104
|
+
cache = self.__a_sync_should_await_cache__
|
|
105
|
+
except AttributeError:
|
|
106
|
+
raise RuntimeError(
|
|
107
|
+
f"{self} has not been properly initialized. "
|
|
108
|
+
f"Please ensure your `{type(self).__name__}.__init__` method calls `ASyncABC.__init__(self)`."
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
if not cache.is_cached:
|
|
112
|
+
cache.value = validate_and_negate_if_necessary(
|
|
113
|
+
self.__a_sync_flag_name__, self.__a_sync_flag_value__
|
|
114
|
+
)
|
|
115
|
+
cache.is_cached = True
|
|
116
|
+
self.__a_sync_should_await_cache__ = cache
|
|
117
|
+
return cache.value
|
|
118
|
+
|
|
119
|
+
@property
|
|
120
|
+
def __a_sync_instance_should_await__(self) -> bint:
|
|
121
|
+
# TODO: refactor this out
|
|
122
|
+
"""Indicates if the instance should default to asynchronous execution.
|
|
123
|
+
|
|
124
|
+
This property can be overridden if dynamic behavior is needed. For
|
|
125
|
+
instance, to allow hot-swapping of instance modes, redefine this as a
|
|
126
|
+
non-cached property.
|
|
127
|
+
|
|
128
|
+
Examples:
|
|
129
|
+
>>> instance = MyASyncClass()
|
|
130
|
+
>>> instance.__a_sync_instance_should_await__
|
|
131
|
+
True
|
|
132
|
+
"""
|
|
133
|
+
cdef ShouldAwaitCache cache
|
|
134
|
+
|
|
135
|
+
try:
|
|
136
|
+
cache = self.__a_sync_should_await_cache__
|
|
137
|
+
except AttributeError:
|
|
138
|
+
raise RuntimeError(
|
|
139
|
+
f"{self} has not been properly initialized. "
|
|
140
|
+
f"Please ensure your `{type(self).__name__}.__init__` method calls `ASyncABC.__init__(self)`."
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
if not cache.is_cached:
|
|
144
|
+
cache.value = validate_and_negate_if_necessary(
|
|
145
|
+
self.__a_sync_flag_name__, self.__a_sync_flag_value__
|
|
146
|
+
)
|
|
147
|
+
cache.is_cached = True
|
|
148
|
+
self.__a_sync_should_await_cache__ = cache
|
|
149
|
+
return cache.value
|
|
150
|
+
|
|
151
|
+
@classmethod
|
|
152
|
+
def __a_sync_instance_will_be_sync__(cls, Tuple[Any, ...] args, Dict[str, Any] kwargs) -> bint:
|
|
153
|
+
"""Determines if a new instance will be synchronous.
|
|
154
|
+
|
|
155
|
+
This method checks the constructor's signature against provided
|
|
156
|
+
keyword arguments to determine the execution mode for the new instance.
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
args: A tuple of positional arguments for the instance.
|
|
160
|
+
kwargs: A dictionary of keyword arguments for the instance.
|
|
161
|
+
|
|
162
|
+
Examples:
|
|
163
|
+
>>> MyASyncClass.__a_sync_instance_will_be_sync__((), {'sync': True})
|
|
164
|
+
True
|
|
165
|
+
"""
|
|
166
|
+
cdef bint debug_logs = _logger_is_enabled(DEBUG)
|
|
167
|
+
|
|
168
|
+
if debug_logs:
|
|
169
|
+
_log_debug(
|
|
170
|
+
"checking `%s.%s.__init__` signature against provided kwargs to determine a_sync mode for the new instance",
|
|
171
|
+
(cls.__module__, cls.__name__),
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
cdef str flag = get_flag_name(kwargs)
|
|
175
|
+
if not debug_logs:
|
|
176
|
+
return is_sync(flag, kwargs, pop_flag=False) if flag else cls.__a_sync_default_mode__() # type: ignore [arg-type]
|
|
177
|
+
|
|
178
|
+
if not flag:
|
|
179
|
+
_log_debug(
|
|
180
|
+
"No valid flags found in kwargs, checking class definition for defined default", ()
|
|
181
|
+
)
|
|
182
|
+
return cls.__a_sync_default_mode__() # type: ignore [arg-type]
|
|
183
|
+
|
|
184
|
+
cdef bint sync = is_sync(flag, kwargs, pop_flag=False) # type: ignore [arg-type]
|
|
185
|
+
_log_debug(
|
|
186
|
+
"kwargs indicate the new instance created with args %s %s is %ssynchronous",
|
|
187
|
+
(args, kwargs, "" if sync else "a"),
|
|
188
|
+
)
|
|
189
|
+
return sync
|
|
190
|
+
|
|
191
|
+
####################
|
|
192
|
+
# Abstract Methods #
|
|
193
|
+
####################
|
|
194
|
+
|
|
195
|
+
@property
|
|
196
|
+
@abstractmethod
|
|
197
|
+
def __a_sync_flag_name__(self) -> str:
|
|
198
|
+
"""Abstract property for the flag name.
|
|
199
|
+
|
|
200
|
+
Subclasses must implement this property to return the name of the flag
|
|
201
|
+
used to determine execution mode.
|
|
202
|
+
"""
|
|
203
|
+
|
|
204
|
+
@property
|
|
205
|
+
@abstractmethod
|
|
206
|
+
def __a_sync_flag_value__(self) -> bool:
|
|
207
|
+
"""Abstract property for the flag value.
|
|
208
|
+
|
|
209
|
+
Subclasses must implement this property to return the value of the flag
|
|
210
|
+
indicating the default execution mode.
|
|
211
|
+
"""
|
|
212
|
+
|
|
213
|
+
@classmethod
|
|
214
|
+
@abstractmethod # type: ignore [arg-type, misc]
|
|
215
|
+
def __a_sync_default_mode__(cls) -> bool: # type: ignore [empty-body]
|
|
216
|
+
"""Abstract class method for the default execution mode.
|
|
217
|
+
|
|
218
|
+
Subclasses must implement this method to return the default execution
|
|
219
|
+
mode (synchronous or asynchronous) for instances of the class.
|
|
220
|
+
"""
|
|
221
|
+
|