def _get_parsing_plan_for_multifile_children( self, obj_on_fs: PersistedObject, desired_type: Type[Any], logger: Logger) -> Dict[str, Any]: """ Simply inspects the required type to find the names and types of its constructor arguments. Then relies on the inner ParserFinder to parse each of them. :param obj_on_fs: :param desired_type: :param logger: :return: """ if is_collection(desired_type, strict=True): # if the destination type is 'strictly a collection' (not a subclass of a collection) we know that we can't # handle it here, the constructor is not pep484-typed raise TypeError( 'Desired object type \'' + get_pretty_type_str(desired_type) + '\' is a collection, ' 'so it cannot be parsed with this default object parser') else: # First get the file children children_on_fs = obj_on_fs.get_multifile_children() # Try the type itself # try: return self.__get_parsing_plan_for_multifile_children( obj_on_fs, desired_type, children_on_fs, logger=logger)
def _get_parsing_plan_for_multifile_children(self, obj_on_fs: PersistedObject, desired_type: Type[Any], logger: Logger) -> Dict[str, Any]: """ Simply simply inspects the required type to find the names and types of its constructor arguments. Then relies on the inner ParserFinder to parse each of them. :param obj_on_fs: :param desired_type: :param logger: :return: """ if is_collection(desired_type, strict=True): raise TypeError('Desired object type \'' + get_pretty_type_str(desired_type)+ '\' is a collection, ' 'so it cannot be parsed with this default object parser') # First get the file children children_on_fs = obj_on_fs.get_multifile_children() # -- (a) extract the schema from the class constructor constructor_args_types_and_opt = get_constructor_attributes_types(desired_type) # -- (b) plan to parse each attribute required by the constructor children_plan = dict() # results will be put in this object # --use sorting in order to lead to reproducible results in case of multiple errors for attribute_name, att_desc in sorted(constructor_args_types_and_opt.items()): attribute_is_mandatory = att_desc[1] attribute_type = att_desc[0] # get the child if attribute_name in children_on_fs.keys(): child_on_fs = children_on_fs[attribute_name] # find a parser parser_found = self.parser_finder.build_parser_for_fileobject_and_desiredtype(child_on_fs, attribute_type, logger=logger) # create a parsing plan children_plan[attribute_name] = parser_found.create_parsing_plan(attribute_type, child_on_fs, logger=logger) else: if attribute_is_mandatory: raise MissingMandatoryAttributeFiles.create(obj_on_fs, desired_type, attribute_name) else: # we don't care : optional attribute # dont use warning since it does not show up nicely #print('----- WARNING: Attribute ' + attribute_name + ' was not found on file system. However ' # 'it is not mandatory for the constructor of type ' + get_pretty_type_str(desired_type) # + ', so we\'ll build the object without it...') logger.warning('----- Attribute ' + attribute_name + ' was not found on file system. However ' 'it is not mandatory for the constructor of type ' + get_pretty_type_str(desired_type) + ', so we\'ll build the object without it...') pass return children_plan
def _get_parsing_plan_for_multifile_children( self, obj_on_fs: PersistedObject, desired_type: Type[Any], logger: Logger) -> Dict[str, Any]: """ Simply inspects the required type to find the base type expected for items of the collection, and relies on the ParserFinder to find the parsing plan :param obj_on_fs: :param desired_type: :param logger: :return: """ # nb of file children n_children = len(obj_on_fs.get_multifile_children()) # first extract base collection type subtypes, key_type = _extract_collection_base_type(desired_type) if isinstance(subtypes, tuple): # -- check the tuple length if n_children != len(subtypes): raise FolderAndFilesStructureError.create_for_multifile_tuple( obj_on_fs, len(subtypes), len(obj_on_fs.get_multifile_children())) else: # -- repeat the subtype n times subtypes = [subtypes] * n_children # -- for each child create a plan with the appropriate parser children_plan = OrderedDict() # use sorting for reproducible results in case of multiple errors for (child_name, child_fileobject), child_typ in zip( sorted(obj_on_fs.get_multifile_children().items()), subtypes): # -- use the parserfinder to find the plan t, child_parser = self.parser_finder.build_parser_for_fileobject_and_desiredtype( child_fileobject, child_typ, logger) children_plan[child_name] = child_parser.create_parsing_plan( t, child_fileobject, logger, _main_call=False) return children_plan