jmux 0.0.4__py3-none-any.whl → 0.0.6__py3-none-any.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.
- jmux/awaitable.py +10 -4
- jmux/decoder.py +20 -4
- jmux/demux.py +109 -60
- jmux/pda.py +8 -3
- jmux/types.py +5 -0
- {jmux-0.0.4.dist-info → jmux-0.0.6.dist-info}/METADATA +2 -2
- jmux-0.0.6.dist-info/RECORD +13 -0
- {jmux-0.0.4.dist-info → jmux-0.0.6.dist-info}/WHEEL +1 -1
- jmux-0.0.4.dist-info/RECORD +0 -13
- {jmux-0.0.4.dist-info → jmux-0.0.6.dist-info}/licenses/LICENSE +0 -0
- {jmux-0.0.4.dist-info → jmux-0.0.6.dist-info}/top_level.txt +0 -0
jmux/awaitable.py
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from asyncio import Event, Queue
|
|
2
4
|
from enum import Enum
|
|
3
5
|
from types import NoneType
|
|
4
6
|
from typing import (
|
|
5
7
|
AsyncGenerator,
|
|
8
|
+
Generic,
|
|
6
9
|
Protocol,
|
|
7
10
|
Set,
|
|
8
11
|
Type,
|
|
12
|
+
TypeVar,
|
|
9
13
|
cast,
|
|
10
14
|
runtime_checkable,
|
|
11
15
|
)
|
|
@@ -13,13 +17,15 @@ from typing import (
|
|
|
13
17
|
from jmux.error import NothingEmittedError, SinkClosedError
|
|
14
18
|
from jmux.helpers import extract_types_from_generic_alias
|
|
15
19
|
|
|
20
|
+
T = TypeVar("T")
|
|
21
|
+
|
|
16
22
|
|
|
17
23
|
class SinkType(Enum):
|
|
18
24
|
STREAMABLE_VALUES = "StreamableValues"
|
|
19
25
|
AWAITABLE_VALUE = "AwaitableValue"
|
|
20
26
|
|
|
21
27
|
|
|
22
|
-
class UnderlyingGenericMixin[T]:
|
|
28
|
+
class UnderlyingGenericMixin(Generic[T]):
|
|
23
29
|
"""
|
|
24
30
|
A mixin class that provides methods for inspecting the generic types of a
|
|
25
31
|
class at runtime.
|
|
@@ -61,7 +67,7 @@ class UnderlyingGenericMixin[T]:
|
|
|
61
67
|
|
|
62
68
|
|
|
63
69
|
@runtime_checkable
|
|
64
|
-
class IAsyncSink[T]
|
|
70
|
+
class IAsyncSink(Protocol[T]):
|
|
65
71
|
"""
|
|
66
72
|
An asynchronous sink protocol that defines a common interface for putting, closing,
|
|
67
73
|
and retrieving values from a sink.
|
|
@@ -96,7 +102,7 @@ class IAsyncSink[T](Protocol):
|
|
|
96
102
|
...
|
|
97
103
|
|
|
98
104
|
|
|
99
|
-
class StreamableValues[T]
|
|
105
|
+
class StreamableValues(UnderlyingGenericMixin[T], Generic[T]):
|
|
100
106
|
"""
|
|
101
107
|
A class that represents a stream of values that can be asynchronously iterated over.
|
|
102
108
|
It uses an asyncio.Queue to store the items and allows for putting items into the
|
|
@@ -198,7 +204,7 @@ class StreamableValues[T](UnderlyingGenericMixin[T]):
|
|
|
198
204
|
yield item
|
|
199
205
|
|
|
200
206
|
|
|
201
|
-
class AwaitableValue[T]
|
|
207
|
+
class AwaitableValue(UnderlyingGenericMixin[T], Generic[T]):
|
|
202
208
|
"""
|
|
203
209
|
A class that represents a value that will be available in the future.
|
|
204
210
|
It can be awaited to get the value, and it can only be set once.
|
jmux/decoder.py
CHANGED
|
@@ -32,26 +32,40 @@ class StringEscapeDecoder:
|
|
|
32
32
|
def __init__(self):
|
|
33
33
|
self._buffer = ""
|
|
34
34
|
self._string_escape = False
|
|
35
|
+
self._is_parsing_unicode = False
|
|
36
|
+
self._unicode_buffer = ""
|
|
35
37
|
|
|
36
38
|
def push(self, ch: str) -> str | None:
|
|
39
|
+
if self._is_parsing_unicode:
|
|
40
|
+
self._unicode_buffer += ch
|
|
41
|
+
if len(self._unicode_buffer) == 4:
|
|
42
|
+
code_point = int(self._unicode_buffer, 16)
|
|
43
|
+
decoded_char = chr(code_point)
|
|
44
|
+
self._buffer += decoded_char
|
|
45
|
+
self._is_parsing_unicode = False
|
|
46
|
+
self._unicode_buffer = ""
|
|
47
|
+
return decoded_char
|
|
48
|
+
return None
|
|
49
|
+
|
|
37
50
|
if self._string_escape:
|
|
38
51
|
self._string_escape = False
|
|
39
52
|
if ch == "u":
|
|
40
|
-
self.
|
|
41
|
-
self.
|
|
42
|
-
return
|
|
53
|
+
self._is_parsing_unicode = True
|
|
54
|
+
self._unicode_buffer = ""
|
|
55
|
+
return None
|
|
43
56
|
escaped_char = self.escape_map.get(ch, ch)
|
|
44
57
|
self._buffer += escaped_char
|
|
45
58
|
return escaped_char
|
|
46
59
|
|
|
47
60
|
if ch == "\\":
|
|
48
61
|
self._string_escape = True
|
|
62
|
+
return None
|
|
49
63
|
else:
|
|
50
64
|
self._buffer += ch
|
|
51
65
|
return ch
|
|
52
66
|
|
|
53
67
|
def is_terminating_quote(self, ch: str) -> bool:
|
|
54
|
-
if self._string_escape:
|
|
68
|
+
if self._string_escape or self._is_parsing_unicode:
|
|
55
69
|
return False
|
|
56
70
|
if ch == '"':
|
|
57
71
|
return True
|
|
@@ -60,6 +74,8 @@ class StringEscapeDecoder:
|
|
|
60
74
|
def reset(self) -> None:
|
|
61
75
|
self._buffer = ""
|
|
62
76
|
self._string_escape = False
|
|
77
|
+
self._is_parsing_unicode = False
|
|
78
|
+
self._unicode_buffer = ""
|
|
63
79
|
|
|
64
80
|
@property
|
|
65
81
|
def buffer(self) -> str:
|
jmux/demux.py
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from abc import ABC
|
|
2
4
|
from enum import Enum
|
|
3
5
|
from types import NoneType
|
|
4
6
|
from typing import (
|
|
7
|
+
Generic,
|
|
5
8
|
Optional,
|
|
6
9
|
Set,
|
|
7
10
|
Type,
|
|
11
|
+
TypeVar,
|
|
12
|
+
Union,
|
|
8
13
|
get_args,
|
|
9
14
|
get_origin,
|
|
10
15
|
get_type_hints,
|
|
@@ -42,6 +47,8 @@ from jmux.types import (
|
|
|
42
47
|
BOOLEAN_OPEN,
|
|
43
48
|
COLON,
|
|
44
49
|
COMMA,
|
|
50
|
+
EXPECT_KEY_IN_ROOT,
|
|
51
|
+
EXPECT_VALUE_IN_ARRAY,
|
|
45
52
|
FLOAT_ALLOWED,
|
|
46
53
|
INTERGER_ALLOWED,
|
|
47
54
|
JSON_FALSE,
|
|
@@ -59,11 +66,13 @@ from jmux.types import (
|
|
|
59
66
|
from jmux.types import Mode as M
|
|
60
67
|
from jmux.types import State as S
|
|
61
68
|
|
|
62
|
-
|
|
63
|
-
|
|
69
|
+
Primitive = Union[int, float, str, bool, None]
|
|
70
|
+
Emittable = Union[int, float, str, bool, None, "JMux", Enum]
|
|
71
|
+
|
|
72
|
+
T = TypeVar("T")
|
|
64
73
|
|
|
65
74
|
|
|
66
|
-
class Sink[T
|
|
75
|
+
class Sink(Generic[T]):
|
|
67
76
|
def __init__(self, delegate: "JMux"):
|
|
68
77
|
self._current_key: Optional[str] = None
|
|
69
78
|
self._current_sink: Optional[IAsyncSink[T]] = None
|
|
@@ -192,60 +201,74 @@ class JMux(ABC):
|
|
|
192
201
|
ForbiddenTypeHintsError: If a type hint is not allowed.
|
|
193
202
|
ObjectMissmatchedError: If the JMux class does not match the Pydantic model.
|
|
194
203
|
"""
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
MaybePydanticType = get_type_hints(pydantic_model).get(attr_name, None)
|
|
201
|
-
if MaybePydanticType is None:
|
|
202
|
-
if NoneType in jmux_subtype_set:
|
|
203
|
-
continue
|
|
204
|
-
else:
|
|
205
|
-
raise MissingAttributeError(
|
|
206
|
-
object_name=pydantic_model.__name__,
|
|
207
|
-
attribute=attr_name,
|
|
208
|
-
)
|
|
204
|
+
try:
|
|
205
|
+
for attr_name, type_alias in get_type_hints(cls).items():
|
|
206
|
+
jmux_main_type_set, jmux_subtype_set = extract_types_from_generic_alias(
|
|
207
|
+
type_alias
|
|
208
|
+
)
|
|
209
209
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
cls._assert_correct_set_combinations(
|
|
220
|
-
jmux_main_type_set,
|
|
221
|
-
pydantic_main_type_set,
|
|
222
|
-
pydantic_subtype_set,
|
|
223
|
-
)
|
|
210
|
+
MaybePydanticType = get_type_hints(pydantic_model).get(attr_name, None)
|
|
211
|
+
if MaybePydanticType is None:
|
|
212
|
+
if NoneType in jmux_subtype_set:
|
|
213
|
+
continue
|
|
214
|
+
else:
|
|
215
|
+
raise MissingAttributeError(
|
|
216
|
+
object_name=pydantic_model.__name__,
|
|
217
|
+
attribute=attr_name,
|
|
218
|
+
)
|
|
224
219
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
jmux_subtype_set,
|
|
228
|
-
pydantic_subtype_set,
|
|
229
|
-
pydantic_main_type_set,
|
|
230
|
-
pydantic_model,
|
|
231
|
-
attr_name,
|
|
220
|
+
pydantic_main_type_set, pydantic_subtype_set = (
|
|
221
|
+
extract_types_from_generic_alias(MaybePydanticType)
|
|
232
222
|
)
|
|
233
|
-
|
|
234
|
-
|
|
223
|
+
cls._assert_only_allowed_types(
|
|
224
|
+
jmux_main_type_set,
|
|
235
225
|
jmux_subtype_set,
|
|
236
|
-
pydantic_subtype_set,
|
|
237
226
|
pydantic_main_type_set,
|
|
238
|
-
|
|
239
|
-
attr_name,
|
|
227
|
+
pydantic_subtype_set,
|
|
240
228
|
)
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
attribute=attr_name,
|
|
246
|
-
message="Unexpected main type on JMux",
|
|
229
|
+
cls._assert_correct_set_combinations(
|
|
230
|
+
jmux_main_type_set,
|
|
231
|
+
pydantic_main_type_set,
|
|
232
|
+
pydantic_subtype_set,
|
|
247
233
|
)
|
|
248
234
|
|
|
235
|
+
if StreamableValues in jmux_main_type_set:
|
|
236
|
+
cls._assert_is_allowed_streamable_values(
|
|
237
|
+
jmux_subtype_set,
|
|
238
|
+
pydantic_subtype_set,
|
|
239
|
+
pydantic_main_type_set,
|
|
240
|
+
pydantic_model,
|
|
241
|
+
attr_name,
|
|
242
|
+
)
|
|
243
|
+
elif AwaitableValue in jmux_main_type_set:
|
|
244
|
+
cls._assert_is_allowed_awaitable_value(
|
|
245
|
+
jmux_subtype_set,
|
|
246
|
+
pydantic_subtype_set,
|
|
247
|
+
pydantic_main_type_set,
|
|
248
|
+
pydantic_model,
|
|
249
|
+
attr_name,
|
|
250
|
+
)
|
|
251
|
+
else:
|
|
252
|
+
raise ObjectMissmatchedError(
|
|
253
|
+
jmux_model=cls.__name__,
|
|
254
|
+
pydantic_model=pydantic_model.__name__,
|
|
255
|
+
attribute=attr_name,
|
|
256
|
+
message="Unexpected main type on JMux",
|
|
257
|
+
)
|
|
258
|
+
except TypeError as e:
|
|
259
|
+
raise ForbiddenTypeHintsError(message=f"Unexpected type hint: {e}") from e
|
|
260
|
+
except MissingAttributeError as e:
|
|
261
|
+
raise e
|
|
262
|
+
except ObjectMissmatchedError as e:
|
|
263
|
+
raise e
|
|
264
|
+
except Exception as e:
|
|
265
|
+
raise ObjectMissmatchedError(
|
|
266
|
+
jmux_model=cls.__name__,
|
|
267
|
+
pydantic_model=pydantic_model.__name__,
|
|
268
|
+
attribute=attr_name,
|
|
269
|
+
message=f"Unexpected main type on JMux: {e}",
|
|
270
|
+
)
|
|
271
|
+
|
|
249
272
|
@classmethod
|
|
250
273
|
def _assert_correct_set_combinations(
|
|
251
274
|
cls,
|
|
@@ -474,18 +497,27 @@ class JMux(ABC):
|
|
|
474
497
|
# CONTEXT: Root
|
|
475
498
|
case M.ROOT:
|
|
476
499
|
match self._pda.state:
|
|
477
|
-
case
|
|
500
|
+
case _ if self._pda.state in EXPECT_KEY_IN_ROOT:
|
|
478
501
|
if ch in JSON_WHITESPACE:
|
|
479
502
|
pass
|
|
480
503
|
elif ch == '"':
|
|
481
504
|
self._pda.set_state(S.PARSING_KEY)
|
|
482
505
|
self._decoder.reset()
|
|
506
|
+
elif ch in OBJECT_CLOSE:
|
|
507
|
+
if self._pda.state is S.EXPECT_KEY_AFTER_COMMA:
|
|
508
|
+
raise UnexpectedCharacterError(
|
|
509
|
+
ch,
|
|
510
|
+
self._pda.stack,
|
|
511
|
+
self._pda.state,
|
|
512
|
+
"Trailing comma in object is not allowed.",
|
|
513
|
+
)
|
|
514
|
+
await self._finalize()
|
|
483
515
|
else:
|
|
484
516
|
raise UnexpectedCharacterError(
|
|
485
517
|
ch,
|
|
486
518
|
self._pda.stack,
|
|
487
519
|
self._pda.state,
|
|
488
|
-
"Char needs to be '\"' or JSON whitespaces",
|
|
520
|
+
"Char needs to be '\"', '}' or JSON whitespaces",
|
|
489
521
|
)
|
|
490
522
|
|
|
491
523
|
case S.PARSING_KEY:
|
|
@@ -530,6 +562,14 @@ class JMux(ABC):
|
|
|
530
562
|
"Expected '[' or '\"' for 'StreamableValues'",
|
|
531
563
|
)
|
|
532
564
|
elif ch in ARRAY_OPEN:
|
|
565
|
+
if self._sink.current_sink_type == SinkType.AWAITABLE_VALUE:
|
|
566
|
+
raise UnexpectedCharacterError(
|
|
567
|
+
ch,
|
|
568
|
+
self._pda.stack,
|
|
569
|
+
self._pda.state,
|
|
570
|
+
"Trying to parse 'array' but sink type is "
|
|
571
|
+
"'AwaitableValue'.",
|
|
572
|
+
)
|
|
533
573
|
self._pda.set_state(S.EXPECT_VALUE)
|
|
534
574
|
self._pda.push(M.ARRAY)
|
|
535
575
|
else:
|
|
@@ -572,12 +612,12 @@ class JMux(ABC):
|
|
|
572
612
|
await self._parse_primitive()
|
|
573
613
|
await self._sink.close()
|
|
574
614
|
self._decoder.reset()
|
|
575
|
-
if ch in
|
|
576
|
-
self._pda.set_state(S.
|
|
577
|
-
|
|
578
|
-
self._pda.set_state(S.EXPECT_KEY)
|
|
579
|
-
if ch in OBJECT_CLOSE:
|
|
615
|
+
if ch in COMMA:
|
|
616
|
+
self._pda.set_state(S.EXPECT_KEY_AFTER_COMMA)
|
|
617
|
+
elif ch in OBJECT_CLOSE:
|
|
580
618
|
await self._finalize()
|
|
619
|
+
else:
|
|
620
|
+
self._pda.set_state(S.EXPECT_COMMA_OR_EOC)
|
|
581
621
|
else:
|
|
582
622
|
self._assert_primitive_character_allowed_in_state(ch)
|
|
583
623
|
self._decoder.push(ch)
|
|
@@ -586,7 +626,7 @@ class JMux(ABC):
|
|
|
586
626
|
if ch in JSON_WHITESPACE:
|
|
587
627
|
pass
|
|
588
628
|
elif ch in COMMA:
|
|
589
|
-
self._pda.set_state(S.
|
|
629
|
+
self._pda.set_state(S.EXPECT_KEY_AFTER_COMMA)
|
|
590
630
|
elif ch in OBJECT_CLOSE:
|
|
591
631
|
await self._finalize()
|
|
592
632
|
else:
|
|
@@ -615,12 +655,19 @@ class JMux(ABC):
|
|
|
615
655
|
)
|
|
616
656
|
|
|
617
657
|
match self._pda.state:
|
|
618
|
-
case
|
|
658
|
+
case _ if self._pda.state in EXPECT_VALUE_IN_ARRAY:
|
|
619
659
|
if ch in JSON_WHITESPACE:
|
|
620
660
|
pass
|
|
621
661
|
elif await self._handle_common__expect_value(ch):
|
|
622
662
|
pass
|
|
623
663
|
elif ch in ARRAY_CLOSE:
|
|
664
|
+
if self._pda.state is S.EXPECT_VALUE_AFTER_COMMA:
|
|
665
|
+
raise UnexpectedCharacterError(
|
|
666
|
+
ch,
|
|
667
|
+
self._pda.stack,
|
|
668
|
+
self._pda.state,
|
|
669
|
+
"Trailing comma in array is not allowed.",
|
|
670
|
+
)
|
|
624
671
|
await self._close_context(S.EXPECT_COMMA_OR_EOC)
|
|
625
672
|
else:
|
|
626
673
|
raise UnexpectedCharacterError(
|
|
@@ -663,9 +710,11 @@ class JMux(ABC):
|
|
|
663
710
|
await self._parse_primitive()
|
|
664
711
|
self._decoder.reset()
|
|
665
712
|
if ch in COMMA:
|
|
666
|
-
self._pda.set_state(S.
|
|
713
|
+
self._pda.set_state(S.EXPECT_VALUE_AFTER_COMMA)
|
|
667
714
|
elif ch in ARRAY_CLOSE:
|
|
668
715
|
await self._close_context(S.EXPECT_COMMA_OR_EOC)
|
|
716
|
+
else:
|
|
717
|
+
self._pda.set_state(S.EXPECT_COMMA_OR_EOC)
|
|
669
718
|
else:
|
|
670
719
|
self._assert_primitive_character_allowed_in_state(ch)
|
|
671
720
|
self._decoder.push(ch)
|
|
@@ -674,7 +723,7 @@ class JMux(ABC):
|
|
|
674
723
|
if ch in JSON_WHITESPACE:
|
|
675
724
|
pass
|
|
676
725
|
elif ch in COMMA:
|
|
677
|
-
self._pda.set_state(S.
|
|
726
|
+
self._pda.set_state(S.EXPECT_VALUE_AFTER_COMMA)
|
|
678
727
|
elif ch in ARRAY_CLOSE:
|
|
679
728
|
await self._close_context(S.EXPECT_COMMA_OR_EOC)
|
|
680
729
|
else:
|
jmux/pda.py
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
from
|
|
1
|
+
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from typing import Generic, List, Optional, TypeVar
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
Context = TypeVar("Context")
|
|
6
|
+
State = TypeVar("State")
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class PushDownAutomata(Generic[Context, State]):
|
|
5
10
|
def __init__(self, start_state: State) -> None:
|
|
6
11
|
self._stack: List[Context] = []
|
|
7
12
|
self._state: State = start_state
|
|
@@ -15,7 +20,7 @@ class PushDownAutomata[Context, State]:
|
|
|
15
20
|
return self._stack
|
|
16
21
|
|
|
17
22
|
@property
|
|
18
|
-
def top(self) -> Context
|
|
23
|
+
def top(self) -> Optional[Context]:
|
|
19
24
|
if not self._stack:
|
|
20
25
|
return None
|
|
21
26
|
return self._stack[-1]
|
jmux/types.py
CHANGED
|
@@ -9,8 +9,10 @@ class State(Enum):
|
|
|
9
9
|
ERROR = "error"
|
|
10
10
|
# expect
|
|
11
11
|
EXPECT_KEY = "expect_key"
|
|
12
|
+
EXPECT_KEY_AFTER_COMMA = "expect_key_after_comma"
|
|
12
13
|
EXPECT_COLON = "expect_colon"
|
|
13
14
|
EXPECT_VALUE = "expect_value"
|
|
15
|
+
EXPECT_VALUE_AFTER_COMMA = "expect_value_after_comma"
|
|
14
16
|
EXPECT_COMMA_OR_EOC = "expect_comma_or_eoc"
|
|
15
17
|
# parsing
|
|
16
18
|
PARSING_KEY = "parsing_key"
|
|
@@ -29,6 +31,9 @@ PARSING_PRIMITIVE_STATES: Set[State] = {
|
|
|
29
31
|
State.PARSING_NULL,
|
|
30
32
|
}
|
|
31
33
|
|
|
34
|
+
EXPECT_KEY_IN_ROOT = {State.EXPECT_KEY, State.EXPECT_KEY_AFTER_COMMA}
|
|
35
|
+
EXPECT_VALUE_IN_ARRAY = {State.EXPECT_VALUE, State.EXPECT_VALUE_AFTER_COMMA}
|
|
36
|
+
|
|
32
37
|
|
|
33
38
|
class Mode(Enum):
|
|
34
39
|
ROOT = "$"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: jmux
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.6
|
|
4
4
|
Summary: JMux: A Python package for demultiplexing a JSON string into multiple awaitable variables.
|
|
5
5
|
Author-email: "Johannes A.I. Unruh" <johannes@unruh.ai>
|
|
6
6
|
License: MIT License
|
|
@@ -32,7 +32,7 @@ Project-URL: Repository, https://github.com/jaunruh/jmux
|
|
|
32
32
|
Keywords: demultiplexer,python,package,json
|
|
33
33
|
Classifier: Programming Language :: Python :: 3
|
|
34
34
|
Classifier: Operating System :: OS Independent
|
|
35
|
-
Requires-Python: >=3.
|
|
35
|
+
Requires-Python: >=3.10
|
|
36
36
|
Description-Content-Type: text/markdown
|
|
37
37
|
License-File: LICENSE
|
|
38
38
|
Requires-Dist: anyio>=4.0.0
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
jmux/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
jmux/awaitable.py,sha256=otX4vbWzVmIwxvMDWOtaIvS9do8YJtbls9xFjwH9Yw0,8534
|
|
3
|
+
jmux/decoder.py,sha256=YoCkBKposMx1PA78BIVawgFw96QsqTZaOW4gNCSkI7I,2197
|
|
4
|
+
jmux/demux.py,sha256=R2vazLOtfh4zvQKoj3_92RgdqG-zaG3CkQMBz72fAIE,38800
|
|
5
|
+
jmux/error.py,sha256=VZJYivt8RPfjcF2bs-T7_UkH3dVA3xH-xGbZggQV14k,4665
|
|
6
|
+
jmux/helpers.py,sha256=zOlw1Yk7-sdKAeasswRRcuUOTEBAUbymoAGwBTMaOjg,2902
|
|
7
|
+
jmux/pda.py,sha256=19joQd0DD5OAmwRpp2jVVbtiFXnjv5P_1mZm87-QOeY,922
|
|
8
|
+
jmux/types.py,sha256=a5Xyx_8A3gsZkscII1_7E6oyu4VQ-oI4_osTnPLi_xs,1649
|
|
9
|
+
jmux-0.0.6.dist-info/licenses/LICENSE,sha256=y0qnwaAe4bEqzNPyq4M_VZA2I2mQly8MawajyZhqw0k,1169
|
|
10
|
+
jmux-0.0.6.dist-info/METADATA,sha256=cJJfsEjvnpvffxjEgdwbsTQFxB8uqIArJApCYRjTETo,13330
|
|
11
|
+
jmux-0.0.6.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
12
|
+
jmux-0.0.6.dist-info/top_level.txt,sha256=TF2N6kHqLghfOkCiNlCueMDX4l5rPn_5MSPNtYrS1-o,5
|
|
13
|
+
jmux-0.0.6.dist-info/RECORD,,
|
jmux-0.0.4.dist-info/RECORD
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
jmux/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
jmux/awaitable.py,sha256=gceBygIf3fAIWLsN1lWxsz9ExWNasDuk1WaGz8d9FAc,8427
|
|
3
|
-
jmux/decoder.py,sha256=Y6KVryRDLvGV5nBsneXpTvC0WUGhR5Z89Dvqz4HMAgg,1562
|
|
4
|
-
jmux/demux.py,sha256=g9DkMc9sLs31nuVwb7jbGZAjs0KulsKDGfOIM87NuWQ,36317
|
|
5
|
-
jmux/error.py,sha256=VZJYivt8RPfjcF2bs-T7_UkH3dVA3xH-xGbZggQV14k,4665
|
|
6
|
-
jmux/helpers.py,sha256=zOlw1Yk7-sdKAeasswRRcuUOTEBAUbymoAGwBTMaOjg,2902
|
|
7
|
-
jmux/pda.py,sha256=81gnh0eWGsgd_SrHkqjRQy_KkOSlBf5nor7pqKGgYjw,791
|
|
8
|
-
jmux/types.py,sha256=CJhFS9RVgR0cDBNJR8ROAFnxzG4YTYpNZ90hyD2SxsY,1389
|
|
9
|
-
jmux-0.0.4.dist-info/licenses/LICENSE,sha256=y0qnwaAe4bEqzNPyq4M_VZA2I2mQly8MawajyZhqw0k,1169
|
|
10
|
-
jmux-0.0.4.dist-info/METADATA,sha256=vVREVDZvfTC0KadGCOrw7RrSGxXdmZZNHJ8K-Zr3ZLM,13330
|
|
11
|
-
jmux-0.0.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
12
|
-
jmux-0.0.4.dist-info/top_level.txt,sha256=TF2N6kHqLghfOkCiNlCueMDX4l5rPn_5MSPNtYrS1-o,5
|
|
13
|
-
jmux-0.0.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|