text: from typing import Any, Iterable, List, Set
  
  from boa3.model.type.annotation.uniontype import UnionType
  from boa3.model.type.itype import IType
  from boa3.model.type.primitive.nonetype import noneType
  
  
  class OptionalType(UnionType):
      """
      An class used to represent Python Optional annotation type
      """
  
      def __init__(self, optional_types: Set[IType] = None):
          if optional_types is None:
              union_types = None
          else:
              union_types = optional_types.copy()
              if noneType in optional_types:
                  optional_types.remove(noneType)
              else:
                  union_types.add(noneType)
  
          super().__init__(union_types)
          self._identifier = 'Optional'
          self._optional_type = optional_types
  
      @property
      def identifier(self) -> str:
          return '{0}[{1}]'.format(self._identifier,
                                   ', '.join([t.identifier for t in self._optional_type]))
  
      @property
      def optional_types(self) -> List[IType]:
          return list(self._optional_type)
  
      def _is_type_of(self, value: Any) -> bool:
          if not isinstance(self._optional_type, Iterable):
              return False
          if isinstance(value, UnionType):
              return all(self._is_type_of(x) for x in value._union_types)
          return any(t.is_type_of(value) for t in self._union_types)
  
      @classmethod
      def build(cls, value: Any) -> IType:
          if isinstance(value, Iterable):
              value = set(value)
          else:
              value = {value}
          value.add(noneType)
          return super().build(value)
  