Commit 835afd55 authored by Arnaud Fontaine's avatar Arnaud Fontaine

Import rope_0.10.3.orig.tar.gz

parent 46d8917b
Metadata-Version: 1.1
Name: rope
Version: 0.10.2
Version: 0.10.3
Summary: a python refactoring library...
Author: Ali Gholami Rudi
......@@ -8,8 +8,6 @@ Author-email:
License: GNU GPL
**Note:** *Please note that this project has been moved to* `GitHub python-rope / rope`_
.. _GitHub python-rope / rope:
......@@ -23,7 +21,7 @@ Description:
`Rope`_ is a python refactoring library.
.. _`rope`:
.. _`rope`:
New Features
**Note:** *Please note that this project has been moved to* `GitHub python-rope / rope`_
.. _GitHub python-rope / rope:
......@@ -14,7 +12,7 @@ Overview
`Rope`_ is a python refactoring library.
.. _`rope`:
.. _`rope`:
New Features
......@@ -3,19 +3,19 @@
Get Involved!
Getting Involved!
Rope's main goal is being a good refactoring tool for python. It also
provides some IDE helpers. If you like to contribute, you're welcome!
provides some IDE helpers. If you would like to contribute, you're
welcome to!
How to Help Rope?
Rope mailing list is `rope-dev (at)`_. You can send
a mail to ``rope-dev-subscribe (at) googlegroups [dot] com`` to
Rope's mailing list is `rope-dev (at)`_. Click the
"Join group to post" button to subscribe. Then:
* Use rope
* Send bug reports and request features
......@@ -28,8 +28,8 @@ subscribe.
Wish List
You are welcome to send your patches to `rope-dev (at)`_ mailing list. Here is only a list of suggestions.
You are welcome to send your patches to the `rope-dev (at)`_ mailing list. Here is a list of suggestions.
......@@ -78,12 +78,8 @@ more information.
Source Repository
Rope uses Mercurial_ CMS:
* Rope main branch:
* Rope py3k branch:
.. _Mercurial:
Rope uses GitHub_. The repository exists at
Submitting patches
......@@ -91,11 +87,21 @@ Submitting patches
Patches are welcome.
Patch style
Programming Style
* Follow :PEP:`8`.
* Use four spaces for indentation.
* Include good unit-tests if possible.
* Include good unit-tests when appropriate.
* Rope test suite should pass after patching
* Use ``hg export`` format to preserve your identity
Sending Patches
Follow the instructions on GitHub_ on how to setup Git and fork the
`python-rope/rope`_ repository. Once your changes are ready, send a
`pull request`_ for review.
.. _GitHub:
.. _`python-rope/rope`:
.. _`pull request`:
This diff is collapsed.
This diff is collapsed.
"""rope, a python refactoring library"""
INFO = __doc__
VERSION = '0.10.2'
VERSION = '0.10.3'
Copyright (C) 2014-2015 Matej Cepl
Copyright (C) 2006-2012 Ali Gholami Rudi
Copyright (C) 2009-2012 Anton Gritsay
......@@ -3,18 +3,23 @@ from _ast import *
from rope.base import fscommands
except NameError:
unicode = str
def parse(source, filename='<string>'):
# NOTE: the raw string should be given to `compile` function
if isinstance(source, unicode):
source = fscommands.unicode_to_file_data(source)
if '\r' in source:
source = source.replace('\r\n', '\n').replace('\r', '\n')
if not source.endswith('\n'):
source += '\n'
if b'\r' in source:
source = source.replace(b'\r\n', b'\n').replace(b'\r', b'\n')
if not source.endswith(b'\n'):
source += b'\n'
return compile(source, filename, 'exec', _ast.PyCF_ONLY_AST)
except (TypeError, ValueError), e:
except (TypeError, ValueError) as e:
error = SyntaxError()
error.lineno = 1
error.filename = filename
"""This module trys to support builtin types and functions."""
import inspect
except NameError:
raw_input = input
import rope.base.evaluate
from rope.base import pynames, pyobjects, arguments, utils, ast
......@@ -32,7 +36,7 @@ class BuiltinModule(pyobjects.AbstractModule):
if self.pycore is not None:
submodules = self.pycore._builtin_submodules(
for name, module in submodules.iteritems():
for name, module in submodules.items():
result[name] = rope.base.builtins.BuiltinName(module)
return result
......@@ -266,7 +270,10 @@ class List(BuiltinClass):
# Getting methods
collector('__getitem__', function=self._list_get)
collector('pop', function=self._list_get)
collector('__getslice__', function=self._self_get)
collector('__getslice__', function=self._self_get)
except AttributeError:
super(List, self).__init__(list, collector.attributes)
......@@ -487,14 +494,21 @@ class Str(BuiltinClass):
collector = _AttributeCollector(str)
collector('__iter__', get_iterator(self_object), check_existence=False)
self_methods = ['__getitem__', '__getslice__', 'capitalize', 'center',
'decode', 'encode', 'expandtabs', 'join', 'ljust',
self_methods = ['__getitem__', 'capitalize', 'center',
'encode', 'expandtabs', 'join', 'ljust',
'lower', 'lstrip', 'replace', 'rjust', 'rstrip',
'strip', 'swapcase', 'title', 'translate', 'upper',
for method in self_methods:
collector(method, self_object)
py2_self_methods = ["__getslice__", "decode"]
for method in py2_self_methods:
collector(method, self_object)
except AttributeError:
for method in ['rsplit', 'split', 'splitlines']:
collector(method, get_list(self_object))
......@@ -568,7 +582,7 @@ class File(BuiltinClass):
attributes = {}
def add(name, returned=None, function=None):
builtin = getattr(file, name, None)
builtin = getattr(open, name, None)
attributes[name] = BuiltinName(
BuiltinFunction(returned=returned, function=function,
......@@ -578,7 +592,7 @@ class File(BuiltinClass):
for method in ['close', 'flush', 'lineno', 'isatty', 'seek', 'tell',
'truncate', 'write', 'writelines']:
super(File, self).__init__(file, attributes)
super(File, self).__init__(open, attributes)
get_file = _create_builtin_getter(File)
......@@ -369,7 +369,7 @@ class _ResourceOperations(object):
except IOError, e:
except IOError as e:
raise exceptions.RopeError(e)
......@@ -19,9 +19,7 @@ class ChangeCollector(object):
if not self.changes:
return None
def compare_changes(change1, change2):
return cmp(change1[:2], change2[:2])
self.changes.sort(key=lambda x: x[:2])
pieces = []
last_changed = 0
for change in self.changes:
......@@ -177,7 +175,7 @@ class LogicalLineFinder(object):
block_start = get_block_start(self.lines, line_number, indents)
return self._block_logical_line(block_start, line_number)
except IndentationError, e:
except IndentationError as e:
tries += 1
if tries == 5:
raise e
......@@ -222,7 +220,7 @@ class LogicalLineFinder(object):
if line_number <= end:
return (start, end)
last_end = end + 1
except tokenize.TokenError, e:
except tokenize.TokenError as e:
current = e.args[1][0]
return (last_end, max(last_end, current - 1))
return (last_end, None)
......@@ -355,7 +353,7 @@ def count_line_indents(line):
def get_string_pattern():
start = r'(\b[uU]?[rR]?)?'
longstr = r'%s"""(\\.|"(?!"")|\\\n|[^"\\])*"""' % start
shortstr = r'%s"(\\.|[^"\\\n])*"' % start
shortstr = r'%s"(\\.|\\\n|[^"\\])*"' % start
return '|'.join([longstr, longstr.replace('"', "'"),
shortstr, shortstr.replace('"', "'")])
......@@ -79,6 +79,16 @@ def set_prefs(prefs):
# appear in the importing namespace.
prefs['ignore_bad_imports'] = False
# If `True`, rope will transform a comma list of imports into
# multiple separate import statements when organizing
# imports.
prefs['split_imports'] = False
# 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
def project_opened(project):
"""This function is called after opening the project"""
......@@ -10,6 +10,10 @@ import os
import shutil
import subprocess
except NameError:
unicode = str
def create_fscommands(root):
dirlist = os.listdir(root)
......@@ -240,16 +244,27 @@ def read_file_coding(path):
def read_str_coding(source):
if type(source) == bytes:
newline = b'\n'
newline = '\n'
# source = source.decode("utf-8")
#except AttributeError:
# pass
first = source.index('\n') + 1
second = source.index('\n', first) + 1
first = source.index(newline) + 1
second = source.index(newline, first) + 1
except ValueError:
second = len(source)
return _find_coding(source[:second])
def _find_coding(text):
coding = 'coding'
if type(text) == bytes:
coding = b'coding'
coding = "coding"
start = text.index(coding) + len(coding)
if text[start] not in '=:':
......@@ -3,6 +3,8 @@ import os.path
import rope.base.project
import rope.base.pycore
from rope.base import pyobjectsdef
from rope.base import utils
from rope.base import taskhandle
......@@ -17,7 +19,7 @@ def path_to_resource(project, path, type=None):
`Project.get_file()`, and `Project.get_folder()` methods.
project_path = relative(project.address, path)
project_path = path_relative_to_project_root(project, path)
if project_path is None:
project_path = rope.base.project._realpath(path)
project = rope.base.project.get_no_project()
......@@ -30,6 +32,10 @@ def path_to_resource(project, path, type=None):
return None
def path_relative_to_project_root(project, path):
return relative(project.address, path)
def relative(root, path):
root = rope.base.project._realpath(root).replace(os.path.sep, '/')
path = rope.base.project._realpath(path).replace(os.path.sep, '/')
......@@ -55,14 +61,62 @@ def report_change(project, path, old_content):
def analyze_module(project, resource):
"""Perform static object analysis on a python file in the project
Note that this might be really time consuming.
def analyze_modules(project, task_handle=taskhandle.NullTaskHandle()):
"""Perform static object analysis on all python files in the project
Note that this might be really time consuming.
resources = project.pycore.get_python_files()
resources = project.get_python_files()
job_set = task_handle.create_jobset('Analyzing Modules', len(resources))
for resource in resources:
analyze_module(project, resource)
def get_string_module(project, code, resource=None, force_errors=False):
"""Returns a `PyObject` object for the given code
If `force_errors` is `True`, `exceptions.ModuleSyntaxError` is
raised if module has syntax errors. This overrides
``ignore_syntax_errors`` project config.
return pyobjectsdef.PyModule(project.pycore, code, resource,
def get_string_scope(project, code, resource=None):
"""Returns a `Scope` object for the given code"""
return get_string_module(project, code, resource).get_scope()
def is_python_file(project, resource):
return project.pycore.is_python_file(resource)
def modname(resource):
if resource.is_folder():
module_name =
source_folder = resource.parent
elif == '':
module_name =
source_folder = resource.parent.parent
module_name =[:-3]
source_folder = resource.parent
while source_folder != source_folder.parent and \
module_name = + '.' + module_name
source_folder = source_folder.parent
return module_name
import cPickle as pickle
import pickle
except ImportError:
import cPickle as pickle
import marshal
import os
import socket
......@@ -25,11 +28,11 @@ class PythonFileRunner(object):
"""Execute the process"""
env = dict(os.environ)
file_path = self.file.real_path
path_folders = self.pycore.get_source_folders() + \
path_folders = self.pycore.project.get_source_folders() + \
env['PYTHONPATH'] = os.pathsep.join(folder.real_path
for folder in path_folders)
runmod_path = self.pycore.find_module('rope.base.oi.runmod').real_path
runmod_path = self.pycore.project.find_module('rope.base.oi.runmod').real_path
self.receiver = None
send_info = '-'
......@@ -21,6 +21,16 @@ class MemoryDB(objectdb.FileDict):
def keys(self):
return self._files.keys()
def __iter__(self):
for f in self._files:
yield f
def __len__(self):
return len(self._files)
def __setitem__(self):
raise NotImplementedError()
def __contains__(self, key):
return key in self._files
......@@ -76,6 +86,17 @@ class FileInfo(objectdb.FileInfo):
def __delitem__(self, key):
del self.scopes[key]
def __iter__(self):
for s in self.scopes:
yield s
def __len__(self):
return len(self.scopes)
def __setitem__(self):
raise NotImplementedError()
class ScopeInfo(objectdb.ScopeInfo):
import UserDict
from __future__ import print_function
from collections import MutableMapping
except ImportError:
from UserDict import DictMixin as MutableMapping
class ObjectDB(object):
......@@ -78,7 +82,7 @@ class ObjectDB(object):
result = self.files[path][key]
if isinstance(result, dict):
print self.files, self.files[path], self.files[path][key]
print(self.files, self.files[path], self.files[path][key])
return result
def _file_removed(self, path):
......@@ -120,13 +124,13 @@ class _NullScopeInfo(object):
raise NotImplementedError()
class FileInfo(UserDict.DictMixin):
class FileInfo(MutableMapping):
def create_scope(self, key):
class FileDict(UserDict.DictMixin):
class FileDict(MutableMapping):
def create(self, key):
except NameError:
def execfile(fn, global_vars, local_vars):
with open(fn) as f:
code = compile(, fn, 'exec')
exec(code, global_vars, local_vars)
def __rope_start_everything():
import os
import sys
import socket
import cPickle as pickle
import pickle
except ImportError:
import cPickle as pickle
import marshal
import inspect
import types
......@@ -166,14 +177,14 @@ def __rope_start_everything():
if isinstance(object_, types.CodeType):
return self._get_persisted_code(object_)
if isinstance(object_, types.FunctionType):
return self._get_persisted_code(object_.func_code)
return self._get_persisted_code(object_.__code__)
if isinstance(object_, types.MethodType):
return self._get_persisted_code(object_.im_func.func_code)
return self._get_persisted_code(object_.__func__.__code__)
if isinstance(object_, types.ModuleType):
return self._get_persisted_module(object_)
if isinstance(object_, (str, unicode, list, dict, tuple, set)):
return self._get_persisted_builtin(object_)
if isinstance(object_, (types.TypeType, types.ClassType)):
if isinstance(object_, type):
return self._get_persisted_class(object_)
return ('instance', self._get_persisted_class(type(object_)))
......@@ -202,7 +202,7 @@ class TextualToPyObject(object):
def _get_pymodule(self, path):
resource = self.path_to_resource(path)
if resource is not None:
return self.project.pycore.resource_to_pyobject(resource)
return self.project.get_pymodule(resource)
def path_to_resource(self, path):
......@@ -278,8 +278,8 @@ class DOITextualToPyObject(TextualToPyObject):
def path_to_resource(self, path):
import rope.base.libutils
root = self.project.address
relpath = rope.base.libutils.relative(root, path)
relpath = rope.base.libutils.path_relative_to_project_root(
self.project, path)
if relpath is not None:
path = relpath
return super(DOITextualToPyObject, self).path_to_resource(path)
import cPickle as pickle
import os
import shutil
import sys
......@@ -8,6 +7,20 @@ import rope.base.fscommands
from rope.base import exceptions, taskhandle, prefs, history, pycore, utils
import rope.base.resourceobserver as resourceobserver
from rope.base.resources import File, Folder, _ResourceMatcher
from rope.base.exceptions import ModuleNotFoundError
import pickle
except ImportError:
import cPickle as pickle
except NameError:
def execfile(fn, global_vars, local_vars):
with open(fn) as f:
code = compile(, fn, 'exec')
exec(code, global_vars, local_vars)
class _Project(object):
......@@ -17,6 +30,7 @@ class _Project(object):
self.fscommands = fscommands
self.prefs = prefs.Prefs()
self.data_files = _DataFiles(self)
self._custom_source_folders = []
def get_resource(self, resource_name):
"""Get a resource in a project.
......@@ -41,6 +55,40 @@ class _Project(object):
raise exceptions.ResourceNotFoundError('Unknown resource '
+ resource_name)
def get_module(self, name, folder=None):
"""Returns a `PyObject` if the module was found."""
# check if this is a builtin module
pymod = self.pycore.builtin_module(name)
if pymod is not None:
return pymod
module = self.find_module(name, folder)
if module is None:
raise ModuleNotFoundError('Module %s not found' % name)
return self.pycore.resource_to_pyobject(module)
def get_python_path_folders(self):
result = []
for src in self.prefs.get('python_path', []) + sys.path:
src_folder = get_no_project().get_resource(src)
except exceptions.ResourceNotFoundError:
return result
# INFO: It was decided not to cache source folders, since:
# - Does not take much time when the root folder contains
# packages, that is most of the time
# - We need a separate resource observer; ``
# does not get notified about module and folder creations
def get_source_folders(self):
"""Returns project source folders"""
if self.root is None:
return []
result = list(self._custom_source_folders)
return result
def validate(self, folder):
"""Validate files and folders contained in this folder
......@@ -71,6 +119,9 @@ class _Project(object):
""", task_handle=task_handle)
def get_pymodule(self, resource, force_errors=False):
return self.pycore.resource_to_pyobject(resource, force_errors)
def get_pycore(self):
return self.pycore
......@@ -82,12 +133,45 @@ class _Project(object):
"""Get the folder with `path` (it may not exist)"""
return Folder(self, path)
def is_ignored(self, resource):
return False
def get_prefs(self):
return self.prefs
def get_relative_module(self, name, folder, level):
module = self.find_relative_module(name, folder, level)
if module is None:
raise ModuleNotFoundError('Module %s not found' % name)
return self.pycore.resource_to_pyobject(module)
def find_module(self, modname, folder=None):
"""Returns a resource corresponding to the given module
returns None if it can not be found
for src in self.get_source_folders():
module = _find_module_in_folder(src, modname)
if module is not None:
return module
for src in self.get_python_path_folders():
module = _find_module_in_folder(src, modname)
if module is not None:
return module
if folder is not None:
module = _find_module_in_folder(folder, modname)
if module is not None:
return module
return None
def find_relative_module(self, modname, folder, level):
for i in range(level - 1):
folder = folder.parent
if modname == '':
return folder
return _find_module_in_folder(folder, modname)
def is_ignored(self, resource):
return False
def _get_resource_path(self, name):
......@@ -144,10 +228,22 @@ class Project(_Project):
if ropefolder is not None: