Files
codeql/python/ql/test/query-tests/Variables/unused/variables_test.py
Taus 301ebcb12b Python: Extend test cases for "unused global var" query
Adds two test cases having to do with type annotations. The first one
demonstrates that type annotations (even if they are never executed by
the Python interpreter) count as uses for the purposes of the unused
variable query. The second one demonstrates that this is _not_ the case
if all such uses are inside strings (i.e. forward declarations), as we
do not currently inspect the content of these strings.
2025-03-04 13:52:31 +00:00

158 lines
2.2 KiB
Python

__all__ = [ 'is_used_var1' ]
__author__ = "Mark"
__hidden_marker = False
#Unused parameter, local and global
def u1(x):
return 0
def u2():
x = 1
return 1
#These parameters are OK due to (potential overriding)
class C(object):
@abstractmethod
def ok2(self, p):
pass
def ok3(self, arg):
pass
class D(C):
def ok3(self, arg):
pass
#Unused module variable
not_used_var1 = 17
not_used_var2 = 18
is_used_var1 = 19
is_used_var2 = 20
def func():
return is_used_var2
#Redundant global declaration
global g_x
g_x = 0
#Use global
def uses_global(arg):
global g_x
g_x = arg
use(g_x)
#Unused but with acceptable names
unused_var3 = g_x
#Use at least one element of the tuple
_a, _b, c = t
use(c)
def f(t):
_a, _b, c = t
use(c)
# Entirely unused tuple
a,b,c = t
def f(t):
a,b,c = t
use(t)
def second_def_undefined():
var = 0
use(var)
var = 1 # unused.
#And gloablly
glob_var = 0
use(glob_var)
glob_var = 1 # unused
#OK if marked as unused:
def ok_unused(unused_1):
unused_2 = 1
return 0
#Decorators count as a use:
@compound.decorator()
def _unused_but_decorated():
pass
def decorated_inner_function():
@flasklike.routing("/route")
def end_point():
pass
@complex.decorator("x")
class C(object):
pass
return 0
#FP observed
def test_dict_unpacking(queryset, field_name, value):
#True positive
for tag in value.split(','):
queryset = queryset.filter(**{field_name + '__name': tag1})
return queryset
#False positive
for tag in value.split(','):
queryset = queryset.filter(**{field_name + '__name': tag})
return queryset
from typing import TYPE_CHECKING
if TYPE_CHECKING:
ParamAnnotation = int
ReturnAnnotation = int
AssignmentAnnotation = int
ForwardParamAnnotation = int
ForwardReturnAnnotation = int
ForwardAssignmentAnnotation = int
def test_direct_annotation(x: ParamAnnotation) -> ReturnAnnotation:
if x:
y : AssignmentAnnotation = 1
def test_forward_annotation(x: "ForwardParamAnnotation") -> "ForwardReturnAnnotation":
if x:
y : "ForwardAssignmentAnnotation" = 1