@@ -668,6 +668,22 @@ def is_pathlike(typehint) -> bool:
668668 return is_subclass (typehint , os .PathLike )
669669
670670
671+ def get_subclasses_from_type (typehint , names = True , subclasses = None ) -> tuple :
672+ if subclasses is None :
673+ subclasses = []
674+ origin = get_typehint_origin (typehint )
675+ if origin == Union or origin in sequence_origin_types :
676+ for subtype in typehint .__args__ :
677+ get_subclasses_from_type (subtype , names , subclasses )
678+ elif ActionTypeHint .is_subclass_typehint (typehint , all_subtypes = False ):
679+ if names :
680+ if typehint .__name__ not in subclasses :
681+ subclasses .append (typehint .__name__ )
682+ elif typehint not in subclasses :
683+ subclasses .append (typehint )
684+ return tuple (subclasses )
685+
686+
671687def raise_unexpected_value (message : str , val : Any = inspect ._empty , exception : Optional [Exception ] = None ) -> NoReturn :
672688 if val is not inspect ._empty :
673689 message += f". Got value: { val } "
@@ -1105,14 +1121,20 @@ def is_private(class_path):
11051121 return "._" in class_path
11061122
11071123 def add_subclasses (cl ):
1124+ if hasattr (cl , "__args__" ) and get_typehint_origin (cl ) in {List , list , Union }:
1125+ for arg in cl .__args__ :
1126+ add_subclasses (arg )
1127+ return
11081128 try :
11091129 class_path = get_import_path (cl )
11101130 except (ImportError , AttributeError ) as err : # Attribute is added in case of dot notation imports
11111131 warning (f"Hit failing import with following error: { err } " )
11121132 return
1113- if is_local (cl ) or issubclass (cl , LazyInitBaseClass ):
1133+ if is_local (cl ) or is_subclass (cl , LazyInitBaseClass ):
11141134 return
11151135 if not (inspect .isabstract (cl ) or is_private (class_path )):
1136+ if class_path in subclass_list :
1137+ return
11161138 subclass_list .append (class_path )
11171139 for subclass in cl .__subclasses__ () if hasattr (cl , "__subclasses__" ) else []:
11181140 add_subclasses (subclass )
@@ -1124,7 +1146,7 @@ def add_subclasses(cl):
11241146
11251147 if get_typehint_origin (cls ) in {Union , Type , type }:
11261148 for arg in cls .__args__ :
1127- if ActionTypeHint .is_subclass_typehint (arg ) and arg not in {object , type }:
1149+ if ActionTypeHint .is_subclass_typehint (arg , also_lists = True ) and arg not in {object , type }:
11281150 add_subclasses (arg )
11291151 else :
11301152 add_subclasses (cls )
0 commit comments