Source code for srcgen.python

from __future__ import with_statement
import pickle
import six
from contextlib import contextmanager
from srcgen.base import BaseModule, BaseE, R


class PythonModule(BaseModule):
    def comment(self, *lines, **kwargs):
        box = kwargs.pop("box", False)
        sep = kwargs.pop("sep", False)
        if sep and box:
            self._append("")
            self._append("#" * self._line_width)
        elif sep:
            self._append("#")
        elif box:
            self._append("#" * self._line_width)
        self._curr.extend("# %s" % (l,) for l in "\n".join(lines).splitlines())
        if sep and box:
            self._append("#" * self._line_width)
            self._append("")
        elif sep:
            self._append("#")
        elif box:
            self._append("#" * self._line_width)    
    
    #
    # Statements
    #
    def stmt(self, text, *args):
        self._append(text.format(*args) if args else text)
    def doc(self, text):
        self.stmt(repr(text))
    def break_(self):
        self.stmt("break")
    def continue_(self):
        self.stmt("continue")
    def return_(self, expr, *args):
        self.stmt("return %s" % (expr,), *args)
    def yield_(self, expr, *args):
        self.stmt("yield %s" % (expr,), *args)
    def raise_(self, expr, *args):
        self.stmt("raise %s" % (expr,), *args)
    def import_(self, modname):
        self.stmt("import %s" % (modname,))
    def from_(self, modname, *attrs):
        self.stmt("from %s import %s" % (modname, ", ".join(attrs)))
    def pass_(self):
        self.stmt("pass")
    
    #
    # Suites
    #
    @contextmanager
    def suite(self, headline, *args):
        self.stmt(headline, *args)
        prev = self._curr
        self._curr = []
        prev.append(self._curr)
        yield
        self._curr = prev
    def if_(self, cond, *args):
        return self.suite("if %s:" % (cond,), *args)
    def elif_(self, cond, *args):
        return self.suite("elif %s:" % (cond,), *args)
    def else_(self):
        return self.suite("else:")
    def for_(self, var, expr):
        return self.suite("for %s in %s:" % (var, expr))
    def while_(self, cond, *args):
        return self.suite("while %s:" % (cond,), *args)
    def try_(self):
        return self.suite("try:")
    def except_(self, exceptions, var = None):
        if var:
            return self.suite("except (%s) as %s:" % (", ".join(exceptions), var))
        else:
            return self.suite("except (%s):" % (", ".join(exceptions),))
    def finally_(self):
        return self.suite("finally:")
    @contextmanager
    def def_(self, name, *args):
        with self.suite("def %s(%s):" % (name, ", ".join(str(a) for a in args))): yield
        self.sep()

    @contextmanager
    def class_(self, name, bases = ("object",)):
        if isinstance(bases, six.string_types):
            bases = (bases,)
        with self.suite("class %s(%s):" % (name, ", ".join(bases,))): yield
        self.sep()

    @contextmanager
    def cython(self):
        mod = CythonModule()
        mod._curr = self._curr
        yield mod

    def method(self, name, *args):
        args = ("self",) + args
        return self.def_(name, *args)
    def classmethod(self, name, *args):
        args = ("cls",) + args
        self.stmt("@classmethod")
        return self.def_(name, *args)
    def staticmethod(self, name, *args):
        self.stmt("@staticmethod")
        return self.def_(name, *args)


class CythonModule(PythonModule):
    def __init__(self, *args, **kwargs):
        PythonModule.__init__(self, *args, **kwargs)
        self._in_cdef = False
        
    @property
    def cdef(self):
        self._in_cdef = True
        return self
    
    @contextmanager
    def __call__(self, name, *args):
        assert self._in_cdef
        with self.suite("%s(%s):" % (name, ", ".join(str(a) for a in args))): yield
        self.sep()
    
    def stmt(self, text, *args):
        in_cdef = self._in_cdef
        self._in_cdef = False
        PythonModule.stmt(self, ("cdef " + text) if in_cdef else text, *args)
    
    def typedef(self, type, newname):
        self.stmt("ctypedef %s %s" % (type, newname))
    
    @contextmanager
    def suite(self, text, *args):
        in_cdef = self._in_cdef
        self._in_cdef = False
        with PythonModule.suite(self, ("cdef " + text) if in_cdef else text, *args): yield
    
    def cppclass(self, name, bases = ()):
        return self.suite("cppclass %s:" % (name))
    
    @contextmanager
    def extern(self, from_ = None, namespace = None):
        head = "extern"
        if from_:
            head += ' from "%s"' % (repr(from_)[1:-1],)
        if namespace:
            head += ' namespace "%s"' % (repr(namespace)[1:-1],)
        with self.suite(head): yield
        self.sep()
    
    @contextmanager
    def struct(self, name):
        with self.suite("struct %s:" % (name,)): yield
        self.sep()
    @contextmanager
    def union(self, name):
        with self.suite("union %s:" % (name,)): yield
        self.sep()
    @contextmanager
    def enum(self, name):
        with self.suite("enum %s:" % (name,)): yield
        self.sep()

    @contextmanager
    def property(self, name):
        with self.suite("property %s:" % (name,)): yield
        self.sep()
    @contextmanager
    def get(self):
        with self.suite("def __get__(self):"): yield
        self.sep()
    @contextmanager
    def set(self):
        with self.suite("def __set__(self, value):"): yield
        self.sep()
    @contextmanager
    def get_property(self, name):
        with self.property(name):
            with self.get():
                yield


[docs]class P(object): """ Pickled object """ __slots__ = ["data"] def __init__(self, obj): self.data = "pickle.loads(%r)" % (pickle.dumps(obj),) def __str__(self): return self.data __repr__ = __str__
class E(BaseE): __slots__ = [] def __floordiv__(self, other): return E("(%r // %r)" % (self, other)) def __or__(self, other): return E("(%r or %r)" % (self, other)) def __and__(self, other): return E("(%r and %r)" % (self, other)) def __rfloordiv__(self, other): return E("(%r // %r)" % (other, self)) def __ror__(self, other): return E("(%r or %r)" % (other, self)) def __rand__(self, other): return E("(%r and %r)" % (other, self)) def __inv__(self): return E("not %r" % (self,)) __invert__ = __inv__ def __call__(self, *args, **kwargs): textargs = "" if args: textargs += ", ".join(repr(a) for a in args) if kwargs: if args: textargs += ", " textargs += ",".join("%s = %r" % (k, v) for k, v in kwargs.items()) return E("%r(%s)" % (self, textargs))