@@ -196,7 +196,9 @@ def setter(self, value):
196196 return property (getter , setter )
197197
198198
199- def make_structure (data_type : ua .NodeId , struct_name : str , sdef : ua .StructureDefinition , log_error : bool = True ) -> dict [str , type ]:
199+ def make_structure (
200+ data_type : ua .NodeId , struct_name : str , sdef : ua .StructureDefinition , log_error : bool = True
201+ ) -> dict [str , type ]:
200202 """
201203 given a StructureDefinition object, generate Python class
202204 """
@@ -235,9 +237,6 @@ def make_structure(data_type: ua.NodeId, struct_name: str, sdef: ua.StructureDef
235237
236238 for idx , sfield in enumerate (sdef .Fields , start = 1 ):
237239 fname = clean_name (sfield .Name )
238- if fname in seen_names :
239- _logger .warning ("Field name %s is duplicated in structure %s, renaming to %s_%s" , fname , struct_name , fname , idx )
240- fname = f"{ fname } _{ idx } "
241240 seen_names .add (fname )
242241 if sfield .DataType .NamespaceIndex == 0 and sfield .DataType .Identifier in ua .ObjectIdNames :
243242 if sfield .DataType .Identifier == 24 :
@@ -409,18 +408,20 @@ def __str__(self):
409408 return f"<{ self .__class__ .__name__ } : { self .name !r} >"
410409
411410
412- async def _recursive_parse (server , base_node , dtypes , parent_sdef = None , add_existing = False ):
411+ async def _recursive_parse (server , base_node , dtypes , parent_sdef = None , add_existing = False ) -> None :
413412 ch = await base_node .get_children_descriptions (refs = ua .ObjectIds .HasSubtype )
414413
415414 requests = [_read_data_type_definition (server , desc , read_existing = add_existing ) for desc in ch ]
416415 results = await asyncio .gather (* requests )
417416
418- def __add_recursion (sdef , desc ):
417+ def __add_recursion (sdef , desc ) -> Any :
419418 name = clean_name (desc .BrowseName .Name )
420419 if sdef :
421420 if parent_sdef :
421+ names = [f .Name for f in sdef .Fields ]
422422 for sfield in reversed (parent_sdef .Fields ):
423- sdef .Fields .insert (0 , sfield )
423+ if sfield .Name not in names :
424+ sdef .Fields .insert (0 , sfield )
424425 if isinstance (sdef , ua .StructureDefinition ):
425426 dtypes .append (DataTypeSorter (desc .NodeId , name , desc , sdef ))
426427 return _recursive_parse (
@@ -443,7 +444,7 @@ def __add_recursion(sdef, desc):
443444 await asyncio .gather (* requests )
444445
445446
446- async def _get_parent_types (node : Node ):
447+ async def _get_parent_types (node : Node ) -> list [ Node ] :
447448 parents = []
448449 tmp_node = node
449450 for _ in range (10 ):
@@ -463,16 +464,18 @@ async def load_custom_struct(node: Node) -> Any:
463464 name = (await node .read_browse_name ()).Name
464465 for parent in await _get_parent_types (node ):
465466 parent_sdef = await parent .read_data_type_definition ()
467+ names = [f .Name for f in sdef .Fields ]
466468 for f in reversed (parent_sdef .Fields ):
467- sdef .Fields .insert (0 , f )
469+ if f .Name not in names :
470+ sdef .Fields .insert (0 , f )
468471 env = _generate_object (name , sdef , data_type = node .nodeid )
469472 struct = env [name ]
470473 setattr (ua , name , struct )
471474 ua .register_extension_object (name , sdef .DefaultEncodingId , struct , node .nodeid )
472475 return struct
473476
474477
475- async def load_custom_struct_xml_import (node_id : ua .NodeId , attrs : ua .DataTypeAttributes ):
478+ async def load_custom_struct_xml_import (node_id : ua .NodeId , attrs : ua .DataTypeAttributes ) -> Any :
476479 """
477480 This function is used to load custom structs from xmlimporter
478481 """
@@ -488,7 +491,7 @@ async def load_custom_struct_xml_import(node_id: ua.NodeId, attrs: ua.DataTypeAt
488491 return struct
489492
490493
491- async def _recursive_parse_basedatatypes (server , base_node , parent_datatype , new_alias ) -> Any :
494+ async def _recursive_parse_basedatatypes (server , base_node , parent_datatype , new_alias ) -> None :
492495 for desc in await base_node .get_children_descriptions (refs = ua .ObjectIds .HasSubtype ):
493496 name = clean_name (desc .BrowseName .Name )
494497 if parent_datatype not in "Number" :
@@ -500,7 +503,7 @@ async def _recursive_parse_basedatatypes(server, base_node, parent_datatype, new
500503 await _recursive_parse_basedatatypes (server , server .get_node (desc .NodeId ), name , new_alias )
501504
502505
503- async def load_basetype_alias_xml_import (server , name , nodeid , parent_datatype_nid ):
506+ async def load_basetype_alias_xml_import (server , name , nodeid , parent_datatype_nid ) -> Any :
504507 """
505508 Insert alias for a datatype used for xml import
506509 """
@@ -521,7 +524,7 @@ def make_basetype(name: str, parent_datatype: str) -> dict[str, Any]:
521524 return {name : getattr (ua , parent_datatype )}
522525
523526
524- async def _load_base_datatypes (server : Server | Client ) -> Any :
527+ async def _load_base_datatypes (server : Server | Client ) -> dict [ str , Any ] :
525528 new_alias = {}
526529 descriptions = await server .nodes .base_data_type .get_children_descriptions ()
527530 for desc in descriptions :
0 commit comments