Skip to content

Instantly share code, notes, and snippets.

@tai
Created July 3, 2015 13:41
Show Gist options
  • Select an option

  • Save tai/dbd2ae1722c477d9c2fd to your computer and use it in GitHub Desktop.

Select an option

Save tai/dbd2ae1722c477d9c2fd to your computer and use it in GitHub Desktop.
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
A skelton code of a framework that wraps user function
without any modification. This makes framework really
transparent and help keeping user's code clean.
The problem is that once user function gets enhanced
and needs some framework-dependent info (like processing
context), it is hard to pass it down. Hence this code to
solve the problem.
This framework "sandwitches" a user function in following manner:
[framework] callfunc()
-> [user] userfunc()
-> [framework] get_context()
Whenever userfunc needs some extra framework data,
it can call get_context() API to obtain one.
With a help of yield call, get_context() obtains
data in callfunc() namespace and returns it to userfunc.
It'd be perfect if Python can hide a yield call needed
in userfunc with some meta-programming, but it seems
current Python does not have that capability.
"""
# request id used by inter-framework protocol
GET_CONTEXT = 1
def frameworkapi(func):
"""Decorates user function so it can be embedded in the framework"""
return func
@frameworkapi
def userfunc(a, b, c):
"""user function to be wrapped by this framework"""
# obtain extra data from side-channel (= over yield call)
ctx = yield from get_context()
print("userfunc: ctx=" + str(ctx))
return a + b + c
def callfunc(func, *args):
"""Calls user function, with a side-channel to exchange extra data"""
ctx = "some extra framework context"
gen = func(*args)
# inter-framework protocol handler
try:
yield_ret = None
while True:
yield_arg = gen.send(yield_ret)
yield_ret = None
if yield_arg == GET_CONTEXT:
yield_ret = ctx
except StopIteration as func_ret:
return func_ret.value
def get_context():
ret = yield GET_CONTEXT
return ret
ret = callfunc(userfunc, 1, 2, 3)
print("userfunc: ret=%s" % str(ret))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment