Skip to content

Commit e3a6daa

Browse files
authored
Merge pull request github#6046 from RasmusWL/typetracking-attributes
Python: Add type-tracking test for attrs set in functions/methods
2 parents d65e6bb + aaddd36 commit e3a6daa

File tree

1 file changed

+62
-2
lines changed

1 file changed

+62
-2
lines changed

python/ql/test/experimental/dataflow/typetracking/attribute_tests.py

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,28 @@ def test_incompatible_types():
3030
x.field = str("Hello") # $str=field str SPURIOUS: int=field int
3131
expects_string(x) # $ str=field SPURIOUS: int=field
3232

33-
33+
# set in different function
34+
def set_foo(some_class_instance): # $ tracked=foo
35+
some_class_instance.foo = tracked # $ tracked=foo tracked
36+
37+
def test_set_x():
38+
x = SomeClass() # $ MISSING: tracked=foo
39+
set_foo(x) # $ MISSING: tracked=foo
40+
print(x.foo) # $ MISSING: tracked=foo tracked
41+
42+
# return from a different function
43+
def create_with_foo():
44+
x = SomeClass() # $ tracked=foo
45+
x.foo = tracked # $ tracked=foo tracked
46+
return x # $ tracked=foo
47+
48+
def test_create_with_foo():
49+
x = create_with_foo() # $ tracked=foo
50+
print(x.foo) # $ tracked=foo tracked
51+
52+
# ------------------------------------------------------------------------------
3453
# Attributes assigned statically to a class
54+
# ------------------------------------------------------------------------------
3555

3656
class MyClass: # $tracked=field
3757
field = tracked # $tracked
@@ -40,7 +60,9 @@ class MyClass: # $tracked=field
4060
instance = MyClass() # $tracked=field
4161
lookup2 = instance.field # MISSING: tracked
4262

43-
## Dynamic attribute access
63+
# ------------------------------------------------------------------------------
64+
# Dynamic attribute access
65+
# ------------------------------------------------------------------------------
4466

4567
# Via `getattr`/`setattr`
4668

@@ -99,3 +121,41 @@ def dunder_dict_indirect_read():
99121
do_stuff(y) # $ MISSING: tracked
100122

101123

124+
# ------------------------------------------------------------------------------
125+
# Tracking of attribute on class instance
126+
# ------------------------------------------------------------------------------
127+
128+
# attribute set in method
129+
# inspired by https://github.com/github/codeql/pull/6023
130+
131+
class MyClass2(object):
132+
def __init__(self): # $ tracked=foo
133+
self.foo = tracked # $ tracked=foo tracked
134+
135+
def print_foo(self): # $ MISSING: tracked=foo
136+
print(self.foo) # $ MISSING: tracked=foo tracked
137+
138+
def possibly_uncalled_method(self): # $ MISSING: tracked=foo
139+
print(self.foo) # $ MISSING: tracked=foo tracked
140+
141+
instance = MyClass2()
142+
print(instance.foo) # $ MISSING: tracked=foo tracked
143+
instance.print_foo() # $ MISSING: tracked=foo
144+
145+
146+
# attribute set from outside of class
147+
148+
class MyClass3(object):
149+
def print_self(self): # $ tracked=foo
150+
print(self) # $ tracked=foo
151+
152+
def print_foo(self): # $ tracked=foo
153+
print(self.foo) # $ tracked=foo tracked
154+
155+
def possibly_uncalled_method(self): # $ MISSING: tracked=foo
156+
print(self.foo) # $ MISSING: tracked=foo tracked
157+
158+
instance = MyClass3() # $ tracked=foo
159+
instance.print_self() # $ tracked=foo
160+
instance.foo = tracked # $ tracked=foo tracked
161+
instance.print_foo() # $ tracked=foo

0 commit comments

Comments
 (0)