File: base.py

package info (click to toggle)
python-genson 1.3.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 344 kB
  • sloc: python: 1,385; makefile: 16
file content (78 lines) | stat: -rw-r--r-- 2,196 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
from copy import copy
from warnings import warn


class SchemaStrategy:
    """
    base schema strategy. This contains the common interface for
    all subclasses:

    * match_schema
    * match_object
    * __init__
    * add_schema
    * add_object
    * to_schema
    * __eq__
    """
    KEYWORDS = ('type',)

    @classmethod
    def match_schema(cls, schema):
        raise NotImplementedError("'match_schema' not implemented")

    @classmethod
    def match_object(cls, obj):
        raise NotImplementedError("'match_object' not implemented")

    def __init__(self, node_class):
        self.node_class = node_class
        self._extra_keywords = {}

    def add_schema(self, schema):
        self._add_extra_keywords(schema)

    def _add_extra_keywords(self, schema):
        for keyword, value in schema.items():
            if keyword in self.KEYWORDS:
                continue
            elif keyword not in self._extra_keywords:
                self._extra_keywords[keyword] = value
            elif self._extra_keywords[keyword] != value:
                warn(('Schema incompatible. Keyword {0!r} has conflicting '
                      'values ({1!r} vs. {2!r}). Using {1!r}').format(
                          keyword, self._extra_keywords[keyword], value))

    def add_object(self, obj):
        pass

    def to_schema(self):
        return copy(self._extra_keywords)

    def __eq__(self, other):
        """ Required for SchemaBuilder.__eq__ to work properly """
        return (isinstance(other, self.__class__)
                and self.__dict__ == other.__dict__)


class TypedSchemaStrategy(SchemaStrategy):
    """
    base schema strategy class for scalar types. Subclasses define
    these two class constants:

    * `JS_TYPE`: a valid value of the `type` keyword
    * `PYTHON_TYPE`: Python type objects - can be a tuple of types
    """

    @classmethod
    def match_schema(cls, schema):
        return schema.get('type') == cls.JS_TYPE

    @classmethod
    def match_object(cls, obj):
        return isinstance(obj, cls.PYTHON_TYPE)

    def to_schema(self):
        schema = super().to_schema()
        schema['type'] = self.JS_TYPE
        return schema