mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Python: CG trace: Fix sorting of ExternalCallee
Also exposed that the better_compare_for_dataclass was exposed to bad loop variable capture :|
This commit is contained in:
@@ -85,7 +85,7 @@ BUILTIN_FUNCTION_OR_METHOD = type(print)
|
|||||||
|
|
||||||
|
|
||||||
@better_compare_for_dataclass
|
@better_compare_for_dataclass
|
||||||
@dataclasses.dataclass(frozen=True, eq=True, order=True)
|
@dataclasses.dataclass(frozen=True, eq=True)
|
||||||
class ExternalCallee(Callee):
|
class ExternalCallee(Callee):
|
||||||
# Some bound methods might not have __module__ attribute: for example,
|
# Some bound methods might not have __module__ attribute: for example,
|
||||||
# `list().append.__module__ is None`
|
# `list().append.__module__ is None`
|
||||||
@@ -102,6 +102,35 @@ class ExternalCallee(Callee):
|
|||||||
is_builtin=type(func) == BUILTIN_FUNCTION_OR_METHOD,
|
is_builtin=type(func) == BUILTIN_FUNCTION_OR_METHOD,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def __lt__(self, other):
|
||||||
|
if not isinstance(other, ExternalCallee):
|
||||||
|
raise TypeError()
|
||||||
|
|
||||||
|
for field in dataclasses.fields(self):
|
||||||
|
s_a = getattr(self, field.name)
|
||||||
|
o_a = getattr(other, field.name)
|
||||||
|
|
||||||
|
# `None < None` gives TypeError
|
||||||
|
if s_a is None and o_a is None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if type(s_a) != type(o_a):
|
||||||
|
return type(s_a).__name__ < type(o_a).__name__
|
||||||
|
|
||||||
|
if not s_a < o_a:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def __gt__(self, other):
|
||||||
|
return other < self
|
||||||
|
|
||||||
|
def __ge__(self, other):
|
||||||
|
return self > other or self == other
|
||||||
|
|
||||||
|
def __le__(self, other):
|
||||||
|
return self < other or self == other
|
||||||
|
|
||||||
|
|
||||||
@better_compare_for_dataclass
|
@better_compare_for_dataclass
|
||||||
@dataclasses.dataclass(frozen=True, eq=True, order=True)
|
@dataclasses.dataclass(frozen=True, eq=True, order=True)
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ def better_compare_for_dataclass(cls):
|
|||||||
]:
|
]:
|
||||||
old = getattr(cls, op)
|
old = getattr(cls, op)
|
||||||
|
|
||||||
def new(self, other):
|
# Fix loop variable capture (py/loop-variable-capture)
|
||||||
|
def new(self, other, op=op, old=old):
|
||||||
if type(self) == type(other):
|
if type(self) == type(other):
|
||||||
return old(self, other)
|
return old(self, other)
|
||||||
return getattr(str, op)(self.__class__.__name__, other.__class__.__name__)
|
return getattr(str, op)(self.__class__.__name__, other.__class__.__name__)
|
||||||
|
|||||||
Reference in New Issue
Block a user