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.

@@ -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 @@
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,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -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
+ 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
+ )