~ubuntu-branches/ubuntu/karmic/pypy/karmic

« back to all changes in this revision

Viewing changes to pypy/annotation/test/test_annrpython.py

  • Committer: Bazaar Package Importer
  • Author(s): Alexandre Fayolle
  • Date: 2007-04-13 09:33:09 UTC
  • Revision ID: james.westby@ubuntu.com-20070413093309-yoojh4jcoocu2krz
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
import autopath
 
3
import py.test
 
4
from pypy import conftest
 
5
from pypy.tool.udir import udir
 
6
 
 
7
from pypy.annotation import model as annmodel
 
8
from pypy.annotation.annrpython import RPythonAnnotator as _RPythonAnnotator
 
9
from pypy.translator.translator import graphof as tgraphof
 
10
from pypy.annotation import policy
 
11
from pypy.annotation import specialize
 
12
from pypy.annotation.listdef import ListDef
 
13
from pypy.annotation.dictdef import DictDef
 
14
from pypy.objspace.flow.model import *
 
15
from pypy.rlib.rarithmetic import r_uint, base_int, r_longlong, r_ulonglong
 
16
from pypy.rlib import objectmodel
 
17
from pypy.objspace.flow import FlowObjSpace
 
18
 
 
19
from pypy.translator.test import snippet
 
20
 
 
21
def graphof(a, func):
 
22
    return tgraphof(a.translator, func)
 
23
 
 
24
def listitem(s_list):
 
25
    assert isinstance(s_list, annmodel.SomeList)
 
26
    return s_list.listdef.listitem.s_value
 
27
 
 
28
def somelist(s_type=annmodel.SomeObject()):
 
29
    return annmodel.SomeList(ListDef(None, s_type))
 
30
 
 
31
def dictkey(s_dict):
 
32
    assert isinstance(s_dict, annmodel.SomeDict)
 
33
    return s_dict.dictdef.dictkey.s_value
 
34
 
 
35
def dictvalue(s_dict):
 
36
    assert isinstance(s_dict, annmodel.SomeDict)
 
37
    return s_dict.dictdef.dictvalue.s_value
 
38
 
 
39
def somedict(s_key=annmodel.SomeObject(), s_value=annmodel.SomeObject()):
 
40
    return annmodel.SomeDict(DictDef(None, s_key, s_value))
 
41
 
 
42
 
 
43
class TestAnnotateTestCase:
 
44
    def setup_class(cls): 
 
45
        cls.space = FlowObjSpace() 
 
46
 
 
47
    def teardown_method(self, meth):
 
48
        assert annmodel.s_Bool == annmodel.SomeBool()
 
49
 
 
50
    class RPythonAnnotator(_RPythonAnnotator):
 
51
        def build_types(self, *args):
 
52
            s = _RPythonAnnotator.build_types(self, *args)
 
53
            if conftest.option.view:
 
54
                self.translator.view()
 
55
            return s
 
56
 
 
57
    def make_fun(self, func):
 
58
        import inspect
 
59
        try:
 
60
            func = func.im_func
 
61
        except AttributeError:
 
62
            pass
 
63
        name = func.func_name
 
64
        funcgraph = self.space.build_flow(func)
 
65
        funcgraph.source = inspect.getsource(func)
 
66
        return funcgraph
 
67
 
 
68
    def test_simple_func(self):
 
69
        """
 
70
        one test source:
 
71
        def f(x):
 
72
            return x+1
 
73
        """
 
74
        x = Variable("x")
 
75
        result = Variable("result")
 
76
        op = SpaceOperation("add", [x, Constant(1)], result)
 
77
        block = Block([x])
 
78
        fun = FunctionGraph("f", block)
 
79
        block.operations.append(op)
 
80
        block.closeblock(Link([result], fun.returnblock))
 
81
        a = self.RPythonAnnotator()
 
82
        a.addpendingblock(fun, fun.startblock, [annmodel.SomeInteger()])
 
83
        a.complete()
 
84
        assert a.gettype(fun.getreturnvar()) == int
 
85
 
 
86
    def test_while(self):
 
87
        """
 
88
        one test source:
 
89
        def f(i):
 
90
            while i > 0:
 
91
                i = i - 1
 
92
            return i
 
93
        """
 
94
        i1 = Variable("i1")
 
95
        i2 = Variable("i2")
 
96
        i3 = Variable("i3")
 
97
        conditionres = Variable("conditionres")
 
98
        conditionop = SpaceOperation("gt", [i1, Constant(0)], conditionres)
 
99
        decop = SpaceOperation("add", [i2, Constant(-1)], i3)
 
100
        headerblock = Block([i1])
 
101
        whileblock = Block([i2])
 
102
 
 
103
        fun = FunctionGraph("f", headerblock)
 
104
        headerblock.operations.append(conditionop)
 
105
        headerblock.exitswitch = conditionres
 
106
        headerblock.closeblock(Link([i1], fun.returnblock, False),
 
107
                               Link([i1], whileblock, True))
 
108
        whileblock.operations.append(decop)
 
109
        whileblock.closeblock(Link([i3], headerblock))
 
110
 
 
111
        a = self.RPythonAnnotator()
 
112
        a.addpendingblock(fun, fun.startblock, [annmodel.SomeInteger()])
 
113
        a.complete()
 
114
        assert a.gettype(fun.getreturnvar()) == int
 
115
 
 
116
    def test_while_sum(self):
 
117
        """
 
118
        one test source:
 
119
        def f(i):
 
120
            sum = 0
 
121
            while i > 0:
 
122
                sum = sum + i
 
123
                i = i - 1
 
124
            return sum
 
125
        """
 
126
        i1 = Variable("i1")
 
127
        i2 = Variable("i2")
 
128
        i3 = Variable("i3")
 
129
        i4 = Variable("i4")
 
130
        sum2 = Variable("sum2")
 
131
        sum3 = Variable("sum3")
 
132
        sum4 = Variable("sum4")
 
133
 
 
134
        conditionres = Variable("conditionres")
 
135
        conditionop = SpaceOperation("gt", [i2, Constant(0)], conditionres)
 
136
        decop = SpaceOperation("add", [i3, Constant(-1)], i4)
 
137
        addop = SpaceOperation("add", [i3, sum3], sum4)
 
138
        startblock = Block([i1])
 
139
        headerblock = Block([i2, sum2])
 
140
        whileblock = Block([i3, sum3])
 
141
 
 
142
        fun = FunctionGraph("f", startblock)
 
143
        startblock.closeblock(Link([i1, Constant(0)], headerblock))
 
144
        headerblock.operations.append(conditionop)
 
145
        headerblock.exitswitch = conditionres
 
146
        headerblock.closeblock(Link([sum2], fun.returnblock, False),
 
147
                               Link([i2, sum2], whileblock, True))
 
148
        whileblock.operations.append(addop)
 
149
        whileblock.operations.append(decop)
 
150
        whileblock.closeblock(Link([i4, sum4], headerblock))
 
151
 
 
152
        a = self.RPythonAnnotator()
 
153
        a.addpendingblock(fun, fun.startblock, [annmodel.SomeInteger()])
 
154
        a.complete()
 
155
        assert a.gettype(fun.getreturnvar()) == int
 
156
 
 
157
    def test_f_calls_g(self):
 
158
        a = self.RPythonAnnotator()
 
159
        s = a.build_types(f_calls_g, [int])
 
160
        # result should be an integer
 
161
        assert s.knowntype == int
 
162
 
 
163
    def test_lists(self):
 
164
        a = self.RPythonAnnotator()
 
165
        end_cell = a.build_types(snippet.poor_man_rev_range, [int])
 
166
        # result should be a list of integers
 
167
        assert listitem(end_cell).knowntype == int
 
168
 
 
169
    def test_factorial(self):
 
170
        a = self.RPythonAnnotator()
 
171
        s = a.build_types(snippet.factorial, [int])
 
172
        # result should be an integer
 
173
        assert s.knowntype == int
 
174
 
 
175
    def test_factorial2(self):
 
176
        a = self.RPythonAnnotator()
 
177
        s = a.build_types(snippet.factorial2, [int])
 
178
        # result should be an integer
 
179
        assert s.knowntype == int
 
180
 
 
181
    def test_build_instance(self):
 
182
        a = self.RPythonAnnotator()
 
183
        s = a.build_types(snippet.build_instance, [])
 
184
        # result should be a snippet.C instance
 
185
        assert isinstance(s, annmodel.SomeInstance)
 
186
        assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.C)
 
187
 
 
188
    def test_set_attr(self):
 
189
        a = self.RPythonAnnotator()
 
190
        s = a.build_types(snippet.set_attr, [])
 
191
        # result should be an integer
 
192
        assert s.knowntype == int
 
193
 
 
194
    def test_merge_setattr(self):
 
195
        a = self.RPythonAnnotator()
 
196
        s = a.build_types(snippet.merge_setattr, [int])
 
197
        # result should be an integer
 
198
        assert s.knowntype == int
 
199
 
 
200
    def test_inheritance1(self):
 
201
        a = self.RPythonAnnotator()
 
202
        s = a.build_types(snippet.inheritance1, [])
 
203
        # result should be exactly:
 
204
        assert s == annmodel.SomeTuple([
 
205
                                a.bookkeeper.immutablevalue(()),
 
206
                                annmodel.SomeInteger()
 
207
                                ])
 
208
 
 
209
    def test_inheritance2(self):
 
210
        a = self.RPythonAnnotator()
 
211
        s = a.build_types(snippet._inheritance_nonrunnable, [])
 
212
        # result should be exactly:
 
213
        assert s == annmodel.SomeTuple([
 
214
                                annmodel.SomeInteger(),
 
215
                                annmodel.SomeObject()
 
216
                                ])
 
217
 
 
218
    def test_poor_man_range(self):
 
219
        a = self.RPythonAnnotator()
 
220
        s = a.build_types(snippet.poor_man_range, [int])
 
221
        # result should be a list of integers
 
222
        assert listitem(s).knowntype == int
 
223
 
 
224
    def test_methodcall1(self):
 
225
        a = self.RPythonAnnotator()
 
226
        s = a.build_types(snippet._methodcall1, [int])
 
227
        # result should be a tuple of (C, positive_int)
 
228
        assert s.knowntype == tuple
 
229
        assert len(s.items) == 2
 
230
        s0 = s.items[0]
 
231
        assert isinstance(s0, annmodel.SomeInstance)
 
232
        assert s0.classdef == a.bookkeeper.getuniqueclassdef(snippet.C)
 
233
        assert s.items[1].knowntype == int
 
234
        assert s.items[1].nonneg == True
 
235
 
 
236
    def test_classes_methodcall1(self):
 
237
        a = self.RPythonAnnotator()
 
238
        a.build_types(snippet._methodcall1, [int])
 
239
        # the user classes should have the following attributes:
 
240
        getcdef = a.bookkeeper.getuniqueclassdef
 
241
        assert getcdef(snippet.F).attrs.keys() == ['m']
 
242
        assert getcdef(snippet.G).attrs.keys() == ['m2']
 
243
        assert getcdef(snippet.H).attrs.keys() == ['attr'] 
 
244
        assert getcdef(snippet.H).about_attribute('attr') == (
 
245
                          a.bookkeeper.immutablevalue(1))
 
246
 
 
247
    def DISABLED_test_knownkeysdict(self):
 
248
        # disabled, SomeDict() is now a general {s_key: s_value} dict
 
249
        a = self.RPythonAnnotator()
 
250
        s = a.build_types(snippet.knownkeysdict, [int])
 
251
        # result should be an integer
 
252
        assert s.knowntype == int
 
253
 
 
254
    def test_generaldict(self):
 
255
        a = self.RPythonAnnotator()
 
256
        s = a.build_types(snippet.generaldict, [str, int, str, int])
 
257
        # result should be an integer
 
258
        assert s.knowntype == int
 
259
 
 
260
    def test_somebug1(self):
 
261
        a = self.RPythonAnnotator()
 
262
        s = a.build_types(snippet._somebug1, [int])
 
263
        # result should be a built-in method
 
264
        assert isinstance(s, annmodel.SomeBuiltin)
 
265
 
 
266
    def test_with_init(self):
 
267
        a = self.RPythonAnnotator()
 
268
        s = a.build_types(snippet.with_init, [int])
 
269
        # result should be an integer
 
270
        assert s.knowntype == int
 
271
 
 
272
    def test_with_more_init(self):
 
273
        a = self.RPythonAnnotator()
 
274
        s = a.build_types(snippet.with_more_init, [int, bool])
 
275
        # the user classes should have the following attributes:
 
276
        getcdef = a.bookkeeper.getuniqueclassdef
 
277
        # XXX on which class should the attribute 'a' appear?  We only
 
278
        #     ever flow WithInit.__init__ with a self which is an instance
 
279
        #     of WithMoreInit, so currently it appears on WithMoreInit.
 
280
        assert getcdef(snippet.WithMoreInit).about_attribute('a') == (
 
281
                          annmodel.SomeInteger())
 
282
        assert getcdef(snippet.WithMoreInit).about_attribute('b') == (
 
283
                          annmodel.SomeBool())
 
284
 
 
285
    def test_global_instance(self):
 
286
        a = self.RPythonAnnotator()
 
287
        s = a.build_types(snippet.global_instance, [])
 
288
        # currently this returns the constant 42.
 
289
        # XXX not sure this is the best behavior...
 
290
        assert s == a.bookkeeper.immutablevalue(42)
 
291
 
 
292
    def test_call_five(self):
 
293
        a = self.RPythonAnnotator()
 
294
        s = a.build_types(snippet.call_five, [])
 
295
        # returns should be a list of constants (= 5)
 
296
        assert listitem(s) == a.bookkeeper.immutablevalue(5)
 
297
 
 
298
    def test_call_five_six(self):
 
299
        a = self.RPythonAnnotator()
 
300
        s = a.build_types(snippet.call_five_six, [])
 
301
        # returns should be a list of positive integers
 
302
        assert listitem(s) == annmodel.SomeInteger(nonneg=True)
 
303
 
 
304
    def test_constant_result(self):
 
305
        a = self.RPythonAnnotator()
 
306
        s = a.build_types(snippet.constant_result, [])
 
307
        #a.translator.simplify()
 
308
        # must return "yadda"
 
309
        assert s == a.bookkeeper.immutablevalue("yadda")
 
310
        graphs = a.translator.graphs
 
311
        assert len(graphs) == 2
 
312
        assert graphs[0].func is snippet.constant_result
 
313
        assert graphs[1].func is snippet.forty_two
 
314
        a.simplify()
 
315
        #a.translator.view()
 
316
 
 
317
    def test_flow_type_info(self):
 
318
        a = self.RPythonAnnotator()
 
319
        s = a.build_types(snippet.flow_type_info, [object])
 
320
        a.simplify()
 
321
        #a.translator.view()
 
322
        assert s.knowntype == int
 
323
 
 
324
    def test_flow_type_info_2(self):
 
325
        a = self.RPythonAnnotator()
 
326
        s = a.build_types(snippet.flow_type_info,
 
327
                          [annmodel.SomeInteger(nonneg=True)])
 
328
        # this checks that isinstance(i, int) didn't lose the
 
329
        # actually more precise information that i is non-negative
 
330
        assert s == annmodel.SomeInteger(nonneg=True)
 
331
 
 
332
    def test_flow_usertype_info(self):
 
333
        a = self.RPythonAnnotator()
 
334
        s = a.build_types(snippet.flow_usertype_info, [object])
 
335
        #a.translator.view()
 
336
        assert isinstance(s, annmodel.SomeInstance)
 
337
        assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithInit)
 
338
 
 
339
    def test_flow_usertype_info2(self):
 
340
        a = self.RPythonAnnotator()
 
341
        s = a.build_types(snippet.flow_usertype_info, [snippet.WithMoreInit])
 
342
        #a.translator.view()
 
343
        assert isinstance(s, annmodel.SomeInstance)
 
344
        assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithMoreInit)
 
345
 
 
346
    def test_flow_identity_info(self):
 
347
        a = self.RPythonAnnotator()
 
348
        s = a.build_types(snippet.flow_identity_info, [object, object])
 
349
        a.simplify()
 
350
        #a.translator.view()
 
351
        assert s == a.bookkeeper.immutablevalue((None, None))
 
352
 
 
353
    def test_mergefunctions(self):
 
354
        a = self.RPythonAnnotator()
 
355
        s = a.build_types(snippet.mergefunctions, [int])
 
356
        # the test is mostly that the above line hasn't blown up
 
357
        # but let's at least check *something*
 
358
        assert isinstance(s, annmodel.SomePBC)
 
359
 
 
360
    def test_func_calls_func_which_just_raises(self):
 
361
        a = self.RPythonAnnotator()
 
362
        s = a.build_types(snippet.funccallsex, [])
 
363
        # the test is mostly that the above line hasn't blown up
 
364
        # but let's at least check *something*
 
365
        #self.assert_(isinstance(s, SomeCallable))
 
366
 
 
367
    def test_tuple_unpack_from_const_tuple_with_different_types(self):
 
368
        a = self.RPythonAnnotator()
 
369
        s = a.build_types(snippet.func_arg_unpack, [])
 
370
        assert isinstance(s, annmodel.SomeInteger) 
 
371
        assert s.const == 3 
 
372
 
 
373
    def test_pbc_attr_preserved_on_instance(self):
 
374
        a = self.RPythonAnnotator()
 
375
        s = a.build_types(snippet.preserve_pbc_attr_on_instance, [bool])
 
376
        #a.simplify()
 
377
        #a.translator.view()
 
378
        assert s == annmodel.SomeInteger(nonneg=True) 
 
379
        #self.assertEquals(s.__class__, annmodel.SomeInteger) 
 
380
 
 
381
    def test_pbc_attr_preserved_on_instance_with_slots(self):
 
382
        a = self.RPythonAnnotator()
 
383
        s = a.build_types(snippet.preserve_pbc_attr_on_instance_with_slots,
 
384
                          [bool])
 
385
        assert s == annmodel.SomeInteger(nonneg=True) 
 
386
 
 
387
    def test_is_and_knowntype_data(self): 
 
388
        a = self.RPythonAnnotator()
 
389
        s = a.build_types(snippet.is_and_knowntype, [str])
 
390
        #a.simplify()
 
391
        #a.translator.view()
 
392
        assert s == a.bookkeeper.immutablevalue(None)
 
393
 
 
394
    def test_isinstance_and_knowntype_data(self): 
 
395
        a = self.RPythonAnnotator()
 
396
        x = a.bookkeeper.immutablevalue(snippet.apbc)
 
397
        s = a.build_types(snippet.isinstance_and_knowntype, [x]) 
 
398
        #a.simplify()
 
399
        #a.translator.view()
 
400
        assert s == x
 
401
 
 
402
    def test_somepbc_simplify(self):
 
403
        a = self.RPythonAnnotator()
 
404
        # this example used to trigger an AssertionError
 
405
        a.build_types(snippet.somepbc_simplify, [])
 
406
 
 
407
    def test_builtin_methods(self):
 
408
        a = self.RPythonAnnotator()
 
409
        iv = a.bookkeeper.immutablevalue
 
410
        # this checks that some built-in methods are really supported by
 
411
        # the annotator (it doesn't check that they operate property, though)
 
412
        for example, methname, s_example in [
 
413
            ('', 'join',    annmodel.SomeString()),
 
414
            ([], 'append',  somelist()), 
 
415
            ([], 'extend',  somelist()),           
 
416
            ([], 'reverse', somelist()),
 
417
            ([], 'insert',  somelist()),
 
418
            ([], 'pop',     somelist()),
 
419
            ]:
 
420
            constmeth = getattr(example, methname)
 
421
            s_constmeth = iv(constmeth)
 
422
            assert isinstance(s_constmeth, annmodel.SomeBuiltin)
 
423
            s_meth = s_example.getattr(iv(methname))
 
424
            assert isinstance(s_constmeth, annmodel.SomeBuiltin)
 
425
 
 
426
    def test_simple_slicing0(self):
 
427
        a = self.RPythonAnnotator()
 
428
        a.build_types(snippet.simple_slice, [list])
 
429
        g = graphof(a, snippet.simple_slice)
 
430
        for block in g.iterblocks():
 
431
            for op in block.operations:
 
432
                if op.opname == "newslice":
 
433
                    assert isinstance(a.binding(op.result),
 
434
                                      annmodel.SomeSlice)
 
435
 
 
436
    def test_simple_slicing(self):
 
437
        a = self.RPythonAnnotator()
 
438
        s = a.build_types(snippet.simple_slice, [list])
 
439
        assert isinstance(s, annmodel.SomeList)
 
440
 
 
441
    def test_simple_iter_list(self):
 
442
        a = self.RPythonAnnotator()
 
443
        s = a.build_types(snippet.simple_iter, [list])
 
444
        assert isinstance(s, annmodel.SomeIterator)
 
445
        
 
446
    def test_simple_iter_next(self):
 
447
        def f(x):
 
448
            i = iter(range(x))
 
449
            return i.next()
 
450
        a = self.RPythonAnnotator()
 
451
        s = a.build_types(f, [int])
 
452
        assert isinstance(s, annmodel.SomeInteger)
 
453
 
 
454
    def test_simple_iter_dict(self):
 
455
        a = self.RPythonAnnotator()
 
456
        t = somedict(annmodel.SomeInteger(), annmodel.SomeInteger())
 
457
        s = a.build_types(snippet.simple_iter, [t])
 
458
        assert isinstance(s, annmodel.SomeIterator)
 
459
 
 
460
    def test_simple_zip(self):
 
461
        a = self.RPythonAnnotator()
 
462
        x = somelist(annmodel.SomeInteger())
 
463
        y = somelist(annmodel.SomeString())
 
464
        s = a.build_types(snippet.simple_zip, [x,y])
 
465
        assert s.knowntype == list
 
466
        assert listitem(s).knowntype == tuple
 
467
        assert listitem(s).items[0].knowntype == int
 
468
        assert listitem(s).items[1].knowntype == str
 
469
        
 
470
    def test_dict_copy(self):
 
471
        a = self.RPythonAnnotator()
 
472
        t = somedict(annmodel.SomeInteger(), annmodel.SomeInteger())
 
473
        s = a.build_types(snippet.dict_copy, [t])
 
474
        assert isinstance(dictkey(s), annmodel.SomeInteger)
 
475
        assert isinstance(dictvalue(s), annmodel.SomeInteger)
 
476
 
 
477
    def test_dict_update(self):
 
478
        a = self.RPythonAnnotator()
 
479
        s = a.build_types(snippet.dict_update, [int])
 
480
        assert isinstance(dictkey(s), annmodel.SomeInteger)
 
481
        assert isinstance(dictvalue(s), annmodel.SomeInteger)
 
482
 
 
483
        a = self.RPythonAnnotator()
 
484
        s = a.build_types(snippet.dict_update, [str])
 
485
        assert not isinstance(dictkey(s), annmodel.SomeString)
 
486
        assert not isinstance(dictvalue(s), annmodel.SomeString)
 
487
 
 
488
    def test_dict_keys(self):
 
489
        a = self.RPythonAnnotator()
 
490
        s = a.build_types(snippet.dict_keys, [])
 
491
        assert isinstance(listitem(s), annmodel.SomeString)
 
492
 
 
493
    def test_dict_keys2(self):
 
494
        a = self.RPythonAnnotator()
 
495
        s = a.build_types(snippet.dict_keys2, [])
 
496
        assert not isinstance(listitem(s), annmodel.SomeString)
 
497
 
 
498
    def test_dict_values(self):
 
499
        a = self.RPythonAnnotator()
 
500
        s = a.build_types(snippet.dict_values, [])
 
501
        assert isinstance(listitem(s), annmodel.SomeString)
 
502
    
 
503
    def test_dict_values2(self):
 
504
        a = self.RPythonAnnotator()
 
505
        s = a.build_types(snippet.dict_values2, [])
 
506
        assert not isinstance(listitem(s), annmodel.SomeString)
 
507
 
 
508
    def test_dict_items(self):
 
509
        a = self.RPythonAnnotator()
 
510
        s = a.build_types(snippet.dict_items, [])
 
511
        assert isinstance(listitem(s), annmodel.SomeTuple)
 
512
        s_key, s_value = listitem(s).items
 
513
        assert isinstance(s_key, annmodel.SomeString)
 
514
        assert isinstance(s_value, annmodel.SomeInteger)
 
515
 
 
516
    def test_dict_setdefault(self):
 
517
        a = self.RPythonAnnotator()
 
518
        def f():
 
519
            d = {}
 
520
            d.setdefault('a', 2)
 
521
            d.setdefault('a', -3)
 
522
            return d
 
523
        s = a.build_types(f, [])
 
524
        assert isinstance(s, annmodel.SomeDict)
 
525
        assert isinstance(dictkey(s), annmodel.SomeString)
 
526
        assert isinstance(dictvalue(s), annmodel.SomeInteger)
 
527
        assert not dictvalue(s).nonneg
 
528
        
 
529
    def test_exception_deduction(self):
 
530
        a = self.RPythonAnnotator()
 
531
        s = a.build_types(snippet.exception_deduction, [])
 
532
        assert isinstance(s, annmodel.SomeInstance)
 
533
        assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc)
 
534
        
 
535
    def test_exception_deduction_we_are_dumb(self):
 
536
        a = self.RPythonAnnotator()
 
537
        s = a.build_types(snippet.exception_deduction_we_are_dumb, [])
 
538
        assert isinstance(s, annmodel.SomeInstance)
 
539
        assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc)
 
540
        
 
541
    def test_nested_exception_deduction(self):
 
542
        a = self.RPythonAnnotator()
 
543
        s = a.build_types(snippet.nested_exception_deduction, [])
 
544
        assert isinstance(s, annmodel.SomeTuple)
 
545
        assert isinstance(s.items[0], annmodel.SomeInstance)
 
546
        assert isinstance(s.items[1], annmodel.SomeInstance)
 
547
        assert s.items[0].classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc)
 
548
        assert s.items[1].classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc2)
 
549
 
 
550
    def test_exc_deduction_our_exc_plus_others(self):
 
551
        a = self.RPythonAnnotator()
 
552
        s = a.build_types(snippet.exc_deduction_our_exc_plus_others, [])
 
553
        assert isinstance(s, annmodel.SomeInteger)
 
554
 
 
555
    def test_exc_deduction_our_excs_plus_others(self):
 
556
        a = self.RPythonAnnotator()
 
557
        s = a.build_types(snippet.exc_deduction_our_excs_plus_others, [])
 
558
        assert isinstance(s, annmodel.SomeInteger)
 
559
 
 
560
    def test_operation_always_raising(self):
 
561
        def operation_always_raising(n):
 
562
            lst = []
 
563
            try:
 
564
                return lst[n]
 
565
            except IndexError:
 
566
                return 24
 
567
        a = self.RPythonAnnotator()
 
568
        s = a.build_types(operation_always_raising, [int])
 
569
        assert s == a.bookkeeper.immutablevalue(24)
 
570
 
 
571
    def test_slice_union(self):
 
572
        a = self.RPythonAnnotator()
 
573
        s = a.build_types(snippet.slice_union, [int])
 
574
        assert isinstance(s, annmodel.SomeSlice)
 
575
 
 
576
    def test_bltin_code_frame_confusion(self):
 
577
        a = self.RPythonAnnotator()
 
578
        a.build_types(snippet.bltin_code_frame_confusion,[])
 
579
        f_flowgraph = graphof(a, snippet.bltin_code_frame_f)
 
580
        g_flowgraph = graphof(a, snippet.bltin_code_frame_g)
 
581
        # annotator confused by original bltin code/frame setup, we just get SomeObject here
 
582
        assert a.binding(f_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject
 
583
        assert a.binding(g_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject
 
584
 
 
585
    def test_bltin_code_frame_reorg(self):
 
586
        a = self.RPythonAnnotator()
 
587
        a.build_types(snippet.bltin_code_frame_reorg,[])
 
588
        f_flowgraph = graphof(a, snippet.bltin_code_frame_f)
 
589
        g_flowgraph = graphof(a, snippet.bltin_code_frame_g)
 
590
        assert isinstance(a.binding(f_flowgraph.getreturnvar()),
 
591
                            annmodel.SomeInteger)
 
592
        assert isinstance(a.binding(g_flowgraph.getreturnvar()),
 
593
                          annmodel.SomeString)
 
594
 
 
595
    def test_propagation_of_fresh_instances_through_attrs(self):
 
596
        a = self.RPythonAnnotator()
 
597
        s = a.build_types(snippet.propagation_of_fresh_instances_through_attrs, [int])
 
598
        assert s is not None
 
599
 
 
600
    def test_propagation_of_fresh_instances_through_attrs_rec_0(self):
 
601
        a = self.RPythonAnnotator()
 
602
        s = a.build_types(snippet.make_r, [int])
 
603
        Rdef = a.bookkeeper.getuniqueclassdef(snippet.R)
 
604
        assert s.classdef == Rdef
 
605
        assert Rdef.attrs['r'].s_value.classdef == Rdef
 
606
        assert Rdef.attrs['n'].s_value.knowntype == int
 
607
        assert Rdef.attrs['m'].s_value.knowntype == int
 
608
    
 
609
        
 
610
    def test_propagation_of_fresh_instances_through_attrs_rec_eo(self):
 
611
        a = self.RPythonAnnotator()
 
612
        s = a.build_types(snippet.make_eo, [int])
 
613
        assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.B)
 
614
        Even_def = a.bookkeeper.getuniqueclassdef(snippet.Even)
 
615
        Odd_def = a.bookkeeper.getuniqueclassdef(snippet.Odd)
 
616
        assert listitem(Even_def.attrs['x'].s_value).classdef == Odd_def
 
617
        assert listitem(Even_def.attrs['y'].s_value).classdef == Even_def
 
618
        assert listitem(Odd_def.attrs['x'].s_value).classdef == Even_def
 
619
        assert listitem(Odd_def.attrs['y'].s_value).classdef == Odd_def
 
620
 
 
621
    def test_flow_rev_numbers(self):
 
622
        a = self.RPythonAnnotator()
 
623
        s = a.build_types(snippet.flow_rev_numbers, [int])
 
624
        assert s.knowntype == int
 
625
        assert not s.is_constant() # !
 
626
 
 
627
    def test_methodcall_is_precise(self):
 
628
        a = self.RPythonAnnotator()
 
629
        s = a.build_types(snippet.methodcall_is_precise, [bool])
 
630
        getcdef = a.bookkeeper.getuniqueclassdef
 
631
        assert 'x' not in getcdef(snippet.CBase).attrs
 
632
        assert (getcdef(snippet.CSub1).attrs['x'].s_value ==
 
633
                a.bookkeeper.immutablevalue(42))
 
634
        assert (getcdef(snippet.CSub2).attrs['x'].s_value ==
 
635
                a.bookkeeper.immutablevalue('world'))
 
636
        assert s == a.bookkeeper.immutablevalue(42)
 
637
 
 
638
    def test_call_star_args(self):
 
639
        a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy())
 
640
        s = a.build_types(snippet.call_star_args, [int])
 
641
        assert s.knowntype == int
 
642
 
 
643
    def test_call_star_args_multiple(self):
 
644
        a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy())
 
645
        s = a.build_types(snippet.call_star_args_multiple, [int])
 
646
        assert s.knowntype == int
 
647
 
 
648
    def test_class_spec(self):
 
649
        a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy())
 
650
        s = a.build_types(snippet.class_spec, [])
 
651
        assert s.items[0].knowntype == int
 
652
        assert s.items[1].knowntype == str
 
653
 
 
654
    def test_class_spec_confused(self):
 
655
        x = snippet.PolyStk()
 
656
        def f():
 
657
            return x
 
658
        a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy())
 
659
        py.test.raises(Exception, a.build_types, f, [])
 
660
 
 
661
    def test_exception_deduction_with_raise1(self):
 
662
        a = self.RPythonAnnotator()
 
663
        s = a.build_types(snippet.exception_deduction_with_raise1, [bool])
 
664
        assert isinstance(s, annmodel.SomeInstance)
 
665
        assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc)
 
666
 
 
667
 
 
668
    def test_exception_deduction_with_raise2(self):
 
669
        a = self.RPythonAnnotator()
 
670
        s = a.build_types(snippet.exception_deduction_with_raise2, [bool])
 
671
        assert isinstance(s, annmodel.SomeInstance)
 
672
        assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc)
 
673
 
 
674
    def test_exception_deduction_with_raise3(self):
 
675
        a = self.RPythonAnnotator()
 
676
        s = a.build_types(snippet.exception_deduction_with_raise3, [bool])
 
677
        assert isinstance(s, annmodel.SomeInstance)
 
678
        assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc)
 
679
 
 
680
    def test_type_is(self):
 
681
        class C(object):
 
682
            pass
 
683
        def f(x):
 
684
            if type(x) is C:
 
685
                return x
 
686
            raise Exception
 
687
        a = self.RPythonAnnotator()
 
688
        s = a.build_types(f, [object])
 
689
        assert s.classdef is a.bookkeeper.getuniqueclassdef(C)
 
690
 
 
691
    def test_ann_assert(self):
 
692
        def assert_(x):
 
693
            assert x,"XXX"
 
694
        a = self.RPythonAnnotator()
 
695
        s = a.build_types(assert_, [int])
 
696
        assert s.const is None
 
697
 
 
698
    def test_string_and_none(self):
 
699
        def f(n):
 
700
            if n:
 
701
                return 'y'
 
702
            else:
 
703
                return 'n'
 
704
        def g(n):
 
705
            if n:
 
706
                return 'y'
 
707
            else:
 
708
                return None
 
709
        a = self.RPythonAnnotator()
 
710
        s = a.build_types(f, [bool])
 
711
        assert s.knowntype == str
 
712
        assert not s.can_be_None
 
713
        s = a.build_types(g, [bool])
 
714
        assert s.knowntype == str
 
715
        assert s.can_be_None
 
716
 
 
717
    def test_implicit_exc(self):
 
718
        def f(l):
 
719
            try:
 
720
                l[0]
 
721
            except (KeyError, IndexError),e:
 
722
                return e
 
723
            return None
 
724
 
 
725
        a = self.RPythonAnnotator()
 
726
        s = a.build_types(f, [list])
 
727
        assert s.classdef is a.bookkeeper.getuniqueclassdef(IndexError)  # KeyError ignored because l is a list
 
728
 
 
729
    def test_overrides(self):
 
730
        import sys
 
731
        excs = []
 
732
        def record_exc(e):
 
733
            """NOT_RPYTHON"""
 
734
            excs.append(sys.exc_info)
 
735
        record_exc._annspecialcase_ = "override:record_exc"
 
736
        def g():
 
737
            pass
 
738
        def f():
 
739
            try:
 
740
                g()
 
741
            except Exception, e:
 
742
                record_exc(e)
 
743
        class MyAnnotatorPolicy(policy.AnnotatorPolicy):
 
744
 
 
745
            def override__record_exc(pol, s_e):
 
746
                return a.bookkeeper.immutablevalue(None)
 
747
            
 
748
        a = self.RPythonAnnotator(policy=MyAnnotatorPolicy())
 
749
        s = a.build_types(f, [])
 
750
        assert s.const is None
 
751
 
 
752
    def test_freeze_protocol(self):
 
753
        class Stuff:
 
754
            def __init__(self, flag):
 
755
                self.called = False
 
756
                self.flag = flag
 
757
            def _freeze_(self):
 
758
                self.called = True
 
759
                return self.flag
 
760
        myobj = Stuff(True)
 
761
        a = self.RPythonAnnotator()
 
762
        s = a.build_types(lambda: myobj, [])
 
763
        assert myobj.called
 
764
        assert isinstance(s, annmodel.SomePBC)
 
765
        assert s.const == myobj
 
766
        myobj = Stuff(False)
 
767
        a = self.RPythonAnnotator()
 
768
        s = a.build_types(lambda: myobj, [])
 
769
        assert myobj.called
 
770
        assert isinstance(s, annmodel.SomeInstance)
 
771
        assert s.classdef is a.bookkeeper.getuniqueclassdef(Stuff)
 
772
 
 
773
    def test_circular_mutable_getattr(self):
 
774
        class C:
 
775
            pass
 
776
        c = C()
 
777
        c.x = c
 
778
        def f():
 
779
            return c.x
 
780
        a = self.RPythonAnnotator()
 
781
        s = a.build_types(f, [])
 
782
        assert isinstance(s, annmodel.SomeInstance)
 
783
        assert s.classdef == a.bookkeeper.getuniqueclassdef(C)
 
784
 
 
785
    def test_circular_list_type(self):
 
786
        def f(n):
 
787
            lst = []
 
788
            for i in range(n):
 
789
                lst = [lst]
 
790
            return lst
 
791
        a = self.RPythonAnnotator()
 
792
        s = a.build_types(f, [int])
 
793
        assert listitem(s) == s
 
794
 
 
795
    def test_harmonic(self):
 
796
        a = self.RPythonAnnotator()
 
797
        s = a.build_types(snippet.harmonic, [int])
 
798
        assert s.knowntype == float
 
799
        # check that the list produced by range() is not mutated or resized
 
800
        for s_value in a.bindings.values():
 
801
            if isinstance(s_value, annmodel.SomeList):
 
802
                assert not s_value.listdef.listitem.resized
 
803
                assert not s_value.listdef.listitem.mutated
 
804
                assert s_value.listdef.listitem.range_step
 
805
 
 
806
    def test_bool(self):
 
807
        def f(a,b):
 
808
            return bool(a) or bool(b)
 
809
        a = self.RPythonAnnotator()
 
810
        s = a.build_types(f, [int,list])
 
811
        assert s.knowntype == bool
 
812
 
 
813
    def test_float(self):
 
814
        def f(n):
 
815
            return float(n)
 
816
        a = self.RPythonAnnotator()
 
817
        s = a.build_types(f, [int])
 
818
        assert s.knowntype == float
 
819
 
 
820
    def test_r_uint(self):
 
821
        def f(n):
 
822
            return n + constant_unsigned_five
 
823
        a = self.RPythonAnnotator()
 
824
        s = a.build_types(f, [r_uint])
 
825
        assert s == annmodel.SomeInteger(nonneg = True, unsigned = True)
 
826
 
 
827
    def test_pbc_getattr(self):
 
828
        class C:
 
829
            def __init__(self, v1, v2):
 
830
                self.v2 = v2
 
831
                self.v1 = v1
 
832
 
 
833
            def _freeze_(self):
 
834
                return True
 
835
 
 
836
        c1 = C(1,'a')
 
837
        c2 = C(2,'b')
 
838
        c3 = C(3,'c')
 
839
 
 
840
        def f1(l, c):
 
841
            l.append(c.v1)
 
842
        def f2(l, c):
 
843
            l.append(c.v2)
 
844
 
 
845
        def g():
 
846
            l1 = []
 
847
            l2 = []
 
848
            f1(l1, c1)
 
849
            f1(l1, c2)
 
850
            f2(l2, c2)
 
851
            f2(l2, c3)
 
852
            return l1,l2
 
853
 
 
854
        a = self.RPythonAnnotator()
 
855
        s = a.build_types(g,[])
 
856
        l1, l2 = s.items
 
857
        assert listitem(l1).knowntype == int
 
858
        assert listitem(l2).knowntype == str
 
859
 
 
860
 
 
861
        acc1 = a.bookkeeper.getdesc(c1).getattrfamily()
 
862
        acc2 = a.bookkeeper.getdesc(c2).getattrfamily()
 
863
        acc3 = a.bookkeeper.getdesc(c3).getattrfamily()
 
864
 
 
865
        assert acc1 is acc2 is acc3
 
866
 
 
867
        assert len(acc1.descs) == 3
 
868
        assert dict.fromkeys(acc1.attrs) == {'v1': None, 'v2': None}
 
869
 
 
870
    def test_single_pbc_getattr(self):
 
871
        class C:
 
872
            def __init__(self, v1, v2):
 
873
                self.v1 = v1
 
874
                self.v2 = v2
 
875
            def _freeze_(self):
 
876
                return True
 
877
        c1 = C(11, "hello")
 
878
        c2 = C(22, 623)
 
879
        def f1(l, c):
 
880
            l.append(c.v1)
 
881
        def f2(c):
 
882
            return c.v2
 
883
        def f3(c):
 
884
            return c.v2
 
885
        def g():
 
886
            l = []
 
887
            f1(l, c1)
 
888
            f1(l, c2)
 
889
            return l, f2(c1), f3(c2)
 
890
 
 
891
        a = self.RPythonAnnotator()
 
892
        s = a.build_types(g,[])
 
893
        s_l, s_c1v2, s_c2v2 = s.items
 
894
        assert listitem(s_l).knowntype == int
 
895
        assert s_c1v2.const == "hello"
 
896
        assert s_c2v2.const == 623
 
897
 
 
898
        acc1 = a.bookkeeper.getdesc(c1).getattrfamily()
 
899
        acc2 = a.bookkeeper.getdesc(c2).getattrfamily()
 
900
        assert acc1 is acc2
 
901
        assert acc1.attrs.keys() == ['v1']
 
902
 
 
903
    def test_simple_pbc_call(self):
 
904
        def f1(x,y=0):
 
905
            pass
 
906
        def f2(x):
 
907
            pass
 
908
        def f3(x):
 
909
            pass
 
910
        def g(f):
 
911
            f(1)
 
912
        def h():
 
913
            f1(1)
 
914
            f1(1,2)
 
915
            g(f2)
 
916
            g(f3)
 
917
        
 
918
        a = self.RPythonAnnotator()
 
919
        s = a.build_types(h, [])
 
920
 
 
921
        fdesc1 = a.bookkeeper.getdesc(f1)
 
922
        fdesc2 = a.bookkeeper.getdesc(f2)
 
923
        fdesc3 = a.bookkeeper.getdesc(f3)
 
924
 
 
925
        fam1 = fdesc1.getcallfamily()
 
926
        fam2 = fdesc2.getcallfamily()
 
927
        fam3 = fdesc3.getcallfamily()
 
928
 
 
929
        assert fam1 is not fam2
 
930
        assert fam1 is not fam3
 
931
        assert fam3 is fam2
 
932
 
 
933
        gf1 = graphof(a, f1)
 
934
        gf2 = graphof(a, f2)
 
935
        gf3 = graphof(a, f3)
 
936
 
 
937
        assert fam1.calltables == {(2, (), False, False): [{fdesc1: gf1}], (1, (), False, False): [{fdesc1: gf1}]}
 
938
        assert fam2.calltables == {(1, (), False, False): [{fdesc2: gf2, fdesc3: gf3}]}
 
939
 
 
940
    def test_pbc_call_ins(self):
 
941
        class A(object):
 
942
            def m(self):
 
943
                pass
 
944
        class B(A):
 
945
            def n(self):
 
946
                pass
 
947
        class C(A):
 
948
            def __init__(self):
 
949
                pass
 
950
            def m(self):
 
951
                pass
 
952
        def f(x):
 
953
            b = B()
 
954
            c = C()
 
955
            b.n()
 
956
            if x:
 
957
                a = b
 
958
            else:
 
959
                a = c
 
960
            a.m()
 
961
 
 
962
        a = self.RPythonAnnotator()
 
963
        s = a.build_types(f, [bool])
 
964
 
 
965
        clsdef = a.bookkeeper.getuniqueclassdef
 
966
        bookkeeper = a.bookkeeper
 
967
 
 
968
        def getmdesc(bmeth):
 
969
            return bookkeeper.immutablevalue(bmeth).descriptions.keys()[0]
 
970
 
 
971
        mdescA_m = getmdesc(A().m)
 
972
        mdescC_m = getmdesc(C().m)
 
973
        mdescB_n = getmdesc(B().n)
 
974
 
 
975
        assert mdescA_m.name == 'm' == mdescC_m.name
 
976
        assert mdescB_n.name == 'n'
 
977
 
 
978
        famA_m = mdescA_m.getcallfamily()
 
979
        famC_m = mdescC_m.getcallfamily()
 
980
        famB_n = mdescB_n.getcallfamily()
 
981
        
 
982
        assert famA_m is famC_m
 
983
        assert famB_n is not famA_m
 
984
 
 
985
        gfB_n = graphof(a, B.n.im_func)
 
986
        gfA_m = graphof(a, A.m.im_func)
 
987
        gfC_m = graphof(a, C.m.im_func)
 
988
 
 
989
        assert famB_n.calltables == {(1, (), False, False): [{mdescB_n.funcdesc: gfB_n}] }
 
990
        assert famA_m.calltables == {(1, (), False, False): [{mdescA_m.funcdesc: gfA_m, mdescC_m.funcdesc: gfC_m }] }
 
991
 
 
992
        mdescCinit = getmdesc(C().__init__)
 
993
        famCinit = mdescCinit.getcallfamily()
 
994
        gfCinit = graphof(a, C.__init__.im_func)
 
995
 
 
996
        assert famCinit.calltables == {(1, (), False, False): [{mdescCinit.funcdesc: gfCinit}] }
 
997
        
 
998
    def test_isinstance_usigned(self):
 
999
        def f(x):
 
1000
            return isinstance(x, r_uint)
 
1001
        def g():
 
1002
            v = r_uint(1)
 
1003
            return f(v)
 
1004
        a = self.RPythonAnnotator()
 
1005
        s = a.build_types(g, [])
 
1006
        assert s.const == True
 
1007
 
 
1008
    def test_isinstance_base_int(self):
 
1009
        def f(x):
 
1010
            return isinstance(x, base_int)
 
1011
        def g(n):
 
1012
            v = r_uint(n)
 
1013
            return f(v)
 
1014
        a = self.RPythonAnnotator()
 
1015
        s = a.build_types(g, [int])
 
1016
        assert s.const == True
 
1017
 
 
1018
    def test_alloc_like(self):
 
1019
        class C1(object):
 
1020
            pass
 
1021
        class C2(object):
 
1022
            pass
 
1023
 
 
1024
        def inst(cls):
 
1025
            return cls()
 
1026
 
 
1027
        def alloc(cls):
 
1028
            i = inst(cls)
 
1029
            assert isinstance(i, cls)
 
1030
            return i
 
1031
        alloc._annspecialcase_ = "specialize:arg(0)"
 
1032
 
 
1033
        def f():
 
1034
            c1 = alloc(C1)
 
1035
            c2 = alloc(C2)
 
1036
            return c1,c2
 
1037
 
 
1038
        a = self.RPythonAnnotator()
 
1039
        s = a.build_types(f, [])
 
1040
        C1df = a.bookkeeper.getuniqueclassdef(C1)
 
1041
        C2df = a.bookkeeper.getuniqueclassdef(C2)
 
1042
        
 
1043
        assert s.items[0].classdef == C1df
 
1044
        assert s.items[1].classdef == C2df
 
1045
 
 
1046
        allocdesc = a.bookkeeper.getdesc(alloc)
 
1047
        s_C1 = a.bookkeeper.immutablevalue(C1)
 
1048
        s_C2 = a.bookkeeper.immutablevalue(C2)
 
1049
        graph1 = allocdesc.specialize([s_C1])
 
1050
        graph2 = allocdesc.specialize([s_C2])
 
1051
        assert a.binding(graph1.getreturnvar()).classdef == C1df
 
1052
        assert a.binding(graph2.getreturnvar()).classdef == C2df
 
1053
        assert graph1 in a.translator.graphs
 
1054
        assert graph2 in a.translator.graphs
 
1055
    
 
1056
    def test_specialcase_args(self):
 
1057
        class C1(object):
 
1058
            pass
 
1059
        
 
1060
        class C2(object):
 
1061
            pass
 
1062
        
 
1063
        def alloc(cls, cls2):
 
1064
            i = cls()
 
1065
            assert isinstance(i, cls)
 
1066
            j = cls2()
 
1067
            assert isinstance(j, cls2)
 
1068
            return i
 
1069
        
 
1070
        def f():
 
1071
            alloc(C1, C1)
 
1072
            alloc(C1, C2)
 
1073
            alloc(C2, C1)
 
1074
            alloc(C2, C2)
 
1075
        
 
1076
        alloc._annspecialcase_ = "specialize:arg(0,1)"
 
1077
        
 
1078
        a = self.RPythonAnnotator()
 
1079
        C1df = a.bookkeeper.getuniqueclassdef(C1)
 
1080
        C2df = a.bookkeeper.getuniqueclassdef(C2)
 
1081
        s = a.build_types(f, [])
 
1082
        allocdesc = a.bookkeeper.getdesc(alloc)
 
1083
        s_C1 = a.bookkeeper.immutablevalue(C1)
 
1084
        s_C2 = a.bookkeeper.immutablevalue(C2)
 
1085
        graph1 = allocdesc.specialize([s_C1, s_C2])
 
1086
        graph2 = allocdesc.specialize([s_C2, s_C2])
 
1087
        assert a.binding(graph1.getreturnvar()).classdef == C1df
 
1088
        assert a.binding(graph2.getreturnvar()).classdef == C2df
 
1089
        assert graph1 in a.translator.graphs
 
1090
        assert graph2 in a.translator.graphs
 
1091
 
 
1092
    def test_assert_list_doesnt_lose_info(self):
 
1093
        class T(object):
 
1094
            pass
 
1095
        def g(l):
 
1096
            assert isinstance(l, list)
 
1097
            return l
 
1098
        def f():
 
1099
            l = [T()]
 
1100
            return g(l)
 
1101
        a = self.RPythonAnnotator()
 
1102
        s = a.build_types(f, [])
 
1103
        s_item = listitem(s)
 
1104
        assert isinstance(s_item, annmodel.SomeInstance)
 
1105
        assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T)
 
1106
          
 
1107
    def test_assert_type_is_list_doesnt_lose_info(self):
 
1108
        class T(object):
 
1109
            pass
 
1110
        def g(l):
 
1111
            assert type(l) is list
 
1112
            return l
 
1113
        def f():
 
1114
            l = [T()]
 
1115
            return g(l)
 
1116
        a = self.RPythonAnnotator()
 
1117
        s = a.build_types(f, [])
 
1118
        s_item = listitem(s)
 
1119
        assert isinstance(s_item, annmodel.SomeInstance)
 
1120
        assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T)
 
1121
 
 
1122
 
 
1123
    def test_int_str_mul(self):
 
1124
        def f(x,a,b):
 
1125
            return a*x+x*b
 
1126
        a = self.RPythonAnnotator()
 
1127
        s = a.build_types(f, [str,int,int])
 
1128
        assert s.knowntype == str
 
1129
 
 
1130
    def test_list_tuple(self):
 
1131
        def g0(x):
 
1132
            return list(x)
 
1133
        def g1(x):
 
1134
            return list(x)
 
1135
        def f(n):
 
1136
            l1 = g0(())
 
1137
            l2 = g1((1,))
 
1138
            if n:
 
1139
                t = (1,)
 
1140
            else:
 
1141
                t = (2,)
 
1142
            l3 = g1(t)
 
1143
            return l1, l2, l3
 
1144
        a = self.RPythonAnnotator()
 
1145
        s = a.build_types(f, [bool])
 
1146
        assert listitem(s.items[0]) == annmodel.SomeImpossibleValue()
 
1147
        assert listitem(s.items[1]).knowntype == int
 
1148
        assert listitem(s.items[2]).knowntype == int
 
1149
 
 
1150
    def test_empty_list(self):
 
1151
        def f():
 
1152
            l = []
 
1153
            return bool(l)
 
1154
        def g():
 
1155
            l = []
 
1156
            x = bool(l)
 
1157
            l.append(1)
 
1158
            return x, bool(l)
 
1159
        
 
1160
        a = self.RPythonAnnotator()
 
1161
        s = a.build_types(f, [])
 
1162
        assert s.const == False
 
1163
 
 
1164
        a = self.RPythonAnnotator()
 
1165
        s = a.build_types(g, [])
 
1166
 
 
1167
        assert s.items[0].knowntype == bool and not s.items[0].is_constant()
 
1168
        assert s.items[1].knowntype == bool and not s.items[1].is_constant()
 
1169
        
 
1170
    def test_empty_dict(self):
 
1171
        def f():
 
1172
            d = {}
 
1173
            return bool(d)
 
1174
        def g():
 
1175
            d = {}
 
1176
            x = bool(d)
 
1177
            d['a'] = 1
 
1178
            return x, bool(d)
 
1179
        
 
1180
        a = self.RPythonAnnotator()
 
1181
        s = a.build_types(f, [])
 
1182
        assert s.const == False
 
1183
 
 
1184
        a = self.RPythonAnnotator()
 
1185
        s = a.build_types(g, [])
 
1186
 
 
1187
        assert s.items[0].knowntype == bool and not s.items[0].is_constant()
 
1188
        assert s.items[1].knowntype == bool and not s.items[1].is_constant()
 
1189
 
 
1190
    def test_call_two_funcs_but_one_can_only_raise(self):
 
1191
        a = self.RPythonAnnotator()
 
1192
        s = a.build_types(snippet.call_two_funcs_but_one_can_only_raise,
 
1193
                          [int])
 
1194
        assert s == a.bookkeeper.immutablevalue(None)
 
1195
 
 
1196
    def test_reraiseKeyError(self):
 
1197
        def f(dic):
 
1198
            try:
 
1199
                dic[5]
 
1200
            except KeyError:
 
1201
                raise
 
1202
        a = self.RPythonAnnotator()
 
1203
        a.build_types(f, [dict])
 
1204
        fg = graphof(a, f)
 
1205
        et, ev = fg.exceptblock.inputargs
 
1206
        t = annmodel.SomeObject()
 
1207
        t.knowntype = type
 
1208
        t.const = KeyError
 
1209
        t.is_type_of = [ev]
 
1210
        assert a.binding(et) == t
 
1211
        assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(KeyError)
 
1212
 
 
1213
    def test_reraiseAnything(self):
 
1214
        def f(dic):
 
1215
            try:
 
1216
                dic[5]
 
1217
            except:
 
1218
                raise
 
1219
        a = self.RPythonAnnotator()
 
1220
        a.build_types(f, [dict])
 
1221
        fg = graphof(a, f)
 
1222
        et, ev = fg.exceptblock.inputargs
 
1223
        t = annmodel.SomeObject()
 
1224
        t.knowntype = type
 
1225
        t.is_type_of = [ev]
 
1226
        t.const = KeyError    # IndexError ignored because 'dic' is a dict
 
1227
        assert a.binding(et) == t
 
1228
        assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(KeyError)
 
1229
 
 
1230
    def test_exception_mixing(self):
 
1231
        def h():
 
1232
            pass
 
1233
 
 
1234
        def g():
 
1235
            pass
 
1236
 
 
1237
        class X(Exception):
 
1238
            def __init__(self, x=0):
 
1239
                self.x = x
 
1240
 
 
1241
        def f(a, l):
 
1242
            if a==1:
 
1243
                raise X
 
1244
            elif a==2:
 
1245
                raise X(1)
 
1246
            elif a==3:
 
1247
                raise X,4
 
1248
            else:
 
1249
                try:
 
1250
                    l[0]
 
1251
                    x,y = l
 
1252
                    g()
 
1253
                finally:
 
1254
                    h()
 
1255
        a = self.RPythonAnnotator()
 
1256
        a.build_types(f, [int, list])
 
1257
        fg = graphof(a, f)
 
1258
        et, ev = fg.exceptblock.inputargs
 
1259
        t = annmodel.SomeObject()
 
1260
        t.knowntype = type
 
1261
        t.is_type_of = [ev]
 
1262
        assert a.binding(et) == t
 
1263
        assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception)
 
1264
 
 
1265
    def test_try_except_raise_finally1(self):
 
1266
        def h(): pass
 
1267
        def g(): pass
 
1268
        class X(Exception): pass
 
1269
        def f():
 
1270
            try:
 
1271
                try:
 
1272
                    g()
 
1273
                except X:
 
1274
                    h()
 
1275
                    raise
 
1276
            finally:
 
1277
                h()
 
1278
        a = self.RPythonAnnotator()
 
1279
        a.build_types(f, [])
 
1280
        fg = graphof(a, f)
 
1281
        et, ev = fg.exceptblock.inputargs
 
1282
        t = annmodel.SomeObject()
 
1283
        t.knowntype = type
 
1284
        t.is_type_of = [ev]
 
1285
        assert a.binding(et) == t
 
1286
        assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception)
 
1287
 
 
1288
    def test_sys_attrs(self):
 
1289
        import sys
 
1290
        def f():
 
1291
            return sys.argv[0]
 
1292
        a = self.RPythonAnnotator()
 
1293
        try:
 
1294
            oldvalue = sys.argv
 
1295
            sys.argv = []
 
1296
            s = a.build_types(f, [])
 
1297
        finally:
 
1298
            sys.argv = oldvalue
 
1299
        assert s is not None
 
1300
 
 
1301
    def test_pow(self):
 
1302
        def f(n):
 
1303
            n **= 2
 
1304
            return 2 ** n
 
1305
        a = self.RPythonAnnotator()
 
1306
        s = a.build_types(f, [int])
 
1307
        # result should be an integer
 
1308
        assert s.knowntype == int
 
1309
 
 
1310
    def test_prime(self):
 
1311
        a = self.RPythonAnnotator()
 
1312
        s = a.build_types(snippet.prime, [int])
 
1313
        assert s.knowntype == bool
 
1314
 
 
1315
    def test_and_is_true_coalesce(self):
 
1316
        def f(a,b,c,d,e):
 
1317
            x = a and b
 
1318
            if x:
 
1319
                return d,c
 
1320
            return e,c
 
1321
        a = self.RPythonAnnotator()
 
1322
        s = a.build_types(f, [int, str, a.bookkeeper.immutablevalue(1.0), a.bookkeeper.immutablevalue('d'), a.bookkeeper.immutablevalue('e')])
 
1323
        assert s == annmodel.SomeTuple([annmodel.SomeChar(), a.bookkeeper.immutablevalue(1.0)])
 
1324
        assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject]
 
1325
 
 
1326
    def test_is_true_coalesce2(self):
 
1327
        def f(a,b,a1,b1,c,d,e):
 
1328
            x = (a or  b) and (a1 or b1)
 
1329
            if x:
 
1330
                return d,c
 
1331
            return e,c
 
1332
        a = self.RPythonAnnotator()
 
1333
        s = a.build_types(f, [int, str, float, list,  a.bookkeeper.immutablevalue(1.0), a.bookkeeper.immutablevalue('d'), a.bookkeeper.immutablevalue('e')])
 
1334
        assert s == annmodel.SomeTuple([annmodel.SomeChar(), a.bookkeeper.immutablevalue(1.0)])
 
1335
        assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject]
 
1336
 
 
1337
    def test_is_true_coalesce_sanity(self):
 
1338
        def f(a):
 
1339
            while a:
 
1340
                pass
 
1341
        a = self.RPythonAnnotator()
 
1342
        s = a.build_types(f, [int])
 
1343
        assert s == a.bookkeeper.immutablevalue(None)
 
1344
 
 
1345
    def test_non_None_path(self):
 
1346
        class C:
 
1347
            pass
 
1348
        def g(c):
 
1349
            if c is None:
 
1350
                return C()
 
1351
            return c
 
1352
        def f(x):
 
1353
            if x:
 
1354
                c = None
 
1355
            else:
 
1356
                c = C()
 
1357
            return g(c)
 
1358
        a = self.RPythonAnnotator()
 
1359
        s = a.build_types(f, [bool])
 
1360
        assert s.can_be_none() == False
 
1361
 
 
1362
    def test_can_be_None_path(self):
 
1363
        class C:
 
1364
            pass
 
1365
        def f(x):
 
1366
            if x:
 
1367
                c = None
 
1368
            else:
 
1369
                c = C()
 
1370
            return isinstance(c, C)
 
1371
        a = self.RPythonAnnotator()
 
1372
        s = a.build_types(f, [bool])
 
1373
        assert not s.is_constant()
 
1374
 
 
1375
    def test_nonneg_cleverness(self):
 
1376
        def f(a, b, c, d, e, f, g, h):
 
1377
            if a < 0: a = 0
 
1378
            if b <= 0: b = 0
 
1379
            if c >= 0:
 
1380
                pass
 
1381
            else:
 
1382
                c = 0
 
1383
            if d < a: d = a
 
1384
            if e <= b: e = 1
 
1385
            if c > f: f = 2
 
1386
            if d >= g: g = 3
 
1387
            if h != a: h = 0
 
1388
            return a, b, c, d, e, f, g, h
 
1389
        a = self.RPythonAnnotator()
 
1390
        s = a.build_types(f, [int]*8)
 
1391
        assert s == annmodel.SomeTuple([annmodel.SomeInteger(nonneg=True)] * 8)
 
1392
 
 
1393
    def test_general_nonneg_cleverness(self):
 
1394
        def f(a, b, c, d, e, f, g, h):
 
1395
            if a < 0: a = 0
 
1396
            if b <= 0: b = 0
 
1397
            if c >= 0:
 
1398
                pass
 
1399
            else:
 
1400
                c = 0
 
1401
            if d < a: d = a
 
1402
            if e <= b: e = 1
 
1403
            if c > f: f = 2
 
1404
            if d >= g: g = 3
 
1405
            if h != a: h = 0
 
1406
            return a, b, c, d, e, f, g, h
 
1407
        a = self.RPythonAnnotator()
 
1408
        s = a.build_types(f, [r_longlong]*8)
 
1409
        assert s == annmodel.SomeTuple([annmodel.SomeInteger(nonneg=True, knowntype=r_longlong)] * 8)
 
1410
 
 
1411
 
 
1412
    def test_more_nonneg_cleverness(self):
 
1413
        def f(start, stop):
 
1414
            assert 0 <= start <= stop
 
1415
            return start, stop
 
1416
        a = self.RPythonAnnotator()
 
1417
        s = a.build_types(f, [int, int])
 
1418
        assert s == annmodel.SomeTuple([annmodel.SomeInteger(nonneg=True)] * 2)
 
1419
 
 
1420
    def test_more_general_nonneg_cleverness(self):
 
1421
        def f(start, stop):
 
1422
            assert 0 <= start <= stop
 
1423
            return start, stop
 
1424
        a = self.RPythonAnnotator()
 
1425
        s = a.build_types(f, [r_longlong, r_longlong])
 
1426
        assert s == annmodel.SomeTuple([annmodel.SomeInteger(nonneg=True, knowntype=r_longlong)] * 2)
 
1427
 
 
1428
    def test_nonneg_cleverness_is_gentle_with_unsigned(self):
 
1429
        def witness1(x):
 
1430
            pass
 
1431
        def witness2(x):
 
1432
            pass        
 
1433
        def f(x):
 
1434
            if 0 < x:
 
1435
                witness1(x)
 
1436
            if x > 0:
 
1437
                witness2(x)
 
1438
        a = self.RPythonAnnotator()
 
1439
        s = a.build_types(f, [annmodel.SomeInteger(unsigned=True)])
 
1440
        wg1 = graphof(a, witness1)
 
1441
        wg2 = graphof(a, witness2)        
 
1442
        assert a.binding(wg1.getargs()[0]).unsigned is True
 
1443
        assert a.binding(wg2.getargs()[0]).unsigned is True        
 
1444
        
 
1445
    def test_general_nonneg_cleverness_is_gentle_with_unsigned(self):
 
1446
        def witness1(x):
 
1447
            pass
 
1448
        def witness2(x):
 
1449
            pass        
 
1450
        def f(x):
 
1451
            if 0 < x:
 
1452
                witness1(x)
 
1453
            if x > 0:
 
1454
                witness2(x)
 
1455
        a = self.RPythonAnnotator()
 
1456
        s = a.build_types(f, [annmodel.SomeInteger(knowntype=r_ulonglong)])
 
1457
        wg1 = graphof(a, witness1)
 
1458
        wg2 = graphof(a, witness2)        
 
1459
        assert a.binding(wg1.getargs()[0]).knowntype is r_ulonglong
 
1460
        assert a.binding(wg2.getargs()[0]).knowntype is r_ulonglong
 
1461
 
 
1462
    def test_nonneg_cleverness_in_max(self):
 
1463
        def f(x):
 
1464
            return max(x, 0) + max(0, x)
 
1465
        a = self.RPythonAnnotator()
 
1466
        s = a.build_types(f, [int])
 
1467
        assert s.nonneg
 
1468
 
 
1469
    def test_attr_moving_into_parent(self):
 
1470
        class A: pass
 
1471
        class B(A): pass
 
1472
        a1 = A()
 
1473
        b1 = B()
 
1474
        b1.stuff = a1
 
1475
        a1.stuff = None
 
1476
        def f():
 
1477
            return b1.stuff
 
1478
        a = self.RPythonAnnotator()
 
1479
        s = a.build_types(f, [])
 
1480
        assert isinstance(s, annmodel.SomeInstance)
 
1481
        assert not s.can_be_None
 
1482
        assert s.classdef is a.bookkeeper.getuniqueclassdef(A)
 
1483
 
 
1484
    def test_class_attribute(self):
 
1485
        class A:
 
1486
            stuff = 42
 
1487
        class B(A):
 
1488
            pass
 
1489
        def f():
 
1490
            b = B()
 
1491
            return b.stuff
 
1492
        a = self.RPythonAnnotator()
 
1493
        s = a.build_types(f, [])
 
1494
        assert s == a.bookkeeper.immutablevalue(42)
 
1495
 
 
1496
    def test_attr_recursive_getvalue(self):
 
1497
        class A: pass
 
1498
        a2 = A()
 
1499
        a2.stuff = None
 
1500
        a1 = A()
 
1501
        a1.stuff = a2
 
1502
        def f():
 
1503
            return a1.stuff
 
1504
        a = self.RPythonAnnotator()
 
1505
        s = a.build_types(f, [])
 
1506
        assert isinstance(s, annmodel.SomeInstance)
 
1507
        assert s.can_be_None
 
1508
        assert s.classdef is a.bookkeeper.getuniqueclassdef(A)
 
1509
 
 
1510
    def test_long_list_recursive_getvalue(self):
 
1511
        class A: pass
 
1512
        lst = []
 
1513
        for i in range(500):
 
1514
            a1 = A()
 
1515
            a1.stuff = lst
 
1516
            lst.append(a1)
 
1517
        def f():
 
1518
            A().stuff = None
 
1519
            return (A().stuff, lst)[1]
 
1520
        a = self.RPythonAnnotator()
 
1521
        s = a.build_types(f, [])
 
1522
        assert isinstance(s, annmodel.SomeList)
 
1523
        s_item = s.listdef.listitem.s_value
 
1524
        assert isinstance(s_item, annmodel.SomeInstance)
 
1525
 
 
1526
    def test_immutable_dict(self):
 
1527
        d = {4: "hello",
 
1528
             5: "world"}
 
1529
        def f(n):
 
1530
            return d[n]
 
1531
        a = self.RPythonAnnotator()
 
1532
        s = a.build_types(f, [int])
 
1533
        assert isinstance(s, annmodel.SomeString)
 
1534
 
 
1535
    def test_immutable_recursive_list(self):
 
1536
        l = []
 
1537
        l.append(l)
 
1538
        def f():
 
1539
            return l
 
1540
        a = self.RPythonAnnotator()
 
1541
        s = a.build_types(f, [])
 
1542
        assert isinstance(s, annmodel.SomeList)
 
1543
        s_item = s.listdef.listitem.s_value
 
1544
        assert isinstance(s_item, annmodel.SomeList)
 
1545
        assert s_item.listdef.same_as(s.listdef)
 
1546
 
 
1547
    def test_defaults_with_list_or_dict(self):
 
1548
        def fn1(a=[]):
 
1549
            return a
 
1550
        def fn2(a={}):
 
1551
            return a
 
1552
        def f():
 
1553
            fn1()
 
1554
            fn2()
 
1555
            return fn1([6, 7]), fn2({2: 3, 4: 5})
 
1556
        a = self.RPythonAnnotator()
 
1557
        s = a.build_types(f, [])
 
1558
        assert isinstance(s, annmodel.SomeTuple)
 
1559
        s1, s2 = s.items
 
1560
        assert not s1.is_constant()
 
1561
        assert not s2.is_constant()
 
1562
        assert isinstance(s1.listdef.listitem. s_value, annmodel.SomeInteger)
 
1563
        assert isinstance(s2.dictdef.dictkey.  s_value, annmodel.SomeInteger)
 
1564
        assert isinstance(s2.dictdef.dictvalue.s_value, annmodel.SomeInteger)
 
1565
 
 
1566
    def test_pbc_union(self):
 
1567
        class A:
 
1568
            def meth(self):
 
1569
                return 12
 
1570
        class B(A):
 
1571
            pass
 
1572
        class C(B):
 
1573
            pass
 
1574
        def f(i):
 
1575
            if i:
 
1576
                f(0)
 
1577
                x = B()
 
1578
            else:
 
1579
                x = C()
 
1580
            return x.meth()
 
1581
        a = self.RPythonAnnotator()
 
1582
        s = a.build_types(f, [int])
 
1583
        assert s == a.bookkeeper.immutablevalue(12)
 
1584
 
 
1585
    def test_int(self):
 
1586
        def f(x, s):
 
1587
            return int(x) + int(s) + int(s, 16)
 
1588
        a = self.RPythonAnnotator()
 
1589
        s = a.build_types(f, [int, str])
 
1590
        assert s.knowntype == int
 
1591
 
 
1592
    def test_listitem_merge_asymmetry_bug(self):
 
1593
        class K:
 
1594
            pass
 
1595
        def mutr(k, x, i):
 
1596
            k.l2 = [x] + k.l2 # this involves a side-effectful union and unification, with this order
 
1597
                              # of arguments some reflowing was missed
 
1598
            k.l2[i] = x
 
1599
        def witness(i):
 
1600
            pass
 
1601
        def trouble(k):
 
1602
            l = k.l1 + k.l2
 
1603
            for i in range(len(l)):
 
1604
                witness(l[i])
 
1605
        def f(flag, k, x, i):
 
1606
            if flag:
 
1607
                k = K()
 
1608
                k.l1 = []
 
1609
                k.l2 = []
 
1610
            trouble(k)
 
1611
            mutr(k, x, i)
 
1612
        a = self.RPythonAnnotator()
 
1613
        a.build_types(f, [bool, K,  int, int])
 
1614
        g = graphof(a, witness)
 
1615
        assert a.binding(g.getargs()[0]).knowntype == int
 
1616
 
 
1617
    # check RPython static semantics of isinstance(x,bool|int) as needed for wrap
 
1618
 
 
1619
    def test_isinstance_int_bool(self):
 
1620
        def f(x):
 
1621
            if isinstance(x, int):
 
1622
                if isinstance(x, bool):
 
1623
                    return "bool"
 
1624
                return "int"
 
1625
            return "dontknow"
 
1626
        a = self.RPythonAnnotator()
 
1627
        s = a.build_types(f, [bool])
 
1628
        assert s.const == "bool"
 
1629
        a = self.RPythonAnnotator()
 
1630
        s = a.build_types(f, [int])
 
1631
        assert s.const == "int"        
 
1632
        a = self.RPythonAnnotator()
 
1633
        s = a.build_types(f, [float])
 
1634
        assert s.const == "dontknow"        
 
1635
        
 
1636
    def test_hidden_method(self):
 
1637
        class Base:
 
1638
            def method(self):
 
1639
                return ["should be hidden"]
 
1640
            def indirect(self):
 
1641
                return self.method()
 
1642
        class A(Base):
 
1643
            def method(self):
 
1644
                return "visible"
 
1645
        class B(A):       # note: it's a chain of subclasses
 
1646
            def method(self):
 
1647
                return None
 
1648
        def f(flag):
 
1649
            if flag:
 
1650
                obj = A()
 
1651
            else:
 
1652
                obj = B()
 
1653
            return obj.indirect()
 
1654
        a = self.RPythonAnnotator()
 
1655
        s = a.build_types(f, [bool])
 
1656
        assert s == annmodel.SomeString(can_be_None=True)
 
1657
 
 
1658
    def test_dont_see_AttributeError_clause(self):
 
1659
        class Stuff:
 
1660
            def _freeze_(self):
 
1661
                return True
 
1662
            def createcompiler(self):
 
1663
                try:
 
1664
                    return self.default_compiler
 
1665
                except AttributeError:
 
1666
                    compiler = "yadda"
 
1667
                    self.default_compiler = compiler
 
1668
                    return compiler
 
1669
        stuff = Stuff()
 
1670
        stuff.default_compiler = 123
 
1671
        def f():
 
1672
            return stuff.createcompiler()
 
1673
        a = self.RPythonAnnotator()
 
1674
        s = a.build_types(f, [])
 
1675
        assert s == a.bookkeeper.immutablevalue(123)
 
1676
 
 
1677
    def test_class_attribute_is_an_instance_of_itself(self):
 
1678
        class Base:
 
1679
            hello = None
 
1680
        class A(Base):
 
1681
            pass
 
1682
        A.hello = globalA = A()
 
1683
        def f():
 
1684
            return (Base().hello, globalA)
 
1685
        a = self.RPythonAnnotator()
 
1686
        s = a.build_types(f, [])
 
1687
        assert isinstance(s, annmodel.SomeTuple)
 
1688
        assert isinstance(s.items[0], annmodel.SomeInstance)
 
1689
        assert s.items[0].classdef is a.bookkeeper.getuniqueclassdef(A)
 
1690
        assert s.items[0].can_be_None
 
1691
        assert s.items[1] == a.bookkeeper.immutablevalue(A.hello)
 
1692
 
 
1693
    def test_dict_and_none(self):
 
1694
        def f(i):
 
1695
            if i:
 
1696
                return {}
 
1697
            else:
 
1698
                return None
 
1699
        a = self.RPythonAnnotator()
 
1700
        s = a.build_types(f, [int])
 
1701
        assert s.knowntype == dict
 
1702
 
 
1703
    def test_const_list_and_none(self):
 
1704
        def g(l=None):
 
1705
            return l is None
 
1706
        L = [1,2]
 
1707
        def f():
 
1708
            g()
 
1709
            return g(L)
 
1710
        a = self.RPythonAnnotator()
 
1711
        s = a.build_types(f, [])
 
1712
        assert s.knowntype == bool
 
1713
        assert not s.is_constant()
 
1714
            
 
1715
    def test_const_dict_and_none(self):
 
1716
        def g(d=None):
 
1717
            return d is None
 
1718
        D = {1:2}
 
1719
        def f():
 
1720
            g(D)
 
1721
            return g()
 
1722
        a = self.RPythonAnnotator()
 
1723
        s = a.build_types(f, [])
 
1724
        assert s.knowntype == bool
 
1725
        assert not s.is_constant()
 
1726
                        
 
1727
    def test_issubtype_and_const(self):
 
1728
        class A(object):
 
1729
            pass
 
1730
        class B(object):
 
1731
            pass
 
1732
        class C(A):
 
1733
            pass
 
1734
        b = B()
 
1735
        c = C()
 
1736
        def g(f):
 
1737
            if f == 1:
 
1738
                x = b
 
1739
            elif f == 2:
 
1740
                x = c
 
1741
            else:
 
1742
                x = C()
 
1743
            t = type(x)
 
1744
            return issubclass(t, A)
 
1745
 
 
1746
        def f():
 
1747
            x = g(1)
 
1748
            y = g(0)
 
1749
            return x or y
 
1750
        a = self.RPythonAnnotator()
 
1751
        s = a.build_types(f, [])
 
1752
        assert s.knowntype == bool
 
1753
        assert not s.is_constant()
 
1754
        a = self.RPythonAnnotator()
 
1755
        # sanity check
 
1756
        x = annmodel.SomeInteger()
 
1757
        x.const = 1
 
1758
        s = a.build_types(g, [x])
 
1759
        assert s.const == False
 
1760
        a = self.RPythonAnnotator()
 
1761
        x = annmodel.SomeInteger()
 
1762
        x.const = 2
 
1763
        s = a.build_types(g, [x])
 
1764
        assert s.const == True
 
1765
 
 
1766
    def test_reading_also_generalizes(self):
 
1767
        def f1(i):
 
1768
            d = {'c': i}
 
1769
            return d['not-a-char'], d
 
1770
        a = self.RPythonAnnotator()
 
1771
        s = a.build_types(f1, [int])
 
1772
        assert dictkey(s.items[1]).__class__ == annmodel.SomeString
 
1773
        def f2(i):
 
1774
            d = {'c': i}
 
1775
            return d.get('not-a-char', i+1), d
 
1776
        a = self.RPythonAnnotator()
 
1777
        s = a.build_types(f2, [int])
 
1778
        assert dictkey(s.items[1]).__class__ == annmodel.SomeString
 
1779
        def f3(i):
 
1780
            d = {'c': i}
 
1781
            return 'not-a-char' in d, d
 
1782
        a = self.RPythonAnnotator()
 
1783
        s = a.build_types(f3, [int])
 
1784
        assert dictkey(s.items[1]).__class__ == annmodel.SomeString
 
1785
        def f4():
 
1786
            lst = ['a', 'b', 'c']
 
1787
            return 'not-a-char' in lst, lst
 
1788
        a = self.RPythonAnnotator()
 
1789
        s = a.build_types(f4, [])
 
1790
        assert listitem(s.items[1]).__class__ == annmodel.SomeString
 
1791
        def f5():
 
1792
            lst = ['a', 'b', 'c']
 
1793
            return lst.index('not-a-char'), lst
 
1794
        a = self.RPythonAnnotator()
 
1795
        s = a.build_types(f5, [])
 
1796
        assert listitem(s.items[1]).__class__ == annmodel.SomeString
 
1797
 
 
1798
    def test_true_str_is_not_none(self):
 
1799
        def f(s):
 
1800
            if s:
 
1801
                return s
 
1802
            else:
 
1803
                return ''
 
1804
        def g(i):
 
1805
            if i:
 
1806
                return f(None)
 
1807
            else:
 
1808
                return f('')
 
1809
        a = self.RPythonAnnotator()
 
1810
        s = a.build_types(g, [int])
 
1811
        assert s.knowntype == str
 
1812
        assert not s.can_be_None
 
1813
 
 
1814
    def test_true_func_is_not_none(self):
 
1815
        def a1():
 
1816
            pass
 
1817
        def a2():
 
1818
            pass
 
1819
        def f(a):
 
1820
            if a:
 
1821
                return a
 
1822
            else:
 
1823
                return a2
 
1824
        def g(i):
 
1825
            if i:
 
1826
                return f(None)
 
1827
            else:
 
1828
                return f(a1)
 
1829
        a = self.RPythonAnnotator()
 
1830
        s = a.build_types(g, [int])
 
1831
        assert not s.can_be_None
 
1832
 
 
1833
    def test_emulated_pbc_call_simple(self):
 
1834
        def f(a,b):
 
1835
            return a + b
 
1836
        from pypy.annotation import annrpython
 
1837
        a = annrpython.RPythonAnnotator()
 
1838
        from pypy.annotation import model as annmodel
 
1839
 
 
1840
        s_f = a.bookkeeper.immutablevalue(f) 
 
1841
        a.bookkeeper.emulate_pbc_call('f', s_f, [annmodel.SomeInteger(), annmodel.SomeInteger()])
 
1842
        a.complete()
 
1843
 
 
1844
        assert a.binding(graphof(a, f).getreturnvar()).knowntype == int
 
1845
        fdesc = a.bookkeeper.getdesc(f)
 
1846
 
 
1847
        someint = annmodel.SomeInteger()
 
1848
 
 
1849
        assert (fdesc.get_s_signatures((2,(),False,False)) 
 
1850
                == [([someint,someint],someint)])
 
1851
 
 
1852
    def test_emulated_pbc_call_callback(self):
 
1853
        def f(a,b):
 
1854
            return a + b
 
1855
        from pypy.annotation import annrpython
 
1856
        a = annrpython.RPythonAnnotator()
 
1857
        from pypy.annotation import model as annmodel
 
1858
 
 
1859
        memo = []
 
1860
        def callb(ann, graph):
 
1861
            memo.append(annmodel.SomeInteger() == ann.binding(graph.getreturnvar()))
 
1862
 
 
1863
        s_f = a.bookkeeper.immutablevalue(f) 
 
1864
        s = a.bookkeeper.emulate_pbc_call('f', s_f, [annmodel.SomeInteger(), annmodel.SomeInteger()],
 
1865
                                          callback=callb)
 
1866
        assert s == annmodel.SomeImpossibleValue()
 
1867
        a.complete()
 
1868
 
 
1869
        assert a.binding(graphof(a, f).getreturnvar()).knowntype == int
 
1870
        assert len(memo) >= 1
 
1871
        for t in memo:
 
1872
            assert t
 
1873
 
 
1874
    def test_iterator_union(self):
 
1875
        def it(d):
 
1876
            return d.iteritems()
 
1877
        d0 = {1:2}
 
1878
        def f():
 
1879
            it(d0)
 
1880
            return it({1:2})
 
1881
        a = self.RPythonAnnotator()
 
1882
        s = a.build_types(f, [])
 
1883
        assert isinstance(s, annmodel.SomeIterator)
 
1884
        assert s.variant == ('items',)
 
1885
        
 
1886
    def test_non_none_and_none_with_isinstance(self):
 
1887
        class A(object):
 
1888
            pass
 
1889
        class B(A):
 
1890
            pass
 
1891
        def g(x):
 
1892
            if isinstance(x, A):
 
1893
                return x
 
1894
            return None
 
1895
        def f():
 
1896
            g(B())
 
1897
            return g(None)
 
1898
        a = self.RPythonAnnotator()
 
1899
        s = a.build_types(f, [])
 
1900
        assert isinstance(s, annmodel.SomeInstance)
 
1901
        assert s.classdef == a.bookkeeper.getuniqueclassdef(B)
 
1902
 
 
1903
    def test_type_is_no_improvement(self):
 
1904
        class B(object):
 
1905
            pass
 
1906
        class C(B):
 
1907
            pass
 
1908
        class D(B):
 
1909
            pass
 
1910
        def f(x):
 
1911
            if type(x) is C:
 
1912
                return x
 
1913
            raise Exception
 
1914
        a = self.RPythonAnnotator()
 
1915
        s = a.build_types(f, [D])
 
1916
        assert s == annmodel.SomeImpossibleValue()
 
1917
 
 
1918
    def test_is_constant_instance(self):
 
1919
        class A(object):
 
1920
            pass
 
1921
        prebuilt_instance = A()
 
1922
        def f(x):
 
1923
            if x is prebuilt_instance:
 
1924
                return x
 
1925
            raise Exception
 
1926
        a = self.RPythonAnnotator()
 
1927
        s = a.build_types(f, [A])
 
1928
        assert s.is_constant()
 
1929
        assert s.const is prebuilt_instance
 
1930
 
 
1931
    def test_call_memoized_function(self):
 
1932
        fr1 = Freezing()
 
1933
        fr2 = Freezing()
 
1934
        def getorbuild(key):
 
1935
            a = 1
 
1936
            if key is fr1:
 
1937
                result = eval("a+2")
 
1938
            else:
 
1939
                result = eval("a+6")
 
1940
            return result
 
1941
        getorbuild._annspecialcase_ = "specialize:memo"
 
1942
 
 
1943
        def f1(i):
 
1944
            if i > 0:
 
1945
                fr = fr1
 
1946
            else:
 
1947
                fr = fr2
 
1948
            return getorbuild(fr)
 
1949
 
 
1950
        a = self.RPythonAnnotator()
 
1951
        s = a.build_types(f1, [int])
 
1952
        assert s.knowntype == int
 
1953
 
 
1954
    def test_call_memoized_function_with_bools(self):
 
1955
        fr1 = Freezing()
 
1956
        fr2 = Freezing()
 
1957
        def getorbuild(key, flag1, flag2):
 
1958
            a = 1
 
1959
            if key is fr1:
 
1960
                result = eval("a+2")
 
1961
            else:
 
1962
                result = eval("a+6")
 
1963
            if flag1:
 
1964
                result += 100
 
1965
            if flag2:
 
1966
                result += 1000
 
1967
            return result
 
1968
        getorbuild._annspecialcase_ = "specialize:memo"
 
1969
 
 
1970
        def f1(i):
 
1971
            if i > 0:
 
1972
                fr = fr1
 
1973
            else:
 
1974
                fr = fr2
 
1975
            return getorbuild(fr, i % 2 == 0, i % 3 == 0)
 
1976
 
 
1977
        a = self.RPythonAnnotator()
 
1978
        s = a.build_types(f1, [int])
 
1979
        assert s.knowntype == int
 
1980
 
 
1981
    def test_stored_bound_method(self):
 
1982
        # issue 129
 
1983
        class H:
 
1984
            def h(self):
 
1985
                return 42
 
1986
        class C:
 
1987
            def __init__(self, func):
 
1988
                self.f = func
 
1989
            def do(self):
 
1990
                return self.f()
 
1991
        def g():
 
1992
            h = H()
 
1993
            c = C(h.h)
 
1994
            return c.do()
 
1995
 
 
1996
        a = self.RPythonAnnotator()
 
1997
        s = a.build_types(g, [])
 
1998
        assert s.is_constant()
 
1999
        assert s.const == 42
 
2000
 
 
2001
    def test_stored_bound_method_2(self):
 
2002
        # issue 129
 
2003
        class H:
 
2004
            pass
 
2005
        class H1(H):
 
2006
            def h(self):
 
2007
                return 42
 
2008
        class H2(H):
 
2009
            def h(self):
 
2010
                return 17
 
2011
        class C:
 
2012
            def __init__(self, func):
 
2013
                self.f = func
 
2014
            def do(self):
 
2015
                return self.f()
 
2016
        def g(flag):
 
2017
            if flag:
 
2018
                h = H1()
 
2019
            else:
 
2020
                h = H2()
 
2021
            c = C(h.h)
 
2022
            return c.do()
 
2023
 
 
2024
        a = self.RPythonAnnotator()
 
2025
        s = a.build_types(g, [int])
 
2026
        assert s.knowntype == int
 
2027
        assert not s.is_constant()
 
2028
 
 
2029
    def test_getorbuild_as_attr(self):
 
2030
        from pypy.tool.cache import Cache
 
2031
        class SpaceCache(Cache):
 
2032
            def _build(self, callable):
 
2033
                return callable()
 
2034
        class CacheX(Cache):
 
2035
            def _build(self, key):
 
2036
                return key.x
 
2037
        class CacheY(Cache):
 
2038
            def _build(self, key):
 
2039
                return key.y
 
2040
        class X:
 
2041
            def __init__(self, x):
 
2042
                self.x = x
 
2043
            def _freeze_(self):
 
2044
                return True
 
2045
        class Y:
 
2046
            def __init__(self, y):
 
2047
                self.y = y
 
2048
            def _freeze_(self):
 
2049
                return True
 
2050
        X1 = X(1)
 
2051
        Y2 = Y("hello")
 
2052
        fromcache = SpaceCache().getorbuild
 
2053
        def f():
 
2054
            return (fromcache(CacheX).getorbuild(X1),
 
2055
                    fromcache(CacheY).getorbuild(Y2))
 
2056
 
 
2057
        a = self.RPythonAnnotator()
 
2058
        s = a.build_types(f, [])
 
2059
        assert s.items[0].knowntype == int
 
2060
        assert s.items[1].knowntype == str
 
2061
 
 
2062
    def test_constant_bound_method(self):
 
2063
        class C:
 
2064
            def __init__(self, value):
 
2065
                self.value = value
 
2066
            def meth(self):
 
2067
                return self.value
 
2068
        meth = C(1).meth
 
2069
        def f():
 
2070
            return meth()
 
2071
        a = self.RPythonAnnotator()
 
2072
        s = a.build_types(f, [])
 
2073
        assert s.knowntype == int
 
2074
 
 
2075
    def test_annotate__del__(self):
 
2076
        class A(object):
 
2077
            def __init__(self):
 
2078
                self.a = 2
 
2079
            def __del__(self):
 
2080
                self.a = 1
 
2081
        def f():
 
2082
            return A().a
 
2083
        a = self.RPythonAnnotator()
 
2084
        t = a.translator
 
2085
        s = a.build_types(f, [])
 
2086
        assert s.knowntype == int
 
2087
        graph = tgraphof(t, A.__del__.im_func)
 
2088
        assert graph.startblock in a.annotated
 
2089
 
 
2090
    def test_annotate__del__baseclass(self):
 
2091
        class A(object):
 
2092
            def __init__(self):
 
2093
                self.a = 2
 
2094
            def __del__(self):
 
2095
                self.a = 1
 
2096
        class B(A):
 
2097
            def __init__(self):
 
2098
                self.a = 3
 
2099
        def f():
 
2100
            return B().a
 
2101
        a = self.RPythonAnnotator()
 
2102
        t = a.translator
 
2103
        s = a.build_types(f, [])
 
2104
        assert s.knowntype == int
 
2105
        graph = tgraphof(t, A.__del__.im_func)
 
2106
        assert graph.startblock in a.annotated
 
2107
 
 
2108
    def test_annotate_type(self):
 
2109
        class A:
 
2110
            pass
 
2111
        x = [A(), A()]
 
2112
        def witness(t):
 
2113
            return type(t)
 
2114
        def get(i):
 
2115
            return x[i]
 
2116
        def f(i):
 
2117
            witness(None)
 
2118
            return witness(get(i))
 
2119
            
 
2120
        a = self.RPythonAnnotator()
 
2121
        s = a.build_types(f, [int])
 
2122
        assert s.__class__ == annmodel.SomeObject
 
2123
        assert s.knowntype == type
 
2124
 
 
2125
    def test_annotate_iter_empty_container(self):
 
2126
        def f():
 
2127
            n = 0
 
2128
            d = {}
 
2129
            for x in []:                n += x
 
2130
            for y in d:                 n += y
 
2131
            for z in d.iterkeys():      n += z
 
2132
            for s in d.itervalues():    n += s
 
2133
            for t, u in d.items():      n += t * u
 
2134
            for t, u in d.iteritems():  n += t * u
 
2135
            return n
 
2136
 
 
2137
        a = self.RPythonAnnotator()
 
2138
        s = a.build_types(f, [])
 
2139
        assert s.is_constant()
 
2140
        assert s.const == 0
 
2141
 
 
2142
    def test_mixin(self):
 
2143
        class Mixin(object):
 
2144
            _mixin_ = True
 
2145
 
 
2146
            def m(self, v):
 
2147
                return v
 
2148
 
 
2149
        class Base(object):
 
2150
            pass
 
2151
 
 
2152
        class A(Base, Mixin):
 
2153
            pass
 
2154
 
 
2155
        class B(Base, Mixin):
 
2156
            pass
 
2157
 
 
2158
        class C(B):
 
2159
            pass
 
2160
 
 
2161
        def f():
 
2162
            a = A()
 
2163
            v0 = a.m(2)
 
2164
            b = B()
 
2165
            v1 = b.m('x')
 
2166
            c = C()
 
2167
            v2 = c.m('y')
 
2168
            return v0, v1, v2
 
2169
 
 
2170
        a = self.RPythonAnnotator()
 
2171
        s = a.build_types(f, [])
 
2172
        assert isinstance(s.items[0], annmodel.SomeInteger)
 
2173
        assert isinstance(s.items[1], annmodel.SomeChar)        
 
2174
        assert isinstance(s.items[2], annmodel.SomeChar)        
 
2175
 
 
2176
    def test___class___attribute(self):
 
2177
        class Base(object): pass
 
2178
        class A(Base): pass
 
2179
        class B(Base): pass
 
2180
        class C(A): pass
 
2181
        def seelater():
 
2182
            C()
 
2183
        def f(n):
 
2184
            if n == 1:
 
2185
                x = A()
 
2186
            else:
 
2187
                x = B()
 
2188
            y = B()
 
2189
            result = x.__class__, y.__class__
 
2190
            seelater()
 
2191
            return result
 
2192
 
 
2193
        a = self.RPythonAnnotator()
 
2194
        s = a.build_types(f, [int])
 
2195
        assert isinstance(s.items[0], annmodel.SomePBC)
 
2196
        assert len(s.items[0].descriptions) == 4
 
2197
        assert isinstance(s.items[1], annmodel.SomePBC)
 
2198
        assert len(s.items[1].descriptions) == 1
 
2199
 
 
2200
    def test_slots(self):
 
2201
        # check that the annotator ignores slots instead of being
 
2202
        # confused by them showing up as 'member' objects in the class
 
2203
        class A(object):
 
2204
            __slots__ = ('a', 'b')
 
2205
        def f(x):
 
2206
            a = A()
 
2207
            a.b = x
 
2208
            return a.b
 
2209
 
 
2210
        a = self.RPythonAnnotator()
 
2211
        s = a.build_types(f, [int])
 
2212
        assert s.knowntype == int
 
2213
 
 
2214
    def test_unboxed_value(self):
 
2215
        class A(object):
 
2216
            __slots__ = ()
 
2217
        class C(A, objectmodel.UnboxedValue):
 
2218
            __slots__ = unboxedattrname = 'smallint'
 
2219
        def f(n):
 
2220
            return C(n).smallint
 
2221
 
 
2222
        a = self.RPythonAnnotator()
 
2223
        s = a.build_types(f, [int])
 
2224
        assert s.knowntype == int
 
2225
 
 
2226
 
 
2227
    def test_annotate_bool(self):
 
2228
        def f(x):
 
2229
            return ~x
 
2230
        a = self.RPythonAnnotator()
 
2231
        s = a.build_types(f, [bool])
 
2232
        assert s.knowntype == int
 
2233
        
 
2234
 
 
2235
        def f(x):
 
2236
            return -x
 
2237
        a = self.RPythonAnnotator()
 
2238
        s = a.build_types(f, [bool])
 
2239
        assert s.knowntype == int
 
2240
 
 
2241
        def f(x):
 
2242
            return +x
 
2243
        a = self.RPythonAnnotator()
 
2244
        s = a.build_types(f, [bool])
 
2245
        assert s.knowntype == int
 
2246
 
 
2247
        def f(x):
 
2248
            return abs(x)
 
2249
        a = self.RPythonAnnotator()
 
2250
        s = a.build_types(f, [bool])
 
2251
        assert s.knowntype == int
 
2252
 
 
2253
        def f(x):
 
2254
            return int(x)
 
2255
        a = self.RPythonAnnotator()
 
2256
        s = a.build_types(f, [bool])
 
2257
        assert s.knowntype == int
 
2258
 
 
2259
 
 
2260
        def f(x, y):
 
2261
            return x + y
 
2262
        a = self.RPythonAnnotator()
 
2263
        s = a.build_types(f, [bool, int])
 
2264
        assert s.knowntype == int
 
2265
 
 
2266
        a = self.RPythonAnnotator()
 
2267
        s = a.build_types(f, [int, bool])
 
2268
        assert s.knowntype == int
 
2269
 
 
2270
 
 
2271
 
 
2272
    def test_annotate_rarith(self):
 
2273
        inttypes = [int, r_uint, r_longlong, r_ulonglong]
 
2274
        for inttype in inttypes:
 
2275
            c = inttype()
 
2276
            def f():
 
2277
                return c
 
2278
            a = self.RPythonAnnotator()
 
2279
            s = a.build_types(f, [])
 
2280
            assert isinstance(s, annmodel.SomeInteger)
 
2281
            assert s.knowntype == inttype
 
2282
            assert s.unsigned == (inttype(-1) > 0)
 
2283
            
 
2284
        for inttype in inttypes:
 
2285
            def f():
 
2286
                return inttype(0)
 
2287
            a = self.RPythonAnnotator()
 
2288
            s = a.build_types(f, [])
 
2289
            assert isinstance(s, annmodel.SomeInteger)
 
2290
            assert s.knowntype == inttype
 
2291
            assert s.unsigned == (inttype(-1) > 0)
 
2292
 
 
2293
        for inttype in inttypes:
 
2294
            def f(x):
 
2295
                return x
 
2296
            a = self.RPythonAnnotator()
 
2297
            s = a.build_types(f, [inttype])
 
2298
            assert isinstance(s, annmodel.SomeInteger)
 
2299
            assert s.knowntype == inttype
 
2300
            assert s.unsigned == (inttype(-1) > 0)
 
2301
 
 
2302
    def test_annotate_rshift(self):
 
2303
        def f(x):
 
2304
            return x >> 2
 
2305
        a = self.RPythonAnnotator()
 
2306
        s = a.build_types(f, [annmodel.SomeInteger(nonneg=True)])
 
2307
        assert isinstance(s, annmodel.SomeInteger)
 
2308
        assert s.nonneg
 
2309
 
 
2310
    def test_prebuilt_mutables(self):
 
2311
        class A:
 
2312
            pass
 
2313
        class B:
 
2314
            pass
 
2315
        a1 = A()
 
2316
        a2 = A()
 
2317
        a1.d = {}    # this tests confusion between the two '{}', which
 
2318
        a2.d = {}    # compare equal
 
2319
        a1.l = []
 
2320
        a2.l = []
 
2321
        b = B()
 
2322
        b.d1 = a1.d
 
2323
        b.d2 = a2.d
 
2324
        b.l1 = a1.l
 
2325
        b.l2 = a2.l
 
2326
 
 
2327
        def dmutate(d):
 
2328
            d[123] = 321
 
2329
 
 
2330
        def lmutate(l):
 
2331
            l.append(42)
 
2332
 
 
2333
        def readout(d, l):
 
2334
            return len(d) + len(l)
 
2335
 
 
2336
        def f():
 
2337
            dmutate(b.d1)
 
2338
            dmutate(b.d2)
 
2339
            dmutate(a1.d)
 
2340
            dmutate(a2.d)
 
2341
            lmutate(b.l1)
 
2342
            lmutate(b.l2)
 
2343
            lmutate(a1.l)
 
2344
            lmutate(a2.l)
 
2345
            return readout(a1.d, a1.l) + readout(a2.d, a2.l)
 
2346
 
 
2347
        a = self.RPythonAnnotator()
 
2348
        a.build_types(f, [])
 
2349
        v1, v2 = graphof(a, readout).getargs()
 
2350
        assert not a.bindings[v1].is_constant()
 
2351
        assert not a.bindings[v2].is_constant()
 
2352
    
 
2353
    def test_helper_method_annotator(self):
 
2354
        def fun():
 
2355
            return 21
 
2356
        
 
2357
        class A(object):
 
2358
            def helper(self):
 
2359
                return 42
 
2360
        
 
2361
        a = self.RPythonAnnotator()
 
2362
        a.build_types(fun, [])
 
2363
        a.annotate_helper_method(A, "helper", [])
 
2364
        assert a.bookkeeper.getdesc(A.helper).getuniquegraph()
 
2365
 
 
2366
    def test_chr_out_of_bounds(self):
 
2367
        def g(n, max):
 
2368
            if n < max:
 
2369
                return chr(n)
 
2370
            else:
 
2371
                return '?'
 
2372
        def fun(max):
 
2373
            v = g(1000, max)
 
2374
            return g(ord(v), max)
 
2375
 
 
2376
        a = self.RPythonAnnotator()
 
2377
        s = a.build_types(fun, [int])
 
2378
        assert isinstance(s, annmodel.SomeChar)
 
2379
 
 
2380
    def test_range_nonneg(self):
 
2381
        def fun(n, k):
 
2382
            for i in range(n):
 
2383
                if k == 17:
 
2384
                    return i
 
2385
            return 0
 
2386
        a = self.RPythonAnnotator()
 
2387
        s = a.build_types(fun, [int, int])
 
2388
        assert isinstance(s, annmodel.SomeInteger)
 
2389
        assert s.nonneg
 
2390
 
 
2391
    def test_reverse_range_nonneg(self):
 
2392
        def fun(n, k):
 
2393
            for i in range(n-1, -1, -1):
 
2394
                if k == 17:
 
2395
                    return i
 
2396
            return 0
 
2397
        a = self.RPythonAnnotator()
 
2398
        s = a.build_types(fun, [int, int])
 
2399
        assert isinstance(s, annmodel.SomeInteger)
 
2400
        assert s.nonneg
 
2401
 
 
2402
    def test_sig(self):
 
2403
        def fun(x, y):
 
2404
            return x+y
 
2405
        s_nonneg = annmodel.SomeInteger(nonneg=True)
 
2406
        fun._annenforceargs_ = policy.Sig(int, s_nonneg)
 
2407
 
 
2408
        a = self.RPythonAnnotator()
 
2409
        s = a.build_types(fun, [s_nonneg, s_nonneg])
 
2410
        assert isinstance(s, annmodel.SomeInteger)
 
2411
        assert not s.nonneg
 
2412
        py.test.raises(Exception, a.build_types, fun, [int, int])
 
2413
 
 
2414
    def test_sig_simpler(self):
 
2415
        def fun(x, y):
 
2416
            return x+y
 
2417
        s_nonneg = annmodel.SomeInteger(nonneg=True)
 
2418
        fun._annenforceargs_ = (int, s_nonneg)
 
2419
 
 
2420
        a = self.RPythonAnnotator()
 
2421
        s = a.build_types(fun, [s_nonneg, s_nonneg])
 
2422
        assert isinstance(s, annmodel.SomeInteger)
 
2423
        assert not s.nonneg
 
2424
        py.test.raises(Exception, a.build_types, fun, [int, int])
 
2425
 
 
2426
    def test_sig_lambda(self):
 
2427
        def fun(x, y):
 
2428
            return y
 
2429
        s_nonneg = annmodel.SomeInteger(nonneg=True)
 
2430
        fun._annenforceargs_ = policy.Sig(lambda s1,s2: s1, lambda s1,s2: s1)
 
2431
        # means: the 2nd argument's annotation becomes the 1st argument's
 
2432
        #        input annotation
 
2433
 
 
2434
        a = self.RPythonAnnotator()
 
2435
        s = a.build_types(fun, [int, s_nonneg])
 
2436
        assert isinstance(s, annmodel.SomeInteger)
 
2437
        assert not s.nonneg
 
2438
        py.test.raises(Exception, a.build_types, fun, [s_nonneg, int])
 
2439
 
 
2440
    def test_slots_check(self):
 
2441
        class Base(object):
 
2442
            __slots__ = 'x'
 
2443
        class A(Base):
 
2444
            __slots__ = 'y'
 
2445
            def m(self):
 
2446
                return 65
 
2447
        class C(Base):
 
2448
            __slots__ = 'z'
 
2449
            def m(self):
 
2450
                return 67
 
2451
        for attrname, works in [('x', True),
 
2452
                                ('y', False),
 
2453
                                ('z', False),
 
2454
                                ('t', False)]:
 
2455
            def fun(n):
 
2456
                if n: o = A()
 
2457
                else: o = C()
 
2458
                setattr(o, attrname, 12)
 
2459
                return o.m()
 
2460
            a = self.RPythonAnnotator()
 
2461
            if works:
 
2462
                a.build_types(fun, [int])
 
2463
            else:
 
2464
                from pypy.annotation.classdef import NoSuchAttrError
 
2465
                py.test.raises(NoSuchAttrError, a.build_types, fun, [int])
 
2466
 
 
2467
    def test_slots_enforce_attrs(self):
 
2468
        class Superbase(object):
 
2469
            __slots__ = 'x'
 
2470
        class Base(Superbase):
 
2471
            pass
 
2472
        class A(Base):
 
2473
            pass
 
2474
        class B(Base):
 
2475
            pass
 
2476
        def fun(s):
 
2477
            if s is None:   # known not to be None in this test
 
2478
                o = B()
 
2479
                o.x = 12
 
2480
            elif len(s) > 5:
 
2481
                o = A()
 
2482
            else:
 
2483
                o = Base()
 
2484
            return o.x
 
2485
        a = self.RPythonAnnotator()
 
2486
        s = a.build_types(fun, [str])
 
2487
        assert s == annmodel.s_ImpossibleValue   # but not blocked blocks
 
2488
 
 
2489
    def test_enforced_attrs_check(self):
 
2490
        class Base(object):
 
2491
            _attrs_ = 'x'
 
2492
        class A(Base):
 
2493
            _attrs_ = 'y'
 
2494
            def m(self):
 
2495
                return 65
 
2496
        class C(Base):
 
2497
            _attrs_ = 'z'
 
2498
            def m(self):
 
2499
                return 67
 
2500
        for attrname, works in [('x', True),
 
2501
                                ('y', False),
 
2502
                                ('z', False),
 
2503
                                ('t', False)]:
 
2504
            def fun(n):
 
2505
                if n: o = A()
 
2506
                else: o = C()
 
2507
                setattr(o, attrname, 12)
 
2508
                return o.m()
 
2509
            a = self.RPythonAnnotator()
 
2510
            if works:
 
2511
                a.build_types(fun, [int])
 
2512
            else:
 
2513
                from pypy.annotation.classdef import NoSuchAttrError
 
2514
                py.test.raises(NoSuchAttrError, a.build_types, fun, [int])
 
2515
 
 
2516
    def test_attrs_enforce_attrs(self):
 
2517
        class Superbase(object):
 
2518
            _attrs_ = 'x'
 
2519
        class Base(Superbase):
 
2520
            pass
 
2521
        class A(Base):
 
2522
            pass
 
2523
        class B(Base):
 
2524
            pass
 
2525
        def fun(s):
 
2526
            if s is None:   # known not to be None in this test
 
2527
                o = B()
 
2528
                o.x = 12
 
2529
            elif len(s) > 5:
 
2530
                o = A()
 
2531
            else:
 
2532
                o = Base()
 
2533
            return o.x
 
2534
        a = self.RPythonAnnotator()
 
2535
        s = a.build_types(fun, [str])
 
2536
        assert s == annmodel.s_ImpossibleValue   # but not blocked blocks
 
2537
 
 
2538
 
 
2539
    def test_pbc_enforce_attrs(self):
 
2540
        class F(object):
 
2541
            _attrs_ = ['foo',]
 
2542
 
 
2543
            def _freeze_(self):
 
2544
                return True
 
2545
 
 
2546
        p1 = F()
 
2547
        p2 = F()
 
2548
 
 
2549
        def g(): pass
 
2550
 
 
2551
        def f(x):
 
2552
            if x:
 
2553
                p = p1
 
2554
            else:
 
2555
                p = p2
 
2556
            g()
 
2557
            return p.foo
 
2558
 
 
2559
        a = self.RPythonAnnotator()
 
2560
        a.build_types(f, [bool])
 
2561
 
 
2562
    def test_enforce_settled(self):
 
2563
        class A(object):
 
2564
            _settled_ = True
 
2565
 
 
2566
            def m(self):
 
2567
                raise NotImplementedError
 
2568
 
 
2569
        class B(A):
 
2570
 
 
2571
            def m(self):
 
2572
                return 1
 
2573
 
 
2574
            def n(self):
 
2575
                return 1
 
2576
 
 
2577
        def fun(x):
 
2578
            if x:
 
2579
                a = A()
 
2580
            else:
 
2581
                a = B()
 
2582
 
 
2583
            return a.m()
 
2584
 
 
2585
        a = self.RPythonAnnotator()
 
2586
        s = a.build_types(fun, [bool])
 
2587
        assert s.knowntype == int
 
2588
 
 
2589
        def fun(x):
 
2590
            if x:
 
2591
                a = A()
 
2592
            else:
 
2593
                a = B()
 
2594
 
 
2595
            return a.n()
 
2596
 
 
2597
        a = self.RPythonAnnotator()
 
2598
        py.test.raises(Exception, a.build_types, fun, [bool])
 
2599
 
 
2600
    def test_float_cmp(self):
 
2601
        def fun(x, y):
 
2602
            return (x < y,
 
2603
                    x <= y,
 
2604
                    x == y,
 
2605
                    x != y,
 
2606
                    x > y,
 
2607
                    x >= y)
 
2608
 
 
2609
        a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy())
 
2610
        s = a.build_types(fun, [float, float])
 
2611
        assert [s_item.knowntype for s_item in s.items] == [bool] * 6
 
2612
 
 
2613
    def test_empty_range(self):
 
2614
        def g(lst):
 
2615
            total = 0
 
2616
            for i in range(len(lst)):
 
2617
                total += lst[i]
 
2618
            return total
 
2619
        def fun():
 
2620
            return g([])
 
2621
 
 
2622
        a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy())
 
2623
        s = a.build_types(fun, [])
 
2624
        assert s.const == 0
 
2625
 
 
2626
    def test_some_generic_function_call(self):
 
2627
        def h(x):
 
2628
            return int(x)
 
2629
 
 
2630
        def c(x):
 
2631
            return int(x)
 
2632
        
 
2633
        def g(a, x):
 
2634
            if x == -1:
 
2635
                a = None
 
2636
            if x < 0:
 
2637
                if x == -1:
 
2638
                    a = h
 
2639
                else:
 
2640
                    a = c
 
2641
                x = x + .01
 
2642
            return a(x)
 
2643
 
 
2644
        #def fun(x):   
 
2645
 
 
2646
        a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy())
 
2647
        s = a.build_types(g, [annmodel.SomeGenericCallable(
 
2648
            args=[annmodel.SomeFloat()], result=annmodel.SomeInteger()),
 
2649
                              annmodel.SomeFloat()])
 
2650
        assert isinstance(s, annmodel.SomeInteger)
 
2651
        assert not hasattr(s, 'const')
 
2652
 
 
2653
    def test_compare_int_bool(self):
 
2654
        def fun(x):
 
2655
            return 50 < x
 
2656
        a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy())
 
2657
        s = a.build_types(fun, [bool])
 
2658
        assert isinstance(s, annmodel.SomeBool)
 
2659
 
 
2660
    def test_long_as_intermediate_value(self):
 
2661
        from sys import maxint
 
2662
        from pypy.rlib.rarithmetic import intmask
 
2663
        def fun(x):
 
2664
            if x > 0:
 
2665
                v = maxint
 
2666
            else:
 
2667
                v = -maxint
 
2668
            return intmask(v * 10)
 
2669
        P = policy.AnnotatorPolicy()
 
2670
        P.allow_someobjects = False
 
2671
        a = self.RPythonAnnotator(policy=P)
 
2672
        s = a.build_types(fun, [bool])
 
2673
        assert isinstance(s, annmodel.SomeInteger)
 
2674
 
 
2675
    def test_unionof_some_external_builtin(self):
 
2676
        from pypy.rpython.ootypesystem.bltregistry import BasicExternal
 
2677
        
 
2678
        class A(BasicExternal):
 
2679
            pass
 
2680
 
 
2681
        class B(A):
 
2682
            pass
 
2683
 
 
2684
        class C(A):
 
2685
            pass
 
2686
 
 
2687
        def f(x):
 
2688
            if x:
 
2689
                return B()
 
2690
            else:
 
2691
                return C()
 
2692
 
 
2693
        P = policy.AnnotatorPolicy()
 
2694
        P.allow_someobjects = False
 
2695
        a = self.RPythonAnnotator(policy=P)
 
2696
        s = a.build_types(f, [bool])
 
2697
        assert isinstance(s, annmodel.SomeExternalBuiltin)        
 
2698
 
 
2699
    def test_instance_with_flags(self):
 
2700
        from pypy.rlib.objectmodel import hint
 
2701
 
 
2702
        class A:
 
2703
            _virtualizable_ = True
 
2704
        class B(A):
 
2705
            def meth(self):
 
2706
                return self
 
2707
        class C(A): 
 
2708
            def meth(self):
 
2709
                return self
 
2710
 
 
2711
        def f(n):
 
2712
            x = B()
 
2713
            x = hint(x, access_directly=True)
 
2714
            m = x.meth
 
2715
            for i in range(n):
 
2716
                x = C()
 
2717
                m = x.meth
 
2718
            return x, m, m()
 
2719
 
 
2720
        a = self.RPythonAnnotator()
 
2721
        s = a.build_types(f, [a.bookkeeper.immutablevalue(0)])
 
2722
        assert isinstance(s.items[0], annmodel.SomeInstance)
 
2723
        assert s.items[0].flags == {'access_directly': True}
 
2724
        assert isinstance(s.items[1], annmodel.SomePBC)
 
2725
        assert len(s.items[1].descriptions) == 1
 
2726
        assert s.items[1].descriptions.keys()[0].flags == {'access_directly':
 
2727
                                                           True}
 
2728
        assert isinstance(s.items[2], annmodel.SomeInstance)
 
2729
        assert s.items[2].flags == {'access_directly': True}
 
2730
 
 
2731
        a = self.RPythonAnnotator()
 
2732
        s = a.build_types(f, [int])
 
2733
        assert isinstance(s.items[0], annmodel.SomeInstance)
 
2734
        assert s.items[0].flags == {}
 
2735
        assert isinstance(s.items[1], annmodel.SomePBC)
 
2736
        assert isinstance(s.items[2], annmodel.SomeInstance)
 
2737
        assert s.items[2].flags == {}
 
2738
 
 
2739
def g(n):
 
2740
    return [0,1,2,n]
 
2741
 
 
2742
def f_calls_g(n):
 
2743
    total = 0
 
2744
    lst = g(n)
 
2745
    i = 0
 
2746
    while i < len(lst):
 
2747
        total += i
 
2748
        i += 1
 
2749
    return total
 
2750
 
 
2751
constant_unsigned_five = r_uint(5)
 
2752
        
 
2753
class Freezing:
 
2754
    def _freeze_(self):
 
2755
        return True
 
2756