soia-client 1.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.
Potentially problematic release.
This version of soia-client might be problematic. Click here for more details.
- soia_client-1.0.0/PKG-INFO +11 -0
- soia_client-1.0.0/README +1 -0
- soia_client-1.0.0/pyproject.toml +22 -0
- soia_client-1.0.0/setup.cfg +4 -0
- soia_client-1.0.0/soia_client.egg-info/PKG-INFO +11 -0
- soia_client-1.0.0/soia_client.egg-info/SOURCES.txt +25 -0
- soia_client-1.0.0/soia_client.egg-info/dependency_links.txt +1 -0
- soia_client-1.0.0/soia_client.egg-info/top_level.txt +1 -0
- soia_client-1.0.0/soialib/__init__.py +0 -0
- soia_client-1.0.0/soialib/impl/__init__.py +0 -0
- soia_client-1.0.0/soialib/impl/arrays.py +163 -0
- soia_client-1.0.0/soialib/impl/encoding.py +41 -0
- soia_client-1.0.0/soialib/impl/enums.py +414 -0
- soia_client-1.0.0/soialib/impl/function_maker.py +196 -0
- soia_client-1.0.0/soialib/impl/optionals.py +74 -0
- soia_client-1.0.0/soialib/impl/primitives.py +210 -0
- soia_client-1.0.0/soialib/impl/repr.py +43 -0
- soia_client-1.0.0/soialib/impl/structs.py +718 -0
- soia_client-1.0.0/soialib/impl/type_adapter.py +56 -0
- soia_client-1.0.0/soialib/keyed_items.py +14 -0
- soia_client-1.0.0/soialib/module_initializer.py +79 -0
- soia_client-1.0.0/soialib/never.py +4 -0
- soia_client-1.0.0/soialib/serializer.py +87 -0
- soia_client-1.0.0/soialib/spec.py +148 -0
- soia_client-1.0.0/soialib/timestamp.py +127 -0
- soia_client-1.0.0/tests/test_module_initializer.py +755 -0
- soia_client-1.0.0/tests/test_timestamp.py +123 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: soia-client
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Read the latest Real Python tutorials
|
|
5
|
+
Author-email: Tyler Fibonacci <gepheum@gmail.com>
|
|
6
|
+
Project-URL: Homepage, https://github.com/realpython/reader
|
|
7
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
+
Classifier: Programming Language :: Python
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Requires-Python: >=3.10
|
|
11
|
+
Description-Content-Type: text/markdown
|
soia_client-1.0.0/README
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
python3 -m unittest tests/**.py
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "soia-client"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "Read the latest Real Python tutorials"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
authors = [{ name = "Tyler Fibonacci", email = "gepheum@gmail.com" }]
|
|
11
|
+
license = { file = "LICENSE" }
|
|
12
|
+
classifiers = [
|
|
13
|
+
"License :: OSI Approved :: MIT License",
|
|
14
|
+
"Programming Language :: Python",
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
]
|
|
17
|
+
keywords = []
|
|
18
|
+
dependencies = []
|
|
19
|
+
requires-python = ">=3.10"
|
|
20
|
+
|
|
21
|
+
[project.urls]
|
|
22
|
+
Homepage = "https://github.com/realpython/reader"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: soia-client
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Read the latest Real Python tutorials
|
|
5
|
+
Author-email: Tyler Fibonacci <gepheum@gmail.com>
|
|
6
|
+
Project-URL: Homepage, https://github.com/realpython/reader
|
|
7
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
+
Classifier: Programming Language :: Python
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Requires-Python: >=3.10
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
README
|
|
2
|
+
pyproject.toml
|
|
3
|
+
soia_client.egg-info/PKG-INFO
|
|
4
|
+
soia_client.egg-info/SOURCES.txt
|
|
5
|
+
soia_client.egg-info/dependency_links.txt
|
|
6
|
+
soia_client.egg-info/top_level.txt
|
|
7
|
+
soialib/__init__.py
|
|
8
|
+
soialib/keyed_items.py
|
|
9
|
+
soialib/module_initializer.py
|
|
10
|
+
soialib/never.py
|
|
11
|
+
soialib/serializer.py
|
|
12
|
+
soialib/spec.py
|
|
13
|
+
soialib/timestamp.py
|
|
14
|
+
soialib/impl/__init__.py
|
|
15
|
+
soialib/impl/arrays.py
|
|
16
|
+
soialib/impl/encoding.py
|
|
17
|
+
soialib/impl/enums.py
|
|
18
|
+
soialib/impl/function_maker.py
|
|
19
|
+
soialib/impl/optionals.py
|
|
20
|
+
soialib/impl/primitives.py
|
|
21
|
+
soialib/impl/repr.py
|
|
22
|
+
soialib/impl/structs.py
|
|
23
|
+
soialib/impl/type_adapter.py
|
|
24
|
+
tests/test_module_initializer.py
|
|
25
|
+
tests/test_timestamp.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
soialib
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
from dataclasses import FrozenInstanceError
|
|
3
|
+
from typing import Generic, Optional
|
|
4
|
+
from weakref import WeakKeyDictionary
|
|
5
|
+
|
|
6
|
+
from soialib import spec
|
|
7
|
+
from soialib.impl.function_maker import Any, Expr, ExprLike, Line, make_function
|
|
8
|
+
from soialib.impl.type_adapter import TypeAdapter
|
|
9
|
+
from soialib.keyed_items import Item, Key, KeyedItems
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def get_array_adapter(
|
|
13
|
+
item_adapter: TypeAdapter,
|
|
14
|
+
key_attributes: tuple[str, ...],
|
|
15
|
+
) -> TypeAdapter:
|
|
16
|
+
if key_attributes:
|
|
17
|
+
default_expr = item_adapter.default_expr()
|
|
18
|
+
listuple_class = _new_keyed_items_class(key_attributes, default_expr)
|
|
19
|
+
else:
|
|
20
|
+
listuple_class = _new_listuple_class()
|
|
21
|
+
array_adapter = _ArrayAdapter(item_adapter, listuple_class)
|
|
22
|
+
key_spec_to_array_adapter = _item_to_array_adapters.setdefault(item_adapter, {})
|
|
23
|
+
return key_spec_to_array_adapter.setdefault(key_attributes, array_adapter)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class _ArrayAdapter(TypeAdapter):
|
|
27
|
+
__slots__ = (
|
|
28
|
+
"item_adapter",
|
|
29
|
+
"listuple_class",
|
|
30
|
+
"empty_listuple",
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
item_adapter: TypeAdapter
|
|
34
|
+
listuple_class: type
|
|
35
|
+
empty_listuple: tuple[()]
|
|
36
|
+
|
|
37
|
+
def __init__(
|
|
38
|
+
self,
|
|
39
|
+
item_adapter: TypeAdapter,
|
|
40
|
+
listuple_class: type,
|
|
41
|
+
):
|
|
42
|
+
self.item_adapter = item_adapter
|
|
43
|
+
self.listuple_class = listuple_class
|
|
44
|
+
self.empty_listuple = listuple_class()
|
|
45
|
+
|
|
46
|
+
def default_expr(self) -> ExprLike:
|
|
47
|
+
return "()"
|
|
48
|
+
|
|
49
|
+
def to_frozen_expr(self, arg_expr: ExprLike) -> Expr:
|
|
50
|
+
listuple_class_local = Expr.local("_lstpl?", self.listuple_class)
|
|
51
|
+
empty_listuple_local = Expr.local("_emp?", self.empty_listuple)
|
|
52
|
+
return Expr.join(
|
|
53
|
+
"(",
|
|
54
|
+
arg_expr,
|
|
55
|
+
" if ",
|
|
56
|
+
arg_expr,
|
|
57
|
+
".__class__ is ",
|
|
58
|
+
listuple_class_local,
|
|
59
|
+
" else (",
|
|
60
|
+
listuple_class_local,
|
|
61
|
+
"([",
|
|
62
|
+
self.item_adapter.to_frozen_expr("_e"),
|
|
63
|
+
" for _e in ",
|
|
64
|
+
arg_expr,
|
|
65
|
+
"]) or ",
|
|
66
|
+
empty_listuple_local,
|
|
67
|
+
"))",
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
def is_not_default_expr(self, arg_expr: ExprLike, attr_expr: ExprLike) -> ExprLike:
|
|
71
|
+
# Can't use arg_expr, an empty iterable is not guaranteed to evaluate to False.
|
|
72
|
+
return attr_expr
|
|
73
|
+
|
|
74
|
+
def to_json_expr(self, in_expr: ExprLike, readable: bool) -> ExprLike:
|
|
75
|
+
e = Expr.join("_e")
|
|
76
|
+
item_to_json = self.item_adapter.to_json_expr(e, readable)
|
|
77
|
+
if item_to_json == e:
|
|
78
|
+
return in_expr
|
|
79
|
+
return Expr.join(
|
|
80
|
+
"[",
|
|
81
|
+
item_to_json,
|
|
82
|
+
" for ",
|
|
83
|
+
e,
|
|
84
|
+
" in ",
|
|
85
|
+
in_expr,
|
|
86
|
+
"]",
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
def from_json_expr(self, json_expr: ExprLike) -> Expr:
|
|
90
|
+
listuple_class_local = Expr.local("_lstpl?", self.listuple_class)
|
|
91
|
+
empty_listuple_local = Expr.local("_emp?", self.empty_listuple)
|
|
92
|
+
return Expr.join(
|
|
93
|
+
listuple_class_local,
|
|
94
|
+
"([",
|
|
95
|
+
self.item_adapter.from_json_expr(Expr.join("_e")),
|
|
96
|
+
" for e in ",
|
|
97
|
+
json_expr,
|
|
98
|
+
"] or ",
|
|
99
|
+
empty_listuple_local,
|
|
100
|
+
")",
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
def finalize(
|
|
104
|
+
self,
|
|
105
|
+
resolve_type_fn: Callable[[spec.Type], "TypeAdapter"],
|
|
106
|
+
) -> None:
|
|
107
|
+
self.item_adapter.finalize(resolve_type_fn)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
_KeyAttributesToArrayAdapter = dict[tuple[str, ...], _ArrayAdapter]
|
|
111
|
+
_ItemToArrayAdapters = WeakKeyDictionary[TypeAdapter, _KeyAttributesToArrayAdapter]
|
|
112
|
+
|
|
113
|
+
_item_to_array_adapters: _ItemToArrayAdapters = WeakKeyDictionary()
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def _new_listuple_class() -> type:
|
|
117
|
+
class Listuple(Generic[Item], tuple[Item, ...]):
|
|
118
|
+
__slots__ = ()
|
|
119
|
+
|
|
120
|
+
return Listuple
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def _new_keyed_items_class(attributes: tuple[str, ...], default_expr: ExprLike):
|
|
124
|
+
key_items = make_function(
|
|
125
|
+
name="key_items",
|
|
126
|
+
params=["items"],
|
|
127
|
+
body=[
|
|
128
|
+
"ret = {}",
|
|
129
|
+
"for item in items:",
|
|
130
|
+
f" ret[item.{'.'.join(attributes)}] = item",
|
|
131
|
+
"return ret",
|
|
132
|
+
],
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
default = make_function(
|
|
136
|
+
name="get_default",
|
|
137
|
+
params="",
|
|
138
|
+
body=[Line.join("return ", default_expr)],
|
|
139
|
+
)()
|
|
140
|
+
|
|
141
|
+
class KeyedItemsImpl(KeyedItems[Item, Key]):
|
|
142
|
+
# nonempty __slots__ not supported for subtype of 'tuple'
|
|
143
|
+
|
|
144
|
+
_key_to_item: dict[Key, Item]
|
|
145
|
+
|
|
146
|
+
def find(self, key: Key) -> Optional[Item]:
|
|
147
|
+
try:
|
|
148
|
+
key_to_item = self._key_to_item
|
|
149
|
+
except AttributeError:
|
|
150
|
+
key_to_item = key_items(self)
|
|
151
|
+
object.__setattr__(self, "_key_to_item", key_to_item)
|
|
152
|
+
return key_to_item.get(key)
|
|
153
|
+
|
|
154
|
+
def find_or_default(self, key: Key) -> Any:
|
|
155
|
+
return self.find(key) or default
|
|
156
|
+
|
|
157
|
+
def __setattr__(self, name: str, value: Any):
|
|
158
|
+
raise FrozenInstanceError(self.__class__.__qualname__)
|
|
159
|
+
|
|
160
|
+
def __delattr__(self, name: str):
|
|
161
|
+
raise FrozenInstanceError(self.__class__.__qualname__)
|
|
162
|
+
|
|
163
|
+
return KeyedItemsImpl
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from struct import pack
|
|
2
|
+
from typing import Final
|
|
3
|
+
|
|
4
|
+
from soialib.impl.function_maker import Expr
|
|
5
|
+
|
|
6
|
+
EMPTY_STRING_WIRE: Final[Expr] = Expr.local("EMPTY_STRING_WIRE", bytes([242]))
|
|
7
|
+
STRING_WIRE: Final[Expr] = Expr.local("STRING_WIRE", bytes([243]))
|
|
8
|
+
EMPTY_BYTE_STRING_WIRE: Final[Expr] = Expr.local("EMPTY_BYTE_STRING_WIRE", bytes([244]))
|
|
9
|
+
BYTE_STRING_WIRE: Final[Expr] = Expr.local("BYTE_STRING_WIRE", bytes([245]))
|
|
10
|
+
SMALL_ARRAY_WIRES: Final[Expr] = Expr.local(
|
|
11
|
+
"SMALL_ARRAY_WIRES", tuple(bytes(b) for b in range(246, 250))
|
|
12
|
+
)
|
|
13
|
+
ARRAY_WIRE: Final[Expr] = Expr.local("ARRAY_WIRE", bytes(250))
|
|
14
|
+
NULL_WIRE: Final[Expr] = Expr.local("NULL_WIRE", bytes([255]))
|
|
15
|
+
|
|
16
|
+
_LOW_INT_BYTES: Final[tuple[bytes, ...]] = tuple([bytes([i]) for i in range(232)])
|
|
17
|
+
_ZERO_BYTES: Final[bytes] = _LOW_INT_BYTES[0]
|
|
18
|
+
_ONE_BYTES: Final[bytes] = _LOW_INT_BYTES[1]
|
|
19
|
+
|
|
20
|
+
LOW_INT_BYTES: Final[Expr] = Expr.local("LOW_INT_BYTES", _LOW_INT_BYTES)
|
|
21
|
+
ZERO_BYTES: Final[Expr] = Expr.local("ZERO_BYTES_LOCAL", _ZERO_BYTES)
|
|
22
|
+
ONE_BYTES: Final[Expr] = Expr.local("ONE_BYTES_LOCAL", _ONE_BYTES)
|
|
23
|
+
|
|
24
|
+
PACK: Final[Expr] = Expr.local("pack", pack)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _len_bytes_high(l: int) -> bytes:
|
|
28
|
+
if l < 65536:
|
|
29
|
+
return pack("H", l)
|
|
30
|
+
elif l < 2147483648:
|
|
31
|
+
return pack("I", l)
|
|
32
|
+
raise OverflowError(f"len={l}")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
LEN_BYTES: Final[Expr] = Expr.join(
|
|
36
|
+
"(",
|
|
37
|
+
LOW_INT_BYTES,
|
|
38
|
+
"[l] if l < 232 else ",
|
|
39
|
+
Expr.local("len_bytes_high", _len_bytes_high),
|
|
40
|
+
"(l))",
|
|
41
|
+
)
|