1818import warnings
1919from dataclasses import asdict , dataclass , field
2020from datetime import datetime
21- from enum import Enum
21+ from enum import Enum , IntEnum
2222from json import JSONDecodeError
2323from string import Template
2424from typing import (
@@ -892,6 +892,30 @@ class runopt:
892892 Represents the metadata about the specific run option
893893 """
894894
895+ class AutoAlias (IntEnum ):
896+ snake_case = 0x1
897+ SNAKE_CASE = 0x2
898+ camelCase = 0x4
899+
900+ @staticmethod
901+ def convert_to_camel_case (alias : str ) -> str :
902+ words = re .split (r"[_\-\s]+|(?<=[a-z])(?=[A-Z])" , alias )
903+ words = [w for w in words if w ] # Remove empty strings
904+ if not words :
905+ return ""
906+ return words [0 ].lower () + "" .join (w .capitalize () for w in words [1 :])
907+
908+ @staticmethod
909+ def convert_to_snake_case (alias : str ) -> str :
910+ alias = re .sub (r"[-\s]+" , "_" , alias )
911+ alias = re .sub (r"([a-z0-9])([A-Z])" , r"\1_\2" , alias )
912+ alias = re .sub (r"([A-Z]+)([A-Z][a-z])" , r"\1_\2" , alias )
913+ return alias .lower ()
914+
915+ @staticmethod
916+ def convert_to_const_case (alias : str ) -> str :
917+ return runopt .AutoAlias .convert_to_snake_case (alias ).upper ()
918+
895919 class alias (str ):
896920 pass
897921
@@ -902,8 +926,8 @@ class deprecated(str):
902926 opt_type : Type [CfgVal ]
903927 is_required : bool
904928 help : str
905- aliases : list [alias ] | None = None
906- deprecated_aliases : list [deprecated ] | None = None
929+ aliases : set [alias ] | None = None
930+ deprecated_aliases : set [deprecated ] | None = None
907931
908932 @property
909933 def is_type_list_of_str (self ) -> bool :
@@ -1189,15 +1213,28 @@ def cfg_from_json_repr(self, json_repr: str) -> Dict[str, CfgVal]:
11891213 cfg [key ] = val
11901214 return cfg
11911215
1216+ def _generate_aliases (
1217+ self , auto_alias : int , aliases : set [str ]
1218+ ) -> set [runopt .alias ]:
1219+ generated_aliases = set ()
1220+ for alias in aliases :
1221+ if auto_alias & runopt .AutoAlias .camelCase :
1222+ generated_aliases .add (runopt .AutoAlias .convert_to_camel_case (alias ))
1223+ if auto_alias & runopt .AutoAlias .snake_case :
1224+ generated_aliases .add (runopt .AutoAlias .convert_to_snake_case (alias ))
1225+ if auto_alias & runopt .AutoAlias .SNAKE_CASE :
1226+ generated_aliases .add (runopt .AutoAlias .convert_to_const_case (alias ))
1227+ return generated_aliases
1228+
11921229 def _get_primary_key_and_aliases (
11931230 self ,
1194- cfg_key : list [str ] | str ,
1195- ) -> tuple [str , list [runopt .alias ], list [runopt .deprecated ]]:
1231+ cfg_key : list [str | int ] | str ,
1232+ ) -> tuple [str , set [runopt .alias ], set [runopt .deprecated ]]:
11961233 """
11971234 Returns the primary key and aliases for the given cfg_key.
11981235 """
11991236 if isinstance (cfg_key , str ):
1200- return cfg_key , [], []
1237+ return cfg_key , set (), set ()
12011238
12021239 if len (cfg_key ) == 0 :
12031240 raise ValueError ("cfg_key must be a non-empty list" )
@@ -1211,13 +1248,16 @@ def _get_primary_key_and_aliases(
12111248 stacklevel = 2 ,
12121249 )
12131250 primary_key = None
1214- aliases = list [runopt .alias ]()
1215- deprecated_aliases = list [runopt .deprecated ]()
1251+ auto_alias = 0x0
1252+ aliases = set [runopt .alias ]()
1253+ deprecated_aliases = set [runopt .deprecated ]()
12161254 for name in cfg_key :
12171255 if isinstance (name , runopt .alias ):
1218- aliases .append (name )
1256+ aliases .add (name )
12191257 elif isinstance (name , runopt .deprecated ):
1220- deprecated_aliases .append (name )
1258+ deprecated_aliases .add (name )
1259+ elif isinstance (name , int ):
1260+ auto_alias = auto_alias | name
12211261 else :
12221262 if primary_key is not None :
12231263 raise ValueError (
@@ -1228,11 +1268,17 @@ def _get_primary_key_and_aliases(
12281268 raise ValueError (
12291269 "Missing cfg_key. Please provide one other than the aliases."
12301270 )
1271+ if auto_alias != 0x0 :
1272+ aliases_to_generate_for = aliases | {primary_key }
1273+ additional_aliases = self ._generate_aliases (
1274+ auto_alias , aliases_to_generate_for
1275+ )
1276+ aliases .update (additional_aliases )
12311277 return primary_key , aliases , deprecated_aliases
12321278
12331279 def add (
12341280 self ,
1235- cfg_key : str | list [str ],
1281+ cfg_key : str | list [str | int ],
12361282 type_ : Type [CfgVal ],
12371283 help : str ,
12381284 default : CfgVal = None ,
0 commit comments