4
4
5
5
Provides versioning support for Counter classes and codes
6
6
"""
7
+ import copy
7
8
8
9
from dataclasses import dataclass , astuple , asdict
9
10
from collections import namedtuple
@@ -147,18 +148,15 @@ def __iter__(self):
147
148
148
149
CtrDex_2_0 = CounterCodex_2_0 ()
149
150
150
- # keys and values as strings of keys
151
- Codict1 = asdict (CtrDex_1_0 )
152
- Tagage_1_0 = namedtuple ("Tagage_1_0" , list (Codict1 ), defaults = list (Codict1 ))
153
- Tags_1_0 = Tagage_1_0 () # uses defaults
154
-
155
- Codict2 = asdict (CtrDex_2_0 )
156
- Tagage_2_0 = namedtuple ("Tagage_2_0" , list (Codict2 ), defaults = list (Codict2 ))
157
- Tags_2_0 = Tagage_2_0 () # uses defaults
158
-
159
- CodictAll = Codict2 | Codict1
160
- AllTagage = namedtuple ("AllTagage" , list (CodictAll ), defaults = list (CodictAll ))
161
- AllTags = AllTagage () # uses defaults
151
+ # CodeNames is tuple of codes names given by attributes of union of codices
152
+ CodeNames = tuple (asdict (CtrDex_2_0 ) | asdict (CtrDex_1_0 ))
153
+ # Codens is namedtuple of CodeNames where its names are the code names
154
+ # Codens enables using the attributes of the named tuple to specify a code by
155
+ # name (indirection) so that changes in the code itself do not break the
156
+ # creation of a counter. Enables specifying a counter by the code name not the
157
+ # code itself. The code may change between versions but the code name does not.
158
+ Codenage = namedtuple ("Codenage" , CodeNames , defaults = CodeNames )
159
+ Codens = Codenage ()
162
160
163
161
164
162
@dataclass (frozen = True )
@@ -200,8 +198,9 @@ class Counter:
200
198
Includes the following attributes and properties:
201
199
202
200
Class Attributes:
203
- Codes (dict): of codexes keyed by version
204
- Tags (dict): of tagages keyed by version
201
+ Codes (dict): nested of codexes keyed by major and minor version
202
+ Names (dict): nested of map of code names to codes keyed by
203
+ major and minor version
205
204
Hards (dict): of hard code sizes keyed by text domain selector
206
205
Bards (dict): of hard code sizes keyed by binary domain selector
207
206
Sizes (dict): of size tables keyed by version. Size table is dict
@@ -310,7 +309,15 @@ class Counter:
310
309
},
311
310
}
312
311
313
- Tags = {Vrsn_1_0 : Tags_1_0 , Vrsn_2_0 : Tags_2_0 }
312
+
313
+ # invert dataclass codenames: codes to dict codes: codenames
314
+ Names = copy .deepcopy (Codes ) # make deep nested copy so can invert nested values
315
+ for minor in Names .values ():
316
+ for key in minor :
317
+ minor [key ] = {val : key for key , val in asdict (minor [key ]).items ()}
318
+
319
+
320
+
314
321
315
322
# Hards table maps from bytes Base64 first two code chars to int of
316
323
# hard size, hs,(stable) of code. The soft size, ss, (unstable) for Counter
@@ -415,17 +422,16 @@ class Counter:
415
422
}
416
423
417
424
418
- def __init__ (self , tag = None , * , code = None , count = None , countB64 = None ,
425
+ def __init__ (self , code = None , * , count = None , countB64 = None ,
419
426
qb64b = None , qb64 = None , qb2 = None , strip = False , gvrsn = Vrsn_2_0 ):
420
427
"""
421
428
Validate as fully qualified
422
429
Parameters:
423
- tag (str | None): label of stable (hard) part of derivation code
424
- to lookup in codex so it can depend on version.
425
- takes precedence over code.
426
- code (str | None): stable (hard) part of derivation code
427
- if tag provided lookup code from tag
428
- else if tag is None and code provided use code.
430
+ code (str | None): either stable (hard) part of derivation code or
431
+ code name. When code name then look up code from
432
+ ._codes. This allows versioning to change code
433
+ but keep stable code name.
434
+
429
435
count (int | None): count of framed material in quadlets/triplets
430
436
for composition. Count does not include code.
431
437
When both count and countB64 are None then count
@@ -466,14 +472,15 @@ def __init__(self, tag=None, *, code = None, count=None, countB64=None,
466
472
self ._version = gvrsn # provided version may be earlier than supported version
467
473
468
474
469
- if tag :
470
- if not hasattr (self ._codes , tag ):
471
- raise kering .InvalidCodeError (f"Unsupported { tag = } ." )
472
- code = self ._codes [tag ]
473
-
474
- if code is not None : # code (hard) provided
475
+ if code : # code (hard) provided
476
+ # assumes ._sizes ._codes coherent
475
477
if code not in self ._sizes or len (code ) < 2 :
476
- raise kering .InvalidCodeError (f"Unsupported { code = } ." )
478
+ try :
479
+ code = self ._codes [code ] # code is code name so look up code
480
+ if code not in self ._sizes or len (code ) < 2 :
481
+ raise kering .InvalidCodeError (f"Unsupported { code = } ." )
482
+ except Exception as ex :
483
+ raise kering .InvalidCodeError (f"Unsupported { code = } ." ) from ex
477
484
478
485
hs , ss , fs , ls = self ._sizes [code ] # get sizes for code
479
486
cs = hs + ss # both hard + soft code size
@@ -520,8 +527,7 @@ def __init__(self, tag=None, *, code = None, count=None, countB64=None,
520
527
"(code and count) or qb64b or "
521
528
"qb64 or qb2." )
522
529
523
- codenames = { val : key for key , val in asdict (self .codes ).items ()} # map codes to code names
524
- self ._tag = codenames [self .code ]
530
+ self ._name = self .Names [gvrsn .major ][latest ][self .code ]
525
531
526
532
@property
527
533
def version (self ):
@@ -547,13 +553,13 @@ def codes(self):
547
553
"""
548
554
return self ._codes
549
555
550
- @property
551
- def tags (self ):
552
- """
553
- Returns tags for current .version
554
- Makes .tags read only
555
- """
556
- return self .Tags [self .version ] # use own version
556
+ # @property
557
+ # def tags(self):
558
+ # """
559
+ # Returns tags for current .version
560
+ # Makes .tags read only
561
+ # """
562
+ # return self.Tags[self.version] # use own version
557
563
558
564
@property
559
565
def sizes (self ):
@@ -574,25 +580,17 @@ def code(self):
574
580
"""
575
581
return self ._code
576
582
577
- @property
578
- def tag (self ):
579
- """
580
- Returns:
581
- tag (str): code name for self.code
582
-
583
- Getter for ._tag. Makes .tag read only
584
- """
585
- return self ._tag
586
-
587
583
@property
588
584
def name (self ):
589
585
"""
590
586
Returns:
591
- name (str): code name for self.code alias of .tag . Match interface
587
+ name (str): code name for self.code. Match interface
592
588
for annotation for primitives like Matter
593
589
590
+ Getter for ._name. Makes .name read only
591
+
594
592
"""
595
- return self .tag
593
+ return self ._name
596
594
597
595
598
596
@property
0 commit comments