Source code for cis_interface.metaschema.datatypes.FunctionMetaschemaType

import types
import importlib
from cis_interface.metaschema.datatypes import register_type
from cis_interface.metaschema.datatypes.MetaschemaType import MetaschemaType


[docs]@register_type class FunctionMetaschemaType(MetaschemaType): r"""Type for evaluating functions.""" name = 'function' description = 'Type for callable Python functions.' python_types = (types.BuiltinFunctionType, types.FunctionType, types.BuiltinMethodType, types.MethodType)
[docs] @classmethod def normalize(cls, obj): r"""Normalize an object, if possible, to conform to this type. Args: obj (object): Object to normalize. Returns: object: Normalized object. """ if isinstance(obj, str): try: obj = cls.decode_data(obj, {'type': 'function'}) except (ValueError, AttributeError): pass return obj
[docs] @classmethod def encode_data(cls, obj, typedef): r"""Encode an object's data. Args: obj (object): Object to encode. typedef (dict): Type definition that should be used to encode the object. Returns: string: Encoded object. """ # fname = obj.__globals__['__file__'] mod = obj.__module__ fun = obj.__name__ out = '%s:%s' % (mod, fun) return out
[docs] @classmethod def decode_data(cls, obj, typedef): r"""Decode an object. Args: obj (string): Encoded object to decode. typedef (dict): Type definition that should be used to decode the object. Returns: object: Decoded object. """ pkg_mod = obj.split(':') if len(pkg_mod) != 2: raise ValueError("Could not parse function string: %s" % obj) mod, fun = pkg_mod[:] modobj = importlib.import_module(mod) if not hasattr(modobj, fun): raise AttributeError("Module %s has no funciton %s" % (modobj, fun)) return getattr(modobj, fun)