Hello community, here is the log from the commit of package python-rope for openSUSE:Factory checked in at 2018-08-18 00:00:47 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-rope (Old) and /work/SRC/openSUSE:Factory/.python-rope.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-rope" Sat Aug 18 00:00:47 2018 rev:11 rq:628350 version:0.11.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-rope/python-rope.changes 2017-08-29 11:47:33.618893811 +0200 +++ /work/SRC/openSUSE:Factory/.python-rope.new/python-rope.changes 2018-08-18 00:00:48.354484918 +0200 @@ -1,0 +2,7 @@ +Thu Aug 9 07:55:22 UTC 2018 - [email protected] + +- update to 0.11.0 + + Upstream provides no changelog +- Remove patch CVE-2014-3539-disable-doa.patch (included upstream) + +------------------------------------------------------------------- Old: ---- CVE-2014-3539-disable-doa.patch rope-0.10.7.tar.gz New: ---- rope-0.11.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-rope.spec ++++++ --- /var/tmp/diff_new_pack.WssWlS/_old 2018-08-18 00:00:49.274487660 +0200 +++ /var/tmp/diff_new_pack.WssWlS/_new 2018-08-18 00:00:49.282487684 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-rope # -# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -16,23 +16,21 @@ # +%define upname rope %{?!python_module:%define python_module() python-%{**} python3-%{**}} %bcond_without test Name: python-rope -Version: 0.10.7 +Version: 0.11.0 Release: 0 Summary: A python refactoring library -License: GPL-2.0+ +License: GPL-2.0-or-later Group: Development/Languages/Python -Url: https://github.com/python-rope/rope +URL: https://github.com/python-rope/rope Source: https://files.pythonhosted.org/packages/source/r/rope/rope-%{version}.tar.gz -# PATCH-FIX-UPSTREAM - CVE-2014-3539-disable-doa.patch - https://github.com/python-rope/rope/issues/105 -Patch0: CVE-2014-3539-disable-doa.patch BuildRequires: %{python_module devel} BuildRequires: fdupes BuildRequires: python-rpm-macros BuildArch: noarch - %python_subpackages %description @@ -40,16 +38,15 @@ %prep %setup -q -n rope-%{version} -%patch0 -p1 %build export LANG=en_US.UTF-8 -%{python_build} +%python_build %install export LANG=en_US.UTF-8 -%{python_install} -%{python_expand rm -rf %{buildroot}/%{%python_sitelib}/python-rope/ropetest/ +%python_install +%{python_expand rm -rf %{buildroot}/%{%{python_sitelib}}/python-rope/ropetest/ %fdupes %{buildroot}/%{$python_sitelib} } @@ -60,7 +57,8 @@ %endif %files %{python_files} -%doc COPYING README.rst +%license COPYING +%doc README.rst %doc docs/ %{python_sitelib}/ ++++++ rope-0.10.7.tar.gz -> rope-0.11.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.10.7/PKG-INFO new/rope-0.11.0/PKG-INFO --- old/rope-0.10.7/PKG-INFO 2017-08-23 06:44:12.000000000 +0200 +++ new/rope-0.11.0/PKG-INFO 2018-08-08 21:18:36.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: rope -Version: 0.10.7 +Version: 0.11.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.10.7/docs/contributing.rst new/rope-0.11.0/docs/contributing.rst --- old/rope-0.10.7/docs/contributing.rst 2017-02-22 18:40:14.000000000 +0100 +++ new/rope-0.11.0/docs/contributing.rst 2018-05-11 20:54:36.000000000 +0200 @@ -42,12 +42,6 @@ .. _`dev/issues.rst`: dev/issues.rst -Getting Ready For Python 3.0 ----------------------------- - -Checkout http://bitbucket.org/agr/rope_py3k Mercurial_ repository. -Contributions are welcome. - Write Plugins For Other IDEs ---------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.10.7/rope/__init__.py new/rope-0.11.0/rope/__init__.py --- old/rope-0.10.7/rope/__init__.py 2017-08-23 06:41:28.000000000 +0200 +++ new/rope-0.11.0/rope/__init__.py 2018-08-08 21:06:01.000000000 +0200 @@ -1,9 +1,9 @@ """rope, a python refactoring library""" INFO = __doc__ -VERSION = '0.10.7' +VERSION = '0.11.0' COPYRIGHT = """\ -Copyright (C) 2015-2016 Nicholas Smith +Copyright (C) 2015-2018 Nicholas Smith Copyright (C) 2014-2015 Matej Cepl Copyright (C) 2006-2012 Ali Gholami Rudi Copyright (C) 2009-2012 Anton Gritsay diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.10.7/rope/base/default_config.py new/rope-0.11.0/rope/base/default_config.py --- old/rope-0.10.7/rope/base/default_config.py 2017-02-22 18:40:14.000000000 +0100 +++ new/rope-0.11.0/rope/base/default_config.py 2018-02-27 21:54:30.000000000 +0100 @@ -21,7 +21,7 @@ # useful when you have scripts inside your project. Only files # ending with ``.py`` are considered to be python files by # default. - #prefs['python_files'] = ['*.py'] + # prefs['python_files'] = ['*.py'] # Custom source folders: By default rope searches the project # for finding source folders (folders that should be searched @@ -31,10 +31,10 @@ # The folders should be relative to project root and use '/' for # separating folders regardless of the platform rope is running on. # 'src/my_source_folder' for instance. - #prefs.add('source_folders', 'src') + # prefs.add('source_folders', 'src') # You can extend python path for looking up modules - #prefs.add('python_path', '~/python/') + # prefs.add('python_path', '~/python/') # Should rope save object information or not. prefs['save_objectdb'] = True @@ -93,18 +93,20 @@ # reinsert them at the top of the module when making changes. prefs['pull_imports_to_top'] = True - # If `True`, rope will sort imports alphabetically by module name instead of - # alphabetically by import statement, with from imports after normal + # If `True`, rope will sort imports alphabetically by module name instead + # of alphabetically by import statement, with from imports after normal # imports. prefs['sort_imports_alphabetically'] = False - # Location of implementation of rope.base.oi.type_hinting.interfaces.ITypeHintingFactory - # In general case, you don't have to change this value, unless you're an rope expert. + # Location of implementation of + # rope.base.oi.type_hinting.interfaces.ITypeHintingFactory In general + # case, you don't have to change this value, unless you're an rope expert. # Change this value to inject you own implementations of interfaces # listed in module rope.base.oi.type_hinting.providers.interfaces - # For example, you can add you own providers for Django Models, or disable the search - # type-hinting in a class hierarchy, etc. - prefs['type_hinting_factory'] = 'rope.base.oi.type_hinting.factory.default_type_hinting_factory' + # For example, you can add you own providers for Django Models, or disable + # the search type-hinting in a class hierarchy, etc. + prefs['type_hinting_factory'] = ( + 'rope.base.oi.type_hinting.factory.default_type_hinting_factory') def project_opened(project): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.10.7/rope/base/evaluate.py new/rope-0.11.0/rope/base/evaluate.py --- old/rope-0.10.7/rope/base/evaluate.py 2017-02-22 18:40:14.000000000 +0100 +++ new/rope-0.11.0/rope/base/evaluate.py 2018-05-11 20:56:15.000000000 +0200 @@ -101,8 +101,9 @@ offset, lineno): name = self.worder.get_primary_at(offset).strip() return (None, holding_scope.parent[name]) - # from statement module - if self.worder.is_from_statement_module(offset): + # module in a from statement or an imported name that is aliased + if (self.worder.is_from_statement_module(offset) or + self.worder.is_import_statement_aliased_module(offset)): module = self.worder.get_primary_at(offset) module_pyname = self._find_module(module) return (None, module_pyname) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.10.7/rope/base/oi/doa.py new/rope-0.11.0/rope/base/oi/doa.py --- old/rope-0.10.7/rope/base/oi/doa.py 2017-02-22 18:40:14.000000000 +0100 +++ new/rope-0.11.0/rope/base/oi/doa.py 2018-08-08 21:04:57.000000000 +0200 @@ -1,7 +1,10 @@ +import base64 +import hashlib +import hmac try: - import pickle -except ImportError: import cPickle as pickle +except ImportError: + import pickle import marshal import os import socket @@ -11,6 +14,28 @@ import threading +def _compat_compare_digest(a, b): + """Implementation of hmac.compare_digest for python < 2.7.7. + + This function uses an approach designed to prevent timing analysis by + avoiding content-based short circuiting behaviour, making it appropriate + for cryptography. + """ + if len(a) != len(b): + return False + # Computes the bitwise difference of all characters in the two strings + # before returning whether or not they are equal. + difference = 0 + for (a_char, b_char) in zip(a, b): + difference |= ord(a_char) ^ ord(b_char) + return difference == 0 + +try: + from hmac import compare_digest +except ImportError: + compare_digest = _compat_compare_digest + + class PythonFileRunner(object): """A class for running python project files""" @@ -114,24 +139,55 @@ def __init__(self): self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.data_port = 3037 + self.key = os.urandom(32) + while self.data_port < 4000: try: - self.server_socket.bind(('', self.data_port)) + self.server_socket.bind(('localhost', self.data_port)) break except socket.error: self.data_port += 1 self.server_socket.listen(1) def get_send_info(self): - return str(self.data_port) + return '%d:%s' % (self.data_port, + base64.b64encode(self.key).decode('utf-8')) def receive_data(self): conn, addr = self.server_socket.accept() self.server_socket.close() my_file = conn.makefile('rb') while True: + # Received messages must meet the following criteria: + # 1. Must be contained on a single line. + # 2. Must be prefixed with a base64 encoded sha256 message digest + # of the base64 encoded pickle data. + # 3. Message digest must be computed using the correct key. + # + # Any messages received that do not meet these criteria will never + # be unpickled and will be dropped silently. try: - yield pickle.load(my_file) + buf = my_file.readline() + if len(buf) == 0: + break + + try: + digest_end = buf.index(b':') + buf_digest = base64.b64decode(buf[:digest_end]) + buf_data = buf[digest_end + 1:-1] + decoded_buf_data = base64.b64decode(buf_data) + except: + # Corrupted data; the payload cannot be trusted and just has + # to be dropped. See CVE-2014-3539. + continue + + digest = hmac.new(self.key, buf_data, hashlib.sha256).digest() + if not compare_digest(buf_digest, digest): + # Signature mismatch; the payload cannot be trusted and just + # has to be dropped. See CVE-2014-3539. + continue + + yield pickle.loads(decoded_buf_data) except EOFError: break my_file.close() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.10.7/rope/base/oi/runmod.py new/rope-0.11.0/rope/base/oi/runmod.py --- old/rope-0.10.7/rope/base/oi/runmod.py 2017-02-22 18:40:14.000000000 +0100 +++ new/rope-0.11.0/rope/base/oi/runmod.py 2018-08-08 21:04:57.000000000 +0200 @@ -3,14 +3,17 @@ import sys import socket try: - import pickle - except ImportError: import cPickle as pickle + except ImportError: + import pickle import marshal import inspect import types import threading import rope.base.utils.pycompat as pycompat + import base64 + import hashlib + import hmac class _MessageSender(object): @@ -19,15 +22,19 @@ class _SocketSender(_MessageSender): - def __init__(self, port): + def __init__(self, port, key): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1', port)) self.my_file = s.makefile('wb') + self.key = base64.b64decode(key) def send_data(self, data): if not self.my_file.closed: - pickle.dump(data, self.my_file) - + pickled_data = base64.b64encode( + pickle.dumps(data, pickle.HIGHEST_PROTOCOL)) + dgst = hmac.new(self.key, pickled_data, hashlib.sha256).digest() + self.my_file.write(base64.b64encode(dgst) + b':' + + pickled_data + b'\n') def close(self): self.my_file.close() @@ -58,8 +65,9 @@ def __init__(self, send_info, project_root): self.project_root = project_root - if send_info.isdigit(): - self.sender = _SocketSender(int(send_info)) + if send_info[0].isdigit(): + port, key = send_info.split(':', 1) + self.sender = _SocketSender(int(port), key) else: self.sender = _FileSender(send_info) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.10.7/rope/base/project.py new/rope-0.11.0/rope/base/project.py --- old/rope-0.10.7/rope/base/project.py 2017-02-22 18:40:14.000000000 +0100 +++ new/rope-0.11.0/rope/base/project.py 2018-08-08 21:04:57.000000000 +0200 @@ -11,9 +11,9 @@ from rope.base.resources import File, Folder, _ResourceMatcher try: - import pickle -except ImportError: import cPickle as pickle +except ImportError: + import pickle class _Project(object): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.10.7/rope/base/pyobjectsdef.py new/rope-0.11.0/rope/base/pyobjectsdef.py --- old/rope-0.10.7/rope/base/pyobjectsdef.py 2017-02-24 22:06:11.000000000 +0100 +++ new/rope-0.11.0/rope/base/pyobjectsdef.py 2018-02-27 21:54:30.000000000 +0100 @@ -354,6 +354,9 @@ self.names[node.name] = pynames.DefinedName(pyfunction) self.defineds.append(pyfunction) + def _AsyncFunctionDef(self, node): + return self._FunctionDef(node) + def _Assign(self, node): ast.walk(node, _AssignVisitor(self)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.10.7/rope/base/stdmods.py new/rope-0.11.0/rope/base/stdmods.py --- old/rope-0.10.7/rope/base/stdmods.py 2017-02-22 18:40:14.000000000 +0100 +++ new/rope-0.11.0/rope/base/stdmods.py 2018-02-27 21:54:30.000000000 +0100 @@ -43,6 +43,10 @@ """ if "cpython" in name: return os.path.splitext(os.path.splitext(name)[0])[0] + # XXX: Special handling for Fedora python2 distribution + # See: https://github.com/python-rope/rope/issues/211 + if name == "timemodule.so": + return "time" return os.path.splitext(name)[0] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.10.7/rope/base/worder.py new/rope-0.11.0/rope/base/worder.py --- old/rope-0.10.7/rope/base/worder.py 2017-05-17 23:55:59.000000000 +0200 +++ new/rope-0.11.0/rope/base/worder.py 2018-08-03 19:56:11.000000000 +0200 @@ -65,6 +65,9 @@ def is_from_aliased(self, offset): return self.code_finder.is_from_aliased(offset) + def is_import_statement_aliased_module(self, offset): + return self.code_finder.is_import_statement_aliased_module(offset) + def find_parens_start_from_inside(self, offset): return self.code_finder.find_parens_start_from_inside(offset) @@ -317,7 +320,9 @@ last_import = self.code.rindex('import ', 0, offset) except ValueError: return False - return self._find_import_end(last_import + 7) >= offset + line_start = self._get_line_start(last_import) + return (self._find_import_end(last_import + 7) >= offset and + self._find_word_start(line_start) == last_import) def is_from_statement(self, offset): try: @@ -337,6 +342,27 @@ prev_word = self.code[line_start:stmt_start].strip() return prev_word == 'from' + def is_import_statement_aliased_module(self, offset): + if not self.is_import_statement(offset): + return False + try: + line_start = self._get_line_start(offset) + import_idx = self.code.rindex('import', line_start, offset) + imported_names = import_idx + 7 + except ValueError: + return False + # Check if the offset is within the imported names + if (imported_names - 1 > offset or + self._find_import_end(imported_names) < offset): + return False + try: + end = self._find_word_end(offset) + as_end = min(self._find_word_end(end + 1), len(self.code)) + as_start = self._find_word_start(as_end) + return self.code[as_start:as_end + 1] == 'as' + except ValueError: + return False + def is_a_name_after_from_import(self, offset): try: if len(self.code) > offset and self.code[offset] == '\n': @@ -368,8 +394,7 @@ end = self._find_word_end(offset) as_end = min(self._find_word_end(end + 1), len(self.code)) as_start = self._find_word_start(as_end) - if self.code[as_start:as_end + 1] == 'as': - return True + return self.code[as_start:as_end + 1] == 'as' except ValueError: return False @@ -463,7 +488,8 @@ while current > first: primary_start = current current = self._find_primary_start(current) - while current != first and self.code[current] not in '=,': + while current != first and (self.code[current] not in '=,' + or self.code[current-1] in '=!<>'): current = self._find_last_non_space_char(current - 1) primary = self.raw[current + 1:primary_start + 1].strip() if self.code[current] == '=': diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.10.7/rope/contrib/generate.py new/rope-0.11.0/rope/contrib/generate.py --- old/rope-0.10.7/rope/contrib/generate.py 2017-02-22 18:40:14.000000000 +0100 +++ new/rope-0.11.0/rope/contrib/generate.py 2018-05-11 20:56:15.000000000 +0200 @@ -42,15 +42,16 @@ class _Generate(object): - def __init__(self, project, resource, offset): + def __init__(self, project, resource, offset, goal_resource=None): self.project = project self.resource = resource + self.goal_resource = goal_resource self.info = self._generate_info(project, resource, offset) self.name = self.info.get_name() self._check_exceptional_conditions() def _generate_info(self, project, resource, offset): - return _GenerationInfo(project.pycore, resource, offset) + return _GenerationInfo(project.pycore, resource, offset, self.goal_resource) def _check_exceptional_conditions(self): if self.info.element_already_exists(): @@ -77,6 +78,9 @@ collector.add_change(start, end, definition) changes.add_change(change.ChangeContents( resource, collector.get_changed())) + if self.goal_resource: + relative_import = _add_relative_import_to_module(self.project, self.resource, self.goal_resource, self.name) + changes.add_change(relative_import) return changes def get_location(self): @@ -183,12 +187,22 @@ return change.ChangeContents(resource, module_imports.get_changed_source()) +def _add_relative_import_to_module(project, resource, imported, name): + pymodule = project.get_pymodule(resource) + import_tools = importutils.ImportTools(project) + module_imports = import_tools.module_imports(pymodule) + new_import = import_tools.get_from_import(imported, name) + module_imports.add_import(new_import) + return change.ChangeContents(resource, module_imports.get_changed_source()) + + class _GenerationInfo(object): - def __init__(self, pycore, resource, offset): + def __init__(self, pycore, resource, offset, goal_resource=None): self.pycore = pycore self.resource = resource self.offset = offset + self.goal_resource = goal_resource self.source_pymodule = self.pycore.project.get_pymodule(resource) finder = rope.base.evaluate.ScopeNameFinder(self.source_pymodule) self.primary, self.pyname = finder.get_primary_and_pyname_at(offset) @@ -201,7 +215,10 @@ def _get_goal_scope(self): if self.primary is None: - return self._get_source_scope() + if self.goal_resource: + return self.pycore.project.get_pymodule(self.goal_resource).get_scope() + else: + return self._get_source_scope() pyobject = self.primary.get_object() if isinstance(pyobject, pyobjects.PyDefinedObject): return pyobject.get_scope() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.10.7/rope/refactor/extract.py new/rope-0.11.0/rope/refactor/extract.py --- old/rope-0.10.7/rope/refactor/extract.py 2017-02-22 18:40:14.000000000 +0100 +++ new/rope-0.11.0/rope/refactor/extract.py 2018-08-03 19:56:11.000000000 +0200 @@ -251,8 +251,15 @@ finder = similarfinder.SimilarFinder(self.info.pymodule) matches = [] for start, end in regions: - matches.extend((finder.get_matches(collector.body_pattern, - collector.checks, start, end))) + region_matches = finder.get_matches(collector.body_pattern, + collector.checks, start, end) + # Don't extract overlapping regions + last_match_end = -1 + for region_match in region_matches: + start, end = region_match.get_region() + if last_match_end < start: + matches.append(region_match) + last_match_end = end collector.matches = matches def _where_to_search(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.10.7/rope/refactor/patchedast.py new/rope-0.11.0/rope/refactor/patchedast.py --- old/rope-0.10.7/rope/refactor/patchedast.py 2017-02-22 18:40:14.000000000 +0100 +++ new/rope-0.11.0/rope/refactor/patchedast.py 2018-02-27 21:54:30.000000000 +0100 @@ -268,15 +268,38 @@ self._handle(node, ['break']) def _Call(self, node): + def _arg_sort_key(node): + if isinstance(node, ast.keyword): + return (node.value.lineno, node.value.col_offset) + return (node.lineno, node.col_offset) + children = [node.func, '('] - args = list(node.args) + node.keywords - children.extend(self._child_nodes(args, ',')) + unstarred_args = [] + starred_and_keywords = list(node.keywords) + for i, arg in enumerate(node.args): + if hasattr(ast, 'Starred') and isinstance(arg, ast.Starred): + starred_and_keywords.append(arg) + else: + unstarred_args.append(arg) if getattr(node, 'starargs', None): - if args: - children.append(',') - children.extend(['*', node.starargs]) + starred_and_keywords.append(node.starargs) + starred_and_keywords.sort(key=_arg_sort_key) + children.extend(self._child_nodes(unstarred_args, ',')) + + # positional args come before keywords, *args comes after all + # positional args, and **kwargs comes last + if starred_and_keywords: + if len(children) > 2: + children.append(',') + for i, arg in enumerate(starred_and_keywords): + if arg == getattr(node, 'starargs', None): + children.append('*') + children.append(arg) + if i + 1 < len(starred_and_keywords): + children.append(',') + if getattr(node, 'kwargs', None): - if args or node.starargs is not None: + if len(children) > 2: children.append(',') children.extend(['**', node.kwargs]) children.append(')') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.10.7/rope.egg-info/PKG-INFO new/rope-0.11.0/rope.egg-info/PKG-INFO --- old/rope-0.10.7/rope.egg-info/PKG-INFO 2017-08-23 06:44:12.000000000 +0200 +++ new/rope-0.11.0/rope.egg-info/PKG-INFO 2018-08-08 21:18:36.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: rope -Version: 0.10.7 +Version: 0.11.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.10.7/rope.egg-info/SOURCES.txt new/rope-0.11.0/rope.egg-info/SOURCES.txt --- old/rope-0.10.7/rope.egg-info/SOURCES.txt 2017-08-23 06:44:12.000000000 +0200 +++ new/rope-0.11.0/rope.egg-info/SOURCES.txt 2018-08-08 21:18:36.000000000 +0200 @@ -108,6 +108,7 @@ ropetest/advanced_oi_test.py ropetest/builtinstest.py ropetest/codeanalyzetest.py +ropetest/doatest.py ropetest/historytest.py ropetest/objectdbtest.py ropetest/objectinfertest.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.10.7/ropetest/__init__.py new/rope-0.11.0/ropetest/__init__.py --- old/rope-0.10.7/ropetest/__init__.py 2017-02-22 18:40:14.000000000 +0100 +++ new/rope-0.11.0/ropetest/__init__.py 2018-08-08 21:04:57.000000000 +0200 @@ -6,6 +6,7 @@ import ropetest.projecttest import ropetest.codeanalyzetest +import ropetest.doatest import ropetest.type_hinting_test import ropetest.pycoretest import ropetest.pyscopestest @@ -25,6 +26,7 @@ result = unittest.TestSuite() result.addTests(ropetest.projecttest.suite()) result.addTests(ropetest.codeanalyzetest.suite()) + result.addTests(ropetest.doatest.suite()) result.addTests(ropetest.type_hinting_test.suite()) result.addTests(ropetest.pycoretest.suite()) result.addTests(ropetest.pyscopestest.suite()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.10.7/ropetest/builtinstest.py new/rope-0.11.0/ropetest/builtinstest.py --- old/rope-0.10.7/ropetest/builtinstest.py 2017-05-30 23:15:55.000000000 +0200 +++ new/rope-0.11.0/ropetest/builtinstest.py 2018-02-27 21:54:30.000000000 +0100 @@ -502,6 +502,11 @@ import rope.base.stdmods self.assertTrue('time' in rope.base.stdmods.standard_modules()) + def test_timemodule_normalizes_to_time(self): + import rope.base.stdmods + self.assertEqual( + rope.base.stdmods.normalize_so_name('timemodule.so'), 'time') + def suite(): result = unittest.TestSuite() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.10.7/ropetest/contrib/generatetest.py new/rope-0.11.0/ropetest/contrib/generatetest.py --- old/rope-0.10.7/ropetest/contrib/generatetest.py 2015-10-30 00:36:06.000000000 +0100 +++ new/rope-0.11.0/ropetest/contrib/generatetest.py 2018-05-11 20:56:15.000000000 +0200 @@ -25,8 +25,8 @@ def _get_generate(self, offset): return generate.GenerateVariable(self.project, self.mod, offset) - def _get_generate_class(self, offset): - return generate.GenerateClass(self.project, self.mod, offset) + def _get_generate_class(self, offset, goal_mod=None): + return generate.GenerateClass(self.project, self.mod, offset, goal_resource=goal_mod) def _get_generate_module(self, offset): return generate.GenerateModule(self.project, self.mod, offset) @@ -109,6 +109,16 @@ self.assertEquals('class C(object):\n pass\n\n\nc = C()\n', self.mod.read()) + def test_generating_classes_in_other_module(self): + code = 'c = C()\n' + self.mod.write(code) + changes = self._get_generate_class(code.index('C'), self.mod2).get_changes() + self.project.do(changes) + self.assertEquals('class C(object):\n pass\n', + self.mod2.read()) + self.assertEquals('from mod2 import C\nc = C()\n', + self.mod.read()) + def test_generating_modules(self): code = 'import pkg\npkg.mod\n' self.mod.write(code) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.10.7/ropetest/doatest.py new/rope-0.11.0/ropetest/doatest.py --- old/rope-0.10.7/ropetest/doatest.py 1970-01-01 01:00:00.000000000 +0100 +++ new/rope-0.11.0/ropetest/doatest.py 2018-08-08 21:04:57.000000000 +0200 @@ -0,0 +1,91 @@ +import base64 +import hashlib +import hmac +import multiprocessing +try: + import cPickle as pickle +except ImportError: + import pickle +import socket +try: + import unittest2 as unittest +except ImportError: + import unittest + + +from rope.base.oi import doa + + +class DOATest(unittest.TestCase): + + def try_CVE_2014_3539_exploit(self, receiver, payload): + # Simulated attacker writing to the socket + def attacker(data_port): + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.connect(('127.0.0.1', data_port)) + s_file = s.makefile('wb') + s_file.write(payload) + s.close() + + # Assume the attacker guesses the port correctly; 3037 is used by + # default if it is available. + attacker_proc = multiprocessing.Process(target=attacker, + args=(receiver.data_port,)) + + attacker_proc.start() + received_objs = list(receiver.receive_data()) + attacker_proc.join() + return received_objs + + def test_CVE_2014_3539_no_encoding(self): + # Attacker sends pickled data to the receiver socket. + receiver = doa._SocketReceiver() + + payload = pickle.dumps('def foo():\n return 123\n') + received_objs = self.try_CVE_2014_3539_exploit(receiver, payload) + + # Make sure the exploit did not run + self.assertEqual(0, len(received_objs)) + + def test_CVE_2014_3539_signature_mismatch(self): + # Attacker sends well-formed data with an incorrect signature. + receiver = doa._SocketReceiver() + + pickled_data = pickle.dumps('def foo():\n return 123\n', + pickle.HIGHEST_PROTOCOL) + digest = hmac.new(b'invalid-key', pickled_data, hashlib.sha256).digest() + payload = (base64.b64encode(digest) + b':' + + base64.b64encode(pickled_data) + b'\n') + received_objs = self.try_CVE_2014_3539_exploit(receiver, payload) + + # Make sure the exploit did not run + self.assertEqual(0, len(received_objs)) + + def test_CVE_2014_3539_sanity(self): + # Tests that sending valid, signed data on the socket does work. + receiver = doa._SocketReceiver() + + pickled_data = base64.b64encode( + pickle.dumps('def foo():\n return 123\n', + pickle.HIGHEST_PROTOCOL)) + digest = hmac.new(receiver.key, pickled_data, hashlib.sha256).digest() + payload = (base64.b64encode(digest) + b':' + pickled_data + b'\n') + received_objs = self.try_CVE_2014_3539_exploit(receiver, payload) + + # Make sure the exploit did not run + self.assertEqual(1, len(received_objs)) + + def test_compare_digest_compat(self): + self.assertTrue(doa._compat_compare_digest('', '')) + self.assertTrue(doa._compat_compare_digest('abc', 'abc')) + self.assertFalse(doa._compat_compare_digest('abc', 'abd')) + self.assertFalse(doa._compat_compare_digest('abc', 'abcd')) + + +def suite(): + result = unittest.TestSuite() + result.addTests(unittest.makeSuite(DOATest)) + return result + +if __name__ == '__main__': + unittest.main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.10.7/ropetest/refactor/extracttest.py new/rope-0.11.0/ropetest/refactor/extracttest.py --- old/rope-0.10.7/ropetest/refactor/extracttest.py 2017-02-22 18:40:14.000000000 +0100 +++ new/rope-0.11.0/ropetest/refactor/extracttest.py 2018-08-03 19:56:11.000000000 +0200 @@ -636,6 +636,27 @@ ' self.attr = self.new_func(p2)\n' self.assertEquals(expected, refactored) + def test_extract_method_and_similar_sttemnts_overlapping_regions(self): + code = 'def func(p):\n' \ + ' a = p\n' \ + ' b = a\n' \ + ' c = b\n' \ + ' d = c\n' \ + ' return d' + start = code.index('a') + end = code.rindex('a') + 1 + refactored = self.do_extract_method( + code, start, end, 'new_func', similar=True) + expected = 'def func(p):\n' \ + ' b = new_func(p)\n' \ + ' d = new_func(b)\n' \ + ' return d\n' \ + 'def new_func(p):\n' \ + ' a = p\n' \ + ' b = a\n' \ + ' return b\n' + self.assertEquals(expected, refactored) + def test_definition_should_appear_where_it_is_visible(self): code = 'if True:\n a = 1\nelse:\n b = 1\n' start = code.rindex('1') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.10.7/ropetest/refactor/inlinetest.py new/rope-0.11.0/ropetest/refactor/inlinetest.py --- old/rope-0.10.7/ropetest/refactor/inlinetest.py 2017-02-22 18:40:14.000000000 +0100 +++ new/rope-0.11.0/ropetest/refactor/inlinetest.py 2018-08-03 19:56:11.000000000 +0200 @@ -217,6 +217,13 @@ self._inline2(self.mod, self.mod.read().index('a_func') + 1) self.assertEquals('print(1, 3)\n', self.mod.read()) + def test_arguments_containing_comparisons(self): + self.mod.write('def a_func(param1, param2, param3):' + '\n param2.name\n' + 'a_func(2 <= 1, item, True)\n') + self._inline2(self.mod, self.mod.read().index('a_func') + 1) + self.assertEquals('item.name\n', self.mod.read()) + def test_badly_formatted_text(self): self.mod.write('def a_func ( param1 = 1 ,param2 = 2 ) :' '\n print(param1, param2)\n' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.10.7/ropetest/refactor/patchedasttest.py new/rope-0.11.0/ropetest/refactor/patchedasttest.py --- old/rope-0.10.7/ropetest/refactor/patchedasttest.py 2017-02-22 18:40:14.000000000 +0100 +++ new/rope-0.11.0/ropetest/refactor/patchedasttest.py 2018-02-27 21:54:30.000000000 +0100 @@ -324,7 +324,7 @@ ' ', 'keyword', '', ')']) @testutils.only_for_versions_lower('3.5') - def test_call_func_and_start_args(self): + def test_call_func_and_star_args(self): source = 'f(1, *args)\n' ast_frag = patchedast.get_patched_ast(source, True) checker = _ResultChecker(self, ast_frag) @@ -333,7 +333,7 @@ ' ', '*', '', 'Name', '', ')']) @testutils.only_for('3.5') - def test_call_func_and_start_argspython35(self): + def test_call_func_and_star_argspython35(self): source = 'f(1, *args)\n' ast_frag = patchedast.get_patched_ast(source, True) checker = _ResultChecker(self, ast_frag) @@ -342,7 +342,7 @@ ' *', 'Starred', '', ')']) @testutils.only_for_versions_lower('3.5') - def test_call_func_and_only_dstart_args(self): + def test_call_func_and_only_dstar_args(self): source = 'f(**kwds)\n' ast_frag = patchedast.get_patched_ast(source, True) checker = _ResultChecker(self, ast_frag) @@ -350,7 +350,7 @@ 'Call', ['Name', '', '(', '', '**', '', 'Name', '', ')']) @testutils.only_for('3.5') - def test_call_func_and_only_dstart_args_python35(self): + def test_call_func_and_only_dstar_args_python35(self): source = 'f(**kwds)\n' ast_frag = patchedast.get_patched_ast(source, True) checker = _ResultChecker(self, ast_frag) @@ -983,6 +983,60 @@ checker.check_children( 'Delete', ['del', ' ', 'Name', '', ',', ' ', 'Name']) + @testutils.only_for_versions_lower('3.5') + def test_starargs_before_keywords(self): + source = 'foo(*args, a=1)\n' + ast_frag = patchedast.get_patched_ast(source, True) + checker = _ResultChecker(self, ast_frag) + checker.check_children( + 'Call', ['Name', '', '(', '', '*', '', 'Name', '', ',', ' ', + 'keyword', '', ')']) + + @testutils.only_for_versions_lower('3.5') + def test_starargs_in_keywords(self): + source = 'foo(a=1, *args, b=2)\n' + ast_frag = patchedast.get_patched_ast(source, True) + checker = _ResultChecker(self, ast_frag) + checker.check_children( + 'Call', ['Name', '', '(', '', 'keyword', '', ',', ' ', '*', '', + 'Name', '', ',', ' ', 'keyword', '',')']) + + @testutils.only_for_versions_lower('3.5') + def test_starargs_after_keywords(self): + source = 'foo(a=1, *args)\n' + ast_frag = patchedast.get_patched_ast(source, True) + checker = _ResultChecker(self, ast_frag) + checker.check_children( + 'Call', ['Name', '', '(', '', 'keyword', '', ',', ' ', '*', '', + 'Name', '', ')']) + + @testutils.only_for('3.5') + def test_starargs_before_keywords(self): + source = 'foo(*args, a=1)\n' + ast_frag = patchedast.get_patched_ast(source, True) + checker = _ResultChecker(self, ast_frag) + checker.check_children( + 'Call', ['Name', '', '(', '*', 'Starred', '', ',', ' ', + 'keyword', '', ')']) + + @testutils.only_for('3.5') + def test_starargs_in_keywords(self): + source = 'foo(a=1, *args, b=2)\n' + ast_frag = patchedast.get_patched_ast(source, True) + checker = _ResultChecker(self, ast_frag) + checker.check_children( + 'Call', ['Name', '', '(', '', 'keyword', '', ',', ' *', + 'Starred', '', ',', ' ', 'keyword', '',')']) + + @testutils.only_for('3.5') + def test_starargs_after_keywords(self): + source = 'foo(a=1, *args)\n' + ast_frag = patchedast.get_patched_ast(source, True) + checker = _ResultChecker(self, ast_frag) + checker.check_children( + 'Call', ['Name', '', '(', '', 'keyword', '', ',', ' *', + 'Starred', '', ')']) + class _ResultChecker(object): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.10.7/ropetest/refactor/renametest.py new/rope-0.11.0/ropetest/refactor/renametest.py --- old/rope-0.10.7/ropetest/refactor/renametest.py 2017-02-22 18:40:14.000000000 +0100 +++ new/rope-0.11.0/ropetest/refactor/renametest.py 2018-05-11 20:56:15.000000000 +0200 @@ -165,6 +165,13 @@ self.assertEquals('def new_func():\n pass\nnew_func()\n', refactored) + @testutils.only_for('3.5') + def test_renaming_async_function(self): + code = 'async def a_func():\n pass\na_func()' + refactored = self._local_rename(code, len(code) - 5, 'new_func') + self.assertEquals('async def new_func():\n pass\nnew_func()', + refactored) + def test_renaming_functions_across_modules(self): mod1 = testutils.create_module(self.project, 'mod1') mod1.write('def a_func():\n pass\na_func()\n') @@ -216,6 +223,16 @@ self.project.find_module('newmod') is not None) self.assertEquals('from newmod import a_func\n', mod2.read()) + def test_renaming_modules_aliased(self): + mod1 = testutils.create_module(self.project, 'mod1') + mod1.write('def a_func():\n pass\n') + mod2 = testutils.create_module(self.project, 'mod2') + mod2.write('import mod1 as m\nm.a_func()\n') + self._rename(mod1, None, 'newmod') + self.assertTrue(not mod1.exists() and + self.project.find_module('newmod') is not None) + self.assertEquals('import newmod as m\nm.a_func()\n', mod2.read()) + def test_renaming_packages(self): pkg = testutils.create_package(self.project, 'pkg') mod1 = testutils.create_module(self.project, 'mod1', pkg) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rope-0.10.7/setup.cfg new/rope-0.11.0/setup.cfg --- old/rope-0.10.7/setup.cfg 2017-08-23 06:44:12.000000000 +0200 +++ new/rope-0.11.0/setup.cfg 2018-08-08 21:18:36.000000000 +0200 @@ -1,5 +1,4 @@ [egg_info] tag_build = tag_date = 0 -tag_svn_revision = 0
