Skip to content

Instantly share code, notes, and snippets.

@mh-firouzjah
Created November 16, 2024 03:30
Show Gist options
  • Save mh-firouzjah/5d7f3fefed7d6f1a44a63d5d48bddfd8 to your computer and use it in GitHub Desktop.
Save mh-firouzjah/5d7f3fefed7d6f1a44a63d5d48bddfd8 to your computer and use it in GitHub Desktop.
to share
@model_validator(mode="after")
def validate_other_information(self):
    parsed_info = {}
    errors = []
    remaining_text = self.other_information[:]

    for key, pattern in regex_patterns.OTHER_INFO_SWITCHES_MAPPING.items():
        bounded_pattern = re.compile(rf"\b{pattern[1:-1]}\b")  # Full validation regex
        switch_pattern = re.compile(rf"\b{key}/")  # Preliminary switch detection

        # Check for any occurrence of the switch
        matches = list(bounded_pattern.finditer(remaining_text))
        if matches:
            if len(matches) > 1:
                # Duplicate switch error
                errors.append(
                    InitErrorDetails(
                        type=PydanticCustomError(
                            "value_error.duplicate_switch",
                            error_messages.OTHER_INFO_SWITCH_DUPLICATE.format(switch=key),
                        ),
                        loc=("other_information", key),
                        input=self.other_information,
                        ctx={},
                    )
                )
            else:
                # Valid switch found, process it
                data = matches[0].groupdict()
                match_span = matches[0].span()
                remaining_text = remaining_text[:match_span[0]] + remaining_text[match_span[1]:]
                parsed_info.update(data)
        else:
            # Detect switches that exist but have invalid values
            invalid_matches = list(switch_pattern.finditer(remaining_text))
            if invalid_matches:
                for match in invalid_matches:
                    match_span = match.span()
                    errors.append(
                        InitErrorDetails(
                            type=PydanticCustomError(
                                "value_error.invalid_value",
                                f"Invalid value for switch '{key}'",
                            ),
                            loc=("other_information", key),
                            input=remaining_text[match_span[0]:match_span[1]],
                            ctx={},
                        )
                    )
                    # Remove the invalid switch occurrence from the text
                    remaining_text = remaining_text[:match_span[0]] + remaining_text[match_span[1]:]

    # Handle any remaining ambiguous data
    if remaining_text.strip():
        errors.append(
            InitErrorDetails(
                type=PydanticCustomError(
                    "value_error.ambiguous_data",
                    error_messages.OTHER_INFO_AMBIGUOUS_DATA.format(text=remaining_text.strip()),
                ),
                loc=("other_information",),
                input=self.other_information,
                ctx={},
            )
        )

    # Raise validation errors if any
    if errors:
        raise ValidationError.from_exception_data(
            title=self.__class__.__name__,
            line_errors=errors,
        )

    # Update the instance's parsed information
    self._other_information = parsed_info

    return self
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment