Fix examples formatting issues and make them pep8 compliant

This commit is contained in:
Jason Paryani
2013-12-11 01:59:52 -08:00
parent 5811213321
commit 03bac73120
2 changed files with 122 additions and 91 deletions

View File

@@ -7,25 +7,38 @@ import capnp
import calculator_capnp
class PowerFunction(calculator_capnp.Calculator.Function.Server):
'''An implementation of the Function interface wrapping pow(). Note that
we're implementing this on the client side and will pass a reference to
the server. The server will then be able to make calls back to the client.'''
def call(self, params, **kwargs):
'''Note the **kwargs. This is very necessary to include, since protocols can add parameters over time. Also, by default, a _context variable is passed to all server methods. Read the docs for further explanation.'''
'''Note the **kwargs. This is very necessary to include, since
protocols can add parameters over time. Also, by default, a _context
variable is passed to all server methods, but you can also return
results directly as python objects, and they'll be added to the
results struct in the correct order'''
return pow(params[0], params[1])
def parse_args():
parser = argparse.ArgumentParser(usage='Connects to the Calculator server at the given address and does some RPCs')
parser = argparse.ArgumentParser(usage='Connects to the Calculator server \
at the given address and does some RPCs')
parser.add_argument("host", help="HOST:PORT")
return parser.parse_args()
def main(sock):
client = capnp.TwoPartyClient(sock)
# Pass "calculator" to ez_restore (there's also a `restore` function that takes a struct or AnyPointer as an argument), and then cast the returned capability to it's proper type. This casting is due to capabilities not having a reference to their schema
# Pass "calculator" to ez_restore (there's also a `restore` function that
# takes a struct or AnyPointer as an argument), and then cast the returned
# capability to it's proper type. This casting is due to capabilities not
# having a reference to their schema
calculator = client.ez_restore('calculator').cast_as(calculator_capnp.Calculator)
'''Make a request that just evaluates the literal value 123.
@@ -40,14 +53,17 @@ def main(sock):
print('Evaluating a literal... ', end="")
# Set up the request. Note the form is 'evaluate' + '_request', where 'evaluate' is the name of the method we want to call
# Set up the request. Note the form is 'evaluate' + '_request', where
# 'evaluate' is the name of the method we want to call
request = calculator.evaluate_request()
request.expression.literal = 123
# Send it, which returns a promise for the result (without blocking).
eval_promise = request.send()
# Using the promise, create a pipelined request to call read() on the returned object. Note that here we are using the shortened method call syntax read(), which is mostly just sugar for read_request().send()
# Using the promise, create a pipelined request to call read() on the
# returned object. Note that here we are using the shortened method call
# syntax read(), which is mostly just sugar for read_request().send()
read_promise = eval_promise.value.read()
# Now that we've sent all the requests, wait for the response. Until this
@@ -94,7 +110,6 @@ def main(sock):
print("PASS")
'''Make a request to evaluate 4 * 6, then use the result in two more
requests that add 3 and 5.
@@ -110,13 +125,12 @@ def main(sock):
# Get the "multiply" function from the server.
multiply = calculator.getOperator(op='multiply').func
# Build the request to evaluate 4 * 6
request = calculator.evaluate_request()
multiply_call = request.expression.init("call")
multiply_call.function = multiply
multiply_params = multiply_call.init("params", 2);
multiply_params = multiply_call.init("params", 2)
multiply_params[0].literal = 4
multiply_params[1].literal = 6
@@ -124,25 +138,25 @@ def main(sock):
# Use the result in two calls that add 3 and add 5.
add3Request = calculator.evaluate_request()
add3Call = add3Request.expression.init("call")
add3Call.function = add
add3Params = add3Call.init("params", 2)
add3Params[0].previousResult = multiply_result
add3Params[1].literal = 3
add3Promise = add3Request.send().value.read()
add_3_request = calculator.evaluate_request()
add_3_call = add_3_request.expression.init("call")
add_3_call.function = add
add_3_params = add_3_call.init("params", 2)
add_3_params[0].previousResult = multiply_result
add_3_params[1].literal = 3
add_3_promise = add_3_request.send().value.read()
add5Request = calculator.evaluate_request()
add5Call = add5Request.expression.init("call")
add5Call.function = add
add5Params = add5Call.init("params", 2)
add5Params[0].previousResult = multiply_result
add5Params[1].literal = 5
add5Promise = add5Request.send().value.read()
add_5_request = calculator.evaluate_request()
add_5_call = add_5_request.expression.init("call")
add_5_call.function = add
add_5_params = add_5_call.init("params", 2)
add_5_params[0].previousResult = multiply_result
add_5_params[1].literal = 5
add_5_promise = add_5_request.send().value.read()
# Now wait for the results.
assert add3Promise.wait().value == 27
assert add5Promise.wait().value == 29
assert add_3_promise.wait().value == 27
assert add_5_promise.wait().value == 29
print("PASS")
@@ -168,16 +182,16 @@ def main(sock):
request.paramCount = 2
# Build the function body.
addCall = request.body.init("call")
addCall.function = add
addParams = addCall.init("params", 2)
addParams[1].parameter = 1 # y
add_call = request.body.init("call")
add_call.function = add
add_params = add_call.init("params", 2)
add_params[1].parameter = 1 # y
multiplyCall = addParams[0].init("call")
multiplyCall.function = multiply
multiplyParams = multiplyCall.init("params", 2)
multiplyParams[0].parameter = 0 # x
multiplyParams[1].literal = 100
multiply_call = add_params[0].init("call")
multiply_call.function = multiply
multiply_params = multiply_call.init("params", 2)
multiply_params[0].parameter = 0 # x
multiply_params[1].literal = 100
f = request.send().func
@@ -186,45 +200,45 @@ def main(sock):
request.paramCount = 1
# Build the function body.
multiplyCall = request.body.init("call")
multiplyCall.function = multiply
multiplyParams = multiplyCall.init("params", 2)
multiplyParams[1].literal = 2
multiply_call = request.body.init("call")
multiply_call.function = multiply
multiply_params = multiply_call.init("params", 2)
multiply_params[1].literal = 2
fCall = multiplyParams[0].init("call")
fCall.function = f
fParams = fCall.init("params", 2)
fParams[0].parameter = 0
f_call = multiply_params[0].init("call")
f_call.function = f
f_params = f_call.init("params", 2)
f_params[0].parameter = 0
addCall = fParams[1].init("call")
addCall.function = add
addParams = addCall.init("params", 2)
addParams[0].parameter = 0
addParams[1].literal = 1
add_call = f_params[1].init("call")
add_call.function = add
add_params = add_call.init("params", 2)
add_params[0].parameter = 0
add_params[1].literal = 1
g = request.send().func
# OK, we've defined all our functions. Now create our eval requests.
# f(12, 34)
fEvalRequest = calculator.evaluate_request()
fCall = fEvalRequest.expression.init("call")
fCall.function = f
fParams = fCall.init("params", 2)
fParams[0].literal = 12
fParams[1].literal = 34
fEvalPromise = fEvalRequest.send().value.read()
f_eval_request = calculator.evaluate_request()
f_call = f_eval_request.expression.init("call")
f_call.function = f
f_params = f_call.init("params", 2)
f_params[0].literal = 12
f_params[1].literal = 34
f_eval_promise = f_eval_request.send().value.read()
# g(21)
gEvalRequest = calculator.evaluate_request()
gCall = gEvalRequest.expression.init("call")
gCall.function = g
gCall.init('params', 1)[0].literal = 21
gEvalPromise = gEvalRequest.send().value.read()
g_eval_request = calculator.evaluate_request()
g_call = g_eval_request.expression.init("call")
g_call.function = g
g_call.init('params', 1)[0].literal = 21
g_eval_promise = g_eval_request.send().value.read()
# Wait for the results.
assert fEvalPromise.wait().value == 1234
assert gEvalPromise.wait().value == 4244
assert f_eval_promise.wait().value == 1234
assert g_eval_promise.wait().value == 4244
print("PASS")
@@ -250,16 +264,16 @@ def main(sock):
# Build the eval request for 2^(4+5).
request = calculator.evaluate_request()
powCall = request.expression.init("call")
powCall.function = PowerFunction()
powParams = powCall.init("params", 2)
powParams[0].literal = 2
pow_call = request.expression.init("call")
pow_call.function = PowerFunction()
pow_params = pow_call.init("params", 2)
pow_params[0].literal = 2
addCall = powParams[1].init("call")
addCall.function = add
addParams = addCall.init("params", 2)
addParams[0].literal = 4
addParams[1].literal = 5
add_call = pow_params[1].init("call")
add_call.function = add
add_params = add_call.init("params", 2)
add_params[0].literal = 4
add_params[1].literal = 5
# Send the request and wait.
response = request.send().value.read().wait()

View File

@@ -8,6 +8,7 @@ import capnp
import calculator_capnp
def readValue(value):
'''Helper function to asynchronously call read() on a Calculator::Value and
return a promise for the result. (In the future, the generated code might
@@ -15,6 +16,7 @@ def readValue(value):
return value.read().then(lambda result: result.value)
def evaluateImpl(expression, params=None):
'''Implementation of CalculatorImpl::evaluate(), also shared by
FunctionImpl::call(). In the latter case, `params` are the parameter
@@ -22,17 +24,15 @@ def evaluateImpl(expression, params=None):
empty list.'''
which = expression.which()
if which == 'literal':
return capnp.Promise(expression.literal)
return capnp.Promise(expression.literal)
elif which == 'previousResult':
return readValue(expression.previousResult)
return readValue(expression.previousResult)
elif which == 'parameter':
assert expression.parameter < len(params)
return capnp.Promise(params[expression.parameter])
assert expression.parameter < len(params)
return capnp.Promise(params[expression.parameter])
elif which == 'call':
def then(vals):
ret = func.call(vals).then(lambda result: result.value)
return ret
call = expression.call
func = call.function
@@ -41,14 +41,15 @@ def evaluateImpl(expression, params=None):
joinedParams = capnp.join_promises(paramPromises)
# When the parameters are complete, call the function.
ret = joinedParams.then(then)
ret = joinedParams.then(lambda vals: func.call(vals).then(lambda result: result.value))
return ret
else:
raise ValueError("Unknown expression type: " + which)
class ValueImpl(calculator_capnp.Calculator.Value.Server):
"Simple implementation of the Calculator.Value Cap'n Proto interface."
def __init__(self, value):
@@ -57,21 +58,29 @@ class ValueImpl(calculator_capnp.Calculator.Value.Server):
def read(self, **kwargs):
return self.value
class FunctionImpl(calculator_capnp.Calculator.Function.Server):
'''Implementation of the Calculator.Function Cap'n Proto interface, where the
function is defined by a Calculator.Expression.'''
def __init__(self, paramCount, body, obj):
def __init__(self, paramCount, body):
self.paramCount = paramCount
self.body = body.as_builder()
self.obj = obj
def call(self, params, _context, **kwargs):
'''Note that we're returning a Promise object here, and bypassing the
helper functionality that normally sets the results struct from the
returned object. Instead, we set _context.results directly inside of
another promise'''
assert len(params) == self.paramCount
return evaluateImpl(self.body, params).then(lambda value: setattr(_context.results, 'value', value)) # using setattr because '=' is not allowed inside of lambdas
# using setattr because '=' is not allowed inside of lambdas
return evaluateImpl(self.body, params).then(lambda value: setattr(_context.results, 'value', value))
class OperatorImpl(calculator_capnp.Calculator.Function.Server):
'''Implementation of the Calculator.Function Cap'n Proto interface, wrapping
basic binary arithmetic operators.'''
@@ -82,6 +91,7 @@ class OperatorImpl(calculator_capnp.Calculator.Function.Server):
assert len(params) == 2
op = self.op
if op == 'add':
return params[0] + params[1]
elif op == 'subtract':
@@ -93,23 +103,25 @@ class OperatorImpl(calculator_capnp.Calculator.Function.Server):
else:
raise ValueError('Unknown operator')
class CalculatorImpl(calculator_capnp.Calculator.Server):
"Implementation of the Calculator Cap'n Proto interface."
def evaluate(self, expression, _context, **kwargs):
return evaluateImpl(expression).then(lambda value: setattr(_context.results, 'value', ValueImpl(value)))
def defFunction(self, paramCount, body, _context, **kwargs):
return FunctionImpl(paramCount, body, _context)
return FunctionImpl(paramCount, body)
def getOperator(self, op, **kwargs):
return OperatorImpl(op)
def parse_args():
parser = argparse.ArgumentParser(usage='''Runs the server bound to the given address/port
ADDRESS may be '*' to bind to all local addresses.
:PORT may be omitted to choose a port automatically.
''')
parser = argparse.ArgumentParser(usage='''Runs the server bound to the\
given address/port ADDRESS may be '*' to bind to all local addresses.\
:PORT may be omitted to choose a port automatically. ''')
parser.add_argument("address", help="ADDRESS[:PORT]")
@@ -117,6 +129,10 @@ ADDRESS may be '*' to bind to all local addresses.
class CalcRestorer:
'''A RPC Restorer. This requires a `restore` function to be defined, and
will be passed in a SturdyRef by your client'''
def __init__(self):
self.calc = CalculatorImpl()
@@ -124,6 +140,7 @@ class CalcRestorer:
assert ref.as_text() == 'calculator'
return CalculatorImpl()
def main():
address = parse_args().address
@@ -131,16 +148,16 @@ def main():
address, port = address.split(':')
port = int(port)
else:
port = random.randint(60000,61000)
port = random.randint(60000, 61000)
if address == '*':
address = ''
print("Listening on port: {}".format(port))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((address,port))
s.listen(1) # service only 1 client at a time
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((address, port))
s.listen(1) # service only 1 client at a time
while True:
try: