transit-python 0.8.321__cp310-abi3-win_arm64.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.
@@ -0,0 +1,104 @@
1
+ ## Copyright 2014 Cognitect. All Rights Reserved.
2
+ ## Copyright 2026 Vendekagon Labs LLC.
3
+ ##
4
+ ## Licensed under the Apache License, Version 2.0 (the "License");
5
+ ## you may not use this file except in compliance with the License.
6
+ ## You may obtain a copy of the License at
7
+ ##
8
+ ## http://www.apache.org/licenses/LICENSE-2.0
9
+ ##
10
+ ## Unless required by applicable law or agreed to in writing, software
11
+ ## distributed under the License is distributed on an "AS-IS" BASIS,
12
+ ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ ## See the License for the specific language governing permissions and
14
+ ## limitations under the License.
15
+
16
+ from transit.constants import SUB, MAP_AS_ARR
17
+
18
+ FIRST_ORD = 48
19
+ CACHE_CODE_DIGITS = 44
20
+ CACHE_SIZE = CACHE_CODE_DIGITS * CACHE_CODE_DIGITS
21
+ MIN_SIZE_CACHEABLE = 4
22
+
23
+
24
+ def is_cache_key(name):
25
+ return len(name) > 0 and name[0] == SUB and name != MAP_AS_ARR
26
+
27
+
28
+ def encode_key(i):
29
+ lo = i % CACHE_CODE_DIGITS
30
+ hi = i // CACHE_CODE_DIGITS
31
+ if hi == 0:
32
+ return "^" + chr(lo + FIRST_ORD)
33
+ return "^" + chr(hi + FIRST_ORD) + chr(lo + FIRST_ORD)
34
+
35
+
36
+ def decode_key(s):
37
+ sz = len(s)
38
+ if sz == 2:
39
+ return ord(s[1]) - FIRST_ORD
40
+ return (ord(s[2]) - FIRST_ORD) + \
41
+ (CACHE_CODE_DIGITS * (ord(s[1]) - FIRST_ORD))
42
+
43
+
44
+ def is_cacheable(string, as_map_key=False):
45
+ return len(string) >= MIN_SIZE_CACHEABLE \
46
+ and (as_map_key or string[:2] in ("~#", "~$", "~:"))
47
+
48
+
49
+ class RollingCache:
50
+ """This is the internal cache used by python-transit for cacheing and
51
+ expanding map keys during writing and reading. The cache enables transit
52
+ to minimize the amount of duplicate data sent over the wire, effectively
53
+ compressing down the overall payload size. The cache is not intended to
54
+ be used directly.
55
+
56
+ Readers and writers must agree on cache codes, so this follows the
57
+ transit spec (and transit-java): codes are assigned in order from "^0",
58
+ and once CACHE_SIZE entries are in use the cache starts over from "^0".
59
+ """
60
+ def __init__(self):
61
+ self.key_to_value = {}
62
+ self.value_to_key = {}
63
+ self.index = 0
64
+
65
+ def decode(self, name, as_map_key=False):
66
+ """Reading: expand a cache code, or remember a cacheable value.
67
+ Always returns the (uncached) name.
68
+ """
69
+ if is_cache_key(name):
70
+ try:
71
+ return self.key_to_value[name]
72
+ except KeyError:
73
+ raise ValueError("Unknown cache code: " + name) from None
74
+ if is_cacheable(name, as_map_key):
75
+ self.encache(name)
76
+ return name
77
+
78
+ def encode(self, name, as_map_key=False):
79
+ """Writing: returns the name the first time and the code after that."""
80
+ if name in self.value_to_key:
81
+ return self.value_to_key[name]
82
+ if is_cacheable(name, as_map_key):
83
+ self.encache(name)
84
+ return name
85
+
86
+ def size(self):
87
+ return len(self.key_to_value)
88
+
89
+ def is_cache_full(self):
90
+ return self.index >= CACHE_SIZE
91
+
92
+ def encache(self, name):
93
+ if self.is_cache_full():
94
+ self.clear()
95
+ key = encode_key(self.index)
96
+ self.index += 1
97
+ self.key_to_value[key] = name
98
+ self.value_to_key[name] = key
99
+ return name
100
+
101
+ def clear(self):
102
+ self.key_to_value = {}
103
+ self.value_to_key = {}
104
+ self.index = 0
transit/sosjson.py ADDED
@@ -0,0 +1,129 @@
1
+ ## copyright 2014 cognitect. all rights reserved.
2
+ ## Copyright 2026 Vendekagon Labs LLC.
3
+ ##
4
+ ## licensed under the apache license, version 2.0 (the "license");
5
+ ## you may not use this file except in compliance with the license.
6
+ ## you may obtain a copy of the license at
7
+ ##
8
+ ## http://www.apache.org/licenses/license-2.0
9
+ ##
10
+ ## unless required by applicable law or agreed to in writing, software
11
+ ## distributed under the license is distributed on an "as-is" basis,
12
+ ## without warranties or conditions of any kind, either express or implied.
13
+ ## see the license for the specific language governing permissions and
14
+ ## limitations under the license.
15
+ # Streaming reads of a sequence of JSON texts (as sent over a pipe or socket),
16
+ # yielding each top level value as soon as it has fully arrived.
17
+ #
18
+ # Rather than scanning a character at a time, whatever data is available is
19
+ # read in one go and a regex skips ahead to the characters that matter for
20
+ # finding the end of a value (brackets, quotes and escapes). Each complete
21
+ # value is then handed to json.loads.
22
+ import codecs
23
+ import json
24
+ import re
25
+
26
+ CHUNK_SIZE = 64 * 1024
27
+
28
+ _NON_WS = re.compile(r"[^ \t\n\r]")
29
+ _STRUCTURAL = re.compile(r'[\[\]{}"]')
30
+ _IN_STRING = re.compile(r'["\\]')
31
+
32
+
33
+ def read_available(stream, size=CHUNK_SIZE):
34
+ """Return a function that reads whatever data is available from stream,
35
+ blocking only until there is some. Returns an empty value at EOF.
36
+ """
37
+ buffer = getattr(stream, "buffer", None)
38
+ if buffer is not None and hasattr(buffer, "read1"):
39
+ # A text wrapper (e.g. sys.stdin); read(n) on it blocks until n
40
+ # characters arrive, so read bytes from the underlying buffer.
41
+ return lambda: buffer.read1(size)
42
+ if hasattr(stream, "read1"):
43
+ return lambda: stream.read1(size)
44
+ return lambda: stream.read(size)
45
+
46
+
47
+ def chunks_raw(stream):
48
+ """Yield data from stream as it becomes available, until EOF."""
49
+ read = read_available(stream)
50
+ while True:
51
+ data = read()
52
+ if not data:
53
+ return
54
+ yield data
55
+
56
+
57
+ def chunks(stream):
58
+ """Yield text from stream as it becomes available, decoding bytes as UTF-8."""
59
+ decoder = codecs.getincrementaldecoder("utf-8")()
60
+ for data in chunks_raw(stream):
61
+ text = data if isinstance(data, str) else decoder.decode(data)
62
+ if text:
63
+ yield text
64
+ decoder.decode(b"", final=True) # raises on truncated UTF-8
65
+
66
+
67
+ def yield_json(stream):
68
+ """Yield the text of each top level JSON array, object or string in stream."""
69
+ buf = ""
70
+ pos = 0 # where to resume scanning in buf
71
+ start = None # start of the value being read, None between values
72
+ depth = 0
73
+ in_string = False
74
+ for text in chunks(stream):
75
+ buf += text
76
+ while True:
77
+ if start is None:
78
+ m = _NON_WS.search(buf, pos)
79
+ if not m:
80
+ buf, pos = "", 0
81
+ break
82
+ start = m.start()
83
+ c = buf[start]
84
+ pos = start + 1
85
+ if c == '"':
86
+ in_string = True
87
+ elif c in "[{":
88
+ depth = 1
89
+ else:
90
+ raise ValueError("Expected a JSON array, object or string, "
91
+ "found: " + repr(buf[start:start + 20]))
92
+ elif in_string:
93
+ m = _IN_STRING.search(buf, pos)
94
+ if not m:
95
+ pos = len(buf)
96
+ break
97
+ if m.group() == "\\":
98
+ if m.end() == len(buf):
99
+ # escaped character hasn't arrived yet
100
+ pos = m.start()
101
+ break
102
+ pos = m.end() + 1
103
+ continue
104
+ pos = m.end()
105
+ in_string = False
106
+ else:
107
+ m = _STRUCTURAL.search(buf, pos)
108
+ if not m:
109
+ pos = len(buf)
110
+ break
111
+ c = m.group()
112
+ pos = m.end()
113
+ if c == '"':
114
+ in_string = True
115
+ continue
116
+ depth += 1 if c in "[{" else -1
117
+ if depth == 0 and not in_string:
118
+ yield buf[start:pos]
119
+ buf, pos, start = buf[pos:], 0, None
120
+ if start is not None:
121
+ raise ValueError("Stream ended in the middle of a JSON value")
122
+
123
+
124
+ def items(stream, **kwargs):
125
+ """Yield each top level JSON value in stream as soon as it is available.
126
+ Keyword arguments are passed to json.loads (e.g. object_pairs_hook).
127
+ """
128
+ for s in yield_json(stream):
129
+ yield json.loads(s, **kwargs)
@@ -0,0 +1,267 @@
1
+ ## Copyright 2014 Cognitect. All Rights Reserved.
2
+ ## Copyright 2026 Vendekagon Labs LLC.
3
+ ##
4
+ ## Licensed under the Apache License, Version 2.0 (the "License");
5
+ ## you may not use this file except in compliance with the License.
6
+ ## You may obtain a copy of the License at
7
+ ##
8
+ ## http://www.apache.org/licenses/LICENSE-2.0
9
+ ##
10
+ ## Unless required by applicable law or agreed to in writing, software
11
+ ## distributed under the License is distributed on an "AS-IS" BASIS,
12
+ ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ ## See the License for the specific language governing permissions and
14
+ ## limitations under the License.
15
+ from collections.abc import Hashable, Mapping
16
+
17
+
18
+ class Named:
19
+ def _parse(self):
20
+ p = self.str.split('/', 1)
21
+ if len(p) == 1:
22
+ self._name = self.str
23
+ self._namespace = None
24
+ else:
25
+ self._namespace = p[0] or None
26
+ self._name = p[1] or "/"
27
+ return self._name, self._namespace
28
+
29
+ @property
30
+ def name(self):
31
+ return self._name if hasattr(self, "_name") else self._parse()[0]
32
+
33
+ @property
34
+ def namespace(self):
35
+ return self._namespace if hasattr(self, "_namespace") \
36
+ else self._parse()[1]
37
+
38
+
39
+ class Keyword(Named):
40
+ def __init__(self, value):
41
+ assert isinstance(value, str)
42
+ self.str = value
43
+ self.hv = value.__hash__()
44
+
45
+ def __hash__(self):
46
+ return self.hv
47
+
48
+ def __eq__(self, other):
49
+ return isinstance(other, Keyword) and self.str == other.str
50
+
51
+ def __ne__(self, other):
52
+ return not self == other
53
+
54
+ def __call__(self, mp):
55
+ return mp[self]
56
+
57
+ def __repr__(self):
58
+ return "<Keyword " + self.str + ">"
59
+
60
+ def __str__(self):
61
+ return self.str
62
+
63
+
64
+ class Symbol(Named):
65
+ def __init__(self, value):
66
+ assert isinstance(value, str)
67
+ self.str = value
68
+ self.hv = value.__hash__()
69
+
70
+ def __hash__(self):
71
+ return self.hv
72
+
73
+ def __eq__(self, other):
74
+ return isinstance(other, Symbol) and self.str == other.str
75
+
76
+ def __ne__(self, other):
77
+ return not self == other
78
+
79
+ def __call__(self, mp):
80
+ return mp[self]
81
+
82
+ def __repr__(self):
83
+ return self.str
84
+
85
+ def __str__(self):
86
+ return self.str
87
+
88
+ kw_cache = {}
89
+
90
+
91
+ class _KWS:
92
+ def __getattr__(self, item):
93
+ value = self(item)
94
+ setattr(self, item, value)
95
+ return value
96
+
97
+ def __call__(self, str):
98
+ if str in kw_cache:
99
+ return kw_cache[str]
100
+ else:
101
+ kw_cache[str] = Keyword(str)
102
+ return kw_cache[str]
103
+
104
+ kws = _KWS()
105
+
106
+
107
+ class TaggedValue:
108
+ def __init__(self, tag, rep):
109
+ self.tag = tag
110
+ self.rep = rep
111
+
112
+ def __eq__(self, other):
113
+ if isinstance(other, TaggedValue):
114
+ return self.tag == other.tag and \
115
+ self.rep == other.rep
116
+ return False
117
+
118
+ def __ne__(self, other):
119
+ return not (self == other)
120
+
121
+ def __hash__(self):
122
+ if isinstance(self.rep, list):
123
+ return hash(tuple(self.rep))
124
+ return hash(self.rep)
125
+
126
+ def __str__(self):
127
+ return repr(self)
128
+
129
+ def __repr__(self):
130
+ return self.tag + " " + repr(self.rep)
131
+
132
+
133
+ class Set(TaggedValue):
134
+ def __init__(self, rep):
135
+ TaggedValue.__init__(self, "set", rep)
136
+
137
+
138
+ class CMap(TaggedValue):
139
+ def __init__(self, rep):
140
+ TaggedValue.__init__(self, "cmap", rep)
141
+
142
+
143
+ class Vector(TaggedValue):
144
+ def __init__(self, rep):
145
+ TaggedValue.__init__(self, "vector", rep)
146
+
147
+
148
+ class Array(TaggedValue):
149
+ def __init__(self, rep):
150
+ TaggedValue.__init__(self, "array", rep)
151
+
152
+
153
+ class List(TaggedValue):
154
+ def __init__(self, rep):
155
+ TaggedValue.__init__(self, "list", rep)
156
+
157
+
158
+ class URI(TaggedValue):
159
+ def __init__(self, rep):
160
+ TaggedValue.__init__(self, "uri", rep)
161
+
162
+
163
+ class frozendict(Mapping, Hashable):
164
+ def __init__(self, *args, **kwargs):
165
+ self._dict = dict(*args, **kwargs)
166
+
167
+ def __len__(self):
168
+ return len(self._dict)
169
+
170
+ def __iter__(self):
171
+ return iter(self._dict)
172
+
173
+ def __getitem__(self, key):
174
+ return self._dict[key]
175
+
176
+ def __hash__(self):
177
+ return hash(frozenset(self._dict.items()))
178
+
179
+ def __repr__(self):
180
+ return 'frozendict(%r)' % (self._dict,)
181
+
182
+
183
+ class Link:
184
+ # Class property constants for rendering types
185
+ LINK = "link"
186
+ IMAGE = "image"
187
+
188
+ # Class property constants for keywords/obj properties.
189
+ HREF = "href"
190
+ REL = "rel"
191
+ PROMPT = "prompt"
192
+ NAME = "name"
193
+ RENDER = "render"
194
+
195
+ def __init__(self, href=None, rel=None, name=None, render=None,
196
+ prompt=None):
197
+ self._dict = frozendict()
198
+ assert href and rel
199
+ if render:
200
+ assert render.lower() in [Link.LINK, Link.IMAGE]
201
+ self._dict = {Link.HREF: href,
202
+ Link.REL: rel,
203
+ Link.NAME: name,
204
+ Link.RENDER: render,
205
+ Link.PROMPT: prompt}
206
+
207
+ def __eq__(self, other):
208
+ return self._dict == other._dict
209
+
210
+ def __ne__(self, other):
211
+ return self._dict != other._dict
212
+
213
+ @property
214
+ def href(self):
215
+ return self._dict[Link.HREF]
216
+
217
+ @property
218
+ def rel(self):
219
+ return self._dict[Link.REL]
220
+
221
+ @property
222
+ def prompt(self):
223
+ return self._dict[Link.PROMPT]
224
+
225
+ @property
226
+ def name(self):
227
+ return self._dict[Link.NAME]
228
+
229
+ @property
230
+ def render(self):
231
+ return self._dict[Link.RENDER]
232
+
233
+ @property
234
+ def as_map(self):
235
+ return self._dict
236
+
237
+ @property
238
+ def as_array(self):
239
+ return [self.href, self.rel, self.name, self.render, self.prompt]
240
+
241
+
242
+ class Boolean:
243
+ """To allow a separate t/f that won't hash as 1/0. Don't call directly,
244
+ instead use true and false as singleton objects. Can use with type check.
245
+
246
+ Note that the Booleans are for preserving hash/set bools that duplicate 1/0
247
+ and not designed for use in Python outside logical evaluation (don't treat
248
+ as an int, they're not). You can get a Python bool using bool(x)
249
+ where x is a true or false Boolean.
250
+ """
251
+ def __init__(self, name):
252
+ self.v = True if name == "true" else False
253
+ self.name = name
254
+
255
+ def __bool__(self):
256
+ return self.v
257
+
258
+ def __repr__(self):
259
+ return self.name
260
+
261
+ def __str__(self):
262
+ return self.name
263
+
264
+ # lowercase rep matches java/clojure
265
+
266
+ false = Boolean("false")
267
+ true = Boolean("true")