Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- #623, #819, #863 Support MatchOr, MatchSequence, MatchStar (@jheld, @lieryan)
- #870 Add default implementation for is_dir() (@lieryan)
- #872 Fix unicode handling in patchedast (@lieryan)
- #862 Recognize type alias statements as assignments in rename refactoring (@TanbirRamim)

# Release 1.14.0

Expand Down
9 changes: 9 additions & 0 deletions rope/base/pyobjectsdef.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,12 @@ def _Assign(self, node):
self.visit(child_node)
_ExpressionVisitor(self.scope_visitor).visit(node.value)

def _TypeAlias(self, node):
# the alias value is not recorded as an assigned value: a type
# alias is a distinct TypeAliasType object whose value is evaluated
# lazily, so substituting the value for the alias name is unsafe
self.visit(node.name)

def _assigned(self, name, assignment=None):
self.scope_visitor._assigned(name, assignment)

Expand Down Expand Up @@ -451,6 +457,9 @@ def _Assign(self, node):
def _AnnAssign(self, node):
_AnnAssignVisitor(self).visit(node)

def _TypeAlias(self, node):
_AssignVisitor(self).visit(node)

def _AugAssign(self, node):
pass

Expand Down
31 changes: 31 additions & 0 deletions ropetest/refactor/inlinetest.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,37 @@ def test_empty_case(self):
refactored = self._inline(code, code.index("a_var") + 1)
self.assertEqual("", refactored)

@testutils.only_for_versions_higher("3.12")
def test_inlining_type_alias_is_refused(self):
code = dedent("""\
type an_alias = int
value = an_alias.__value__
""")
with self.assertRaises(rope.base.exceptions.RefactoringError):
self._inline(code, code.index("an_alias") + 1)

@testutils.only_for_versions_higher("3.12")
def test_inlining_lazily_evaluated_type_alias_is_refused(self):
code = dedent("""\
type an_alias = Later
def a_func(param: an_alias):
pass
class Later:
pass
""")
with self.assertRaises(rope.base.exceptions.RefactoringError):
self._inline(code, code.index("an_alias") + 1)

@testutils.only_for_versions_higher("3.12")
def test_inlining_generic_type_alias(self):
code = dedent("""\
type an_alias[T] = list[T]
def a_func(param: an_alias[int]):
pass
""")
with self.assertRaises(rope.base.exceptions.RefactoringError):
self._inline(code, code.index("an_alias") + 1)

def test_long_definition(self):
code = dedent("""\
a_var = 10 + (10 + 10)
Expand Down
68 changes: 68 additions & 0 deletions ropetest/refactor/renametest.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,74 @@ def test_renaming_inline_assignment(self):
refactored,
)

@testutils.only_for_versions_higher("3.12")
def test_renaming_type_alias(self):
code = dedent("""\
type old_name = int
x: old_name = 1
""")
refactored = self._local_rename(code, code.index("old_name") + 1, "new_name")
self.assertEqual(
dedent("""\
type new_name = int
x: new_name = 1
"""),
refactored,
)

@testutils.only_for_versions_higher("3.12")
def test_renaming_type_alias_from_its_usage(self):
code = dedent("""\
type old_name = int
def a_func(param: old_name) -> old_name:
pass
""")
offset = code.rindex("old_name") + 1
refactored = self._local_rename(code, offset, "new_name")
self.assertEqual(
dedent("""\
type new_name = int
def a_func(param: new_name) -> new_name:
pass
"""),
refactored,
)

@testutils.only_for_versions_higher("3.12")
def test_renaming_type_alias_in_function_scope(self):
code = dedent("""\
old_name = 1
def a_func():
type old_name = int
x: old_name = 1
""")
offset = code.index("old_name", code.index("type")) + 1
refactored = self._local_rename(code, offset, "new_name")
self.assertEqual(
dedent("""\
old_name = 1
def a_func():
type new_name = int
x: new_name = 1
"""),
refactored,
)

@testutils.only_for_versions_higher("3.12")
def test_renaming_generic_type_alias(self):
code = dedent("""\
type OldAlias[T] = list[T]
x: OldAlias[int] = []
""")
refactored = self._local_rename(code, code.index("OldAlias") + 1, "NewAlias")
self.assertEqual(
dedent("""\
type NewAlias[T] = list[T]
x: NewAlias[int] = []
"""),
refactored,
)

def test_renaming_arguments_for_normal_args_changing_calls(self):
code = dedent("""\
def a_func(p1=None, p2=None):
Expand Down