Skip to content

Commit 5d031d7

Browse files
committed
Python: CG trace: Fix sorting of ExternalCallee
Also exposed that the better_compare_for_dataclass was exposed to bad loop variable capture :|
1 parent da518ed commit 5d031d7

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

python/tools/recorded-call-graph-metrics/src/cg_trace/tracer.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class Callee:
8585

8686

8787
@better_compare_for_dataclass
88-
@dataclasses.dataclass(frozen=True, eq=True, order=True)
88+
@dataclasses.dataclass(frozen=True, eq=True)
8989
class ExternalCallee(Callee):
9090
# Some bound methods might not have __module__ attribute: for example,
9191
# `list().append.__module__ is None`
@@ -102,6 +102,35 @@ def from_arg(cls, func):
102102
is_builtin=type(func) == BUILTIN_FUNCTION_OR_METHOD,
103103
)
104104

105+
def __lt__(self, other):
106+
if not isinstance(other, ExternalCallee):
107+
raise TypeError()
108+
109+
for field in dataclasses.fields(self):
110+
s_a = getattr(self, field.name)
111+
o_a = getattr(other, field.name)
112+
113+
# `None < None` gives TypeError
114+
if s_a is None and o_a is None:
115+
return False
116+
117+
if type(s_a) != type(o_a):
118+
return type(s_a).__name__ < type(o_a).__name__
119+
120+
if not s_a < o_a:
121+
return False
122+
123+
return True
124+
125+
def __gt__(self, other):
126+
return other < self
127+
128+
def __ge__(self, other):
129+
return self > other or self == other
130+
131+
def __le__(self, other):
132+
return self < other or self == other
133+
105134

106135
@better_compare_for_dataclass
107136
@dataclasses.dataclass(frozen=True, eq=True, order=True)

python/tools/recorded-call-graph-metrics/src/cg_trace/utils.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ def better_compare_for_dataclass(cls):
1111
]:
1212
old = getattr(cls, op)
1313

14-
def new(self, other):
14+
# Fix loop variable capture (py/loop-variable-capture)
15+
def new(self, other, op=op, old=old):
1516
if type(self) == type(other):
1617
return old(self, other)
1718
return getattr(str, op)(self.__class__.__name__, other.__class__.__name__)

0 commit comments

Comments
 (0)