1
""" Test refcounting and behavior of SCXX.
6
from numpy.testing import *
8
from weave import inline_tools
11
class test_object_construct(ScipyTestCase):
12
#------------------------------------------------------------------------
13
# Check that construction from basic types is allowed and have correct
15
#------------------------------------------------------------------------
16
def check_int(self,level=5):
17
# strange int value used to try and make sure refcount is 2.
19
py::object val = 1001;
22
res = inline_tools.inline(code)
23
assert sys.getrefcount(res) == 2
25
def check_float(self,level=5):
27
py::object val = (float)1.0;
30
res = inline_tools.inline(code)
31
assert sys.getrefcount(res) == 2
33
def check_double(self,level=5):
38
res = inline_tools.inline(code)
39
assert sys.getrefcount(res) == 2
41
def check_complex(self,level=5):
43
std::complex<double> num = std::complex<double>(1.0,1.0);
47
res = inline_tools.inline(code)
48
assert sys.getrefcount(res) == 2
49
assert res == 1.0+1.0j
50
def check_string(self,level=5):
52
py::object val = "hello";
55
res = inline_tools.inline(code)
56
assert sys.getrefcount(res) == 2
59
def check_std_string(self,level=5):
61
std::string s = std::string("hello");
65
res = inline_tools.inline(code)
66
assert sys.getrefcount(res) == 2
69
class test_object_print(ScipyTestCase):
70
#------------------------------------------------------------------------
71
# Check the object print protocol.
72
#------------------------------------------------------------------------
73
def check_stdout(self,level=5):
75
py::object val = "how now brown cow";
78
res = inline_tools.inline(code)
79
# visual check on this one.
80
def check_stringio(self,level=5):
82
file_imposter = cStringIO.StringIO()
84
py::object val = "how now brown cow";
85
val.print(file_imposter);
87
res = inline_tools.inline(code,['file_imposter'])
88
print file_imposter.getvalue()
89
assert file_imposter.getvalue() == "'how now brown cow'"
91
## def check_failure(self,level=5):
94
## py::object val = "how now brown cow";
98
## res = inline_tools.inline(code)
100
## # error was supposed to occur.
104
class test_object_cast(ScipyTestCase):
105
def check_int_cast(self,level=5):
110
inline_tools.inline(code)
111
def check_double_cast(self,level=5):
113
py::object val = 1.0;
114
double raw_val = val;
116
inline_tools.inline(code)
117
def check_float_cast(self,level=5):
119
py::object val = 1.0;
122
inline_tools.inline(code)
123
def check_complex_cast(self,level=5):
125
std::complex<double> num = std::complex<double>(1.0,1.0);
126
py::object val = num;
127
std::complex<double> raw_val = val;
129
inline_tools.inline(code)
130
def check_string_cast(self,level=5):
132
py::object val = "hello";
133
std::string raw_val = val;
135
inline_tools.inline(code)
137
# test class used for testing python class access from C++.
141
def bar2(self,val1,val2):
143
def bar3(self,val1,val2,val3=1):
144
return val1, val2, val3
150
class test_object_hasattr(ScipyTestCase):
151
def check_string(self,level=5):
155
return_val = a.hasattr("b");
157
res = inline_tools.inline(code,['a'])
159
def check_std_string(self,level=5):
164
return_val = a.hasattr(attr_name);
166
res = inline_tools.inline(code,['a','attr_name'])
168
def check_string_fail(self,level=5):
172
return_val = a.hasattr("c");
174
res = inline_tools.inline(code,['a'])
176
def check_inline(self,level=5):
177
""" THIS NEEDS TO MOVE TO THE INLINE TEST SUITE
182
throw_error(PyExc_AttributeError,"bummer");
185
before = sys.getrefcount(a)
186
res = inline_tools.inline(code,['a'])
187
except AttributeError:
188
after = sys.getrefcount(a)
190
res = inline_tools.inline(code,['a'])
192
after2 = sys.getrefcount(a)
193
print "after and after2 should be equal in the following"
194
print 'before, after, after2:', before, after, after2
197
def check_func(self,level=5):
201
return_val = a.hasattr("bar");
203
res = inline_tools.inline(code,['a'])
206
class test_object_attr(ScipyTestCase):
208
def generic_attr(self,code,args=['a']):
212
before = sys.getrefcount(a.b)
213
res = inline_tools.inline(code,args)
216
after = sys.getrefcount(a.b)
217
assert after == before
219
def check_char(self,level=5):
220
self.generic_attr('return_val = a.attr("b");')
222
def check_char_fail(self,level=5):
224
self.generic_attr('return_val = a.attr("c");')
225
except AttributeError:
228
def check_string(self,level=5):
229
self.generic_attr('return_val = a.attr(std::string("b"));')
231
def check_string_fail(self,level=5):
233
self.generic_attr('return_val = a.attr(std::string("c"));')
234
except AttributeError:
237
def check_obj(self,level=5):
239
py::object name = "b";
240
return_val = a.attr(name);
242
self.generic_attr(code,['a'])
244
def check_obj_fail(self,level=5):
247
py::object name = "c";
248
return_val = a.attr(name);
250
self.generic_attr(code,['a'])
251
except AttributeError:
254
def check_attr_call(self,level=5):
256
res = inline_tools.inline('return_val = a.attr("bar").call();',['a'])
257
first = sys.getrefcount(res)
259
res = inline_tools.inline('return_val = a.attr("bar").call();',['a'])
260
second = sys.getrefcount(res)
261
assert res == "bar results"
262
assert first == second
264
class test_object_set_attr(ScipyTestCase):
266
def generic_existing(self, code, desired):
270
res = inline_tools.inline(code,args)
271
assert a.b == desired
273
def generic_new(self, code, desired):
276
res = inline_tools.inline(code,args)
277
assert a.b == desired
279
def check_existing_char(self,level=5):
280
self.generic_existing('a.set_attr("b","hello");',"hello")
281
def check_new_char(self,level=5):
282
self.generic_new('a.set_attr("b","hello");',"hello")
283
def check_existing_string(self,level=5):
284
self.generic_existing('a.set_attr("b",std::string("hello"));',"hello")
285
def check_new_string(self,level=5):
286
self.generic_new('a.set_attr("b",std::string("hello"));',"hello")
287
def check_existing_object(self,level=5):
289
py::object obj = "hello";
292
self.generic_existing(code,"hello")
293
def check_new_object(self,level=5):
295
py::object obj = "hello";
298
self.generic_new(code,"hello")
299
def check_new_fail(self,level=5):
303
a.set_attr(obj,"hello");
305
self.generic_new(code,"hello")
309
def check_existing_int(self,level=5):
310
self.generic_existing('a.set_attr("b",1);',1)
311
def check_existing_double(self,level=5):
312
self.generic_existing('a.set_attr("b",1.0);',1.0)
313
def check_existing_complex(self,level=5):
315
std::complex<double> obj = std::complex<double>(1,1);
318
self.generic_existing(code,1+1j)
319
def check_existing_char1(self,level=5):
320
self.generic_existing('a.set_attr("b","hello");',"hello")
321
def check_existing_string1(self,level=5):
323
std::string obj = std::string("hello");
326
self.generic_existing(code,"hello")
328
class test_object_del(ScipyTestCase):
329
def generic(self, code):
333
res = inline_tools.inline(code,args)
334
assert not hasattr(a,"b")
336
def check_char(self,level=5):
337
self.generic('a.del("b");')
338
def check_string(self,level=5):
340
std::string name = std::string("b");
344
def check_object(self,level=5):
346
py::object name = py::object("b");
351
class test_object_cmp(ScipyTestCase):
352
def check_equal(self,level=5):
354
res = inline_tools.inline('return_val = (a == b);',['a','b'])
355
assert res == (a == b)
356
def check_equal_objects(self,level=5):
358
def __init__(self,x):
360
def __cmp__(self,other):
361
return cmp(self.x,other.x)
363
res = inline_tools.inline('return_val = (a == b);',['a','b'])
364
assert res == (a == b)
365
def check_lt(self,level=5):
367
res = inline_tools.inline('return_val = (a < b);',['a','b'])
368
assert res == (a < b)
369
def check_gt(self,level=5):
371
res = inline_tools.inline('return_val = (a > b);',['a','b'])
372
assert res == (a > b)
373
def check_gte(self,level=5):
375
res = inline_tools.inline('return_val = (a >= b);',['a','b'])
376
assert res == (a >= b)
377
def check_lte(self,level=5):
379
res = inline_tools.inline('return_val = (a <= b);',['a','b'])
380
assert res == (a <= b)
381
def check_not_equal(self,level=5):
383
res = inline_tools.inline('return_val = (a != b);',['a','b'])
384
assert res == (a != b)
385
def check_int(self,level=5):
387
res = inline_tools.inline('return_val = (a == 1);',['a'])
388
assert res == (a == 1)
389
def check_int2(self,level=5):
391
res = inline_tools.inline('return_val = (1 == a);',['a'])
392
assert res == (a == 1)
393
def check_unsigned_long(self,level=5):
395
res = inline_tools.inline('return_val = (a == (unsigned long)1);',['a'])
396
assert res == (a == 1)
397
def check_double(self,level=5):
399
res = inline_tools.inline('return_val = (a == 1.0);',['a'])
400
assert res == (a == 1.0)
401
def check_char(self,level=5):
403
res = inline_tools.inline('return_val = (a == "hello");',['a'])
404
assert res == (a == "hello")
405
def check_std_string(self,level=5):
408
std::string hello = std::string("hello");
409
return_val = (a == hello);
411
res = inline_tools.inline(code,['a'])
412
assert res == (a == "hello")
414
class test_object_repr(ScipyTestCase):
415
def check_repr(self,level=5):
422
res = inline_tools.inline('return_val = a.repr();',['a'])
423
first = sys.getrefcount(res)
425
res = inline_tools.inline('return_val = a.repr();',['a'])
426
second = sys.getrefcount(res)
427
assert first == second
428
assert res == "repr return"
430
class test_object_str(ScipyTestCase):
431
def check_str(self,level=5):
438
res = inline_tools.inline('return_val = a.str();',['a'])
439
first = sys.getrefcount(res)
441
res = inline_tools.inline('return_val = a.str();',['a'])
442
second = sys.getrefcount(res)
443
assert first == second
445
assert res == "str return"
447
class test_object_unicode(ScipyTestCase):
448
# This ain't going to win awards for test of the year...
449
def check_unicode(self,level=5):
456
res = inline_tools.inline('return_val = a.unicode();',['a'])
457
first = sys.getrefcount(res)
459
res = inline_tools.inline('return_val = a.unicode();',['a'])
460
second = sys.getrefcount(res)
461
assert first == second
462
assert res == "unicode"
464
class test_object_is_callable(ScipyTestCase):
465
def check_true(self,level=5):
470
res = inline_tools.inline('return_val = a.is_callable();',['a'])
472
def check_false(self,level=5):
476
res = inline_tools.inline('return_val = a.is_callable();',['a'])
479
class test_object_call(ScipyTestCase):
480
def check_noargs(self,level=5):
483
res = inline_tools.inline('return_val = foo.call();',['foo'])
484
assert res == (1,2,3)
485
assert sys.getrefcount(res) == 2
486
def check_args(self,level=5):
493
return_val = foo.call(args);
495
res = inline_tools.inline(code,['foo'])
496
assert res == (1,"hello")
497
assert sys.getrefcount(res) == 2
498
def check_args_kw(self,level=5):
499
def foo(val1,val2,val3=1):
500
return (val1,val2,val3)
507
return_val = foo.call(args,kw);
509
res = inline_tools.inline(code,['foo'])
510
assert res == (1,"hello",3)
511
assert sys.getrefcount(res) == 2
512
def check_noargs_with_args(self,level=5):
513
# calling a function that does take args with args
521
return_val = foo.call(args);
524
first = sys.getrefcount(foo)
525
res = inline_tools.inline(code,['foo'])
527
second = sys.getrefcount(foo)
529
res = inline_tools.inline(code,['foo'])
531
third = sys.getrefcount(foo)
532
# first should == second, but the weird refcount error
533
assert second == third
535
class test_object_mcall(ScipyTestCase):
536
def check_noargs(self,level=5):
538
res = inline_tools.inline('return_val = a.mcall("bar");',['a'])
539
assert res == "bar results"
540
first = sys.getrefcount(res)
542
res = inline_tools.inline('return_val = a.mcall("bar");',['a'])
543
assert res == "bar results"
544
second = sys.getrefcount(res)
545
assert first == second
546
def check_args(self,level=5):
552
return_val = a.mcall("bar2",args);
554
res = inline_tools.inline(code,['a'])
555
assert res == (1,"hello")
556
assert sys.getrefcount(res) == 2
557
def check_args_kw(self,level=5):
565
return_val = a.mcall("bar3",args,kw);
567
res = inline_tools.inline(code,['a'])
568
assert res == (1,"hello",3)
569
assert sys.getrefcount(res) == 2
570
def check_std_noargs(self,level=5):
573
res = inline_tools.inline('return_val = a.mcall(method);',['a','method'])
574
assert res == "bar results"
575
first = sys.getrefcount(res)
577
res = inline_tools.inline('return_val = a.mcall(method);',['a','method'])
578
assert res == "bar results"
579
second = sys.getrefcount(res)
580
assert first == second
581
def check_std_args(self,level=5):
588
return_val = a.mcall(method,args);
590
res = inline_tools.inline(code,['a','method'])
591
assert res == (1,"hello")
592
assert sys.getrefcount(res) == 2
593
def check_std_args_kw(self,level=5):
602
return_val = a.mcall(method,args,kw);
604
res = inline_tools.inline(code,['a','method'])
605
assert res == (1,"hello",3)
606
assert sys.getrefcount(res) == 2
607
def check_noargs_with_args(self,level=5):
608
# calling a function that does take args with args
615
return_val = a.mcall("bar",args);
618
first = sys.getrefcount(a)
619
res = inline_tools.inline(code,['a'])
621
second = sys.getrefcount(a)
623
res = inline_tools.inline(code,['a'])
625
third = sys.getrefcount(a)
626
# first should == second, but the weird refcount error
627
assert second == third
629
class test_object_hash(ScipyTestCase):
630
def check_hash(self,level=5):
635
res = inline_tools.inline('return_val = a.hash(); ',['a'])
639
class test_object_is_true(ScipyTestCase):
640
def check_true(self,level=5):
644
res = inline_tools.inline('return_val = a.is_true();',['a'])
646
def check_false(self,level=5):
648
res = inline_tools.inline('return_val = a.is_true();',['a'])
651
class test_object_is_true(ScipyTestCase):
652
def check_false(self,level=5):
656
res = inline_tools.inline('return_val = a.not();',['a'])
658
def check_true(self,level=5):
660
res = inline_tools.inline('return_val = a.not();',['a'])
663
class test_object_type(ScipyTestCase):
664
def check_type(self,level=5):
668
res = inline_tools.inline('return_val = a.type();',['a'])
669
assert res == type(a)
671
class test_object_size(ScipyTestCase):
672
def check_size(self,level=5):
677
res = inline_tools.inline('return_val = a.size();',['a'])
679
def check_len(self,level=5):
684
res = inline_tools.inline('return_val = a.len();',['a'])
686
def check_length(self,level=5):
691
res = inline_tools.inline('return_val = a.length();',['a'])
694
from UserList import UserList
695
class test_object_set_item_op_index(ScipyTestCase):
696
def check_list_refcount(self,level=5):
697
a = UserList([1,2,3])
698
# temporary refcount fix until I understand why it incs by one.
699
inline_tools.inline("a[1] = 1234;",['a'])
700
before1 = sys.getrefcount(a)
701
after1 = sys.getrefcount(a)
702
assert after1 == before1
703
def check_set_int(self,level=5):
704
a = UserList([1,2,3])
705
inline_tools.inline("a[1] = 1234;",['a'])
706
assert sys.getrefcount(a[1]) == 2
708
def check_set_double(self,level=5):
709
a = UserList([1,2,3])
710
inline_tools.inline("a[1] = 123.0;",['a'])
711
assert sys.getrefcount(a[1]) == 2
713
def check_set_char(self,level=5):
714
a = UserList([1,2,3])
715
inline_tools.inline('a[1] = "bubba";',['a'])
716
assert sys.getrefcount(a[1]) == 2
717
assert a[1] == 'bubba'
718
def check_set_string(self,level=5):
719
a = UserList([1,2,3])
720
inline_tools.inline('a[1] = std::string("sissy");',['a'])
721
assert sys.getrefcount(a[1]) == 2
722
assert a[1] == 'sissy'
723
def check_set_string(self,level=5):
724
a = UserList([1,2,3])
725
inline_tools.inline('a[1] = std::complex<double>(1,1);',['a'])
726
assert sys.getrefcount(a[1]) == 2
729
from UserDict import UserDict
730
class test_object_set_item_op_key(ScipyTestCase):
731
def check_key_refcount(self,level=5):
736
py::tuple ref_counts(3);
737
py::tuple obj_counts(3);
738
py::tuple val_counts(3);
739
py::tuple key_counts(3);
740
obj_counts[0] = a.refcount();
741
key_counts[0] = one.refcount();
742
val_counts[0] = two.refcount();
744
obj_counts[1] = a.refcount();
745
key_counts[1] = one.refcount();
746
val_counts[1] = two.refcount();
748
obj_counts[2] = a.refcount();
749
key_counts[2] = one.refcount();
750
val_counts[2] = two.refcount();
752
ref_counts[0] = obj_counts;
753
ref_counts[1] = key_counts;
754
ref_counts[2] = val_counts;
755
return_val = ref_counts;
757
obj,key,val = inline_tools.inline(code,['a'])
758
assert obj[0] == obj[1] and obj[1] == obj[2]
759
assert key[0] + 1 == key[1] and key[1] == key[2]
760
assert val[0] + 1 == val[1] and val[1] == val[2]
762
def check_set_double_exists(self,level=5):
766
inline_tools.inline('a[key] = 123.0;',['a','key'])
767
first = sys.getrefcount(key)
768
inline_tools.inline('a[key] = 123.0;',['a','key'])
769
second = sys.getrefcount(key)
770
assert first == second
771
# !! I think the following should be 3
772
assert sys.getrefcount(key) == 5
773
assert sys.getrefcount(a[key]) == 2
774
assert a[key] == 123.0
775
def check_set_double_new(self,level=5):
778
inline_tools.inline('a[key] = 123.0;',['a','key'])
779
assert sys.getrefcount(key) == 4 # should be 3
780
assert sys.getrefcount(a[key]) == 2
781
assert a[key] == 123.0
782
def check_set_complex(self,level=5):
785
inline_tools.inline("a[key] = 1234;",['a','key'])
786
assert sys.getrefcount(key) == 3
787
assert sys.getrefcount(a[key]) == 2
788
assert a[key] == 1234
789
def check_set_char(self,level=5):
791
inline_tools.inline('a["hello"] = 123.0;',['a'])
792
assert sys.getrefcount(a["hello"]) == 2
793
assert a["hello"] == 123.0
795
def check_set_class(self,level=5):
798
def __init__(self,val):
803
inline_tools.inline('a[key] = "bubba";',['a','key'])
804
first = sys.getrefcount(key)
805
inline_tools.inline('a[key] = "bubba";',['a','key'])
806
second = sys.getrefcount(key)
807
# I don't think we're leaking if this is true
808
assert first == second
809
# !! BUT -- I think this should be 3
810
assert sys.getrefcount(key) == 4
811
assert sys.getrefcount(a[key]) == 2
812
assert a[key] == 'bubba'
813
def check_set_from_member(self,level=5):
817
inline_tools.inline('a["first"] = a["second"];',['a'])
818
assert a['first'] == a['second']
820
if __name__ == "__main__":