11# This file is part of IMAS-Python.
22# You should have received the IMAS-Python LICENSE file with this project.
3- """IMAS-Python module to support Data Dictionary identifiers.
4- """
3+ """IMAS-Python module to support Data Dictionary identifiers."""
54
65import logging
76from enum import Enum , EnumMeta
@@ -30,20 +29,34 @@ def __getitem__(cls, name):
3029
3130
3231class IDSIdentifier (Enum , metaclass = IDSIdentifierMeta ):
32+ # class IDSIdentifier(Enum):
3333 """Base class for all identifier enums."""
3434
35- def __new__ (self , value : int , description : str , alias : str = None ):
36- obj = object .__new__ (self )
35+ def __new__ (cls , value : int , description : str , aliases = None ):
36+ obj = object .__new__ (cls )
3737 obj ._value_ = value
3838 return obj
3939
40- def __init__ (self , value : int , description : str , alias : str = None ) -> None :
40+ def __init__ (self , value : int , description : str , aliases = None ) -> None :
4141 self .index = value
4242 """Unique index for this identifier value."""
4343 self .description = description
4444 """Description for this identifier value."""
45- self .alias = alias
46- """Alias for this identifier value (if any)."""
45+
46+ # Store aliases as a list for multi-alias support; keep a single 'alias'
47+ # attribute pointing to the first alias for backwards compatibility.
48+ if aliases is None :
49+ self .aliases = []
50+ else :
51+ # Accept either a single string or list of strings
52+ if isinstance (aliases , str ):
53+ # comma-separated string -> list
54+ parsed = [a .strip () for a in aliases .split ("," ) if a .strip ()]
55+ else :
56+ parsed = list (aliases )
57+ self .aliases = parsed
58+ if self .aliases :
59+ self .alias = self .aliases [0 ]
4760
4861 def __eq__ (self , other ):
4962 if self is other :
@@ -52,37 +65,33 @@ def __eq__(self, other):
5265 other_name = str (other .name )
5366 other_index = int (other .index )
5467 other_description = str (other .description )
55- other_alias = getattr (other , "alias" , None )
5668 except (AttributeError , TypeError , ValueError ):
5769 # Attribute doesn't exist, or failed to convert
5870 return NotImplemented
71+
5972 # Index must match
6073 if other_index == self .index :
6174 # Name may be left empty, or match name or alias
62- name_matches = (
75+ if (
6376 other_name == self .name
6477 or other_name == ""
65- or (self .alias and other_name == self .alias )
66- or (other_alias and other_alias == self .name )
67- or (self .alias and other_alias and self .alias == other_alias )
68- )
69- if name_matches :
78+ or other_name in getattr (self , "aliases" , [])
79+ ):
7080 # Description doesn't have to match, though we will warn when it doesn't
71- if other_description != self .description and other_description != "" :
81+ if other_description not in ( self .description , "" ) :
7282 logger .warning (
7383 "Description of %r does not match identifier description %r" ,
7484 other .description ,
7585 self .description ,
7686 )
7787 return True
78- else :
79- logger .warning (
80- "Name %r does not match identifier name %r or "
81- "alias %r, but indexes are equal." ,
82- other .name ,
83- self .name ,
84- self .alias ,
85- )
88+
89+ # If we get here with matching indexes but no name/alias match, warn
90+ logger .warning (
91+ "Name %r does not match identifier name %r, but indexes are equal." ,
92+ other .name ,
93+ self .name ,
94+ )
8695 return False
8796
8897 @classmethod
@@ -92,16 +101,21 @@ def _from_xml(cls, identifier_name, xml) -> Type["IDSIdentifier"]:
92101 aliases = {}
93102 for int_element in element .iterfind ("int" ):
94103 name = int_element .get ("name" )
95- alias = (
96- int_element .get ("alias" )
97- if int_element .get ("alias" ) is not None
98- else None
99- )
100104 value = int_element .text
101105 description = int_element .get ("description" )
102- enum_values [name ] = (int (value ), description , alias )
103- if alias :
104- aliases [alias ] = name
106+ # alias attribute may contain multiple comma-separated aliases
107+ alias_attr = int_element .get ("alias" )
108+ if alias_attr :
109+ aliases = [a .strip () for a in alias_attr .split ("," ) if a .strip ()]
110+ else :
111+ aliases = []
112+ # Canonical entry: use the canonical 'name' as key
113+ enum_values [name ] = (int (value ), description , aliases )
114+ # Also add alias names as enum *aliases* (they become enum attributes)
115+ # only if they are valid Python identifiers and not already present.
116+ for match in aliases :
117+ if match and match not in enum_values :
118+ enum_values [match ] = (int (value ), description , aliases )
105119 # Create the enumeration
106120 enum = cls (
107121 identifier_name ,
@@ -110,9 +124,6 @@ def _from_xml(cls, identifier_name, xml) -> Type["IDSIdentifier"]:
110124 qualname = f"{ __name__ } .{ identifier_name } " ,
111125 )
112126 enum .__doc__ = element .find ("header" ).text
113- enum ._aliases = aliases
114- for alias , canonical_name in aliases .items ():
115- setattr (enum , alias , getattr (enum , canonical_name ))
116127 return enum
117128
118129
0 commit comments