Skip to content

Commit 6bff4a9

Browse files
committed
Add pure python fallback implementation
1 parent 34b2e36 commit 6bff4a9

File tree

6 files changed

+403
-125
lines changed

6 files changed

+403
-125
lines changed

setup.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
#!/usr/bin/env python
2+
import os
3+
import sys
24
import sysconfig
35
from typing import Any, Dict, List, Optional, Tuple
46

57
from setuptools import Extension, setup
68

9+
build: bool = os.environ.get("SONYFLAKE_TURBO_BUILD", "1").lower() in ("1", "true")
710
options: Dict[str, Any] = {}
811
define_macros: List[Tuple[str, Optional[str]]] = []
912
py_limited_api: bool = not sysconfig.get_config_var("Py_GIL_DISABLED")
1013
cflags: List[str] = []
1114

15+
if sys.implementation.name != "cpython":
16+
build = False
17+
1218
if sysconfig.get_platform().startswith("win"):
1319
cflags.append("/utf-8")
1420
cflags.append("/std:c17")
@@ -24,9 +30,10 @@
2430
options["bdist_wheel"] = {"py_limited_api": "cp310"}
2531
define_macros.append(("Py_LIMITED_API", "0x030a00f0"))
2632

27-
setup(
28-
options=options,
29-
ext_modules=[
33+
34+
setup_kwargs = {
35+
"options": options,
36+
"ext_modules": [
3037
Extension(
3138
"sonyflake_turbo._sonyflake",
3239
sources=[
@@ -39,4 +46,9 @@
3946
extra_compile_args=cflags,
4047
),
4148
],
42-
)
49+
}
50+
51+
if not build:
52+
setup_kwargs = {}
53+
54+
setup(**setup_kwargs)

src/sonyflake_turbo/__init__.py

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
1-
from typing import (
2-
Any,
3-
AsyncIterable,
4-
AsyncIterator,
5-
Awaitable,
6-
Callable,
7-
ClassVar,
8-
Generator,
9-
TypeAlias,
10-
)
11-
12-
from ._sonyflake import (
13-
SONYFLAKE_EPOCH,
14-
SONYFLAKE_MACHINE_ID_BITS,
15-
SONYFLAKE_MACHINE_ID_MAX,
16-
SONYFLAKE_MACHINE_ID_OFFSET,
17-
SONYFLAKE_SEQUENCE_BITS,
18-
SONYFLAKE_SEQUENCE_MAX,
19-
SONYFLAKE_TIME_OFFSET,
20-
MachineIDLCG,
21-
SonyFlake,
22-
)
23-
24-
AsyncSleep: TypeAlias = Callable[[float], Awaitable[None]]
1+
try:
2+
from ._sonyflake import (
3+
SONYFLAKE_EPOCH,
4+
SONYFLAKE_MACHINE_ID_BITS,
5+
SONYFLAKE_MACHINE_ID_MAX,
6+
SONYFLAKE_MACHINE_ID_OFFSET,
7+
SONYFLAKE_SEQUENCE_BITS,
8+
SONYFLAKE_SEQUENCE_MAX,
9+
SONYFLAKE_TIME_OFFSET,
10+
MachineIDLCG,
11+
SonyFlake,
12+
)
13+
except ImportError: # pragma: no cover
14+
from .pure import (
15+
SONYFLAKE_EPOCH,
16+
SONYFLAKE_MACHINE_ID_BITS,
17+
SONYFLAKE_MACHINE_ID_MAX,
18+
SONYFLAKE_MACHINE_ID_OFFSET,
19+
SONYFLAKE_SEQUENCE_BITS,
20+
SONYFLAKE_SEQUENCE_MAX,
21+
SONYFLAKE_TIME_OFFSET,
22+
MachineIDLCG,
23+
SonyFlake,
24+
)
2525

2626
__all__ = [
2727
"SONYFLAKE_EPOCH",
@@ -37,7 +37,7 @@
3737
]
3838

3939

40-
class AsyncSonyFlake(Awaitable[int], AsyncIterable[int]):
40+
class AsyncSonyFlake:
4141
"""Async wrapper for :class:`SonyFlake`.
4242
4343
Usage:
@@ -57,10 +57,9 @@ class AsyncSonyFlake(Awaitable[int], AsyncIterable[int]):
5757
break
5858
"""
5959

60-
__slots__: ClassVar[tuple[str, ...]] = ("sf", "sleep")
61-
sleep: AsyncSleep
60+
__slots__ = ("sf", "sleep")
6261

63-
def __init__(self, sf: SonyFlake, sleep: AsyncSleep | None = None) -> None:
62+
def __init__(self, sf: SonyFlake, sleep=None):
6463
"""Initialize AsyncSonyFlake ID generator.
6564
6665
Args:
@@ -76,7 +75,7 @@ def __init__(self, sf: SonyFlake, sleep: AsyncSleep | None = None) -> None:
7675
self.sf = sf
7776
self.sleep = sleep
7877

79-
async def __call__(self, n: int) -> list[int]:
78+
async def __call__(self, n):
8079
"""Generate multiple SonyFlake IDs at once.
8180
8281
Roughly equivalent to ``[await asf for _ in range(n)]``, but more
@@ -96,7 +95,7 @@ async def __call__(self, n: int) -> list[int]:
9695

9796
return ids
9897

99-
def __await__(self) -> Generator[Any, Any, int]:
98+
def __await__(self):
10099
"""Produce a SonyFlake ID."""
101100

102101
id_, to_sleep = self.sf._raw(None)
@@ -105,12 +104,12 @@ def __await__(self) -> Generator[Any, Any, int]:
105104

106105
return id_
107106

108-
def __aiter__(self) -> AsyncIterator[int]:
107+
def __aiter__(self):
109108
"""Return an infinite SonyFlake ID async iterator."""
110109

111110
return self._gen().__aiter__()
112111

113-
async def _gen(self) -> AsyncIterator[int]:
112+
async def _gen(self):
114113
"""Infinite SonyFlake ID async generator."""
115114

116115
while True:

src/sonyflake_turbo/__init__.pyi

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
from collections.abc import AsyncIterable, AsyncIterator, Awaitable
2+
from typing import (
3+
Any,
4+
Callable,
5+
ClassVar,
6+
Generator,
7+
TypeAlias,
8+
)
9+
10+
from ._sonyflake import (
11+
SONYFLAKE_EPOCH,
12+
SONYFLAKE_MACHINE_ID_BITS,
13+
SONYFLAKE_MACHINE_ID_MAX,
14+
SONYFLAKE_MACHINE_ID_OFFSET,
15+
SONYFLAKE_SEQUENCE_BITS,
16+
SONYFLAKE_SEQUENCE_MAX,
17+
SONYFLAKE_TIME_OFFSET,
18+
MachineIDLCG,
19+
SonyFlake,
20+
)
21+
22+
__all__ = [
23+
"SONYFLAKE_EPOCH",
24+
"SONYFLAKE_MACHINE_ID_BITS",
25+
"SONYFLAKE_MACHINE_ID_MAX",
26+
"SONYFLAKE_MACHINE_ID_OFFSET",
27+
"SONYFLAKE_SEQUENCE_BITS",
28+
"SONYFLAKE_SEQUENCE_MAX",
29+
"SONYFLAKE_TIME_OFFSET",
30+
"AsyncSonyFlake",
31+
"MachineIDLCG",
32+
"SonyFlake",
33+
]
34+
35+
AsyncSleep: TypeAlias = Callable[[float], Awaitable[None]]
36+
37+
class AsyncSonyFlake(Awaitable[int], AsyncIterable[int]):
38+
"""Async wrapper for :class:`SonyFlake`.
39+
40+
Usage:
41+
42+
.. code-block:: python
43+
44+
import asyncio
45+
46+
sf = SonyFlake(0x1337, 0xCAFE, start_time=1749081600)
47+
asf = AsyncSonyFlake(sf, asyncio.sleep)
48+
49+
print(await asf)
50+
print(await asf(5))
51+
52+
async for id_ in asf:
53+
print(id_)
54+
break
55+
"""
56+
57+
__slots__: ClassVar[tuple[str, ...]]
58+
sleep: AsyncSleep
59+
60+
def __init__(self, sf: SonyFlake, sleep: AsyncSleep | None = None) -> None: ...
61+
async def __call__(self, n: int) -> list[int]: ...
62+
def __await__(self) -> Generator[Any, Any, int]: ...
63+
def __aiter__(self) -> AsyncIterator[int]: ...
64+
async def _gen(self) -> AsyncIterator[int]: ...

0 commit comments

Comments
 (0)