Skip to content

Commit 0b54c41

Browse files
authored
Merge pull request #61 from cwacek/feature/fix-array-handling
Fixes several issues handling arrays
2 parents aa4c915 + 03861cb commit 0b54c41

File tree

4 files changed

+63
-5
lines changed

4 files changed

+63
-5
lines changed

python_jsonschema_objects/classbuilder.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,11 @@ def setprop(self, val):
744744
instance = info['validator'](val)
745745
val = instance.validate()
746746

747+
elif util.safe_issubclass(info['type'], validators.ArrayValidator):
748+
# An array type may have already been converted into an ArrayValidator
749+
instance = info['type'](val)
750+
val = instance.validate()
751+
747752
elif getattr(info['type'], 'isLiteralClass', False) is True:
748753
if not isinstance(val, info['type']):
749754
validator = info['type'](val)

python_jsonschema_objects/util.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,12 @@ class ProtocolJSONEncoder(json.JSONEncoder):
4444

4545
def default(self, obj):
4646
from python_jsonschema_objects import classbuilder
47+
from python_jsonschema_objects import validators
4748

4849
if isinstance(obj, classbuilder.LiteralValue):
4950
return obj._value
51+
if isinstance(obj, validators.ArrayValidator):
52+
return obj.for_json()
5053
if isinstance(obj, classbuilder.ProtocolBase):
5154
props = {}
5255
for raw, trans in six.iteritems(obj.__prop_names__):

python_jsonschema_objects/validators.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,13 @@ def from_json(cls, jsonmsg):
186186
obj.validate()
187187
return obj
188188

189-
@classmethod
190189
def serialize(self):
191-
self.validate()
190+
d = self.validate()
192191
enc = util.ProtocolJSONEncoder()
193-
return enc.encode(self)
192+
return enc.encode(d)
193+
194+
def for_json(self):
195+
return self.validate()
194196

195197
def validate(self):
196198
converted = self.validate_items()
@@ -245,6 +247,7 @@ def validate_items(self):
245247
validator = registry(param)
246248
if validator is not None:
247249
validator(paramval, elem, typ)
250+
typed_elems.append(elem)
248251

249252
elif util.safe_issubclass(typ, classbuilder.LiteralValue):
250253
val = typ(elem)
@@ -313,6 +316,8 @@ def create(name, item_constraint=None, **addl_constraints):
313316
"Item constraint (position {0}) is not a schema".format(i))
314317
elif isinstance(item_constraint, classbuilder.TypeProxy):
315318
pass
319+
elif util.safe_issubclass(item_constraint, ArrayValidator):
320+
pass
316321
else:
317322
isdict = isinstance(item_constraint, (dict,))
318323
isklass = isinstance( item_constraint, type) and util.safe_issubclass(
@@ -368,8 +373,6 @@ def create(name, item_constraint=None, **addl_constraints):
368373

369374
item_constraint = classbuilder.TypeProxy(type_array)
370375

371-
372-
373376
props['__itemtype__'] = item_constraint
374377

375378
props.update(addl_constraints)

test/test_nested_arrays.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
2+
import pytest
3+
4+
from jsonschema import validate
5+
import python_jsonschema_objects as pjo
6+
import json
7+
import logging
8+
9+
10+
@pytest.fixture
11+
def nested_arrays():
12+
return {
13+
"title": 'example',
14+
"properties": {
15+
"foo": {
16+
"type": "array",
17+
"items": {
18+
"type": "array",
19+
'items': [
20+
{'type': 'number'},
21+
{'type': 'number'}
22+
]
23+
}
24+
}
25+
}
26+
27+
}
28+
29+
@pytest.fixture
30+
def instance():
31+
return {'foo': [[42, 44]]}
32+
33+
34+
def test_validates(nested_arrays, instance):
35+
validate(instance, nested_arrays)
36+
37+
38+
def test_nested_array_regression(nested_arrays, instance):
39+
logging.basicConfig(level=logging.DEBUG)
40+
logging.getLogger().setLevel(logging.DEBUG)
41+
builder = pjo.ObjectBuilder(nested_arrays)
42+
ns = builder.build_classes()
43+
44+
q = ns.Example.from_json(json.dumps(instance))
45+
46+
assert q.serialize() == '{"foo": [[42, 44]]}'
47+

0 commit comments

Comments
 (0)