Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rebuild include argument #143

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
39 changes: 12 additions & 27 deletions pykwalify/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,17 @@ def __init__(self, source_file=None, schema_files=None, source_data=None, schema
if self.source is None:
log.debug(u"No source file loaded, trying source data variable")
self.source = source_data

if self.schema is None:
log.debug(u"No schema file loaded, trying schema data variable")
self.schema = schema_data

if isinstance(schema_data, list):
merged_schema = {}
for schema in schema_data:
merged_schema.update(schema)
self.schema = merged_schema
else:
self.schema = schema_data

# Test if anything was loaded
if self.source is None:
Expand Down Expand Up @@ -256,9 +264,9 @@ def _validate(self, value, rule, path, done):
return

log.debug(u" ? ValidateRule: %s", rule)
if rule.include_name is not None:
self._validate_include(value, rule, path, done=None)
elif rule.sequence is not None:
# if rule.include_name is not None:
# self._validate_include(value, rule, path, done=None)
if rule.sequence is not None:
self._validate_sequence(value, rule, path, done=None)
elif rule.mapping is not None or rule.allowempty_map:
self._validate_mapping(value, rule, path, done=None)
Expand Down Expand Up @@ -303,29 +311,6 @@ def _handle_func(self, value, rule, path, done=None):
if not found_method:
raise CoreError(u"Did not find method '{0}' in any loaded extension file".format(func))

def _validate_include(self, value, rule, path, done=None):
"""
"""
# TODO: It is difficult to get a good test case to trigger this if case
if rule.include_name is None:
self.errors.append(SchemaError.SchemaErrorEntry(
msg=u'Include name not valid',
path=path,
value=value.encode('unicode_escape')))
return
include_name = rule.include_name
partial_schema_rule = pykwalify.partial_schemas.get(include_name)
if not partial_schema_rule:
self.errors.append(SchemaError.SchemaErrorEntry(
msg=u"Cannot find partial schema with name '{include_name}'. Existing partial schemas: '{existing_schemas}'. Path: '{path}'",
path=path,
value=value,
include_name=include_name,
existing_schemas=", ".join(sorted(pykwalify.partial_schemas.keys()))))
return

self._validate(value, partial_schema_rule, path, done)

def _validate_sequence(self, value, rule, path, done=None):
"""
"""
Expand Down
49 changes: 38 additions & 11 deletions pykwalify/rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,9 +372,25 @@ def init(self, schema, path):

# Check if this item is a include, overwrite schema with include schema and continue to parse
if include:
log.debug(u"Found include tag...")
self.include_name = include
return
import pykwalify

partial_schema_rule = pykwalify.partial_schemas.get(include)

if not partial_schema_rule:
raise RuleError(
msg=u"Include key: {0} not defined in schema".format(include),
error_key=u"include.key.unknown",
path=path,
)

# schema = {key: value for (key, value) in (schema.items() + partial_schema_rule.schema.items())}
# schema = dict(schema.items() | partial_schema_rule.schema.items())
for k, v in partial_schema_rule.schema.items():
schema[k] = v

# log.debug(u"Found include tag...")
# self.include_name = include
# return

t = None
rule = self
Expand Down Expand Up @@ -419,6 +435,7 @@ def init(self, schema, path):
"format": self.init_format_value,
"func": self.init_func,
"ident": self.init_ident_value,
"include": self.init_include,
"length": self.init_length_value,
"map": self.init_mapping_value,
"mapping": self.init_mapping_value,
Expand All @@ -438,17 +455,24 @@ def init(self, schema, path):
"version": self.init_version,
}

# Do a initial pass of all keys to look for the schema tagg.
# If we are on the root rule, this check will not be done.
# If we are in any child rules, check all keys for any schema and
# raise error if we find any as schemas can only be defined at root level
if self.parent:
for k, v in schema.items():
if k.startswith("schema;"):
# Schema tag is only allowed on top level of data
log.debug(u"Found schema tag...")
raise RuleError(
msg=u"Schema is only allowed on top level of schema file",
error_key=u"schema.not.toplevel",
path=path,
)

for k, v in schema.items():
if k in func_mapping:
func_mapping[k](v, rule, path)
elif k.startswith("schema;"):
# Schema tag is only allowed on top level of data
log.debug(u"Found schema tag...")
raise RuleError(
msg=u"Schema is only allowed on top level of schema file",
error_key=u"schema.not.toplevel",
path=path,
)
else:
raise RuleError(
msg=u"Unknown key: {0} found".format(k),
Expand All @@ -460,6 +484,9 @@ def init(self, schema, path):

self.check_type_keywords(schema, rule, path)

def init_include(self, v, rule, path):
pass

def init_format_value(self, v, rule, path):
log.debug(u"Init format value : %s", path)

Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@
},
install_requires=[
'docopt>=0.6.2',
"ruamel.yaml>=0.16.0"
'ruamel.yaml>=0.16.0',
'python-dateutil>=2.8.0',
],
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*",
classifiers=[
# 'Development Status :: 1 - Planning',
# 'Development Status :: 2 - Pre-Alpha',
Expand Down
24 changes: 24 additions & 0 deletions tests/files/partial_schemas/10f.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
data:
point:
x: 3

schema:
type: map
mapping:
point:
mapping:
x:
required: true
include: coordinate_value
y:
required: true
include: coordinate_value

partial-files:
- schema;coordinate_value:
type: number

fail-exception-class: "SchemaError"
fail-validation-errors:
- "Cannot find required key 'y'. Path: '/point'"
11 changes: 0 additions & 11 deletions tests/files/partial_schemas/1s-partials.yaml

This file was deleted.

12 changes: 12 additions & 0 deletions tests/files/partial_schemas/1s-schema.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
type: seq
sequence:
- include: fooone

schema;fooone:
type: map
mapping:
foo:
type: str

schema;footwo:
type: map
mapping:
foo:
type: bool
16 changes: 0 additions & 16 deletions tests/files/partial_schemas/2s-partials.yaml

This file was deleted.

17 changes: 17 additions & 0 deletions tests/files/partial_schemas/2s-schema.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
type: seq
sequence:
- include: fooone

schema;foothree:
type: seq
sequence:
- type: bool

schema;footwo:
type: map
mapping:
bar:
include: foothree

schema;fooone:
type: map
mapping:
foo:
include: footwo
12 changes: 6 additions & 6 deletions tests/files/partial_schemas/4f-schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ type: seq
sequence:
- include: fooone

schema;fooone:
schema;foothree:
type: map
mapping:
foo:
include: footwo
bar:
type: str

schema;footwo:
type: seq
sequence:
- include: foothree

schema;foothree:
schema;fooone:
type: map
mapping:
bar:
type: str
foo:
include: footwo
8 changes: 4 additions & 4 deletions tests/files/partial_schemas/5f-schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ type: seq
sequence:
- include: fooone

schema;fooone:
schema;foothree:
type: seq
sequence:
- include: footwo
- type: str

schema;footwo:
type: seq
sequence:
- include: foothree

schema;foothree:
schema;fooone:
type: seq
sequence:
- type: str
- include: footwo
12 changes: 6 additions & 6 deletions tests/files/partial_schemas/6f-schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ mapping:
foo:
include: fooone

schema;fooone:
schema;foothree:
type: map
mapping:
bar:
include: footwo
ewq:
type: str

schema;footwo:
type: map
mapping:
qwe:
include: foothree

schema;foothree:
schema;fooone:
type: map
mapping:
ewq:
type: str
bar:
include: footwo
1 change: 1 addition & 0 deletions tests/files/partial_schemas/7s-schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mapping:
required: True
bar:
include: bar

schema;bar:
type: seq
required: True
Expand Down
Loading