#!/usr/bin/env python3 # Copyright 2023 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import os import re import sys from typing import Optional, Union, Literal _THIS_DIR = os.path.abspath(os.path.dirname(__file__)) # The repo's root directory. _ROOT_DIR = os.path.abspath(os.path.join(_THIS_DIR, "..", "..", "..")) # Add the repo's root directory for clearer imports. sys.path.insert(0, _ROOT_DIR) import metadata.fields.field_types as field_types import metadata.fields.util as util import metadata.validation_result as vr _PATTERNS_NOT_MODIFIED = [ # "None" and its variants, like "(none)", "none." re.compile(r"^\(?none\.?\)?\.?$", re.IGNORECASE), # "No modification" or "No modifications". re.compile(r"^no modifications?\.?$", re.IGNORECASE), # "N/A" and its variants, like "NA", "N/A", "N/A.". re.compile(r"^(N ?\/ ?A)\.?|na\.?$", re.IGNORECASE), # "Not applicable". re.compile(r"^not applicable\.?$", re.IGNORECASE), ] class LocalModificationsField(field_types.FreeformTextField): """Custom field for local modification.""" def __init__(self): super().__init__(name="Local Modifications", structured=False) def _is_no_modification(self, value) -> bool: for pattern in _PATTERNS_NOT_MODIFIED: if pattern.match(value): return True return False def should_terminate_field(self, value) -> bool: value = value.strip() # If we can reasonably infer the field value means "No modification", # terminate this field to avoid over extraction. if self._is_no_modification(value): return True return False def narrow_type(self, value) -> Optional[Union[Literal[False], str]]: if not value: return False if self._is_no_modification(value): return False return value