Created
February 16, 2013 02:04
-
-
Save zeha/4965133 to your computer and use it in GitHub Desktop.
Quick DSL example for Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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