-
Notifications
You must be signed in to change notification settings - Fork 5
Open
Labels
bugSomething isn't workingSomething isn't working
Description
there is a commented/disabled doctest in validation.containers.SetWithKnownFields now (introduced by c3d08d3 ):
from flatland import Dict, Integer
from flatland.validation import SetWithKnownFields
schema = Dict.of(Integer.named('x'), Integer.named('y')).validated_by(SetWithKnownFields())
schema.policy = None
element = schema()
element.set({'x': 123})
assert element.validate() # assertion error, issue #25, FIXME! (1)
element.set({'x': 123, 'z': 789})
assert not element.validate() # no assertion error, but maybe due to #25 also. (2)
I did a bit of debugging, but I am not familiar enough with the code to fix it, so here is what I found out:
There's a problem in validate():
valid might get set to False early (when encountering the y == None value) and thus validate() will not be able to return True after that. This is why assertion (1) fails although the SetWithKnownFields validator returns True.
def validate(self, state=None, recurse=True):
if not recurse:
down = self._validate(state, True)
if down is Unevaluated:
self.valid = down
else:
self.valid = bool(down)
up = self._validate(state, False)
# an Unevaluated ascent validator does not override the results
# of descent validation
if up is not Unevaluated:
self.valid = bool(up)
return self.valid
valid = True
elements, seen, queue = [], set(), collections.deque([self])
# descend breadth first, skipping any branches that return All*
while queue:
element = queue.popleft()
if id(element) in seen:
continue
seen.add(id(element))
elements.append(element)
validated = element._validate(state, True)
if validated is Unevaluated:
element.valid = validated
else:
element.valid = bool(validated)
if valid:
valid &= validated # <<<<<<<<<<<<<<<<<< getting False here due to y == None
if validated is SkipAll or validated is SkipAllFalse:
continue
queue.extend(element.children)
# back up, visiting only the elements that weren't skipped above
for element in reversed(elements):
validated = element._validate(state, False) # <<< SetWithKnownFields gets called, validated = True
# an Unevaluated ascent validator does not override the results
# of descent validation
if validated is Unevaluated:
pass
elif element.valid:
element.valid = bool(validated)
if valid: # <<<<<<< as valid is already False, it stays False
valid &= validated
return bool(valid)
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working