I am using Python 3.11 and I would need to detect if an optional class attribute is type of Enum (i.e. type of a subclass of Enum). With typing.get_type_hints() I can get the type hints as a dict, but how to check if a field's type is optional Enum (subclass)? Even better if I could get the type of any optional field regardless is it Optional[str], Optional[int], Optional[Class_X], etc. Example code from typing import Optional, get_type_hints from enum import IntEnum, Enum class TestEnum(IntEnum): foo = 1 bar = 2 class Foo(): opt_enum : TestEnum | None = None types = get_type_hints(Foo)['opt_enum'] This works (ipython) In [4]: Optional[TestEnum] == types Out[4]: True These ones fail (yes, these are desperate attempts) In [6]: Optional[IntEnum] == types Out[6]: False and In [11]: issubclass(Enum, types) Out[11]: False and In [12]: issubclass(types, Enum) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In [12], line 1 ----> 1 issubclass(types, Enum) TypeError: issubclass() arg 1 must be a class and In [13]: issubclass(types, Optional[Enum]) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In [13], line 1 ----> 1 issubclass(types, Optional[Enum]) File /usr/lib/python3.10/typing.py:1264, in _UnionGenericAlias.__subclasscheck__(self, cls) 1262 def __subclasscheck__(self, cls): 1263 for arg in self.__args__: -> 1264 if issubclass(cls, arg): 1265 return True TypeError: issubclass() arg 1 must be a class and In [7]: IntEnum in types --------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In [7], line 1 ----> 1 IntEnum in types TypeError: argument of type 'types.UnionType' is not iterable Why I needed this I have several cases where I am importing data from csv files and creating objects of a class from each row. csv.DictReader() returns a dict[str, str] and I need to fix the types for the fields before attempting to create the object. However, some of the object fields are Optional[int], Optional[bool], Optional[EnumX] or Optional[ClassX]. I have several of those classes multi-inheriting my CSVImportable() class/interface. I want to implement the logic once into CSVImportable() class instead of writing roughly same code in field-aware way in every subclass. This CSVImportable._field_type_updater() should: correctly change the types at least for basic types and enums Gracefully skip Optional[ClassX] fields Naturally I am thankful for better designs too Continue reading...