Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2c25dc7

Browse files
committed
Initial commit
0 parents  commit 2c25dc7

4 files changed

Lines changed: 441 additions & 0 deletions

File tree

.gitignore

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
.DS_Store
2+
3+
*.pyc
4+
*.pyo
5+
6+
*.egg-info
7+
_build
8+
build
9+
dist
10+
MANIFEST
11+
12+
.coverage
13+
.coveragerc
14+
coverage
15+
htmlcov
16+
17+
_trial_temp
18+
19+
.tox

COPYING

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2011 Julian Berman
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is
8+
furnished to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in
11+
all copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE.

jsons.py

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
from __future__ import unicode_literals
2+
3+
import numbers
4+
import re
5+
import types
6+
7+
8+
_PYTYPES = {
9+
"array" : list, "boolean" : bool, "integer" : int,
10+
"null" : types.NoneType, "number" : numbers.Number,
11+
"object" : dict, "string" : unicode
12+
}
13+
14+
_PYTYPES["any"] = tuple(_PYTYPES.values())
15+
16+
17+
class SchemaError(Exception):
18+
pass
19+
20+
21+
class ValidationError(Exception):
22+
pass
23+
24+
25+
class Validator(object):
26+
27+
# required and dependencies are handled in validate_properties
28+
# exclusive Minium and Maximum are handled in validate_minimum
29+
SKIPPED = {
30+
"dependencies", "required", "exclusiveMinimum", "exclusiveMaximum"
31+
}
32+
33+
def is_valid(self, instance, schema):
34+
try:
35+
self.validate(instance, schema)
36+
return True
37+
except ValidationError:
38+
return False
39+
40+
def validate(self, instance, schema):
41+
for k, v in schema.iteritems():
42+
if k in self.SKIPPED:
43+
continue
44+
45+
validator = getattr(self, "validate_%s" % k, None)
46+
47+
if validator is None:
48+
raise SchemaError("'%s' is not a known schema property" % k)
49+
50+
validator(v, instance, schema)
51+
52+
def validate_type(self, types, instance, schema):
53+
types = _(types)
54+
55+
for type in types:
56+
if (
57+
isinstance(type, dict) and
58+
isinstance(instance, dict) and
59+
self.is_valid(instance, type)
60+
):
61+
return
62+
63+
elif isinstance(type, unicode):
64+
type = _PYTYPES.get(type)
65+
66+
if type is None:
67+
raise SchemaError("'%s' is not a known type" % type)
68+
69+
# isinstance(a_bool, int) will make us even sadder here, so
70+
# let's be even dirtier than we would otherwise be.
71+
72+
elif (
73+
isinstance(instance, type) and
74+
(not isinstance(instance, bool) or
75+
type is bool or types == ["any"])
76+
):
77+
return
78+
else:
79+
raise ValidationError("'%s' is not of type %s" % (instance, types))
80+
81+
def validate_properties(self, properties, instance, schema):
82+
for property, subschema in properties.iteritems():
83+
if property in instance:
84+
dependencies = _(subschema.get("dependencies", []))
85+
if isinstance(dependencies, dict):
86+
self.validate(instance, dependencies)
87+
else:
88+
missing = (d for d in dependencies if d not in instance)
89+
first = next(missing, None)
90+
if first is not None:
91+
raise ValidationError(
92+
"'%s' is a dependency of '%s'" % (first, property)
93+
)
94+
95+
self.validate(instance[property], subschema)
96+
elif subschema.get("required", False):
97+
raise ValidationError("'%s' is a required property" % property)
98+
99+
def validate_patternProperties(self, patternProperties, instance, schema):
100+
for pattern, subschema in patternProperties.iteritems():
101+
for k, v in instance.iteritems():
102+
if re.match(pattern, k):
103+
self.validate(v, subschema)
104+
105+
def validate_additionalProperties(self, aP, instance, schema):
106+
extras = instance.viewkeys() - schema.get("properties", {}).viewkeys()
107+
108+
if isinstance(aP, dict):
109+
for extra in extras:
110+
self.validate(instance[extra], aP)
111+
elif not aP and extras:
112+
raise ValidationError("Additional properties are not allowed")
113+
114+
def validate_items(self, items, instance, schema):
115+
if isinstance(items, dict):
116+
for item in instance:
117+
self.validate(item, items)
118+
else:
119+
for item, subschema in zip(instance, items):
120+
self.validate(item, subschema)
121+
122+
def validate_additionalItems(self, aI, instance, schema):
123+
if isinstance(aI, dict):
124+
for item in instance[len(schema):]:
125+
self.validate(item, aI)
126+
elif not aI and len(instance) > len(schema):
127+
raise ValidationError("Additional items are not allowed")
128+
129+
def validate_minimum(self, minimum, instance, schema):
130+
if schema.get("exclusiveMinimum", False):
131+
failed = instance <= minimum
132+
cmp = "less than or equal to"
133+
else:
134+
failed = instance < minimum
135+
cmp = "less than"
136+
137+
if failed:
138+
raise ValidationError(
139+
"%s is %s the minimum (%s)" % (instance, cmp, minimum)
140+
)
141+
142+
def validate_maximum(self, maximum, instance, schema):
143+
if schema.get("exclusiveMaximum", False):
144+
failed = instance >= maximum
145+
cmp = "greater than or equal to"
146+
else:
147+
failed = instance > maximum
148+
cmp = "greater than"
149+
150+
if failed:
151+
raise ValidationError(
152+
"%s is %s the maximum (%s)" % (instance, cmp, maximum)
153+
)
154+
155+
def validate_minItems(self, mI, instance, schema):
156+
if len(instance) < mI:
157+
raise ValidationError("'%s' is too short" % (instance,))
158+
159+
def validate_maxItems(self, mI, instance, schema):
160+
if len(instance) > mI:
161+
raise ValidationError("'%s' is too long" % (instance,))
162+
163+
def validate_minLength(self, mL, instance, schema):
164+
if len(instance) < mL:
165+
raise ValidationError("'%s' is too short" % (instance,))
166+
167+
def validate_maxLength(self, mL, instance, schema):
168+
if len(instance) > mL:
169+
raise ValidationError("'%s' is too long" % (instance,))
170+
171+
172+
def _(thing):
173+
if isinstance(thing, unicode):
174+
return [thing]
175+
return thing
176+
177+
178+
_default_validator = Validator()
179+
validate = _default_validator.validate

0 commit comments

Comments
 (0)