docs: def _dict_to_object(desired_type: Type[T], contents_dict: Dict[str, Any], logger: Logger,
                      options: Dict[str, Dict[str, Any]], conversion_finder: ConversionFinder = None,
                      is_dict_of_dicts: bool = False) -> T:
      """
      Utility method to create an object from a dictionary of constructor arguments. Constructor arguments that dont have
      the correct type are intelligently converted if possible
  
      :param desired_type:
      :param contents_dict:
      :param logger:
      :param options:
      :param conversion_finder:
      :param is_dict_of_dicts:
      :return:
      """
      # collect pep-484 information in the constructor to be able to understand what is required
      constructor_args_types_and_opt = get_constructor_attributes_types(desired_type)
  
      try:
          # for each attribute, convert the types of its parsed values if required
          dict_for_init = dict()
          for attr_name, provided_attr_value in contents_dict.items():
  
              # check if this attribute name is required by the constructor
              if attr_name in constructor_args_types_and_opt.keys():
  
                  # check the theoretical type wanted by the constructor
                  attr_type_required = constructor_args_types_and_opt[attr_name][0]
  
                  # resolve forward references
                  attr_type_required = resolve_forward_ref(attr_type_required)
  
                  if not is_dict_of_dicts:
                      if is_valid_pep484_type_hint(attr_type_required):
                          # this will not fail if type information is not present;the attribute will only be used 'as is'
                          full_attr_name = get_pretty_type_str(desired_type) + '.' + attr_name
  
                          dict_for_init[attr_name] = ConversionFinder.try_convert_value(conversion_finder, full_attr_name,
                                                                                        provided_attr_value,
                                                                                        attr_type_required, logger,
                                                                                        options)
  
                      else:
                          warn("Constructor for type <{t}> has no valid PEP484 Type hint for attribute {att}, trying to "
                               "use the parsed value in the dict directly".format(t=get_pretty_type_str(desired_type),
                                                                           att=attr_name))
                          dict_for_init[attr_name] = provided_attr_value
  
                  else:
                      # in that mode, the attribute value itself is a dict, so the attribute needs to be built from that
                      # dict first
                      if isinstance(provided_attr_value, dict):
                          # recurse : try to build this attribute from the dictionary provided. We need to know the type
                          # for this otherwise we wont be able to call the constructor :)
                          if (attr_type_required is None) or (attr_type_required is Parameter.empty):
                              raise TypeInformationRequiredError.create_for_object_attributes(desired_type, attr_name,
                                                                                              attr_type_required)
  
                          elif not is_valid_pep484_type_hint(attr_type_required):
                              raise InvalidPEP484TypeHint.create_for_object_attributes(desired_type, attr_name,
                                                                                       attr_type_required)
  
                          else:
                              # we can build the attribute from the sub-dict
                              dict_for_init[attr_name] = dict_to_object(attr_type_required, provided_attr_value,
                                                                        logger, options,
                                                                        conversion_finder=conversion_finder)
  
                      else:
                          raise ValueError('Error while trying to build object of type ' + str(desired_type) + ' from a '
                                           'dictionary of dictionaries. Entry \'' + attr_name + '\' is not a dictionary')
              else:
                  if is_dict_of_dicts and attr_name is 'DEFAULT':
                      # -- tolerate but ignore - this is probably due to a configparser
                      # warning('Property name \'' + attr_name + '\' is not an attribute of the object constructor. <'
                      #         + get_pretty_type_str(desired_type) + '> constructor attributes are : '
                      #         + list(set(constructor_args_types.keys()) - {'self'}) + '. However it is named DEFAULT')
                      pass
                  else:
                      # the dictionary entry does not correspond to a valid attribute of the object
                      raise InvalidAttributeNameForConstructorError.create(desired_type,
                                                                           list(set(constructor_args_types_and_opt.keys()) - {'self'}),
                                                                           attr_name)
  
          # create the object using its constructor
          try:
              return desired_type(**dict_for_init)
          except Exception as e:
              # Wrap into an Exception
              raise ObjectInstantiationException.create(desired_type, dict_for_init, e)
  
      except TypeError as e:
          raise CaughtTypeErrorDuringInstantiation.create(desired_type, contents_dict, e)