1
+ # This tests some of the common built-in functions and methods.
2
+ # We need a decent model of data flow through these in order to
3
+ # analyse most programs.
4
+ #
5
+ # All functions starting with "test_" should run and execute `print("OK")` exactly once.
6
+ # This can be checked by running validTest.py.
7
+
8
+ import sys
9
+ import os
10
+
11
+ sys .path .append (os .path .dirname (os .path .dirname ((__file__ ))))
12
+ from testlib import expects
13
+
14
+ # These are defined so that we can evaluate the test code.
15
+ NONSOURCE = "not a source"
16
+ SOURCE = "source"
17
+
18
+ def is_source (x ):
19
+ return x == "source" or x == b"source" or x == 42 or x == 42.0 or x == 42j
20
+
21
+ def SINK (x ):
22
+ if is_source (x ):
23
+ print ("OK" )
24
+ else :
25
+ print ("Unexpected flow" , x )
26
+
27
+ def SINK_F (x ):
28
+ if is_source (x ):
29
+ print ("Unexpected flow" , x )
30
+ else :
31
+ print ("OK" )
32
+
33
+
34
+ # Actual tests
35
+
36
+ ## Container constructors
37
+
38
+ ### List
39
+
40
+ @expects (2 )
41
+ def test_list_from_list ():
42
+ l1 = [SOURCE , NONSOURCE ]
43
+ l2 = list (l1 )
44
+ SINK (l2 [0 ]) #$ MISSING: flow="SOURCE, l:-2 -> l2[0]"
45
+ SINK_F (l2 [1 ]) # expecting FP due to imprecise flow
46
+
47
+ # -- skip list_from_string
48
+
49
+ @expects (2 )
50
+ def test_list_from_tuple ():
51
+ t = (SOURCE , NONSOURCE )
52
+ l = list (t )
53
+ SINK (l [0 ]) #$ MISSING: flow="SOURCE, l:-2 -> l[0]"
54
+ SINK_F (l [1 ]) # expecting FP due to imprecise flow
55
+
56
+ def test_list_from_set ():
57
+ s = {SOURCE }
58
+ l = list (s )
59
+ SINK (l [0 ]) #$ MISSING: flow="SOURCE, l:-2 -> l[0]"
60
+
61
+ @expects (2 )
62
+ def test_list_from_dict ():
63
+ d = {SOURCE : 'v' , NONSOURCE : 'v2' }
64
+ l = list (d )
65
+ SINK (l [0 ]) #$ MISSING: flow="SOURCE, l:-2 -> l[0]"
66
+ SINK_F (l [1 ]) # expecting FP due to imprecise flow
67
+
68
+ ### Tuple
69
+
70
+ @expects (2 )
71
+ def test_tuple_from_list ():
72
+ l = [SOURCE , NONSOURCE ]
73
+ t = tuple (l )
74
+ SINK (t [0 ]) #$ MISSING: flow="SOURCE, l:-2 -> t[0]"
75
+ SINK_F (t [1 ])
76
+
77
+ @expects (2 )
78
+ def test_tuple_from_tuple ():
79
+ t0 = (SOURCE , NONSOURCE )
80
+ t = tuple (t0 )
81
+ SINK (t [0 ]) #$ MISSING: flow="SOURCE, l:-2 -> t[0]"
82
+ SINK_F (t [1 ])
83
+
84
+ def test_tuple_from_set ():
85
+ s = {SOURCE }
86
+ t = tuple (s )
87
+ SINK (t [0 ]) #$ MISSING: flow="SOURCE, l:-2 -> t[0]"
88
+
89
+ @expects (2 )
90
+ def test_tuple_from_dict ():
91
+ d = {SOURCE : "v1" , NONSOURCE : "v2" }
92
+ t = tuple (d )
93
+ SINK (t [0 ]) #$ MISSING: flow="SOURCE, l:-2 -> t[0]"
94
+ SINK_F (t [1 ])
95
+
96
+
97
+ ### Set
98
+
99
+ def test_set_from_list ():
100
+ l = [SOURCE ]
101
+ s = set (l )
102
+ v = s .pop ()
103
+ SINK (v ) #$ MISSING: flow="SOURCE, l:-3 -> v"
104
+
105
+ def test_set_from_tuple ():
106
+ t = (SOURCE ,)
107
+ s = set (t )
108
+ v = s .pop ()
109
+ SINK (v ) #$ MISSING: flow="SOURCE, l:-3 -> v"
110
+
111
+ def test_set_from_set ():
112
+ s0 = {SOURCE }
113
+ s = set (s0 )
114
+ v = s .pop ()
115
+ SINK (v ) #$ MISSING: flow="SOURCE, l:-3 -> v"
116
+
117
+ def test_set_from_dict ():
118
+ d = {SOURCE : "val" }
119
+ s = set (d )
120
+ v = s .pop ()
121
+ SINK (v ) #$ MISSING: flow="SOURCE, l:-3 -> v"
122
+
123
+
124
+ ### Dict
125
+
126
+ @expects (2 )
127
+ def test_dict_from_keyword ():
128
+ d = dict (k = SOURCE , k1 = NONSOURCE )
129
+ SINK (d ["k" ]) #$ MISSING: flow="SOURCE, l:-1 -> d[k]"
130
+ SINK_F (d ["k1" ])
131
+
132
+ @expects (2 )
133
+ def test_dict_from_list ():
134
+ d = dict ([("k" , SOURCE ), ("k1" , NONSOURCE )])
135
+ SINK (d ["k" ]) #$ MISSING: flow="SOURCE, l:-1 -> d[k]"
136
+ SINK_F (d ["k1" ])
137
+
138
+ @expects (2 )
139
+ def test_dict_from_dict ():
140
+ d1 = {'k' : SOURCE , 'k1' : NONSOURCE }
141
+ d2 = dict (d1 )
142
+ SINK (d2 ["k" ]) #$ MISSING: flow="SOURCE, l:-2 -> d[k]"
143
+ SINK_F (d2 ["k1" ])
144
+
145
+ ## Container methods
146
+
147
+ ### List
148
+
149
+ def test_list_pop ():
150
+ l = [SOURCE ]
151
+ v = l .pop ()
152
+ SINK (v ) #$ flow="SOURCE, l:-2 -> v"
153
+
154
+ def test_list_pop_index ():
155
+ l = [SOURCE ]
156
+ v = l .pop (0 )
157
+ SINK (v ) #$ MISSING: flow="SOURCE, l:-2 -> v"
158
+
159
+ def test_list_pop_index_imprecise ():
160
+ l = [SOURCE , NONSOURCE ]
161
+ v = l .pop (1 )
162
+ SINK_F (v )
163
+
164
+ @expects (2 )
165
+ def test_list_copy ():
166
+ l0 = [SOURCE , NONSOURCE ]
167
+ l = l0 .copy ()
168
+ SINK (l [0 ]) #$ MISSING: flow="SOURCE, l:-2 -> l[0]"
169
+ SINK_F (l [1 ])
170
+
171
+ def test_list_append ():
172
+ l = [NONSOURCE ]
173
+ l .append (SOURCE )
174
+ SINK (l [1 ]) #$ MISSING: flow="SOURCE, l:-1 -> l[1]"
175
+
176
+ ### Set
177
+
178
+ def test_set_pop ():
179
+ s = {SOURCE }
180
+ v = s .pop ()
181
+ SINK (v ) #$ flow="SOURCE, l:-2 -> v"
182
+
183
+ def test_set_copy ():
184
+ s0 = {SOURCE }
185
+ s = s0 .copy ()
186
+ SINK (s .pop ()) #$ MISSING: flow="SOURCE, l:-2 -> s.pop()"
187
+
188
+ def test_set_add ():
189
+ s = set ([])
190
+ s .add (SOURCE )
191
+ SINK (s .pop ()) #$ MISSING: flow="SOURCE, l:-2 -> s.pop()"
192
+
193
+ ### Dict
194
+
195
+ def test_dict_keys ():
196
+ d = {SOURCE : "value" }
197
+ keys = d .keys ()
198
+ key_list = list (keys )
199
+ SINK (key_list [0 ]) #$ MISSING: flow="SOURCE, l:-3 -> key_list[0]"
200
+
201
+ def test_dict_values ():
202
+ d = {'k' : SOURCE }
203
+ vals = d .values ()
204
+ val_list = list (vals )
205
+ SINK (val_list [0 ]) #$ MISSING: flow="SOURCE, l:-3 -> val_list[0]"
206
+
207
+ @expects (4 )
208
+ def test_dict_items ():
209
+ d = {'k' : SOURCE , SOURCE : "value" }
210
+ items = d .items ()
211
+ item_list = list (items )
212
+ SINK_F (item_list [0 ][0 ]) # expecting FP due to imprecise flow
213
+ SINK (item_list [0 ][1 ]) #$ MISSING: flow="SOURCE, l:-4 -> item_list[0][1]"
214
+ SINK (item_list [1 ][0 ]) #$ MISSING: flow="SOURCE, l:-5 -> item_list[1][0]"
215
+ SINK_F (item_list [1 ][1 ]) # expecting FP due to imprecise flow
216
+
217
+ @expects (2 )
218
+ def test_dict_pop ():
219
+ d = {'k' : SOURCE }
220
+ v = d .pop ("k" )
221
+ SINK (v ) #$ flow="SOURCE, l:-2 -> v"
222
+ v1 = d .pop ("k" , SOURCE )
223
+ SINK (v1 ) #$ flow="SOURCE, l:-4 -> v1"
224
+
225
+ @expects (2 )
226
+ def test_dict_get ():
227
+ d = {'k' : SOURCE }
228
+ v = d .get ("k" )
229
+ SINK (v ) #$ flow="SOURCE, l:-2 -> v"
230
+ v1 = d .get ("k" , SOURCE )
231
+ SINK (v1 ) #$ flow="SOURCE, l:-4 -> v1"
232
+
233
+ @expects (2 )
234
+ def test_dict_popitem ():
235
+ d = {'k' : SOURCE }
236
+ t = d .popitem () # could be any pair (before 3.7), but we only have one
237
+ SINK_F (t [0 ])
238
+ SINK (t [1 ]) #$ MISSING: flow="SOURCE, l:-3 -> t[1]"
239
+
240
+ @expects (2 )
241
+ def test_dict_copy ():
242
+ d = {'k' : SOURCE , 'k1' : NONSOURCE }
243
+ d1 = d .copy ()
244
+ SINK (d1 ["k" ]) #$ MISSING: flow="SOURCE, l:-2 -> d[k]"
245
+ SINK_F (d1 ["k1" ])
246
+
247
+
248
+ ## Functions on containers
249
+
250
+ ### sorted
251
+
252
+ def test_sorted_list ():
253
+ l0 = [SOURCE ]
254
+ l = sorted (l0 )
255
+ SINK (l [0 ]) #$ MISSING: flow="SOURCE, l:-2 -> l[0]"
256
+
257
+ def test_sorted_tuple ():
258
+ t = (SOURCE ,)
259
+ l = sorted (t )
260
+ SINK (l [0 ]) #$ MISSING: flow="SOURCE, l:-2 -> l[0]"
261
+
262
+ def test_sorted_set ():
263
+ s = {SOURCE }
264
+ l = sorted (s )
265
+ SINK (l [0 ]) #$ MISSING: flow="SOURCE, l:-2 -> l[0]"
266
+
267
+ def test_sorted_dict ():
268
+ d = {SOURCE : "val" }
269
+ l = sorted (d )
270
+ SINK (l [0 ]) #$ MISSING: flow="SOURCE, l:-2 -> l[0]"
271
+
272
+ ### reversed
273
+
274
+ @expects (2 )
275
+ def test_reversed_list ():
276
+ l0 = [SOURCE , NONSOURCE ]
277
+ r = reversed (l0 )
278
+ l = list (r )
279
+ SINK_F (l [0 ])
280
+ SINK (l [1 ]) #$ MISSING: flow="SOURCE, l:-4 -> l[1]"
281
+
282
+ @expects (2 )
283
+ def test_reversed_tuple ():
284
+ t = (SOURCE , NONSOURCE )
285
+ r = reversed (t )
286
+ l = list (r )
287
+ SINK_F (l [0 ])
288
+ SINK (l [1 ]) #$ MISSING: flow="SOURCE, l:-4 -> l[1]"
289
+
290
+ @expects (2 )
291
+ def test_reversed_dict ():
292
+ d = {SOURCE : "v1" , NONSOURCE : "v2" }
293
+ r = reversed (d )
294
+ l = list (r )
295
+ SINK_F (l [0 ])
296
+ SINK (l [1 ]) #$ MISSING: flow="SOURCE, l:-4 -> l[1]"
297
+
298
+ ### iter
299
+
300
+ def test_iter_list ():
301
+ l0 = [SOURCE ]
302
+ i = iter (l0 )
303
+ l = list (i )
304
+ SINK (l [0 ]) #$ MISSING: flow="SOURCE, l:-3 -> l[0]"
305
+
306
+ def test_iter_tuple ():
307
+ t = (SOURCE ,)
308
+ i = iter (t )
309
+ l = list (i )
310
+ SINK (l [0 ]) #$ MISSING: flow="SOURCE, l:-3 -> l[0]"
311
+
312
+ def test_iter_set ():
313
+ t = {SOURCE }
314
+ i = iter (t )
315
+ l = list (i )
316
+ SINK (l [0 ]) #$ MISSING: flow="SOURCE, l:-3 -> l[0]"
317
+
318
+ def test_iter_dict ():
319
+ d = {SOURCE : "val" }
320
+ i = iter (d )
321
+ l = list (i )
322
+ SINK (l [0 ]) #$ MISSING: flow="SOURCE, l:-3 -> l[0]"
323
+
324
+ ### next
325
+
326
+ def test_next_list ():
327
+ l = [SOURCE ]
328
+ i = iter (l )
329
+ n = next (i )
330
+ SINK (n ) #$ MISSING: flow="SOURCE, l:-3 -> n"
331
+
332
+ def test_next_tuple ():
333
+ t = (SOURCE ,)
334
+ i = iter (t )
335
+ n = next (i )
336
+ SINK (n ) #$ MISSING: flow="SOURCE, l:-3 -> n"
337
+
338
+ def test_next_set ():
339
+ s = {SOURCE }
340
+ i = iter (s )
341
+ n = next (i )
342
+ SINK (n ) #$ MISSING: flow="SOURCE, l:-3 -> n"
343
+
344
+ def test_next_dict ():
345
+ d = {SOURCE : "val" }
346
+ i = iter (d )
347
+ n = next (i )
348
+ SINK (n ) #$ MISSING: flow="SOURCE, l:-3 -> n"
0 commit comments