Skip to content

Instantly share code, notes, and snippets.

@zeha
Created February 16, 2013 02:04
Show Gist options
  • Save zeha/4965133 to your computer and use it in GitHub Desktop.
Save zeha/4965133 to your computer and use it in GitHub Desktop.
Quick DSL example for Python
from __future__ import print_function
from contextlib import contextmanager
class DslRunner(object):
"""Runs Python code in the context of a class.
Public methods will be exposed to the DSL code.
"""
def __init__(self, contextclass):
self.contextclass = contextclass
def make_context(self):
ctx = self.contextclass()
ctxmap = {}
method_names = [fun for fun in ctx.__class__.__dict__ if not fun.startswith('_')]
methods = ctx.__class__.__dict__
def method_caller(fun):
unbound = methods[fun]
def wrapped(*args, **kw):
args = (ctx,) + args
return unbound(*args, **kw)
return wrapped
for fun in method_names:
ctxmap[fun] = method_caller(fun)
return (ctx, ctxmap)
def execfile(self, filename):
ctx, ctxmap = self.make_context()
execfile(filename, {}, ctxmap)
return ctx
class MyContext(object):
"""DSL Context class. All methods not starting with an underscore
are exposed."""
def __init__(self):
self.cities = []
self.bars = []
def bar(self, name):
self.bars.append(name)
@contextmanager
def city(self, name):
self.cities.append(name)
yield
print("back from city %r" % name)
if __name__ == "__main__":
import sys
ctx = DslRunner(MyContext).execfile(sys.argv[1])
print("cities:", ctx.cities)
print("bars:", ctx.bars)
bar("room minibar")
with city("Vienna"):
bar("Silver Bar")
bar("D Bar")
bar("Rosengarten")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment