diff options
| author | S. Solomon Darnell | 2025-03-28 21:52:21 -0500 |
|---|---|---|
| committer | S. Solomon Darnell | 2025-03-28 21:52:21 -0500 |
| commit | 4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch) | |
| tree | ee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/strictyaml/utils.py | |
| parent | cc961e04ba734dd72309fb548a2f97d67d578813 (diff) | |
| download | gn-ai-master.tar.gz | |
Diffstat (limited to '.venv/lib/python3.12/site-packages/strictyaml/utils.py')
| -rw-r--r-- | .venv/lib/python3.12/site-packages/strictyaml/utils.py | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/strictyaml/utils.py b/.venv/lib/python3.12/site-packages/strictyaml/utils.py new file mode 100644 index 00000000..32ce5e01 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/strictyaml/utils.py @@ -0,0 +1,255 @@ +from strictyaml.ruamel.comments import CommentedSeq, CommentedMap +from strictyaml import exceptions +from re import compile +import decimal +import sys + +if sys.version_info[:2] > (3, 4): + from collections.abc import Iterable +else: + from collections import Iterable + +if sys.version_info[0] == 3: + unicode = str + + +def flatten(items): + """ + Yield items from any nested iterable. + + >>> list(flatten([[1, 2, 3], [[4, 5], 6, 7]])) + [1, 2, 3, 4, 5, 6, 7] + """ + for x in items: + if isinstance(x, Iterable) and not isinstance(x, (str, bytes)): + for sub_x in flatten(x): + yield sub_x + else: + yield x + + +def has_number_type(value): + """ + Is a value a number or a non-number? + + >>> has_number_type(3.5) + True + + >>> has_number_type(3) + True + + >>> has_number_type(decimal.Decimal("3.5")) + True + + >>> has_number_type("3.5") + False + + >>> has_number_type(True) + False + """ + return isinstance(value, (int, float, decimal.Decimal)) and not isinstance( + value, bool + ) + + +def is_string(value): + """ + Python 2/3 compatible way of checking if a value is a string. + """ + return isinstance(value, unicode) or str(type(value)) in ( + "<type 'unicode'>", + "<type 'str'>", + "<class 'str'>", + ) + + +def is_integer(value): + """ + Is a string a string of an integer? + + >>> is_integer("4") + True + + >>> is_integer("4_000") + True + + >>> is_integer("3.4") + False + """ + return compile(r"^[-+]?[0-9_]+$").match(value) is not None + + +def is_hexadecimal(value): + """ + Is a string a string of a hexademcial integer? + + >>> is_hexadecimal("0xa1") + True + + >>> is_hexadecimal("0XA1") + True + + >>> is_hexadecimal("0xa1x") + False + + >>> is_hexadecimal("xa1") + False + + >>> is_hexadecimal("a1") + False + + >>> is_hexadecimal("1") + False + """ + return compile(r"^0[xX]+[a-fA-F0-9]+$").match(value) is not None + + +def is_decimal(value): + """ + Is a string a decimal? + + >>> is_decimal("4") + True + + >>> is_decimal("4_000") + True + + >>> is_decimal("3.5") + True + + >>> is_decimal("4.") + True + + >>> is_decimal("4.000_001") + True + + >>> is_decimal("blah") + False + """ + return ( + compile(r"^[-+]?[0-9_]*(\.[0-9_]*)?([eE][-+]?[0-9_]+)?$").match(value) + is not None + ) + + +def is_infinity(value): + """ + Is string a valid representation for positive or negative infinity? + + Valid formats are: + [+/-]inf, [+/-]INF, [+/-]Inf, [+/-].inf, [+/-].INF and [+/-].Inf + + >>> is_infinity(".inf") + True + + >>> is_infinity("+.INF") + True + + >>> is_infinity("-.Inf") + True + + >>> is_infinity("Inf") + True + + >>> is_infinity("INF") + True + + >>> is_infinity("-INF") + True + + >>> is_infinity("infinitesimal") + False + """ + return compile(r"^[-+]?\.?(?:inf|Inf|INF)$").match(value) is not None + + +def is_not_a_number(value): + """ + Is string a valid representation for 'not a number'? + + Valid formats are: nan, NaN, NAN, .nan, .NaN, .NAN. + + >>> is_not_a_number(".nan") + True + + >>> is_not_a_number(".NaN") + True + + >>> is_not_a_number("NAN") + True + + >>> is_not_a_number("nan") + True + + >>> is_not_a_number("nanan") + False + + >>> is_not_a_number("1e5") + False + """ + return compile(r"^\.?(?:nan|NaN|NAN)$").match(value) is not None + + +def comma_separated_positions(text): + """ + Start and end positions of comma separated text items. + + Commas and trailing spaces should not be included. + + >>> comma_separated_positions("ABC, 2,3") + [(0, 3), (5, 6), (7, 8)] + """ + chunks = [] + start = 0 + end = 0 + for item in text.split(","): + space_increment = 1 if item[0] == " " else 0 + start += space_increment # Is there a space after the comma to ignore? ", " + end += len(item.lstrip()) + space_increment + chunks.append((start, end)) + start += len(item.lstrip()) + 1 # Plus comma + end = start + return chunks + + +def ruamel_structure(data, validator=None): + """ + Take dicts and lists and return a strictyaml.ruamel style + structure of CommentedMaps, CommentedSeqs and + data. + + If a validator is presented and the type is unknown, + it is checked against the validator to see if it will + turn it back in to YAML. + """ + if isinstance(data, dict): + if len(data) == 0: + raise exceptions.CannotBuildDocumentsFromEmptyDictOrList( + "Document must be built with non-empty dicts and lists" + ) + return CommentedMap( + [ + (ruamel_structure(key), ruamel_structure(value)) + for key, value in data.items() + ] + ) + elif isinstance(data, list): + if len(data) == 0: + raise exceptions.CannotBuildDocumentsFromEmptyDictOrList( + "Document must be built with non-empty dicts and lists" + ) + return CommentedSeq([ruamel_structure(item) for item in data]) + elif isinstance(data, bool): + return "yes" if data else "no" + elif isinstance(data, (int, float)): + return str(data) + else: + if not is_string(data): + raise exceptions.CannotBuildDocumentFromInvalidData( + ( + "Document must be built from a combination of:\n" + "string, int, float, bool or nonempty list/dict\n\n" + "Instead, found variable with type '{}': '{}'" + ).format(type(data).__name__, data) + ) + return data |
