1from jsonschema import _utils
2from jsonschema.compat import iteritems
3from jsonschema.exceptions import ValidationError
4
5
6def dependencies_draft3(validator, dependencies, instance, schema):
7    if not validator.is_type(instance, "object"):
8        return
9
10    for property, dependency in iteritems(dependencies):
11        if property not in instance:
12            continue
13
14        if validator.is_type(dependency, "object"):
15            for error in validator.descend(
16                instance, dependency, schema_path=property,
17            ):
18                yield error
19        elif validator.is_type(dependency, "string"):
20            if dependency not in instance:
21                yield ValidationError(
22                    "%r is a dependency of %r" % (dependency, property)
23                )
24        else:
25            for each in dependency:
26                if each not in instance:
27                    message = "%r is a dependency of %r"
28                    yield ValidationError(message % (each, property))
29
30
31def disallow_draft3(validator, disallow, instance, schema):
32    for disallowed in _utils.ensure_list(disallow):
33        if validator.is_valid(instance, {"type": [disallowed]}):
34            yield ValidationError(
35                "%r is disallowed for %r" % (disallowed, instance)
36            )
37
38
39def extends_draft3(validator, extends, instance, schema):
40    if validator.is_type(extends, "object"):
41        for error in validator.descend(instance, extends):
42            yield error
43        return
44    for index, subschema in enumerate(extends):
45        for error in validator.descend(instance, subschema, schema_path=index):
46            yield error
47
48
49def items_draft3_draft4(validator, items, instance, schema):
50    if not validator.is_type(instance, "array"):
51        return
52
53    if validator.is_type(items, "object"):
54        for index, item in enumerate(instance):
55            for error in validator.descend(item, items, path=index):
56                yield error
57    else:
58        for (index, item), subschema in zip(enumerate(instance), items):
59            for error in validator.descend(
60                item, subschema, path=index, schema_path=index,
61            ):
62                yield error
63
64
65def minimum_draft3_draft4(validator, minimum, instance, schema):
66    if not validator.is_type(instance, "number"):
67        return
68
69    if schema.get("exclusiveMinimum", False):
70        failed = instance <= minimum
71        cmp = "less than or equal to"
72    else:
73        failed = instance < minimum
74        cmp = "less than"
75
76    if failed:
77        yield ValidationError(
78            "%r is %s the minimum of %r" % (instance, cmp, minimum)
79        )
80
81
82def maximum_draft3_draft4(validator, maximum, instance, schema):
83    if not validator.is_type(instance, "number"):
84        return
85
86    if schema.get("exclusiveMaximum", False):
87        failed = instance >= maximum
88        cmp = "greater than or equal to"
89    else:
90        failed = instance > maximum
91        cmp = "greater than"
92
93    if failed:
94        yield ValidationError(
95            "%r is %s the maximum of %r" % (instance, cmp, maximum)
96        )
97
98
99def properties_draft3(validator, properties, instance, schema):
100    if not validator.is_type(instance, "object"):
101        return
102
103    for property, subschema in iteritems(properties):
104        if property in instance:
105            for error in validator.descend(
106                instance[property],
107                subschema,
108                path=property,
109                schema_path=property,
110            ):
111                yield error
112        elif subschema.get("required", False):
113            error = ValidationError("%r is a required property" % property)
114            error._set(
115                validator="required",
116                validator_value=subschema["required"],
117                instance=instance,
118                schema=schema,
119            )
120            error.path.appendleft(property)
121            error.schema_path.extend([property, "required"])
122            yield error
123
124
125def type_draft3(validator, types, instance, schema):
126    types = _utils.ensure_list(types)
127
128    all_errors = []
129    for index, type in enumerate(types):
130        if validator.is_type(type, "object"):
131            errors = list(validator.descend(instance, type, schema_path=index))
132            if not errors:
133                return
134            all_errors.extend(errors)
135        else:
136            if validator.is_type(instance, type):
137                return
138    else:
139        yield ValidationError(
140            _utils.types_msg(instance, types), context=all_errors,
141        )
142