Mercurial > hgrepos > Python > libs > data-schema
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 45:8a560e0c3180 | 46:92ae1e882cef |
|---|---|
| 32 import copy | 32 import copy |
| 33 import datetime | 33 import datetime |
| 34 import enum | 34 import enum |
| 35 import pickle | 35 import pickle |
| 36 import re | 36 import re |
| 37 import sys | |
| 37 import urllib.parse | 38 import urllib.parse |
| 38 | 39 |
| 39 import rfc3986 | 40 import rfc3986 |
| 40 | 41 |
| 41 try: | 42 try: |
| 145 assert 80000 <= int(w[1:], 10), "Invalid WARNING code number in `{}'".format(w) | 146 assert 80000 <= int(w[1:], 10), "Invalid WARNING code number in `{}'".format(w) |
| 146 | 147 |
| 147 | 148 |
| 148 TYPE_RE = type(re.compile(r"\A.+\Z")) | 149 TYPE_RE = type(re.compile(r"\A.+\Z")) |
| 149 | 150 |
| 150 _SENTINEL = object() | |
| 151 | |
| 152 SCHEMA_REF_KEY = "$ref" | 151 SCHEMA_REF_KEY = "$ref" |
| 153 """Key name for schema references (like a symlink within a schema)""" | 152 """Key name for schema references (like a symlink within a schema)""" |
| 154 | 153 |
| 155 SCHEMA_PATH_ROOT = "$root" | 154 SCHEMA_PATH_ROOT = "$root" |
| 156 """URI path to the root schema""" | 155 """URI path to the root schema""" |
| 157 | 156 |
| 158 SCHEMA_PATH_SELF = "$self" | 157 SCHEMA_PATH_SELF = "$self" |
| 159 """URI path to the current schema""" | 158 """URI path to the current schema""" |
| 159 | |
| 160 | |
| 161 class _SENTINELType(object): | |
| 162 | |
| 163 @staticmethod | |
| 164 def _get_single(module, name): | |
| 165 return getattr(sys.modules[module], name) | |
| 166 | |
| 167 def __reduce_ex__(self, proto): | |
| 168 """Make sure the _SENTINEL is ever only instantiated as singleton""" | |
| 169 return (_SENTINELType._get_single, (self.__module__, "_SENTINEL")) | |
| 170 | |
| 171 | |
| 172 _SENTINEL = _SENTINELType() | |
| 160 | 173 |
| 161 | 174 |
| 162 def problem_message(pr): | 175 def problem_message(pr): |
| 163 """ | 176 """ |
| 164 | 177 |
| 307 self.is_sub_root = True | 320 self.is_sub_root = True |
| 308 else: | 321 else: |
| 309 self.is_sub_root = is_sub_root | 322 self.is_sub_root = is_sub_root |
| 310 | 323 |
| 311 def __reduce_ex__(self, proto): | 324 def __reduce_ex__(self, proto): |
| 312 rv = super().__reduce_ex__(proto) | 325 return super().__reduce_ex__(proto) |
| 313 #assert False, repr(rv) | |
| 314 print("RRRRRRR\n\n", repr(rv)) | |
| 315 assert False, repr(rv) | |
| 316 return rv | |
| 317 | 326 |
| 318 def __getstate__(self): | 327 def __getstate__(self): |
| 319 return (1, self.parent, self.is_sub_root) | 328 return (1, self.parent, self.is_sub_root) |
| 320 | 329 |
| 321 def __setstate__(self, state): | 330 def __setstate__(self, state): |
| 445 else: | 454 else: |
| 446 if key is _SENTINEL and index is _SENTINEL: | 455 if key is _SENTINEL and index is _SENTINEL: |
| 447 raise TypeError("one of `key` and `index` must be given in a non-root context") | 456 raise TypeError("one of `key` and `index` must be given in a non-root context") |
| 448 if root_object is not _SENTINEL: | 457 if root_object is not _SENTINEL: |
| 449 raise TypeError("non-root context may not have a root object") | 458 raise TypeError("non-root context may not have a root object") |
| 459 self.root_object = root_object | |
| 450 if root_schema is not _SENTINEL: | 460 if root_schema is not _SENTINEL: |
| 451 raise TypeError("non-root context may not have a root schema") | 461 raise TypeError("non-root context may not have a root schema") |
| 462 self.root_schema = root_schema | |
| 452 if key is not _SENTINEL and index is not _SENTINEL: | 463 if key is not _SENTINEL and index is not _SENTINEL: |
| 453 raise ValueError("only one of `key` and `index` may be given in a context") | 464 raise ValueError("only one of `key` and `index` may be given in a context") |
| 454 if key_index is not _SENTINEL and key is _SENTINEL: | 465 if key_index is not _SENTINEL and key is _SENTINEL: |
| 455 raise ValueError("when having a `key_index` a `key` also must be given") | 466 raise ValueError("when having a `key_index` a `key` also must be given") |
| 456 self._parent = parent | 467 self._parent = parent |
| 470 if ver == 1: | 481 if ver == 1: |
| 471 _dummy, self._parent, self._key, self._key_index, self._index, self.root_object, self.root_schema, self._current_object, self._settings = state | 482 _dummy, self._parent, self._key, self._key_index, self._index, self.root_object, self.root_schema, self._current_object, self._settings = state |
| 472 else: | 483 else: |
| 473 raise pickle.UnpicklingError( | 484 raise pickle.UnpicklingError( |
| 474 "Unsupported pickle version for _Context: %d" % (ver,)) | 485 "Unsupported pickle version for _Context: %d" % (ver,)) |
| 486 | |
| 487 def __eq__(self, other): | |
| 488 if not isinstance(other, Context): | |
| 489 return NotImplemented | |
| 490 return ((self._parent == other._parent) | |
| 491 and (self._key == other._key) | |
| 492 and (self._key_index == other._key_index) | |
| 493 # XXX FIXME ??? | |
| 494 # and (self.root_object == other.root_object) | |
| 495 # and (self.root_schema == other.root_schema) | |
| 496 # and (self._current_object == other._current_object) | |
| 497 and (self._settings == other._settings) | |
| 498 ) | |
| 499 | |
| 500 def __ne__(self, other): | |
| 501 # | |
| 502 # While the default in Python3 is sensible implementing is recommended | |
| 503 # when a built-in __eq__ is overwritten (Raymond Hettinger). | |
| 504 # | |
| 505 # Do not use not self == other because NotImplemented is not handled | |
| 506 # properly in some early Python versions (including Py2). | |
| 507 # | |
| 508 equal = self.__eq__(other) | |
| 509 return NotImplemented if equal is NotImplemented else not equal | |
| 475 | 510 |
| 476 @property | 511 @property |
| 477 def parent(self): | 512 def parent(self): |
| 478 return self._parent | 513 return self._parent |
| 479 | 514 |
