Mercurial > hgrepos > Python > libs > data-schema
annotate data_schema/__init__.py @ 46:92ae1e882cef
Enhance pickling support
| author | Franz Glasner <f.glasner@feldmann-mg.com> |
|---|---|
| date | Wed, 02 Aug 2023 16:51:34 +0200 |
| parents | 8a560e0c3180 |
| children | e7f6fc454f84 |
| rev | line source |
|---|---|
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1 # -*- coding: utf-8 -*- |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
2 r""" |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
3 Object schema validation support. |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
4 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
5 Somewhat modelled after JSON schema. |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
6 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
7 .. seealso:: https://json-schema.org/understanding-json-schema/index.html |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
8 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
9 :Author: Franz Glasner <fzglas.hg@dom66.de> |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
10 :Copyright: \(c) 2023 Franz Glasner |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
11 :License: BSD 3-Clause "New" or "Revised" License. |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
12 See :ref:`LICENSE.txt <license>` for details. |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
13 :ID: @(#) $Header$ |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
14 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
15 """ |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
16 |
|
37
ef586378f79a
Prepare for development of v0.3: v0.3.dev1
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
34
diff
changeset
|
17 __version__ = "0.3.dev1" |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
18 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
19 __revision__ = "|VCSRevision|" |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
20 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
21 __date__ = "|VCSJustDate|" |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
22 |
|
16
2a9e7c4b717e
Problem severity now is also an enum
Franz Glasner <fzglas.hg@dom66.de>
parents:
15
diff
changeset
|
23 __all__ = ["SEVERITY", "ERRORS", "WARNINGS", |
|
17
65f937fb8de7
Put the computation of the default problem severity into a new public function
Franz Glasner <fzglas.hg@dom66.de>
parents:
16
diff
changeset
|
24 "problem_message", "problem_severity", |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
25 "ValidationProblem", "SchemaError", |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
26 "validate", |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
27 "log_problem_cause"] |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
28 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
29 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
30 import ast |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
31 import collections |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
32 import copy |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
33 import datetime |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
34 import enum |
|
44
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
35 import pickle |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
36 import re |
|
46
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
37 import sys |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
38 import urllib.parse |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
39 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
40 import rfc3986 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
41 |
|
28
db3491e1b590
Allow to customize the loading of the schema dict
Franz Glasner <fzglas.hg@dom66.de>
parents:
25
diff
changeset
|
42 try: |
|
db3491e1b590
Allow to customize the loading of the schema dict
Franz Glasner <fzglas.hg@dom66.de>
parents:
25
diff
changeset
|
43 from configmix.yaml import load as default_schema_loader |
|
db3491e1b590
Allow to customize the loading of the schema dict
Franz Glasner <fzglas.hg@dom66.de>
parents:
25
diff
changeset
|
44 except ImportError: |
|
db3491e1b590
Allow to customize the loading of the schema dict
Franz Glasner <fzglas.hg@dom66.de>
parents:
25
diff
changeset
|
45 default_schema_loader = None |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
46 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
47 from .util import get_data_stream |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
48 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
49 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
50 def NC_(ctx, msg): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
51 """Mimimum dummy translation support""" |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
52 return msg |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
53 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
54 |
|
16
2a9e7c4b717e
Problem severity now is also an enum
Franz Glasner <fzglas.hg@dom66.de>
parents:
15
diff
changeset
|
55 @enum.unique |
|
2a9e7c4b717e
Problem severity now is also an enum
Franz Glasner <fzglas.hg@dom66.de>
parents:
15
diff
changeset
|
56 class SEVERITY(enum.IntEnum): |
|
2a9e7c4b717e
Problem severity now is also an enum
Franz Glasner <fzglas.hg@dom66.de>
parents:
15
diff
changeset
|
57 INFO = 20 |
|
2a9e7c4b717e
Problem severity now is also an enum
Franz Glasner <fzglas.hg@dom66.de>
parents:
15
diff
changeset
|
58 WARNING = 30 |
|
2a9e7c4b717e
Problem severity now is also an enum
Franz Glasner <fzglas.hg@dom66.de>
parents:
15
diff
changeset
|
59 ERROR = 40 |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
60 |
|
44
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
61 def __reduce_ex__(self, protocol): |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
62 return (getattr, (self.__class__, self._name_)) |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
63 |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
64 |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
65 @enum.unique |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
66 class ERRORS(enum.Enum): |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
67 E10000 = NC_("schema-msg", "dict expected") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
68 E10001 = NC_("schema-msg", "list expected") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
69 E10002 = NC_("schema-msg", "string expected") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
70 E10003 = NC_("schema-msg", "dict key must be a string") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
71 E10004 = NC_("schema-msg", "additional key encountered") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
72 E10005 = NC_("schema-msg", "required key(s) missing") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
73 E10006 = NC_("schema-msg", "min string length encountered") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
74 E10007 = NC_("schema-msg", "max string length exceeded") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
75 E10008 = NC_("schema-msg", "string value does not match the required RE pattern") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
76 E10009 = NC_("schema-msg", "string value does not validate") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
77 E10010 = NC_("schema-msg", "validation error") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
78 E10011 = NC_("schema-msg", "None/Null object expected") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
79 E10012 = NC_("schema-msg", "min list length encountered") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
80 E10013 = NC_("schema-msg", "max list length exceeded") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
81 E10014 = NC_("schema-msg", "tuple expected") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
82 E10015 = NC_("schema-msg", "min tuple length encountered") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
83 E10016 = NC_("schema-msg", "max tuple length exceeded") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
84 E10017 = NC_("schema-msg", "additional items in tuple not allowed") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
85 E10018 = NC_("schema-msg", "object is not empty") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
86 E10019 = NC_("schema-msg", "more than one match in `one-of' detected") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
87 E10020 = NC_("schema-msg", "int expected") |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
88 E10021 = NC_("schema-msg", "int value lower than min-value") |
|
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
89 E10022 = NC_("schema-msg", "int value greater than max-value") |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
90 E10023 = NC_("schema-msg", "float expected") |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
91 E10024 = NC_("schema-msg", "float value lower than min-value") |
|
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
92 E10025 = NC_("schema-msg", "float value greater than max-value") |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
93 E10026 = NC_("schema-msg", "boolean value expected") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
94 E10027 = NC_("schema-msg", "boolean true expected") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
95 E10028 = NC_("schema-msg", "boolean false expected") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
96 E10029 = NC_("schema-msg", "`not' expected problems but got none") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
97 E10030 = NC_("schema-msg", "numeric type (int or float) expected") |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
98 E10031 = NC_("schema-msg", "numeric value lower than min-value") |
|
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
99 E10032 = NC_("schema-msg", "numeric value greater than max-value") |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
100 E10033 = NC_("schema-msg", "a plain scalar value expected") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
101 E10034 = NC_("schema-msg", "dict key does not match required schema") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
102 E10035 = NC_("schema-msg", "binary data expected") |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
103 E10036 = NC_("schema-msg", "length of binary data lower than min-value") |
|
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
104 E10037 = NC_("schema-msg", "length of binary data exceeds max-value") |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
105 E10038 = NC_("schema-msg", "a set is expected") |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
106 E10039 = NC_("schema-msg", "length of set lower than min-length") |
|
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
107 E10040 = NC_("schema-msg", "length of set greater than max-length") |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
108 E10041 = NC_("schema-msg", "timestamp expected") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
109 E10042 = NC_("schema-msg", "value of timestamp does not validate") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
110 E10043 = NC_("schema-msg", "enumerated string value expected but not found") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
111 E10044 = NC_("schema-msg", "referenced object doest not exist") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
112 E10045 = NC_("schema-msg", "key is not contained in referenced object") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
113 E10046 = NC_("schema-msg", "referenced object is not a container") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
114 E10047 = NC_("schema-msg", "binary data does not match the required RE pattern") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
115 E10048 = NC_("schema-msg", "enumerated integer value expected but not found") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
116 E10049 = NC_("schema-msg", "enumerated number value expected but not found") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
117 E10050 = NC_("schema-msg", "min dict length encountered") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
118 E10051 = NC_("schema-msg", "max dict length exceeded") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
119 E10052 = NC_("schema-msg", "index constraint violated") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
120 E10053 = NC_("schema-msg", "`one-of' failed") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
121 E10054 = NC_("schema-msg", "failing `one-of' item") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
122 E10055 = NC_("schema-msg", "`any-of' failed") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
123 E10056 = NC_("schema-msg", "failing `any-of' item") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
124 E10057 = NC_("schema-msg", "`all-of' failed") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
125 E10058 = NC_("schema-msg", "failing `all-of' item") |
|
38
5a2fba996773
Implement a "forbidden" schema field for dicts
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
37
diff
changeset
|
126 E10059 = NC_("schema-msg", "forbidden key detected") |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
127 |
|
44
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
128 def __reduce_ex__(self, protocol): |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
129 return (getattr, (self.__class__, self._name_)) |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
130 |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
131 |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
132 @enum.unique |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
133 class WARNINGS(enum.Enum): |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
134 W80000 = NC_("schema-msg", "duplicate dict key") |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
135 |
|
44
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
136 def __reduce_ex__(self, protocol): |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
137 return (getattr, (self.__class__, self._name_)) |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
138 |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
139 |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
140 # Check some invariants at import time |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
141 for e in ERRORS.__members__: |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
142 assert e.startswith('E'), "ERROR code `{}' shall start with letter `E'".format(e) |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
143 assert 10000 <= int(e[1:], 10) < 80000, "Invalid ERROR code number in `{}'".format(e) |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
144 for w in WARNINGS.__members__: |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
145 assert w.startswith('W'), "WARNING code `{}' must start with letter `W'".format(w) |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
146 assert 80000 <= int(w[1:], 10), "Invalid WARNING code number in `{}'".format(w) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
147 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
148 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
149 TYPE_RE = type(re.compile(r"\A.+\Z")) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
150 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
151 SCHEMA_REF_KEY = "$ref" |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
152 """Key name for schema references (like a symlink within a schema)""" |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
153 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
154 SCHEMA_PATH_ROOT = "$root" |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
155 """URI path to the root schema""" |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
156 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
157 SCHEMA_PATH_SELF = "$self" |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
158 """URI path to the current schema""" |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
159 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
160 |
|
46
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
161 class _SENTINELType(object): |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
162 |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
163 @staticmethod |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
164 def _get_single(module, name): |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
165 return getattr(sys.modules[module], name) |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
166 |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
167 def __reduce_ex__(self, proto): |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
168 """Make sure the _SENTINEL is ever only instantiated as singleton""" |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
169 return (_SENTINELType._get_single, (self.__module__, "_SENTINEL")) |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
170 |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
171 |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
172 _SENTINEL = _SENTINELType() |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
173 |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
174 |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
175 def problem_message(pr): |
|
17
65f937fb8de7
Put the computation of the default problem severity into a new public function
Franz Glasner <fzglas.hg@dom66.de>
parents:
16
diff
changeset
|
176 """ |
|
65f937fb8de7
Put the computation of the default problem severity into a new public function
Franz Glasner <fzglas.hg@dom66.de>
parents:
16
diff
changeset
|
177 |
|
65f937fb8de7
Put the computation of the default problem severity into a new public function
Franz Glasner <fzglas.hg@dom66.de>
parents:
16
diff
changeset
|
178 :raises KeyError: the code in `pr` does not refer to |
|
65f937fb8de7
Put the computation of the default problem severity into a new public function
Franz Glasner <fzglas.hg@dom66.de>
parents:
16
diff
changeset
|
179 :class:`.ERRORS` or `.WARNINGS` |
|
65f937fb8de7
Put the computation of the default problem severity into a new public function
Franz Glasner <fzglas.hg@dom66.de>
parents:
16
diff
changeset
|
180 |
|
65f937fb8de7
Put the computation of the default problem severity into a new public function
Franz Glasner <fzglas.hg@dom66.de>
parents:
16
diff
changeset
|
181 """ |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
182 if isinstance(pr, ValidationProblem): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
183 code = getattr(pr, "code", None) |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
184 elif isinstance(pr, (ERRORS, WARNINGS)): |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
185 code = pr |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
186 else: |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
187 if pr >= 80000: |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
188 code = WARNINGS["W" + str(pr)] |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
189 else: |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
190 code = ERRORS["E" + str(pr)] |
|
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
191 return code.value |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
192 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
193 |
|
17
65f937fb8de7
Put the computation of the default problem severity into a new public function
Franz Glasner <fzglas.hg@dom66.de>
parents:
16
diff
changeset
|
194 def problem_severity(pr): |
|
65f937fb8de7
Put the computation of the default problem severity into a new public function
Franz Glasner <fzglas.hg@dom66.de>
parents:
16
diff
changeset
|
195 """Get the default severity for error or warning code `pr` |
|
65f937fb8de7
Put the computation of the default problem severity into a new public function
Franz Glasner <fzglas.hg@dom66.de>
parents:
16
diff
changeset
|
196 |
|
65f937fb8de7
Put the computation of the default problem severity into a new public function
Franz Glasner <fzglas.hg@dom66.de>
parents:
16
diff
changeset
|
197 :raises TypeError: if `pr` is not in :class:`.ERRORS` or :class:`.WARNINGS` |
|
65f937fb8de7
Put the computation of the default problem severity into a new public function
Franz Glasner <fzglas.hg@dom66.de>
parents:
16
diff
changeset
|
198 |
|
65f937fb8de7
Put the computation of the default problem severity into a new public function
Franz Glasner <fzglas.hg@dom66.de>
parents:
16
diff
changeset
|
199 """ |
|
65f937fb8de7
Put the computation of the default problem severity into a new public function
Franz Glasner <fzglas.hg@dom66.de>
parents:
16
diff
changeset
|
200 if pr in ERRORS: |
|
65f937fb8de7
Put the computation of the default problem severity into a new public function
Franz Glasner <fzglas.hg@dom66.de>
parents:
16
diff
changeset
|
201 return SEVERITY.ERROR |
|
65f937fb8de7
Put the computation of the default problem severity into a new public function
Franz Glasner <fzglas.hg@dom66.de>
parents:
16
diff
changeset
|
202 if pr in WARNINGS: |
|
65f937fb8de7
Put the computation of the default problem severity into a new public function
Franz Glasner <fzglas.hg@dom66.de>
parents:
16
diff
changeset
|
203 return SEVERITY.WARNING |
|
65f937fb8de7
Put the computation of the default problem severity into a new public function
Franz Glasner <fzglas.hg@dom66.de>
parents:
16
diff
changeset
|
204 raise TypeError("invalid error or warning code: %r" % (pr, )) |
|
65f937fb8de7
Put the computation of the default problem severity into a new public function
Franz Glasner <fzglas.hg@dom66.de>
parents:
16
diff
changeset
|
205 |
|
65f937fb8de7
Put the computation of the default problem severity into a new public function
Franz Glasner <fzglas.hg@dom66.de>
parents:
16
diff
changeset
|
206 |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
207 class ValidationProblem(object): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
208 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
209 __slots__ = ("code", "severity", "hint", "context", "cause", "index") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
210 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
211 def __init__(self, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
212 code=None, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
213 severity=None, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
214 hint=None, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
215 context=None, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
216 cause=None, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
217 index=None): |
|
14
cfb97c7c9e5b
Simplify ctor of ValidationProblem somewhat
Franz Glasner <fzglas.hg@dom66.de>
parents:
13
diff
changeset
|
218 if code is None: |
|
15
696b83f29363
Use enum props when printing validation problems
Franz Glasner <fzglas.hg@dom66.de>
parents:
14
diff
changeset
|
219 raise TypeError("`code' must be given") |
|
14
cfb97c7c9e5b
Simplify ctor of ValidationProblem somewhat
Franz Glasner <fzglas.hg@dom66.de>
parents:
13
diff
changeset
|
220 # check validity |
|
cfb97c7c9e5b
Simplify ctor of ValidationProblem somewhat
Franz Glasner <fzglas.hg@dom66.de>
parents:
13
diff
changeset
|
221 if code not in ERRORS and code not in WARNINGS: |
|
cfb97c7c9e5b
Simplify ctor of ValidationProblem somewhat
Franz Glasner <fzglas.hg@dom66.de>
parents:
13
diff
changeset
|
222 raise ValueError( |
|
cfb97c7c9e5b
Simplify ctor of ValidationProblem somewhat
Franz Glasner <fzglas.hg@dom66.de>
parents:
13
diff
changeset
|
223 "unknown validation error code: {}".format(code)) |
|
cfb97c7c9e5b
Simplify ctor of ValidationProblem somewhat
Franz Glasner <fzglas.hg@dom66.de>
parents:
13
diff
changeset
|
224 self.code = code |
|
cfb97c7c9e5b
Simplify ctor of ValidationProblem somewhat
Franz Glasner <fzglas.hg@dom66.de>
parents:
13
diff
changeset
|
225 if severity is None: |
|
17
65f937fb8de7
Put the computation of the default problem severity into a new public function
Franz Glasner <fzglas.hg@dom66.de>
parents:
16
diff
changeset
|
226 self.severity = problem_severity(code) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
227 else: |
|
16
2a9e7c4b717e
Problem severity now is also an enum
Franz Glasner <fzglas.hg@dom66.de>
parents:
15
diff
changeset
|
228 if not isinstance(severity, SEVERITY): |
|
2a9e7c4b717e
Problem severity now is also an enum
Franz Glasner <fzglas.hg@dom66.de>
parents:
15
diff
changeset
|
229 raise TypeError("invalid type for `severity'") |
|
14
cfb97c7c9e5b
Simplify ctor of ValidationProblem somewhat
Franz Glasner <fzglas.hg@dom66.de>
parents:
13
diff
changeset
|
230 self.severity = severity |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
231 self.hint = hint |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
232 self.context = context |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
233 if cause: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
234 if not isinstance(cause, (list, tuple, set, frozenset)): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
235 cause = (cause, ) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
236 for c in cause: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
237 if not isinstance(c, ValidationProblem): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
238 raise SchemaError( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
239 "can only nest other `ValidationProblem' instances") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
240 self.cause = cause |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
241 self.index = index |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
242 |
|
44
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
243 def __eq__(self, other): |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
244 if not isinstance(other, ValidationProblem): |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
245 return NotImplemented |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
246 return ((self.code == other.code) |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
247 and (self.severity == other.severity) |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
248 and (self.hint == other.hint) |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
249 and (self.context == other.context) |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
250 and (self.cause == other.cause) |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
251 and (self.index == other.index)) |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
252 |
|
45
8a560e0c3180
Implement __ne__ also where __eq__ is implemented
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
44
diff
changeset
|
253 def __ne__(self, other): |
|
8a560e0c3180
Implement __ne__ also where __eq__ is implemented
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
44
diff
changeset
|
254 # |
|
8a560e0c3180
Implement __ne__ also where __eq__ is implemented
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
44
diff
changeset
|
255 # While the default in Python3 is sensible implementing is recommended |
|
8a560e0c3180
Implement __ne__ also where __eq__ is implemented
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
44
diff
changeset
|
256 # when a built-in __eq__ is overwritten (Raymond Hettinger). |
|
8a560e0c3180
Implement __ne__ also where __eq__ is implemented
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
44
diff
changeset
|
257 # |
|
8a560e0c3180
Implement __ne__ also where __eq__ is implemented
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
44
diff
changeset
|
258 # Do not use not self == other because NotImplemented is not handled |
|
8a560e0c3180
Implement __ne__ also where __eq__ is implemented
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
44
diff
changeset
|
259 # properly in some early Python versions (including Py2). |
|
8a560e0c3180
Implement __ne__ also where __eq__ is implemented
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
44
diff
changeset
|
260 # |
|
8a560e0c3180
Implement __ne__ also where __eq__ is implemented
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
44
diff
changeset
|
261 equal = self.__eq__(other) |
|
8a560e0c3180
Implement __ne__ also where __eq__ is implemented
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
44
diff
changeset
|
262 return NotImplemented if equal is NotImplemented else not equal |
|
8a560e0c3180
Implement __ne__ also where __eq__ is implemented
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
44
diff
changeset
|
263 |
|
44
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
264 def __getstate__(self): |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
265 return (1, self.code, self.severity, self.hint, self.context, |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
266 self.cause, self.index) |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
267 |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
268 def __setstate__(self, state): |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
269 ver = state[0] |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
270 if ver == 1: |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
271 _dummy, self.code, self.severity, self.hint, self.context, self.cause, self.index = state |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
272 else: |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
273 raise pickle.UnpicklingError( |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
274 "Unsupported pickle version for ValidationProblem: %d" % (ver,)) |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
275 |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
276 def __repr__(self): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
277 try: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
278 msg = " (" + problem_message(self) + ")" |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
279 except LookupError: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
280 msg = "" |
|
30
2e7c08c356ee
Test the the ValidationProblem's str() and repr()
Franz Glasner <fzglas.hg@dom66.de>
parents:
29
diff
changeset
|
281 if self.context is not None: |
|
2e7c08c356ee
Test the the ValidationProblem's str() and repr()
Franz Glasner <fzglas.hg@dom66.de>
parents:
29
diff
changeset
|
282 context_depth = self.context.depth |
|
2e7c08c356ee
Test the the ValidationProblem's str() and repr()
Franz Glasner <fzglas.hg@dom66.de>
parents:
29
diff
changeset
|
283 else: |
|
2e7c08c356ee
Test the the ValidationProblem's str() and repr()
Franz Glasner <fzglas.hg@dom66.de>
parents:
29
diff
changeset
|
284 context_depth = None |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
285 if self.index is None: |
|
16
2a9e7c4b717e
Problem severity now is also an enum
Franz Glasner <fzglas.hg@dom66.de>
parents:
15
diff
changeset
|
286 return "ValidationProblem(code={}{}, severity={}, hint={}, context=[depth={}]{})".format( |
|
30
2e7c08c356ee
Test the the ValidationProblem's str() and repr()
Franz Glasner <fzglas.hg@dom66.de>
parents:
29
diff
changeset
|
287 self.code.name, msg, self.severity.name, self.hint, context_depth, self.context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
288 else: |
|
16
2a9e7c4b717e
Problem severity now is also an enum
Franz Glasner <fzglas.hg@dom66.de>
parents:
15
diff
changeset
|
289 return "ValidationProblem(code={}{}, severity={}, hint={}, context=[depth={}]{}, index={})".format( |
|
30
2e7c08c356ee
Test the the ValidationProblem's str() and repr()
Franz Glasner <fzglas.hg@dom66.de>
parents:
29
diff
changeset
|
290 self.code.name, msg, self.severity.name, self.hint, context_depth, self.context, self.index) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
291 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
292 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
293 class SchemaError(Exception): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
294 """An error within the schema itself""" |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
295 pass |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
296 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
297 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
298 ValidationSettings = collections.namedtuple( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
299 "ValidationSettings", |
|
29
68286d27f27d
FIX: Allow customization of the data stream loader (get_data_stream())
Franz Glasner <fzglas.hg@dom66.de>
parents:
28
diff
changeset
|
300 ["skip_keys", "break_on_keynames_problems", |
|
68286d27f27d
FIX: Allow customization of the data stream loader (get_data_stream())
Franz Glasner <fzglas.hg@dom66.de>
parents:
28
diff
changeset
|
301 "data_stream_loader", "schema_loader"]) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
302 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
303 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
304 class _Schema(dict): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
305 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
306 __slots__ = ("parent", "is_sub_root", "_schema_cache") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
307 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
308 def __init__(self, parent, is_sub_root, *args, **kwds): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
309 super().__init__(*args, **kwds) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
310 if parent is None or isinstance(parent, _Schema): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
311 self.parent = parent |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
312 else: |
|
25
fd2a40c3d87b
Enhance exception message
Franz Glasner <fzglas.hg@dom66.de>
parents:
23
diff
changeset
|
313 raise TypeError( |
|
fd2a40c3d87b
Enhance exception message
Franz Glasner <fzglas.hg@dom66.de>
parents:
23
diff
changeset
|
314 "`_Schema' or `None' expected for `parent` argument") |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
315 if parent is None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
316 self._schema_cache = {} |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
317 if not is_sub_root: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
318 raise ValueError( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
319 "the root schmema must be a sub-root (aka `$self') also") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
320 self.is_sub_root = True |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
321 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
322 self.is_sub_root = is_sub_root |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
323 |
|
44
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
324 def __reduce_ex__(self, proto): |
|
46
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
325 return super().__reduce_ex__(proto) |
|
44
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
326 |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
327 def __getstate__(self): |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
328 return (1, self.parent, self.is_sub_root) |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
329 |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
330 def __setstate__(self, state): |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
331 ver = state[0] |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
332 if ver == 1: |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
333 _dummy, self.parent, self.is_sub_root = state |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
334 if self.parent is None: |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
335 self._schema_cache = {} |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
336 else: |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
337 raise pickle.UnpicklingError( |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
338 "Unsupported pickle version for _Schema: %d" % (ver,)) |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
339 |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
340 @property |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
341 def ROOT(self): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
342 """Get the root schema""" |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
343 r = self |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
344 while r.parent is not None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
345 r = r.parent |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
346 return r |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
347 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
348 @property |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
349 def SELF(self): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
350 r = self |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
351 while not r.is_sub_root: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
352 r = r.parent |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
353 return r |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
354 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
355 def copy(self): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
356 return _Schema(self.parent, self.is_sub_root, self) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
357 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
358 def get_child(self, name, default=None): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
359 return self.ensure_child_schema(self.get(name, default)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
360 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
361 def ensure_child_schema(self, v): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
362 if v is None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
363 return None |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
364 elif isinstance(v, _Schema): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
365 return v |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
366 elif isinstance(v, dict): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
367 return _Schema(self, False, v) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
368 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
369 return v |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
370 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
371 def ensure_list_of_child_schemata(self, v): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
372 if isinstance(v, (list, tuple)): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
373 return [_Schema(self, False, i) for i in v] |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
374 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
375 return v |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
376 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
377 def __eq__(self, other): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
378 if not isinstance(other, _Schema): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
379 return NotImplemented |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
380 return (self.parent is other.parent |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
381 and bool(self.is_sub_root) == bool(other.is_sub_root) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
382 and dict(self) == dict(other)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
383 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
384 def __ne__(self, other): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
385 # |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
386 # While the default in Python3 is sensible implementing is recommended |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
387 # when a built-in __eq__ is overwritten (Raymond Hettinger). |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
388 # |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
389 # Do not use not self == other because NotImplemented is not handled |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
390 # properly in some early Python versions (including Py2). |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
391 # |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
392 equal = self.__eq__(other) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
393 return NotImplemented if equal is NotImplemented else not equal |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
394 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
395 def __copy__(self): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
396 return _Schema(self.parent, self.is_sub_root, self) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
397 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
398 def __deepcopy__(self, memo): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
399 return _Schema(self.parent, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
400 self.is_sub_root, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
401 copy.deepcopy(dict(self), memo)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
402 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
403 def __str__(self): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
404 return "<_Schema " + super().__str__() + ">" |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
405 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
406 def __repr__(self): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
407 return "<_Schema " + super().__repr__() + ">" |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
408 |
|
29
68286d27f27d
FIX: Allow customization of the data stream loader (get_data_stream())
Franz Glasner <fzglas.hg@dom66.de>
parents:
28
diff
changeset
|
409 def get_cached_schema(self, key, load_if_needed=True, |
|
68286d27f27d
FIX: Allow customization of the data stream loader (get_data_stream())
Franz Glasner <fzglas.hg@dom66.de>
parents:
28
diff
changeset
|
410 data_stream_loader=None, |
|
68286d27f27d
FIX: Allow customization of the data stream loader (get_data_stream())
Franz Glasner <fzglas.hg@dom66.de>
parents:
28
diff
changeset
|
411 schema_loader=None): |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
412 root = self.ROOT |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
413 s = root._schema_cache.get(key, None) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
414 if s is None and load_if_needed: |
|
28
db3491e1b590
Allow to customize the loading of the schema dict
Franz Glasner <fzglas.hg@dom66.de>
parents:
25
diff
changeset
|
415 if schema_loader is None: |
|
db3491e1b590
Allow to customize the loading of the schema dict
Franz Glasner <fzglas.hg@dom66.de>
parents:
25
diff
changeset
|
416 raise SchemaError("no schema loader available") |
|
29
68286d27f27d
FIX: Allow customization of the data stream loader (get_data_stream())
Franz Glasner <fzglas.hg@dom66.de>
parents:
28
diff
changeset
|
417 dsl = data_stream_loader or get_data_stream |
|
68286d27f27d
FIX: Allow customization of the data stream loader (get_data_stream())
Franz Glasner <fzglas.hg@dom66.de>
parents:
28
diff
changeset
|
418 with dsl(key) as schemastream: |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
419 # load schema a new `$self' (i.e. sub-root is True) |
|
28
db3491e1b590
Allow to customize the loading of the schema dict
Franz Glasner <fzglas.hg@dom66.de>
parents:
25
diff
changeset
|
420 s = _Schema(self, True, schema_loader(schemastream)) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
421 root._schema_cache[key] = s |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
422 return s |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
423 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
424 def add_cached_schema(self, key, schema): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
425 r = self.ROOT |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
426 assert isinstance(schema, _Schema) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
427 r._schema_cache[key] = schema |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
428 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
429 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
430 class Context(object): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
431 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
432 __slots__ = ("_parent", "_key", "_key_index", |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
433 "_index", |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
434 "root_object", "root_schema", |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
435 "_current_object", |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
436 "_settings") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
437 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
438 def __init__(self, parent, *, key=_SENTINEL, index=_SENTINEL, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
439 root_object=_SENTINEL, root_schema=_SENTINEL, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
440 current_object=_SENTINEL, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
441 settings=_SENTINEL, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
442 key_index=_SENTINEL): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
443 if parent is None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
444 if key is not _SENTINEL: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
445 raise TypeError("the root context may not have a key") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
446 if index is not _SENTINEL: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
447 raise TypeError("the root context may not have an index") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
448 if settings is _SENTINEL: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
449 raise TypeError("the root context must have settings") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
450 self.root_object = root_object |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
451 if current_object is _SENTINEL: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
452 current_object = root_object |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
453 self.root_schema = root_schema |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
454 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
455 if key is _SENTINEL and index is _SENTINEL: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
456 raise TypeError("one of `key` and `index` must be given in a non-root context") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
457 if root_object is not _SENTINEL: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
458 raise TypeError("non-root context may not have a root object") |
|
46
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
459 self.root_object = root_object |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
460 if root_schema is not _SENTINEL: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
461 raise TypeError("non-root context may not have a root schema") |
|
46
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
462 self.root_schema = root_schema |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
463 if key is not _SENTINEL and index is not _SENTINEL: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
464 raise ValueError("only one of `key` and `index` may be given in a context") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
465 if key_index is not _SENTINEL and key is _SENTINEL: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
466 raise ValueError("when having a `key_index` a `key` also must be given") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
467 self._parent = parent |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
468 self._key = key |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
469 self._key_index = key_index |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
470 self._index = index |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
471 self._current_object = current_object |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
472 self._settings = settings |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
473 |
|
44
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
474 def __getstate__(self): |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
475 return (1, self._parent, self._key, self._key_index, self._index, |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
476 self.root_object, self.root_schema, |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
477 self._current_object, self._settings) |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
478 |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
479 def __setstate__(self, state): |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
480 ver = state[0] |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
481 if ver == 1: |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
482 _dummy, self._parent, self._key, self._key_index, self._index, self.root_object, self.root_schema, self._current_object, self._settings = state |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
483 else: |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
484 raise pickle.UnpicklingError( |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
485 "Unsupported pickle version for _Context: %d" % (ver,)) |
|
ea8c2d01a9d9
Begin pickling support for ValidatenProblems, _Schema and Context
Franz Glasner <fzglas.hg@dom66.de>
parents:
40
diff
changeset
|
486 |
|
46
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
487 def __eq__(self, other): |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
488 if not isinstance(other, Context): |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
489 return NotImplemented |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
490 return ((self._parent == other._parent) |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
491 and (self._key == other._key) |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
492 and (self._key_index == other._key_index) |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
493 # XXX FIXME ??? |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
494 # and (self.root_object == other.root_object) |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
495 # and (self.root_schema == other.root_schema) |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
496 # and (self._current_object == other._current_object) |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
497 and (self._settings == other._settings) |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
498 ) |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
499 |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
500 def __ne__(self, other): |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
501 # |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
502 # While the default in Python3 is sensible implementing is recommended |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
503 # when a built-in __eq__ is overwritten (Raymond Hettinger). |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
504 # |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
505 # Do not use not self == other because NotImplemented is not handled |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
506 # properly in some early Python versions (including Py2). |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
507 # |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
508 equal = self.__eq__(other) |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
509 return NotImplemented if equal is NotImplemented else not equal |
|
92ae1e882cef
Enhance pickling support
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
45
diff
changeset
|
510 |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
511 @property |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
512 def parent(self): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
513 return self._parent |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
514 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
515 @property |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
516 def safe_parent(self): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
517 if self.is_root: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
518 raise TypeError("the root context has no parent") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
519 return self.parent |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
520 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
521 @property |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
522 def root(self): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
523 """Get the root context""" |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
524 ctx = self |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
525 while not ctx.is_root: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
526 ctx = ctx.parent |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
527 return ctx |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
528 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
529 @property |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
530 def is_root(self): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
531 return not bool(self.parent) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
532 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
533 @property |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
534 def key(self): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
535 if self._key is _SENTINEL: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
536 raise AttributeError("no `key' in Context") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
537 return self._key |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
538 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
539 @property |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
540 def index(self): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
541 if self._index is _SENTINEL: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
542 raise AttributeError("no `index' in Context") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
543 return self._index |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
544 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
545 @property |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
546 def key_index(self): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
547 if self._key_index is _SENTINEL: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
548 raise AttributeError("no `key_index' in Context") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
549 return self._key_index |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
550 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
551 @property |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
552 def current_object(self): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
553 if self._current_object is _SENTINEL: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
554 raise AttributeError("no `current_object' in Context") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
555 return self._current_object |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
556 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
557 @property |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
558 def settings(self): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
559 s = self._settings |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
560 return s if s is not _SENTINEL else self.parent.settings |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
561 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
562 @property |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
563 def depth(self): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
564 if self._key is _SENTINEL and self._index is _SENTINEL and self.is_root: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
565 return 0 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
566 n = 0 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
567 ctx = self |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
568 while not ctx.is_root: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
569 n += 1 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
570 ctx = ctx.parent |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
571 return n |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
572 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
573 def __str__(self): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
574 if self._key is _SENTINEL and self._index is _SENTINEL and self.is_root: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
575 return "<ROOT>" |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
576 chain = [] |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
577 ctx = self |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
578 while not ctx.is_root: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
579 if ctx._key is not _SENTINEL: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
580 chain.append(str(ctx.key)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
581 elif ctx._index is not _SENTINEL: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
582 chain.append("INDEX:{}".format(ctx.index)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
583 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
584 chain.append("") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
585 ctx = ctx.parent |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
586 chain.reverse() |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
587 return " / ".join(chain) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
588 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
589 def __repr__(self): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
590 return "<Context path=`{}'>".format(str(self)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
591 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
592 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
593 def _get_one_of(d, *keys, default=None, strict=True): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
594 """Get the first found key and its value of `keys` from dict `d`. |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
595 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
596 """ |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
597 for k in keys: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
598 v = d.get(k, _SENTINEL) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
599 if v is not _SENTINEL: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
600 if strict: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
601 # |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
602 # check that all no other key of `keys` besides of `k` is |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
603 # in `d` |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
604 # |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
605 other_keys = set(keys) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
606 other_keys.remove(k) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
607 for k2 in other_keys: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
608 if k2 in d: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
609 raise SchemaError("ambiguous key from: {}".format( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
610 ", ".join(keys))) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
611 return k, v |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
612 return None, default |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
613 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
614 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
615 def validate(obj, schema, **kwds): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
616 """Validate object `obj` against the *specific* schema `schema`. |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
617 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
618 Yields errors and warnings |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
619 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
620 """ |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
621 settings = { |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
622 "skip_keys": None, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
623 "break_on_keynames_problems": True, |
|
29
68286d27f27d
FIX: Allow customization of the data stream loader (get_data_stream())
Franz Glasner <fzglas.hg@dom66.de>
parents:
28
diff
changeset
|
624 "data_stream_loader": get_data_stream, |
|
28
db3491e1b590
Allow to customize the loading of the schema dict
Franz Glasner <fzglas.hg@dom66.de>
parents:
25
diff
changeset
|
625 "schema_loader": default_schema_loader |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
626 } |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
627 settings.update(kwds) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
628 if not isinstance(schema, _Schema): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
629 if not isinstance(schema, dict): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
630 raise SchemaError("Schema must be a dict-alike." |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
631 " Got: {!r}".format(schema)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
632 schema = _Schema(None, True, schema) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
633 context = Context(None, root_object=obj, root_schema=schema, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
634 settings=ValidationSettings(**settings)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
635 yield from _validate(obj, schema, context, is_root=True) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
636 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
637 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
638 def _validate(obj, schema, context, is_root=False): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
639 """Validate object `obj` against the *specific* schema `schema`. |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
640 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
641 Yields errors and warnings |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
642 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
643 """ |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
644 if not isinstance(schema, _Schema): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
645 raise SchemaError("Schema must be a `_Schema'." |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
646 " Got: {!r}. Context: {!s}".format(schema, context)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
647 # 1. Process "cond" or "match" |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
648 schema = process_schema_conditionals(schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
649 # 2. Process "$ref" schema references |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
650 schema = process_schema_references( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
651 schema, context, check_single_ref_key=not is_root) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
652 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
653 # 3. Real validation |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
654 |
|
31
271ec3abdfa3
Use "$type" as the schema's type specifier instead of "type".
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
30
diff
changeset
|
655 # check combinator shortcuts without "$type" indirection |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
656 combinator, combinator_schema = _get_one_of( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
657 schema, "not", "all-of", "any-of", "one-of") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
658 if combinator is None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
659 try: |
|
31
271ec3abdfa3
Use "$type" as the schema's type specifier instead of "type".
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
30
diff
changeset
|
660 t = schema["$type"] |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
661 except KeyError: |
|
31
271ec3abdfa3
Use "$type" as the schema's type specifier instead of "type".
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
30
diff
changeset
|
662 raise SchemaError("Schema has no `$type' key: {!r}." |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
663 " Context: {!s}".format(schema, context)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
664 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
665 # |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
666 # Construct a temporary schema with the proper indirection for |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
667 # the check below |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
668 # |
|
31
271ec3abdfa3
Use "$type" as the schema's type specifier instead of "type".
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
30
diff
changeset
|
669 t = {"$type": {combinator: combinator_schema}} |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
670 if combinator_schema is None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
671 raise SchemaError("a combinator requires a child") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
672 if callable(t): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
673 yield from t(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
674 elif t is None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
675 yield from validate_null(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
676 elif isinstance(t, dict): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
677 if len(t) != 1: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
678 raise SchemaError("type dict must be of length 1") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
679 # Check whether a shortcut is already seen above |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
680 if combinator is None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
681 combinator = list(t.keys())[0] |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
682 combinator_schema = t[combinator] |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
683 if combinator == "not": |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
684 yield from validate_not( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
685 obj, schema.ensure_child_schema(combinator_schema), context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
686 elif combinator == "all-of": |
|
23
413b344be2d1
Consistent naming of validation methods: all lowercase
Franz Glasner <fzglas.hg@dom66.de>
parents:
19
diff
changeset
|
687 yield from validate_all_of( |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
688 obj, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
689 schema.ensure_list_of_child_schemata(combinator_schema), |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
690 context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
691 elif combinator == "any-of": |
|
23
413b344be2d1
Consistent naming of validation methods: all lowercase
Franz Glasner <fzglas.hg@dom66.de>
parents:
19
diff
changeset
|
692 yield from validate_any_of( |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
693 obj, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
694 schema.ensure_list_of_child_schemata(combinator_schema), |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
695 context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
696 elif combinator == "one-of": |
|
23
413b344be2d1
Consistent naming of validation methods: all lowercase
Franz Glasner <fzglas.hg@dom66.de>
parents:
19
diff
changeset
|
697 yield from validate_one_of( |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
698 obj, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
699 schema.ensure_list_of_child_schemata(combinator_schema), |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
700 context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
701 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
702 raise SchemaError("unknown combinator: {}".format(combinator)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
703 elif isinstance(t, (list, tuple)): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
704 # a simple list is "any-of" |
|
23
413b344be2d1
Consistent naming of validation methods: all lowercase
Franz Glasner <fzglas.hg@dom66.de>
parents:
19
diff
changeset
|
705 yield from validate_any_of( |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
706 obj, schema.ensure_list_of_child_schemata(t), context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
707 elif t in ("dict", "map", "object"): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
708 yield from validate_dict(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
709 elif t in ("list", "array",): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
710 yield from validate_list(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
711 elif t in ("tuple", "record"): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
712 yield from validate_tuple(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
713 elif t in ("set", "frozenset"): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
714 yield from validate_set(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
715 elif t in ("string", "str"): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
716 yield from validate_str(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
717 elif t in ("deny", ): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
718 yield from validate_deny(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
719 elif t in ("accept", ): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
720 yield from validate_accept(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
721 elif t in ("none", "null", "nil"): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
722 yield from validate_null(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
723 elif t in ("empty", ): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
724 yield from validate_empty(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
725 elif t in ("integer", "int"): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
726 yield from validate_integer(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
727 elif t in ("float", "real", "double"): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
728 yield from validate_float(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
729 elif t in ("number", "num"): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
730 yield from validate_number(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
731 elif t in ("bool", "boolean"): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
732 yield from validate_bool(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
733 elif t in ("scalar", ): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
734 yield from validate_scalar(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
735 elif t in ("binary", ): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
736 yield from validate_binary(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
737 elif t in ("timestamp", "datetime"): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
738 yield from validate_timestamp(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
739 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
740 raise SchemaError("unknown type in schema: {}".format(t)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
741 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
742 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
743 def _is_in_skip_keys(key, skip_keys): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
744 if not skip_keys: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
745 return False |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
746 for sk in skip_keys: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
747 if isinstance(sk, str): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
748 if key == sk: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
749 return True |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
750 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
751 if sk.search(key): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
752 return True |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
753 return False |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
754 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
755 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
756 def _is_null_allowed_for_object(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
757 if obj is None and schema.get("nullable", False): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
758 return True |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
759 return False |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
760 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
761 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
762 def _validate_index_constraint(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
763 # No evaluation of index constraints for the root context |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
764 if context.is_root: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
765 return |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
766 try: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
767 index_constraints = schema["index-constraint"] |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
768 except KeyError: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
769 return # no constraints |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
770 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
771 if not isinstance(index_constraints, (list, tuple, set, frozenset)): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
772 index_constraints = [index_constraints] |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
773 if not index_constraints: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
774 return |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
775 parent = context.safe_parent |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
776 try: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
777 effective_index = context.index |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
778 except AttributeError: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
779 try: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
780 effective_index = context.key_index |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
781 except AttributeError: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
782 raise SchemaError("parent container has no usable index") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
783 for idx in index_constraints: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
784 if idx < 0: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
785 idx = len(parent.current_object) + idx |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
786 if idx == effective_index: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
787 break |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
788 else: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
789 yield ValidationProblem(code=ERRORS.E10052, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
790 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
791 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
792 def validate_dict(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
793 if _is_null_allowed_for_object(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
794 return |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
795 if not isinstance(obj, dict): |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
796 yield ValidationProblem(code=ERRORS.E10000, hint="got: {}".format(type(obj).__name__), context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
797 return |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
798 yield from _validate_index_constraint(obj, schema, context) |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
799 minlen = schema.get("min-length", None) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
800 if minlen: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
801 if len(obj) < minlen: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
802 yield ValidationProblem(code=ERRORS.E10050, hint=obj, context=context) |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
803 maxlen = schema.get("max-length", None) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
804 if maxlen is not None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
805 if len(obj) > maxlen: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
806 yield ValidationProblem(code=ERRORS.E10051, hint=obj, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
807 schema_keys = schema.get("keys", {}) if schema else {} |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
808 seen_keys = set() |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
809 schema_keynames = schema.get_child("key-names", None) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
810 idx = -1 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
811 for key, item in obj.items(): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
812 idx += 1 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
813 if schema_keynames is None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
814 if not isinstance(key, str): |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
815 yield ValidationProblem(code=ERRORS.E10003, hint=repr(key), context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
816 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
817 # validate the key against given schema |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
818 new_context = Context(context, key=key, key_index=idx, current_object=key) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
819 key_probs = list(_validate(key, schema_keynames, new_context)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
820 if key_probs: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
821 yield ValidationProblem( |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
822 code=ERRORS.E10034, hint=key, context=context, cause=key_probs) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
823 if context.settings.break_on_keynames_problems: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
824 return |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
825 if key in seen_keys: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
826 yield ValidationProblem(code=WARNINGS.W80000, hint=key, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
827 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
828 seen_keys.add(key) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
829 # XXX FIXME: context: new leaf context with new key for recursion |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
830 if key in schema_keys: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
831 new_context = Context(context, key=key, key_index=idx, current_object=item) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
832 yield from _validate(item, schema.ensure_child_schema(schema_keys[key]), new_context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
833 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
834 # check whether additional keys are allowed |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
835 additional_keys = schema.get_child("additional-keys", False) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
836 if isinstance(additional_keys, bool): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
837 if not additional_keys: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
838 if not _is_in_skip_keys(key, context.settings.skip_keys): |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
839 yield ValidationProblem(code=ERRORS.E10004, hint=str(key), context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
840 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
841 if not _is_in_skip_keys(key, context.settings.skip_keys): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
842 # try this as the common schema for all the additional keys |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
843 new_context = Context(context, key=key, key_index=idx, current_object=item) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
844 yield from _validate(item, additional_keys, new_context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
845 # check whether all required keys are seen |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
846 try: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
847 required_keys = set(schema.get("required", set())) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
848 except (TypeError, ValueError): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
849 raise SchemaError("`required` must be an iterable") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
850 if not required_keys <= seen_keys: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
851 hs = [str(i) for i in required_keys - seen_keys] |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
852 yield ValidationProblem(code=ERRORS.E10005, hint=sorted(hs), context=context) |
|
38
5a2fba996773
Implement a "forbidden" schema field for dicts
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
37
diff
changeset
|
853 # check whether no forbidden keys are seen |
|
5a2fba996773
Implement a "forbidden" schema field for dicts
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
37
diff
changeset
|
854 try: |
|
5a2fba996773
Implement a "forbidden" schema field for dicts
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
37
diff
changeset
|
855 forbidden_keys = set(schema.get("forbidden", set())) |
|
5a2fba996773
Implement a "forbidden" schema field for dicts
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
37
diff
changeset
|
856 except (TypeError, ValueError): |
|
5a2fba996773
Implement a "forbidden" schema field for dicts
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
37
diff
changeset
|
857 raise SchemaError("`forbidden` must be an iterable") |
|
5a2fba996773
Implement a "forbidden" schema field for dicts
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
37
diff
changeset
|
858 if forbidden_keys & seen_keys: |
|
5a2fba996773
Implement a "forbidden" schema field for dicts
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
37
diff
changeset
|
859 hs = [str(i) for i in forbidden_keys & seen_keys] |
|
5a2fba996773
Implement a "forbidden" schema field for dicts
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
37
diff
changeset
|
860 yield ValidationProblem(code=ERRORS.E10059, hint=sorted(hs), context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
861 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
862 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
863 def validate_list(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
864 if _is_null_allowed_for_object(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
865 return |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
866 if not isinstance(obj, (list, tuple)): |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
867 yield ValidationProblem(code=ERRORS.E10001, hint="got: {}".format(type(obj).__name__), context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
868 return |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
869 yield from _validate_index_constraint(obj, schema, context) |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
870 minlen = schema.get("min-length", None) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
871 if minlen: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
872 if len(obj) < minlen: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
873 yield ValidationProblem(code=ERRORS.E10012, hint=obj, context=context) |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
874 maxlen = schema.get("max-length", None) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
875 if maxlen is not None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
876 if len(obj) > maxlen: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
877 yield ValidationProblem(code=ERRORS.E10013, hint=obj, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
878 try: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
879 schema_items = schema.ensure_child_schema(schema["items"]) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
880 except KeyError: |
|
31
271ec3abdfa3
Use "$type" as the schema's type specifier instead of "type".
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
30
diff
changeset
|
881 schema_items = _Schema(schema, False, {"$type": validate_deny}) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
882 for idx, o in enumerate(obj): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
883 new_context = Context(parent=context, index=idx, current_object=o) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
884 yield from _validate(o, schema_items, new_context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
885 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
886 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
887 def validate_set(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
888 if _is_null_allowed_for_object(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
889 return |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
890 if not isinstance(obj, (set, frozenset)): |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
891 yield ValidationProblem(code=ERRORS.E10038, hint="got: {}".format(type(obj).__name__), context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
892 return |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
893 yield from _validate_index_constraint(obj, schema, context) |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
894 minlen = schema.get("min-length", None) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
895 if minlen: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
896 if len(obj) < minlen: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
897 yield ValidationProblem(code=ERRORS.E10039, hint=obj, context=context) |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
898 maxlen = schema.get("max-length", None) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
899 if maxlen is not None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
900 if len(obj) > maxlen: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
901 yield ValidationProblem(code=ERRORS.E10040, hint=obj, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
902 try: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
903 schema_items = schema.ensure_child_schema(schema["items"]) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
904 except KeyError: |
|
31
271ec3abdfa3
Use "$type" as the schema's type specifier instead of "type".
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
30
diff
changeset
|
905 schema_items = _Schema(schema, False, {"$type": validate_deny}) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
906 for o in obj: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
907 new_context = Context(parent=context, key=o, current_object=o) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
908 yield from _validate(o, schema_items, new_context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
909 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
910 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
911 def validate_tuple(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
912 if _is_null_allowed_for_object(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
913 return |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
914 if not isinstance(obj, (list, tuple)): |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
915 yield ValidationProblem(code=ERRORS.E10014, hint="got: {}".format(type(obj).__name__), context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
916 return |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
917 yield from _validate_index_constraint(obj, schema, context) |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
918 minlen = schema.get("min-length", None) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
919 if minlen: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
920 if len(obj) < minlen: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
921 yield ValidationProblem(code=ERRORS.E10015, hint=obj, context=context) |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
922 maxlen = schema.get("max-length", None) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
923 if maxlen is not None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
924 if len(obj) > maxlen: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
925 yield ValidationProblem(code=ERRORS.E10016, hint=obj, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
926 schema_items = schema.get("items", []) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
927 if not isinstance(schema_items, (list, tuple)): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
928 raise SchemaError("tuple items require a list of schemata in items") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
929 for idx, o in enumerate(obj): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
930 # early exit at maxlen |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
931 if maxlen is not None and idx >= maxlen: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
932 break |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
933 new_context = Context(parent=context, index=idx, current_object=o) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
934 try: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
935 schema_index = schema.ensure_child_schema(schema_items[idx]) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
936 except IndexError: |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
937 additional_items = schema.get_child("additional-items", False) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
938 if isinstance(additional_items, bool): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
939 if not additional_items: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
940 yield ValidationProblem(code=ERRORS.E10017, context=new_context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
941 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
942 yield from _validate(o, additional_items, new_context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
943 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
944 yield from _validate(o, schema_index, new_context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
945 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
946 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
947 def validate_str(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
948 if _is_null_allowed_for_object(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
949 return |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
950 if not isinstance(obj, str): |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
951 yield ValidationProblem(code=ERRORS.E10002, hint=obj, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
952 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
953 yield from _validate_index_constraint(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
954 enumvalues = schema.get("enum", None) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
955 if enumvalues is not None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
956 for ev in enumvalues: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
957 if ev == obj: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
958 break |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
959 else: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
960 yield ValidationProblem(code=ERRORS.E10043, hint=obj, context=context) |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
961 minlen = schema.get("min-length", None) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
962 if minlen: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
963 if len(obj) < minlen: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
964 yield ValidationProblem(code=ERRORS.E10006, hint=obj, context=context) |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
965 maxlen = schema.get("max-length", None) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
966 if maxlen is not None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
967 if len(obj) > maxlen: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
968 yield ValidationProblem(code=ERRORS.E10007, hint=obj, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
969 pattern = schema.get("pattern", None) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
970 if pattern is not None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
971 if isinstance(pattern, str): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
972 mo = re.search(pattern, obj) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
973 if not mo: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
974 yield ValidationProblem(code=ERRORS.E10008, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
975 elif isinstance(pattern, TYPE_RE): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
976 mo = pattern.search(obj) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
977 if not mo: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
978 yield ValidationProblem(code=ERRORS.E10008, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
979 elif callable(pattern): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
980 yield from pattern(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
981 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
982 raise SchemaError("unknown pattern type") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
983 is_contained = schema.get("is-contained-in-ref", None) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
984 if is_contained is not None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
985 refobj = try_get_reference(is_contained, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
986 context, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
987 schema, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
988 default=_SENTINEL) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
989 if refobj is _SENTINEL: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
990 yield ValidationProblem(code=ERRORS.E10044, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
991 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
992 try: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
993 if obj not in refobj: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
994 yield ValidationProblem(code=ERRORS.E10045, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
995 except TypeError: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
996 yield ValidationProblem(code=ERRORS.E10046, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
997 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
998 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
999 def validate_binary(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1000 if not isinstance(obj, (bytes, bytearray)): |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1001 yield ValidationProblem(code=ERRORS.E10035, hint=obj, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1002 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1003 yield from _validate_index_constraint(obj, schema, context) |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
1004 minlen = schema.get("min-length", None) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1005 if minlen: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1006 if len(obj) < minlen: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1007 yield ValidationProblem(code=ERRORS.E10036, hint=obj, context=context) |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
1008 maxlen = schema.get("max-length", None) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1009 if maxlen is not None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1010 if len(obj) > maxlen: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1011 yield ValidationProblem(code=ERRORS.E10037, hint=obj, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1012 pattern = schema.get("pattern", None) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1013 if pattern is not None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1014 if isinstance(pattern, (str, bytes, bytearray)): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1015 if isinstance(pattern, str): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1016 if "'''" not in pattern: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1017 bytes_pattern = ast.literal_eval( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1018 "b'''" + pattern + "'''") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1019 elif '"""' not in pattern: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1020 bytes_pattern = ast.literal_eval( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1021 'b"""' + pattern + '"""') |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1022 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1023 raise SchemaError("incompatible bytes pattern") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1024 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1025 bytes_pattern = pattern |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1026 mo = re.search(bytes_pattern, obj) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1027 if not mo: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1028 yield ValidationProblem(code=ERRORS.E10047, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1029 elif isinstance(pattern, TYPE_RE): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1030 mo = pattern.search(obj) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1031 if not mo: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1032 yield ValidationProblem(code=ERRORS.E10047, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1033 elif callable(pattern): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1034 yield from pattern(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1035 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1036 raise SchemaError("unknown pattern type") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1037 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1038 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1039 def validate_timestamp(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1040 if not isinstance(obj, datetime.datetime): |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1041 yield ValidationProblem(code=ERRORS.E10041, hint=obj, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1042 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1043 yield from _validate_index_constraint(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1044 value = schema.get("value", None) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1045 if value is not None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1046 if callable(value): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1047 yield from value(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1048 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1049 raise SchemaError("unknown value validator (only a callable allowed)") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1050 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1051 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1052 def validate_integer(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1053 if _is_null_allowed_for_object(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1054 return |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1055 if not isinstance(obj, int): |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1056 yield ValidationProblem(code=ERRORS.E10020, hint=obj, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1057 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1058 yield from _validate_index_constraint(obj, schema, context) |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
1059 min_value = schema.get("min-value", None) |
|
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
1060 if min_value is not None and obj < min_value: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1061 yield ValidationProblem(code=ERRORS.E10021, hint=obj, context=context) |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
1062 max_value = schema.get("max-value", None) |
|
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
1063 if max_value is not None and obj > max_value: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1064 yield ValidationProblem(code=ERRORS.E10022, hint=obj, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1065 enumvalues = schema.get("enum", None) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1066 if enumvalues is not None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1067 for ev in enumvalues: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1068 if ev == obj: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1069 break |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1070 else: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1071 yield ValidationProblem(code=ERRORS.E10048, hint=obj, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1072 value = schema.get("value", None) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1073 if value is not None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1074 if callable(value): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1075 yield from value(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1076 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1077 raise SchemaError("unknown value validator (only a callable allowed)") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1078 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1079 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1080 def validate_float(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1081 if _is_null_allowed_for_object(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1082 return |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1083 if not isinstance(obj, float): |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1084 yield ValidationProblem(code=ERRORS.E10023, hint=obj, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1085 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1086 yield from _validate_index_constraint(obj, schema, context) |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
1087 min_value = schema.get("min-value", None) |
|
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
1088 if min_value is not None and obj < min_value: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1089 yield ValidationProblem(code=ERRORS.E10024, hint=obj, context=context) |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
1090 max_value = schema.get("max-value", None) |
|
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
1091 if max_value is not None and obj > max_value: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1092 yield ValidationProblem(code=ERRORS.E10025, hint=obj, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1093 value = schema.get("value", None) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1094 if value is not None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1095 if callable(value): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1096 yield from value(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1097 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1098 raise SchemaError("unknown value validator (only a callable allowed)") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1099 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1100 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1101 def validate_number(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1102 if _is_null_allowed_for_object(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1103 return |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1104 if not isinstance(obj, (int, float)): |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1105 yield ValidationProblem(code=ERRORS.E10030, hint=obj, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1106 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1107 yield from _validate_index_constraint(obj, schema, context) |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
1108 min_value = schema.get("min-value", None) |
|
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
1109 if min_value is not None and isinstance(obj, float): |
|
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
1110 min_value *= 1.0 |
|
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
1111 if min_value is not None and obj < min_value: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1112 yield ValidationProblem(code=ERRORS.E10031, hint=obj, context=context) |
|
19
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
1113 max_value = schema.get("max-value", None) |
|
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
1114 if max_value is not None and isinstance(obj, float): |
|
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
1115 max_value *= 1.0 |
|
c3a0fe8d4587
Consistent casing of schema items: all lowercase with dash as separator
Franz Glasner <fzglas.hg@dom66.de>
parents:
17
diff
changeset
|
1116 if max_value is not None and obj > max_value: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1117 yield ValidationProblem(code=ERRORS.E10032, hint=obj, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1118 enumvalues = schema.get("enum", None) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1119 if enumvalues is not None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1120 for ev in enumvalues: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1121 if ev == obj: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1122 break |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1123 else: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1124 yield ValidationProblem(code=ERRORS.E10049, hint=obj, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1125 value = schema.get("value", None) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1126 if value is not None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1127 if callable(value): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1128 yield from value(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1129 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1130 raise SchemaError("unknown value validator (only a callable allowed)") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1131 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1132 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1133 def validate_scalar(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1134 if _is_null_allowed_for_object(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1135 return |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1136 yield from _validate_index_constraint(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1137 if obj is None: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1138 yield ValidationProblem(code=ERRORS.E10033, hint=obj, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1139 if isinstance(obj, (dict, list, tuple, set, frozenset)): |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1140 yield ValidationProblem(code=ERRORS.E10033, hint=obj, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1141 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1142 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1143 def validate_deny(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1144 yield from _validate_index_constraint(obj, schema, context) |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1145 yield ValidationProblem(code=ERRORS.E10010, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1146 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1147 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1148 def validate_accept(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1149 yield from _validate_index_constraint(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1150 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1151 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1152 def validate_null(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1153 yield from _validate_index_constraint(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1154 if obj is not None: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1155 yield ValidationProblem(code=ERRORS.E10011, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1156 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1157 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1158 def validate_empty(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1159 yield from _validate_index_constraint(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1160 if obj is None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1161 return |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1162 if isinstance(obj, (dict, list, tuple, set, frozenset)) and not obj: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1163 return |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1164 yield ValidationProblem(ERRORS.E10018, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1165 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1166 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1167 def validate_bool(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1168 if _is_null_allowed_for_object(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1169 return |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1170 if not isinstance(obj, bool): |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1171 yield ValidationProblem(code=ERRORS.E10026, hint=obj, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1172 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1173 yield from _validate_index_constraint(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1174 value = schema.get("value", None) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1175 if value is not None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1176 if callable(value): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1177 yield from value(obj, schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1178 elif value and not obj: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1179 yield ValidationProblem(code=ERRORS.E10027, hint=obj, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1180 elif not value and obj: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1181 yield ValidationProblem(code=ERRORS.E10028, hint=obj, context=context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1182 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1183 |
|
23
413b344be2d1
Consistent naming of validation methods: all lowercase
Franz Glasner <fzglas.hg@dom66.de>
parents:
19
diff
changeset
|
1184 def validate_all_of(obj, schema, context): |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1185 if not isinstance(schema, (list, tuple)): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1186 raise SchemaError("require a list of schematas for `all-of'") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1187 res = [] |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1188 for idx, s in enumerate(schema): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1189 assert isinstance(s, _Schema) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1190 tr = list(_validate(obj, s, context)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1191 if tr: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1192 res.append((idx, tr, )) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1193 if res: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1194 yield ValidationProblem( |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1195 code=ERRORS.E10057, |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1196 context=context, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1197 cause=[ |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1198 ValidationProblem( |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1199 code=ERRORS.E10058, |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1200 context=context, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1201 cause=tr, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1202 index=idx) for (idx, tr) in res]) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1203 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1204 |
|
23
413b344be2d1
Consistent naming of validation methods: all lowercase
Franz Glasner <fzglas.hg@dom66.de>
parents:
19
diff
changeset
|
1205 def validate_any_of(obj, schema, context): |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1206 if not isinstance(schema, (list, tuple)): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1207 raise SchemaError("require a list of schematas for `any-of'") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1208 res = [] |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1209 for s in schema: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1210 assert isinstance(s, _Schema) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1211 tr = list(_validate(obj, s, context)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1212 if tr: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1213 res.append(tr) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1214 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1215 # Erfolg: gleich positiv zurueck ohne Meldungen |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1216 return |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1217 # Ansonsten: alle Fehlschlaege protokollieren |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1218 if res: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1219 yield ValidationProblem( |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1220 code=ERRORS.E10055, |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1221 context=context, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1222 cause=[ |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1223 ValidationProblem( |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1224 code=ERRORS.E10056, |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1225 context=context, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1226 cause=tr) for tr in res]) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1227 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1228 |
|
23
413b344be2d1
Consistent naming of validation methods: all lowercase
Franz Glasner <fzglas.hg@dom66.de>
parents:
19
diff
changeset
|
1229 def validate_one_of(obj, schema, context): |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1230 if not isinstance(schema, (list, tuple)): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1231 raise SchemaError("require a list of schematas for `one-of'") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1232 success_res = [] |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1233 failed_res = [] |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1234 for idx, s in enumerate(schema): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1235 assert isinstance(s, _Schema) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1236 tr = list(_validate(obj, s, context)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1237 if tr: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1238 failed_res.append((idx, tr, )) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1239 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1240 success_res.append(idx) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1241 if len(success_res) == 1: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1242 return |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1243 elif len(success_res) == 0: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1244 # Ansonsten: alle Fehlschlaege protokollieren |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1245 if failed_res: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1246 yield ValidationProblem( |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1247 code=ERRORS.E10053, |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1248 context=context, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1249 cause=[ |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1250 ValidationProblem( |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1251 code=ERRORS.E10054, |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1252 context=context, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1253 cause=tr, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1254 index=idx) for (idx, tr) in failed_res]) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1255 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1256 # Die Indizes der "zuvielen" in "hint" anzeigen |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1257 yield ValidationProblem(code=ERRORS.E10019, hint=",".join([str(k) for k in success_res])) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1258 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1259 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1260 def validate_not(obj, schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1261 assert isinstance(schema, _Schema) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1262 res = list(_validate(obj, schema, context)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1263 if not res: |
|
13
940676a0de84
ERRORS and WARNINGS are now enums
Franz Glasner <fzglas.hg@dom66.de>
parents:
10
diff
changeset
|
1264 yield ValidationProblem(code=ERRORS.E10029, hint=obj, context=context, |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1265 cause=res) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1266 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1267 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1268 def process_schema_references(schema, context, check_single_ref_key=True): |
|
40
2376224a9717
FIX: when processing schema references and the resolved schema contains conditionals they must be evaluated
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
39
diff
changeset
|
1269 """ |
|
2376224a9717
FIX: when processing schema references and the resolved schema contains conditionals they must be evaluated
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
39
diff
changeset
|
1270 |
|
2376224a9717
FIX: when processing schema references and the resolved schema contains conditionals they must be evaluated
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
39
diff
changeset
|
1271 .. note:: If a new dereferenced schema is found schema conditionals are |
|
2376224a9717
FIX: when processing schema references and the resolved schema contains conditionals they must be evaluated
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
39
diff
changeset
|
1272 evaluated also. So the resolved schema containing conditionals |
|
2376224a9717
FIX: when processing schema references and the resolved schema contains conditionals they must be evaluated
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
39
diff
changeset
|
1273 behaves according to the given conditions. |
|
2376224a9717
FIX: when processing schema references and the resolved schema contains conditionals they must be evaluated
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
39
diff
changeset
|
1274 |
|
2376224a9717
FIX: when processing schema references and the resolved schema contains conditionals they must be evaluated
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
39
diff
changeset
|
1275 """ |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1276 try: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1277 ref = schema[SCHEMA_REF_KEY] |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1278 except (KeyError, TypeError): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1279 return schema |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1280 # if `$ref' is found it MUST be the only key |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1281 if check_single_ref_key and len(schema) != 1: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1282 raise SchemaError("`{}' must be the single key if it exists") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1283 schema = try_get_reference(ref, context, schema) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1284 if not isinstance(schema, _Schema): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1285 raise SchemaError( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1286 "dereferenced schema is not a `_Schema': {}".format(ref)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1287 schema = copy.deepcopy(schema) |
|
40
2376224a9717
FIX: when processing schema references and the resolved schema contains conditionals they must be evaluated
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
39
diff
changeset
|
1288 # process schema conditionals "cond" and "match" again |
|
2376224a9717
FIX: when processing schema references and the resolved schema contains conditionals they must be evaluated
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
39
diff
changeset
|
1289 schema = process_schema_conditionals(schema, context) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1290 return process_schema_references(schema, context, check_single_ref_key=True) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1291 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1292 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1293 def process_schema_conditionals(schema, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1294 """Lisp-like `cond` to provide schema modifications |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1295 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1296 :param schema: the input schema |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1297 :param context: the validation context with a valid |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1298 `context.root.root_object` |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1299 :returns: the processed schema: the schema itself if it is unchanged and |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1300 a copy of the schema if has been changed |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1301 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1302 """ |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1303 what, conds = _get_one_of(schema, "cond", "match", default=None) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1304 if what is None or conds is None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1305 return schema |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1306 if not isinstance(conds, (list, tuple)): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1307 raise SchemaError("the conditions of a cond must be a sequence") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1308 if what == "cond": |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1309 return _process_schema_conditionals_cond(schema, conds, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1310 elif what == "match": |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1311 return _process_schema_conditionals_match(schema, conds, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1312 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1313 assert False, "unreachable" |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1314 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1315 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1316 def _process_schema_conditionals_cond(schema, conds, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1317 for cond in conds: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1318 if not isinstance(cond, dict): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1319 raise SchemaError("a single condition must be a dict") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1320 if eval_condition(cond, context, schema): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1321 rep_type, rep_schema = _get_one_of( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1322 cond, "then", "then-replace", "then-merge") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1323 rep_schema = schema.ensure_child_schema(rep_schema) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1324 if rep_type in ("then", "then-replace"): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1325 do_merge = False |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1326 elif rep_type == "then-merge": |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1327 do_merge = True |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1328 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1329 raise SchemaError("unknown then type: {}".format(rep_type)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1330 break |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1331 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1332 # |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1333 # No condition was true: just remove the "cond" to get the |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1334 # effective schema. |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1335 # |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1336 rep_schema = None |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1337 do_merge = False |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1338 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1339 new_schema = schema.copy() |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1340 del new_schema["cond"] |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1341 if rep_schema: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1342 rep_schema = process_schema_references(rep_schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1343 # this could insert a new nested "cond" or "match" again |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1344 if do_merge: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1345 rep_schema = copy.deepcopy(rep_schema) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1346 new_schema = _merge(rep_schema, new_schema) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1347 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1348 new_schema.update(rep_schema) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1349 # Recursively apply "cond/match" evaluation to the resulting schema |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1350 return process_schema_conditionals(new_schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1351 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1352 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1353 def _process_schema_conditionals_match(schema, conds, context): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1354 rep_schemata = [] |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1355 for cond in conds: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1356 if not isinstance(cond, dict): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1357 raise SchemaError("a single condition must be a dict") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1358 if eval_condition(cond, context, schema): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1359 rep_type, rep_schema = _get_one_of( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1360 cond, "then", "then-replace", "then-merge") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1361 rep_schema = schema.ensure_child_schema(rep_schema) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1362 if rep_type in ("then", "then-replace"): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1363 rep_schemata.append((False, rep_schema)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1364 elif rep_type == "then-merge": |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1365 rep_schemata.append((True, rep_schema)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1366 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1367 raise SchemaError("unknown then type: {}".format(rep_type)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1368 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1369 new_schema = schema.copy() |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1370 del new_schema["match"] |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1371 for do_merge, rep_schema in rep_schemata: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1372 rep_schema = process_schema_references(rep_schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1373 # this could insert a new nested "cond" or "match" again |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1374 if do_merge: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1375 rep_schema = copy.deepcopy(rep_schema) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1376 new_schema = _merge(rep_schema, new_schema) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1377 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1378 new_schema.update(rep_schema) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1379 # Recursively apply "cond/match" evaluation to the resulting schema |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1380 return process_schema_conditionals(new_schema, context) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1381 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1382 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1383 def eval_condition(cond, context, schema): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1384 """Eval the condition in `cond` and return a tuple `(hit, predval)` |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1385 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1386 """ |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1387 pred, predval = _get_one_of( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1388 cond, |
|
39
78f5ef0ee087
Implement "ref-false", "ref-not-exists", "when-ref-false" and "when-ref-not-exists" in addition to the existing conditions
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
38
diff
changeset
|
1389 "when-ref-true", "when-ref-false", |
|
78f5ef0ee087
Implement "ref-false", "ref-not-exists", "when-ref-false" and "when-ref-not-exists" in addition to the existing conditions
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
38
diff
changeset
|
1390 "when-ref-exists", "when-ref-not-exists", "when", |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1391 default=_SENTINEL) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1392 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1393 if pred == "when": |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1394 # rekursive evaluation of `predval` as the real predicate |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1395 return eval_pred(predval, context, schema) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1396 elif pred == "when-ref-true": |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1397 refobj = try_get_reference(predval, context, schema, default=None) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1398 return bool(refobj) |
|
39
78f5ef0ee087
Implement "ref-false", "ref-not-exists", "when-ref-false" and "when-ref-not-exists" in addition to the existing conditions
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
38
diff
changeset
|
1399 elif pred == "when-ref-false": |
|
78f5ef0ee087
Implement "ref-false", "ref-not-exists", "when-ref-false" and "when-ref-not-exists" in addition to the existing conditions
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
38
diff
changeset
|
1400 refobj = try_get_reference(predval, context, schema, default=None) |
|
78f5ef0ee087
Implement "ref-false", "ref-not-exists", "when-ref-false" and "when-ref-not-exists" in addition to the existing conditions
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
38
diff
changeset
|
1401 return not bool(refobj) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1402 elif pred == "when-ref-exists": |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1403 refobj = try_get_reference(predval, context, schema, default=_SENTINEL) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1404 return refobj is not _SENTINEL |
|
39
78f5ef0ee087
Implement "ref-false", "ref-not-exists", "when-ref-false" and "when-ref-not-exists" in addition to the existing conditions
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
38
diff
changeset
|
1405 elif pred == "when-ref-not-exists": |
|
78f5ef0ee087
Implement "ref-false", "ref-not-exists", "when-ref-false" and "when-ref-not-exists" in addition to the existing conditions
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
38
diff
changeset
|
1406 refobj = try_get_reference(predval, context, schema, default=_SENTINEL) |
|
78f5ef0ee087
Implement "ref-false", "ref-not-exists", "when-ref-false" and "when-ref-not-exists" in addition to the existing conditions
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
38
diff
changeset
|
1407 return refobj is _SENTINEL |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1408 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1409 raise SchemaError("unknown condition type: {}".format(pred)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1410 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1411 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1412 def eval_pred(pred, context, schema): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1413 if isinstance(pred, dict): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1414 combinator, combinator_val = _get_one_of( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1415 pred, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1416 "not", "all-of", "any-of", "one-of", |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1417 default=None) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1418 if combinator: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1419 if combinator == "not": |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1420 return not eval_pred(combinator_val, context, schema) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1421 elif combinator == "all-of": |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1422 if not isinstance(combinator_val, (list, tuple)): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1423 raise SchemaError("`all-of' requires a list of childs") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1424 for cv in combinator_val: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1425 if not eval_pred(cv, context, schema): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1426 return False |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1427 return True |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1428 elif combinator == "any-of": |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1429 if not isinstance(combinator_val, (list, tuple)): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1430 raise SchemaError("`any-of' requires a list of childs") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1431 for cv in combinator_val: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1432 if eval_pred(cv, context, schema): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1433 return True |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1434 return False |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1435 elif combinator == "one-of": |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1436 if not isinstance(combinator_val, (list, tuple)): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1437 raise SchemaError("`one-of' requires a list of childs") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1438 num_true = 0 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1439 for cv in combinator_val: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1440 if eval_pred(cv, context, schema): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1441 num_true += 1 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1442 # shortcut |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1443 if num_true > 1: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1444 return False |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1445 if num_true == 1: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1446 return True |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1447 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1448 return False |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1449 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1450 raise SchemaError( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1451 "unknown logical operator: {}".format(combinator)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1452 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1453 pred_key, pred_val = _get_one_of( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1454 pred, |
|
39
78f5ef0ee087
Implement "ref-false", "ref-not-exists", "when-ref-false" and "when-ref-not-exists" in addition to the existing conditions
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
38
diff
changeset
|
1455 "ref-true", "ref-false", "ref-exists", "ref-not-exists", |
|
78f5ef0ee087
Implement "ref-false", "ref-not-exists", "when-ref-false" and "when-ref-not-exists" in addition to the existing conditions
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
38
diff
changeset
|
1456 "equals", |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1457 default=None) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1458 if pred_key == "ref-true": |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1459 refobj = try_get_reference( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1460 pred_val, context, schema, default=None) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1461 return bool(refobj) |
|
39
78f5ef0ee087
Implement "ref-false", "ref-not-exists", "when-ref-false" and "when-ref-not-exists" in addition to the existing conditions
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
38
diff
changeset
|
1462 elif pred_key == "ref-false": |
|
78f5ef0ee087
Implement "ref-false", "ref-not-exists", "when-ref-false" and "when-ref-not-exists" in addition to the existing conditions
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
38
diff
changeset
|
1463 refobj = try_get_reference( |
|
78f5ef0ee087
Implement "ref-false", "ref-not-exists", "when-ref-false" and "when-ref-not-exists" in addition to the existing conditions
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
38
diff
changeset
|
1464 pred_val, context, schema, default=None) |
|
78f5ef0ee087
Implement "ref-false", "ref-not-exists", "when-ref-false" and "when-ref-not-exists" in addition to the existing conditions
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
38
diff
changeset
|
1465 return not bool(refobj) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1466 elif pred_key == "ref-exists": |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1467 refobj = try_get_reference( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1468 pred_val, context, schema, default=_SENTINEL) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1469 return refobj is not _SENTINEL |
|
39
78f5ef0ee087
Implement "ref-false", "ref-not-exists", "when-ref-false" and "when-ref-not-exists" in addition to the existing conditions
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
38
diff
changeset
|
1470 elif pred_key == "ref-not-exists": |
|
78f5ef0ee087
Implement "ref-false", "ref-not-exists", "when-ref-false" and "when-ref-not-exists" in addition to the existing conditions
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
38
diff
changeset
|
1471 refobj = try_get_reference( |
|
78f5ef0ee087
Implement "ref-false", "ref-not-exists", "when-ref-false" and "when-ref-not-exists" in addition to the existing conditions
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
38
diff
changeset
|
1472 pred_val, context, schema, default=_SENTINEL) |
|
78f5ef0ee087
Implement "ref-false", "ref-not-exists", "when-ref-false" and "when-ref-not-exists" in addition to the existing conditions
Franz Glasner <f.glasner@feldmann-mg.com>
parents:
38
diff
changeset
|
1473 return refobj is _SENTINEL |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1474 elif pred_key == "equals": |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1475 if not isinstance(pred_val, (list, tuple)): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1476 raise SchemaError("`equals' requires a list as childs") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1477 if len(pred_val) != 2: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1478 raise SchemaError("`equals' requires a list of len 2") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1479 op1 = eval_comparison_operator_operand( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1480 pred_val[0], context, schema) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1481 op2 = eval_comparison_operator_operand( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1482 pred_val[1], context, schema) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1483 return op1 == op2 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1484 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1485 raise SchemaError("unknown predicate: {}".format(pred)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1486 elif isinstance(pred, list): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1487 # implicit all-of (aka AND) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1488 for cv in pred: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1489 if not eval_pred(cv, context, schema): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1490 return False |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1491 return True |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1492 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1493 return pred |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1494 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1495 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1496 def eval_comparison_operator_operand(op, context, schema): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1497 if not isinstance(op, dict): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1498 raise SchemaError("an operand must be a dict") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1499 opkey, opval = _get_one_of(op, "ref", "val", "value") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1500 if opkey is None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1501 raise SchemaError("no operant given in {!r}".format(op)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1502 if opkey == "ref": |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1503 return try_get_reference(opval, context, schema) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1504 elif opkey in ("val", "value"): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1505 return opval |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1506 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1507 assert False |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1508 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1509 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1510 def try_get_reference(ref, context, schema, default=None): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1511 """Get the object referenced in `ref` |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1512 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1513 Use `context` as data/object context and `schema` as the current schema |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1514 context. |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1515 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1516 """ |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1517 uri = rfc3986.URIReference.from_string(ref).normalize() |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1518 if not uri.scheme: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1519 uri = uri.copy_with(scheme="object") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1520 if uri.scheme == "object": |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1521 if ref.startswith("object#"): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1522 for attr in ("authority", "path", "query"): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1523 if getattr(uri, attr, None) is not None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1524 raise SchemaError( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1525 "bogus {} in URI reference `{}'".format(attr, ref)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1526 if uri.fragment is None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1527 raise SchemaError("fragment required in reference") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1528 if not uri.fragment: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1529 return context.root.root_object |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1530 elif uri.fragment == '.': |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1531 return context.current_object |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1532 parts = uri.fragment.split('.') # use '.' separator as in configmix |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1533 if parts[0]: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1534 # absolute |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1535 d = context.root.root_object |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1536 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1537 # relative |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1538 d = context.current_object |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1539 parts = parts[1:] |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1540 c = context # needed to determine relative object references |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1541 relative_refs_allowed = True |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1542 for part in [urllib.parse.unquote(p) for p in parts]: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1543 if part: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1544 relative_refs_allowed = False |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1545 try: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1546 d = d[part] |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1547 except (KeyError, IndexError, TypeError): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1548 return default |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1549 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1550 if not relative_refs_allowed: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1551 raise SchemaError( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1552 "empty part in path to object reference not allowed") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1553 c = c.safe_parent |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1554 d = c.current_object |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1555 return d |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1556 elif uri.scheme == "schema": |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1557 if not uri.path or (uri.path == SCHEMA_PATH_SELF): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1558 s = schema.SELF |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1559 elif uri.path == SCHEMA_PATH_ROOT: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1560 s = schema.ROOT |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1561 else: |
|
28
db3491e1b590
Allow to customize the loading of the schema dict
Franz Glasner <fzglas.hg@dom66.de>
parents:
25
diff
changeset
|
1562 s = schema.get_cached_schema( |
|
db3491e1b590
Allow to customize the loading of the schema dict
Franz Glasner <fzglas.hg@dom66.de>
parents:
25
diff
changeset
|
1563 uri.path, |
|
db3491e1b590
Allow to customize the loading of the schema dict
Franz Glasner <fzglas.hg@dom66.de>
parents:
25
diff
changeset
|
1564 load_if_needed=True, |
|
29
68286d27f27d
FIX: Allow customization of the data stream loader (get_data_stream())
Franz Glasner <fzglas.hg@dom66.de>
parents:
28
diff
changeset
|
1565 data_stream_loader=context.settings.data_stream_loader, |
|
28
db3491e1b590
Allow to customize the loading of the schema dict
Franz Glasner <fzglas.hg@dom66.de>
parents:
25
diff
changeset
|
1566 schema_loader=context.settings.schema_loader) |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1567 if uri.fragment is None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1568 raise SchemaError("fragment required in reference") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1569 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1570 if not uri.fragment.startswith('/'): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1571 raise SchemaError("references to parts of a schema must be absolute (begin with `/')") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1572 if uri.fragment == '/': |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1573 return s |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1574 parts = uri.fragment.split('/') |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1575 parent_for_subschema = s |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1576 for part in [urllib.parse.unquote(p) for p in parts[1:]]: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1577 try: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1578 v = s[part] |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1579 except (KeyError, IndexError, TypeError): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1580 return default |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1581 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1582 if isinstance(v, _Schema): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1583 pass |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1584 elif isinstance(v, dict): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1585 s = _Schema(parent_for_subschema, False, v) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1586 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1587 # need not try further |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1588 return default |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1589 return s |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1590 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1591 raise SchemaError("Unknown schema reference scheme: {}".format(uri.scheme)) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1592 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1593 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1594 _DEL_VALUE = '{{::DEL::}}' |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1595 """Sigil to mark keys to be deleted in the target when merging""" |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1596 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1597 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1598 def _merge(user, default): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1599 """Logically merge the configuration in `user` into `default`. |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1600 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1601 :param dict user: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1602 the new configuration that will be logically merged |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1603 into `default` |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1604 :param dict default: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1605 the base configuration where `user` is logically merged into |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1606 :returns: `user` with the necessary amendments from `default`. |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1607 If `user` is ``None`` then `default` is returned. |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1608 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1609 .. note:: Implementation: The configuration in `user` is |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1610 augmented/changed **inplace**. |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1611 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1612 If a value in `user` is equal to :data:`._DEL_VALUE` |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1613 (``{{::DEL::}}``) the corresponding key will be deleted from the |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1614 merged output. |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1615 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1616 From http://stackoverflow.com/questions/823196/yaml-merge-in-python |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1617 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1618 """ |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1619 if user is None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1620 _filter_deletions(default) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1621 return default |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1622 if isinstance(user, dict) and isinstance(default, dict): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1623 for k, v in default.items(): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1624 if k in user: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1625 if user[k] == _DEL_VALUE: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1626 # do not copy and delete the marker |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1627 del user[k] |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1628 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1629 user[k] = _merge_item(user[k], v) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1630 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1631 user[k] = v |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1632 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1633 raise SchemaError("can only merge two dicts on top-level") |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1634 _filter_deletions(user) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1635 return user |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1636 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1637 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1638 def _merge_item(user, default): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1639 """Recursion helper for :func:`._merge` |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1640 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1641 """ |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1642 if isinstance(user, dict) and isinstance(default, dict): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1643 for k, v in default.items(): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1644 if k in user: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1645 if user[k] == _DEL_VALUE: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1646 # do not copy and delete the marker |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1647 del user[k] |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1648 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1649 user[k] = _merge_item(user[k], v) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1650 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1651 user[k] = v |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1652 elif isinstance(user, (list, tuple)) and isinstance(default, (list, tuple)): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1653 for idx, v in enumerate(default): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1654 user.insert(idx, v) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1655 return user |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1656 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1657 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1658 def _filter_deletions(d): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1659 """Recursively filter deletions in the dict `d`. |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1660 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1661 Deletions have values that equal :data:`._DEL_VALUE`. |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1662 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1663 """ |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1664 if not isinstance(d, dict): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1665 return |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1666 # use a copy of the items because we change `d` while iterating |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1667 for k, v in list(d.items()): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1668 if v == _DEL_VALUE: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1669 del d[k] |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1670 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1671 if isinstance(d[k], dict): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1672 _filter_deletions(d[k]) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1673 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1674 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1675 def _log_problem_cause_all(logger, loglevel, level, problems): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1676 if not problems: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1677 return |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1678 for pr in problems: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1679 logger.log(loglevel, "%s> %r", "-"*((level*2)+2), pr) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1680 _log_problem_cause_all(logger, loglevel, level+1, pr.cause) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1681 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1682 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1683 def _build_problems_by_level_and_depth(by_level, by_depth, level, problems): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1684 for pr in problems: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1685 if not pr.cause: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1686 continue |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1687 try: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1688 prl = by_level[level] |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1689 except LookupError: |
| 9 | 1690 prl = [] |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1691 by_level[level] = prl |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1692 prl.append(pr) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1693 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1694 depth = pr.context.depth |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1695 try: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1696 prd = by_depth[depth] |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1697 except LookupError: |
| 9 | 1698 prd = [] |
|
5
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1699 by_depth[depth] = prd |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1700 prd.append(pr) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1701 _build_problems_by_level_and_depth( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1702 by_level, by_depth, level+1, pr.cause) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1703 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1704 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1705 def _log_problem_cause(logger, loglevel, max_level, max_depth, level, problems): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1706 for pr in problems: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1707 # |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1708 # Check whether we will start logging from this level downwards |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1709 # all problems |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1710 # |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1711 if max_level is None or level == max_level: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1712 new_max_level = None # trigger logging |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1713 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1714 new_max_level = max_level |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1715 if max_depth is None or max_depth == pr.context.depth: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1716 new_max_depth = None # trigger logging |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1717 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1718 new_max_depth = max_depth |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1719 if new_max_level is None or new_max_depth is None: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1720 logger.log(loglevel, "%s> %r", "-"*((level*2)+2), pr) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1721 if pr.cause: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1722 _log_problem_cause( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1723 logger, loglevel, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1724 new_max_level, new_max_depth, |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1725 level+1, pr.cause) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1726 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1727 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1728 def log_problem_cause(logger, loglevel, debug, level, problems): |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1729 if not problems: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1730 return |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1731 if debug: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1732 _log_problem_cause_all(logger, loglevel, level, problems) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1733 else: |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1734 by_level = {} # to determine maximum problem nesting level |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1735 by_depth = {} # to determine maximum context nexting level |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1736 _build_problems_by_level_and_depth(by_level, by_depth, level, problems) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1737 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1738 max_level = max(by_level.keys()) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1739 max_depth = max(by_depth.keys()) |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1740 |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1741 _log_problem_cause( |
|
84dfd1a94926
Add the existing implementation.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff
changeset
|
1742 logger, loglevel, max_level, max_depth, level, problems) |
