def add_arguments(schema, kwargs): """ Create a new schema like ``schema`` but with the arguments given by ``kwargs`` prepended to the signature. :param foolscap.remoteinterface.RemoteMethodSchema schema: The existing schema. :param list[(bytes, foolscap.IConstraint)] kwargs: The arguments to prepend to the signature of ``schema``. :return foolscap.remoteinterface.RemoteMethodSchema: The new schema object. """ new_kwargs = dict(schema.argConstraints) new_kwargs.update(kwargs) modified_schema = RemoteMethodSchema(**new_kwargs) # Initialized from **new_kwargs, RemoteMethodSchema.argumentNames is in # some arbitrary, probably-incorrect order. This breaks user code which # tries to use positional arguments. Put them back in the order they were # in originally (in the input ``schema``), prepended with the newly added # arguments. modified_schema.argumentNames = ( # The new arguments list(argName for (argName, _) in kwargs) + # The original arguments in the original order schema.argumentNames ) return modified_schema
class RIMyTarget(RemoteInterface): # method constraints can be declared directly: add1 = RemoteMethodSchema(_response=int, a=int, b=int) free = UnconstrainedMethod() # or through their function definitions: def add(a=int, b=int): return int #add = schema.callable(add) # the metaclass makes this unnecessary # but it could be used for adding options or something def join(a=str, b=str, c=int): return str def getName(): return str disputed = RemoteMethodSchema(_response=int, a=int) def fail(): return str # actually raises an exception def failstring(): return str # raises a string exception
class RIMyCryptoTarget(RemoteInterface): # method constraints can be declared directly: add1 = RemoteMethodSchema(_response=int, a=int, b=int) # or through their function definitions: def add(a=int, b=int): return int #add = schema.callable(add) # the metaclass makes this unnecessary # but it could be used for adding options or something def join(a=str, b=str, c=int): return str def getName(): return str
class RIMyTarget2(RemoteInterface): __remote_name__ = "RIMyTargetInterface2" sub = RemoteMethodSchema(_response=int, a=int, b=int)
def failstring(): return str # raises a string exception class RIMyTarget2(RemoteInterface): __remote_name__ = "RIMyTargetInterface2" sub = RemoteMethodSchema(_response=int, a=int, b=int) # For some tests, we want the two sides of the connection to disagree about # the contents of the RemoteInterface they are using. This is remarkably # difficult to accomplish within a single process. We do it by creating # something that behaves just barely enough like a RemoteInterface to work. class FakeTarget(dict): pass RIMyTarget3 = FakeTarget() RIMyTarget3.__remote_name__ = RIMyTarget.__remote_name__ RIMyTarget3['disputed'] = RemoteMethodSchema(_response=int, a=str) RIMyTarget3['disputed'].name = "disputed" RIMyTarget3['disputed'].interface = RIMyTarget3 RIMyTarget3['disputed2'] = RemoteMethodSchema(_response=str, a=int) RIMyTarget3['disputed2'].name = "disputed" RIMyTarget3['disputed2'].interface = RIMyTarget3 RIMyTarget3['sub'] = RemoteMethodSchema(_response=int, a=int, b=int) RIMyTarget3['sub'].name = "sub" RIMyTarget3['sub'].interface = RIMyTarget3 @implementer(RIMyTarget) class Target(Referenceable): def __init__(self, name=None):
def test_arguments(self): def foo(a=int, b=bool, c=int): return bytes r = RemoteMethodSchema(method=foo) getpos = r.getPositionalArgConstraint getkw = r.getKeywordArgConstraint self.assertTrue(isinstance(getpos(0)[1], schema.IntegerConstraint)) self.assertTrue(isinstance(getpos(1)[1], schema.BooleanConstraint)) self.assertTrue(isinstance(getpos(2)[1], schema.IntegerConstraint)) self.assertTrue(isinstance(getkw("a")[1], schema.IntegerConstraint)) self.assertTrue(isinstance(getkw("b")[1], schema.BooleanConstraint)) self.assertTrue(isinstance(getkw("c")[1], schema.IntegerConstraint)) self.assertTrue( isinstance(r.getResponseConstraint(), schema.ByteStringConstraint)) self.assertTrue( isinstance(getkw("c", 1, [])[1], schema.IntegerConstraint)) self.assertRaises(schema.Violation, getkw, "a", 1, []) self.assertRaises(schema.Violation, getkw, "b", 1, ["b"]) self.assertRaises(schema.Violation, getkw, "a", 2, []) self.assertTrue( isinstance(getkw("c", 2, [])[1], schema.IntegerConstraint)) self.assertTrue( isinstance(getkw("c", 0, ["a", "b"])[1], schema.IntegerConstraint)) try: r.checkAllArgs((1, True, 2), {}, False) r.checkAllArgs((), {"a": 1, "b": False, "c": 2}, False) r.checkAllArgs((1, ), {"b": False, "c": 2}, False) r.checkAllArgs((1, True), {"c": 3}, False) r.checkResults(b"good", False) except schema.Violation: self.fail("that shouldn't have raised a Violation") self.assertRaises( schema.Violation, # 2 is not bool r.checkAllArgs, (1, 2, 3), {}, False) self.assertRaises( schema.Violation, # too many r.checkAllArgs, (1, True, 3, 4), {}, False) self.assertRaises( schema.Violation, # double "a" r.checkAllArgs, (1, ), { "a": 1, "b": True, "c": 3 }, False) self.assertRaises( schema.Violation, # missing required "b" r.checkAllArgs, (1, ), {"c": 3}, False) self.assertRaises( schema.Violation, # missing required "a" r.checkAllArgs, (), { "b": True, "c": 3 }, False) self.assertRaises(schema.Violation, r.checkResults, 12, False)
def failstring(): return str # raises a string exception class RIMyTarget2(RemoteInterface): __remote_name__ = "RIMyTargetInterface2" sub = RemoteMethodSchema(_response=int, a=int, b=int) # For some tests, we want the two sides of the connection to disagree about # the contents of the RemoteInterface they are using. This is remarkably # difficult to accomplish within a single process. We do it by creating # something that behaves just barely enough like a RemoteInterface to work. class FakeTarget(dict): pass RIMyTarget3 = FakeTarget() RIMyTarget3.__remote_name__ = RIMyTarget.__remote_name__ RIMyTarget3['disputed'] = RemoteMethodSchema(_response=int, a=str) RIMyTarget3['disputed'].name = "disputed" RIMyTarget3['disputed'].interface = RIMyTarget3 RIMyTarget3['disputed2'] = RemoteMethodSchema(_response=str, a=int) RIMyTarget3['disputed2'].name = "disputed" RIMyTarget3['disputed2'].interface = RIMyTarget3 RIMyTarget3['sub'] = RemoteMethodSchema(_response=int, a=int, b=int) RIMyTarget3['sub'].name = "sub" RIMyTarget3['sub'].interface = RIMyTarget3 class Target(Referenceable): implements(RIMyTarget) def __init__(self, name=None):
def test_arguments(self): def foo(a=int, b=bool, c=int): return str r = RemoteMethodSchema(method=foo) getpos = r.getPositionalArgConstraint getkw = r.getKeywordArgConstraint self.failUnless(isinstance(getpos(0)[1], schema.IntegerConstraint)) self.failUnless(isinstance(getpos(1)[1], schema.BooleanConstraint)) self.failUnless(isinstance(getpos(2)[1], schema.IntegerConstraint)) self.failUnless(isinstance(getkw("a")[1], schema.IntegerConstraint)) self.failUnless(isinstance(getkw("b")[1], schema.BooleanConstraint)) self.failUnless(isinstance(getkw("c")[1], schema.IntegerConstraint)) self.failUnless(isinstance(r.getResponseConstraint(), schema.ByteStringConstraint)) self.failUnless(isinstance(getkw("c", 1, [])[1], schema.IntegerConstraint)) self.failUnlessRaises(schema.Violation, getkw, "a", 1, []) self.failUnlessRaises(schema.Violation, getkw, "b", 1, ["b"]) self.failUnlessRaises(schema.Violation, getkw, "a", 2, []) self.failUnless(isinstance(getkw("c", 2, [])[1], schema.IntegerConstraint)) self.failUnless(isinstance(getkw("c", 0, ["a", "b"])[1], schema.IntegerConstraint)) try: r.checkAllArgs((1,True,2), {}, False) r.checkAllArgs((), {"a":1, "b":False, "c":2}, False) r.checkAllArgs((1,), {"b":False, "c":2}, False) r.checkAllArgs((1,True), {"c":3}, False) r.checkResults("good", False) except schema.Violation: self.fail("that shouldn't have raised a Violation") self.failUnlessRaises(schema.Violation, # 2 is not bool r.checkAllArgs, (1,2,3), {}, False) self.failUnlessRaises(schema.Violation, # too many r.checkAllArgs, (1,True,3,4), {}, False) self.failUnlessRaises(schema.Violation, # double "a" r.checkAllArgs, (1,), {"a":1, "b":True, "c": 3}, False) self.failUnlessRaises(schema.Violation, # missing required "b" r.checkAllArgs, (1,), {"c": 3}, False) self.failUnlessRaises(schema.Violation, # missing required "a" r.checkAllArgs, (), {"b":True, "c": 3}, False) self.failUnlessRaises(schema.Violation, r.checkResults, 12, False)