summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJimmy <jimmy@spalge.com>2022-04-16 13:49:49 +1200
committerJimmy <jimmy@spalge.com>2022-04-30 13:34:31 +1200
commite2785664c8ac9f6e055fd035ea4644a1e7071f67 (patch)
treeef953798c86038520241d12bcae9ef35a0ba0d50
parent557a8d4b66c7bc17927a706a8103392b87895494 (diff)
downloadqutebrowser-e2785664c8ac9f6e055fd035ea4644a1e7071f67.tar.gz
qutebrowser-e2785664c8ac9f6e055fd035ea4644a1e7071f67.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.py10
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: