classFieldErrors(Error):"""Base class for errors associated with a specific field."""def__init__(self,field:FieldReference,errors:Iterable[Error])->None:self._field=fieldself._errors:Sequence[Error]=tuple(errors)ifnoterrorsornotfield:raiseValueError("FieldErrors must contain at least one error and field defined.")message=ErrorMessage(f"{len(self._errors)} error(s) for field '{field}'.")super().__init__(message=message)def__repr__(self)->str:"""Return a concise string representation of the field errors."""return(f"<{self._get_title_prefix()} field={self._field.value!r} errors={len(self._errors)}>")def__str__(self)->str:"""Return a human-readable string representation of the field errors."""error_messages="\n".join(f" - {str(error)}"forerrorinself._errors)returnf"{self._get_title_prefix()} for field '{self._field.value}':\n{error_messages}"def__iter__(self)->Iterator[Error]:"""Iterate over the errors associated with the field."""returniter(self._errors)def__len__(self)->int:"""Return the number of errors associated with the field."""returnlen(self._errors)@propertydeffield(self)->FieldReference:"""The field associated with these errors."""returnself._field@propertydeferrors(self)->Sequence[Error]:"""The collection of errors associated with the field."""returnself._errorsdefas_debug_string(self)->str:"""Return detailed, multi-line string of this field error collection for debugging."""error_strings=[f" {err.as_debug_string()}"forerrinself._errors]return(f"{self._get_title_prefix()}(\n"f" field={repr(self._field)},\n"f" errors=[\n"+(""ifnoterror_stringselse"\n".join(error_strings)+"\n")+" ]\n"")")def_get_title_prefix(self)->str:"""Get the title prefix for this field error type."""returnself.__class__.__name__
def__repr__(self)->str:"""Return a concise string representation of the field errors."""return(f"<{self._get_title_prefix()} field={self._field.value!r} errors={len(self._errors)}>")
def__str__(self)->str:"""Return a human-readable string representation of the field errors."""error_messages="\n".join(f" - {str(error)}"forerrorinself._errors)returnf"{self._get_title_prefix()} for field '{self._field.value}':\n{error_messages}"
defas_debug_string(self)->str:"""Return detailed, multi-line string of this field error collection for debugging."""error_strings=[f" {err.as_debug_string()}"forerrinself._errors]return(f"{self._get_title_prefix()}(\n"f" field={repr(self._field)},\n"f" errors=[\n"+(""ifnoterror_stringselse"\n".join(error_strings)+"\n")+" ]\n"")")