Paste number 69988: Cython version of capbase.py

Paste number 69988: Cython version of capbase.py
Pasted by: tav
When:1 year, 9 months ago
Share:Tweet this! | http://paste.lisp.org/+1I04
Channel:#esp
Paste contents:
Raw Source | XML | Display As
from weakref import ref
from sys import _getframe as get_frame
from types import FunctionType

cdef extern from "Python.h":
    ctypedef void PyObject
    ctypedef struct PyTypeObject
    int PyObject_TypeCheck(object, PyTypeObject*)
    bint PyFunction_Check(object o)
    int PyDict_Contains(object p, object key)
    int PyDict_SetItemString(object p, char *key, object val)
    object PyDict_Keys(object p)

cdef inline bint typecheck(object ob, object tp):
    return PyObject_TypeCheck(ob, <PyTypeObject*>tp)

cdef object store, inverted_store, last_id

store = {}
inverted_store = {}
last_id = [1]

cdef class Namespace:
    """A Namespace object."""

    cdef object __weakref__
    cdef object env
    cdef object val
    cdef int id

    def __cinit__(Namespace self, **env):
        cdef object key, keys, id_data, new_env, obj
        cdef int id
        if env:
            keys = tuple(env.keys())
        else:
            env = get_frame(0).f_locals
            keys = tuple([
                name for name in PyDict_Keys(env)
                if not name.startswith('_') and not name.endswith('__')
                ])
        # keys.sort()
        if PyDict_Contains(inverted_store, keys):
            # id_data = PyDict_GetItem(inverted_store, keys)
            id_data = inverted_store[keys]
            id = id_data[0]
            id_data.append(ref(self))
        else:
            id = last_id[0]
            last_id[0] = id + 1
            inverted_store[keys] = [id, ref(self)]
            store[id] = keys
        self.id = id
        # self.env = [env[key] for key in keys]
        new_env = []
        for key in keys:
            # obj = PyDict_GetItem(env, key)
            obj = env[key]
            if PyFunction_Check(obj):
                obj = staticmethod(obj)
            new_env.append(obj)
        self.env = new_env

    def __getattribute__(Namespace self, char *attr):
        cdef int i
        cdef object j, v
        i = 0
        for j in store[self.id]:
            if j == attr:
                v = self.env[i]
                if hasattr(v, '__get__'):
                    return v.__get__(None, self)
                return v
            i = i + 1
        raise AttributeError("'Namespace' object has no attribute %r" % attr)

    def __dir__(Namespace self):
        return list(store[self.id])

def get_store():
    return (store, inverted_store)

This paste has no annotations.

Colorize as:
Show Line Numbers

Lisppaste pastes can be made by anyone at any time. Imagine a fearsomely comprehensive disclaimer of liability. Now fear, comprehensively.