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
 


Reply via email to