Skip to content

# Preserves Schema

This is an implementation of Preserves Schema for Python 3.

TODO

## `meta = load_schema_file(__metaschema_filename).schema` `module-attribute`

TODO

## `Compiler()`

TODO

Source code in `preserves/schema.py`

    470
    471

    def __init__(self):
        self.root = Namespace(())

## `Definition(*args, **kwargs)`

Bases: `SchemaObject`

TODO

Source code in `preserves/schema.py`

    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290

    def __init__(self, *args, **kwargs):
        self._fields = args
        if self.SIMPLE:
            if self.EMPTY:
                if len(args) != 0:
                    raise TypeError('%s takes no arguments' % (self._constructor_name(),))
            else:
                if len(args) != 1:
                    raise TypeError('%s needs exactly one argument' % (self._constructor_name(),))
                self.value = args[0]
        else:
            i = 0
            for arg in args:
                if i >= len(self.FIELD_NAMES):
                    raise TypeError('%s given too many positional arguments' % (self._constructor_name(),))
                setattr(self, self.SAFE_FIELD_NAMES[i], arg)
                i = i + 1
            for (argname, arg) in kwargs.items():
                if hasattr(self, argname):
                    raise TypeError('%s given duplicate attribute: %r' % (self._constructor_name, argname))
                if argname not in self.SAFE_FIELD_NAMES:
                    raise TypeError('%s given unknown attribute: %r' % (self._constructor_name, argname))
                setattr(self, argname, arg)
                i = i + 1
            if i != len(self.FIELD_NAMES):
                raise TypeError('%s needs argument(s) %r' % (self._constructor_name(), self.FIELD_NAMES))

## `Enumeration()`

Bases: `SchemaObject`

TODO

Source code in `preserves/schema.py`

    206
    207

    def __init__(self):
        raise TypeError('Cannot create instance of Enumeration')

## `Namespace(prefix)`

TODO

Source code in `preserves/schema.py`

    447
    448

    def __init__(self, prefix):
        self._prefix = prefix

## `SchemaDecodeFailed(cls, p, v, failures=None)`

Bases: `ValueError`

TODO

Source code in `preserves/schema.py`

    43
    44
    45
    46
    47
    48

    def __init__(self, cls, p, v, failures=None):
        super().__init__()
        self.cls = cls
        self.pattern = p
        self.value = v
        self.failures = [] if failures is None else failures

## `SchemaObject`

TODO

### `__preserve__()`

TODO

Source code in `preserves/schema.py`

    184
    185
    186

    def __preserve__(self):
        """TODO"""
        raise NotImplementedError('Subclass responsibility')

### `decode(v)` `classmethod`

TODO

Source code in `preserves/schema.py`

    94
    95
    96
    97

    @classmethod
    def decode(cls, v):
        """TODO"""
        raise NotImplementedError('Subclass responsibility')

### `try_decode(v)` `classmethod`

TODO

Source code in `preserves/schema.py`

     99
    100
    101
    102
    103
    104
    105

    @classmethod
    def try_decode(cls, v):
        """TODO"""
        try:
            return cls.decode(v)
        except SchemaDecodeFailed:
            return None

## `encode(p, v)`

TODO

Source code in `preserves/schema.py`

    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390

    def encode(p, v):
        """TODO"""
        if hasattr(v, '__escape_schema__'):
            return preserve(v.__escape_schema__())
        if p == ANY:
            return v
        if p.key == NAMED:
            return encode(p[1], safegetattr(v, p[0].name))
        if p.key == ATOM:
            return v
        if p.key == EMBEDDED:
            return Embedded(v)
        if p.key == LIT:
            return p[0]
        if p.key == SEQOF:
            return tuple(encode(p[0], w) for w in v)
        if p.key == SETOF:
            return set(encode(p[0], w) for w in v)
        if p.key == DICTOF:
            return dict((encode(p[0], k), encode(p[1], w)) for (k, w) in v.items())
        if p.key == REF:
            return preserve(v)
        if p.key == REC:
            return Record(encode(p[0], v), encode(p[1], v))
        if p.key == TUPLE:
            return tuple(encode(pp, v) for pp in p[0])
        if p.key == TUPLE_PREFIX:
            return tuple(encode(pp, v) for pp in p[0]) + encode(p[1], v)
        if p.key == DICT:
            return dict((k, encode(pp, v)) for (k, pp) in p[0].items())
        if p.key == AND:
            return merge(*[encode(pp, v) for pp in p[0]])
        raise ValueError(f'Bad schema {p}')

## `extend(cls)`

TODO

Source code in `preserves/schema.py`

    510
    511
    512
    513
    514
    515

    def extend(cls):
        """TODO"""
        def extender(f):
            setattr(cls, f.__name__, f)
            return f
        return extender

## `load_schema_file(filename)`

TODO

Source code in `preserves/schema.py`

    503
    504
    505
    506
    507

    def load_schema_file(filename):
        """TODO"""
        c = Compiler()
        c.load(filename)
        return c.root

Last update: March 16, 2023
Created: March 16, 2023