-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathtest.py
More file actions
157 lines (114 loc) · 3.55 KB
/
test.py
File metadata and controls
157 lines (114 loc) · 3.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
def get_tracked():
x = tracked # $tracked
return x # $tracked
def use_tracked_foo(x): # $tracked
do_stuff(x) # $tracked
def foo():
use_tracked_foo(
get_tracked() # $tracked
)
def use_tracked_bar(x): # $tracked
do_stuff(x) # $tracked
def bar():
x = get_tracked() # $tracked
use_tracked_bar(x) # $tracked
def use_tracked_baz(x): # $tracked
do_stuff(x) # $tracked
def baz():
x = tracked # $tracked
use_tracked_baz(x) # $tracked
def id(x): # $tracked
return x # $tracked
def use_tracked_quux(x): # $ MISSING: tracked
do_stuff(y) # call after return -- not tracked in here.
def quux():
x = tracked # $tracked
y = id(x) # $tracked
use_tracked_quux(y) # not tracked out of call to id.
g = None
def write_g(x): # $tracked
global g
g = x # $tracked
def use_g():
do_stuff(g) # $tracked
def global_var_write_test():
x = tracked # $tracked
write_g(x) # $tracked
use_g()
def test_import():
import mymodule
mymodule.x # $tracked
y = mymodule.func() # $tracked
y # $tracked
mymodule.z # $tracked
def to_inner_scope():
x = tracked # $tracked
def foo():
y = x # $ MISSING: tracked
return y # $ MISSING: tracked
also_x = foo() # $ MISSING: tracked
print(also_x) # $ MISSING: tracked
def my_decorator(func):
# This part doesn't make any sense in a normal decorator, but just shows how we
# handle type-tracking
func() # $tracked
def wrapper():
print("before function call")
val = func() # $ MISSING: tracked
print("after function call")
return val # $ MISSING: tracked
return wrapper
@my_decorator
def get_tracked2():
return tracked # $tracked
@my_decorator
def unrelated_func():
return "foo"
def use_funcs_with_decorators():
x = get_tracked2() # $ MISSING: tracked
y = unrelated_func()
# ------------------------------------------------------------------------------
def expects_int(x): # $int
do_int_stuff(x) # $int
def expects_string(x): # $str
do_string_stuff(x) # $str
def redefine_test():
x = int(5) # $int
expects_int(x) # $int
x = str("Hello") # $str
expects_string(x) # $str
# ------------------------------------------------------------------------------
# Tracking of self in methods
# ------------------------------------------------------------------------------
class Foo(object):
def meth1(self):
do_stuff(self)
def meth2(self): # $ MISSING: tracked_self
do_stuff(self) # $ MISSING: tracked_self
def meth3(self): # $ MISSING: tracked_self
do_stuff(self) # $ MISSING: tracked_self
class Bar(Foo):
def meth1(self): # $ tracked_self
do_stuff(self) # $ tracked_self
def meth2(self):
do_stuff(self)
def meth3(self):
do_stuff(self)
def track_self(self): # $ tracked_self
self.meth1() # $ tracked_self
super().meth2()
super(Bar, self).foo3() # $ tracked_self
# ------------------------------------------------------------------------------
# Tracking of attribute lookup after "long" import chain
# ------------------------------------------------------------------------------
def test_long_import_chain():
import foo.bar
foo.baz
x = foo.bar.baz # $ tracked_foo_bar_baz
do_stuff(x) # $ tracked_foo_bar_baz
class Example(foo.bar.baz): # $ tracked_foo_bar_baz
pass
def test_long_import_chain_full_path():
from foo.bar import baz # $ tracked_foo_bar_baz
x = baz # $ tracked_foo_bar_baz
do_stuff(x) # $ tracked_foo_bar_baz