diff options
author | Jimmy <jimmy@spalge.com> | 2022-04-16 13:49:49 +1200 |
---|---|---|
committer | toofar <toofar@spalge.com> | 2022-06-26 13:15:18 +1200 |
commit | 46c53382aa594bd04e1c1b01e34187c11c34d694 (patch) | |
tree | d4d0728bf8753833030c7f4c71925211bedfa12d | |
parent | a798bd21f7192b35da97d1f73641646e6a83080d (diff) | |
download | qutebrowser-46c53382aa594bd04e1c1b01e34187c11c34d694.tar.gz qutebrowser-46c53382aa594bd04e1c1b01e34187c11c34d694.zip |
rename codemod: reset cache vars between modules
(From my LibCST fork e6b990836204b)
The rename codemod currently has a few variables cached on `self` which
are used to transfer information between different visitor methods.
For example one of the nodes being visited inside an import from
statement might cause the import to be skipped in `leave_Import` using
`self.bypass_import`.
Or in the test case below relevant seen imports are cached in
`self.scheduled_removals` so they can be given special attention in
`leave_Module`.
The lifecycles don't work out though as the transforms that codemods run
ass are only initialised once for a whole run. So stuff can leak between
modules. There is probably a better place for them, but this works for
now. I'm not sure if this is reproducable outside of this wildcard
rename support.
Here is an example:
1. Have a folder with two test files
==> context_test/1.py <==
from a.b import c
c.x.foo
==> context_test/2.py <==
from a.b.g import d
d.bar
2. Rename something from the first file
python3 -m libcst.tool codemod rename.RenameCommand context_test/ -j 1 --old_name=a.b.c.* --new_name=a.b:c.* --no-format ; head -n-0 context_test/*
3. Observe a removed import from the first file leaks into the second
==> context_test/1.py <==
from a.b import c
c.x.foo
==> context_test/2.py <==
from a.b.g import d
from a.b import c
d.bar
-rw-r--r-- | scripts/codemods/rename_pyqt.py | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/scripts/codemods/rename_pyqt.py b/scripts/codemods/rename_pyqt.py index ba20f4f54..e4cf82b0b 100644 --- a/scripts/codemods/rename_pyqt.py +++ b/scripts/codemods/rename_pyqt.py @@ -117,6 +117,13 @@ class RenameCommand(VisitorBasedCodemodCommand): # this so that we do not end up with two of the same import. self.bypass_import = False + def per_module_reset(self): + """Reset attributes that are cached on self.""" + # They should probably really be on self.context.scratch? + self.as_name = None + self.scheduled_removals = set() + self.bypass_import = False + def visit_Import(self, node: cst.Import) -> None: for import_alias in node.names: alias_name = get_full_name_for_node(import_alias.name) @@ -315,6 +322,9 @@ class RenameCommand(VisitorBasedCodemodCommand): return updated_node + def visit_Module(self, node: cst.Module) -> Optional[bool]: + self.per_module_reset() + def leave_Module( self, original_node: cst.Module, updated_node: cst.Module ) -> cst.Module: |