78 lines
1.8 KiB
Python
78 lines
1.8 KiB
Python
from .base import SchemaStrategy, TypedSchemaStrategy
|
|
|
|
|
|
class Typeless(SchemaStrategy):
|
|
"""
|
|
schema strategy for schemas with no type. This is only used when
|
|
there is no other active strategy, and it will be merged into the
|
|
first typed strategy that gets added.
|
|
"""
|
|
|
|
@classmethod
|
|
def match_schema(cls, schema):
|
|
return 'type' not in schema
|
|
|
|
@classmethod
|
|
def match_object(cls, obj):
|
|
return False
|
|
|
|
|
|
class Null(TypedSchemaStrategy):
|
|
"""
|
|
strategy for null schemas
|
|
"""
|
|
JS_TYPE = 'null'
|
|
PYTHON_TYPE = type(None)
|
|
|
|
|
|
class Boolean(TypedSchemaStrategy):
|
|
"""
|
|
strategy for boolean schemas
|
|
"""
|
|
JS_TYPE = 'boolean'
|
|
PYTHON_TYPE = bool
|
|
|
|
|
|
class String(TypedSchemaStrategy):
|
|
"""
|
|
strategy for string schemas - works for ascii and unicode strings
|
|
"""
|
|
JS_TYPE = 'string'
|
|
PYTHON_TYPE = str
|
|
|
|
|
|
class Number(SchemaStrategy):
|
|
"""
|
|
strategy for integer and number schemas. It automatically
|
|
converts from `integer` to `number` when a float object or a
|
|
number schema is added
|
|
"""
|
|
JS_TYPES = ('integer', 'number')
|
|
PYTHON_TYPES = (int, float)
|
|
|
|
@classmethod
|
|
def match_schema(cls, schema):
|
|
return schema.get('type') in cls.JS_TYPES
|
|
|
|
@classmethod
|
|
def match_object(cls, obj):
|
|
# cannot use isinstance() because boolean is a subtype of int
|
|
return type(obj) in cls.PYTHON_TYPES
|
|
|
|
def __init__(self, node_class):
|
|
super().__init__(node_class)
|
|
self._type = 'integer'
|
|
|
|
def add_schema(self, schema):
|
|
super().add_schema(schema)
|
|
if schema.get('type') == 'number':
|
|
self._type = 'number'
|
|
|
|
def add_object(self, obj):
|
|
if isinstance(obj, float):
|
|
self._type = 'number'
|
|
|
|
def to_schema(self):
|
|
schema = super().to_schema()
|
|
schema['type'] = self._type
|
|
return schema
|