Skip to content

Commit

Permalink
Fixed a major bug in very nested *seq* schemas where if the schema ex…
Browse files Browse the repository at this point in the history
…pected another *seq* but the value was something else it would not raise it as a validation error.

This has now been fixed and now raises the proper error.
In the case of multiple items in a sequence block and any errors is raised from the children, it will not only track the children that did not validate and not all children.
NotSequenceError is no longer used as a mechanism but a proper SchemaError is not stores instead. Will be removed in the future.
Commented out test method test_validate_sequence until it can be refactored at a later time.
  • Loading branch information
Grokzen committed Jan 7, 2017
1 parent e2a86fc commit 031b438
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 11 deletions.
2 changes: 2 additions & 0 deletions docs/release-notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ Bug fixes:
- Fixed a bug with keyword *ident* when the rule value was verified to be a *boolean*. It now only accepts *boolean* values as expected.
- Fixed a bug where if *allowempty* was specefied in a mapping type inside a sequence type then it would not properly validate.
- Fixed a bug where loaded extensions would not allways work in complex & nested objects.
- Fixed a major bug in very nested *seq* schemas where if the schema expected another *seq* but the value was something else it would not raise it as a validation error.
This has now been fixed and now raises the proper error.

New features:

Expand Down
16 changes: 11 additions & 5 deletions pykwalify/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,12 @@ def _validate_sequence(self, value, rule, path, done=None):
if not isinstance(value, list):
if isinstance(value, str):
value = value.encode('unicode_escape')
raise NotSequenceError(u"Value: {0} is not of a sequence type".format(value))
self.errors.append(SchemaError.SchemaErrorEntry(
u"Value '{value}' is not a list. Value path: '{path}'",
path,
value,
))
return

# Handle 'func' argument on this sequence
self._handle_func(value, rule, path, done)
Expand Down Expand Up @@ -442,10 +447,11 @@ def _validate_sequence(self, value, rule, path, done=None):
elif rule.matching == "all":
log.debug(u" * Value: %s did not validate against all possible sequence schemas", value)

for i, _ in enumerate(ok_values):
for error in error_tracker[i]:
for e in error:
self.errors.append(e)
for i, is_ok in enumerate(ok_values):
if not is_ok:
for error in error_tracker[i]:
for e in error:
self.errors.append(e)

log.debug(u" * Core seq: validation recursivley done...")

Expand Down
17 changes: 17 additions & 0 deletions tests/files/fail/test_sequence.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,20 @@ errors:
# - "Value 'None' is not of type 'str'. Path: '/2'"
# :required_novalue : (line 3)[/2] value required but none.
# :type_unmatch : (line 5)[/4] '100': not a string.
---
name: fail-sequence-4
desc: Test that very deep nested sequences fail when schema expected sequence but value was something else
schema:
type: seq
sequence:
- type: seq
sequence:
- type: seq
sequence:
- type: seq
sequence:
- type: str
data:
- - - 1
errors:
- "Value '1' is not a list. Value path: '/0/0/0'"
15 changes: 9 additions & 6 deletions tests/test_core_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

from pykwalify.compat import unicode
from pykwalify.core import Core
from pykwalify.errors import NotSequenceError, CoreError
# from pykwalify.errors import NotSequenceError, CoreError
from pykwalify.errors import CoreError


class Rule(object):
Expand All @@ -18,11 +19,13 @@ def _remap_errors(c):
return [unicode(error) for error in c.errors]


def test_validate_sequence():
# If the type is set to sequence but value is int, it should raise NotSequenceError
with pytest.raises(NotSequenceError):
c = Core(source_data={}, schema_data={})
c._validate_sequence(123, Rule(sequence=['']), '', [])
# TODO: Refactor this becuase it no longer raises NotSequenceError but it now adds an error to the
# error stack and it should look for that one instead.
# def test_validate_sequence():
# # If the type is set to sequence but value is int, it should raise NotSequenceError
# with pytest.raises(NotSequenceError):
# c = Core(source_data={}, schema_data={})
# c._validate_sequence(123, Rule(sequence=['']), '', [])


def ec():
Expand Down

0 comments on commit 031b438

Please sign in to comment.