jmux 0.0.2__py3-none-any.whl → 0.0.4__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/demux.py +115 -86
- jmux/helpers.py +37 -13
- jmux/types.py +8 -2
- {jmux-0.0.2.dist-info → jmux-0.0.4.dist-info}/METADATA +1 -1
- jmux-0.0.4.dist-info/RECORD +13 -0
- jmux-0.0.2.dist-info/RECORD +0 -13
- {jmux-0.0.2.dist-info → jmux-0.0.4.dist-info}/WHEEL +0 -0
- {jmux-0.0.2.dist-info → jmux-0.0.4.dist-info}/licenses/LICENSE +0 -0
- {jmux-0.0.2.dist-info → jmux-0.0.4.dist-info}/top_level.txt +0 -0
jmux/demux.py
CHANGED
|
@@ -32,7 +32,7 @@ from jmux.error import (
|
|
|
32
32
|
from jmux.helpers import (
|
|
33
33
|
extract_types_from_generic_alias,
|
|
34
34
|
get_main_type,
|
|
35
|
-
|
|
35
|
+
str_to_bool,
|
|
36
36
|
)
|
|
37
37
|
from jmux.pda import PushDownAutomata
|
|
38
38
|
from jmux.types import (
|
|
@@ -47,12 +47,13 @@ from jmux.types import (
|
|
|
47
47
|
JSON_FALSE,
|
|
48
48
|
JSON_NULL,
|
|
49
49
|
JSON_TRUE,
|
|
50
|
+
JSON_WHITESPACE,
|
|
50
51
|
NULL_ALLOWED,
|
|
51
52
|
NULL_OPEN,
|
|
52
53
|
NUMBER_OPEN,
|
|
53
54
|
OBJECT_CLOSE,
|
|
54
55
|
OBJECT_OPEN,
|
|
55
|
-
|
|
56
|
+
PARSING_PRIMITIVE_STATES,
|
|
56
57
|
QUOTE,
|
|
57
58
|
)
|
|
58
59
|
from jmux.types import Mode as M
|
|
@@ -215,17 +216,11 @@ class JMux(ABC):
|
|
|
215
216
|
pydantic_main_type_set,
|
|
216
217
|
pydantic_subtype_set,
|
|
217
218
|
)
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
wrong_set = (
|
|
224
|
-
jmux_main_type_set if pydantic_wrong else pydantic_main_type_set
|
|
225
|
-
)
|
|
226
|
-
raise ForbiddenTypeHintsError(
|
|
227
|
-
message=(f"Forbidden typing received on {wrong_obj}: {wrong_set}"),
|
|
228
|
-
)
|
|
219
|
+
cls._assert_correct_set_combinations(
|
|
220
|
+
jmux_main_type_set,
|
|
221
|
+
pydantic_main_type_set,
|
|
222
|
+
pydantic_subtype_set,
|
|
223
|
+
)
|
|
229
224
|
|
|
230
225
|
if StreamableValues in jmux_main_type_set:
|
|
231
226
|
cls._assert_is_allowed_streamable_values(
|
|
@@ -251,6 +246,80 @@ class JMux(ABC):
|
|
|
251
246
|
message="Unexpected main type on JMux",
|
|
252
247
|
)
|
|
253
248
|
|
|
249
|
+
@classmethod
|
|
250
|
+
def _assert_correct_set_combinations(
|
|
251
|
+
cls,
|
|
252
|
+
jmux_main_type_set: Set[Type],
|
|
253
|
+
pydantic_main_type_set: Set[Type],
|
|
254
|
+
pydantic_subtype_set: Set[Type],
|
|
255
|
+
):
|
|
256
|
+
if (
|
|
257
|
+
pydantic_wrong := (
|
|
258
|
+
len(pydantic_main_type_set) != 1 and list not in pydantic_main_type_set
|
|
259
|
+
)
|
|
260
|
+
and len(pydantic_subtype_set) > 0
|
|
261
|
+
) or len(jmux_main_type_set) != 1:
|
|
262
|
+
wrong_obj = "pydantic" if pydantic_wrong else "JMux"
|
|
263
|
+
wrong_set = pydantic_main_type_set if pydantic_wrong else jmux_main_type_set
|
|
264
|
+
raise ForbiddenTypeHintsError(
|
|
265
|
+
message=(f"Forbidden typing received on {wrong_obj}: {wrong_set}"),
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
@classmethod
|
|
269
|
+
def _assert_only_allowed_types(
|
|
270
|
+
cls,
|
|
271
|
+
jmux_main_type_set: Set[Type],
|
|
272
|
+
jmux_subtype_set: Set[Type],
|
|
273
|
+
pydantic_main_type_set: Set[Type],
|
|
274
|
+
pydantic_subtype_set: Set[Type],
|
|
275
|
+
) -> None:
|
|
276
|
+
if not all(t in (AwaitableValue, StreamableValues) for t in jmux_main_type_set):
|
|
277
|
+
raise ForbiddenTypeHintsError(
|
|
278
|
+
message=(
|
|
279
|
+
"JMux must have either AwaitableValue or StreamableValues as "
|
|
280
|
+
f"main type, got {jmux_main_type_set}."
|
|
281
|
+
)
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
if not cls._all_elements_in_set_a_are_subclass_of_an_element_in_set_b(
|
|
285
|
+
set_a=jmux_subtype_set,
|
|
286
|
+
set_b={int, float, str, bool, NoneType, JMux, Enum},
|
|
287
|
+
):
|
|
288
|
+
raise ForbiddenTypeHintsError(
|
|
289
|
+
message=(
|
|
290
|
+
"JMux sub type must be one of the emittable types, got: "
|
|
291
|
+
f"{jmux_subtype_set}."
|
|
292
|
+
)
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
if not cls._all_elements_in_set_a_are_subclass_of_an_element_in_set_b(
|
|
296
|
+
set_a=pydantic_subtype_set,
|
|
297
|
+
set_b={int, float, str, bool, NoneType, BaseModel, Enum},
|
|
298
|
+
):
|
|
299
|
+
raise ForbiddenTypeHintsError(
|
|
300
|
+
message=(
|
|
301
|
+
"Pydantic sub type must be one of the primitive, enum or "
|
|
302
|
+
f"BaseModel, got: {pydantic_subtype_set}."
|
|
303
|
+
)
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
if not cls._all_elements_in_set_a_are_subclass_of_an_element_in_set_b(
|
|
307
|
+
set_a=pydantic_main_type_set,
|
|
308
|
+
set_b={int, float, str, bool, list, NoneType, BaseModel, Enum},
|
|
309
|
+
):
|
|
310
|
+
raise ForbiddenTypeHintsError(
|
|
311
|
+
message=(
|
|
312
|
+
"Pydantic main type must be one of the primitive, enum, list "
|
|
313
|
+
f"or BaseModel, got {pydantic_main_type_set}."
|
|
314
|
+
)
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
@classmethod
|
|
318
|
+
def _all_elements_in_set_a_are_subclass_of_an_element_in_set_b(
|
|
319
|
+
cls, set_a: Set[Type], set_b: Set[Type]
|
|
320
|
+
) -> bool:
|
|
321
|
+
return all(any(issubclass(elem, t) for t in set_b) for elem in set_a)
|
|
322
|
+
|
|
254
323
|
@classmethod
|
|
255
324
|
def _assert_is_allowed_streamable_values(
|
|
256
325
|
cls,
|
|
@@ -328,58 +397,6 @@ class JMux(ABC):
|
|
|
328
397
|
),
|
|
329
398
|
)
|
|
330
399
|
|
|
331
|
-
@classmethod
|
|
332
|
-
def _assert_only_allowed_types(
|
|
333
|
-
cls,
|
|
334
|
-
jmux_main_type_set: Set[Type],
|
|
335
|
-
jmux_subtype_set: Set[Type],
|
|
336
|
-
pydantic_main_type_set: Set[Type],
|
|
337
|
-
pydantic_subtype_set: Set[Type],
|
|
338
|
-
) -> None:
|
|
339
|
-
if not all(t in (AwaitableValue, StreamableValues) for t in jmux_main_type_set):
|
|
340
|
-
raise ForbiddenTypeHintsError(
|
|
341
|
-
message=(
|
|
342
|
-
"JMux must have either AwaitableValue or StreamableValues as "
|
|
343
|
-
f"main type, got {jmux_main_type_set}."
|
|
344
|
-
)
|
|
345
|
-
)
|
|
346
|
-
|
|
347
|
-
if not any(
|
|
348
|
-
issubclass(elem, t)
|
|
349
|
-
for t in (int, float, str, bool, NoneType, JMux, Enum)
|
|
350
|
-
for elem in jmux_subtype_set
|
|
351
|
-
):
|
|
352
|
-
raise ForbiddenTypeHintsError(
|
|
353
|
-
message=(
|
|
354
|
-
"JMux sub type must be one of the emittable types: "
|
|
355
|
-
f"{jmux_subtype_set}."
|
|
356
|
-
)
|
|
357
|
-
)
|
|
358
|
-
|
|
359
|
-
if len(pydantic_subtype_set) > 0 and not any(
|
|
360
|
-
issubclass(elem, t)
|
|
361
|
-
for t in (int, float, str, bool, NoneType, BaseModel, Enum)
|
|
362
|
-
for elem in pydantic_subtype_set
|
|
363
|
-
):
|
|
364
|
-
raise ForbiddenTypeHintsError(
|
|
365
|
-
message=(
|
|
366
|
-
"Pydantic sub type must be one of the primitive, enum or "
|
|
367
|
-
f"BaseModel, got: {pydantic_subtype_set}."
|
|
368
|
-
)
|
|
369
|
-
)
|
|
370
|
-
|
|
371
|
-
if not any(
|
|
372
|
-
issubclass(elem, t)
|
|
373
|
-
for t in (int, float, str, bool, list, NoneType, BaseModel, Enum)
|
|
374
|
-
for elem in pydantic_main_type_set
|
|
375
|
-
):
|
|
376
|
-
raise ForbiddenTypeHintsError(
|
|
377
|
-
message=(
|
|
378
|
-
"Pydantic main type must be one of the primitive, enum, list "
|
|
379
|
-
f"or BaseModel, got {pydantic_main_type_set}."
|
|
380
|
-
)
|
|
381
|
-
)
|
|
382
|
-
|
|
383
400
|
async def feed_chunks(self, chunks: str) -> None:
|
|
384
401
|
"""
|
|
385
402
|
Feeds a string of characters to the JMux parser.
|
|
@@ -421,7 +438,7 @@ class JMux(ABC):
|
|
|
421
438
|
case None:
|
|
422
439
|
match self._pda.state:
|
|
423
440
|
case S.START:
|
|
424
|
-
if
|
|
441
|
+
if ch in JSON_WHITESPACE:
|
|
425
442
|
pass
|
|
426
443
|
elif ch in OBJECT_OPEN:
|
|
427
444
|
self._pda.push(M.ROOT)
|
|
@@ -434,7 +451,7 @@ class JMux(ABC):
|
|
|
434
451
|
"JSON must start with '{' character.",
|
|
435
452
|
)
|
|
436
453
|
case S.END:
|
|
437
|
-
if
|
|
454
|
+
if ch in JSON_WHITESPACE:
|
|
438
455
|
pass
|
|
439
456
|
else:
|
|
440
457
|
raise ObjectAlreadyClosedError(
|
|
@@ -458,7 +475,7 @@ class JMux(ABC):
|
|
|
458
475
|
case M.ROOT:
|
|
459
476
|
match self._pda.state:
|
|
460
477
|
case S.EXPECT_KEY:
|
|
461
|
-
if
|
|
478
|
+
if ch in JSON_WHITESPACE:
|
|
462
479
|
pass
|
|
463
480
|
elif ch == '"':
|
|
464
481
|
self._pda.set_state(S.PARSING_KEY)
|
|
@@ -485,7 +502,7 @@ class JMux(ABC):
|
|
|
485
502
|
self._decoder.push(ch)
|
|
486
503
|
|
|
487
504
|
case S.EXPECT_COLON:
|
|
488
|
-
if
|
|
505
|
+
if ch in JSON_WHITESPACE:
|
|
489
506
|
pass
|
|
490
507
|
elif ch in COLON:
|
|
491
508
|
self._pda.set_state(S.EXPECT_VALUE)
|
|
@@ -498,7 +515,7 @@ class JMux(ABC):
|
|
|
498
515
|
)
|
|
499
516
|
|
|
500
517
|
case S.EXPECT_VALUE:
|
|
501
|
-
if
|
|
518
|
+
if ch in JSON_WHITESPACE:
|
|
502
519
|
pass
|
|
503
520
|
elif res := await self._handle_common__expect_value(ch):
|
|
504
521
|
if (
|
|
@@ -550,20 +567,23 @@ class JMux(ABC):
|
|
|
550
567
|
):
|
|
551
568
|
await self._sink.emit(maybe_char)
|
|
552
569
|
|
|
553
|
-
case _ if self._pda.state in
|
|
554
|
-
if ch
|
|
555
|
-
self._assert_primitive_character_allowed_in_state(ch)
|
|
556
|
-
self._decoder.push(ch)
|
|
557
|
-
else:
|
|
570
|
+
case _ if self._pda.state in PARSING_PRIMITIVE_STATES:
|
|
571
|
+
if ch in COMMA | OBJECT_CLOSE | JSON_WHITESPACE:
|
|
558
572
|
await self._parse_primitive()
|
|
559
573
|
await self._sink.close()
|
|
560
574
|
self._decoder.reset()
|
|
561
|
-
|
|
575
|
+
if ch in JSON_WHITESPACE:
|
|
576
|
+
self._pda.set_state(S.EXPECT_COMMA_OR_EOC)
|
|
577
|
+
else:
|
|
578
|
+
self._pda.set_state(S.EXPECT_KEY)
|
|
562
579
|
if ch in OBJECT_CLOSE:
|
|
563
580
|
await self._finalize()
|
|
581
|
+
else:
|
|
582
|
+
self._assert_primitive_character_allowed_in_state(ch)
|
|
583
|
+
self._decoder.push(ch)
|
|
564
584
|
|
|
565
585
|
case S.EXPECT_COMMA_OR_EOC:
|
|
566
|
-
if
|
|
586
|
+
if ch in JSON_WHITESPACE:
|
|
567
587
|
pass
|
|
568
588
|
elif ch in COMMA:
|
|
569
589
|
self._pda.set_state(S.EXPECT_KEY)
|
|
@@ -596,7 +616,7 @@ class JMux(ABC):
|
|
|
596
616
|
|
|
597
617
|
match self._pda.state:
|
|
598
618
|
case S.EXPECT_VALUE:
|
|
599
|
-
if
|
|
619
|
+
if ch in JSON_WHITESPACE:
|
|
600
620
|
pass
|
|
601
621
|
elif await self._handle_common__expect_value(ch):
|
|
602
622
|
pass
|
|
@@ -638,20 +658,20 @@ class JMux(ABC):
|
|
|
638
658
|
else:
|
|
639
659
|
self._decoder.push(ch)
|
|
640
660
|
|
|
641
|
-
case _ if self._pda.state in
|
|
642
|
-
if ch
|
|
643
|
-
self._assert_primitive_character_allowed_in_state(ch)
|
|
644
|
-
self._decoder.push(ch)
|
|
645
|
-
else:
|
|
661
|
+
case _ if self._pda.state in PARSING_PRIMITIVE_STATES:
|
|
662
|
+
if ch in COMMA | ARRAY_CLOSE | JSON_WHITESPACE:
|
|
646
663
|
await self._parse_primitive()
|
|
647
664
|
self._decoder.reset()
|
|
648
665
|
if ch in COMMA:
|
|
649
666
|
self._pda.set_state(S.EXPECT_VALUE)
|
|
650
667
|
elif ch in ARRAY_CLOSE:
|
|
651
668
|
await self._close_context(S.EXPECT_COMMA_OR_EOC)
|
|
669
|
+
else:
|
|
670
|
+
self._assert_primitive_character_allowed_in_state(ch)
|
|
671
|
+
self._decoder.push(ch)
|
|
652
672
|
|
|
653
673
|
case S.EXPECT_COMMA_OR_EOC:
|
|
654
|
-
if
|
|
674
|
+
if ch in JSON_WHITESPACE:
|
|
655
675
|
pass
|
|
656
676
|
elif ch in COMMA:
|
|
657
677
|
self._pda.set_state(S.EXPECT_VALUE)
|
|
@@ -681,8 +701,16 @@ class JMux(ABC):
|
|
|
681
701
|
self._pda.state,
|
|
682
702
|
"State in object context must be 'parsing_object'",
|
|
683
703
|
)
|
|
684
|
-
if ch in
|
|
704
|
+
if ch in OBJECT_OPEN:
|
|
705
|
+
if self._pda.top is M.OBJECT:
|
|
706
|
+
await self._sink.forward_char(ch)
|
|
707
|
+
self._pda.push(M.OBJECT)
|
|
708
|
+
elif ch in OBJECT_CLOSE:
|
|
685
709
|
self._pda.pop()
|
|
710
|
+
if self._pda.top is M.OBJECT:
|
|
711
|
+
await self._sink.forward_char(ch)
|
|
712
|
+
return
|
|
713
|
+
|
|
686
714
|
if self._pda.top is M.ROOT:
|
|
687
715
|
await self._sink.close()
|
|
688
716
|
self._pda.set_state(S.EXPECT_COMMA_OR_EOC)
|
|
@@ -699,7 +727,8 @@ class JMux(ABC):
|
|
|
699
727
|
)
|
|
700
728
|
await self._sink.emit(None)
|
|
701
729
|
elif self._pda.state is S.PARSING_BOOLEAN:
|
|
702
|
-
|
|
730
|
+
bool_value = str_to_bool(self._decoder.buffer)
|
|
731
|
+
await self._sink.emit(bool_value)
|
|
703
732
|
else:
|
|
704
733
|
try:
|
|
705
734
|
buffer = self._decoder.buffer
|
jmux/helpers.py
CHANGED
|
@@ -1,17 +1,37 @@
|
|
|
1
|
-
from types import NoneType
|
|
2
|
-
from typing import Set, Tuple, Type,
|
|
1
|
+
from types import NoneType
|
|
2
|
+
from typing import Set, Tuple, Type, get_args, get_origin
|
|
3
3
|
|
|
4
|
+
from jmux.error import ParsePrimitiveError
|
|
5
|
+
from jmux.types import TYPES_LIKE_NONE, TYPES_LIKE_UNION
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
|
|
8
|
+
def str_to_bool(s: str) -> bool:
|
|
9
|
+
if s == "true":
|
|
10
|
+
return True
|
|
11
|
+
elif s == "false":
|
|
12
|
+
return False
|
|
13
|
+
else:
|
|
14
|
+
raise ParsePrimitiveError(
|
|
15
|
+
f"Cannot convert string '{s}' to boolean. Expected 'true' or 'false', got"
|
|
16
|
+
f" '{s}'."
|
|
17
|
+
)
|
|
7
18
|
|
|
8
19
|
|
|
9
20
|
def extract_types_from_generic_alias(UnknownType: Type) -> Tuple[Set[Type], Set[Type]]:
|
|
10
21
|
Origin: Type | None = get_origin(UnknownType)
|
|
11
22
|
if Origin is None:
|
|
12
23
|
return {UnknownType}, set()
|
|
13
|
-
if Origin
|
|
14
|
-
|
|
24
|
+
if Origin in TYPES_LIKE_UNION:
|
|
25
|
+
deconstructed = deconstruct_flat_type(UnknownType)
|
|
26
|
+
maybe_list_types = [
|
|
27
|
+
subtypes for subtypes in deconstructed if get_origin(subtypes) is list
|
|
28
|
+
]
|
|
29
|
+
if len(maybe_list_types) == 1:
|
|
30
|
+
list_based_type = maybe_list_types[0]
|
|
31
|
+
non_list_types = deconstructed - {list_based_type}
|
|
32
|
+
main_type, subtype = extract_types_from_generic_alias(list_based_type)
|
|
33
|
+
return non_list_types | main_type, subtype
|
|
34
|
+
return deconstructed, set()
|
|
15
35
|
|
|
16
36
|
type_args = get_args(UnknownType)
|
|
17
37
|
if len(type_args) != 1:
|
|
@@ -21,7 +41,7 @@ def extract_types_from_generic_alias(UnknownType: Type) -> Tuple[Set[Type], Set[
|
|
|
21
41
|
)
|
|
22
42
|
|
|
23
43
|
Generic: Type = type_args[0]
|
|
24
|
-
type_set =
|
|
44
|
+
type_set = deconstruct_flat_type(Generic)
|
|
25
45
|
if len(type_set) == 1:
|
|
26
46
|
return {Origin}, type_set
|
|
27
47
|
if len(type_set) != 2:
|
|
@@ -36,16 +56,20 @@ def extract_types_from_generic_alias(UnknownType: Type) -> Tuple[Set[Type], Set[
|
|
|
36
56
|
return {Origin}, type_set
|
|
37
57
|
|
|
38
58
|
|
|
39
|
-
def
|
|
59
|
+
def deconstruct_flat_type(UnknownType: Type) -> Set[Type]:
|
|
40
60
|
Origin: Type | None = get_origin(UnknownType)
|
|
41
|
-
if UnknownType
|
|
61
|
+
if UnknownType in TYPES_LIKE_NONE:
|
|
42
62
|
return {NoneType}
|
|
43
63
|
if Origin is None:
|
|
44
64
|
return {UnknownType}
|
|
45
|
-
if
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
65
|
+
if Origin in TYPES_LIKE_UNION:
|
|
66
|
+
type_args = get_args(UnknownType)
|
|
67
|
+
return set(type_args)
|
|
68
|
+
raise TypeError(
|
|
69
|
+
f"Unknown type {UnknownType} is not a Union or optional type, "
|
|
70
|
+
"only only those types and their syntactic sugar are supported "
|
|
71
|
+
"for flat deconstruction."
|
|
72
|
+
)
|
|
49
73
|
|
|
50
74
|
|
|
51
75
|
def get_main_type(type_set: Set[Type]) -> Type:
|
jmux/types.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from enum import Enum
|
|
2
|
-
from
|
|
2
|
+
from types import NoneType, UnionType
|
|
3
|
+
from typing import List, Set, Union
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
class State(Enum):
|
|
@@ -21,7 +22,7 @@ class State(Enum):
|
|
|
21
22
|
PARSING_OBJECT = "parsing_object"
|
|
22
23
|
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
PARSING_PRIMITIVE_STATES: Set[State] = {
|
|
25
26
|
State.PARSING_INTEGER,
|
|
26
27
|
State.PARSING_FLOAT,
|
|
27
28
|
State.PARSING_BOOLEAN,
|
|
@@ -55,3 +56,8 @@ NULL_ALLOWED = set("nul")
|
|
|
55
56
|
JSON_FALSE = "false"
|
|
56
57
|
JSON_TRUE = "true"
|
|
57
58
|
JSON_NULL = "null"
|
|
59
|
+
JSON_WHITESPACE = set(" \t\n\r")
|
|
60
|
+
|
|
61
|
+
TYPES_LIKE_UNION = {UnionType, Union}
|
|
62
|
+
TYPES_LIKE_NONE = {NoneType, None}
|
|
63
|
+
TYPES_LIKE_LIST = {List, list}
|
|
@@ -0,0 +1,13 @@
|
|
|
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,,
|
jmux-0.0.2.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=7YJBD_EGUyxjiwjVnKCZOA-NrpXWrTe_y2Eitl4EU3E,35089
|
|
5
|
-
jmux/error.py,sha256=VZJYivt8RPfjcF2bs-T7_UkH3dVA3xH-xGbZggQV14k,4665
|
|
6
|
-
jmux/helpers.py,sha256=6y33RohUGVvGGaAREyRQTmEWfgV4w295SyqDwIMnUNs,1982
|
|
7
|
-
jmux/pda.py,sha256=81gnh0eWGsgd_SrHkqjRQy_KkOSlBf5nor7pqKGgYjw,791
|
|
8
|
-
jmux/types.py,sha256=V63wMx1I7l_P83JAqzOQ7H7B-xKrNUuGshJ3NjKsdeQ,1192
|
|
9
|
-
jmux-0.0.2.dist-info/licenses/LICENSE,sha256=y0qnwaAe4bEqzNPyq4M_VZA2I2mQly8MawajyZhqw0k,1169
|
|
10
|
-
jmux-0.0.2.dist-info/METADATA,sha256=G3PPpw0VhSYx9YyeVUT9T12YCGxORI7HVFAQYTB4Od4,13330
|
|
11
|
-
jmux-0.0.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
12
|
-
jmux-0.0.2.dist-info/top_level.txt,sha256=TF2N6kHqLghfOkCiNlCueMDX4l5rPn_5MSPNtYrS1-o,5
|
|
13
|
-
jmux-0.0.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|