asynkio 0.0.0__tar.gz
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.
- asynkio-0.0.0/LICENSE +33 -0
- asynkio-0.0.0/PKG-INFO +110 -0
- asynkio-0.0.0/README.md +86 -0
- asynkio-0.0.0/asynkio/__init__.py +0 -0
- asynkio-0.0.0/asynkio/time/__init__.py +6 -0
- asynkio-0.0.0/asynkio/time/types.py +233 -0
- asynkio-0.0.0/asynkio.egg-info/PKG-INFO +110 -0
- asynkio-0.0.0/asynkio.egg-info/SOURCES.txt +13 -0
- asynkio-0.0.0/asynkio.egg-info/dependency_links.txt +1 -0
- asynkio-0.0.0/asynkio.egg-info/requires.txt +12 -0
- asynkio-0.0.0/asynkio.egg-info/top_level.txt +1 -0
- asynkio-0.0.0/pyproject.toml +39 -0
- asynkio-0.0.0/setup.cfg +4 -0
- asynkio-0.0.0/tests/test_time.py +150 -0
- asynkio-0.0.0/tests/test_timer.py +78 -0
asynkio-0.0.0/LICENSE
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
asynkio - BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025, Matthew Wilson and Synesis Information Systems
|
|
4
|
+
|
|
5
|
+
All rights reserved.
|
|
6
|
+
|
|
7
|
+
Redistribution and use in source and binary forms, with or without
|
|
8
|
+
modification, are permitted provided that the following conditions are
|
|
9
|
+
met:
|
|
10
|
+
|
|
11
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer.
|
|
13
|
+
|
|
14
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
15
|
+
this list of conditions and the following disclaimer in the documentation
|
|
16
|
+
and/or other materials provided with the distribution.
|
|
17
|
+
|
|
18
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
19
|
+
contributors may be used to endorse or promote products derived from
|
|
20
|
+
this software without specific prior written permission.
|
|
21
|
+
|
|
22
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
23
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
24
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
25
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
26
|
+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
27
|
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
28
|
+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
29
|
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
30
|
+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
31
|
+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
32
|
+
POSSIBILITY OF SUCH DAMAGE.
|
|
33
|
+
|
asynkio-0.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: asynkio
|
|
3
|
+
Version: 0.0.0
|
|
4
|
+
Summary: Path parsing library
|
|
5
|
+
Author-email: Matt Wilson <matthew@synesis.com.au>
|
|
6
|
+
License: BSD-3
|
|
7
|
+
Project-URL: Changelog, https://github.com/synesissoftware/asynkio/releases
|
|
8
|
+
Project-URL: Homepage, https://github.com/synesissoftware/asynkio
|
|
9
|
+
Project-URL: Issues, https://github.com/synesissoftware/asynkio/issues
|
|
10
|
+
Requires-Python: >=3.11
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Requires-Dist: asyncio
|
|
14
|
+
Requires-Dist: diagnosticism
|
|
15
|
+
Provides-Extra: dev
|
|
16
|
+
Requires-Dist: aiofiles; extra == "dev"
|
|
17
|
+
Requires-Dist: pyclasp>=0.8.10; extra == "dev"
|
|
18
|
+
Requires-Dist: pytest>=7.4.4; extra == "dev"
|
|
19
|
+
Provides-Extra: test
|
|
20
|
+
Requires-Dist: aiofiles; extra == "test"
|
|
21
|
+
Requires-Dist: pyclasp>=0.8.10; extra == "test"
|
|
22
|
+
Requires-Dist: pytest>=7.4.4; extra == "test"
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# asynkio - README <!-- omit in toc -->
|
|
26
|
+
|
|
27
|
+
<!--
|
|
28
|
+
[](https://circleci.com/gh/google/asynkio)
|
|
29
|
+
-->
|
|
30
|
+
[](https://opensource.org/licenses/BSD-3-Clause)
|
|
31
|
+
[](https://badge.fury.io/py/asynkio)
|
|
32
|
+

|
|
33
|
+
[](https://github.com/synesissoftware/asynkio/actions/workflows/python-package.yml)
|
|
34
|
+
[](https://github.com/synesissoftware/asynkio/commits/master)
|
|
35
|
+
|
|
36
|
+
Tokio-like functionality for Python
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
## Table of contents <!-- omit in toc -->
|
|
40
|
+
|
|
41
|
+
- [Introduction](#introduction)
|
|
42
|
+
- [Installation \& Usage](#installation--usage)
|
|
43
|
+
- [Components](#components)
|
|
44
|
+
- [Examples](#examples)
|
|
45
|
+
- [Project Information](#project-information)
|
|
46
|
+
- [Where to get help](#where-to-get-help)
|
|
47
|
+
- [Contribution guidelines](#contribution-guidelines)
|
|
48
|
+
- [Dependencies](#dependencies)
|
|
49
|
+
- [Related projects](#related-projects)
|
|
50
|
+
- [License](#license)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
## Introduction
|
|
54
|
+
|
|
55
|
+
**asynkio** - a portmanteau of **asyncio** and **Tokio**, pronounced "ay sink ee-oh" - is a small, simple **Python** library that provides some of the features of the **Rust** **Tokio** library's features, such as `Duration`, `Instant`, and `Interval`.
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
## Installation & Usage
|
|
59
|
+
|
|
60
|
+
Install via **pip** or **pip3**, as in:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
$ pip3 install asynkio
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Use via **import**:
|
|
67
|
+
|
|
68
|
+
T.B.C.
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
## Components
|
|
72
|
+
|
|
73
|
+
T.B.C.
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
## Examples
|
|
77
|
+
|
|
78
|
+
Examples are provided in the ```examples``` directory, along with a markdown description for each. A detailed list TOC of them is provided in [EXAMPLES.md](./EXAMPLES.md).
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
## Project Information
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
### Where to get help
|
|
85
|
+
|
|
86
|
+
[GitHub Page](https://github.com/synesissoftware/asynkio "GitHub Page")
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
### Contribution guidelines
|
|
90
|
+
|
|
91
|
+
Defect reports, feature requests, and pull requests are welcome on https://github.com/synesissoftware/asynkio.
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
### Dependencies
|
|
95
|
+
|
|
96
|
+
T.B.C.
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
### Related projects
|
|
100
|
+
|
|
101
|
+
T.B.C.
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
### License
|
|
105
|
+
|
|
106
|
+
**asynkio** is released under the 3-clause BSD license. See [LICENSE](./LICENSE) for details.
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
<!-- ########################### end of file ########################### -->
|
|
110
|
+
|
asynkio-0.0.0/README.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# asynkio - README <!-- omit in toc -->
|
|
2
|
+
|
|
3
|
+
<!--
|
|
4
|
+
[](https://circleci.com/gh/google/asynkio)
|
|
5
|
+
-->
|
|
6
|
+
[](https://opensource.org/licenses/BSD-3-Clause)
|
|
7
|
+
[](https://badge.fury.io/py/asynkio)
|
|
8
|
+

|
|
9
|
+
[](https://github.com/synesissoftware/asynkio/actions/workflows/python-package.yml)
|
|
10
|
+
[](https://github.com/synesissoftware/asynkio/commits/master)
|
|
11
|
+
|
|
12
|
+
Tokio-like functionality for Python
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## Table of contents <!-- omit in toc -->
|
|
16
|
+
|
|
17
|
+
- [Introduction](#introduction)
|
|
18
|
+
- [Installation \& Usage](#installation--usage)
|
|
19
|
+
- [Components](#components)
|
|
20
|
+
- [Examples](#examples)
|
|
21
|
+
- [Project Information](#project-information)
|
|
22
|
+
- [Where to get help](#where-to-get-help)
|
|
23
|
+
- [Contribution guidelines](#contribution-guidelines)
|
|
24
|
+
- [Dependencies](#dependencies)
|
|
25
|
+
- [Related projects](#related-projects)
|
|
26
|
+
- [License](#license)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
## Introduction
|
|
30
|
+
|
|
31
|
+
**asynkio** - a portmanteau of **asyncio** and **Tokio**, pronounced "ay sink ee-oh" - is a small, simple **Python** library that provides some of the features of the **Rust** **Tokio** library's features, such as `Duration`, `Instant`, and `Interval`.
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
## Installation & Usage
|
|
35
|
+
|
|
36
|
+
Install via **pip** or **pip3**, as in:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
$ pip3 install asynkio
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Use via **import**:
|
|
43
|
+
|
|
44
|
+
T.B.C.
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
## Components
|
|
48
|
+
|
|
49
|
+
T.B.C.
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
## Examples
|
|
53
|
+
|
|
54
|
+
Examples are provided in the ```examples``` directory, along with a markdown description for each. A detailed list TOC of them is provided in [EXAMPLES.md](./EXAMPLES.md).
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
## Project Information
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
### Where to get help
|
|
61
|
+
|
|
62
|
+
[GitHub Page](https://github.com/synesissoftware/asynkio "GitHub Page")
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
### Contribution guidelines
|
|
66
|
+
|
|
67
|
+
Defect reports, feature requests, and pull requests are welcome on https://github.com/synesissoftware/asynkio.
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
### Dependencies
|
|
71
|
+
|
|
72
|
+
T.B.C.
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
### Related projects
|
|
76
|
+
|
|
77
|
+
T.B.C.
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
### License
|
|
81
|
+
|
|
82
|
+
**asynkio** is released under the 3-clause BSD license. See [LICENSE](./LICENSE) for details.
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
<!-- ########################### end of file ########################### -->
|
|
86
|
+
|
|
File without changes
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
|
|
2
|
+
import time
|
|
3
|
+
from typing import Self
|
|
4
|
+
|
|
5
|
+
class Duration:
|
|
6
|
+
"""
|
|
7
|
+
Represents a span of time.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
def __init__(
|
|
11
|
+
self,
|
|
12
|
+
from_ns,
|
|
13
|
+
to_ns,
|
|
14
|
+
):
|
|
15
|
+
"""
|
|
16
|
+
Creates a new instance from the number of nanoseconds represented by
|
|
17
|
+
`to_ns - from_ns`.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
assert from_ns <= to_ns
|
|
21
|
+
|
|
22
|
+
self._duration = to_ns - from_ns
|
|
23
|
+
|
|
24
|
+
@staticmethod
|
|
25
|
+
def from_nanos(t_ns : int) -> Self:
|
|
26
|
+
"""
|
|
27
|
+
Creates a new instance from the specified number of nanoseconds.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
return Duration(0, t_ns)
|
|
31
|
+
|
|
32
|
+
@staticmethod
|
|
33
|
+
def from_micros(t_us : int) -> Self:
|
|
34
|
+
"""
|
|
35
|
+
Creates a new instance from the specified number of microseconds.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
return Duration(0, t_us * 1_000)
|
|
39
|
+
|
|
40
|
+
@staticmethod
|
|
41
|
+
def from_millis(t_ms : int) -> Self:
|
|
42
|
+
"""
|
|
43
|
+
Creates a new instance from the specified number of milliseconds.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
return Duration(0, t_ms * 1_000_000)
|
|
47
|
+
|
|
48
|
+
@staticmethod
|
|
49
|
+
def from_secs(t_s : int) -> Self:
|
|
50
|
+
"""
|
|
51
|
+
Creates a new instance from the specified number of seconds.
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
return Duration(0, t_s * 1_000_000_000)
|
|
55
|
+
|
|
56
|
+
def as_nanos(self) -> int:
|
|
57
|
+
"""
|
|
58
|
+
Total number of whole nanoseconds contained by this instance.
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
return self._duration
|
|
62
|
+
|
|
63
|
+
def as_micros(self) -> int:
|
|
64
|
+
"""
|
|
65
|
+
Total number of whole microseconds contained by this instance.
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
return self._duration // 1_000
|
|
69
|
+
|
|
70
|
+
def as_millis(self) -> int:
|
|
71
|
+
"""
|
|
72
|
+
Total number of whole milliseconds contained by this instance.
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
return self._duration // 1_000_000
|
|
76
|
+
|
|
77
|
+
def as_secs(self) -> int:
|
|
78
|
+
"""
|
|
79
|
+
Total number of whole seconds contained by this instance.
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
return self._duration // 1_000_000_000
|
|
83
|
+
|
|
84
|
+
def as_secs_f(self) -> float:
|
|
85
|
+
"""
|
|
86
|
+
The fractional number of seconds contained by this instance.
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
return self._duration / 1_000_000_000
|
|
90
|
+
|
|
91
|
+
def subsec_nanos(self) -> int:
|
|
92
|
+
"""
|
|
93
|
+
The fractional part of this instance, in nanoseconds.
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
return self._duration % 1_000_000_000
|
|
97
|
+
|
|
98
|
+
def subsec_micros(self) -> int:
|
|
99
|
+
"""
|
|
100
|
+
The fractional part of this instance, in microseconds.
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
return (self._duration % 1_000_000_000) // 1_000
|
|
104
|
+
|
|
105
|
+
def subsec_millis(self) -> int:
|
|
106
|
+
"""
|
|
107
|
+
The fractional part of this instance, in milliseconds.
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
return (self._duration % 1_000_000_000) // 1_000_000
|
|
111
|
+
|
|
112
|
+
def __format__(self, format_spec) -> str:
|
|
113
|
+
|
|
114
|
+
v = self._duration
|
|
115
|
+
|
|
116
|
+
if v == 0:
|
|
117
|
+
|
|
118
|
+
return "0s"
|
|
119
|
+
|
|
120
|
+
if v >= 1_000_000:
|
|
121
|
+
|
|
122
|
+
if v >= 1_000_000_000:
|
|
123
|
+
|
|
124
|
+
q, r = divmod(v, 1_000_000_000)
|
|
125
|
+
|
|
126
|
+
if r > 1_000_000:
|
|
127
|
+
|
|
128
|
+
return f"{self._duration / 1_000_000_000.0:.4}s"
|
|
129
|
+
else:
|
|
130
|
+
|
|
131
|
+
return f"{self._duration // 1_000_000_000}s"
|
|
132
|
+
else:
|
|
133
|
+
|
|
134
|
+
q, r = divmod(v, 1_000_000)
|
|
135
|
+
|
|
136
|
+
if r > 1_000:
|
|
137
|
+
|
|
138
|
+
return f"{self._duration / 1_000_000.0:.4}ms"
|
|
139
|
+
else:
|
|
140
|
+
|
|
141
|
+
return f"{self._duration // 1_000_000}ms"
|
|
142
|
+
|
|
143
|
+
if v >= 1_000:
|
|
144
|
+
|
|
145
|
+
q, r = divmod(v, 1_000)
|
|
146
|
+
|
|
147
|
+
if r > 1:
|
|
148
|
+
|
|
149
|
+
return f"{self._duration / 1_000.0:.4}µs"
|
|
150
|
+
else:
|
|
151
|
+
|
|
152
|
+
return f"{self._duration // 1_000}µs"
|
|
153
|
+
|
|
154
|
+
return f"{self._duration}ns"
|
|
155
|
+
|
|
156
|
+
def __str__(self):
|
|
157
|
+
|
|
158
|
+
return self.__format__('')
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
class Instant:
|
|
162
|
+
"""
|
|
163
|
+
Represents a moment in time.
|
|
164
|
+
"""
|
|
165
|
+
|
|
166
|
+
def __init__(self, t_ns):
|
|
167
|
+
"""
|
|
168
|
+
Initialises with the given time instant (specified in nanoseconds).
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
self._t = t_ns
|
|
172
|
+
|
|
173
|
+
@staticmethod
|
|
174
|
+
def now() -> Self:
|
|
175
|
+
"""
|
|
176
|
+
Initialises with the current time instant.
|
|
177
|
+
"""
|
|
178
|
+
|
|
179
|
+
t_now_ns = time.time_ns()
|
|
180
|
+
|
|
181
|
+
return Instant(t_now_ns)
|
|
182
|
+
|
|
183
|
+
def __lt__(self, other):
|
|
184
|
+
"""
|
|
185
|
+
Determines whether the called instance is less-than the `other`
|
|
186
|
+
instance of `Instant`.
|
|
187
|
+
"""
|
|
188
|
+
|
|
189
|
+
if isinstance(other, Instant):
|
|
190
|
+
|
|
191
|
+
return self._t < other._t
|
|
192
|
+
|
|
193
|
+
raise NotImplemented
|
|
194
|
+
|
|
195
|
+
def __le__(self, other):
|
|
196
|
+
"""
|
|
197
|
+
Determines whether the called instance is less-than-or-equal-to the
|
|
198
|
+
`other` instance of `Instant`.
|
|
199
|
+
"""
|
|
200
|
+
|
|
201
|
+
if isinstance(other, Instant):
|
|
202
|
+
|
|
203
|
+
return self._t <= other._t
|
|
204
|
+
|
|
205
|
+
raise NotImplemented
|
|
206
|
+
|
|
207
|
+
def __sub__(self, other):
|
|
208
|
+
"""
|
|
209
|
+
Subtracts the `other` - which may be an instance of `Instant` or an
|
|
210
|
+
instance of `Duration` - from the called instance.
|
|
211
|
+
"""
|
|
212
|
+
|
|
213
|
+
if isinstance(other, Instant):
|
|
214
|
+
|
|
215
|
+
return Duration(other._t, self._t)
|
|
216
|
+
|
|
217
|
+
if isinstance(other, Duration):
|
|
218
|
+
|
|
219
|
+
return Instant(self._t - other.as_nanos())
|
|
220
|
+
|
|
221
|
+
return NotImplemented
|
|
222
|
+
|
|
223
|
+
def __add__(self, other):
|
|
224
|
+
"""
|
|
225
|
+
Adds the `other` instance of `Duration` to the called instance.
|
|
226
|
+
"""
|
|
227
|
+
|
|
228
|
+
if isinstance(other, Duration):
|
|
229
|
+
|
|
230
|
+
return Instant(self._t + other.as_nanos())
|
|
231
|
+
|
|
232
|
+
return NotImplemented
|
|
233
|
+
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: asynkio
|
|
3
|
+
Version: 0.0.0
|
|
4
|
+
Summary: Path parsing library
|
|
5
|
+
Author-email: Matt Wilson <matthew@synesis.com.au>
|
|
6
|
+
License: BSD-3
|
|
7
|
+
Project-URL: Changelog, https://github.com/synesissoftware/asynkio/releases
|
|
8
|
+
Project-URL: Homepage, https://github.com/synesissoftware/asynkio
|
|
9
|
+
Project-URL: Issues, https://github.com/synesissoftware/asynkio/issues
|
|
10
|
+
Requires-Python: >=3.11
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Requires-Dist: asyncio
|
|
14
|
+
Requires-Dist: diagnosticism
|
|
15
|
+
Provides-Extra: dev
|
|
16
|
+
Requires-Dist: aiofiles; extra == "dev"
|
|
17
|
+
Requires-Dist: pyclasp>=0.8.10; extra == "dev"
|
|
18
|
+
Requires-Dist: pytest>=7.4.4; extra == "dev"
|
|
19
|
+
Provides-Extra: test
|
|
20
|
+
Requires-Dist: aiofiles; extra == "test"
|
|
21
|
+
Requires-Dist: pyclasp>=0.8.10; extra == "test"
|
|
22
|
+
Requires-Dist: pytest>=7.4.4; extra == "test"
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# asynkio - README <!-- omit in toc -->
|
|
26
|
+
|
|
27
|
+
<!--
|
|
28
|
+
[](https://circleci.com/gh/google/asynkio)
|
|
29
|
+
-->
|
|
30
|
+
[](https://opensource.org/licenses/BSD-3-Clause)
|
|
31
|
+
[](https://badge.fury.io/py/asynkio)
|
|
32
|
+

|
|
33
|
+
[](https://github.com/synesissoftware/asynkio/actions/workflows/python-package.yml)
|
|
34
|
+
[](https://github.com/synesissoftware/asynkio/commits/master)
|
|
35
|
+
|
|
36
|
+
Tokio-like functionality for Python
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
## Table of contents <!-- omit in toc -->
|
|
40
|
+
|
|
41
|
+
- [Introduction](#introduction)
|
|
42
|
+
- [Installation \& Usage](#installation--usage)
|
|
43
|
+
- [Components](#components)
|
|
44
|
+
- [Examples](#examples)
|
|
45
|
+
- [Project Information](#project-information)
|
|
46
|
+
- [Where to get help](#where-to-get-help)
|
|
47
|
+
- [Contribution guidelines](#contribution-guidelines)
|
|
48
|
+
- [Dependencies](#dependencies)
|
|
49
|
+
- [Related projects](#related-projects)
|
|
50
|
+
- [License](#license)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
## Introduction
|
|
54
|
+
|
|
55
|
+
**asynkio** - a portmanteau of **asyncio** and **Tokio**, pronounced "ay sink ee-oh" - is a small, simple **Python** library that provides some of the features of the **Rust** **Tokio** library's features, such as `Duration`, `Instant`, and `Interval`.
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
## Installation & Usage
|
|
59
|
+
|
|
60
|
+
Install via **pip** or **pip3**, as in:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
$ pip3 install asynkio
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Use via **import**:
|
|
67
|
+
|
|
68
|
+
T.B.C.
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
## Components
|
|
72
|
+
|
|
73
|
+
T.B.C.
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
## Examples
|
|
77
|
+
|
|
78
|
+
Examples are provided in the ```examples``` directory, along with a markdown description for each. A detailed list TOC of them is provided in [EXAMPLES.md](./EXAMPLES.md).
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
## Project Information
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
### Where to get help
|
|
85
|
+
|
|
86
|
+
[GitHub Page](https://github.com/synesissoftware/asynkio "GitHub Page")
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
### Contribution guidelines
|
|
90
|
+
|
|
91
|
+
Defect reports, feature requests, and pull requests are welcome on https://github.com/synesissoftware/asynkio.
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
### Dependencies
|
|
95
|
+
|
|
96
|
+
T.B.C.
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
### Related projects
|
|
100
|
+
|
|
101
|
+
T.B.C.
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
### License
|
|
105
|
+
|
|
106
|
+
**asynkio** is released under the 3-clause BSD license. See [LICENSE](./LICENSE) for details.
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
<!-- ########################### end of file ########################### -->
|
|
110
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
asynkio/__init__.py
|
|
5
|
+
asynkio.egg-info/PKG-INFO
|
|
6
|
+
asynkio.egg-info/SOURCES.txt
|
|
7
|
+
asynkio.egg-info/dependency_links.txt
|
|
8
|
+
asynkio.egg-info/requires.txt
|
|
9
|
+
asynkio.egg-info/top_level.txt
|
|
10
|
+
asynkio/time/__init__.py
|
|
11
|
+
asynkio/time/types.py
|
|
12
|
+
tests/test_time.py
|
|
13
|
+
tests/test_timer.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
asynkio
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
build-backend = "setuptools.build_meta"
|
|
3
|
+
requires = [
|
|
4
|
+
"setuptools>=61.0",
|
|
5
|
+
"wheel",
|
|
6
|
+
]
|
|
7
|
+
|
|
8
|
+
[project]
|
|
9
|
+
authors = [
|
|
10
|
+
{ name = "Matt Wilson", email = "matthew@synesis.com.au" },
|
|
11
|
+
]
|
|
12
|
+
dependencies = [
|
|
13
|
+
"asyncio",
|
|
14
|
+
"diagnosticism",
|
|
15
|
+
]
|
|
16
|
+
description = "Path parsing library"
|
|
17
|
+
license = { text = "BSD-3" }
|
|
18
|
+
name = "asynkio"
|
|
19
|
+
readme = "README.md"
|
|
20
|
+
requires-python = ">=3.11"
|
|
21
|
+
version = "0.0.0"
|
|
22
|
+
|
|
23
|
+
[project.urls]
|
|
24
|
+
Changelog = "https://github.com/synesissoftware/asynkio/releases"
|
|
25
|
+
Homepage = "https://github.com/synesissoftware/asynkio"
|
|
26
|
+
Issues = "https://github.com/synesissoftware/asynkio/issues"
|
|
27
|
+
|
|
28
|
+
[project.optional-dependencies]
|
|
29
|
+
dev = [
|
|
30
|
+
"aiofiles",
|
|
31
|
+
"pyclasp>=0.8.10",
|
|
32
|
+
"pytest>=7.4.4",
|
|
33
|
+
]
|
|
34
|
+
test = [
|
|
35
|
+
"aiofiles",
|
|
36
|
+
"pyclasp>=0.8.10",
|
|
37
|
+
"pytest>=7.4.4",
|
|
38
|
+
]
|
|
39
|
+
|
asynkio-0.0.0/setup.cfg
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
#! /usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
# ######################################################################## #
|
|
4
|
+
# File: tests/test_time.py
|
|
5
|
+
#
|
|
6
|
+
# Purpose: Unit-test for `asynkio.time.Duration`.
|
|
7
|
+
#
|
|
8
|
+
# Created: 25th July 2025
|
|
9
|
+
# Updated: 24th August 2025
|
|
10
|
+
#
|
|
11
|
+
# Copyright (c) Matthew Wilson, Synesis Information Systems Pty Ltd
|
|
12
|
+
# All rights reserved
|
|
13
|
+
#
|
|
14
|
+
# ######################################################################## #
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
import math
|
|
18
|
+
from asynkio.time import (
|
|
19
|
+
Duration,
|
|
20
|
+
Instant,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def test_Duration_DURATION_0():
|
|
25
|
+
|
|
26
|
+
duration = Duration(0, 0)
|
|
27
|
+
|
|
28
|
+
assert 0 == duration.as_nanos()
|
|
29
|
+
assert 0 == duration.as_micros()
|
|
30
|
+
assert 0 == duration.as_millis()
|
|
31
|
+
assert 0 == duration.as_secs()
|
|
32
|
+
assert 0.0 == duration.as_secs_f()
|
|
33
|
+
|
|
34
|
+
assert 0 == duration.subsec_nanos()
|
|
35
|
+
assert 0 == duration.subsec_micros()
|
|
36
|
+
assert 0 == duration.subsec_millis()
|
|
37
|
+
|
|
38
|
+
assert "0s" == str(duration)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def test_Duration_DURATION_1_SECOND():
|
|
42
|
+
|
|
43
|
+
duration = Duration.from_secs(1)
|
|
44
|
+
|
|
45
|
+
assert 1_000_000_000 == duration.as_nanos()
|
|
46
|
+
assert 1_000_000 == duration.as_micros()
|
|
47
|
+
assert 1_000 == duration.as_millis()
|
|
48
|
+
assert 1 == duration.as_secs()
|
|
49
|
+
assert math.isclose(1.0, duration.as_secs_f())
|
|
50
|
+
|
|
51
|
+
assert 0 == duration.subsec_nanos()
|
|
52
|
+
assert 0 == duration.subsec_micros()
|
|
53
|
+
assert 0 == duration.subsec_millis()
|
|
54
|
+
|
|
55
|
+
assert "1s" == str(duration)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def test_Duration_DURATION_123_MILLISECONDS():
|
|
59
|
+
|
|
60
|
+
duration = Duration.from_millis(123)
|
|
61
|
+
|
|
62
|
+
assert 123_000_000 == duration.as_nanos()
|
|
63
|
+
assert 123_000 == duration.as_micros()
|
|
64
|
+
assert 123 == duration.as_millis()
|
|
65
|
+
assert 0 == duration.as_secs()
|
|
66
|
+
assert math.isclose(0.123, duration.as_secs_f())
|
|
67
|
+
|
|
68
|
+
assert 123_000_000 == duration.subsec_nanos()
|
|
69
|
+
assert 123_000 == duration.subsec_micros()
|
|
70
|
+
assert 123 == duration.subsec_millis()
|
|
71
|
+
|
|
72
|
+
assert "123ms" == str(duration)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def test_Duration_DURATION_123_456_789_NANOSECONDS():
|
|
76
|
+
|
|
77
|
+
duration = Duration.from_nanos(123_456_789)
|
|
78
|
+
|
|
79
|
+
assert 123_456_789 == duration.as_nanos()
|
|
80
|
+
assert 123_456 == duration.as_micros()
|
|
81
|
+
assert 123 == duration.as_millis()
|
|
82
|
+
assert 0 == duration.as_secs()
|
|
83
|
+
assert math.isclose(0.123_456_789, duration.as_secs_f())
|
|
84
|
+
|
|
85
|
+
assert 123_456_789 == duration.subsec_nanos()
|
|
86
|
+
assert 123_456 == duration.subsec_micros()
|
|
87
|
+
assert 123 == duration.subsec_millis()
|
|
88
|
+
|
|
89
|
+
assert "123.5ms" == str(duration)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def test_Duration_STRINGS():
|
|
93
|
+
|
|
94
|
+
assert "9ns" == str(Duration.from_nanos(9))
|
|
95
|
+
assert "89ns" == str(Duration.from_nanos(89))
|
|
96
|
+
assert "789ns" == str(Duration.from_nanos(789))
|
|
97
|
+
|
|
98
|
+
assert "6.789µs" == str(Duration.from_nanos(6_789))
|
|
99
|
+
assert "56.79µs" == str(Duration.from_nanos(56_789))
|
|
100
|
+
assert "456.8µs" == str(Duration.from_nanos(456_789))
|
|
101
|
+
|
|
102
|
+
assert "3.457ms" == str(Duration.from_nanos(3_456_789))
|
|
103
|
+
assert "23.46ms" == str(Duration.from_nanos(23_456_789))
|
|
104
|
+
assert "123.5ms" == str(Duration.from_nanos(123_456_789))
|
|
105
|
+
|
|
106
|
+
assert "9.123s" == str(Duration.from_nanos(9_123_456_789))
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
assert "9ns" == str(Duration.from_nanos(9))
|
|
110
|
+
assert "80ns" == str(Duration.from_nanos(80))
|
|
111
|
+
assert "700ns" == str(Duration.from_nanos(700))
|
|
112
|
+
|
|
113
|
+
assert "6µs" == str(Duration.from_nanos(6_000))
|
|
114
|
+
assert "50µs" == str(Duration.from_nanos(50_000))
|
|
115
|
+
assert "400µs" == str(Duration.from_nanos(400_000))
|
|
116
|
+
|
|
117
|
+
assert "3ms" == str(Duration.from_nanos(3_000_000))
|
|
118
|
+
assert "20ms" == str(Duration.from_nanos(20_000_000))
|
|
119
|
+
assert "100ms" == str(Duration.from_nanos(100_000_000))
|
|
120
|
+
|
|
121
|
+
assert "9s" == str(Duration.from_nanos(9_000_000_000))
|
|
122
|
+
assert "10s" == str(Duration.from_nanos(10_000_000_000))
|
|
123
|
+
assert "200s" == str(Duration.from_nanos(200_000_000_000))
|
|
124
|
+
assert "3000s" == str(Duration.from_nanos(3_000_000_000_000))
|
|
125
|
+
assert "40000s" == str(Duration.from_nanos(40_000_000_000_000))
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def test_Instant_CREATE():
|
|
129
|
+
|
|
130
|
+
instant_1 = Instant.now()
|
|
131
|
+
instant_2 = Instant.now()
|
|
132
|
+
|
|
133
|
+
assert instant_1 < instant_2
|
|
134
|
+
assert instant_1 <= instant_2
|
|
135
|
+
|
|
136
|
+
assert instant_2 > instant_1
|
|
137
|
+
assert instant_2 >= instant_1
|
|
138
|
+
|
|
139
|
+
duration_1_2 = instant_2 - instant_1
|
|
140
|
+
|
|
141
|
+
max_duration_delta = 10
|
|
142
|
+
|
|
143
|
+
assert duration_1_2.as_micros() < max_duration_delta, f"{duration_1_2.as_micros()} should be < {max_duration_delta}"
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
instant_3 = instant_1 + Duration.from_micros(123)
|
|
147
|
+
|
|
148
|
+
duration_1_3 = instant_3 - instant_1
|
|
149
|
+
|
|
150
|
+
assert 123_000 == duration_1_3.as_nanos()
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#! /usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
# ######################################################################## #
|
|
4
|
+
# File: tests/test_timer.py
|
|
5
|
+
#
|
|
6
|
+
# Created: 25th July 2025
|
|
7
|
+
# Updated: 25th July 2025
|
|
8
|
+
#
|
|
9
|
+
# Author: Matthew Wilson
|
|
10
|
+
#
|
|
11
|
+
# Copyright (c) Matthew Wilson, Synesis Information Systems Pty Ltd
|
|
12
|
+
# All rights reserved
|
|
13
|
+
#
|
|
14
|
+
# ######################################################################## #
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
import asyncio
|
|
18
|
+
import pyclasp as clasp
|
|
19
|
+
import diagnosticism as d
|
|
20
|
+
import diagnosticism.severity as sev
|
|
21
|
+
import time
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
async def run_sleep():
|
|
25
|
+
|
|
26
|
+
d.trace()
|
|
27
|
+
|
|
28
|
+
t1 = time.time_ns()
|
|
29
|
+
|
|
30
|
+
while True:
|
|
31
|
+
|
|
32
|
+
await asyncio.sleep(1)
|
|
33
|
+
|
|
34
|
+
t2 = time.time_ns()
|
|
35
|
+
|
|
36
|
+
d.log(sev.NOTICE, f"{d.func()} slept for {t2 - t1}")
|
|
37
|
+
|
|
38
|
+
t1 = t2
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
async def run_delay():
|
|
42
|
+
|
|
43
|
+
d.trace()
|
|
44
|
+
|
|
45
|
+
t0 = time.perf_counter_ns()
|
|
46
|
+
|
|
47
|
+
count = 0
|
|
48
|
+
|
|
49
|
+
t1 = time.time_ns()
|
|
50
|
+
|
|
51
|
+
delta = 1
|
|
52
|
+
|
|
53
|
+
while True:
|
|
54
|
+
|
|
55
|
+
await asyncio.sleep(delta)
|
|
56
|
+
|
|
57
|
+
t2 = time.time_ns()
|
|
58
|
+
|
|
59
|
+
d.log(sev.NOTICE, f"{d.func()} slept for {t2 - t1}")
|
|
60
|
+
|
|
61
|
+
t1 = t2
|
|
62
|
+
|
|
63
|
+
delta = 0.8
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
async def main():
|
|
67
|
+
|
|
68
|
+
d.trace()
|
|
69
|
+
|
|
70
|
+
await asyncio.gather(run_sleep(), run_delay())
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
if __name__ == "__main__":
|
|
74
|
+
|
|
75
|
+
d.enable_logging('ENABLE_LOGGING', True)
|
|
76
|
+
d.enable_tracing('ENABLE_TRACING', True)
|
|
77
|
+
|
|
78
|
+
asyncio.run(main())
|