"""Utilities for storing collections of error messages... warning:: This module is treated as private API. Users should not need to use this module directly."""frommarshmallow.exceptionsimportSCHEMAclassErrorStore:def__init__(self):#: Dictionary of errors stored during serializationself.errors={}defstore_error(self,messages,field_name=SCHEMA,index=None):# field error -> store/merge error messages under field name key# schema error -> if string or list, store/merge under _schema key# -> if dict, store/merge with other top-level keysmessages=copy_containers(messages)iffield_name!=SCHEMAornotisinstance(messages,dict):messages={field_name:messages}ifindexisnotNone:messages={index:messages}self.errors=merge_errors(self.errors,messages)defcopy_containers(errors):ifisinstance(errors,list):return[copy_containers(val)forvalinerrors]ifisinstance(errors,dict):return{key:copy_containers(val)forkey,valinerrors.items()}returnerrors
[docs]defmerge_errors(errors1,errors2):# noqa: PLR0911"""Deeply merge two error messages. The format of ``errors1`` and ``errors2`` matches the ``message`` parameter of :exc:`marshmallow.exceptions.ValidationError`. """ifnoterrors1:returnerrors2ifnoterrors2:returnerrors1ifisinstance(errors1,list):ifisinstance(errors2,list):errors1.extend(errors2)returnerrors1ifisinstance(errors2,dict):errors2[SCHEMA]=merge_errors(errors1,errors2.get(SCHEMA))returnerrors2errors1.append(errors2)returnerrors1ifisinstance(errors1,dict):ifisinstance(errors2,dict):forkey,valinerrors2.items():ifkeyinerrors1:errors1[key]=merge_errors(errors1[key],val)else:errors1[key]=valreturnerrors1errors1[SCHEMA]=merge_errors(errors1.get(SCHEMA),errors2)returnerrors1ifisinstance(errors2,list):return[errors1,*errors2]ifisinstance(errors2,dict):errors2[SCHEMA]=merge_errors(errors1,errors2.get(SCHEMA))returnerrors2return[errors1,errors2]