#!/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 re from typing import List # Preferred values for yes/no fields (i.e. all lowercase). YES = "yes" NO = "no" # Pattern used to check if the entire string is "unknown", # case-insensitive. _PATTERN_UNKNOWN = re.compile(r"^unknown$", re.IGNORECASE) # Pattern used to check if the entire string is functionally empty, i.e. # empty string, or all characters are only whitespace. _PATTERN_ONLY_WHITESPACE = re.compile(r"^\s*$") # Pattern used to check if the string starts with "yes", # case-insensitive. _PATTERN_STARTS_WITH_YES = re.compile(r"^yes", re.IGNORECASE) # Pattern used to check if the string starts with "no", # case-insensitive. _PATTERN_STARTS_WITH_NO = re.compile(r"^no", re.IGNORECASE) # Variants of N/A (Not Applicable). _PATTERN_NOT_APPLICABLE = re.compile(r"^(N ?\/ ?A)\.?|na\.?|not applicable\.?$", re.IGNORECASE) # A collection of values that provides little information. # Use lower-case for easier comparison. _KNOWN_INVALID_VALUES = { "0", "varies", "-", "unknown", "head", "see deps", "deps", } def matches(pattern: re.Pattern, value: str) -> bool: """Returns whether the value matches the pattern.""" return pattern.match(value) is not None def is_empty(value: str) -> bool: """Returns whether the value is functionally empty.""" return matches(_PATTERN_ONLY_WHITESPACE, value) def is_unknown(value: str) -> bool: """Returns whether the value is 'unknown' (case insensitive).""" return matches(_PATTERN_UNKNOWN, value) def quoted(values: List[str]) -> str: """Returns a string of the given values, each being individually quoted. """ return ", ".join([f"'{entry}'" for entry in values]) def infer_as_boolean(value: str, default: bool = True) -> bool: """Attempts to infer the value as a boolean, where: - "yes"-ish values return True; - "no"-ish values return False; and - default is returned otherwise. """ if matches(_PATTERN_STARTS_WITH_YES, value): return True elif matches(_PATTERN_STARTS_WITH_NO, value): return False else: return default def is_known_invalid_value(value: str): """Returns whether `value` is among the known bad values that provides little machine readable information. """ if not value: return False if value.lower() in _KNOWN_INVALID_VALUES: return True return False def is_not_applicable(value: str) -> bool: return matches(_PATTERN_NOT_APPLICABLE, value)