@@ -281,6 +281,9 @@ def get_module_name(domain: str, domain_version: str):
281281 ns = ENERGYML_NAMESPACES [domain ]
282282 if not domain_version .startswith ("v" ):
283283 domain_version = "v" + domain_version
284+
285+ if "." in domain_version :
286+ domain_version = domain_version .replace ("." , "_" )
284287 return f"energyml.{ domain } .{ domain_version } .{ ns [ns .rindex ('/' ) + 1 :]} "
285288
286289
@@ -368,6 +371,9 @@ def get_class_attributes(cls: Union[type, Any]) -> List[str]:
368371
369372
370373def get_class_attribute_type (cls : Union [type , Any ], attribute_name : str ):
374+ """
375+ Return the type of an attribute of a class.
376+ """
371377 fields = get_class_fields (cls )
372378 try :
373379 return fields [attribute_name ].type
@@ -430,7 +436,7 @@ def get_object_attribute(obj: Any, attr_dot_path: str, force_snake_case=True) ->
430436
431437 :param obj:
432438 :param attr_dot_path:
433- :param force_snake_case:
439+ :param force_snake_case: if True, the method will try to find the attribute name in snake case (only for class attribute, not for dict keys nor list index)
434440 :return:
435441 """
436442 current_attrib_name , path_next = path_next_attribute (attr_dot_path )
@@ -439,16 +445,15 @@ def get_object_attribute(obj: Any, attr_dot_path: str, force_snake_case=True) ->
439445 logging .error (f"Attribute path '{ attr_dot_path } ' is invalid." )
440446 return None
441447
442- if force_snake_case :
443- current_attrib_name = snake_case (current_attrib_name )
444-
445448 value = None
446449 if isinstance (obj , list ):
447450 value = obj [int (current_attrib_name )]
448451 elif isinstance (obj , dict ):
449452 value = obj .get (current_attrib_name , None )
450453 else :
451454 try :
455+ if force_snake_case :
456+ current_attrib_name = snake_case (current_attrib_name )
452457 value = getattr (obj , current_attrib_name )
453458 except AttributeError :
454459 return None
@@ -960,7 +965,7 @@ def search_attribute_matching_name_with_path(
960965 re_flags = re_flags ,
961966 current_path = matched_path ,
962967 deep_search = deep_search , # no deep with partial
963- search_in_sub_obj = True ,
968+ search_in_sub_obj = search_in_sub_obj ,
964969 )
965970 if search_in_sub_obj :
966971 for not_matched_path , not_matched in not_match_path_and_obj :
@@ -989,8 +994,8 @@ def search_attribute_matching_name(
989994 :param obj:
990995 :param name_rgx:
991996 :param re_flags:
992- :param deep_search:
993- :param search_in_sub_obj:
997+ :param deep_search: if True, the method will search for matching attribute in the sub attributes of a matching attribute (recursive search). If False, only the first level of attributes will be searched for a match.
998+ :param search_in_sub_obj: if True, the method will search for matching attribute in the sub attributes of a non-matching attribute (recursive search). If False, only the first level of attributes will be searched for a match.
994999 :return:
9951000 """
9961001 return [
@@ -1136,7 +1141,14 @@ def get_obj_uuid(obj: Any) -> Optional[str]:
11361141 :param obj:
11371142 :return:
11381143 """
1139- return getattr (obj , "uuid" , None ) or getattr (obj , "uid" , None )
1144+ try :
1145+ return getattr (obj , "uuid" , None ) or getattr (obj , "uid" )
1146+ except AttributeError :
1147+ if isinstance (obj , dict ):
1148+ for k in obj .keys ():
1149+ if re .match (r"[Uu]u?id|UUID" , k ):
1150+ return obj [k ]
1151+ return None
11401152 # return get_object_attribute_rgx(obj, "[Uu]u?id|UUID")
11411153
11421154
@@ -1150,7 +1162,7 @@ def get_obj_version(obj: Any) -> Optional[str]:
11501162 return (
11511163 getattr (obj , "object_version" , None )
11521164 or getattr (obj , "version_string" , None )
1153- or (getattr (obj , "citation" , None ) and getattr ( obj . citation , "version_string" , None ) )
1165+ or getattr (getattr (obj , "citation" ) , "version_string" , None )
11541166 )
11551167 except AttributeError :
11561168 # Log with full call stack to see WHO called this function
@@ -1159,6 +1171,14 @@ def get_obj_version(obj: Any) -> Optional[str]:
11591171 # exc_info=True,
11601172 # stack_info=True, # This shows the full call stack including caller
11611173 # )
1174+ if isinstance (obj , dict ):
1175+ for k in obj .keys ():
1176+ if re .match (r"object_version|version_string" , k , re .IGNORECASE ):
1177+ return obj [k ]
1178+ elif re .match (r"citation" , k , re .IGNORECASE ) and isinstance (obj [k ], dict ):
1179+ for ck in obj [k ].keys ():
1180+ if re .match (r"version_string" , ck , re .IGNORECASE ):
1181+ return obj [k ][ck ]
11621182 pass
11631183 return None
11641184 # raise e
@@ -1171,10 +1191,15 @@ def get_obj_title(obj: Any) -> Optional[str]:
11711191 :return:
11721192 """
11731193 try :
1174- return getattr (obj , "citation" , None ) and getattr (obj .citation , "title" , None )
1175- # return get_object_attribute_advanced(obj, "citation.title")
1194+ return getattr (getattr (obj , "citation" ), "title" , None )
11761195 except AttributeError :
1177- return None
1196+ if isinstance (obj , dict ):
1197+ for k in obj .keys ():
1198+ if re .match (r"citation" , k , re .IGNORECASE ) and isinstance (obj [k ], dict ):
1199+ for ck in obj [k ].keys ():
1200+ if re .match (r"title" , ck , re .IGNORECASE ):
1201+ return obj [k ][ck ]
1202+ return None
11781203
11791204
11801205def get_obj_pkg_pkgv_type_uuid_version (
0 commit comments