Convert Python qlref tests to inline expectations

This commit is contained in:
Owen Mansel-Chan
2026-06-15 11:06:48 +01:00
parent d6ade8fe95
commit 0c2df7c7e9
475 changed files with 1612 additions and 1382 deletions

View File

@@ -1 +1 @@
Statements/DocStrings.ql
query: Statements/DocStrings.ql

View File

@@ -1 +1,2 @@
Statements/ReturnOrYieldOutsideFunction.ql
query: Statements/ReturnOrYieldOutsideFunction.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -28,36 +28,36 @@ def valid_func3():
# invalid class with return outside a function
class InvalidClass1(object):
if [1, 2, 3]:
return "Exists"
return "Exists" # $ Alert
# invalid class with yield outside a function
class InvalidClass2(object):
while True:
yield 1
yield 1 # $ Alert
# invalid class with yield from outside a function
class InvalidClass3(object):
while True:
yield from [1, 2]
yield from [1, 2] # $ Alert
# invalid statement with return outside a function
for i in [1, 2, 3]:
return i
return i # $ Alert
# invalid statement with yield outside a function
for i in [1, 2, 3]:
yield i
yield i # $ Alert
# invalid statement with yield from outside a function
for i in [1, 2, 3]:
yield from i
yield from i # $ Alert
# invalid statement with yield from outside a function
var = [1,2,3]
yield from var
yield from var # $ Alert
# invalid statement with return outside a function
return False
return False # $ Alert
# invalid statement with yield outside a function
yield False
yield False # $ Alert

View File

@@ -1 +1,2 @@
Statements/AssertLiteralConstant.ql
query: Statements/AssertLiteralConstant.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1,2 @@
Statements/AssertOnTuple.ql
query: Statements/AssertOnTuple.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1,2 @@
Statements/SideEffectInAssert.ql
query: Statements/SideEffectInAssert.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -2,10 +2,10 @@ import sys
import six
def _f():
assert (yield 3)
assert (yield 3) # $ Alert[py/side-effect-in-assert]
x = [ 1 ]
assert len(x) #Call without side-effects
assert sys.exit(1) #Call with side-effects
assert sys.exit(1) # $ Alert[py/side-effect-in-assert] #Call with side-effects
expected_types = (Response, six.text_type, six.binary_type)
assert isinstance(obj, expected_types), \
"obj must be %s, not %s" % (
@@ -13,8 +13,8 @@ def _f():
type(obj).__name__)
def assert_tuple(x, y):
assert ()
assert (x, y)
assert () # $ Alert[py/asserts-tuple]
assert (x, y) # $ Alert[py/asserts-tuple]
@@ -31,31 +31,31 @@ def assert_tuple(x, y):
def error_assert_true(x):
if x:
assert True, "Bad"
assert True, "Bad" # $ Alert[py/assert-literal-constant]
else:
assert True
assert True # $ Alert[py/assert-literal-constant]
def error_assert_false(x):
if x:
assert False, "Bad"
assert False, "Bad" # $ Alert[py/assert-literal-constant]
def error_assert_zero(x):
if x:
assert 0, "Bad"
assert 0, "Bad" # $ Alert[py/assert-literal-constant]
def error_assert_one(x):
if x:
assert 1, "Bad"
assert 1, "Bad" # $ Alert[py/assert-literal-constant]
def error_assert_empty_string(x):
if x:
assert "", "Bad"
assert "", "Bad" # $ Alert[py/assert-literal-constant]
def error_assert_nonempty_string(x):
if x:
assert "X", "Bad"
assert "X", "Bad" # $ Alert[py/assert-literal-constant]
else:
assert "X"
assert "X" # $ Alert[py/assert-literal-constant]
def ok_assert_false(x):
if x:
@@ -91,7 +91,7 @@ def error_assert_in_final_branch1(x):
if foo(x):
pass
else:
assert False, "Error"
assert False, "Error" # $ Alert[py/assert-literal-constant]
def error_assert_in_intermediate_branch(x):
if foo(x):
@@ -99,7 +99,7 @@ def error_assert_in_intermediate_branch(x):
elif bar(x):
pass
elif quux(x):
assert False, "Error"
assert False, "Error" # $ Alert[py/assert-literal-constant]
elif yks(x):
pass
else:

View File

@@ -2,4 +2,4 @@
# messes up the results of the refers-to/points-to analysis
# see /home/rasmus/code/ql/python/ql/test/library-tests/PointsTo/regressions/subprocess-assert/mwe_failure.py
import subprocess
assert subprocess.call(['run-backup']) == 0
assert subprocess.call(['run-backup']) == 0 # $ Alert[py/side-effect-in-assert]

View File

@@ -1 +1,2 @@
Statements/UseOfExit.ql
query: Statements/UseOfExit.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -4,4 +4,4 @@ def main():
process()
except Exception as ex:
print(ex)
exit(1)
exit(1) # $ Alert

View File

@@ -1 +1,2 @@
Statements/BreakOrReturnInFinally.ql
query: Statements/BreakOrReturnInFinally.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1,2 @@
Statements/C_StyleParentheses.ql
query: Statements/C_StyleParentheses.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1,2 @@
Statements/ConstantInConditional.ql
query: Statements/ConstantInConditional.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1,2 @@
Statements/MismatchInMultipleAssignment.ql
query: Statements/MismatchInMultipleAssignment.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1,2 @@
Statements/ModificationOfLocals.ql
query: Statements/ModificationOfLocals.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1,2 @@
Statements/NestedLoopsSameVariable.ql
query: Statements/NestedLoopsSameVariable.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1,2 @@
Statements/NestedLoopsSameVariableWithReuse.ql
query: Statements/NestedLoopsSameVariableWithReuse.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1,2 @@
Statements/NonIteratorInForLoop.ql
query: Statements/NonIteratorInForLoop.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1,2 @@
Statements/RedundantAssignment.ql
query: Statements/RedundantAssignment.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1,2 @@
Statements/ShouldUseWithStatement.ql
query: Statements/ShouldUseWithStatement.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1,2 @@
Statements/StringConcatenationInLoop.ql
query: Statements/StringConcatenationInLoop.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1,2 @@
Statements/UnnecessaryDelete.ql
query: Statements/UnnecessaryDelete.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1,2 @@
Statements/UnnecessaryElseClause.ql
query: Statements/UnnecessaryElseClause.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1,2 @@
Statements/UnnecessaryPass.ql
query: Statements/UnnecessaryPass.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,6 +1,6 @@
def f1():
for repeated_var in range(10):
for repeated_var in range(10):
for repeated_var in range(10): # $ Alert[py/nested-loops-with-same-variable-reused] Alert[py/nested-loops-with-same-variable]
pass
do_something(repeated_var)
@@ -16,7 +16,7 @@ def f2():
def f3(y,p):
for x in y:
if p(y):
for x in y:
for x in y: # $ Alert[py/nested-loops-with-same-variable]
good1(x)
else:
good2(x)
@@ -24,7 +24,7 @@ def f3(y,p):
def f4(y):
for x in y:
good1(x)
for x in y:
for x in y: # $ Alert[py/nested-loops-with-same-variable-reused] Alert[py/nested-loops-with-same-variable]
good2(x)
bad(x)
@@ -32,14 +32,14 @@ def f5(y):
for x in y:
good1(x)
temp = x
for x in y:
for x in y: # $ Alert[py/nested-loops-with-same-variable]
good2(x)
x = temp
good3(x)
def f6(y, f):
for x in y:
for x in y:
for x in y: # $ Alert[py/nested-loops-with-same-variable]
good(x)
x = f(x)
bad(x)
@@ -47,7 +47,7 @@ def f6(y, f):
def f7(y,p):
for x in y:
good(x)
for x in y:
for x in y: # $ Alert[py/nested-loops-with-same-variable-reused] Alert[py/nested-loops-with-same-variable]
if p(x):
x = 1
break

View File

@@ -3,10 +3,10 @@
def y(seq):
y_accum = ''
for s in seq:
y_accum += s
y_accum += s # $ Alert[py/string-concatenation-in-loop]
def z(seq):
z_accum = ''
for s in seq:
z_accum = z_accum + s
z_accum = z_accum + s # $ Alert[py/string-concatenation-in-loop]

View File

@@ -2,11 +2,11 @@
#Constant in conditional
def cc1():
if True:
if True: # $ Alert[py/constant-conditional-expression]
print("Hi")
def cc2():
if 3:
if 3: # $ Alert[py/constant-conditional-expression]
print("Hi")
def not_cc():
@@ -16,7 +16,7 @@ def not_cc():
#Mismatch in multiple assignment
def mima():
x, y, z = 1, 2
x, y, z = 1, 2 # $ Alert[py/mismatched-multiple-assignment]
return x, y, z
#Statement has no effect (4 statements, 3 of which are violations)
@@ -51,10 +51,10 @@ ok = ok # Pyflakes
class Redundant(object):
x = x # OK
x = x # violation
x = x # $ Alert[py/redundant-assignment] # violation
def __init__(self, args):
args = args # violation
args = args # $ Alert[py/redundant-assignment] # violation
if sys.version_info < (3,):
bytes = str
@@ -62,12 +62,12 @@ else:
bytes = bytes # Should not be flagged
#Pointless else clauses
for x in range(10):
for x in range(10): # $ Alert[py/redundant-else]
func(x)
else:
do_something()
while x < 10:
while x < 10: # $ Alert[py/redundant-else]
func(x)
else:
do_something()
@@ -116,7 +116,7 @@ def maybe_property(x):
class WithoutProp(object):
def meth(self):
self.x = self.x
self.x = self.x # $ Alert[py/redundant-assignment]
#Accessing a property has an effect:
def prop_acc():
@@ -166,7 +166,7 @@ if False:
def error_mismatched_multi_assign_list():
a,b,c = [1,2,3,4,5]
a,b,c = [1,2,3,4,5] # $ Alert[py/mismatched-multiple-assignment]
def returning_different_tuple_sizes(x):
if x:
@@ -175,7 +175,7 @@ def returning_different_tuple_sizes(x):
return 1,2,3,4,5,6
def error_indirect_mismatched_multi_assign(x):
a, b, c = returning_different_tuple_sizes(x)
a, b, c = returning_different_tuple_sizes(x) # $ Alert[py/mismatched-multiple-assignment]
return a, b, c
@@ -184,7 +184,7 @@ def error_indirect_mismatched_multi_assign(x):
#ODASA-6754
def error_unnecessary_delete():
x = big_object()
del x
del x # $ Alert[py/unnecessary-delete]
def ok_delete_in_loop():
y = 0

View File

@@ -8,7 +8,7 @@ def break_in_finally(seq, x):
try:
x()
finally:
break
break # $ Alert[py/exit-from-finally]
return 0
def return_in_finally(seq, x):
@@ -16,7 +16,7 @@ def return_in_finally(seq, x):
try:
x()
finally:
return 1
return 1 # $ Alert[py/exit-from-finally]
return 0
#Break in loop in finally
@@ -34,11 +34,11 @@ def return_in_loop_in_finally(f, seq):
f()
finally:
for i in seq:
return
return # $ Alert[py/exit-from-finally]
def unnecessary_pass(arg):
print (arg)
pass
pass # $ Alert[py/unnecessary-pass]
#Non-iterator in for loop
@@ -47,7 +47,7 @@ class NonIterator(object):
def __init__(self):
pass
for x in NonIterator():
for x in NonIterator(): # $ Alert[py/non-iterable-in-for-loop]
do_something(x)
#None in for loop
@@ -95,12 +95,12 @@ for z in D():
def modification_of_locals():
x = 0
locals()['x'] = 1
locals()['x'] = 1 # $ Alert[py/modification-of-locals]
l = locals()
l.update({'x':1, 'y':2})
l.pop('y')
del l['x']
l.clear()
l.update({'x':1, 'y':2}) # $ Alert[py/modification-of-locals]
l.pop('y') # $ Alert[py/modification-of-locals]
del l['x'] # $ Alert[py/modification-of-locals]
l.clear() # $ Alert[py/modification-of-locals]
return x
@@ -112,16 +112,16 @@ locals()['foo'] = 43 # technically OK
#C-style things
if (cond):
if (cond): # $ Alert[py/c-style-parentheses]
pass
while (cond):
while (cond): # $ Alert[py/c-style-parentheses]
pass
assert (test)
assert (test) # $ Alert[py/c-style-parentheses]
def parens(x):
return (x)
return (x) # $ Alert[py/c-style-parentheses]
#ODASA-2038
@@ -165,7 +165,7 @@ def no_with():
f.write("Hello ")
f.write(" World\n")
finally:
f.close()
f.close() # $ Alert[py/should-use-with]
#Assert without side-effect
def assert_ok(seq):

View File

@@ -1 +1,2 @@
Statements/StatementNoEffect.ql
query: Statements/StatementNoEffect.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1,2 @@
Statements/UnusedExceptionObject.ql
query: Statements/UnusedExceptionObject.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -6,6 +6,6 @@ class T(unittest.TestCase):
l = 10
s = [0]
with self.assertRaises(TypeError):
l[1000]
l[1000] # $ Alert[py/ineffectual-statement]
with self.assertRaises(IndexError):
s[1]
s[1] # $ Alert[py/ineffectual-statement]

View File

@@ -21,9 +21,9 @@ import sys
#Statement has no effect (4 statements, 3 of which are violations)
"Not a docstring" # This is acceptable as strings can be used as comments.
len
sys.argv + []
3 == 4
len # $ Alert[py/ineffectual-statement]
sys.argv + [] # $ Alert[py/ineffectual-statement]
3 == 4 # $ Alert[py/ineffectual-statement]
#The 'sys' statements have an effect
try:
@@ -77,7 +77,7 @@ x.deco
x.deco + 2
#No effect
x.func
x.func # $ Alert[py/ineffectual-statement]
#Cannot infer what attribute is, so be conservative
x.thing
@@ -113,7 +113,7 @@ def possible_fps(x):
h = Horrible()
h + "innocent bystander"
h < "upstanding citizen"
x - 3 #True positive
x - 3 # $ Alert[py/ineffectual-statement] #True positive
# Forgotten raise.
@@ -124,7 +124,7 @@ def do_action_forgotten_raise(action):
elif action == "stop":
stop()
else:
ValueError(action)
ValueError(action) # $ Alert[py/unused-exception-object]
def do_action(action):
if action == "go":

View File

@@ -1 +1,2 @@
Statements/UnreachableCode.ql
query: Statements/UnreachableCode.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -5,27 +5,27 @@ def f(x):
while x:
print (x)
while 0:
asgn = unreachable()
asgn = unreachable() # $ Alert
while False:
return unreachable()
return unreachable() # $ Alert
while 7:
print(x)
def g(x):
if False:
unreachable()
unreachable() # $ Alert
else:
reachable()
print(x)
return 5
for x in first_unreachable_stmt():
for x in first_unreachable_stmt(): # $ Alert
raise more_unreachable()
def h(a,b):
if True:
reachable()
else:
unreachable()
unreachable() # $ Alert
def intish(n):
""""Regression test - the 'except' statement is reachable"""
@@ -81,7 +81,7 @@ class Odasa3686(object):
def odasa5387():
try:
str
except NameError: # Unreachable 'str' is always defined
except NameError: # $ Alert # Unreachable 'str' is always defined
pass
try:
unicode

View File

@@ -1 +1,2 @@
Statements/UnreachableCode.ql
query: Statements/UnreachableCode.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql