Skip to content

Commit bfb72ae

Browse files
authored
Merge pull request #47 from cwacek/fix/17-permit-multiple-types
feature: Permit an array to be provided for 'type'. Fixes #17
2 parents ad1ce37 + 4a492df commit bfb72ae

File tree

2 files changed

+51
-2
lines changed

2 files changed

+51
-2
lines changed

python_jsonschema_objects/classbuilder.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ def __new__(cls, **props):
145145
else: # We got nothing
146146
raise validators.ValidationError(
147147
"Unable to instantiate any valid types: \n"
148-
"\n".join("{0}: {1}".format(k, e) for k, e in validation_errors)
148+
"".join("{0}: {1}\n".format(k, e) for k, e in validation_errors)
149149
)
150150

151151
return obj
@@ -314,7 +314,7 @@ def __call__(self, *a, **kw):
314314
else: # We got nothing
315315
raise validators.ValidationError(
316316
"Unable to instantiate any valid types: \n"
317-
"\n".join("{0}: {1}".format(k, e) for k, e in validation_errors)
317+
"".join("{0}: {1}\n".format(k, e) for k, e in validation_errors)
318318
)
319319

320320

@@ -474,6 +474,18 @@ def _construct(self, uri, clsdata, parent=(ProtocolBase,)):
474474
**clsdata_copy)
475475
return self.resolved[uri]
476476

477+
elif isinstance(clsdata.get('type'), list):
478+
types = []
479+
for i, item_detail in enumerate(clsdata['type']):
480+
subdata = {k: v for k, v in six.iteritems(clsdata) if k != 'type'}
481+
subdata['type'] = item_detail
482+
types.append(self._build_literal(
483+
uri + "_%s" % i,
484+
subdata))
485+
486+
self.resolved[uri] = TypeProxy(types)
487+
return self.resolved[uri]
488+
477489
elif (clsdata.get('type', None) == 'object' or
478490
clsdata.get('properties', None) is not None or
479491
clsdata.get('additionalProperties', False)):
@@ -770,6 +782,10 @@ def setprop(self, val):
770782
val = info['type'](**util.coerce_for_expansion(val))
771783

772784
val.validate()
785+
786+
elif isinstance(info['type'], TypeProxy):
787+
val = info['type'](val)
788+
773789
elif info['type'] is None:
774790
# This is the null value
775791
if val is not None:

test/test_regression_17.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import pytest
2+
3+
import python_jsonschema_objects as pjo
4+
5+
6+
@pytest.fixture
7+
def test_class():
8+
schema = {
9+
'title': 'Example',
10+
'properties': {
11+
"claimed_by": {
12+
"id": "claimed",
13+
"type": ["string", "integer", "null"],
14+
"description": "Robots Only. The human agent that has claimed this robot.",
15+
"required": False
16+
},
17+
}
18+
}
19+
20+
builder = pjo.ObjectBuilder(schema)
21+
ns = builder.build_classes()
22+
return ns
23+
24+
25+
@pytest.mark.parametrize('value', [
26+
"Hi", 4, None])
27+
def test_properties_can_have_multiple_types(test_class, value):
28+
test_class.Example(claimed_by=value)
29+
30+
@pytest.mark.parametrize('value', [2.4])
31+
def test_multiply_typed_properties_still_validate(test_class, value):
32+
with pytest.raises(pjo.ValidationError):
33+
test_class.Example(claimed_by=value)

0 commit comments

Comments
 (0)