Exemple #1
0
def get_validator(overwrite=False, normalizers=None, **kwargs):
    r"""Return the validator that includes ygg expansion types.

    Args:
        overwrite (bool, optional): If True, the existing validator will be
            overwritten. Defaults to False.
        normalizers (dict, optional): Additional normalizers to add.
        **kwargs: Additional keyword arguments are passed to normalizer.create.

    Returns:
        jsonschema.IValidator: JSON schema validator.

    """
    from yggdrasil.metaschema import normalizer
    global _validator
    if (_validator is None) or overwrite:
        metaschema = get_metaschema()
        # Get set of validators
        all_validators = copy.deepcopy(_base_validator.VALIDATORS)
        for k, v in get_registered_properties().items():
            if (not v._replaces_existing):
                assert (k not in all_validators)
            all_validators[k] = v.wrapped_validate
        # Get set of datatypes
        # TODO: This will need to be changed if back-ported in jsonschema
        if _jsonschema_ver_maj < 3:
            all_datatypes = copy.deepcopy(_base_validator.DEFAULT_TYPES)
            for k, v in get_registered_types().items():
                if (not v._replaces_existing):
                    # Error raised on registration
                    assert (k not in all_datatypes)
                all_datatypes[k] = v.python_types
            kwargs['default_types'] = all_datatypes
        else:
            type_checker = copy.deepcopy(_base_validator.TYPE_CHECKER)
            new_type_checkers = {}
            for k, v in get_registered_types().items():
                if (not v._replaces_existing):
                    # Error raised on registration
                    assert (k not in type_checker._type_checkers)
                new_type_checkers[k] = v.jsonschema_type_checker
            kwargs['type_checker'] = type_checker.redefine_many(
                new_type_checkers)
        # Get set of normalizers
        if normalizers is None:
            normalizers = {}
        # Use default base and update validators
        _validator = normalizer.create(meta_schema=metaschema,
                                       validators=all_validators,
                                       normalizers=normalizers,
                                       **kwargs)
        _validator._base_validator = _base_validator
    return _validator
Exemple #2
0
def create_metaschema(overwrite=False):
    r"""Create the meta schema for validating ygg schema.

    Args:
        overwrite (bool, optional): If True, the existing meta schema will be
            overwritten. If False and the metaschema exists, an error will be
            raised. Defaults to False.

    Returns:
        dict: Meta schema specifying rules for ygg type schema. This includes
            all original JSON schema rules with the addition of types and
            property definitions.

    Raises:
        RuntimeError: If the file already exists and overwrite is False.

    """
    if (not overwrite) and os.path.isfile(_metaschema_fname):
        raise RuntimeError("Metaschema file already exists.")
    out = copy.deepcopy(_base_validator.META_SCHEMA)
    out['title'] = "Ygg meta-schema for data type schemas"
    # Lower versions have a differing draft4
    if _jsonschema_ver_maj < 3:
        for x in ['minItems', 'uniqueItems']:
            if x in out['properties']['enum']:
                del out['properties']['enum'][x]
    # TODO: Replace schema with a link to the metaschema in the documentation
    # del out['$schema']
    # Add properties
    for k, v in get_registered_properties().items():
        if v.schema is not None:
            assert (k not in out['properties'])
            out['properties'][k] = v.schema
    # Add types
    for k, v in sorted(get_registered_types().items()):
        if k not in out['definitions']['simpleTypes']['enum']:
            out['definitions']['simpleTypes']['enum'].append(k)
        for p in v.properties:
            assert (p in out['properties'])
    # Convert to unicode if python 2
    if backwards.PY2:  # pragma: Python 2
        out = backwards.as_unicode(out,
                                   recurse=True,
                                   convert_types=(str, ),
                                   allow_pass=True)
    # Print
    print('Created metaschema')
    pprint.pprint(out)
    # Save it to a file
    with open(_metaschema_fname, 'w') as fd:
        encode_json(out, fd)
    return out
Exemple #3
0
def test_get_registered_properties():
    r"""Test get_registered_properties."""
    assert (properties.get_registered_properties())
Exemple #4
0
from yggdrasil.tests import (assert_raises, assert_equal, assert_not_equal)
from yggdrasil.metaschema import properties, get_metaschema, _base_validator
from yggdrasil.metaschema.properties.MetaschemaProperty import MetaschemaProperty

existing = properties.get_registered_properties()
non_existant = 'invalid_xyz123'
existing_class = list(existing.keys())[0]
existing_validator = non_existant
assert (non_existant not in existing)
assert (non_existant not in _base_validator.VALIDATORS)
for k, v in _base_validator.VALIDATORS.items():
    if k not in existing:
        existing_validator = k
        break
else:  # pragma: debug
    # Not sure how this would happen, but guarantee it dosn't do it silently
    raise Exception('Could not locate unregistered jsonschema property.')


def test_register_metaschema_property():
    r"""Test errors in register_metaschema_property."""
    # Error when property class already registered
    args = ('ReplacementClassSchema', (MetaschemaProperty, ), {
        'name': existing_class
    })
    assert_raises(ValueError, type, *args)
    # Error when replacement class has schema
    args = ('ReplacementClassSchema', (MetaschemaProperty, ), {
        'name': existing_validator,
        'schema': {}
    })