Source code for jsondata

"""Modular processing of JSON data by trees and branches, pointers and patches.
"""

import sys
import os

import filesysobjects.userdata
import filesysobjects.osdata

__author__ = 'Arno-Can Uestuensoez'
__maintainer__ = 'Arno-Can Uestuensoez'
__license__ = "Artistic-License-2.0 + Forced-Fairplay-Constraints"
__copyright__ = "Copyright (C) 2015-2016 Arno-Can Uestuensoez" \
                " @Ingenieurbuero Arno-Can Uestuensoez"
__version__ = '0.2.21'
__uuid__ = '63b597d6-4ada-4880-9f99-f5e0961351fb'


#
# used for default names
appname = 'jsondata'

[docs]class JSONDataError(Exception): """ base Exception.""" def __init__(self, *arg): """To be replaced by derived Exceptions. Fetch standard parameters and forward message to base class 'Exception'. """ self.fetch(*arg) Exception.__init__(self, self.s) def fetch(self, *arg): """Fetch arguments. Args: *args: The following order is expected: 0. Reason of exception. 1. Name of object that caused the exception. 2. Value of the object. Returns: None. Raises: None. """ self.s = "" for a in arg: self.s += ":" + str(a) self.s = self.s[1:] def __repr__(self): """Cause: <reason>:<object>:<value>""" return self.s def __str__(self): """Cause with additional header text.""" return "ERROR::" + self.s
# Sets display for inetractive JSON/JSONschema design. _interactive = False V3K = False #: Python3.5+ if sys.version_info[:2] > (3, 4,): V3K = True ISSTR = (str,) """string and unicode""" elif sys.version_info[:2] > (2, 6,) and sys.version_info[:2][0] < 3: ISSTR = (str, unicode,) # @UndefinedVariable """string and unicode""" else: raise JSONDataError( "Requires Python 2.7+, or 3.5+:" + str(sys.version_info[:2])) # # generic exceptions #
[docs]class JSONDataIndexError(JSONDataError, IndexError): """ Error on key.""" def __init__(self, *arg): JSONDataError.__init__(self, *arg) JSONDataError.fetch(self, *arg) IndexError.__init__(self, self.s) def __str__(self): return "JSONDataIndexError:" + self.s
[docs]class JSONDataKeyError(JSONDataError, KeyError): """ Error on key.""" def __init__(self, *arg): JSONDataError.__init__(self, *arg) JSONDataError.fetch(self, *arg) KeyError.__init__(self, self.s) def __str__(self): return "JSONDataKeyError:" + self.s
[docs]class JSONDataPathError(JSONDataError, KeyError): """ Error on key.""" def __init__(self, *arg): JSONDataError.__init__(self, *arg) JSONDataError.fetch(self, *arg) KeyError.__init__(self, self.s) def __str__(self): return "JSONDataPathError:" + self.s
class JSONDataNodeError(JSONDataError): """ Error on node, slightly different from key.""" def __str__(self): return "JSONDataNodeError:" + self.s
[docs]class JSONDataNodeTypeError(JSONDataError): """ Error on NodeTypes.""" def __str__(self): return "JSONDataNodeTypeError:" + self.s
[docs]class JSONDataParameterError(JSONDataError): """ Erroneous parameters.""" def __str__(self): return "JSONDataParameterError:" + self.s
[docs]class JSONDataSourceFileError(JSONDataError): """ Error on read of a source file.""" def __str__(self): return "JSONDataSourceFileError:" + self.s
[docs]class JSONDataModeError(JSONDataError): """ Type error of source file content.""" def __str__(self): return "JSONDataModeError:" + self.s
[docs]class JSONDataTargetFileError(JSONDataError): """ Error on writing a file.""" def __str__(self): return "JSONDataTargetFileError:" + self.s
[docs]class JSONDataValueError(JSONDataError): """ Error on a value.""" def __str__(self): return "JSONDataValueError:" + self.s
[docs]class JSONDataAmbiguityError(Exception): """ Error ambiguity of provided parameters.""" def __init__(self, requested, *sources): if _interactive: self.s = "Ambiguious input for:\n " + str(requested) for sx in sources: self.s += "\n " + str(sx) else: self.s = "Ambiguious input for:" + str(requested) for sx in sources: self.s += ":" + str(sx) Exception.__init__(self, self.s) def __str__(self): return "JSONDataAmbiguityError:" + self.s
[docs]class JSONPointerError(JSONDataError): """ Pointer error.""" pass
[docs]class JSONPointerTypeError(JSONDataError): """ Pointer type error, the JSON pointer syntax does not represent a valid pointer.""" pass
class JSONTypeError(JSONDataError): """ Pointer error.""" pass class JSONDiffError(JSONDataError): """Error in JSONDiff.""" pass class JSONSearchError(JSONDataError): """Error in JSONSearch.""" pass
[docs]class JSONDataPatchError(JSONDataError): pass
[docs]class JSONDataPatchItemError(JSONDataPatchError): pass
# # mode of operations # MJ_RFC4627 = 1 #: The first JSON RFC. MJ_RFC7493 = 2 #: The IJSON RFC. MJ_RFC7159 = 2 #: The JSON RFC by 'now'. MJ_RFC8259 = 4 #: The JSON RFC by 'now'. MJ_ECMA404 = 16 #: The first JSON EMCMA standard. MJ_RFC6901 = 32 #: JSONPointer first IETF RFC. MJ_RELPOINTERD1 = 64 #: JSONPointer - relative pointer Draft-1. MJ_RFC6902 = 128 #: JSONPatch first IETF RFC. MJ_DEFAULT = MJ_RFC7159 # # validation of schemes # MS_OFF = 40 #: No validation. MS_DRAFT3 = 43 #: The first supported JSONSchema IETF-Draft. MS_DRAFT4 = 44 #: The current supported JSONSchema IETF-Draft. MS_ON = MS_DRAFT4 #: The current when the default is activated. MODE_SCHEMA_DEFAULT = MS_OFF #: The current default validation mode. str2mj = { "rfc4627": MJ_RFC4627, "rfc7493": MJ_RFC7493, "rfc7159": MJ_RFC7159, "rfc8259": MJ_RFC8259, "relpointerD1": MJ_RELPOINTERD1, "ecma404": MJ_ECMA404, "rfc6901": MJ_RFC6901, "rfc6902": MJ_RFC6902, "oss": MS_OFF, str(MJ_RFC4627): MJ_RFC4627, str(MJ_RFC7493): MJ_RFC7493, str(MJ_RFC7159): MJ_RFC7159, str(MJ_RFC8259): MJ_RFC8259, str(MJ_ECMA404): MJ_ECMA404, str(MJ_RFC6901): MJ_RFC6901, str(MJ_RELPOINTERD1): MJ_RELPOINTERD1, str(MJ_RFC6902): MJ_RFC6902, str(MS_OFF): MS_OFF, MJ_RFC4627: MJ_RFC4627, MJ_RFC7493: MJ_RFC7493, MJ_RFC7159: MJ_RFC7159, MJ_ECMA404: MJ_ECMA404, MJ_RFC6901: MJ_RFC6901, MJ_RFC6902: MJ_RFC6902, MS_OFF: MS_OFF, } mj2str = { MJ_RFC4627: "rfc4627", MJ_RFC7493: "rfc7493", MJ_RFC7159: "rfc7159", MJ_RFC8259: "rfc8259", MJ_RELPOINTERD1: "relpointerD1", MJ_ECMA404: "ecma404", MJ_RFC6901: "rfc6901", MJ_RFC6902: "rfc6902", MS_OFF: "off", } # # match criteria for node comparison # MATCH_INSERT = 0 #: for dicts MATCH_NO = 1 #: negates the whole set MATCH_KEY = 2 #: for dicts MATCH_CHLDATTR = 3 #: for dicts and lists MATCH_INDEX = 4 #: for lists MATCH_MEM = 5 #: for dicts(value) and lists MATCH_NEW = 6 #: If not present create a new, else ignore and keep present untouched. MATCH_PRESENT = 7 #: Check all are present, else fails. # # application constraints and types for branch operations :: # res = a OP b # B_ALL = 0 #: OP-On-Branches: process in any case. B_AND = 1 #: OP-On-Branches: process only when both present. B_OR = 2 #: OP-On-Branches: process if one at all is present. B_XOR = 4 #: OP-On-Branches: process if only one is present. B_ADD = 8 #: OP-On-Branches: add in accordance to RFC6902 B_MOD = 16 #: OP-On-Branches: modulo of branches. B_SUB = 32 #: OP-On-Branches: subtract branches. # # copy property # C_REF = 0 #: OP-Copy: Copy reference. C_DEEP = 1 #: OP-Copy: Copy deep. C_SHALLOW = 2 #: OP-Copy: Copy shallow. C_DEFAULT = C_REF #: Default value. # # application-scope # SC_DATA = 0 #: OP-Scope: the managed JSON data only SC_SCHEMA = 1 #: OP-Scope: the managed JSON schema only SC_JSON = 2 #: OP-Scope: the managed JSON data and schema only. SC_OBJ = 3 #: OP-Scope: the attributes of current instance. SC_ALL = 4 #: OP-Scope: the complete object, including data. # # data-scope # SD_BOTH = 0 #: Apply on mixed input and output data. SD_INPUT = 1 #: Apply on input data. SD_OUTPUT = 2 #: Apply on output data. # # sort order # S_NONE = 0 # no sort S_SIMPLE = 1 # goups upper lower # # return types # R_OBJ = 0 #: Return object of type self. R_DATA = 1 #: Return self.data. R_JDATA = 2 #: Return object of type JSONData. # # types of return values # RT_STR = 1 #: string - 'str' or 'unicode' RT_DICT = 2 #: dict RT_LST = 4 #: list RT_JSONPOINTER = 8 #: JSONPointer RT_JSONPATCH= 16 #: JSONPatch RT_JSONDATA = 32 #: JSONData RT_DEFAULT = RT_JSONPOINTER #: default rtypes2num = { 'RT_DICT': RT_DICT, 'RT_JSONDATA': RT_JSONDATA, 'RT_JSONPATCH': RT_JSONPATCH, 'RT_JSONPOINTER': RT_JSONPOINTER, 'RT_LST': RT_LST, 'RT_STR': RT_STR, 'default': RT_DEFAULT, 'dict': RT_DICT, 'jdata': RT_JSONPATCH, 'jpatch': RT_JSONDATA, 'jpointer': RT_JSONPOINTER, 'list': RT_LST, 'str': RT_STR, None: RT_DEFAULT, RT_DEFAULT: RT_DEFAULT, RT_DICT: RT_DICT, RT_JSONDATA: RT_JSONDATA, RT_JSONPATCH: RT_JSONPATCH, RT_JSONPOINTER: RT_JSONPOINTER, RT_LST: RT_LST, RT_STR: RT_STR, } # # match sets # M_FIRST = 1 #: First match only. M_LAST = 2 #: Last match only. M_ALL = 4 #: All matches. # # verify pointers against jsondata # V_NONE = 1 #: no checks at all V_FINAL = 2 #: checks final result only V_STEPS = 4 #: checks each intermediate directory V_DEFAULT = V_NONE #: default verify2num = { 'V_DEFAULT': V_DEFAULT, 'V_FINAL': V_FINAL, 'V_NONE': V_NONE, 'V_STEPS': V_STEPS, 'default': V_DEFAULT, 'final': V_FINAL, 'none': V_NONE, 'steps': V_STEPS, None: V_DEFAULT, V_DEFAULT: V_DEFAULT, V_FINAL: V_FINAL, V_NONE: V_NONE, V_STEPS: V_STEPS, } # # display formats for JSONDiff # DF_SUMUP = 0 # short list DF_CSV = 1 # csv, for now semicolon only DF_JSON = 3 # JSON struture DF_TABLE = 4 # table, for now fixed DF_REVIEW = 5 # short for quick review format DF_REPR = 6 # repr() - raw string, Python syntax DF_STR = 7 # str() - formatted string, Python syntax str2df = { 'sumup': DF_SUMUP, 'csv': DF_CSV, 'json': DF_JSON, 'review': DF_REVIEW, 'repr': DF_REPR, 'str': DF_STR, 'tabble': DF_TABLE, str(DF_SUMUP): DF_SUMUP, str(DF_CSV): DF_CSV, str(DF_JSON): DF_JSON, str(DF_REVIEW): DF_REVIEW, str(DF_REPR): DF_REPR, str(DF_STR): DF_STR, str(DF_TABLE): DF_TABLE, DF_SUMUP: DF_SUMUP, DF_CSV: DF_CSV, DF_JSON: DF_JSON, DF_REVIEW: DF_REVIEW, DF_REPR: DF_REPR, DF_STR: DF_STR, DF_TABLE: DF_TABLE, } df2str = { DF_SUMUP: 'sumup', DF_CSV: 'csv', DF_JSON: 'json', DF_REVIEW: 'review', DF_REPR: 'repr', DF_STR: 'str', DF_TABLE: 'tabble', } # # display formats for JSONData # PJ_TREE = 0 #: tree view JSON syntax PJ_FLAT = 1 #: flat print JSON syntax PJ_PYTREE = 2 #: tree view Python syntax PJ_PYFLAT = 3 #: flat print Python syntax PJ_REPR = 4 #: repr() - raw string, Python syntax PJ_STR = 5 #: str() - formatted string, Python syntax str2pj = { 'tree': PJ_TREE, 'flat': PJ_FLAT, 'pytree': PJ_PYTREE, 'pyflat': PJ_PYFLAT, 'repr': PJ_REPR, 'str': PJ_STR, str(PJ_TREE): PJ_TREE, str(PJ_FLAT): PJ_FLAT, str(PJ_PYTREE): PJ_PYTREE, str(PJ_PYFLAT): PJ_PYFLAT, str(PJ_REPR): PJ_REPR, str(PJ_STR): PJ_STR, PJ_TREE: PJ_TREE, PJ_FLAT: PJ_FLAT, PJ_PYTREE: PJ_PYTREE, PJ_PYFLAT: PJ_PYFLAT, PJ_REPR: PJ_REPR, PJ_STR: PJ_STR, } pj2str = { PJ_TREE: 'tree', PJ_FLAT: 'flat', PJ_PYTREE: 'pytree', PJ_PYFLAT: 'pyflat', PJ_REPR: 'repr', PJ_STR: 'str', } # # Notation at the API - in/out. # NOTATION_NATIVE = 0 #: JSON notation in accordance to RFC7159 NOTATION_JSON = 1 #: JSON notation in accordance to RFC7159 NOTATION_JSON_REL = 2 #: JSON notation as relative pointer NOTATION_HTTP_FRAGMENT = 3 #: JSON notation in accordance to RFC7159 with RFC3986. # # character display # CHARS_RAW = 0 #: display character set as raw CHARS_STR = 1 #: display character set as str CHARS_UTF = 2 #: display character set as utf # # line handling for overflow # LINE_CUT = 0 #: force line fit LINE_WRAP = 1 #: wrap line in order to fit to length # # search parameters # SEARCH_FIRST = 0 #: Break display after first match. SEARCH_ALL = 1 #: List all matches. # # pointer style # PT_PATH = 0 #: Displays a list of items. PT_RFC6901 = 1 #: Displays rfc6901 strings. PT_NODE = 2 #: Displays the node. # # json syntax # JSYN_NATIVE = 1 #: Literally in accordance to standards. JSYN_PYTHON = 2 #: Python in-memory syntax representation. # maps match strings and enums onto match-enums match2match ={ 'child_attr_list': MATCH_CHLDATTR, 'index': MATCH_INDEX, 'key': MATCH_KEY, 'mem': MATCH_MEM, 'new': MATCH_NEW, 'no': MATCH_NO, 'present': MATCH_PRESENT, MATCH_CHLDATTR: MATCH_CHLDATTR, MATCH_INDEX: MATCH_INDEX, MATCH_KEY: MATCH_KEY, MATCH_MEM: MATCH_MEM, MATCH_NEW: MATCH_NEW, MATCH_NO: MATCH_NO, MATCH_PRESENT: MATCH_PRESENT, } # maps mode strings and enums onto mde-enums mode2mj = { 'default': MJ_RFC7159, 'ecma404': MJ_RFC8259, 'rfc4627': MJ_RFC4627, 'rfc7159': MJ_RFC7159, 'rfc7493': MJ_RFC7493, 'rfc8259': MJ_RFC8259, MJ_ECMA404: MJ_RFC8259, MJ_RFC4627: MJ_RFC4627, MJ_RFC7159: MJ_RFC7159, MJ_RFC7493: MJ_RFC7493, MJ_RFC8259: MJ_RFC8259, } # maps validator strings and enums onto validator-enums validator2ms = { 'default': MS_DRAFT4, 'draft3': MS_DRAFT3, 'off': MS_OFF, MS_DRAFT3: MS_DRAFT3, MS_DRAFT4: MS_DRAFT4, MS_OFF: MS_OFF, } # maps copy strings and enums onto copy-enums copy2c = { 'deep': C_DEEP, 'default': C_REF, 'ref': C_REF, 'shallow': C_SHALLOW, C_DEEP: C_DEEP, C_REF: C_REF, C_SHALLOW: C_SHALLOW, } # # for now hard-coded # consolewidth = 80 # # misc # _verbose = 0 # common verbose variable _debug = 0 # common verbose variable