libasterix 0.36.2__tar.gz → 0.37.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: libasterix
3
- Version: 0.36.2
3
+ Version: 0.37.0
4
4
  Summary: Asterix data processing library
5
5
  Author-email: Zoran Bošnjak <zoran.bosnjak@via.si>
6
6
  License-Expression: MIT
@@ -41,7 +41,7 @@ type checking with `mypy`. In a simple untyped environment,
41
41
  the type annotations and assertions could be skipped.
42
42
 
43
43
  ```python
44
- #| file: example0.py
44
+ #| file: readme-samples/example0.py
45
45
  from typing import *
46
46
  from binascii import hexlify, unhexlify
47
47
  from dataclasses import dataclass
@@ -298,7 +298,7 @@ and if a subitem is present, it applies a modifier function `f` to the subitem.
298
298
  Otherwises, if the subitem is not present, the method returns `self` unchanged.
299
299
 
300
300
  ```python
301
- #| file: example-modify-subitems.py
301
+ #| file: readme-samples/example-modify-subitems.py
302
302
  from asterix.base import *
303
303
  import asterix.generated as gen
304
304
 
@@ -330,7 +330,7 @@ assert v020.unparse() == result2.unparse()
330
330
  **Example**: Category filter, drop datablocks if category == 1
331
331
 
332
332
  ```python
333
- #| file: example1.py
333
+ #| file: readme-samples/example1.py
334
334
  from binascii import hexlify, unhexlify
335
335
  from asterix.base import *
336
336
 
@@ -357,7 +357,7 @@ send_to_udp(output_data)
357
357
  **Example**: Asterix filter, rewrite SAC/SIC code.
358
358
 
359
359
  ```python
360
- #| file: example4.py
360
+ #| file: readme-samples/example4.py
361
361
  from asterix.base import *
362
362
  from asterix.generated import *
363
363
 
@@ -430,7 +430,7 @@ Multiple spare bit groups can be defined on a single item.
430
430
  **Example**
431
431
 
432
432
  ```python
433
- #| file: example-spare.py
433
+ #| file: readme-samples/example-spare.py
434
434
  from asterix.generated import *
435
435
 
436
436
  # I062/120 contain single group of spare bits
@@ -476,7 +476,7 @@ a possiblity to explicitly select both editions individually.
476
476
  This example demonstrates required steps for constructing and parsing:
477
477
 
478
478
  ```python
479
- #| file: example5.py
479
+ #| file: readme-samples/example5.py
480
480
  from asterix.generated import *
481
481
 
482
482
  Spec = Cat_062_1_20
@@ -543,7 +543,7 @@ explicit about subitems, for example `["010", "SAC"]`.
543
543
  **Example**: Show raw content of all toplevel items of each record
544
544
 
545
545
  ```python
546
- #| file: example9.py
546
+ #| file: readme-samples/example9.py
547
547
  from binascii import unhexlify
548
548
  from asterix.generated import *
549
549
 
@@ -581,7 +581,7 @@ for db in RawDatablock.parse(Bits.from_bytes(s)):
581
581
  **Example**: Generate dummy single record datablock with all fixed items set to zero
582
582
 
583
583
  ```python
584
- #| file: example10.py
584
+ #| file: readme-samples/example10.py
585
585
  from binascii import hexlify
586
586
  from asterix.generated import *
587
587
 
@@ -640,7 +640,7 @@ This structure can be used to extract *latest* editions for each defined
640
640
  category, for example:
641
641
 
642
642
  ```python
643
- #| file: example7.py
643
+ #| file: readme-samples/example7.py
644
644
  from asterix.generated import *
645
645
 
646
646
  Specs = {cat: manifest['CATS'][cat][-1] for cat in manifest['CATS']}
@@ -653,7 +653,7 @@ Alternatively, a prefered way is to be explicit about each edition,
653
653
  for example:
654
654
 
655
655
  ```python
656
- #| file: example8.py
656
+ #| file: readme-samples/example8.py
657
657
  from asterix.generated import *
658
658
 
659
659
  Specs = {
@@ -701,7 +701,7 @@ All operation on asterix objects are *immutable*.
701
701
  For example:
702
702
 
703
703
  ```python
704
- #| file: example-immutable.py
704
+ #| file: readme-samples/example-immutable.py
705
705
  from asterix.generated import *
706
706
 
707
707
  Spec = Cat_002_1_1
@@ -743,7 +743,7 @@ There is a `spec` class method which follows this structure deeper to the
743
743
  hierarchy. For example:
744
744
 
745
745
  ```python
746
- #| file: example-spec.py
746
+ #| file: readme-samples/example-spec.py
747
747
  from binascii import unhexlify
748
748
  from asterix.generated import *
749
749
 
@@ -828,7 +828,7 @@ Found 3 errors in 1 file (checked 1 source file)
828
828
  Correct version of this program is:
829
829
 
830
830
  ```python
831
- #| file: example11.py
831
+ #| file: readme-samples/example11.py
832
832
  from asterix.generated import *
833
833
 
834
834
  Spec = Cat_008_1_3
@@ -877,7 +877,7 @@ This example demonstrates how to work with **content dependency**,
877
877
  such as `I062/380/IAS`.
878
878
 
879
879
  ```python
880
- #| file: example-dep-content.py
880
+ #| file: readme-samples/example-dep-content.py
881
881
  from asterix.base import *
882
882
  from asterix.generated import *
883
883
 
@@ -967,7 +967,7 @@ This example demonstrates how to work with **variation dependency**,
967
967
  such as `I004/120/CC/CPC`.
968
968
 
969
969
  ```python
970
- #| file: example-dep-variation.py
970
+ #| file: readme-samples/example-dep-variation.py
971
971
  from asterix.base import *
972
972
  from asterix.generated import *
973
973
 
@@ -1075,7 +1075,7 @@ value, for example for CAT001:
1075
1075
  - `['020', 'TYP'] = 1` for `track`
1076
1076
 
1077
1077
  ```python
1078
- #| file: example6.py
1078
+ #| file: readme-samples/example6.py
1079
1079
  from asterix.base import *
1080
1080
  from asterix.generated import *
1081
1081
 
@@ -1116,7 +1116,7 @@ An empty list indicates that no such item is present in the RFS.
1116
1116
  **Example**
1117
1117
 
1118
1118
  ```python
1119
- #| file: example-rfs.py
1119
+ #| file: readme-samples/example-rfs.py
1120
1120
  from binascii import hexlify
1121
1121
  from asterix.generated import *
1122
1122
 
@@ -1197,7 +1197,7 @@ Both methods can fail on invalid input data (return `ValueError`).
1197
1197
  This example demonstrates both parsing modes:
1198
1198
 
1199
1199
  ```python
1200
- #| file: example-partial-parsing.py
1200
+ #| file: readme-samples/example-partial-parsing.py
1201
1201
  from asterix.base import *
1202
1202
  from asterix.generated import *
1203
1203
 
@@ -24,7 +24,7 @@ type checking with `mypy`. In a simple untyped environment,
24
24
  the type annotations and assertions could be skipped.
25
25
 
26
26
  ```python
27
- #| file: example0.py
27
+ #| file: readme-samples/example0.py
28
28
  from typing import *
29
29
  from binascii import hexlify, unhexlify
30
30
  from dataclasses import dataclass
@@ -281,7 +281,7 @@ and if a subitem is present, it applies a modifier function `f` to the subitem.
281
281
  Otherwises, if the subitem is not present, the method returns `self` unchanged.
282
282
 
283
283
  ```python
284
- #| file: example-modify-subitems.py
284
+ #| file: readme-samples/example-modify-subitems.py
285
285
  from asterix.base import *
286
286
  import asterix.generated as gen
287
287
 
@@ -313,7 +313,7 @@ assert v020.unparse() == result2.unparse()
313
313
  **Example**: Category filter, drop datablocks if category == 1
314
314
 
315
315
  ```python
316
- #| file: example1.py
316
+ #| file: readme-samples/example1.py
317
317
  from binascii import hexlify, unhexlify
318
318
  from asterix.base import *
319
319
 
@@ -340,7 +340,7 @@ send_to_udp(output_data)
340
340
  **Example**: Asterix filter, rewrite SAC/SIC code.
341
341
 
342
342
  ```python
343
- #| file: example4.py
343
+ #| file: readme-samples/example4.py
344
344
  from asterix.base import *
345
345
  from asterix.generated import *
346
346
 
@@ -413,7 +413,7 @@ Multiple spare bit groups can be defined on a single item.
413
413
  **Example**
414
414
 
415
415
  ```python
416
- #| file: example-spare.py
416
+ #| file: readme-samples/example-spare.py
417
417
  from asterix.generated import *
418
418
 
419
419
  # I062/120 contain single group of spare bits
@@ -459,7 +459,7 @@ a possiblity to explicitly select both editions individually.
459
459
  This example demonstrates required steps for constructing and parsing:
460
460
 
461
461
  ```python
462
- #| file: example5.py
462
+ #| file: readme-samples/example5.py
463
463
  from asterix.generated import *
464
464
 
465
465
  Spec = Cat_062_1_20
@@ -526,7 +526,7 @@ explicit about subitems, for example `["010", "SAC"]`.
526
526
  **Example**: Show raw content of all toplevel items of each record
527
527
 
528
528
  ```python
529
- #| file: example9.py
529
+ #| file: readme-samples/example9.py
530
530
  from binascii import unhexlify
531
531
  from asterix.generated import *
532
532
 
@@ -564,7 +564,7 @@ for db in RawDatablock.parse(Bits.from_bytes(s)):
564
564
  **Example**: Generate dummy single record datablock with all fixed items set to zero
565
565
 
566
566
  ```python
567
- #| file: example10.py
567
+ #| file: readme-samples/example10.py
568
568
  from binascii import hexlify
569
569
  from asterix.generated import *
570
570
 
@@ -623,7 +623,7 @@ This structure can be used to extract *latest* editions for each defined
623
623
  category, for example:
624
624
 
625
625
  ```python
626
- #| file: example7.py
626
+ #| file: readme-samples/example7.py
627
627
  from asterix.generated import *
628
628
 
629
629
  Specs = {cat: manifest['CATS'][cat][-1] for cat in manifest['CATS']}
@@ -636,7 +636,7 @@ Alternatively, a prefered way is to be explicit about each edition,
636
636
  for example:
637
637
 
638
638
  ```python
639
- #| file: example8.py
639
+ #| file: readme-samples/example8.py
640
640
  from asterix.generated import *
641
641
 
642
642
  Specs = {
@@ -684,7 +684,7 @@ All operation on asterix objects are *immutable*.
684
684
  For example:
685
685
 
686
686
  ```python
687
- #| file: example-immutable.py
687
+ #| file: readme-samples/example-immutable.py
688
688
  from asterix.generated import *
689
689
 
690
690
  Spec = Cat_002_1_1
@@ -726,7 +726,7 @@ There is a `spec` class method which follows this structure deeper to the
726
726
  hierarchy. For example:
727
727
 
728
728
  ```python
729
- #| file: example-spec.py
729
+ #| file: readme-samples/example-spec.py
730
730
  from binascii import unhexlify
731
731
  from asterix.generated import *
732
732
 
@@ -811,7 +811,7 @@ Found 3 errors in 1 file (checked 1 source file)
811
811
  Correct version of this program is:
812
812
 
813
813
  ```python
814
- #| file: example11.py
814
+ #| file: readme-samples/example11.py
815
815
  from asterix.generated import *
816
816
 
817
817
  Spec = Cat_008_1_3
@@ -860,7 +860,7 @@ This example demonstrates how to work with **content dependency**,
860
860
  such as `I062/380/IAS`.
861
861
 
862
862
  ```python
863
- #| file: example-dep-content.py
863
+ #| file: readme-samples/example-dep-content.py
864
864
  from asterix.base import *
865
865
  from asterix.generated import *
866
866
 
@@ -950,7 +950,7 @@ This example demonstrates how to work with **variation dependency**,
950
950
  such as `I004/120/CC/CPC`.
951
951
 
952
952
  ```python
953
- #| file: example-dep-variation.py
953
+ #| file: readme-samples/example-dep-variation.py
954
954
  from asterix.base import *
955
955
  from asterix.generated import *
956
956
 
@@ -1058,7 +1058,7 @@ value, for example for CAT001:
1058
1058
  - `['020', 'TYP'] = 1` for `track`
1059
1059
 
1060
1060
  ```python
1061
- #| file: example6.py
1061
+ #| file: readme-samples/example6.py
1062
1062
  from asterix.base import *
1063
1063
  from asterix.generated import *
1064
1064
 
@@ -1099,7 +1099,7 @@ An empty list indicates that no such item is present in the RFS.
1099
1099
  **Example**
1100
1100
 
1101
1101
  ```python
1102
- #| file: example-rfs.py
1102
+ #| file: readme-samples/example-rfs.py
1103
1103
  from binascii import hexlify
1104
1104
  from asterix.generated import *
1105
1105
 
@@ -1180,7 +1180,7 @@ Both methods can fail on invalid input data (return `ValueError`).
1180
1180
  This example demonstrates both parsing modes:
1181
1181
 
1182
1182
  ```python
1183
- #| file: example-partial-parsing.py
1183
+ #| file: readme-samples/example-partial-parsing.py
1184
1184
  from asterix.base import *
1185
1185
  from asterix.generated import *
1186
1186
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "libasterix"
3
- version = "0.36.2"
3
+ version = "0.37.0"
4
4
  authors = [
5
5
  { name="Zoran Bošnjak", email="zoran.bosnjak@via.si" },
6
6
  ]
@@ -2,7 +2,7 @@
2
2
  """
3
3
 
4
4
  import copy
5
- from itertools import chain, dropwhile
5
+ from itertools import chain, dropwhile, repeat
6
6
  from dataclasses import dataclass
7
7
  from binascii import hexlify, unhexlify
8
8
  from typing import *
@@ -1021,6 +1021,15 @@ class Fspec:
1021
1021
  (a, b) = s.split_at(n * 8)
1022
1022
  return (cls(a), b)
1023
1023
 
1024
+ @classmethod
1025
+ def iter_complete(cls, flags: Any, items: List[Any]) \
1026
+ -> Iterator[Tuple[bool, Any]]:
1027
+ """Make sure to visit all FSPEC bits, even after the last defined
1028
+ item. This is important, to let the caller check all FSPEC bits."""
1029
+
1030
+ for (a, b) in zip(flags, chain(items, repeat(None))):
1031
+ yield (a, b)
1032
+
1024
1033
  def __iter__(self) -> Iterator[bool]:
1025
1034
  n = 0
1026
1035
  for flag in self.bs:
@@ -1089,7 +1098,7 @@ class Compound(Variation):
1089
1098
  return result
1090
1099
  fspec, remaining = result
1091
1100
  items = {}
1092
- for (flag, nsp) in zip(fspec, cls.cv_items_list):
1101
+ for (flag, nsp) in Fspec.iter_complete(fspec, cls.cv_items_list):
1093
1102
  if not flag:
1094
1103
  continue
1095
1104
  if nsp is None:
@@ -1289,7 +1298,7 @@ class Record:
1289
1298
  fspec, remaining = result
1290
1299
  items1: Dict[str, NonSpare] = {}
1291
1300
  items2: List[Optional[List[Tuple[str, NonSpare]]]] = []
1292
- for (flag, i) in zip(fspec, cls.cv_items_list):
1301
+ for (flag, i) in Fspec.iter_complete(fspec, cls.cv_items_list):
1293
1302
  if not flag:
1294
1303
  continue
1295
1304
  if issubclass(i, UapItemSpare):
@@ -1338,7 +1347,7 @@ class Record:
1338
1347
  break
1339
1348
  elif issubclass(i, UapItem):
1340
1349
  nsp = i.cv_non_spare
1341
- result2 = nsp.parse(remaining) # type: ignore
1350
+ result2 = nsp.parse(remaining)
1342
1351
  if isinstance(result2, ValueError):
1343
1352
  if pm == ParsingMode.StrictParsing:
1344
1353
  return result2
@@ -1589,7 +1598,7 @@ class Expansion:
1589
1598
  else:
1590
1599
  raise Exception('Unexpected cv_type', a)
1591
1600
  items = {}
1592
- for (flag, nsp) in zip(flags, cls.cv_items_list):
1601
+ for (flag, nsp) in Fspec.iter_complete(flags, cls.cv_items_list):
1593
1602
  if not flag:
1594
1603
  continue
1595
1604
  if nsp is None: