@@ -343,7 +343,9 @@ class ParamsType(CType):
343
343
344
344
"""
345
345
346
- def __init__ (self , ** kwargs ):
346
+ @classmethod
347
+ def type_parameters (cls , ** kwargs ):
348
+ params = dict ()
347
349
if len (kwargs ) == 0 :
348
350
raise ValueError ("Cannot create ParamsType from empty data." )
349
351
@@ -366,14 +368,14 @@ def __init__(self, **kwargs):
366
368
% (attribute_name , type_name )
367
369
)
368
370
369
- self . length = len (kwargs )
370
- self . fields = tuple (sorted (kwargs .keys ()))
371
- self . types = tuple (kwargs [field ] for field in self . fields )
372
- self . name = self .generate_struct_name ()
371
+ params [ " length" ] = len (kwargs )
372
+ params [ " fields" ] = tuple (sorted (kwargs .keys ()))
373
+ params [ " types" ] = tuple (kwargs [field ] for field in params [ " fields" ] )
374
+ params [ " name" ] = cls .generate_struct_name (params )
373
375
374
- self . __const_to_enum = {}
375
- self . __alias_to_enum = {}
376
- enum_types = [t for t in self . types if isinstance (t , EnumType )]
376
+ params [ "_const_to_enum" ] = {}
377
+ params [ "_alias_to_enum" ] = {}
378
+ enum_types = [t for t in params [ " types" ] if isinstance (t , EnumType )]
377
379
if enum_types :
378
380
# We don't want same enum names in different enum types.
379
381
if sum (len (t ) for t in enum_types ) != len (
@@ -398,35 +400,40 @@ def __init__(self, **kwargs):
398
400
)
399
401
# We map each enum name to the enum type in which it is defined.
400
402
# We will then use this dict to find enum value when looking for enum name in ParamsType object directly.
401
- self . __const_to_enum = {
403
+ params [ "_const_to_enum" ] = {
402
404
enum_name : enum_type
403
405
for enum_type in enum_types
404
406
for enum_name in enum_type
405
407
}
406
- self . __alias_to_enum = {
408
+ params [ "_alias_to_enum" ] = {
407
409
alias : enum_type
408
410
for enum_type in enum_types
409
411
for alias in enum_type .aliases
410
412
}
411
413
414
+ return params
415
+
412
416
def __setstate__ (self , state ):
413
417
# NB:
414
418
# I have overridden __getattr__ to make enum constants available through
415
419
# the ParamsType when it contains enum types. To do that, I use some internal
416
- # attributes: self.__const_to_enum and self.__alias_to_enum . These attributes
420
+ # attributes: self._const_to_enum and self._alias_to_enum . These attributes
417
421
# are normally found by Python without need to call getattr(), but when the
418
422
# ParamsType is unpickled, it seems gettatr() may be called at a point before
419
- # __const_to_enum or __alias_to_enum are unpickled, so that gettatr() can't find
423
+ # _const_to_enum or _alias_to_enum are unpickled, so that gettatr() can't find
420
424
# those attributes, and then loop infinitely.
421
425
# For this reason, I must add this trivial implementation of __setstate__()
422
426
# to avoid errors when unpickling.
423
427
self .__dict__ .update (state )
424
428
425
429
def __getattr__ (self , key ):
426
430
# Now we can access value of each enum defined inside enum types wrapped into the current ParamsType.
427
- if key in self .__const_to_enum :
428
- return self .__const_to_enum [key ][key ]
429
- return super ().__getattr__ (self , key )
431
+ # const_to_enum = super().__getattribute__("_const_to_enum")
432
+ if not key .startswith ("__" ):
433
+ const_to_enum = self ._const_to_enum
434
+ if key in const_to_enum :
435
+ return const_to_enum [key ][key ]
436
+ raise AttributeError (f"'{ self } ' object has no attribute '{ key } '" )
430
437
431
438
def __repr__ (self ):
432
439
return "ParamsType<%s>" % ", " .join (
@@ -446,13 +453,14 @@ def __eq__(self, other):
446
453
def __hash__ (self ):
447
454
return hash ((type (self ),) + self .fields + self .types )
448
455
449
- def generate_struct_name (self ):
450
- # This method tries to generate an unique name for the current instance.
456
+ @staticmethod
457
+ def generate_struct_name (params ):
458
+ # This method tries to generate a unique name for the current instance.
451
459
# This name is intended to be used as struct name in C code and as constant
452
460
# definition to check if a similar ParamsType has already been created
453
461
# (see c_support_code() below).
454
- fields_string = "," .join (self . fields ).encode ("utf-8" )
455
- types_string = "," .join (str (t ) for t in self . types ).encode ("utf-8" )
462
+ fields_string = "," .join (params [ " fields" ] ).encode ("utf-8" )
463
+ types_string = "," .join (str (t ) for t in params [ " types" ] ).encode ("utf-8" )
456
464
fields_hex = hashlib .sha256 (fields_string ).hexdigest ()
457
465
types_hex = hashlib .sha256 (types_string ).hexdigest ()
458
466
return f"_Params_{ fields_hex } _{ types_hex } "
@@ -510,7 +518,7 @@ def get_enum(self, key):
510
518
print(wrapper.TWO)
511
519
512
520
"""
513
- return self .__const_to_enum [key ][key ]
521
+ return self ._const_to_enum [key ][key ]
514
522
515
523
def enum_from_alias (self , alias ):
516
524
"""
@@ -547,10 +555,11 @@ def enum_from_alias(self, alias):
547
555
method to do that.
548
556
549
557
"""
558
+ alias_to_enum = self ._alias_to_enum
550
559
return (
551
- self . __alias_to_enum [alias ].fromalias (alias )
552
- if alias in self . __alias_to_enum
553
- else self .__const_to_enum [alias ][alias ]
560
+ alias_to_enum [alias ].fromalias (alias )
561
+ if alias in alias_to_enum
562
+ else self ._const_to_enum [alias ][alias ]
554
563
)
555
564
556
565
def get_params (self , * objects , ** kwargs ) -> Params :
0 commit comments