Open AndreLouisCaron opened 11 years ago
So this is about a week old, but hopefully it might still be relevant for you. The problem with what you're doing is that a sequence node always requires a single child node. By calling SortedSequenceSchemaNode(missing=[])
, you are assigning the sequence 0 child nodes, hence the IndexError. The way you would accomplish this is through this code:
import colander
class SortedSequenceSchemaNode(colander.SchemaNode):
default = []
title = 'Sorted sequence'
schema_type = colander.Sequence
# children
stuff = colander.SchemaNode(colander.String())
@colander.deferred
def validator(self, kw):
sorting_key = kw.get('sorting_key', None)
def validate_sorted_sequence(node, cstruct):
# Check edge cases.
if cstruct is None or cstruct is colander.null:
return colander.null
if not list(cstruct):
raise colander.Invalid('Expecting a sequence, not %r.' % cstruct)
# Sort items in sequence.
return sorted(cstruct, key=sorting_key)
return validate_sorted_sequence
class TestSchema(colander.MappingSchema):
stuff = SortedSequenceSchemaNode(missing=[])
if __name__ == '__main__':
data = {'stuff': ['A', 'b', 'C', 'd']}
data = TestSchema().bind(sorting_key=unicode.lower).deserialize(data)
print data['stuff']
The notable piece of this new code, is that I add a child node called 'stuff' that has type colander.String
.
@jayd3e Are there any perceivable effects of adding the child node? For instance, if I use this to sort numbers, will it still work as is and sort numbers or will it do a lexical sort over strings?
If you are using it to sort numbers/characters, then would need to make that validator a preparer, as it wouldn't actually change key if its a validator, it would simply make sure that an exception isn't thrown. Right now, we don't support deferred preparers. I'm going to merge your pull request today that does this, so you can at least use master.
But to answer your question, with a preparer you could do both numerical sort or lexical sort.
If you are using it to sort numbers/characters, then would need to make that validator a preparer, as it wouldn't actually change key if its a validator, it would simply make sure that an exception isn't thrown. Right now, we don't support deferred preparers.
Yes I understand that now. That's how I ended up with the deferred preparer patch :-)
I'm following the
RangedIntSchemaNode
example under Subclassing SchemaNode and it works (provided you add aschema_type
class attribute), but I can't get it to work for sequences.For example:
When I execute this, I get
in
colander/__init__.py
, line 858:I'm using Colander 1.0a2.