def check_exceptions(self,level=5): a = 3 code = """ if (a < 2) throw_error(PyExc_ValueError, "the variable 'a' should not be less than 2"); else return_val = PyInt_FromLong(a+1); """ result = inline_tools.inline(code,['a']) assert(result == 4) try: a = 1 result = inline_tools.inline(code,['a']) assert(1) # should've thrown a ValueError except ValueError: pass from distutils.errors import DistutilsError, CompileError try: a = 'string' result = inline_tools.inline(code,['a']) assert(1) # should've gotten an error except: # ?CompileError is the error reported, but catching it doesn't work pass
def test_access_speed(self): N = 1000000 debug_print('%s access -- val = a[i] for N =', (self.seq_type, N)) a = self.seq_type([0]) * N val = 0 t1 = time.time() for i in range(N): val = a[i] t2 = time.time() debug_print('python1:', t2 - t1) t1 = time.time() for i in a: val = i t2 = time.time() debug_print('python2:', t2 - t1) code = """ const int N = a.length(); py::object val; for(int i=0; i < N; i++) val = a[i]; """ # compile not included in timing inline_tools.inline(code,['a']) t1 = time.time() inline_tools.inline(code,['a']) t2 = time.time() debug_print('weave:', t2 - t1)
def test_int_add_speed(self): N = 1000000 debug_print('int add -- b[i] = a[i] + 1 for N =', N) a = [0] * N desired = [1] * N t1 = time.time() for i in xrange(N): desired[i] = a[i] + 1 t2 = time.time() debug_print('python:', t2 - t1) a = [0] * N b = [0] * N code = """ const int N = a.length(); for(int i=0; i < N; i++) b[i] = (int)a[i] + 1; """ # compile not included in timing inline_tools.inline(code,['a','b']) t1 = time.time() inline_tools.inline(code,['a','b']) t2 = time.time() debug_print('weave:', t2 - t1) assert_(b == desired)
def test_int_add_speed(self): N = 1000000 debug_print('int add -- b[i] = a[i] + 1 for N =', N) a = [0] * N desired = [1] * N t1 = time.time() for i in xrange(N): desired[i] = a[i] + 1 t2 = time.time() debug_print('python:', t2 - t1) a = [0] * N b = [0] * N code = """ const int N = a.length(); for(int i=0; i < N; i++) b[i] = (int)a[i] + 1; """ # compile not included in timing inline_tools.inline(code, ['a', 'b']) t1 = time.time() inline_tools.inline(code, ['a', 'b']) t2 = time.time() debug_print('weave:', t2 - t1) assert_(b == desired)
def check_access_set_speed(self,level=5): N = 1000000 print '%s access/set -- b[i] = a[i] for N =', (self.seq_type,N) a = self.seq_type([0]) * N # b is always a list so we can assign to it. b = [1] * N t1 = time.time() for i in xrange(N): b[i] = a[i] t2 = time.time() print 'python:', t2 - t1 a = self.seq_type([0]) * N b = [1] * N code = """ const int N = a.length(); for(int i=0; i < N; i++) b[i] = a[i]; """ # compile not included in timing inline_tools.inline(code,['a','b']) t1 = time.time() inline_tools.inline(code,['a','b']) t2 = time.time() print 'weave:', t2 - t1 assert list(b) == list(a)
def check_string_add_speed(self,level=5): N = 1000000 print 'string add -- b[i] = a[i] + "blah" for N =', N a = ["blah"] * N desired = [1] * N t1 = time.time() for i in xrange(N): desired[i] = a[i] + 'blah' t2 = time.time() print 'python:', t2 - t1 a = ["blah"] * N b = [1] * N code = """ const int N = a.length(); std::string blah = std::string("blah"); for(int i=0; i < N; i++) b[i] = (std::string)a[i] + blah; """ # compile not included in timing inline_tools.inline(code,['a','b']) t1 = time.time() inline_tools.inline(code,['a','b']) t2 = time.time() print 'weave:', t2 - t1 assert b == desired
def test_append(self): a = [] # temporary refcount fix until I understand why it incs by one. inline_tools.inline("a.append(1);", ['a']) del a[0] before1 = sys.getrefcount(a) # check overloaded append(int val) method inline_tools.inline("a.append(1234);", ['a']) assert_(sys.getrefcount(a[0]) == 2) assert_(a[0] == 1234) del a[0] # check overloaded append(double val) method inline_tools.inline("a.append(123.0);", ['a']) assert_(sys.getrefcount(a[0]) == 2) assert_(a[0] == 123.0) del a[0] # check overloaded append(char* val) method inline_tools.inline('a.append("bubba");', ['a']) assert_(sys.getrefcount(a[0]) == 2) assert_(a[0] == 'bubba') del a[0] # check overloaded append(std::string val) method inline_tools.inline('a.append(std::string("sissy"));', ['a']) assert_(sys.getrefcount(a[0]) == 2) assert_(a[0] == 'sissy') del a[0] after1 = sys.getrefcount(a) assert_(after1 == before1)
def check_list_refcount(self,level=5): a = UserList([1,2,3]) # temporary refcount fix until I understand why it incs by one. inline_tools.inline("a[1] = 1234;",['a']) before1 = sys.getrefcount(a) after1 = sys.getrefcount(a) assert_equal(after1,before1)
def test_set_double_new(self): a = UserDict() key = 1.0 inline_tools.inline('a[key] = 123.0;',['a','key']) assert_equal(sys.getrefcount(key),4) # should be 3 assert_equal(sys.getrefcount(a[key]),2) assert_equal(a[key],123.0)
def test_set_complex(self): a = UserDict() key = 1+1j inline_tools.inline("a[key] = 1234;",['a','key']) assert_equal(sys.getrefcount(key),4) # should be 3 assert_equal(sys.getrefcount(a[key]),2) assert_equal(a[key],1234)
def test_set_item_operator_equal(self): a = self.seq_type([1, 2, 3]) # temporary refcount fix until I understand why it incs by one. inline_tools.inline("a[1] = 1234;", ['a']) before1 = sys.getrefcount(a) # check overloaded insert(int ndx, int val) method inline_tools.inline("a[1] = 1234;", ['a']) assert_(sys.getrefcount(a[1]) == 2) assert_(a[1] == 1234) # check overloaded insert(int ndx, double val) method inline_tools.inline("a[1] = 123.0;", ['a']) assert_(sys.getrefcount(a[1]) == 2) assert_(a[1] == 123.0) # check overloaded insert(int ndx, char* val) method inline_tools.inline('a[1] = "bubba";', ['a']) assert_(sys.getrefcount(a[1]) == 2) assert_(a[1] == 'bubba') # check overloaded insert(int ndx, std::string val) method code = """ std::string val = std::string("sissy"); a[1] = val; """ inline_tools.inline(code, ['a']) assert_(sys.getrefcount(a[1]) == 2) assert_(a[1] == 'sissy') after1 = sys.getrefcount(a) assert_(after1 == before1)
def check_complex_cast(self,level=5): code = """ std::complex<double> num = std::complex<double>(1.0,1.0); py::object val = num; std::complex<double> raw_val = val; """ inline_tools.inline(code)
def check_set_double_new(self,level=5): a = UserDict() key = 1.0 inline_tools.inline('a[key] = 123.0;',['a','key']) assert_equal(sys.getrefcount(key),4) # should be 3 assert_equal(sys.getrefcount(a[key]),2) assert_equal(a[key],123.0)
def test_list_refcount(self): a = UserList([1,2,3]) # temporary refcount fix until I understand why it incs by one. inline_tools.inline("a[1] = 1234;",['a']) before1 = sys.getrefcount(a) after1 = sys.getrefcount(a) assert_equal(after1,before1)
def test_string_add_speed(self): N = 1000000 debug_print('string add -- b[i] = a[i] + "blah" for N =', N) a = ["blah"] * N desired = [1] * N t1 = time.time() for i in xrange(N): desired[i] = a[i] + 'blah' t2 = time.time() debug_print('python:', t2 - t1) a = ["blah"] * N b = [1] * N code = """ const int N = a.length(); std::string blah = std::string("blah"); for(int i=0; i < N; i++) b[i] = convert_to_string(a[i],"a") + blah; """ # compile not included in timing inline_tools.inline(code, ['a', 'b']) t1 = time.time() inline_tools.inline(code, ['a', 'b']) t2 = time.time() debug_print('weave:', t2 - t1) assert_(b == desired)
def test_noargs_with_args_not_instantiated(self): # calling a function that doesn't take args with args should fail. # Note: difference between this test add ``test_noargs_with_args`` # below is that here Foo is not instantiated. def Foo(): return "blah" code = """ py::tuple args(2); args[0] = 1; args[1] = "hello"; return_val = Foo.call(args); """ try: first = sys.getrefcount(Foo) inline_tools.inline(code,['Foo']) except TypeError: second = sys.getrefcount(Foo) try: inline_tools.inline(code,['Foo']) except TypeError: third = sys.getrefcount(Foo) # first should == second, but the weird refcount error assert_equal(second,third)
def check_set_complex(self,level=5): a = UserDict() key = 1+1j inline_tools.inline("a[key] = 1234;",['a','key']) assert_equal(sys.getrefcount(key),3) assert_equal(sys.getrefcount(a[key]),2) assert_equal(a[key],1234)
def test_complex_cast(self): code = """ std::complex<double> num = std::complex<double>(1.0, 1.0); py::object val = num; std::complex<double> raw_val __attribute__ ((unused)) = val; """ inline_tools.inline(code)
def test_access_set_speed(self): N = 1000000 debug_print('%s access/set -- b[i] = a[i] for N =', (self.seq_type, N)) a = self.seq_type([0]) * N # b is always a list so we can assign to it. b = [1] * N t1 = time.time() for i in xrange(N): b[i] = a[i] t2 = time.time() debug_print('python:', t2 - t1) a = self.seq_type([0]) * N b = [1] * N code = """ const int N = a.length(); for(int i=0; i < N; i++) b[i] = a[i]; """ # compile not included in timing inline_tools.inline(code, ['a', 'b']) t1 = time.time() inline_tools.inline(code, ['a', 'b']) t2 = time.time() debug_print('weave:', t2 - t1) assert_(list(b) == list(a))
def check_count(self,level=5): """ Test the "count" method for lists. We'll assume it works for sequences if it works hre. """ a = self.seq_type([1,2,'alpha',3.1416]) item = 1 code = "return_val = a.count(item);" res = inline_tools.inline(code,['a','item']) assert res == 1 # check overloaded count(int val) method code = "return_val = a.count(1);" res = inline_tools.inline(code,['a']) assert res == 1 # check overloaded count(double val) method code = "return_val = a.count(3.1416);" res = inline_tools.inline(code,['a']) assert res == 1 # check overloaded count(char* val) method code = 'return_val = a.count("alpha");' res = inline_tools.inline(code,['a']) assert res == 1 # check overloaded count(std::string val) method code = """ std::string alpha = std::string("alpha"); return_val = a.count(alpha); """ res = inline_tools.inline(code,['a']) assert res == 1
def check_int_add_speed(self,level=5): N = 1000000 print 'int add -- b[i] = a[i] + 1 for N =', N a = [0] * N desired = [1] * N t1 = time.time() for i in xrange(N): desired[i] = a[i] + 1 t2 = time.time() print 'python:', t2 - t1 a = [0] * N b = [0] * N code = """ const int N = a.length(); for(int i=0; i < N; i++) b[i] = (int)a[i] + 1; """ # compile not included in timing inline_tools.inline(code,['a','b']) t1 = time.time() inline_tools.inline(code,['a','b']) t2 = time.time() print 'weave:', t2 - t1 assert b == desired
def check_set_item_operator_equal(self,level=5): a = self.seq_type([1,2,3]) # temporary refcount fix until I understand why it incs by one. inline_tools.inline("a[1] = 1234;",['a']) before1 = sys.getrefcount(a) # check overloaded insert(int ndx, int val) method inline_tools.inline("a[1] = 1234;",['a']) assert sys.getrefcount(a[1]) == 2 assert a[1] == 1234 # check overloaded insert(int ndx, double val) method inline_tools.inline("a[1] = 123.0;",['a']) assert sys.getrefcount(a[1]) == 2 assert a[1] == 123.0 # check overloaded insert(int ndx, char* val) method inline_tools.inline('a[1] = "bubba";',['a']) assert sys.getrefcount(a[1]) == 2 assert a[1] == 'bubba' # check overloaded insert(int ndx, std::string val) method code = """ std::string val = std::string("sissy"); a[1] = val; """ inline_tools.inline(code,['a']) assert sys.getrefcount(a[1]) == 2 assert a[1] == 'sissy' after1 = sys.getrefcount(a) assert after1 == before1
def test_access_speed(self): N = 1000000 debug_print('%s access -- val = a[i] for N =', (self.seq_type, N)) a = self.seq_type([0]) * N val = 0 t1 = time.time() for i in xrange(N): val = a[i] t2 = time.time() debug_print('python1:', t2 - t1) t1 = time.time() for i in a: val = i t2 = time.time() debug_print('python2:', t2 - t1) code = """ const int N = a.length(); py::object val; for(int i=0; i < N; i++) val = a[i]; """ # compile not included in timing inline_tools.inline(code, ['a']) t1 = time.time() inline_tools.inline(code, ['a']) t2 = time.time() debug_print('weave:', t2 - t1)
def check_append(self,level=5): a = [] # temporary refcount fix until I understand why it incs by one. inline_tools.inline("a.append(1);",['a']) del a[0] before1 = sys.getrefcount(a) # check overloaded append(int val) method inline_tools.inline("a.append(1234);",['a']) assert sys.getrefcount(a[0]) == 2 assert a[0] == 1234 del a[0] # check overloaded append(double val) method inline_tools.inline("a.append(123.0);",['a']) assert sys.getrefcount(a[0]) == 2 assert a[0] == 123.0 del a[0] # check overloaded append(char* val) method inline_tools.inline('a.append("bubba");',['a']) assert sys.getrefcount(a[0]) == 2 assert a[0] == 'bubba' del a[0] # check overloaded append(std::string val) method inline_tools.inline('a.append(std::string("sissy"));',['a']) assert sys.getrefcount(a[0]) == 2 assert a[0] == 'sissy' del a[0] after1 = sys.getrefcount(a) assert after1 == before1
def check_access_speed(self,level=5): N = 1000000 print '%s access -- val = a[i] for N =', (self.seq_type, N) a = self.seq_type([0]) * N val = 0 t1 = time.time() for i in xrange(N): val = a[i] t2 = time.time() print 'python1:', t2 - t1 t1 = time.time() for i in a: val = i t2 = time.time() print 'python2:', t2 - t1 code = """ const int N = a.length(); py::object val; for(int i=0; i < N; i++) val = a[i]; """ # compile not included in timing inline_tools.inline(code,['a']) t1 = time.time() inline_tools.inline(code,['a']) t2 = time.time() print 'weave:', t2 - t1
def test_count(self): # Test the "count" method for lists. We'll assume it works for # sequences if it works here. a = self.seq_type([1, 2, 'alpha', 3.1416]) item = 1 code = "return_val = a.count(item);" res = inline_tools.inline(code, ['a', 'item']) assert_(res == 1) # check overloaded count(int val) method code = "return_val = a.count(1);" res = inline_tools.inline(code, ['a']) assert_(res == 1) # check overloaded count(double val) method code = "return_val = a.count(3.1416);" res = inline_tools.inline(code, ['a']) assert_(res == 1) # check overloaded count(char* val) method code = 'return_val = a.count("alpha");' res = inline_tools.inline(code, ['a']) assert_(res == 1) # check overloaded count(std::string val) method code = """ std::string alpha = std::string("alpha"); return_val = a.count(alpha); """ res = inline_tools.inline(code, ['a']) assert_(res == 1)
def test_string_add_speed(self): N = 1000000 debug_print('string add -- b[i] = a[i] + "blah" for N =', N) a = ["blah"] * N desired = [1] * N t1 = time.time() for i in xrange(N): desired[i] = a[i] + 'blah' t2 = time.time() debug_print('python:', t2 - t1) a = ["blah"] * N b = [1] * N code = """ const int N = a.length(); std::string blah = std::string("blah"); for(int i=0; i < N; i++) b[i] = convert_to_string(a[i],"a") + blah; """ # compile not included in timing inline_tools.inline(code,['a','b']) t1 = time.time() inline_tools.inline(code,['a','b']) t2 = time.time() debug_print('weave:', t2 - t1) assert_(b == desired)
def check_set_item_operator_equal_fail(self,level=5): # Tuples should only allow setting of variables # immediately after creation. a = (1,2,3) try: inline_tools.inline("a[1] = 1234;",['a']) except TypeError: pass
def check_attr_call(self,level=5): a = foo() res = inline_tools.inline('return_val = a.attr("bar").call();',['a']) first = sys.getrefcount(res) del res res = inline_tools.inline('return_val = a.attr("bar").call();',['a']) second = sys.getrefcount(res) assert_equal(res,"bar results") assert_equal(first,second)
def test_conversion(self): a = self.seq_type([1]) before = sys.getrefcount(a) inline_tools.inline(" ",['a']) # first call is goofing up refcount. before = sys.getrefcount(a) inline_tools.inline(" ",['a']) after = sys.getrefcount(a) assert_(after == before)
def test_attr_call(self): a = Foo() res = inline_tools.inline('return_val = a.attr("bar").call();',['a']) first = sys.getrefcount(res) del res res = inline_tools.inline('return_val = a.attr("bar").call();',['a']) second = sys.getrefcount(res) assert_equal(res,"bar results") assert_equal(first,second)
def test_conversion(self): a = self.seq_type([1]) before = sys.getrefcount(a) inline_tools.inline(" ", ['a']) # first call is goofing up refcount. before = sys.getrefcount(a) inline_tools.inline(" ", ['a']) after = sys.getrefcount(a) assert_(after == before)
def test_py_to_file(self): file_name = os.path.join(test_dir, "testfile") file = open(file_name, 'w') code = """ fprintf(file,"hello bob"); """ inline_tools.inline(code, ['file'], compiler=self.compiler, force=1) file.close() file = open(file_name, 'r') assert_(file.read() == "hello bob")
def test_noargs(self): a = Foo() res = inline_tools.inline('return_val = a.mcall("bar");',['a']) assert_equal(res,"bar results") first = sys.getrefcount(res) del res res = inline_tools.inline('return_val = a.mcall("bar");',['a']) assert_equal(res,"bar results") second = sys.getrefcount(res) assert_equal(first,second)
def test_py_to_file(self): file_name = os.path.join(test_dir, "testfile") file = open(file_name,'w') code = """ fprintf(file,"hello bob"); """ inline_tools.inline(code,['file'],compiler=self.compiler,force=1) file.close() file = open(file_name,'r') assert_(file.read() == "hello bob")
def check_std_noargs(self,level=5): a = foo() method = "bar" res = inline_tools.inline('return_val = a.mcall(method);',['a','method']) assert_equal(res,"bar results") first = sys.getrefcount(res) del res res = inline_tools.inline('return_val = a.mcall(method);',['a','method']) assert_equal(res,"bar results") second = sys.getrefcount(res) assert_equal(first,second)
def check_set_double_exists(self,level=5): a = UserDict() key = 10.0 a[key] = 100.0 inline_tools.inline('a[key] = 123.0;',['a','key']) first = sys.getrefcount(key) inline_tools.inline('a[key] = 123.0;',['a','key']) second = sys.getrefcount(key) assert_equal(first,second) # !! I think the following should be 3 assert_equal(sys.getrefcount(key),5) assert_equal(sys.getrefcount(a[key]),2) assert_equal(a[key],123.0)
def test_set_double_exists(self): a = UserDict() key = 10.0 a[key] = 100.0 inline_tools.inline('a[key] = 123.0;',['a','key']) first = sys.getrefcount(key) inline_tools.inline('a[key] = 123.0;',['a','key']) second = sys.getrefcount(key) assert_equal(first,second) # !! I think the following should be 3 assert_equal(sys.getrefcount(key),5) assert_equal(sys.getrefcount(a[key]),2) assert_equal(a[key],123.0)
def _cast_copy_transpose(type, a_2d): assert (len(shape(a_2d)) == 2) new_array = zeros(shape(a_2d), type) code = """ for(int i = 0; i < Na_2d[0]; i++) for(int j = 0; j < Na_2d[1]; j++) new_array(i,j) = a_2d(j,i); """ inline_tools.inline(code, ['new_array', 'a_2d'], type_converters=cblitz, compiler='gcc', verbose=1) return new_array
def generic_new(self,key,val): # test that value is set correctly and that reference counts # on dict, key, and val are being handled correctly. a = {} # call once to handle mysterious addition of one ref count # on first call to inline. inline_tools.inline("a[key] = val;",['a','key','val']) assert_(a[key] == val) before = sys.getrefcount(a), sys.getrefcount(key), sys.getrefcount(val) inline_tools.inline("a[key] = val;",['a','key','val']) assert_(a[key] == val) after = sys.getrefcount(a), sys.getrefcount(key), sys.getrefcount(val) assert_(before == after)
def _cast_copy_transpose(type,a_2d): assert(len(shape(a_2d)) == 2) new_array = zeros(shape(a_2d),type) code = """ for(int i = 0; i < Na_2d[0]; i++) for(int j = 0; j < Na_2d[1]; j++) new_array(i,j) = a_2d(j,i); """ inline_tools.inline(code,['new_array','a_2d'], type_converters=cblitz, compiler='gcc', verbose=1) return new_array
def check_in(self,level=5): """ Test the "in" method for lists. We'll assume it works for sequences if it works here. """ a = self.seq_type([1,2,'alpha',3.1416]) item = 1 code = "return_val = a.in(item);" res = inline_tools.inline(code,['a','item']) assert res == 1 item = 0 res = inline_tools.inline(code,['a','item']) assert res == 0 # check overloaded in(int val) method code = "return_val = a.in(1);" res = inline_tools.inline(code,['a']) assert res == 1 code = "return_val = a.in(0);" res = inline_tools.inline(code,['a']) assert res == 0 # check overloaded in(double val) method code = "return_val = a.in(3.1416);" res = inline_tools.inline(code,['a']) assert res == 1 code = "return_val = a.in(3.1417);" res = inline_tools.inline(code,['a']) assert res == 0 # check overloaded in(char* val) method code = 'return_val = a.in("alpha");' res = inline_tools.inline(code,['a']) assert res == 1 code = 'return_val = a.in("beta");' res = inline_tools.inline(code,['a']) assert res == 0 # check overloaded in(std::string val) method code = """ std::string val = std::string("alpha"); return_val = a.in(val); """ res = inline_tools.inline(code,['a']) assert res == 1 code = """ std::string val = std::string("beta"); return_val = a.in(val); """ res = inline_tools.inline(code,['a']) assert res == 0
def check_unicode(self,level=5): class foo: def __repr__(self): return "repr return" def __str__(self): return "unicode" a= foo() res = inline_tools.inline('return_val = a.unicode();',['a']) first = sys.getrefcount(res) del res res = inline_tools.inline('return_val = a.unicode();',['a']) second = sys.getrefcount(res) assert_equal(first,second) assert_equal(res,"unicode")
def test_in(self): # Test the "in" method for lists. We'll assume it works for # sequences if it works here. a = self.seq_type([1, 2, 'alpha', 3.1416]) item = 1 code = "return_val = a.in(item);" res = inline_tools.inline(code, ['a', 'item']) assert_(res == 1) item = 0 res = inline_tools.inline(code, ['a', 'item']) assert_(res == 0) # check overloaded in(int val) method code = "return_val = a.in(1);" res = inline_tools.inline(code, ['a']) assert_(res == 1) code = "return_val = a.in(0);" res = inline_tools.inline(code, ['a']) assert_(res == 0) # check overloaded in(double val) method code = "return_val = a.in(3.1416);" res = inline_tools.inline(code, ['a']) assert_(res == 1) code = "return_val = a.in(3.1417);" res = inline_tools.inline(code, ['a']) assert_(res == 0) # check overloaded in(char* val) method code = 'return_val = a.in("alpha");' res = inline_tools.inline(code, ['a']) assert_(res == 1) code = 'return_val = a.in("beta");' res = inline_tools.inline(code, ['a']) assert_(res == 0) # check overloaded in(std::string val) method code = """ std::string val = std::string("alpha"); return_val = a.in(val); """ res = inline_tools.inline(code, ['a']) assert_(res == 1) code = """ std::string val = std::string("beta"); return_val = a.in(val); """ res = inline_tools.inline(code, ['a']) assert_(res == 0)
def test_str(self): class Foo: def __str__(self): return "str return" def __repr__(self): return "repr return" a = Foo() res = inline_tools.inline('return_val = a.str();',['a']) first = sys.getrefcount(res) del res res = inline_tools.inline('return_val = a.str();',['a']) second = sys.getrefcount(res) assert_equal(first,second) assert_equal(res,"str return")
def generic(self,key): # test that value is set correctly and that reference counts # on dict, key, are being handled correctly. after deletion, # the keys refcount should be one less than before. a = {} a[key] = 1 inline_tools.inline("a.del(key);",['a','key']) assert_(key not in a) a[key] = 1 before = sys.getrefcount(a), sys.getrefcount(key) inline_tools.inline("a.del(key);",['a','key']) assert_(key not in a) after = sys.getrefcount(a), sys.getrefcount(key) assert_(before[0] == after[0]) assert_(before[1] == after[1] + 1)
def generic_overwrite(self,key,val): a = {} overwritten = 1 a[key] = overwritten # put an item in the dict to be overwritten # call once to handle mysterious addition of one ref count # on first call to inline. before_overwritten = sys.getrefcount(overwritten) inline_tools.inline("a[key] = val;",['a','key','val']) assert_(a[key] == val) before = sys.getrefcount(a), sys.getrefcount(key), sys.getrefcount(val) inline_tools.inline("a[key] = val;",['a','key','val']) assert_(a[key] == val) after = sys.getrefcount(a), sys.getrefcount(key), sys.getrefcount(val) after_overwritten = sys.getrefcount(overwritten) assert_(before == after) assert_(before_overwritten == after_overwritten)
def test_false(self): class Foo: pass a = Foo() res = inline_tools.inline('return_val = a.is_callable();',['a']) assert_(not res)
def test_type(self): class Foo: pass a = Foo() res = inline_tools.inline('return_val = a.type();',['a']) assert_equal(res,type(a))
def test_key_refcount(self): a = UserDict() code = """ py::object one = 1; py::object two = 2; py::tuple ref_counts(3); py::tuple obj_counts(3); py::tuple val_counts(3); py::tuple key_counts(3); obj_counts[0] = a.refcount(); key_counts[0] = one.refcount(); val_counts[0] = two.refcount(); a[1] = 2; obj_counts[1] = a.refcount(); key_counts[1] = one.refcount(); val_counts[1] = two.refcount(); a[1] = 2; obj_counts[2] = a.refcount(); key_counts[2] = one.refcount(); val_counts[2] = two.refcount(); ref_counts[0] = obj_counts; ref_counts[1] = key_counts; ref_counts[2] = val_counts; return_val = ref_counts; """ obj,key,val = inline_tools.inline(code,['a']) assert_equal(obj[0],obj[1]) assert_equal(obj[1],obj[2]) assert_equal(key[0] + 1, key[1]) assert_equal(key[1], key[2]) assert_equal(val[0] + 1, val[1]) assert_equal(val[1], val[2])
def c_int_search_scxx(seq, t, chk=1): # do partial type checking in Python. # checking that list items are ints should happen in py_to_scalar<int> if chk: assert (type(t) is int) assert (type(seq) is list) code = """ #line 67 "binary_search.py" int val, m, min = 0; int max = seq.len()- 1; for(;;) { if (max < min ) { return_val = -1; break; } m = (min + max) / 2; val = seq[m]; if (val < t) min = m + 1; else if (val > t) max = m - 1; else { return_val = m; break; } } """ # return inline_tools.inline(code,['seq','t'],compiler='msvc') return inline_tools.inline(code, ['seq', 't'], verbose=2)
def c_array_int_search(seq, t): code = """ #line 62 "binary_search.py" int val, m, min = 0; int max = Nseq[0] - 1; PyObject *py_val; for(;;) { if (max < min ) { return_val = -1; break; } m = (min + max) / 2; val = seq[m]; if (val < t) min = m + 1; else if (val > t) max = m - 1; else { return_val = m; break; } } """ # return inline_tools.inline(code,['seq','t'],compiler='msvc') return inline_tools.inline(code, ['seq', 't'], verbose=2, extra_compile_args=['-O2', '-G6'])
def test_noargs(self): def Foo(): return (1, 2, 3) res = inline_tools.inline('return_val = Foo.call();', ['Foo']) assert_equal(res, (1, 2, 3)) assert_equal(sys.getrefcount(res), 3) # should be 2?
def test_string_fail(self): a = {} a["b"] = 12345 code = """ return_val = a.has_key("c"); """ res = inline_tools.inline(code,['a']) assert_(not res)