Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
_utils.py356 linesDownload Raw Back to jsonschema
1from collections.abc import Mapping, MutableMapping, Sequence2from urllib.parse import urlsplit3import itertools4import re5 6 7class URIDict(MutableMapping):8    """9    Dictionary which uses normalized URIs as keys.10    """11 12    def normalize(self, uri):13        return urlsplit(uri).geturl()14 15    def __init__(self, *args, **kwargs):16        self.store = dict()17        self.store.update(*args, **kwargs)18 19    def __getitem__(self, uri):20        return self.store[self.normalize(uri)]21 22    def __setitem__(self, uri, value):23        self.store[self.normalize(uri)] = value24 25    def __delitem__(self, uri):26        del self.store[self.normalize(uri)]27 28    def __iter__(self):29        return iter(self.store)30 31    def __len__(self):  # pragma: no cover -- untested, but to be removed32        return len(self.store)33 34    def __repr__(self):  # pragma: no cover -- untested, but to be removed35        return repr(self.store)36 37 38class Unset:39    """40    An as-of-yet unset attribute or unprovided default parameter.41    """42 43    def __repr__(self):  # pragma: no cover44        return "<unset>"45 46 47def format_as_index(container, indices):48    """49    Construct a single string containing indexing operations for the indices.50 51    For example for a container ``bar``, [1, 2, "foo"] -> bar[1][2]["foo"]52 53    Arguments:54 55        container (str):56 57            A word to use for the thing being indexed58 59        indices (sequence):60 61            The indices to format.62 63    """64    if not indices:65        return container66    return f"{container}[{']['.join(repr(index) for index in indices)}]"67 68 69def find_additional_properties(instance, schema):70    """71    Return the set of additional properties for the given ``instance``.72 73    Weeds out properties that should have been validated by ``properties`` and74    / or ``patternProperties``.75 76    Assumes ``instance`` is dict-like already.77    """78    properties = schema.get("properties", {})79    patterns = "|".join(schema.get("patternProperties", {}))80    for property in instance:81        if property not in properties:82            if patterns and re.search(patterns, property):83                continue84            yield property85 86 87def extras_msg(extras):88    """89    Create an error message for extra items or properties.90    """91    verb = "was" if len(extras) == 1 else "were"92    return ", ".join(repr(extra) for extra in extras), verb93 94 95def ensure_list(thing):96    """97    Wrap ``thing`` in a list if it's a single str.98 99    Otherwise, return it unchanged.100    """101    if isinstance(thing, str):102        return [thing]103    return thing104 105 106def _mapping_equal(one, two):107    """108    Check if two mappings are equal using the semantics of `equal`.109    """110    if len(one) != len(two):111        return False112    return all(113        key in two and equal(value, two[key])114        for key, value in one.items()115    )116 117 118def _sequence_equal(one, two):119    """120    Check if two sequences are equal using the semantics of `equal`.121    """122    if len(one) != len(two):123        return False124    return all(equal(i, j) for i, j in zip(one, two))125 126 127def equal(one, two):128    """129    Check if two things are equal evading some Python type hierarchy semantics.130 131    Specifically in JSON Schema, evade `bool` inheriting from `int`,132    recursing into sequences to do the same.133    """134    if one is two:135        return True136    if isinstance(one, str) or isinstance(two, str):137        return one == two138    if isinstance(one, Sequence) and isinstance(two, Sequence):139        return _sequence_equal(one, two)140    if isinstance(one, Mapping) and isinstance(two, Mapping):141        return _mapping_equal(one, two)142    return unbool(one) == unbool(two)143 144 145def unbool(element, true=object(), false=object()):146    """147    A hack to make True and 1 and False and 0 unique for ``uniq``.148    """149    if element is True:150        return true151    elif element is False:152        return false153    return element154 155 156def uniq(container):157    """158    Check if all of a container's elements are unique.159 160    Tries to rely on the container being recursively sortable, or otherwise161    falls back on (slow) brute force.162    """163    try:164        sort = sorted(unbool(i) for i in container)165        sliced = itertools.islice(sort, 1, None)166 167        for i, j in zip(sort, sliced):168            if equal(i, j):169                return False170 171    except (NotImplementedError, TypeError):172        seen = []173        for e in container:174            e = unbool(e)175 176            for i in seen:177                if equal(i, e):178                    return False179 180            seen.append(e)181    return True182 183 184def find_evaluated_item_indexes_by_schema(validator, instance, schema):185    """186    Get all indexes of items that get evaluated under the current schema.187 188    Covers all keywords related to unevaluatedItems: items, prefixItems, if,189    then, else, contains, unevaluatedItems, allOf, oneOf, anyOf190    """191    if validator.is_type(schema, "boolean"):192        return []193    evaluated_indexes = []194 195    if "items" in schema:196        return list(range(len(instance)))197 198    ref = schema.get("$ref")199    if ref is not None:200        resolved = validator._resolver.lookup(ref)201        evaluated_indexes.extend(202            find_evaluated_item_indexes_by_schema(203                validator.evolve(204                    schema=resolved.contents,205                    _resolver=resolved.resolver,206                ),207                instance,208                resolved.contents,209            ),210        )211 212    dynamicRef = schema.get("$dynamicRef")213    if dynamicRef is not None:214        resolved = validator._resolver.lookup(dynamicRef)215        evaluated_indexes.extend(216            find_evaluated_item_indexes_by_schema(217                validator.evolve(218                    schema=resolved.contents,219                    _resolver=resolved.resolver,220                ),221                instance,222                resolved.contents,223            ),224        )225 226    if "prefixItems" in schema:227        evaluated_indexes += list(range(len(schema["prefixItems"])))228 229    if "if" in schema:230        if validator.evolve(schema=schema["if"]).is_valid(instance):231            evaluated_indexes += find_evaluated_item_indexes_by_schema(232                validator, instance, schema["if"],233            )234            if "then" in schema:235                evaluated_indexes += find_evaluated_item_indexes_by_schema(236                    validator, instance, schema["then"],237                )238        elif "else" in schema:239            evaluated_indexes += find_evaluated_item_indexes_by_schema(240                validator, instance, schema["else"],241            )242 243    for keyword in ["contains", "unevaluatedItems"]:244        if keyword in schema:245            for k, v in enumerate(instance):246                if validator.evolve(schema=schema[keyword]).is_valid(v):247                    evaluated_indexes.append(k)248 249    for keyword in ["allOf", "oneOf", "anyOf"]:250        if keyword in schema:251            for subschema in schema[keyword]:252                errs = next(validator.descend(instance, subschema), None)253                if errs is None:254                    evaluated_indexes += find_evaluated_item_indexes_by_schema(255                        validator, instance, subschema,256                    )257 258    return evaluated_indexes259 260 261def find_evaluated_property_keys_by_schema(validator, instance, schema):262    """263    Get all keys of items that get evaluated under the current schema.264 265    Covers all keywords related to unevaluatedProperties: properties,266    additionalProperties, unevaluatedProperties, patternProperties,267    dependentSchemas, allOf, oneOf, anyOf, if, then, else268    """269    if validator.is_type(schema, "boolean"):270        return []271    evaluated_keys = []272 273    ref = schema.get("$ref")274    if ref is not None:275        resolved = validator._resolver.lookup(ref)276        evaluated_keys.extend(277            find_evaluated_property_keys_by_schema(278                validator.evolve(279                    schema=resolved.contents,280                    _resolver=resolved.resolver,281                ),282                instance,283                resolved.contents,284            ),285        )286 287    dynamicRef = schema.get("$dynamicRef")288    if dynamicRef is not None:289        resolved = validator._resolver.lookup(dynamicRef)290        evaluated_keys.extend(291            find_evaluated_property_keys_by_schema(292                validator.evolve(293                    schema=resolved.contents,294                    _resolver=resolved.resolver,295                ),296                instance,297                resolved.contents,298            ),299        )300 301    properties = schema.get("properties")302    if validator.is_type(properties, "object"):303        evaluated_keys += properties.keys() & instance.keys()304 305    for keyword in ["additionalProperties", "unevaluatedProperties"]:306        if (subschema := schema.get(keyword)) is None:307            continue308        evaluated_keys += (309            key310            for key, value in instance.items()311            if is_valid(validator.descend(value, subschema))312        )313 314    if "patternProperties" in schema:315        for property in instance:316            for pattern in schema["patternProperties"]:317                if re.search(pattern, property):318                    evaluated_keys.append(property)319 320    if "dependentSchemas" in schema:321        for property, subschema in schema["dependentSchemas"].items():322            if property not in instance:323                continue324            evaluated_keys += find_evaluated_property_keys_by_schema(325                validator, instance, subschema,326            )327 328    for keyword in ["allOf", "oneOf", "anyOf"]:329        for subschema in schema.get(keyword, []):330            if not is_valid(validator.descend(instance, subschema)):331                continue332            evaluated_keys += find_evaluated_property_keys_by_schema(333                validator, instance, subschema,334            )335 336    if "if" in schema:337        if validator.evolve(schema=schema["if"]).is_valid(instance):338            evaluated_keys += find_evaluated_property_keys_by_schema(339                validator, instance, schema["if"],340            )341            if "then" in schema:342                evaluated_keys += find_evaluated_property_keys_by_schema(343                    validator, instance, schema["then"],344                )345        elif "else" in schema:346            evaluated_keys += find_evaluated_property_keys_by_schema(347                validator, instance, schema["else"],348            )349 350    return evaluated_keys351 352 353def is_valid(errs_it):354    """Whether there are no errors in the given iterator."""355    return next(errs_it, None) is None356 
codekingpro/portable-devtools · Team Ai