ez-a-sync 0.33.4__cp313-cp313-musllinux_1_2_i686.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.
- a_sync/ENVIRONMENT_VARIABLES.py +42 -0
- a_sync/__init__.pxd +2 -0
- a_sync/__init__.py +145 -0
- a_sync/_smart.c +22830 -0
- a_sync/_smart.cpython-313-i386-linux-musl.so +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 +20537 -0
- a_sync/a_sync/_descriptor.cpython-313-i386-linux-musl.so +0 -0
- a_sync/a_sync/_descriptor.pyi +33 -0
- a_sync/a_sync/_descriptor.pyx +422 -0
- a_sync/a_sync/_flags.c +6082 -0
- a_sync/a_sync/_flags.cpython-313-i386-linux-musl.so +0 -0
- a_sync/a_sync/_flags.pxd +3 -0
- a_sync/a_sync/_flags.pyx +92 -0
- a_sync/a_sync/_helpers.c +14529 -0
- a_sync/a_sync/_helpers.cpython-313-i386-linux-musl.so +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 +12202 -0
- a_sync/a_sync/_kwargs.cpython-313-i386-linux-musl.so +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 +12420 -0
- a_sync/a_sync/abstract.cpython-313-i386-linux-musl.so +0 -0
- a_sync/a_sync/abstract.pyi +141 -0
- a_sync/a_sync/abstract.pyx +221 -0
- a_sync/a_sync/base.c +14940 -0
- a_sync/a_sync/base.cpython-313-i386-linux-musl.so +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.cpython-313-i386-linux-musl.so +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 +37856 -0
- a_sync/a_sync/function.cpython-313-i386-linux-musl.so +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 +29662 -0
- a_sync/a_sync/method.cpython-313-i386-linux-musl.so +0 -0
- a_sync/a_sync/method.pxd +9 -0
- a_sync/a_sync/method.pyi +523 -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 +16157 -0
- a_sync/a_sync/modifiers/manager.cpython-313-i386-linux-musl.so +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 +27268 -0
- a_sync/a_sync/property.cpython-313-i386-linux-musl.so +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 +20397 -0
- a_sync/async_property/cached.cpython-313-i386-linux-musl.so +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 +34662 -0
- a_sync/async_property/proxy.cpython-313-i386-linux-musl.so +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 +18849 -0
- a_sync/asyncio/as_completed.cpython-313-i386-linux-musl.so +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 +15912 -0
- a_sync/asyncio/create_task.cpython-313-i386-linux-musl.so +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 +16687 -0
- a_sync/asyncio/gather.cpython-313-i386-linux-musl.so +0 -0
- a_sync/asyncio/gather.pyi +107 -0
- a_sync/asyncio/gather.pyx +218 -0
- a_sync/asyncio/igather.c +13080 -0
- a_sync/asyncio/igather.cpython-313-i386-linux-musl.so +0 -0
- a_sync/asyncio/igather.pxd +1 -0
- a_sync/asyncio/igather.pyi +8 -0
- a_sync/asyncio/igather.pyx +183 -0
- a_sync/asyncio/sleep.c +9601 -0
- a_sync/asyncio/sleep.cpython-313-i386-linux-musl.so +0 -0
- a_sync/asyncio/sleep.pyi +14 -0
- a_sync/asyncio/sleep.pyx +49 -0
- a_sync/debugging.c +15370 -0
- a_sync/debugging.cpython-313-i386-linux-musl.so +0 -0
- a_sync/debugging.pyi +76 -0
- a_sync/debugging.pyx +107 -0
- a_sync/exceptions.c +13320 -0
- a_sync/exceptions.cpython-313-i386-linux-musl.so +0 -0
- a_sync/exceptions.pyi +376 -0
- a_sync/exceptions.pyx +446 -0
- a_sync/executor.py +619 -0
- a_sync/functools.c +12746 -0
- a_sync/functools.cpython-313-i386-linux-musl.so +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 +37279 -0
- a_sync/iter.cpython-313-i386-linux-musl.so +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 +15765 -0
- a_sync/primitives/_debug.cpython-313-i386-linux-musl.so +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 +11538 -0
- a_sync/primitives/_loggable.cpython-313-i386-linux-musl.so +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 +17938 -0
- a_sync/primitives/locks/counter.cpython-313-i386-linux-musl.so +0 -0
- a_sync/primitives/locks/counter.pxd +12 -0
- a_sync/primitives/locks/counter.pyi +151 -0
- a_sync/primitives/locks/counter.pyx +267 -0
- a_sync/primitives/locks/event.c +17072 -0
- a_sync/primitives/locks/event.cpython-313-i386-linux-musl.so +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 +25635 -0
- a_sync/primitives/locks/prio_semaphore.cpython-313-i386-linux-musl.so +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 +26553 -0
- a_sync/primitives/locks/semaphore.cpython-313-i386-linux-musl.so +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 +1026 -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 +934 -0
- a_sync/utils/__init__.py +105 -0
- a_sync/utils/iterators.py +297 -0
- a_sync/utils/repr.c +15866 -0
- a_sync/utils/repr.cpython-313-i386-linux-musl.so +0 -0
- a_sync/utils/repr.pyi +2 -0
- a_sync/utils/repr.pyx +73 -0
- ez_a_sync-0.33.4.dist-info/METADATA +368 -0
- ez_a_sync-0.33.4.dist-info/RECORD +177 -0
- ez_a_sync-0.33.4.dist-info/WHEEL +5 -0
- ez_a_sync-0.33.4.dist-info/licenses/LICENSE.txt +17 -0
- ez_a_sync-0.33.4.dist-info/top_level.txt +1 -0
|
Binary file
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from libc.stdint cimport uint16_t
|
|
2
|
+
|
|
3
|
+
from a_sync.primitives._debug cimport _DebugDaemonMixin
|
|
4
|
+
|
|
5
|
+
cdef class CythonEvent(_DebugDaemonMixin):
|
|
6
|
+
"""
|
|
7
|
+
An asyncio.Event with additional debug logging to help detect deadlocks.
|
|
8
|
+
|
|
9
|
+
This event class extends asyncio.Event by adding debug logging capabilities. It logs
|
|
10
|
+
detailed information about the event state and waiters, which can be useful for
|
|
11
|
+
diagnosing and debugging potential deadlocks.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
cdef bint _value
|
|
15
|
+
cdef list _waiters
|
|
16
|
+
cdef char* __name
|
|
17
|
+
cdef uint16_t _debug_daemon_interval
|
|
18
|
+
cpdef bint is_set(self)
|
|
19
|
+
cpdef void set(self)
|
|
20
|
+
cpdef void clear(self)
|
|
21
|
+
cpdef object wait(self)
|
|
22
|
+
cdef object c_wait(self)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from a_sync._typing import *
|
|
2
|
+
import asyncio
|
|
3
|
+
from a_sync.primitives._debug import _DebugDaemonMixin
|
|
4
|
+
|
|
5
|
+
class CythonEvent(asyncio.Event, _DebugDaemonMixin):
|
|
6
|
+
"""
|
|
7
|
+
An asyncio.Event with additional debug logging to help detect deadlocks.
|
|
8
|
+
|
|
9
|
+
This event class extends asyncio.Event by adding debug logging capabilities. It logs
|
|
10
|
+
detailed information about the event state and waiters, which can be useful for
|
|
11
|
+
diagnosing and debugging potential deadlocks.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def __init__(
|
|
15
|
+
self,
|
|
16
|
+
name: str = "",
|
|
17
|
+
debug_daemon_interval: int = 300,
|
|
18
|
+
*,
|
|
19
|
+
loop: Optional[asyncio.AbstractEventLoop] = None
|
|
20
|
+
) -> None:
|
|
21
|
+
"""
|
|
22
|
+
Initializes the Event.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
name (str): An optional name for the event, used in debug logs.
|
|
26
|
+
debug_daemon_interval (int): The interval in seconds for the debug daemon to log information.
|
|
27
|
+
loop (Optional[asyncio.AbstractEventLoop]): The event loop to use.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
async def wait(self) -> Literal[True]:
|
|
31
|
+
"""
|
|
32
|
+
Wait until the event is set.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
True when the event is set.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
async def _debug_daemon(self) -> None:
|
|
39
|
+
"""
|
|
40
|
+
Periodically logs debug information about the event state and waiters.
|
|
41
|
+
|
|
42
|
+
This code will only run if `self.logger.isEnabledFor(logging.DEBUG)` is True. You do not need to include any level checks in your custom implementations.
|
|
43
|
+
"""
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# cython: boundscheck=False
|
|
2
|
+
"""
|
|
3
|
+
This module provides an enhanced version of asyncio.Event with additional debug logging to help detect deadlocks.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import sys
|
|
7
|
+
from asyncio import AbstractEventLoop, Future, get_event_loop, sleep
|
|
8
|
+
from libc.stdint cimport uint16_t
|
|
9
|
+
from libc.stdlib cimport malloc, free
|
|
10
|
+
from libc.string cimport strcpy
|
|
11
|
+
from libc.time cimport time
|
|
12
|
+
from weakref import ref
|
|
13
|
+
|
|
14
|
+
from cpython.unicode cimport PyUnicode_CompareWithASCIIString
|
|
15
|
+
|
|
16
|
+
from a_sync._typing import *
|
|
17
|
+
from a_sync.primitives._debug cimport _DebugDaemonMixin, _LoopBoundMixin
|
|
18
|
+
|
|
19
|
+
cdef extern from "time.h":
|
|
20
|
+
ctypedef long time_t
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
async def _return_true():
|
|
24
|
+
return True
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
cdef bint _loop_kwarg_deprecated = sys.version_info >= (3, 10)
|
|
28
|
+
|
|
29
|
+
cdef class CythonEvent(_DebugDaemonMixin):
|
|
30
|
+
"""
|
|
31
|
+
An asyncio.Event with additional debug logging to help detect deadlocks.
|
|
32
|
+
|
|
33
|
+
This event class extends asyncio.Event by adding debug logging capabilities. It logs
|
|
34
|
+
detailed information about the event state and waiters, which can be useful for
|
|
35
|
+
diagnosing and debugging potential deadlocks.
|
|
36
|
+
"""
|
|
37
|
+
def __cinit__(self):
|
|
38
|
+
self._waiters = []
|
|
39
|
+
|
|
40
|
+
def __init__(
|
|
41
|
+
self,
|
|
42
|
+
name: str = "",
|
|
43
|
+
debug_daemon_interval: int = 300,
|
|
44
|
+
*,
|
|
45
|
+
loop: Optional[AbstractEventLoop] = None,
|
|
46
|
+
):
|
|
47
|
+
"""
|
|
48
|
+
Initializes the Event.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
name (str): An optional name for the event, used in debug logs.
|
|
52
|
+
debug_daemon_interval (int): The interval in seconds for the debug daemon to log information.
|
|
53
|
+
loop (Optional[AbstractEventLoop]): The event loop to use.
|
|
54
|
+
"""
|
|
55
|
+
if _loop_kwarg_deprecated:
|
|
56
|
+
_LoopBoundMixin.__init__(self)
|
|
57
|
+
else:
|
|
58
|
+
_LoopBoundMixin.__init__(self, loop=loop)
|
|
59
|
+
|
|
60
|
+
# backwards compatability
|
|
61
|
+
if hasattr(self, "_loop"):
|
|
62
|
+
self._loop = self._loop or get_event_loop()
|
|
63
|
+
if debug_daemon_interval > 65535:
|
|
64
|
+
raise ValueError(f"'debug_daemon_interval' is stored as a uint16 and must be less than 65535")
|
|
65
|
+
self._debug_daemon_interval = debug_daemon_interval
|
|
66
|
+
# we need a constant to coerce to char*
|
|
67
|
+
cdef bytes encoded_name = name.encode("utf-8")
|
|
68
|
+
cdef Py_ssize_t length = len(encoded_name)
|
|
69
|
+
|
|
70
|
+
# Allocate memory for the char* and add 1 for the null character
|
|
71
|
+
self.__name = <char*>malloc(length + 1)
|
|
72
|
+
"""An optional name for the counter, used in debug logs."""
|
|
73
|
+
|
|
74
|
+
if self.__name == NULL:
|
|
75
|
+
raise MemoryError("Failed to allocate memory for __name.")
|
|
76
|
+
# Copy the bytes data into the char*
|
|
77
|
+
strcpy(self.__name, encoded_name)
|
|
78
|
+
|
|
79
|
+
def __dealloc__(self):
|
|
80
|
+
# Free the memory allocated for __name
|
|
81
|
+
if self.__name is not NULL:
|
|
82
|
+
free(self.__name)
|
|
83
|
+
|
|
84
|
+
def __repr__(self) -> str:
|
|
85
|
+
cdef str label = (
|
|
86
|
+
"name={}".format(self.__name.decode("utf-8"))
|
|
87
|
+
if self.__name
|
|
88
|
+
else "object"
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
cdef str status = "set" if self._value else "unset"
|
|
92
|
+
|
|
93
|
+
if len_waiters := len(self._waiters):
|
|
94
|
+
status += ", waiters:{}".format(len_waiters)
|
|
95
|
+
|
|
96
|
+
return "<{}.{} {} at {} [{}]>".format(
|
|
97
|
+
self.__class__.__module__,
|
|
98
|
+
self.__class__.__name__,
|
|
99
|
+
label,
|
|
100
|
+
hex(id(self)),
|
|
101
|
+
status,
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
cpdef bint is_set(self):
|
|
105
|
+
"""Return True if and only if the internal flag is true."""
|
|
106
|
+
return self._value
|
|
107
|
+
|
|
108
|
+
cpdef void set(self):
|
|
109
|
+
"""Set the internal flag to true. All coroutines waiting for it to
|
|
110
|
+
become true are awakened. Coroutine that call wait() once the flag is
|
|
111
|
+
true will not block at all.
|
|
112
|
+
"""
|
|
113
|
+
cdef object fut
|
|
114
|
+
|
|
115
|
+
if not self._value:
|
|
116
|
+
self._value = True
|
|
117
|
+
|
|
118
|
+
for fut in self._waiters:
|
|
119
|
+
if _is_not_done(fut):
|
|
120
|
+
fut.set_result(True)
|
|
121
|
+
|
|
122
|
+
cpdef void clear(self):
|
|
123
|
+
"""Reset the internal flag to false. Subsequently, coroutines calling
|
|
124
|
+
wait() will block until set() is called to set the internal flag
|
|
125
|
+
to true again."""
|
|
126
|
+
self._value = False
|
|
127
|
+
|
|
128
|
+
cpdef object wait(self):
|
|
129
|
+
"""Block until the internal flag is true.
|
|
130
|
+
|
|
131
|
+
If the internal flag is true on entry, return True
|
|
132
|
+
immediately. Otherwise, block until another coroutine calls
|
|
133
|
+
set() to set the flag to true, then return True.
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
True when the event is set.
|
|
137
|
+
"""
|
|
138
|
+
return self.c_wait()
|
|
139
|
+
|
|
140
|
+
cdef object c_wait(self):
|
|
141
|
+
if self._value:
|
|
142
|
+
return _return_true()
|
|
143
|
+
|
|
144
|
+
self._c_ensure_debug_daemon((),{})
|
|
145
|
+
|
|
146
|
+
cdef object fut = Future(loop=self._c_get_loop())
|
|
147
|
+
self._waiters.append(fut)
|
|
148
|
+
return self.__wait(fut)
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
def _name(self) -> str:
|
|
152
|
+
return self.__name.decode("utf-8")
|
|
153
|
+
|
|
154
|
+
async def __wait(self, fut: Future) -> Literal[True]:
|
|
155
|
+
try:
|
|
156
|
+
await fut
|
|
157
|
+
return True
|
|
158
|
+
finally:
|
|
159
|
+
self._waiters.remove(fut)
|
|
160
|
+
|
|
161
|
+
async def _debug_daemon(self) -> None:
|
|
162
|
+
"""
|
|
163
|
+
Periodically logs debug information about the event state and waiters.
|
|
164
|
+
|
|
165
|
+
This code will only run if `self.logger.isEnabledFor(logging.DEBUG)` is True. You do not need to include any level checks in your custom implementations.
|
|
166
|
+
"""
|
|
167
|
+
cdef time_t start, now
|
|
168
|
+
cdef object weakself = ref(self)
|
|
169
|
+
cdef unsigned int loops = 0
|
|
170
|
+
cdef uint16_t interval = self._debug_daemon_interval
|
|
171
|
+
|
|
172
|
+
start = time(NULL)
|
|
173
|
+
while (self := weakself()) and not self._value:
|
|
174
|
+
if loops:
|
|
175
|
+
now = time(NULL)
|
|
176
|
+
self.get_logger().debug(
|
|
177
|
+
"Waiting for %s for %sm", self, round((now - start) / 60, 2)
|
|
178
|
+
)
|
|
179
|
+
del self # no need to hold a reference here
|
|
180
|
+
await sleep(interval)
|
|
181
|
+
loops += 1
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
cdef inline bint _is_not_done(fut: Future):
|
|
185
|
+
return PyUnicode_CompareWithASCIIString(fut._state, b"PENDING") == 0
|