Hello community, here is the log from the commit of package python-rope for openSUSE:Factory checked in at 2020-10-20 16:10:29 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-rope (Old) and /work/SRC/openSUSE:Factory/.python-rope.new.3486 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-rope" Tue Oct 20 16:10:29 2020 rev:22 rq:842555 version:0.18.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-rope/python-rope.changes 2020-05-07 14:54:56.182343310 +0200 +++ /work/SRC/openSUSE:Factory/.python-rope.new.3486/python-rope.changes 2020-10-20 16:20:50.694306259 +0200 @@ -1,0 +2,13 @@ +Mon Oct 19 11:31:41 UTC 2020 - Matej Cepl <[email protected]> + +- Update to 0.18.0: + - Fix `Worder.get_primary_at` for names that start like + keywords. <Rob Kelly> + - Add guess_def_lineno() to get actual function/class + definition line number <Lie Ryan> + - Fix SimilarFinder/_ASTMatcher to consider 1/0 and True/False + to be unequal <Lie Ryan> + - Compatibility with Python 3.8 + - Add pytest.ini to collect all tests <Lie Ryan> + +------------------------------------------------------------------- Old: ---- rope-0.17.0.tar.gz New: ---- rope-0.18.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-rope.spec ++++++ --- /var/tmp/diff_new_pack.7CCwgp/_old 2020-10-20 16:20:54.810308209 +0200 +++ /var/tmp/diff_new_pack.7CCwgp/_new 2020-10-20 16:20:54.814308211 +0200 @@ -19,7 +19,7 @@ %define upname rope %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-rope -Version: 0.17.0 +Version: 0.18.0 Release: 0 Summary: A python refactoring library License: LGPL-3.0-or-later ++++++ rope-0.17.0.tar.gz -> rope-0.18.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.17.0/PKG-INFO new/rope-0.18.0/PKG-INFO --- old/rope-0.17.0/PKG-INFO 2020-05-05 18:24:19.501011400 +0200 +++ new/rope-0.18.0/PKG-INFO 2020-10-07 18:08:40.468835800 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: rope -Version: 0.17.0 +Version: 0.18.0 Summary: a python refactoring library... Home-page: https://github.com/python-rope/rope Author: Ali Gholami Rudi diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.17.0/rope/__init__.py new/rope-0.18.0/rope/__init__.py --- old/rope-0.17.0/rope/__init__.py 2020-05-05 18:19:23.000000000 +0200 +++ new/rope-0.18.0/rope/__init__.py 2020-10-07 18:08:26.000000000 +0200 @@ -1,7 +1,7 @@ """rope, a python refactoring library""" INFO = __doc__ -VERSION = '0.17.0' +VERSION = '0.18.0' COPYRIGHT = """\ Copyright (C) 2019-2020 Matej Cepl Copyright (C) 2015-2018 Nicholas Smith diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.17.0/rope/base/codeanalyze.py new/rope-0.18.0/rope/base/codeanalyze.py --- old/rope-0.17.0/rope/base/codeanalyze.py 2020-02-15 01:43:49.000000000 +0100 +++ new/rope-0.18.0/rope/base/codeanalyze.py 2020-10-06 19:52:52.000000000 +0200 @@ -358,7 +358,7 @@ def get_string_pattern(): - prefix = r'(?<![fF])(\b[uU]?[rR]?)?' + prefix = r'(?<![fF])(\b[uUbB]?[rR]?)?' return get_string_pattern_with_prefix(prefix) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.17.0/rope/base/pynames.py new/rope-0.18.0/rope/base/pynames.py --- old/rope-0.17.0/rope/base/pynames.py 2020-04-27 11:29:13.000000000 +0200 +++ new/rope-0.18.0/rope/base/pynames.py 2020-10-06 19:52:52.000000000 +0200 @@ -21,7 +21,8 @@ return self.pyobject def get_definition_location(self): - return (self.pyobject.get_module(), self.pyobject.get_ast().lineno) + lineno = utils.guess_def_lineno(self.pyobject.get_module(), self.pyobject.get_ast()) + return (self.pyobject.get_module(), lineno) class AssignedName(PyName): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.17.0/rope/base/pyobjectsdef.py new/rope-0.18.0/rope/base/pyobjectsdef.py --- old/rope-0.17.0/rope/base/pyobjectsdef.py 2020-01-30 17:02:09.000000000 +0100 +++ new/rope-0.18.0/rope/base/pyobjectsdef.py 2020-10-06 19:52:52.000000000 +0200 @@ -390,8 +390,11 @@ def _eval(type_=type_, arg=arg): return type_.get_property_object( arguments.ObjectArguments([arg])) + + lineno = utils.guess_def_lineno(self.get_module(), node) + self.names[node.name] = pynames.EvaluatedName( - _eval, module=self.get_module(), lineno=node.lineno) + _eval, module=self.get_module(), lineno=lineno) break else: self.names[node.name] = pynames.DefinedName(pyfunction) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.17.0/rope/base/utils/__init__.py new/rope-0.18.0/rope/base/utils/__init__.py --- old/rope-0.17.0/rope/base/utils/__init__.py 2020-01-30 17:02:09.000000000 +0100 +++ new/rope-0.18.0/rope/base/utils/__init__.py 2020-10-06 19:52:52.000000000 +0200 @@ -96,3 +96,33 @@ __import__(mod_name) mod = sys.modules[mod_name] return getattr(mod, obj_name) if obj_name else mod + +def guess_def_lineno(module, node): + """ Find the line number for a function or class definition. + + `node` may be either an ast.FunctionDef, ast.AsyncFunctionDef, or ast.ClassDef + + Python 3.8 simply provides this to us, but in earlier versions the ast + node.lineno points to the first decorator rather than the actual + definition, so we try our best to find where the definitions are. + + This is to workaround bpo-33211 (https://bugs.python.org/issue33211) + """ + def is_inline_body(): + # class Foo(object): + # def inline_body(): pass + # ^ ^--- body_col_offset + # `--- indent_col_offset + # def not_inline_body(): + # pass + # ^--- body_col_offset == indent_col_offset + line = module.lines.get_line(node.body[0].lineno) + indent_col_offset = len(line) - len(line.lstrip()) + body_col_offset = node.body[0].col_offset + return indent_col_offset < body_col_offset + + if sys.version_info >= (3, 8): + return node.lineno + + possible_def_line = node.body[0].lineno if is_inline_body() else node.body[0].lineno - 1 + return module.logical_lines.logical_line_in(possible_def_line)[0] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.17.0/rope/base/worder.py new/rope-0.18.0/rope/base/worder.py --- old/rope-0.17.0/rope/base/worder.py 2020-01-30 17:02:09.000000000 +0100 +++ new/rope-0.18.0/rope/base/worder.py 2020-10-07 17:19:26.000000000 +0200 @@ -209,7 +209,8 @@ if offset >= 0 and (self.code[offset] in '"\'})]' or self._is_id_char(offset)): atom_start = self._find_atom_start(offset) - if not keyword.iskeyword(self.code[atom_start:offset + 1]): + if not keyword.iskeyword(self.code[atom_start:offset + 1]) or \ + (offset + 1 < len(self.code) and self._is_id_char(offset + 1)): return atom_start return last_atom diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.17.0/rope/refactor/patchedast.py new/rope-0.18.0/rope/refactor/patchedast.py --- old/rope-0.17.0/rope/refactor/patchedast.py 2020-01-30 17:02:09.000000000 +0100 +++ new/rope-0.18.0/rope/refactor/patchedast.py 2020-10-06 19:52:52.000000000 +0200 @@ -1,10 +1,12 @@ import collections +import numbers import re import warnings from rope.base import ast, codeanalyze, exceptions from rope.base.utils import pycompat + try: basestring except NameError: @@ -331,12 +333,34 @@ def _Delete(self, node): self._handle(node, ['del'] + self._child_nodes(node.targets, ',')) + def _Constant(self, node): + if isinstance(node.value, basestring): + self._handle(node, [self.String]) + return + + if any(node.value is v for v in [True, False, None]): + self._handle(node, [str(node.value)]) + return + + if isinstance(node.value, numbers.Number): + self._handle(node, [self.Number]) + return + + if node.value is Ellipsis: + self._handle(node, ['...']) + return + + assert False + def _Num(self, node): self._handle(node, [self.Number]) def _Str(self, node): self._handle(node, [self.String]) + def _Bytes(self, node): + self._handle(node, [self.String]) + def _Continue(self, node): self._handle(node, ['continue']) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.17.0/rope/refactor/similarfinder.py new/rope-0.18.0/rope/refactor/similarfinder.py --- old/rope-0.17.0/rope/refactor/similarfinder.py 2020-01-13 16:35:36.000000000 +0100 +++ new/rope-0.18.0/rope/refactor/similarfinder.py 2020-10-06 19:52:52.000000000 +0200 @@ -204,7 +204,7 @@ if not self._match_nodes(c1, c2, mapping): return False else: - if child1 != child2: + if type(child1) is not type(child2) or child1 != child2: return False return True diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.17.0/rope.egg-info/PKG-INFO new/rope-0.18.0/rope.egg-info/PKG-INFO --- old/rope-0.17.0/rope.egg-info/PKG-INFO 2020-05-05 18:24:19.000000000 +0200 +++ new/rope-0.18.0/rope.egg-info/PKG-INFO 2020-10-07 18:08:40.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: rope -Version: 0.17.0 +Version: 0.18.0 Summary: a python refactoring library... Home-page: https://github.com/python-rope/rope Author: Ali Gholami Rudi diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.17.0/ropetest/codeanalyzetest.py new/rope-0.18.0/ropetest/codeanalyzetest.py --- old/rope-0.17.0/ropetest/codeanalyzetest.py 2020-02-15 01:43:49.000000000 +0100 +++ new/rope-0.18.0/ropetest/codeanalyzetest.py 2020-10-07 17:19:26.000000000 +0200 @@ -111,6 +111,16 @@ result = self._find_primary(code, code.index('attr') + 1) self.assertEqual('a_var.\nattr', result) + def test_word_finder_on_primary_like_keyword(self): + code = 'is_keyword = False\n' + result = self._find_primary(code, 1) + self.assertEqual('is_keyword', result) + + def test_keyword_before_parens_no_space(self): + code = 'if(a_var).an_attr:\n pass\n' + self.assertEqual('(a_var).an_attr', + self._find_primary(code, code.index(':'))) + def test_strings(self): code = '"a string".split()' self.assertEqual('"a string".split', self._find_primary(code, 14)) @@ -118,7 +128,7 @@ def test_function_calls2(self): code = 'file("afile.txt").read()' self.assertEqual('file("afile.txt").read', - self._find_primary(code, 18)) + self._find_primary(code, 18)) def test_parens(self): code = '("afile.txt").split()' @@ -131,7 +141,7 @@ def test_function_with_multiple_param(self): code = 'AClass(a_param, another_param, "a string").a_func()' self.assertEqual('AClass(a_param, another_param, "a string").a_func', - self._find_primary(code, 44)) + self._find_primary(code, 44)) def test_param_expressions(self): code = 'AClass(an_object.an_attr).a_func()' @@ -144,7 +154,7 @@ def test_extra_spaces(self): code = 'a_func ( "(" ) . an_attr' self.assertEqual('a_func ( "(" ) . an_attr', - self._find_primary(code, 26)) + self._find_primary(code, 26)) def test_functions_on_ending_parens(self): code = 'A()' @@ -153,7 +163,7 @@ def test_splitted_statement(self): word_finder = worder.Worder('an_object.an_attr') self.assertEqual(('an_object', 'an_at', 10), - word_finder.get_splitted_primary_before(15)) + word_finder.get_splitted_primary_before(15)) def test_empty_splitted_statement(self): word_finder = worder.Worder('an_attr') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.17.0/ropetest/contrib/codeassisttest.py new/rope-0.18.0/ropetest/contrib/codeassisttest.py --- old/rope-0.17.0/ropetest/contrib/codeassisttest.py 2020-04-27 11:29:13.000000000 +0200 +++ new/rope-0.18.0/ropetest/contrib/codeassisttest.py 2020-10-06 19:52:52.000000000 +0200 @@ -352,15 +352,82 @@ result = get_definition_location(self.project, code, len(code) - 11) self.assertEqual((None, 1), result) - def test_get_definition_location_dotted_names(self): + def test_get_definition_location_dotted_names_method(self): code = 'class AClass(object):\n' \ ' @staticmethod\n' \ ' def a_method():\n' \ ' pass\n' \ 'AClass.a_method()' result = get_definition_location(self.project, code, len(code) - 3) + self.assertEqual((None, 3), result) + + def test_get_definition_location_dotted_names_property(self): + code = 'class AClass(object):\n' \ + ' @property\n' \ + ' @somedecorator\n' \ + ' def a_method():\n' \ + ' pass\n' \ + 'AClass.a_method()' + result = get_definition_location(self.project, code, len(code) - 3) + self.assertEqual((None, 4), result) + + def test_get_definition_location_dotted_names_free_function(self): + code = '@custom_decorator\n' \ + 'def a_method():\n' \ + ' pass\n' \ + 'a_method()' + result = get_definition_location(self.project, code, len(code) - 3) + self.assertEqual((None, 2), result) + + @testutils.only_for_versions_higher('3.5') + def test_get_definition_location_dotted_names_async_def(self): + code = 'class AClass(object):\n' \ + ' @property\n' \ + ' @decorator2\n' \ + ' async def a_method():\n' \ + ' pass\n' \ + 'AClass.a_method()' + result = get_definition_location(self.project, code, len(code) - 3) + self.assertEqual((None, 4), result) + + def test_get_definition_location_dotted_names_class(self): + code = '@custom_decorator\n' \ + 'class AClass(object):\n' \ + ' def a_method():\n' \ + ' pass\n' \ + 'AClass.a_method()' + result = get_definition_location(self.project, code, len(code) - 12) self.assertEqual((None, 2), result) + def test_get_definition_location_dotted_names_with_space(self): + code = 'class AClass(object):\n' \ + ' @staticmethod\n' \ + ' def a_method():\n' \ + ' \n' \ + ' pass\n' \ + 'AClass.a_method()' + result = get_definition_location(self.project, code, len(code) - 3) + self.assertEqual((None, 3), result) + + def test_get_definition_location_dotted_names_inline_body(self): + code = 'class AClass(object):\n' \ + ' @staticmethod\n' \ + ' def a_method(): pass\n' \ + 'AClass.a_method()' + result = get_definition_location(self.project, code, len(code) - 3) + self.assertEqual((None, 3), result) + + def test_get_definition_location_dotted_names_inline_body_split_arg(self): + code = 'class AClass(object):\n' \ + ' @staticmethod\n' \ + ' def a_method(\n' \ + ' self,\n' \ + ' arg1\n' \ + ' ): pass\n' \ + 'AClass.a_method()' + result = get_definition_location(self.project, code, len(code) - 3) + self.assertEqual((None, 3), result) + def test_get_definition_location_dotted_module_names(self): module_resource = testutils.create_module(self.project, 'mod') module_resource.write('def a_func():\n pass\n') @@ -389,7 +456,7 @@ '@staticmethod\n def a_method():\n' \ ' pass\nAClass.\\\n a_method()' result = get_definition_location(self.project, code, len(code) - 3) - self.assertEqual((None, 2), result) + self.assertEqual((None, 3), result) def test_get_definition_location_dot_line_break_inside_parens(self): code = 'class A(object):\n def a_method(self):\n pass\n' + \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.17.0/ropetest/refactor/patchedasttest.py new/rope-0.18.0/ropetest/refactor/patchedasttest.py --- old/rope-0.17.0/ropetest/refactor/patchedasttest.py 2020-01-30 17:02:09.000000000 +0100 +++ new/rope-0.18.0/ropetest/refactor/patchedasttest.py 2020-10-06 19:52:52.000000000 +0200 @@ -14,6 +14,8 @@ except NameError: basestring = (str, bytes) +NameConstant = 'Name' if sys.version_info <= (3, 8) else 'NameConstant' +Bytes = 'Bytes' if (3, 0) <= sys.version_info <= (3, 8) else 'Str' class PatchedASTTest(unittest.TestCase): @@ -23,6 +25,15 @@ def tearDown(self): super(PatchedASTTest, self).tearDown() + def test_bytes_string(self): + source = '1 + b"("\n' + ast_frag = patchedast.get_patched_ast(source, True) + checker = _ResultChecker(self, ast_frag) + str_fragment = 'b"("' + start = source.index(str_fragment) + checker.check_region(Bytes, start, start + len(str_fragment)) + checker.check_children(Bytes, [str_fragment]) + def test_integer_literals_and_region(self): source = 'a = 10\n' ast_frag = patchedast.get_patched_ast(source, True) @@ -85,6 +96,13 @@ # start = source.index('10') checker.check_children('Num', ['10']) + def test_ellipsis(self): + source = 'a[...]\n' + ast_frag = patchedast.get_patched_ast(source, True) + checker = _ResultChecker(self, ast_frag) + start = source.index('...') + checker.check_region('Ellipsis', start, start + len('...')) + def test_ass_name_node(self): source = 'a = 10\n' ast_frag = patchedast.get_patched_ast(source, True) @@ -124,7 +142,7 @@ checker = _ResultChecker(self, ast_frag) checker.check_region('BoolOp', 0, len(source) - 1) checker.check_children( - 'BoolOp', ['Name', ' ', 'and', ' ', 'Name']) + 'BoolOp', [NameConstant, ' ', 'and', ' ', NameConstant]) def test_basic_closing_parens(self): source = '1 + (2)\n' @@ -263,7 +281,7 @@ checker = _ResultChecker(self, ast_frag) checker.check_region('Assert', 0, len(source) - 1) checker.check_children( - 'Assert', ['assert', ' ', 'Name']) + 'Assert', ['assert', ' ', NameConstant]) def test_assert2(self): source = 'assert True, "error"\n' @@ -271,7 +289,7 @@ checker = _ResultChecker(self, ast_frag) checker.check_region('Assert', 0, len(source) - 1) checker.check_children( - 'Assert', ['assert', ' ', 'Name', '', ',', ' ', 'Str']) + 'Assert', ['assert', ' ', NameConstant, '', ',', ' ', 'Str']) def test_aug_assign_node(self): source = 'a += 1\n' @@ -594,7 +612,7 @@ checker = _ResultChecker(self, ast_frag) checker.check_region('If', 0, len(source) - 1) checker.check_children( - 'If', ['if', ' ', 'Name', '', ':', '\n ', 'Pass', '\n', + 'If', ['if', ' ', NameConstant, '', ':', '\n ', 'Pass', '\n', 'else', '', ':', '\n ', 'Pass']) def test_if_node2(self): @@ -603,7 +621,7 @@ checker = _ResultChecker(self, ast_frag) checker.check_region('If', 0, len(source) - 1) checker.check_children( - 'If', ['if', ' ', 'Name', '', ':', '\n ', 'Pass', '\n', + 'If', ['if', ' ', NameConstant, '', ':', '\n ', 'Pass', '\n', 'If']) def test_if_node3(self): @@ -613,7 +631,7 @@ checker = _ResultChecker(self, ast_frag) checker.check_region('If', 0, len(source) - 1) checker.check_children( - 'If', ['if', ' ', 'Name', '', ':', '\n ', 'Pass', '\n', + 'If', ['if', ' ', NameConstant, '', ':', '\n ', 'Pass', '\n', 'else', '', ':', '\n ', 'If']) def test_import_node(self): @@ -630,7 +648,7 @@ checker = _ResultChecker(self, ast_frag) checker.check_region('Lambda', 0, len(source) - 1) checker.check_children( - 'Lambda', ['lambda', ' ', 'arguments', '', ':', ' ', 'Name']) + 'Lambda', ['lambda', ' ', 'arguments', '', ':', ' ', NameConstant]) expected_child = pycompat.ast_arg_type.__name__ checker.check_children( 'arguments', [expected_child, '', ',', ' ', @@ -654,7 +672,7 @@ 'ListComp', ['[', '', 'Name', ' ', 'comprehension', '', ']']) checker.check_children( 'comprehension', ['for', ' ', 'Name', ' ', 'in', ' ', - 'Call', ' ', 'if', ' ', 'Name']) + 'Call', ' ', 'if', ' ', NameConstant]) def test_list_comp_node_with_multiple_comprehensions(self): source = '[i for i in range(1) for j in range(1) if True]\n' @@ -666,7 +684,7 @@ ' ', 'comprehension', '', ']']) checker.check_children( 'comprehension', ['for', ' ', 'Name', ' ', 'in', ' ', - 'Call', ' ', 'if', ' ', 'Name']) + 'Call', ' ', 'if', ' ', NameConstant]) def test_set_node(self): # make sure we are in a python version with set literals @@ -699,7 +717,7 @@ 'SetComp', ['{', '', 'Name', ' ', 'comprehension', '', '}']) checker.check_children( 'comprehension', ['for', ' ', 'Name', ' ', 'in', ' ', - 'Call', ' ', 'if', ' ', 'Name']) + 'Call', ' ', 'if', ' ', NameConstant]) def test_dict_comp_node(self): # make sure we are in a python version with dict comprehensions @@ -718,7 +736,7 @@ ' ', 'comprehension', '', '}']) checker.check_children( 'comprehension', ['for', ' ', 'Name', ' ', 'in', ' ', - 'Call', ' ', 'if', ' ', 'Name']) + 'Call', ' ', 'if', ' ', NameConstant]) def test_ext_slice_node(self): source = 'x = xs[0,:]\n' @@ -747,7 +765,7 @@ ast_frag = patchedast.get_patched_ast(source, True) checker = _ResultChecker(self, ast_frag) checker.check_children('Expr', ['BoolOp']) - checker.check_children('BoolOp', ['UnaryOp', ' ', 'or', ' ', 'Name']) + checker.check_children('BoolOp', ['UnaryOp', ' ', 'or', ' ', NameConstant]) @testutils.only_for_versions_lower('3') def test_print_node(self): @@ -790,7 +808,7 @@ source = 'def f():\n return None\n' ast_frag = patchedast.get_patched_ast(source, True) checker = _ResultChecker(self, ast_frag) - checker.check_children('Return', ['return', ' ', 'Name']) + checker.check_children('Return', ['return', ' ', NameConstant]) def test_empty_return_node(self): source = 'def f():\n return\n' @@ -852,14 +870,14 @@ source = 'def f():\n yield None\n' ast_frag = patchedast.get_patched_ast(source, True) checker = _ResultChecker(self, ast_frag) - checker.check_children('Yield', ['yield', ' ', 'Name']) + checker.check_children('Yield', ['yield', ' ', NameConstant]) def test_while_node(self): source = 'while True:\n pass\nelse:\n pass\n' ast_frag = patchedast.get_patched_ast(source, True) checker = _ResultChecker(self, ast_frag) checker.check_children( - 'While', ['while', ' ', 'Name', '', ':', '\n ', 'Pass', '\n', + 'While', ['while', ' ', NameConstant, '', ':', '\n ', 'Pass', '\n', 'else', '', ':', '\n ', 'Pass']) @testutils.only_for('2.5') @@ -973,7 +991,7 @@ ast_frag = patchedast.get_patched_ast(source, True) checker = _ResultChecker(self, ast_frag) checker.check_children( - 'IfExp', ['Num', ' ', 'if', ' ', 'Name', ' ', 'else', + 'IfExp', ['Num', ' ', 'if', ' ', NameConstant, ' ', 'else', ' ', 'Num']) def test_delete_node(self): @@ -1060,6 +1078,8 @@ def __call__(self, node): for text in goal: + if sys.version_info >= (3, 8) and text in ['Num', 'Str', 'NameConstant', 'Ellipsis']: + text = 'Constant' if str(node).startswith(text): self.result = node break @@ -1088,6 +1108,8 @@ else: self.test_case.assertNotEqual( '', text, 'probably ignoring some node') + if sys.version_info >= (3, 8) and expected in ['Num', 'Str', 'NameConstant', 'Ellipsis']: + expected = 'Constant' self.test_case.assertTrue( child.__class__.__name__.startswith(expected), msg='Expected <%s> but was <%s>' % diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.17.0/ropetest/refactor/similarfindertest.py new/rope-0.18.0/ropetest/refactor/similarfindertest.py --- old/rope-0.17.0/ropetest/refactor/similarfindertest.py 2020-01-30 17:02:09.000000000 +0100 +++ new/rope-0.18.0/ropetest/refactor/similarfindertest.py 2020-10-06 19:52:52.000000000 +0200 @@ -33,6 +33,12 @@ result = [(source.index('10'), source.index('10') + 2)] self.assertEqual(result, list(finder.get_match_regions('10'))) + def test_bool_is_not_similar_to_integer(self): + source = 'a = False\nb = 0' + finder = self._create_finder(source) + result = [(source.index('False'), source.index('False') + len('False'))] + self.assertEqual(result, list(finder.get_match_regions('False'))) + def test_simple_addition(self): source = 'a = 1 + 2\n' finder = self._create_finder(source) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.17.0/ropetest/type_hinting_test.py new/rope-0.18.0/ropetest/type_hinting_test.py --- old/rope-0.17.0/ropetest/type_hinting_test.py 2020-05-05 18:18:09.000000000 +0200 +++ new/rope-0.18.0/ropetest/type_hinting_test.py 2020-10-06 19:52:52.000000000 +0200 @@ -51,9 +51,9 @@ code = 'class Sample(object):\n' \ ' def a_method(self, a_arg):\n' \ ' """:type a_arg: threading.Thread"""\n' \ - ' a_arg.isA' + ' a_arg.is_a' result = self._assist(code) - self.assert_completion_in_result('isAlive', 'attribute', result) + self.assert_completion_in_result('is_alive', 'attribute', result) def test_hierarchical_hint_param(self): code = 'class ISample(object):\n' \ @@ -62,9 +62,9 @@ '\n\n' \ 'class Sample(ISample):\n' \ ' def a_method(self, a_arg):\n' \ - ' a_arg.isA' + ' a_arg.is_a' result = self._assist(code) - self.assert_completion_in_result('isAlive', 'attribute', result) + self.assert_completion_in_result('is_alive', 'attribute', result) class DocstringReturnHintingTest(AbstractHintingTest): @@ -78,9 +78,9 @@ ' def b_method(self):\n' \ ' pass\n' \ ' def a_method(self):\n' \ - ' self.b_method().isA' + ' self.b_method().is_a' result = self._assist(code) - self.assert_completion_in_result('isAlive', 'attribute', result) + self.assert_completion_in_result('is_alive', 'attribute', result) class AbstractAssignmentHintingTest(AbstractHintingTest): @@ -95,9 +95,9 @@ code = 'class Sample(object):\n' \ + self._make_class_hint('threading.Thread') + \ ' def a_method(self):\n' \ - ' self.a_attr.isA' + ' self.a_attr.is_a' result = self._assist(code) - self.assert_completion_in_result('isAlive', 'attribute', result) + self.assert_completion_in_result('is_alive', 'attribute', result) def test_hierarchical_hint_attr(self): code = 'class ISample(object):\n' \ @@ -106,18 +106,18 @@ 'class Sample(ISample):\n' \ ' a_attr = None\n'\ ' def a_method(self):\n' \ - ' self.a_attr.isA' + ' self.a_attr.is_a' result = self._assist(code) - self.assert_completion_in_result('isAlive', 'attribute', result) + self.assert_completion_in_result('is_alive', 'attribute', result) def test_hint_defined_by_constructor(self): code = 'class Sample(object):\n' \ ' def __init__(self, arg):\n' \ + self._make_constructor_hint('threading.Thread') + \ ' def a_method(self):\n' \ - ' self.a_attr.isA' + ' self.a_attr.is_a' result = self._assist(code) - self.assert_completion_in_result('isAlive', 'attribute', result) + self.assert_completion_in_result('is_alive', 'attribute', result) def test_hint_attr_redefined_by_constructor(self): code = 'class Sample(object):\n' \ @@ -125,9 +125,9 @@ ' def __init__(self):\n' \ ' self.a_attr = None\n' \ ' def a_method(self):\n' \ - ' self.a_attr.isA' + ' self.a_attr.is_a' result = self._assist(code) - self.assert_completion_in_result('isAlive', 'attribute', result) + self.assert_completion_in_result('is_alive', 'attribute', result) def test_hierarchical_hint_attr_redefined_by_constructor(self): code = 'class ISample(object):\n' \ @@ -137,61 +137,61 @@ ' def __init__(self):\n' \ ' self.a_attr = None\n' \ ' def a_method(self):\n' \ - ' self.a_attr.isA' + ' self.a_attr.is_a' result = self._assist(code) - self.assert_completion_in_result('isAlive', 'attribute', result) + self.assert_completion_in_result('is_alive', 'attribute', result) def test_hint_attr_for_pre_defined_type(self): code = 'class Other(object):\n' \ - ' def isAlive(self):\n' \ + ' def is_alive(self):\n' \ ' pass\n' \ '\n\n' \ 'class Sample(object):\n' \ + self._make_class_hint('Other') + \ ' def a_method(self):\n' \ - ' self.a_attr.isA' + ' self.a_attr.is_a' result = self._assist(code) - self.assert_completion_in_result('isAlive', 'attribute', result) + self.assert_completion_in_result('is_alive', 'attribute', result) def test_hint_attr_for_post_defined_type(self): code = 'class Sample(object):\n' \ + self._make_class_hint('Other') + \ ' def a_method(self):\n' \ - ' self.a_attr.isA' + ' self.a_attr.is_a' offset = len(code) code += '\n\n' \ 'class Other(object):\n' \ - ' def isAlive(self):\n' \ + ' def is_alive(self):\n' \ ' pass\n' result = self._assist(code, offset) - self.assert_completion_in_result('isAlive', 'attribute', result) + self.assert_completion_in_result('is_alive', 'attribute', result) def test_hint_parametrized_list(self): code = 'class Sample(object):\n' \ + self._make_class_hint('list[threading.Thread]') + \ ' def a_method(self):\n' \ ' for i in self.a_attr:\n' \ - ' i.isA' + ' i.is_a' result = self._assist(code) - self.assert_completion_in_result('isAlive', 'attribute', result) + self.assert_completion_in_result('is_alive', 'attribute', result) def test_hint_parametrized_tuple(self): code = 'class Sample(object):\n' \ + self._make_class_hint('tuple[threading.Thread]') + \ ' def a_method(self):\n' \ ' for i in self.a_attr:\n' \ - ' i.isA' + ' i.is_a' result = self._assist(code) - self.assert_completion_in_result('isAlive', 'attribute', result) + self.assert_completion_in_result('is_alive', 'attribute', result) def test_hint_parametrized_set(self): code = 'class Sample(object):\n' \ + self._make_class_hint('set[threading.Thread]') + \ ' def a_method(self):\n' \ ' for i in self.a_attr:\n' \ - ' i.isA' + ' i.is_a' result = self._assist(code) - self.assert_completion_in_result('isAlive', 'attribute', result) + self.assert_completion_in_result('is_alive', 'attribute', result) def test_hint_parametrized_iterable(self): code = 'class Sample(object):\n' \ @@ -225,9 +225,9 @@ + self._make_class_hint('dict[str, threading.Thread]') + \ ' def a_method(self):\n' \ ' for i in self.a_attr.values():\n' \ - ' i.isA' + ' i.is_a' result = self._assist(code) - self.assert_completion_in_result('isAlive', 'attribute', result) + self.assert_completion_in_result('is_alive', 'attribute', result) def test_hint_parametrized_nested_tuple_list(self): code = 'class Sample(object):\n' \ @@ -235,26 +235,26 @@ ' def a_method(self):\n' \ ' for j in self.a_attr:\n' \ ' for i in j:\n' \ - ' i.isA' + ' i.is_a' result = self._assist(code) - self.assert_completion_in_result('isAlive', 'attribute', result) + self.assert_completion_in_result('is_alive', 'attribute', result) def test_hint_or(self): code = 'class Sample(object):\n' \ + self._make_class_hint('str | threading.Thread') + \ ' def a_method(self):\n' \ ' for i in self.a_attr.values():\n' \ - ' i.isA' + ' i.is_a' result = self._assist(code) # Be sure, there isn't errors currently - # self.assert_completion_in_result('isAlive', 'attribute', result) + # self.assert_completion_in_result('is_alive', 'attribute', result) def test_hint_nonexistent(self): code = 'class Sample(object):\n' \ + self._make_class_hint('sdfdsf.asdfasdf.sdfasdf.Dffg') + \ ' def a_method(self):\n' \ ' for i in self.a_attr.values():\n' \ - ' i.isA' + ' i.is_a' self._assist(code) def test_hint_invalid_syntax(self): @@ -262,7 +262,7 @@ + self._make_class_hint('sdf | & # &*') + \ ' def a_method(self):\n' \ ' for i in self.a_attr.values():\n' \ - ' i.isA' + ' i.is_a' self._assist(code)
