Skip to content

Conversation

@LeiWang1999
Copy link
Member

@LeiWang1999 LeiWang1999 commented Sep 9, 2025

Summary by CodeRabbit

  • New Features

    • None
  • Bug Fixes

    • Fixed an issue where state could persist between decorated functions, especially for methods defined in classes, causing inconsistent behavior. State is now reliably cleared to ensure isolated execution.
  • Refactor

    • Internal adjustments to improve reliability and prevent state leakage across function executions.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 9, 2025

Walkthrough

Adds nonlocal for outer_stack inside a decorator wrapper, clears outer_stack when functions are defined in a class and also unconditionally before parsing non-class functions, preserving TypeError for non-function inputs. Ensures outer_stack can be rebound and avoids leakage of stack state across decorated functions.

Changes

Cohort / File(s) Summary
Decorator stack handling
tilelang/language/tir/entry.py
Added nonlocal declaration for outer_stack. Set outer_stack = None when function is defined in a class and also unconditionally before parsing. Preserves TypeError behavior for non-function inputs. Ensures stack state is cleared and avoids rebinding issues.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor Dev as Developer
    participant Dec as decorator_wrapper
    participant Util as utils.is_defined_in_class
    participant Func as func
    note over Dec: nonlocal outer_stack

    Dev->>Dec: Call decorator on func
    Dec->>Dec: Validate input (TypeError if not function)
    Dec->>Util: Check if func defined in class
    alt Defined in class
        Dec->>Dec: outer_stack = None
        Dec-->>Dev: Return original func
    else Not defined in class
        Dec->>Dec: outer_stack = None
        Dec->>Dec: Parse/handle func with cleared stack
        Dec-->>Dev: Return wrapped func
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Pre-merge checks (1 warning, 2 inconclusive)

❌ Failed checks (1 warning, 2 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title Check ❓ Inconclusive The title refers to resolving a reference cycle, which aligns with the change of clearing the outer_stack to break cycles, but it is overly broad and does not specify which variable or function is affected, making it hard for a reviewer to immediately grasp the scope of the change. Consider updating the title to reference the specific component, for example “Break reference cycle in decorator_wrapper by clearing outer_stack,” so that the main change is immediately clear to anyone scanning the history.
Description Check ❓ Inconclusive The pull request description is currently empty and provides no context or details about the changes, which makes it difficult for reviewers to understand the motivation or the specifics of the implementation. Please add a description summarizing the change’s goals and implementation details, such as introducing a nonlocal declaration and clearing the outer_stack to prevent reference cycles in the decorator_wrapper.

Poem

I tidied the stack with a whisk of my paw,
Cleared every crumb to comply with the law.
Class-born or free, your frames are now clean,
No leaks in the burrow, no state in between.
Hop, set to None—then onward I gnaw! 🐇

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
		  - name: "Undocumented Breaking Changes"
			  mode: "warning"
			  instructions: |
				  Flag potential breaking changes that are not documented:
				  1. Identify changes to public APIs/exports, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints (including removed/renamed items and changes to types, required params, return values, defaults, or behavior).
				  2. Ignore purely internal/private changes (e.g., code not exported from package entry points or marked internal).
				  3. Verify documentation exists: a "Breaking Change" section in the PR description and updates to CHANGELOG.md.

Please share your feedback with us on this Discord post.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @LeiWang1999, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a potential memory management issue by resolving a reference cycle. This is achieved by explicitly clearing a non-local variable (outer_stack) within a decorator, ensuring that references are properly released and preventing memory leaks.

Highlights

  • Reference Cycle Resolution: Explicitly sets the outer_stack variable to None within the prim_func decorator's decorator_wrapper to break potential reference cycles and aid garbage collection.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions
Copy link

github-actions bot commented Sep 9, 2025

👋 Hi! Thank you for contributing to the TileLang project.

Please remember to run bash format.sh in the root directory of the project to ensure your changes are properly linted and formatted. This will help ensure your contribution passes the format check.

We appreciate you taking this step! Our team will review your contribution, and we look forward to your awesome work!

🚀

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses a potential reference cycle in the prim_func decorator by ensuring the outer_stack variable is cleared after use. The approach is functionally correct. My review includes a suggestion to refactor the implementation slightly to improve code clarity and remove redundancy, making the logic for clearing the stack reference more straightforward.

Comment on lines 44 to +47
if utils.is_defined_in_class(outer_stack, func):
outer_stack = None
return func
outer_stack = None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

While this correctly clears outer_stack to prevent reference cycles, the logic can be simplified to avoid setting outer_stack = None in two separate code paths. You can determine whether the function is defined in a class, clear outer_stack immediately after its use, and then return if necessary. This makes the code more concise and easier to follow.

Suggested change
if utils.is_defined_in_class(outer_stack, func):
outer_stack = None
return func
outer_stack = None
is_in_class = utils.is_defined_in_class(outer_stack, func)
outer_stack = None
if is_in_class:
return func

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tilelang/language/tir/entry.py (1)

36-39: Micro: consider lighter stack capture if compatible.

inspect.stack() is expensive and retains source context. If utils.is_defined_in_class doesn’t need context lines, inspect.stack(context=0) can reduce overhead and memory. Please verify utils.is_defined_in_class’s requirements before changing.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bcfc834 and 4639750.

📒 Files selected for processing (1)
  • tilelang/language/tir/entry.py (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: bot-task
🔇 Additional comments (1)
tilelang/language/tir/entry.py (1)

43-43: Good fix: nonlocal prevents UnboundLocalError and enables cleanup.

Declaring nonlocal outer_stack is necessary since you rebind outer_stack below. This prevents a local-scope shadowing bug and lets you clear the captured frames.

Comment on lines 41 to 48
if not inspect.isfunction(func):
raise TypeError(f"Expect a function, but got: {func}")
nonlocal outer_stack
if utils.is_defined_in_class(outer_stack, func):
outer_stack = None
return func
outer_stack = None
f = parse(func, utils.inspect_function_capture(func), check_well_formed=check_well_formed)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consolidate cleanup with try/finally; also clear on TypeError path.

Two explicit resets plus an early raise leave one path (TypeError) where the captured frames aren’t cleared. Use a single finally to guarantee cleanup across all branches and exceptions, and move nonlocal to the top.

Apply:

 def decorator_wrapper(func):
-        if not inspect.isfunction(func):
-            raise TypeError(f"Expect a function, but got: {func}")
-        nonlocal outer_stack
-        if utils.is_defined_in_class(outer_stack, func):
-            outer_stack = None
-            return func
-        outer_stack = None
-        f = parse(func, utils.inspect_function_capture(func), check_well_formed=check_well_formed)
-        setattr(f, "__name__", func.__name__)  # noqa: B010
-        return f
+        nonlocal outer_stack
+        if not inspect.isfunction(func):
+            outer_stack = None
+            raise TypeError(f"Expect a function, but got: {func}")
+        try:
+            if utils.is_defined_in_class(outer_stack, func):
+                return func
+            f = parse(func, utils.inspect_function_capture(func), check_well_formed=check_well_formed)
+            setattr(f, "__name__", func.__name__)  # noqa: B010
+            return f
+        finally:
+            outer_stack = None
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if not inspect.isfunction(func):
raise TypeError(f"Expect a function, but got: {func}")
nonlocal outer_stack
if utils.is_defined_in_class(outer_stack, func):
outer_stack = None
return func
outer_stack = None
f = parse(func, utils.inspect_function_capture(func), check_well_formed=check_well_formed)
def decorator_wrapper(func):
nonlocal outer_stack
if not inspect.isfunction(func):
outer_stack = None
raise TypeError(f"Expect a function, but got: {func}")
try:
if utils.is_defined_in_class(outer_stack, func):
return func
f = parse(
func,
utils.inspect_function_capture(func),
check_well_formed=check_well_formed,
)
setattr(f, "__name__", func.__name__) # noqa: B010
return f
finally:
outer_stack = None
🧰 Tools
🪛 Ruff (0.12.2)

42-42: Avoid specifying long messages outside the exception class

(TRY003)

🤖 Prompt for AI Agents
In tilelang/language/tir/entry.py around lines 41 to 48, the code currently
declares nonlocal and resets outer_stack in multiple places but raises TypeError
before clearing captured frames; move the nonlocal outer_stack declaration to
the top of the function block and refactor the logic to use a try/finally so
outer_stack is always reset to None in the finally clause (remove the duplicate
explicit resets and ensure the TypeError path also runs the finally cleanup);
maintain existing behavior of returning early when
utils.is_defined_in_class(...) is true and preserve raising the TypeError when
func is not a function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant