def setUp(self): func_call1 = FunctionCall.from_function(simple) func_call2 = FunctionCall.from_function(with_defaults) self.statements = [func_call1, func_call2] unittest.TestCase.setUp(self)
def setUp(self): func_call1 = FunctionCall.from_function(simple) func_call2 = FunctionCall.from_function(with_defaults) self.statements = [func_call1,func_call2] unittest.TestCase.setUp(self)
def test_simple(self): func_call = FunctionCall.from_function(simple) inputs = func_call.inputs # Check the names. desired = ['a','b'] self.assertEqual([x.name for x in inputs], desired) # And the default values. desired = [None, None] self.assertEqual([x.default for x in inputs], desired) # And the values values. desired = ['a', 'b'] self.assertEqual([x.binding for x in inputs], desired) # Now check the output names. outputs = [x.name for x in func_call.outputs] desired = ['x','y'] self.assertEqual(outputs, desired) # Check the module. # fixme: Do we actually want to test this here? I think only if # we choose to move module up to the func_call level. desired = simple.__module__ self.assertEqual(func_call.function.module, desired)
def test_simple(self): func_call = FunctionCall.from_function(simple) inputs = func_call.inputs # Check the names. desired = ['a', 'b'] self.assertEqual([x.name for x in inputs], desired) # And the default values. desired = [None, None] self.assertEqual([x.default for x in inputs], desired) # And the values values. desired = ['a', 'b'] self.assertEqual([x.binding for x in inputs], desired) # Now check the output names. outputs = [x.name for x in func_call.outputs] desired = ['x', 'y'] self.assertEqual(outputs, desired) # Check the module. # fixme: Do we actually want to test this here? I think only if # we choose to move module up to the func_call level. desired = simple.__module__ self.assertEqual(func_call.function.module, desired)
def _test_py_modules_in_directory(self, lib_dir): py_files = glob(os.path.join(lib_dir,'*.py')) module_names = [] for path in py_files: base_name = os.path.basename(path) module_name, ext = os.path.splitext(base_name) module_names.append(module_name) for module_name in module_names: # fixme: do this with pkgutil? try: # Skip modules that don't import. Since not all modules # in the standard library will import on all platforms. exec "import %s" % module_name module = eval(module_name) except ImportError: module = None if module: functions = _get_functions(module) for function in functions: func = FunctionCall.from_function(function) signature = func.call_signature
def _test_py_modules_in_directory(self, lib_dir): py_files = glob(os.path.join(lib_dir, '*.py')) module_names = [] for path in py_files: base_name = os.path.basename(path) module_name, ext = os.path.splitext(base_name) module_names.append(module_name) for module_name in module_names: # fixme: do this with pkgutil? try: # Skip modules that don't import. Since not all modules # in the standard library will import on all platforms. exec "import %s" % module_name module = eval(module_name) except ImportError: module = None if module: functions = _get_functions(module) for function in functions: func = FunctionCall.from_function(function) signature = func.call_signature
def test_unbound_default_call_signature(self): func = FunctionCall.from_function(with_defaults) desired = 'x, y = with_defaults(a, b=b)' self.assertEqual(func.call_signature, desired)
def test_no_return(self): func = FunctionCall.from_function(no_return) # Now check the output names. outputs = [x.name for x in func.outputs] desired = [] self.assertEqual(outputs, desired)
def test_remove_function(self): code = "def foo(a, b):\n" " x, y = a, b\n" " return x, y\n" "c, d = foo(1, 2)\n" "e, f = foo(3, 4)" block = Block(code) info = find_functions(block.ast) foo1_func = FunctionCall.from_ast(block.sub_blocks[-1].ast, info) foo2_func = FunctionCall.from_ast(block.sub_blocks[-2].ast, info) assert foo1_func != foo2_func model = ExecutionModel() model.add_function(foo1_func) model.add_function(foo2_func) model.remove_function(foo2_func) assert not (foo2_func in model.statements) assert foo1_func in model.statements
def test_name_change_updates_call_signature(self): func = FunctionCall.from_function(simple) desired = 'x, y = simple(a, b)' self.assertEqual(func.call_signature, desired) func.label_name = 'baz' desired = 'x, y = baz(a, b)' self.assertEqual(func.call_signature, desired)
def test_label_name(self): func = FunctionCall.from_function(simple) self.assertEqual(func.label_name,"simple") func.function.name = "no_return" self.assertEqual(func.label_name, "no_return") func.function.library_name = "foo" self.assertEqual(func.label_name,"foo")
def collect_func_call(statement_info,info): functions = [] for names, node in statement_info.call_funcs: function = FunctionCall.from_ast(node, info) # update the output bindings if we can, else just leave empty if len(function.outputs) == len(names): for output, name in zip(function.outputs, names): output.binding = name functions.append(function) return functions
def test_import_and_rename(self): code = "from blockcanvas.debug.my_operator import add as add1\n" \ "a = add1(1,2)\n" \ "b = add1(a,3)" foo_block = Block(code) info = find_functions(foo_block.ast) foo_call = FunctionCall.from_ast(foo_block.sub_blocks[1].ast, info) desired = 'result = add(1, 2)' self.assertEqual(foo_call.call_signature, desired)
def test_label_name(self): func = FunctionCall.from_function(simple) self.assertEqual(func.label_name, "simple") func.function.name = "no_return" self.assertEqual(func.label_name, "no_return") func.function.library_name = "foo" self.assertEqual(func.label_name, "foo")
def test_local_def(self): code = "def foo(a):\n" \ " b = a\n" \ " return b\n" \ "y = foo(2)\n" foo_block = Block(code) info = find_functions(foo_block.ast) foo_call = FunctionCall.from_ast(foo_block.sub_blocks[-1].ast, info) desired = 'b = foo(2)' self.assertEqual(foo_call.call_signature, desired)
def test_import(self): code = "from blockcanvas.debug.my_operator import add, mul\n" \ "c = add(a,b)\n" \ "d = mul(c, 2)\n" \ "e = mul(c, 3)\n" \ "f = add(d,e)" foo_block = Block(code) info = find_functions(foo_block.ast) foo_call = FunctionCall.from_ast(foo_block.sub_blocks[1].ast, info) desired = 'result = add(a, b)' self.assertEqual(foo_call.call_signature, desired)
def test_remove_function(self): code = "def foo(a, b):\n" \ " x, y = a, b\n" \ " return x, y\n" \ "c, d = foo(1, 2)\n" \ "e, f = foo(3, 4)" block = Block(code) info = find_functions(block.ast) foo1_func = FunctionCall.from_ast(block.sub_blocks[-1].ast, info) foo2_func = FunctionCall.from_ast(block.sub_blocks[-2].ast, info) assert foo1_func != foo2_func model = ExecutionModel() model.add_function(foo1_func) model.add_function(foo2_func) model.remove_function(foo2_func) assert not (foo2_func in model.statements) assert foo1_func in model.statements
def test_with_defaults_none(self): func = FunctionCall.from_function(with_defaults_none) inputs = func.inputs # Check the names. desired = ['a', 'b'] self.assertEqual([x.name for x in inputs], desired) # And the default values. desired = [None, 'None'] self.assertEqual([x.default for x in inputs], desired)
def test_with_defaults_none(self): func = FunctionCall.from_function(with_defaults_none) inputs = func.inputs # Check the names. desired = ['a','b'] self.assertEqual([x.name for x in inputs], desired) # And the default values. desired = [None, 'None'] self.assertEqual([x.default for x in inputs], desired)
def test_add_function(self): code = "def foo(a, b):\n" " x, y = a, b\n" " return x, y\n" "c, d = foo(1, 2)" block = Block(code) info = find_functions(block.ast) func = FunctionCall.from_ast(block.sub_blocks[-1].ast, info) model = ExecutionModel() model.add_function(func) assert len(model.sorted_statements) == 1 desired = "\ndef foo(a, b): \n x, y = (a, b)\n return x, y\n\nx_, y_ = foo(1, 2)" self.assertEqual(desired, model.code)
def test_with_defaults(self): func = FunctionCall.from_function(with_defaults) inputs = func.inputs # Check the names. desired = ['a','b'] self.assertEqual([x.name for x in inputs], desired) # And the default values. desired = [None, '3'] self.assertEqual([x.default for x in inputs], desired) # Now check the output names. outputs = [x.name for x in func.outputs] desired = ['x','y'] self.assertEqual(outputs, desired)
def test_with_defaults(self): func = FunctionCall.from_function(with_defaults) inputs = func.inputs # Check the names. desired = ['a', 'b'] self.assertEqual([x.name for x in inputs], desired) # And the default values. desired = [None, '3'] self.assertEqual([x.default for x in inputs], desired) # Now check the output names. outputs = [x.name for x in func.outputs] desired = ['x', 'y'] self.assertEqual(outputs, desired)
def test_add_function(self): code = "def foo(a, b):\n" \ " x, y = a, b\n" \ " return x, y\n" \ "c, d = foo(1, 2)" block = Block(code) info = find_functions(block.ast) func = FunctionCall.from_ast(block.sub_blocks[-1].ast, info) model = ExecutionModel() model.add_function(func) assert len(model.sorted_statements) == 1 desired = '\ndef foo(a, b): \n x, y = (a, b)\n return x, y\n\nx_, y_ = foo(1, 2)' self.assertEqual(desired, model.code)
if __name__ == '__main__': from blockcanvas.function_tools.local_function_info import LocalFunctionInfo f1code = "def foo(x=3, y=4):\n" \ " z = x + y\n" \ " return z\n" f2code = "def bar(k='ciao'):\n" \ " print 'K=%s' % k\n" f1 = LocalFunctionInfo(code=f1code) f2 = LocalFunctionInfo(code=f2code) F1 = FunctionCall.from_callable_object(f1) F2 = FunctionCall.from_callable_object(f2) group_type = 'for1' lsp = GroupSpec(type=group_type) node = FunctionCallGroup(lsp, statements=[F1,F2], gname='test_group'); print "CODE:\n" print node.code print "\nUUID:%s\n" % node.uuid print "\nUUID_LIST:\n" for u in node.uuid_list: print 'uuid:%s\n' % u print "\nINPUTS:\n" for input in node.inputs: print 'name:%s binding:%s default:%s\n' % (input.name, input.binding, input.default)
def add_function_object_to_model(self, item, x=None, y=None): """ Add the double clicked or dropped FunctionCall object to the code/canvas. The added function is also marked as selected. If "New Function" is clicked, we hand back a FunctionCall based on a LocalFunctionInfo. Otherwise, we hand back a FunctionCall based on a PythonFunctionInfo. # fixme: We need to add LocalFunctionInfo objects to the # FunctionLibrary somehow. """ # Prevent the execution of the code when adding a new block. self.project.active_experiment.exec_model.allow_execute = False group = False if item == NEW_EXPR_ENTRY: node = GeneralExpression() elif item == NEW_FUNCTION_ENTRY: exp = self.project.active_experiment base_name = 'new_function' func_name = exp.exec_model.generate_unique_function_name(base_name = base_name) # This should create a LocalFunctionInfo... # fixme: Generate a unique name that isn't on the canvas. code_template = "def %(name)s(a, b):\n" \ " return x, y\n" code = code_template % {'name':func_name} # fixme: Short term for testing. Remove imports in future and # replace with FunctionCall UI. function = LocalFunctionInfo(code=code) traits_class = self.match_function_to_has_traits_class(item.name) node = FunctionCall.from_callable_object(function, traits_class, exp) elif item == NEW_LOOP_ENTRY: group = True exp = self.project.active_experiment base_name = 'group' group_name = exp.exec_model.generate_unique_function_name(base_name = base_name) selection = SelGType() is_ok = selection.configure_traits(kind='modal') if is_ok: group_type = selection.check_list[0] lsp = GroupSpec(type=group_type,active_experiment=self.project.active_experiment) node = FunctionCallGroup(lsp, gname=group_name); else: return else: function = PythonFunctionInfo(name=item.name, module=item.module) traits_class = self.match_function_to_has_traits_class(item.name) node = FunctionCall.from_callable_object(function, traits_class, self.project.active_experiment) if group: res = node.configure_traits(kind="livemodal") # FIXME: It will disappear when the creation of loops will be # properly managed ("graphically") in the canvas node.update_from_UI() its_OK = res else: # Bring up the dialog box to edit it res = node.edit_traits(kind="modal") its_OK = res.result if its_OK: t_in = time.time() self.add_function_to_execution_model(node, x, y) t_out = time.time() print '%f seconds: add func to execution model' % (t_out-t_in) self.select_function_on_canvas(node) self.project.active_experiment.exec_model.allow_execute = True return
if __name__ == '__main__': from blockcanvas.function_tools.local_function_info import LocalFunctionInfo f1code = "def foo(x=3, y=4):\n" \ " z = x + y\n" \ " return z\n" f2code = "def bar(k='ciao'):\n" \ " print 'K=%s' % k\n" f1 = LocalFunctionInfo(code=f1code) f2 = LocalFunctionInfo(code=f2code) F1 = FunctionCall.from_callable_object(f1) F2 = FunctionCall.from_callable_object(f2) group_type = 'for1' lsp = GroupSpec(type=group_type) node = FunctionCallGroup(lsp, statements=[F1, F2], gname='test_group') print "CODE:\n" print node.code print "\nUUID:%s\n" % node.uuid print "\nUUID_LIST:\n" for u in node.uuid_list: print 'uuid:%s\n' % u print "\nINPUTS:\n" for input in node.inputs: print 'name:%s binding:%s default:%s\n' % (input.name, input.binding,
def add_function_object_to_model(self, item, x=None, y=None): """ Add the double clicked or dropped FunctionCall object to the code/canvas. The added function is also marked as selected. If "New Function" is clicked, we hand back a FunctionCall based on a LocalFunctionInfo. Otherwise, we hand back a FunctionCall based on a PythonFunctionInfo. # fixme: We need to add LocalFunctionInfo objects to the # FunctionLibrary somehow. """ # Prevent the execution of the code when adding a new block. self.project.active_experiment.exec_model.allow_execute = False group = False if item == NEW_EXPR_ENTRY: node = GeneralExpression() elif item == NEW_FUNCTION_ENTRY: exp = self.project.active_experiment base_name = "new_function" func_name = exp.exec_model.generate_unique_function_name(base_name=base_name) # This should create a LocalFunctionInfo... # fixme: Generate a unique name that isn't on the canvas. code_template = "def %(name)s(a, b):\n" " return x, y\n" code = code_template % {"name": func_name} # fixme: Short term for testing. Remove imports in future and # replace with FunctionCall UI. function = LocalFunctionInfo(code=code) traits_class = self.match_function_to_has_traits_class(item.name) node = FunctionCall.from_callable_object(function, traits_class, exp) elif item == NEW_LOOP_ENTRY: group = True exp = self.project.active_experiment base_name = "group" group_name = exp.exec_model.generate_unique_function_name(base_name=base_name) selection = SelGType() is_ok = selection.configure_traits(kind="modal") if is_ok: group_type = selection.check_list[0] lsp = GroupSpec(type=group_type, active_experiment=self.project.active_experiment) node = FunctionCallGroup(lsp, gname=group_name) else: return else: function = PythonFunctionInfo(name=item.name, module=item.module) traits_class = self.match_function_to_has_traits_class(item.name) node = FunctionCall.from_callable_object(function, traits_class, self.project.active_experiment) if group: res = node.configure_traits(kind="livemodal") # FIXME: It will disappear when the creation of loops will be # properly managed ("graphically") in the canvas node.update_from_UI() its_OK = res else: # Bring up the dialog box to edit it res = node.edit_traits(kind="modal") its_OK = res.result if its_OK: t_in = time.time() self.add_function_to_execution_model(node, x, y) t_out = time.time() print "%f seconds: add func to execution model" % (t_out - t_in) self.select_function_on_canvas(node) self.project.active_experiment.exec_model.allow_execute = True return
def test_simple_call_signature(self): func = FunctionCall.from_function(simple) desired = 'x, y = simple(a, b)' self.assertEqual(func.call_signature, desired)
def test_empty_return_call_signature(self): func = FunctionCall.from_function(empty_return) desired = 'empty_return(a, b)' self.assertEqual(func.call_signature, desired)