-
Notifications
You must be signed in to change notification settings - Fork 446
[BugFix] Fix ForwardRef usage in v2 frontend (#1619)
#1621
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…type_hints function
|
👋 Hi! Thank you for contributing to the TileLang project. Please remember to run We appreciate you taking this step! Our team will review your contribution, and we look forward to your awesome work! 🚀 |
📝 WalkthroughWalkthroughFixed ForwardRef construction in builder.py's get_type_hints function to handle Python version differences. For Python 3.10+, the module parameter is passed; for earlier versions, the is_argument parameter is used instead. Changes
Possibly related issues
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom Pre-merge Checks in the settings. ✨ Finishing touches
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. Comment |
There was a problem hiding this 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
🤖 Fix all issues with AI agents
In @tilelang/language/v2/builder.py:
- Around line 819-822: The version check around ForwardRef construction is too
conservative; change the conditional that currently gates ForwardRef(value,
module=func.__module__) to use the Python release that added the module
parameter (>= (3,9,7)) instead of >= (3,10), i.e. in the block that constructs
ForwardRef in builder.py replace the sys.version_info boundary so
ForwardRef(value, module=func.__module__) is used when sys.version_info >=
(3,9,7) and fall back to ForwardRef(value, is_argument=True) otherwise; keep
using func.__module__ for module context and retain the is_argument fallback for
older interpreters.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
tilelang/language/v2/builder.py
⏰ 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: Test for Python 3.12 with Metal (on macos-latest)
🔇 Additional comments (1)
tilelang/language/v2/builder.py (1)
5-5: LGTM!The
sysimport is necessary for the Python version check in theget_type_hintsfunction.
| if sys.version_info >= (3, 10): | ||
| value = ForwardRef(value, module=func.__module__) | ||
| else: | ||
| value = ForwardRef(value, is_argument=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
cd tilelang && head -n 850 language/v2/builder.py | tail -n 50Repository: tile-ai/tilelang
Length of output: 2072
🌐 Web query:
Python 3.10 typing.ForwardRef API changes is_argument module parameter
💡 Result:
Short answer: In Python 3.10 the typing.ForwardRef constructor expanded beyond the original single extra flag (is_argument) — it accepts a module parameter (and an is_class kwarg) so you can provide the module context used when resolving the forward reference. See the ForwardRef implementation and discussion/issue references. [1][2]
Sources
- CPython typing.py (ForwardRef implementation / signature). [1]
- Python issue discussion noting use of the module parameter for cross-module forward refs (issue46371). [2]
References
[1] CPython typing.py — ForwardRef implementation.
[2] bpo issue 46371 — discussion of ForwardRef and module parameter.
🌐 Web query:
Python 3.10 typing.ForwardRef signature is_argument parameter still exists
💡 Result:
Short answer: Yes — in Python 3.10 typing.ForwardRef accepted an is_argument parameter (ForwardRef(arg, is_argument=True)). This is how typing.get_type_hints in 3.10 converted string annotations to ForwardRef (and called _evaluate). See discussion and source excerpts showing ForwardRef(..., is_argument=...) and get_type_hints behavior. [1][2]
Note: the ForwardRef/_evaluate API has evolved in later CPython/PEP work (PEP 749 / annotationlib and changes around 3.13), so third‑party code that calls _evaluate directly may need adjustments for newer Python versions. [3][4]
Sources:
- StackOverflow explanation showing ForwardRef(..., is_argument=False) usage in Python 3.10. [1]
- Python issue discussion about inspect/get_type_hints and ForwardRef behavior in 3.10. [2]
- PEP 749 (annotationlib) describing replacement/evolution of typing.ForwardRef. [3]
- pydantic issue noting ForwardRef._evaluate signature changes in newer Python (example of API evolution). [4]
🌐 Web query:
Python 3.10 ForwardRef __init__ parameters module is_argument deprecated removed
💡 Result:
Short answer — status and history:
- The ForwardRef constructor gained a module keyword in the 3.9.7 series (so typing.ForwardRef(arg, is_argument=True, module=None, *, is_class=False) appears in the stdlib sources and typeshed). [1][2]
- The is_argument parameter continued to exist in 3.10 (it is used internally by typing._type_check / ForwardRef._evaluate). [2][3]
- More recently the typing/annotation machinery is being refactored (PEP 749 / related work): typing.ForwardRef behavior is being clarified, some internal methods/attributes are being moved/renamed or wrapped by new helpers (annotationlib.ForwardRef + typing.evaluate_forward_ref) and some internal APIs are being deprecated for future removal — this is why downstream projects are seeing changes and warnings. The PEP proposes keeping compatibility where practical but deprecating undocumented internals. [3]
If you need concrete compatibility guidance (exact signature in a specific CPython point release, or how to adapt code that passes is_argument/module to ForwardRef), tell me the Python patchlevel you care about (e.g., 3.10.0 vs 3.10.x) and I’ll cite the exact stdlib source for that release.
Sources:
[1] typeshed / typing.pyi (ForwardRef init notes).
[2] CPython typing.py source showing init with is_argument/module and _evaluate.
[3] PEP 749 / proposal discussing annotationlib and ForwardRef changes.
🌐 Web query:
ForwardRef module parameter Python 3.9 vs 3.10 behavior difference semantics
💡 Result:
Short summary — what changed between Python 3.9 and 3.10 for typing.ForwardRef
-
Evaluation behavior: Python 3.10 changed how ForwardRefs are evaluated (more recursive evaluation and different evaluation order), and code that relied on the 3.9 evaluation/caching order can see different/resolved types or name-conflicts across modules. This was reported as a user-visible behavioral change (evaluation order/caching differences) in the Python issue tracker. [1][2]
-
The module parameter: ForwardRef has an internal module parameter used to resolve cross‑module forward references. Some fixes in the typing machinery (and related issues) made explicit use of or reliance on that module parameter in 3.10-era fixes; but TypedDict/NamedTuple and some nested cases still had gaps and required additional handling. Several tracker discussions show using ForwardRef(..., module=...) as a workaround in some cross-module cases. [1][3]
-
API/signature changes used by downstream libs: the internal ForwardRef evaluation implementation gained additional arguments used for recursion-guarding in later 3.x releases (code paths and private helper signatures changed). That caused downstream libraries (e.g., pydantic) to need version-conditional code to call ForwardRef._evaluate with an extra recursive_guard parameter. [4]
Practical effects
- Some get_type_hints() calls that returned different results (or that relied on old caching/side-effects) will behave differently on 3.10+. Cross-module forward refs embedded inside other typing constructs (e.g., inside lists/unions/TypedDict) are a known fragile area and have multiple bug/PR threads. [1][2][3]
References
- ForwardRef/name-conflict and evaluation-order change discussion (issue showing 3.10 started recursive evaluation and caused cross-module name conflicts). [1]
- Discussion about ForwardRef/module parameter and cross-module resolution (tracker issues about TypedDict/NamedTuple and using module= as a workaround). [3]
- Pydantic GitHub issue showing _evaluate gained a recursive_guard parameter and how downstream code must adapt. [4]
- typing module docs (ForwardRef description). [5]
References (links):
[1] Python tracker — Issue 43646 (ForwardRef name conflict / evaluation changed in 3.10).
[2] Python tracker — Issue 46371 (discussion mentioning module parameter and cross-module ForwardRef resolution).
[3] Python tracker — Issue 46373 (TypedDict/NamedTuple cross-module ForwardRef evaluation limitations).
[4] pydantic issue: ForwardRef._evaluate recursive_guard signature differences and workarounds.
[5] Python docs — typing.ForwardRef.
🌐 Web query:
CPython typing.ForwardRef module parameter 3.9.7 3.10 implementation history
💡 Result:
Summary — history of typing.ForwardRef's module parameter
- ForwardRef became a public class in typing in Python 3.7 (documented as added in 3.7.4). [1][2]
- The ForwardRef init originally accepted (arg, is_argument=...) (no module parameter). Evidence: older CPython typing.py implementation (no module arg). [3]
- A module parameter was added to ForwardRef in the 3.9.7-era change; typeshed notes: "The module argument was added in Python 3.9.7." [4]
- The current/later CPython typing.py shows ForwardRef.init(self, arg, is_argument=True, module=None, *, is_class=False) (i.e. module present, plus other internal flags). [5]
- Related tracker discussion and issues (ForwardRef/module interactions when resolving cross-module and nested forward refs) document how the module field is used internally and why it matters for cross-module alias resolution. [6][7]
Sources
- Python typing docs / history (ForwardRef added in 3.7.4). [1][2]
- CPython typing.py (older version without module param). [3]
- typeshed typing.pyi (notes module argument added in 3.9.7). [4]
- CPython typing.py (current implementation showing module parameter in init). [5]
- Python issue tracker discussions about ForwardRef/module and cross-module resolution. [6][7]
References
[1] Python docs, typing — Support for type hints (ForwardRef added in 3.7.4).
[2] Python 3.10/3.11 typing docs (ForwardRef class description).
[3] CPython typing.py (older commit / implementation without module parameter).
[4] typeshed typing.pyi comment: "The module argument was added in Python 3.9.7."
[5] CPython typing.py (implementation with init(..., module=None, *, is_class=False)).
[6] bpo issue 46371 / 46373 (ForwardRef cross-module/type-alias resolution discussions).
[7] bpo issue 43646 / 42904 (ForwardRef evaluation behavior across versions).
If you want, I can fetch the exact CPython commit hashes and show the diff that introduced the module parameter (with dates and PR/commit links).
🏁 Script executed:
fd -t f '(setup.py|pyproject.toml|setup.cfg|README.md)' --maxdepth 2Repository: tile-ai/tilelang
Length of output: 116
🏁 Script executed:
cd tilelang && head -n 30 pyproject.toml 2>/dev/null || head -n 30 setup.py 2>/dev/null || cat README.md 2>/dev/null | head -n 50Repository: tile-ai/tilelang
Length of output: 42
🏁 Script executed:
cat pyproject.toml | head -n 50Repository: tile-ai/tilelang
Length of output: 1827
The version-dependent ForwardRef construction works correctly, but the API history explanation needs correction.
The module parameter was added in Python 3.9.7 (not 3.10), and is_argument was never deprecated—both parameters coexist in Python 3.10+. The version boundary of >= (3, 10) is therefore more conservative than strictly necessary given the project's Python >= 3.9 requirement. That said, the code implementation is sound and will function correctly across all supported versions. Using func.__module__ appropriately provides module context for type resolution.
🤖 Prompt for AI Agents
In @tilelang/language/v2/builder.py around lines 819 - 822, The version check
around ForwardRef construction is too conservative; change the conditional that
currently gates ForwardRef(value, module=func.__module__) to use the Python
release that added the module parameter (>= (3,9,7)) instead of >= (3,10), i.e.
in the block that constructs ForwardRef in builder.py replace the
sys.version_info boundary so ForwardRef(value, module=func.__module__) is used
when sys.version_info >= (3,9,7) and fall back to ForwardRef(value,
is_argument=True) otherwise; keep using func.__module__ for module context and
retain the is_argument fallback for older interpreters.
This pr fix the usage of
ForwardReffor better compatibilitySummary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.