Skip to content

Commit

Permalink
Merge remote-tracking branch 'climbus/inside_line_scope'
Browse files Browse the repository at this point in the history
  • Loading branch information
lieryan committed Oct 3, 2021
2 parents 2a866e4 + c26729d commit fb4bdc3
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- #391, #396 Extract method similar no longer replace the left-hand side of assignment (@climbus)
- #303 Fix inlining into f-string containing quote characters (@lieryan)
- Added scopes for comprehension expressions as part of #293 (@climbus)
- Added support for checking scopes by offset as part of #293 (@climbus)
- #423 Fix `AttributeError: '_ExpressionVisitor' object has no attribute 'defineds'` (@lieryan)
- #398, #104 Fix parsing of nested `with` statement/context manager (@climbus)
- #391, #376 Fix improper replacement when extracting attribute access expression with `similar=True` (@climbus)
Expand Down
25 changes: 23 additions & 2 deletions rope/base/pyscopes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import rope.base.codeanalyze
import rope.base.pynames
from rope.base import ast, exceptions, utils
from rope.refactor import patchedast


class Scope(object):
Expand Down Expand Up @@ -100,6 +101,20 @@ def get_logical_end(self):
def get_kind(self):
pass

@utils.saveit
def get_region(self):
node = patchedast.patch_ast(
self.pyobject.get_ast(), self.pyobject.get_module().source_code
)
region = patchedast.node_region(node)
return region

def in_region(self, offset):
"Checks if offset is in scope region"

region = self.get_region()
return region[0] < offset < region[1]


class GlobalScope(Scope):
def __init__(self, pycore, module):
Expand Down Expand Up @@ -289,8 +304,14 @@ def _is_empty_line(self, lineno):
def _get_body_indents(self, scope):
return self.get_indents(scope.get_body_start())

def get_holding_scope_for_offset(self, scope, offset):
return self.get_holding_scope(scope, self.lines.get_line_number(offset))
@staticmethod
def get_holding_scope_for_offset(scope, offset):
for inner_scope in scope.get_scopes():
if inner_scope.in_region(offset):
return _HoldingScopeFinder.get_holding_scope_for_offset(
inner_scope, offset
)
return scope

def find_scope_end(self, scope):
if not scope.parent:
Expand Down
18 changes: 18 additions & 0 deletions ropetest/pyscopestest.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,24 @@ def test_get_inner_scope_for_staticmethods(self):
f_in_c = c_scope.get_scopes()[0]
self.assertEqual(f_in_c, scope.get_inner_scope_for_line(4))

def test_get_scope_for_offset_for_comprehension(self):
scope = libutils.get_string_scope(self.project, "a = [i for i in range(10)]\n")
c_scope = scope.get_scopes()[0]
self.assertEqual(c_scope, scope.get_inner_scope_for_offset(10))
self.assertEqual(scope, scope.get_inner_scope_for_offset(1))

def test_get_scope_for_offset_for_in_nested_comprehension(self):
scope = libutils.get_string_scope(self.project, "[i for i in [j for j in k]]\n")
c_scope = scope.get_scopes()[0]
self.assertEqual(c_scope, scope.get_inner_scope_for_offset(5))
inner_scope = c_scope.get_scopes()[0]
self.assertEqual(inner_scope, scope.get_inner_scope_for_offset(15))

def test_get_scope_for_offset_for_scope_with_indent(self):
scope = libutils.get_string_scope(self.project, "def f(a):\n" " print(a)\n")
inner_scope = scope.get_scopes()[0]
self.assertEqual(inner_scope, scope.get_inner_scope_for_offset(10))

def test_getting_overwritten_scopes(self):
scope = libutils.get_string_scope(
self.project, "def f():\n pass\ndef f():\n pass\n"
Expand Down

0 comments on commit fb4bdc3

Please sign in to comment.