Skip to content

Commit

Permalink
fix: don't confuse kwargs with symbol to codemod
Browse files Browse the repository at this point in the history
  • Loading branch information
browniebroke committed Jan 21, 2021
1 parent 506a107 commit f576347
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 25 deletions.
37 changes: 12 additions & 25 deletions django_codemod/visitors/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

from libcst import (
Arg,
Attribute,
BaseExpression,
BaseSmallStatement,
Call,
Expand Down Expand Up @@ -168,36 +167,24 @@ def leave_Call(self, original_node: Call, updated_node: Call) -> BaseExpression:
self.context.scratch.pop(self.ctx_key_is_name_called, None)
return super().leave_Call(original_node, updated_node)

@property
def ctx_key_is_name_in_attribute(self):
return f"{self.rename_from}-is_in_attribute"

@property
def entity_is_in_attribute(self):
return self.context.scratch.get(self.ctx_key_is_name_in_attribute, False)

def visit_Attribute(self, node: Attribute) -> Optional[bool]:
if self.is_imported_with_old_name and m.matches(
node, m.Attribute(attr=m.Name(self.old_name))
):
self.context.scratch[self.ctx_key_is_name_in_attribute] = True
return super().visit_Attribute(node)

def leave_Attribute(
self, original_node: Attribute, updated_node: Attribute
) -> BaseExpression:
self.context.scratch.pop(self.ctx_key_is_name_in_attribute, None)
return super().leave_Attribute(original_node, updated_node)

def leave_Name(self, original_node: Name, updated_node: Name) -> BaseExpression:
if (
self.is_imported_with_old_name
and not self.entity_is_name_called
and not self.entity_is_in_attribute
and m.matches(updated_node, m.Name(value=self.old_name))
and self.resolve_scope(original_node) == self.import_scope
):
return updated_node.with_changes(value=self.new_name)
try:
scope = self.resolve_scope(original_node)
except KeyError:
# Can't resolve scope of original_node, ignore it
# Might be because of one of these reasons:
# - It's the same name in another scope
# - It's a attribute with the same name
# - It's a keyword argument
pass
else:
if scope == self.import_scope:
return updated_node.with_changes(value=self.new_name)
return super().leave_Name(original_node, updated_node)


Expand Down
16 changes: 16 additions & 0 deletions tests/visitors/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,22 @@ def test_something():
"""
self.assertCodemod(before, after)

def test_kwargs(self) -> None:
"""When function is called with a kwargs bearing the same name."""
before = """
from django.dummy.module import func
func()
something(func="test")
"""
after = """
from django.dummy.module import better_func
better_func()
something(func="test")
"""
self.assertCodemod(before, after)


class OtherModuleFuncRenameTransformer(BaseFuncRenameTransformer):
"""Transformer with different module."""
Expand Down

0 comments on commit f576347

Please sign in to comment.