Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
dc0846f
TypeVar: First initial version with testing
FrancescoPezzella Aug 26, 2026
071c107
TypeVar: Expanded upon the TypeVars - TypeVar/ParamSpec/TypeVarTuple.…
FrancescoPezzella Aug 26, 2026
9472012
TypeVar: Added type checking and fixed as many linter problems that c…
FrancescoPezzella Aug 26, 2026
cd03dde
Fixed a TODO bug with Snake_Case, file names with 2+ words were not c…
FrancescoPezzella Aug 27, 2026
6a18c4a
Extended TypeVarCheck to fully modernize TypeVar/ParamSpec/TypeVarTup…
FrancescoPezzella Aug 28, 2026
5022ad7
Fixed ASTNode.node being untyped (pyright inferred it as always None,…
FrancescoPezzella Aug 28, 2026
9a6d387
Fixed docs to pass the docs-quality CI (pymarkdown scan): wrapped par…
FrancescoPezzella Aug 28, 2026
f658b0c
Added a Python-version gate to TypeVarCheck (PEP 695 conversion only …
FrancescoPezzella Aug 28, 2026
b5de315
Fixed PythonRstNode crashing and silently dropping part of the AST wh…
FrancescoPezzella Aug 31, 2026
869936b
Extracted type_var_domain.py (TypeVar/ParamSpec/TypeVarTuple domain m…
FrancescoPezzella Aug 31, 2026
36f3024
Fixed the 6 pyright strict findings in type_var_check.py/type_var_dom…
FrancescoPezzella Aug 31, 2026
3723270
Fix silent corruption when two rewrites target the same node (ast_rew…
FrancescoPezzella Aug 31, 2026
b80799c
Fix silent corruption when two rewrites target the same node (ast_rew…
FrancescoPezzella Aug 31, 2026
0422319
Fix TypeVarCheck corrupting or losing code during PEP 695 conversion
FrancescoPezzella Sep 1, 2026
6794b3c
Ruff: Fixed and enabled (W)hitespace rule
FrancescoPezzella Sep 1, 2026
12fe2ba
Ruff: Enabled all unsafe fixes from other rules
FrancescoPezzella Sep 1, 2026
6dd4f82
Fixed ruff releated formatting issues
FrancescoPezzella Sep 1, 2026
78b50fe
Fix 2
FrancescoPezzella Sep 2, 2026
fafbf6d
Applied ruff fixes
FrancescoPezzella Sep 2, 2026
7b678aa
Ruff fixes
FrancescoPezzella Sep 7, 2026
2bcce74
Add migration-type-recipes.py CLI for TypeVarCheck
FrancescoPezzella Sep 8, 2026
1455db5
CLI - both typevar and typevartuplecheck integrated
FrancescoPezzella Sep 8, 2026
cb67ab2
CLI documentation
FrancescoPezzella Sep 8, 2026
ec7c59c
Add Step/run_steps, refactor TypeVarCheck.check() to use it
FrancescoPezzella Sep 9, 2026
41d1750
Removed dead code (which became irrelevant some ago), cleaned up some…
FrancescoPezzella Sep 9, 2026
d9aad59
Delegate unused-import cleanup to ruff F401 (CLI will call Ruff, no n…
FrancescoPezzella Sep 9, 2026
1f28fb6
Rewrite CLI: remove dry-run (issues, easier to remove, git diff alrea…
FrancescoPezzella Sep 9, 2026
67b174b
Updated and cleaned up notes
FrancescoPezzella Sep 9, 2026
e77a219
Small fixes for something that would will be removed soon anyways
FrancescoPezzella Sep 9, 2026
a046db0
Marked two tests as failing due to an earlier fix
FrancescoPezzella Sep 10, 2026
d17e7d2
Quote TYPE_CHECKING-only annotation, scope UP037 noqa to one line
FrancescoPezzella Sep 10, 2026
2dcd29e
Ruff unsafe fix
FrancescoPezzella Sep 11, 2026
a2937d1
Updated outdated documentation
FrancescoPezzella Sep 11, 2026
277b04a
'--review' now gives more information to the user regarding Type reci…
FrancescoPezzella Sep 11, 2026
4bc9b2c
Removed code duplication, fixed incorrect paths to files (before refa…
FrancescoPezzella Sep 11, 2026
bd91410
Fixed a bug with the correct Python version not being identified by t…
FrancescoPezzella Sep 11, 2026
88d5016
Fix broken test
FrancescoPezzella Sep 11, 2026
a41f9a9
Updated outdated Docs - removed references to deleted Python Kind Map
FrancescoPezzella Sep 14, 2026
be16420
New bug documented
FrancescoPezzella Sep 14, 2026
80d270f
Added feedback when processing each file with the Migration tool.
FrancescoPezzella Sep 14, 2026
9f8659e
Updated python-ast doc
FrancescoPezzella Sep 14, 2026
d6b40d4
Updated doc
FrancescoPezzella Sep 14, 2026
8963fa4
Updated doc 2x
FrancescoPezzella Sep 14, 2026
97b046d
docs- removed everything that has been handled by other PRs, issues o…
FrancescoPezzella Sep 15, 2026
4cee1fd
Fix
FrancescoPezzella Sep 15, 2026
719e77e
Forced UTF until becomes Py 3.15 default
FrancescoPezzella Sep 16, 2026
65323a4
New test, and cleaned up some old comments for tests
FrancescoPezzella Sep 17, 2026
d81ef34
typevar modernization - doc on HOW to fix unsafe-fixes manually
FrancescoPezzella Sep 18, 2026
7627cd5
Deleted incorrect files added during the rebase
FrancescoPezzella Sep 21, 2026
f0803a5
Rebase mistakes-
FrancescoPezzella Sep 21, 2026
8a6411c
Last rebase mistake
FrancescoPezzella Sep 21, 2026
7f4d0ca
Add missing docstrings, reword existing ones, add missing import
FrancescoPezzella Sep 21, 2026
a8cb126
TypeVar issues
FrancescoPezzella Sep 21, 2026
661e458
Add project-wide import safety to TypeVar localization
FrancescoPezzella Sep 22, 2026
8dccfb4
Add missing docstrings to TypingRecipe related tests
FrancescoPezzella Sep 23, 2026
1788be0
New test that shows a fault in the CLI
FrancescoPezzella Sep 23, 2026
2bfb53d
Fix project_root wiring and relative paths in TypeVar import safety
FrancescoPezzella Sep 23, 2026
4e93c6e
Clean up comments and doc strings
FrancescoPezzella Sep 23, 2026
93c6fac
Doc update
FrancescoPezzella Sep 23, 2026
42b715c
Add TODOs to migration tool
FrancescoPezzella Sep 23, 2026
a08cbba
Access TypeVars as model attributes
FrancescoPezzella Sep 23, 2026
96561a1
Adjust CLI message and resolve path
FrancescoPezzella Sep 23, 2026
5eae385
Fix outdated references
FrancescoPezzella Sep 23, 2026
adf3f06
Cleaner docstring
FrancescoPezzella Sep 24, 2026
6fd41c2
merging main
FrancescoPezzella Sep 24, 2026
b6b4f5b
Add TODO to a workaround that should be replaced by NodeProtocol, onc…
FrancescoPezzella Sep 24, 2026
c08e277
Tool no longer looks for a Python Version in the project: was suspect…
FrancescoPezzella Sep 24, 2026
c647ffd
Update outdated typevar/recipe doc
FrancescoPezzella Sep 24, 2026
e452013
Removed failing test: CI/CD uses Linux environment (which is UTF-8 by…
FrancescoPezzella Sep 24, 2026
90c016d
Added an optional cmd for the user to not run Ruff with --no-ruff. Th…
FrancescoPezzella Sep 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions docs/TODO
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

## Documentation gaps: action points for docs

### Stub pages that need content
Expand Down Expand Up @@ -35,9 +34,8 @@

15. **Scoping: skip and filter at the file level** (add to strategy-composition.md or a new page) — Java's `skipATU`, `globalFilter`, `sourceFilePostfixes`, and `sourceFileDirectories` provide coarse-grained scoping before any pattern matching runs. The Python equivalent concept needs documentation.


### New pages worth adding

19. **Common parser problems** (new page, e.g., `docs/developer/modules/parser-known-limitations.md`) — Java has CommonCdtParsingProblems.md listing concrete CDT/MSVC-extension parsing failures with workarounds. A Python equivalent covering known tree-sitter, libcst, clang binding, and ANTLR limitations would be directly useful.
19. **Common parser problems** (new page, e.g., `docs/developer/modules/common-parser-problems.md`) — Java has CommonCdtParsingProblems.md listing concrete CDT/MSVC-extension parsing failures with workarounds. A Python equivalent covering known tree-sitter, libcst, clang binding, and ANTLR limitations would be directly useful.

20. **Related works and context** (new section in index.md or index.md) — The Java UserGuide.md relates the tool to WHARS and ADA tooling. Adding a "related works" section that situates Renaissance-Experiments relative to the Java version, comby, and other code transformation tools would help new contributors understand design choices.
20. **Related works and context** (new section in index.md or index.md) — The Java UserGuide.md relates the tool to WHARS and ADA tooling. Adding a "related works" section that situates Renaissance-Experiments relative to the Java version, comby, and other code transformation tools would help new contributors understand design choices.
18 changes: 18 additions & 0 deletions docs/developer/feature-test-map/core.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,21 @@
- **BDD feature file:** `features/rewrite-semantics.feature`
- **BDD steps:** `features/steps/test-rewrite-semantics.py`
- **Code files:** `src/renaissance/common/rewriter.py`, `src/renaissance/syntax_tree/ast_rewriter.py`

## 3. TypeVar modernization

- **Feature:** [TypeVar modernization](../../user/features/typevar-modernization.md)
- **Concepts:** [Type parameter scope](../../user/concepts/type-parameter-scope.md)
- **Code modules:** [Refactoring recipes](../../developer/modules/recipes.md)
- **Test file(s):**
- `test/recipes/test_type_var_check.py`
- `test/recipes/test_type_var_check_convert.py`
- `test/recipes/test_type_var_check_localize.py`
- `test/recipes/test_type_var_check_orphaned.py`
- `test/recipes/test_type_var_check_properties.py`
- `test/recipes/test_type_var_tuple_check.py`
- `test/recipes/test_type_var_tuple_check_fix.py`
- `test/recipes/test_type_var_tuple_check_properties.py`
- `test/recipes/test_type_var_domain.py`
- **Code file(s):** `src/renaissance/recipes/type_var_check.py`, `src/renaissance/recipes/type_var_tuple_check.py`,
`src/renaissance/recipes/type_var_domain.py`
2 changes: 2 additions & 0 deletions docs/developer/modules/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@
5. [Transformation modules](transformation.md)
6. [Observability modules](observability.md)
7. [Strategy modules](strategy.md)
8. [Refactoring recipes](recipes.md)
9. [Python AST known limitations](python-ast-known-limitations.md)
59 changes: 59 additions & 0 deletions docs/developer/modules/python-ast-known-limitations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Python AST known limitations

{ #codemod-python-ast-known-limitations }

**Stable ID:** `CODEMOD-PYTHON_AST_KNOWN_LIMITATIONS`

Concrete limitations found in the Python AST/RST layer (`renaissance.integrations.python.ast`) and the rewrite mechanism it
feeds (`renaissance.syntax_tree.ast_rewriter`, `renaissance.utils.text_utils`) while building recipes
(`TypeVarCheck`, `TypeVarTupleCheck`), that have no other tracker (no fix, no TODO, no test) anywhere in the
codebase. Anything already tracked by a code comment, an `xfail` test, or a fix already merged/sitting on a branch
lives there instead of being duplicated here - a recipe still has to work around both items below.

## 1. `ast.unparse()`/`shift_right` lose comments and indentation

`TextUtils.shift_right`/`shift_left` (`renaissance/utils/text_utils.py`) are pure text operations with no notion of
Python syntax - they shift every line in a range unconditionally, blind to whether a line sits inside a string
literal. `ast.unparse()` already reproduces a docstring's continuation lines verbatim (it's the only multi-line
string constant it emits as a real multi-line literal), so a whole-function/class/module replacement built from
it shifts those already-correctly-indented lines a second time. Separately, regenerating a function's entire body
from the AST also reformats it to `ast.unparse()`'s own style regardless of the original formatting, and -
permanently, since Python's `ast` module never records comments at all - **deletes every comment inside the
body**; there is nothing for `ast.unparse()` to reproduce, and no future fix to this framework can change that
without Python itself changing. Both are real for any recipe that regenerates a whole node's source via
`ast.unparse()` and replaces the original text with it wholesale.

**`TypeVarCheck` avoids this, it doesn't fix it** - see [Refactoring recipes](../../developer/modules/recipes.md)
for how `unparse_signature_only` splices only the new `[T]`/`[**P]`/`[*Ts]` bracket into the function's original
text instead of regenerating anything via `ast.unparse()`.

A future recipe that genuinely needs to regenerate a whole body from the AST - not just a signature - still hits
both issues above and has to work around them itself; neither `ast.unparse()`'s comment blindness nor
`shift_right`/`shift_left`'s string-literal blindness was touched here.

## 2. `__is_ancestor_in_nodes` can't just drop its `and False`

`_RewriteActions.__is_ancestor_in_nodes` (`renaissance/syntax_tree/ast_rewriter.py`) is meant to detect when a
queued rewrite is nested inside another queued rewrite's node, so `apply()` can skip the redundant nested one and
let the outer (ancestor) rewrite silently dominate it - but it ends with `return result and False`, which is
always `False` regardless of `result`. The dominance/suppression check never fires: an ancestor replacement and a
nested descendant edit queued in the same batch both get applied instead of the descendant being suppressed. The
one-line in-code `# TODO` at that `return` doesn't capture why this isn't a one-line fix, so it's spelled out here
instead.

**Why the obvious one-line fix doesn't work:** simply changing `return result and False` to `return result`
does not enable the suppression correctly. `no_conflict(node, rew)` returns `True` for `node is rew` (a node
trivially "overlaps" itself), and `rewrite_nodes` is built by flattening every rewrite in `self.rewrites` - the
same collection `apply()` draws `n` from when it calls `__is_ancestor_in_nodes(n)`. So `result` is a near-total
tautology: `True` for almost any node, since it always includes a self-comparison. Dropping `and False` would
make `__is_ancestor_in_nodes` return `True` for nearly every queued node - including nodes that have no real
ancestor/descendant relationship to anything else - so `apply()`'s `continue` would skip most rewrites, not
just the dominated ones, breaking the majority of currently-passing scenarios rather than fixing the handful that
are `xfail`. A real fix needs to exclude a node's own rewrite from the comparison set and use a genuine
ancestor/descendant check - e.g. reusing `__is_nested` (already used by `__check_for_conflicting_rewrites`, the
sibling check that turns a *different* kind of overlapping-rewrite bug into a clear `ValueError` instead of
corrupting output) - instead of repairing `no_conflict`'s offset-overlap test.

`TypeVarCheck` avoids triggering this gap by construction - see [Refactoring recipes](../../developer/modules/recipes.md)
for how `convert_declared_typevars` collects every touched function and queues exactly one edit per node, never a
second rewrite on the same node.
Loading
Loading