Skip to content

Commit c1b8029

Browse files
authored
Merge pull request #1867 from codeflash-ai/codeflash/optimize-pr1860-2026-03-18T10.39.52
⚡️ Speed up method `InitDecorator.visit_ClassDef` by 10% in PR #1860 (`fix/attrs-init-instrumentation`)
2 parents 46016bd + 5a795be commit c1b8029

File tree

1 file changed

+10
-19
lines changed

1 file changed

+10
-19
lines changed

codeflash/languages/python/instrument_codeflash_capture.py

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@ def visit_ClassDef(self, node: ast.ClassDef) -> ast.ClassDef:
198198
item.decorator_list.insert(0, decorator)
199199
self.inserted_decorator = True
200200

201+
break
202+
201203
if not has_init:
202204
# Skip dataclasses — their __init__ is auto-generated at class creation time and isn't in the AST.
203205
# The synthetic __init__ with super().__init__(*args, **kwargs) overrides it and fails because
@@ -208,25 +210,6 @@ def visit_ClassDef(self, node: ast.ClassDef) -> ast.ClassDef:
208210
dec_name = self._expr_name(dec)
209211
if dec_name is not None and dec_name.endswith("dataclass"):
210212
return node
211-
212-
# Skip NamedTuples — their __init__ is synthesized and cannot be overwritten.
213-
for base in node.bases:
214-
base_name = self._expr_name(base)
215-
if base_name is not None and base_name.endswith("NamedTuple"):
216-
return node
217-
218-
# Attrs classes — their __init__ is auto-generated by the decorator at class creation
219-
# time. With slots=True (the default for @attrs.define), attrs creates a brand-new class
220-
# object, so the __class__ cell baked into a synthesised
221-
# `super().__init__(*args, **kwargs)` still refers to the *original* class while `self`
222-
# is already an instance of the *new* slots class, causing a TypeError.
223-
# We therefore skip modifying the class body and instead emit a module-level
224-
# monkey-patch block after the class (handled in visit_Module):
225-
# _codeflash_orig_ClassName_init = ClassName.__init__
226-
# def _codeflash_patched_ClassName_init(self, *a, **kw): ...
227-
# ClassName.__init__ = codeflash_capture(...)(_codeflash_patched_ClassName_init)
228-
for dec in node.decorator_list:
229-
dec_name = self._expr_name(dec)
230213
if dec_name is not None:
231214
parts = dec_name.split(".")
232215
if len(parts) >= 2 and parts[-2] in _ATTRS_NAMESPACES and parts[-1] in _ATTRS_DECORATOR_NAMES:
@@ -238,6 +221,14 @@ def visit_ClassDef(self, node: ast.ClassDef) -> ast.ClassDef:
238221
self.inserted_decorator = True
239222
return node
240223

224+
# Create super().__init__(*args, **kwargs) call (use prebuilt AST fragments)
225+
226+
# Skip NamedTuples — their __init__ is synthesized and cannot be overwritten.
227+
for base in node.bases:
228+
base_name = self._expr_name(base)
229+
if base_name is not None and base_name.endswith("NamedTuple"):
230+
return node
231+
241232
# Create super().__init__(*args, **kwargs) call (use prebuilt AST fragments)
242233
super_call = self._super_call_expr
243234
# Create the complete function using prebuilt arguments/body but attach the class-specific decorator

0 commit comments

Comments
 (0)