1. zjes
  2. rope_py3k

Commits

Ali Gholami Rudi  committed 73275ae

Change method signature and class hierarchies
Supporting zip and enumerate builtin functions
Renaming refactoring classes

  • Participants
  • Parent commits 242ba74
  • Branches trunk

Comments (0)

Files changed (36)

File docs/dev/done.txt

View file
 ===========
 
 
+- Performing change signature in class hierarchies : February 14, 2007
+
+
+- Supporting builtin `zip` and `enumerate` : February 14, 2007
+
+
 - Replace method with method object : February 12, 2007
 
 
 - Execute command; ``M-x`` : February 10, 2007
 
 
-- Changing editor font in ``~/.rope`` : February 9, 2007
+- Changing editor font and keybinding in ``~/.rope`` : February 9, 2007
 
 
 - Having two keybindings emacs/normal : February 9, 2007

File docs/dev/issues.txt

View file
 * Static type inference(new, better ways)
 * Exclusion principle for occurrence finding
 * Changing structure refactorings; for example: ``a = b -> a(b.c)``
-* Better library interface
 
 
 Hot Topics
 
 * `Better occurrence finding`_
 * `Allowing non-existent resources`_
-* `Python's Implicit Interfaces`_
-* `Rope's preference system`_
+* `Python's implicit interfaces`_
 * `Having virtual PyModules`_
 * Indexing source files for faster occurrence finding
 * Faster module running
 * Finding available refactorings
 
 
-Better Occurrencd Finding
+Multiple Function/Class Definitions
+===================================
+
+Multiple function definitions are known to make lots of mysterious
+problems when performing refactorings.  We should report that to
+the user somehow.
+
+Note: Maybe we should care about redefining any `DefinedObject`.
+
+* Allowing multiple name definitions
+
+  The current implementation doesn't and there aren't good reasons
+  for supporting them.  Anyway, for supporting multiple definitions
+  with the same name we can hold a list rather than a single `PyName`
+  in `PyObject`\s.
+
+* Raising an exception:
+
+  This does not seem to be a good approach.  The existence a
+  duplicate function causes problems only on some conditions and
+  many tasks work as expected.
+
+* Only printing a warning
+
+  The thing is that the rope library cannot write anything to the
+  output.  The `ui` can but not the `base`.
+
+* Maybe we can think of a way for issuing warnings rope encounters
+
+  The warnings seem to belong to the IDE rather than the base.  But
+  the problem is that many warnings are seen in the base package.
+
+
+Better Occurrence Finding
 =========================
 
 The current implementation for finding occurrences of a `PyName` is to
 Or maybe we can use a strategy object for searching.
 
 
-Local History
-=============
-
-Goals:
-
-* Better undoing mechanisms
-* Undoing unrelated refactorings in any order
-* Undoing file operations performed by editing
-* Undoing individual files
-* Moving undo information from `PythonRefactoring` to `Project`
-* Finding changes to a file
-* Saving undo information across sessions?
-* Supporting virtual `PyModule`\s?
-
-Issues:
-
-* Unanticipated changes
-* Having version control systems in parallel
-* Memory inefficiency
-* Saving removed files and folders
-
-Each project change consists of a few basic changes.
-
-* change file contents
-* move resource
-* create file
-* create folder
-* remove resource
-
-
 Allowing Non-Existent Resources
 ===============================
 
 * Updating global `PyCore` after performing changes
 
 
-Inline Method
-=============
-
-* Which of the variables should be renamed?
-* What to do about parameter assignments?
-* What to do about staticmethod and classmethod decorators
-* Moving used imports and importing defining module globals
-* Inlining generators
-* Inner functions
-
-
 Using ASTs For Transformations
 ==============================
 
 be inferred.
 
 
-Refactoring `rope.codeanalyze` Module
-=====================================
-
-Merging `WordRangeFinder` and `StatementRangeFinder`.  Physical source
-divisions:
-
-* scope
-* block
-* logical line
-* primary
-
-After this refactoring, many places of rope can be refactored.  The
-logical line is very useful in many places for instance.
-
-
 The GUI Mess; Working More on the UI Parts
 ==========================================
 

File docs/dev/library.txt

View file
 
 Have a look at `rope.refactor` package and its sub-modules.  For
 example for performing a move refactoring you can create a
-`MoveRefactoring` object like this::
+`Move` object like this::
 
-  mover = MoveRefactoring(project, resource, offset)
+  mover = Move(project, resource, offset)
 
 Where `resource` and `offset` is the location to perform the
 refactoring.
   >>> assert mod2 == pycore.find_module('pkg.mod2')
 
   # Performing rename refactoring on `mod1.a_var`
-  >>> from rope.refactor.rename import RenameRefactoring
-  >>> changes = RenameRefactoring(pycore, mod1, 1).get_changes('new_var')
+  >>> from rope.refactor.rename import Rename
+  >>> changes = Rename(pycore, mod1, 1).get_changes('new_var')
   >>> project.do(changes)
   >>> mod1.read()
   u'new_var = 10\n'

File docs/dev/stories.txt

View file
 IDE And UI Stories
 ==================
 
-* Configuring keys
-* Configuring fonts
 * Showing syntactical errors
 * Editor folding
 * Variable indentation and tab size
 * Replacement; M-%
 * Remembering last open project
 * Go to matching parenthesis
-* Enhancing editor
-
-  * Select all; C-x h
-  * Fixed places for StatusTexts
-
 * Indenting a range of file
 * Auto completion type
 
   * Customizing CWD and parameters
   * Running last run
 
-* View type hierarchy
-* Open Type; C-T
-
 
 Stories
 =======
 > Public Release 0.5 : May 6, 2007
 
 
+* View type hierarchy
+
+
+* Open Type; ``C-T``
+
+
 * Saving history across sessions
 
 
 * Handling the return type of ``yield`` keyword
 
 
-* Handling the type of object after ``with/as`` statements
+* Finding similar statements when extracting variable/method
 
 
-* Finding similar statements when extracting variable/method
+* Encapsulate field using properties
 
 
 * Extracting methods from pieces with only one return/yield statement
 * Inlining a single occurrence
 
 
-* Performing change method signature in class hierarchies
-
-
 * Asking whether to encapsulate field in the class itself
 
 
 * Performing import action only on one import statement
 
 
-* Changing signature in class hierarchies
+* Handling the type of object after ``with/as`` statements
 
 
 > Public Release 0.5m1 : February 18, 2007

File docs/dev/workingon.txt

View file
-Refactoring
-===========
+Small Stories
+=============
 
-- Replace Method With Method Object:
+- Controlling rename in hierarchies
+- Change Signature And Class Hierarchies
 
-  - Multi-line function header
-  - Simple parameters
-  - ``self`` parameter
-  - Using parameters in ``__call__`` body
-  - Args_arg, kwds_arg
-  - Check performing on things other than functions
-  - Adding to UI
-  - Changing the caller
-  - Nested and class methods
+  - Adding a keyword argument for telling whether to search hierarchies
+  - What if its not a method
+  - Adding an option to the UI
 
-- Using `functionutils.DefinitionInfo` in show doc
-- Get pyname on keywords
-- Proposing `functionutils.DefinitionInfo.arg` while none exists
-- Extract method and  ``a = 1 + a\n`` and ``a += 1\n``
-- ``core.set('show_menu_bar', False)``
-- ``core.set('show_status_bar', False)``
-- ``core.set('show_buffer_list_bar', False)``
-- Only showing active actions in current context in execute command
-- ``C-g`` and code assist dialog
-- Problems for inside list comprehension assists
+- `enumerate` builtin function
+- `zip` builtin function
+- Renaming "refresh_project" to "validate_project"
+- Handling wrong arguments to `zip`
+- Adding ``!`` mark in buffer title when it is removed while editing
+- Not stopping in local to field when field already exists
 
-* Showing pysvn urls in docs
+- Mass renaming refactoring classes
+
+  - `ConvertLocalToFieldRefactoring` to `LocalToField`
+  - `MoveRefactoring` to `Move`
+  - `RenameRefactoring` to `Rename`
+  - `InlineRefactoring` to `Inline`
+  - `ExtractMethodRefactoring` to `ExtractMethod`
+  - `ExtractVariable` to `ExtractVariable`
+  - `EncapsulateFieldRefactoring` to `EncapsulateField`
+  - `TransformModuleToPackage` to `ModuleToPackage`
+
+* Reporting multiple definition problems
+* Consider doing `Change`\s sometime in the future and their fields
+
+* Showing properties in quick outline
+* Docs for builtin functions and properties
+* Lambdas as functions; consider their parameters
+* Saving a file that does not exist; Allowing nonexistent resources
 * Changing ``C-a C-a`` to move to the first character in the line
 * Changing open project dialog
+* Handling codetags
+* Unifying builtin lists and iterators?
+
+
+For ``0.5m1``
+=============
+
+* Document the renaming of refactoring classes.
+* Include changes in ``setup.py`` for cheeseshop.
 
 
 Remaining Small Stories
 Main:
 
 * Separating UI and functional tests from unit tests
-* Should we stop when transforming local variable to fields when there
-  the field already exists?
-* Lambdas as functions; consider their parameters
-* Docs for builtin functions and properties
 * Goto definition for ``"# comment.\na_var"``
 
 Others:
 
+* Comments should be indented
 * When running `inlinetest` modules we get
   ``Exception exceptions.SystemError: 'error return without exception set'
     in <generator object at 0xb7173aec> ignored``
 * Undoing `RemoveResource`; It's not used by refactorings
 * Decide when to use `difflib` in `Editor.set_text` based on the
   number of changes
-* Showing properties in quick outline
-* Comments should be indented
 * Caching calculated parameters and returned object in `PyFunction`\s
-* Fixing multiple function definition problems
 * Allowing running code to call rope functions while rope is running?
 * Importing star and removing self imports; stack overflow
 * Extract constant
-* What to do if a file is removed while editing
 * `PyClass.superclasses` should be concluded data
 * Better `ropetest` package structure
 * Handling `AssList` for inline variable and encapsulate field
-* Reporting unhandled exceptions as error dialogs in the GUI
 * Better move dialog; complete modules names; use `editor._CompletionListHandle`
 * Import addition when adding a relative to an absolute import

File docs/index.txt

View file
     * Expand ``from ... import *`` imports
     * Remove unused and duplicate imports and sort them (organize imports)
 
+* Editing and IDE tools
+
+  * Python and reST highlighting
+  * Multiple editers
+  * Auto-completion
+  * Project file history
+  * Basic SVN support using pysvn_ library
+  * An emacs like keybinding
+  * Configurable keybinding
+  * Basic UI plug-in support
+  * Correcting indentation
+  * Project tree view
+  * Unit-test running view
+
 * Object Inference
 
   * A dynamic object inference approach
   * A simple static type inference approach
   * Handling built-in container types
 
-* Auto-completion
-
-  * Global and local variables and imports
-  * Builtins and keywords
-  * Attributes of objects with known types
-
-* Editing and IDE tools
-
-  * Unit-test running view
-  * Python and reST highlighting
-  * Multiple editers
-  * Project file history
-  * Basic SVN support using pysvn library
-  * Configurable keybinding
-  * Basic UI plug-in support
-  * Correcting indentation
-  * Project tree view
-
 
 Download
 ========
 
 .. _project download page: http://sf.net/projects/rope/files
 .. _sourceforge.net project page: http://sf.net/projects/rope
-
+.. _pysvn: http://pysvn.tigris.org

File docs/user/overview.txt

View file
 open/new project            C-x C-p        C-P
 close project               C-x p k
 show project tree           C-x p t        M-Q r
-refresh project             C-x p r        F5
+validate project files      C-x p v        F5
 --------------------------  -------------  -------------  
 new module                  C-x n m
 new package                 C-x n p
 change method signature     C-c r c        M-C
 extract local variable      C-c r l        M-L
 introduce factory           C-c r f
+method to method object     C-c r j
 encapsulate field           C-c r s
 introduce parameter         C-c r p
 rename in file              C-c r e
   a_var = AClass()
 
 and the new project tree would be::
+
   root/
     mod1.py
     newmod.py

File rope/base/builtins.py

View file
             '__new__': BuiltinName(BuiltinFunction(function=self._new_dict)),
             'pop': BuiltinName(BuiltinFunction(self.values)),
             'get': BuiltinName(BuiltinFunction(self.keys)),
-            'keys': BuiltinName(List(self.keys)),
-            'values': BuiltinName(List(self.values)),
-            'iterkeys': BuiltinName(Iterator(self.keys)),
-            'itervalues': BuiltinName(Iterator(self.values)),
-            'items': BuiltinName(List(item)),
-            'iteritems': BuiltinName(Iterator(item)),
+            'keys': BuiltinName(BuiltinFunction(List(self.keys))),
+            'values': BuiltinName(BuiltinFunction(List(self.values))),
+            'iterkeys': BuiltinName(BuiltinFunction(Iterator(self.keys))),
+            'itervalues': BuiltinName(BuiltinFunction(Iterator(self.values))),
+            'items': BuiltinName(BuiltinFunction(List(item))),
+            'iteritems': BuiltinName(BuiltinFunction(Iterator(item))),
             'copy': BuiltinName(BuiltinFunction(pyobjects.PyObject(self))),
             'clear': BuiltinName(BuiltinFunction()),
             'has_key': BuiltinName(BuiltinFunction()),
 def _create_builtin(args, creator):
     passed = args.get_arguments(['sequence'])[0]
     if passed is None:
-        return None
-    holding = _infer_sequence_type(passed)
+        holding = None
+    else:
+        holding = _infer_sequence_type(passed)
     if holding is not None:
         return creator(holding)
     else:
     else:
         return passed_self
 
+def _zip_function(args):
+    args = args.get_arguments(['sequence'])
+    objects = []
+    for seq in args:
+        if seq is None:
+            holding = None
+        else:
+            holding = _infer_sequence_type(seq)
+        objects.append(holding)
+    tuple = get_tuple(*objects)
+    return get_list(tuple)
+
+def _enumerate_function(args):
+    passed = args.get_arguments(['sequence'])[0]
+    if passed is None:
+        holding = None
+    else:
+        holding = _infer_sequence_type(passed)
+    tuple = get_tuple(None, holding)
+    return Iterator(tuple)
+
 
 builtins = {
     'list': BuiltinName(get_list_type()),
     'reversed': BuiltinName(BuiltinFunction(function=_reversed_function)),
     'sorted': BuiltinName(BuiltinFunction(function=_sorted_function)),
     'super': BuiltinName(BuiltinFunction(function=_super_function)),
-    'property': BuiltinName(BuiltinFunction(function=_property_function))}
+    'property': BuiltinName(BuiltinFunction(function=_property_function)),
+    'zip': BuiltinName(BuiltinFunction(function=_zip_function)),
+    'enumerate': BuiltinName(BuiltinFunction(function=_enumerate_function))}

File rope/base/evaluate.py

View file
         self.scope = scope
 
     def get_arguments(self, parameters):
-        result = [None] * len(parameters)
+        result = [None] * max(len(parameters), len(self.args))
         for index, arg in enumerate(self.args):
             if isinstance(arg, compiler.ast.Keyword) and arg.name in parameters:
                 pyname = self._evaluate(arg.expr)

File rope/base/oi/dynamicoi.py

View file
             del parameters[-1]
         if pyfunction._get_ast().flags & 0x8:
             del parameters[-1]
-        arguments = args.get_arguments(parameters)
-        textual_args = tuple([self.to_textual.transform(arg) for arg in arguments])
+        arguments = args.get_arguments(parameters)[:len(parameters)]
+        textual_args = tuple([self.to_textual.transform(arg)
+                              for arg in arguments])
         if textual_args in self.info:
             return self.info[textual_args]
         return self._get_default_returned()

File rope/refactor/__init__.py

View file
 1. Collect some data for performing the refactoring and use them
    to construct a refactoring class.  Like::
 
-     renamer = RenameRefactoring(project, resource, offset)
+     renamer = Rename(project, resource, offset)
 
 2. Some refactorings give you useful information about the
    refactoring after their construction.  Like::
 
 1. Construct a refactoring object by giving it information like
    resource, offset and ... .  Some of the refactoring problems
-   (like performing rename refactoring on keywords) can be
+   (like performing rename refactoring on language keywords) can be
    reported here.
 2. Print some information about the refactoring and ask the user
    about the information that are necessary for completing the
 from rope.refactor.importutils import module_imports
 
 
-class TransformModuleToPackage(object):
+class ModuleToPackage(object):
 
     def __init__(self, project, resource):
         self.project = project

File rope/refactor/change_signature.py

View file
 import copy
 
+import rope.base.exceptions
 import rope.refactor.occurrences
-import rope.base.exceptions
-import rope.base.pyobjects
-from rope.base import codeanalyze
-from rope.refactor import sourceutils, functionutils
+from rope.base import pyobjects, codeanalyze
 from rope.base.change import ChangeContents, ChangeSet
+from rope.refactor import sourceutils, functionutils, rename
 
 
 class ChangeSignature(object):
         self.name = codeanalyze.get_name_at(resource, offset)
         self.pyname = codeanalyze.get_pyname_at(self.pycore, resource, offset)
         if self.pyname is None or self.pyname.get_object() is None or \
-           not isinstance(self.pyname.get_object(), rope.base.pyobjects.PyFunction):
+           not isinstance(self.pyname.get_object(), pyobjects.PyFunction):
             raise rope.base.exceptions.RefactoringError(
                 'Change method signature should be performed on functions')
 
-    def _change_calls(self, call_changer):
+    def _change_calls(self, call_changer, in_hierarchy=False):
         changes = ChangeSet('Changing signature of <%s>' % self.name)
+        if in_hierarchy and self.is_method():
+            pyfunction = self.pyname.get_object()
+            pyclass = pyfunction.parent
+            pynames = rename.get_all_methods_in_hierarchy(pyclass, self.name)
+        else:
+            pynames = [self.pyname]
         finder = rope.refactor.occurrences.FilteredOccurrenceFinder(
-            self.pycore, self.name, [self.pyname])
+            self.pycore, self.name, pynames)
         for file in self.pycore.get_python_files():
             change_calls = _ChangeCallsInModule(
                 self.pycore, finder, file, call_changer)
                 changes.add_change(ChangeContents(file, changed_file))
         return changes
 
+    def is_method(self):
+        pyfunction = self.pyname.get_object()
+        return isinstance(pyfunction.parent, pyobjects.PyClass)
+
     def get_definition_info(self):
         return functionutils.DefinitionInfo.read(self.pyname.get_object())
 
                                     [ArgumentReorderer(new_ordering)])
         return self._change_calls(changer)
 
-    def apply_changers(self, changers):
+    def apply_changers(self, changers, in_hierarchy=False):
         function_changer = _FunctionChangers(
             self.pyname.get_object(), self.get_definition_info(), changers)
-        return self._change_calls(function_changer)
+        return self._change_calls(function_changer, in_hierarchy)
 
 
 class _FunctionChangers(object):

File rope/refactor/encapsulate_field.py

View file
 from rope.base.change import ChangeSet, ChangeContents
 
 
-class EncapsulateFieldRefactoring(object):
+class EncapsulateField(object):
 
     def __init__(self, project, resource, offset):
         self.pycore = project.pycore

File rope/refactor/extract.py

View file
         return offset
 
 
-class ExtractMethodRefactoring(_ExtractRefactoring):
+class ExtractMethod(_ExtractRefactoring):
 
     def get_changes(self, extracted_name):
         info = _ExtractingPartOffsets(self.pycore, self.resource,
         return changes
 
 
-class ExtractVariableRefactoring(_ExtractRefactoring):
+class ExtractVariable(_ExtractRefactoring):
 
     def get_changes(self, extracted_name):
         info = _ExtractingPartOffsets(self.pycore, self.resource,

File rope/refactor/inline.py

View file
 from rope.refactor import occurrences, rename, sourceutils
 
 
-class InlineRefactoring(object):
+class Inline(object):
 
     def __init__(self, project, resource, offset):
         self.pycore = project.pycore

File rope/refactor/localtofield.py

View file
 import rope.base.codeanalyze
-from rope.refactor.rename import RenameRefactoring
+from rope.refactor.rename import Rename
 
 
-class ConvertLocalToFieldRefactoring(object):
+class LocalToField(object):
 
     def __init__(self, project, resource, offset):
         self.project = project
 
         pymodule, lineno = pyname.get_definition_location()
         function_scope = pymodule.get_scope().get_inner_scope_for_line(lineno)
+        # Not checking redefinition
+        #self._check_redefinition(name, function_scope)
+
+        new_name = self._get_field_name(function_scope.pyobject, name)
+        changes = Rename(self.project, self.resource, self.offset).\
+                  get_changes(new_name, in_file=True)
+        return changes
+
+    def _check_redefinition(self, name, function_scope):
         class_scope = function_scope.parent
         if name in class_scope.pyobject.get_attributes():
             raise rope.base.exceptions.RefactoringError(
                 'The field %s already exists' % name)
 
-        new_name = self._get_field_name(function_scope.pyobject, name)
-        changes = RenameRefactoring(self.project, self.resource, self.offset).\
-                  get_changes(new_name, in_file=True)
-        return changes
-
     def _get_field_name(self, pyfunction, name):
         self_name = pyfunction.parameters[0]
         new_name = self_name + '.' + name

File rope/refactor/move.py

View file
 from rope.refactor import importutils, rename, occurrences
 
 
-class MoveRefactoring(object):
+class Move(object):
     """A class for moving modules, packages, global functions and classes."""
 
     def __init__(self, project, resource, offset=None):

File rope/refactor/occurrences.py

View file
     name_finder = property(get_name_finder)
     word_finder = property(get_word_finder)
     source_code = property(get_source_code)
-

File rope/refactor/rename.py

View file
 from rope.refactor import occurrences, sourceutils
 
 
-class RenameRefactoring(object):
+class Rename(object):
 
     def __init__(self, project, resource, offset=None):
         """If `offset` is None, the `resource` itself will be renamed"""
         self.pycore = project.pycore
         self.resource = resource
         if offset is not None:
-            self.old_name = rope.base.codeanalyze.get_name_at(self.resource, offset)
+            self.old_name = rope.base.codeanalyze.get_name_at(self.resource,
+                                                              offset)
             self.old_pyname = rope.base.codeanalyze.get_pyname_at(
                 self.pycore, resource, offset)
             if self.old_pyname is None:
     def get_old_name(self):
         return self.old_name
 
-    def get_changes(self, new_name, in_file=False):
-        old_pynames = self._get_old_pynames(in_file)
+    def get_changes(self, new_name, in_file=False, in_hierarchy=False):
+        """Get the changes needed for this refactoring
+
+        :parameters:
+            - `in_file`: if True implies only renaming occurrences in the
+              passed resource.
+            - `in_hierarchy`: when renaming a method this keyword forces
+              to rename all matching methods in the hierarchy
+
+        """
+        old_pynames = self._get_old_pynames(in_file, in_hierarchy)
         if not old_pynames:
             return None
         if not in_file and len(old_pynames) == 1 and \
             return True
         return False
 
-    def _get_old_pynames(self, in_file):
+    def _get_old_pynames(self, in_file, in_hierarchy):
         if self.old_pyname is None:
             return []
-        if self._is_a_class_method() and not in_file:
-            return self._get_all_methods_in_hierarchy(self.old_pyname.get_object().
-                                                      parent, self.old_name)
+        if self.is_method() and not in_file and in_hierarchy:
+            return get_all_methods_in_hierarchy(self.old_pyname.get_object().
+                                                parent, self.old_name)
         else:
             return [self.old_pyname]
 
             return self.pycore.get_python_files()
         return [self.resource]
 
-    def _is_a_class_method(self):
+    def is_method(self):
         pyname = self.old_pyname
         return isinstance(pyname, rope.base.pynames.DefinedName) and \
                pyname.get_object().get_type() == rope.base.pyobjects.get_base_type('Function') and \
                pyname.get_object().parent.get_type() == rope.base.pyobjects.get_base_type('Type')
 
-    def _get_superclasses_defining_method(self, pyclass, attr_name):
-        result = set()
-        for superclass in pyclass.get_superclasses():
-            if attr_name in superclass.get_attributes():
-                result.update(self._get_superclasses_defining_method(
-                              superclass, attr_name))
-        if not result:
-            return set([pyclass])
-        return result
-
-    def _get_all_methods_in_subclasses(self, pyclass, attr_name):
-        result = set([pyclass.get_attribute(attr_name)])
-        for subclass in self.pycore.get_subclasses(pyclass):
-            result.update(self._get_all_methods_in_subclasses(subclass,
-                                                              attr_name))
-        return result
-
-    def _get_all_methods_in_hierarchy(self, pyclass, attr_name):
-        superclasses = self._get_superclasses_defining_method(pyclass,
-                                                              attr_name)
-        methods = set()
-        for superclass in superclasses:
-            methods.update(self._get_all_methods_in_subclasses(
-                           superclass, attr_name))
-        return methods
-
     def _rename_module(self, pyobject, new_name):
         resource = pyobject.get_resource()
         if not resource.is_folder():
             start, end = occurrence.get_word_range()
         change_collector.add_change(start, end, new_name)
     return change_collector.get_changed()
+
+
+def get_all_methods_in_hierarchy(pyclass, attr_name):
+    superclasses = _get_superclasses_defining_method(pyclass, attr_name)
+    methods = set()
+    for superclass in superclasses:
+        methods.update(_get_all_methods_in_subclasses(
+                       superclass, attr_name))
+    return methods
+
+def _get_superclasses_defining_method(pyclass, attr_name):
+    result = set()
+    for superclass in pyclass.get_superclasses():
+        if attr_name in superclass.get_attributes():
+            result.update(_get_superclasses_defining_method(
+                          superclass, attr_name))
+    if not result:
+        return set([pyclass])
+    return result
+
+def _get_all_methods_in_subclasses(pyclass, attr_name):
+    result = set([pyclass.get_attribute(attr_name)])
+    for subclass in pyclass.pycore.get_subclasses(pyclass):
+        result.update(_get_all_methods_in_subclasses(subclass, attr_name))
+    return result

File rope/ui/actionhelpers.py

View file
         toplevel = Tkinter.Toplevel()
         toplevel.title('Save All')
         frame = Tkinter.Frame(toplevel)
-        label = Tkinter.Label(
-            frame, text='These editors should be saved before this refactoring:\n* ' +
-            '\n* '.join([fileeditor.file.path for fileeditor in editors]))
+        message = 'These editors should be saved before performing this action:\n* '
+        label = Tkinter.Label(frame, text=message +
+                              '\n* '.join([fileeditor.file.path
+                                           for fileeditor in editors]))
         label.grid(row=0, column=0, columnspan=2)
         def ok(event=None):
             context.get_core().save_all_editors()

File rope/ui/core.py

View file
 
     def _load_dot_rope(self):
         dot_rope = os.path.expanduser('~%s.rope' % os.path.sep)
-        if not os.path.exists(dot_rope):
-            write_dot_rope(dot_rope)
-        run_globals = {}
-        run_globals.update({'__name__': '__main__',
-                            '__builtins__': __builtins__,
-                            '__file__': dot_rope})
-        execfile(dot_rope, run_globals)
+        try:
+            if not os.path.exists(dot_rope):
+                write_dot_rope(dot_rope)
+            run_globals = {}
+            run_globals.update({'__name__': '__main__',
+                                '__builtins__': __builtins__,
+                                '__file__': dot_rope})
+            execfile(dot_rope, run_globals)
+        except IOError, e:
+            print 'Unable to load <~.rope> file: ' + e
 
     def open_file(self, file_name):
         if self.project is get_no_project():

File rope/ui/dot_rope.py

View file
     core.rebind_action('create_module', None)
     core.rebind_action('create_package', None)
     core.rebind_action('project_tree', 'M-Q r')
-    core.rebind_action('refresh_project', 'F5')
+    core.rebind_action('validate_project', 'F5')
     core.rebind_action('find_file', 'C-R')
     core.rebind_action('change_buffer', 'C-E')
     core.rebind_action('save_buffer', 'C-s')
     core.rebind_action('encapsulate_field', None)
     core.rebind_action('introduce_parameter', None)
     core.rebind_action('method_object', None)
+    core.rebind_action('module_to_package', None)
     core.rebind_action('rename_current_module', None)
     core.rebind_action('move_current_module', None)
     core.rebind_action('organize_imports', 'C-O')

File rope/ui/editingcontexts.py

View file
 from rope.ui import editingtools
 
+
 class EditingContext(object):
 
     def __init__(self, name, core):

File rope/ui/editorpile.py

View file
         new_title = editor.get_file().name
         if editor.get_editor().is_modified():
             new_title = '*' + new_title
+        if not editor.get_file().exists():
+            new_title = '! ' + new_title
         self.buttons[editor]['text'] = new_title
 
     def _editor_was_changed(self, resource, offset):

File rope/ui/fileactions.py

View file
 def project_tree(context):
     _show_resource_view(context.get_core())
 
-def refresh_project(context):
+def validate_project(context):
     context.project.validate(context.project.root)
 
 def change_editor(context):
                             MenuAddress(['File', 'Find File...'], 'f', 2)))
 actions.append(SimpleAction('project_tree', project_tree, 'C-x p t',
                             MenuAddress(['File', 'Project Tree'], 't', 2)))
-actions.append(SimpleAction('refresh_project', refresh_project, 'C-x p r',
-                            MenuAddress(['File', 'Refresh Project'], 'r', 2)))
+actions.append(SimpleAction('validate_project', validate_project, 'C-x p v',
+                            MenuAddress(['File', 'Validate Project Files'], 'v', 2)))
 
 actions.append(SimpleAction('change_buffer', change_editor, 'C-x b',
                             MenuAddress(['File', 'Change Editor...'], 'c', 3)))

File rope/ui/fileeditor.py

View file
     def _file_was_removed(self, file, new_file=None):
         self._remove_observers()
         # XXX: file was removed while we were editing it.  What to do?
-        if new_file is None:
-            return
-        self.file = new_file
-        self._register_observers()
+        if new_file is not None:
+            self.file = new_file
+            self._register_observers()
         self._editor_was_modified()
 
     def _file_was_modified(self, file_):

File rope/ui/refactor.py

View file
         offset = editor.get_current_offset()
         if current_module:
             offset = None
-        self.renamer = rope.refactor.rename.RenameRefactoring(
+        self.renamer = rope.refactor.rename.Rename(
             context.project, resource, offset)
 
     def _get_changes(self):
         new_name = self.new_name_entry.get()
-        return self.renamer.get_changes(new_name, in_file=self.is_local)
+        return self.renamer.get_changes(new_name, in_file=self.is_local,
+                                        in_hierarchy=self.in_hierarchy.get())
 
     def _get_dialog_frame(self):
         frame = Tkinter.Frame(self.toplevel)
         self.new_name_entry.select_range(0, Tkinter.END)
         self.new_name_entry.grid(row=0, column=1, columnspan=2)
         self.new_name_entry.bind('<Return>', lambda event: self._ok())
+        self.in_hierarchy = Tkinter.IntVar(frame, value=0)
+        in_hierarchy = Tkinter.Checkbutton(
+            frame, text='Do for all matching methods in class hierarchy',
+            variable=self.in_hierarchy)
+        if self.renamer.is_method():
+            in_hierarchy.grid(row=1, columnspan=2, sticky=Tkinter.N)
         self.new_name_entry.focus_set()
         return frame
 
         fileeditor = context.get_active_editor()
         resource = fileeditor.get_file()
         editor = fileeditor.get_editor()
-        changes = rope.refactor.TransformModuleToPackage(
+        changes = rope.refactor.ModuleToPackage(
             context.project, resource).get_changes()
         self.project.do(changes)
 
         editor = context.get_active_editor().get_editor()
         resource = context.resource
         start_offset, end_offset = editor.get_region_offset()
-        return rope.refactor.extract.ExtractMethodRefactoring(
+        return rope.refactor.extract.ExtractMethod(
             context.project, resource, start_offset,
             end_offset).get_changes(new_name)
     ExtractDialog(context, do_extract, 'Method').show()
         editor = context.get_active_editor().get_editor()
         resource = context.get_active_editor().get_file()
         start_offset, end_offset = editor.get_region_offset()
-        return rope.refactor.extract.ExtractVariableRefactoring(
+        return rope.refactor.extract.ExtractVariable(
             context.project, resource, start_offset,
             end_offset).get_changes(new_name)
     ExtractDialog(context, do_extract, 'Variable').show()
         offset = editor.get_current_offset()
         if current_module:
             offset = None
-        self.mover = rope.refactor.move.MoveRefactoring(
+        self.mover = rope.refactor.move.Move(
             context.project, resource, offset)
 
     def _get_changes(self):
         new_ordering = [_get_parameter_index(definition_info, param.name)
                         for param in parameters if not param.name.startswith('*')]
         changers.append(rope.refactor.change_signature.ArgumentReorderer(new_ordering))
-        return self.signature.apply_changers(changers)
+        return self.signature.apply_changers(changers, in_hierarchy=self.in_hierarchy.get())
 
     def _get_dialog_frame(self):
         frame = Tkinter.Frame(self.toplevel)
         move_down.grid(row=1, column=1, sticky=Tkinter.N)
         remove.grid(row=2, column=1, sticky=Tkinter.N)
         add.grid(row=3, column=1, sticky=Tkinter.N)
+        self.in_hierarchy = Tkinter.IntVar(frame, value=0)
+        in_hierarchy = Tkinter.Checkbutton(
+            frame, text='Do for all matching methods in class hierarchy',
+            variable=self.in_hierarchy)
+        if self.signature.is_method():
+            in_hierarchy.grid(row=4, column=1, sticky=Tkinter.N)
         frame.grid()
         frame.focus_set()
         return frame
         fileeditor = context.get_active_editor()
         resource = fileeditor.get_file()
         editor = fileeditor.get_editor()
-        changes = rope.refactor.inline.InlineRefactoring(
+        changes = rope.refactor.inline.Inline(
             context.project, resource,
             editor.get_current_offset()).get_changes()
         context.project.do(changes)
         fileeditor = context.get_active_editor()
         resource = fileeditor.get_file()
         editor = fileeditor.get_editor()
-        changes = rope.refactor.encapsulate_field.EncapsulateFieldRefactoring(
+        changes = rope.refactor.encapsulate_field.EncapsulateField(
             context.project, resource, editor.get_current_offset()).get_changes()
         context.project.do(changes)
 
         fileeditor = context.get_active_editor()
         resource = fileeditor.get_file()
         editor = fileeditor.get_editor()
-        changes = rope.refactor.localtofield.ConvertLocalToFieldRefactoring(
+        changes = rope.refactor.localtofield.LocalToField(
             context.project, resource,
             editor.get_current_offset()).get_changes()
         context.project.do(changes)
                             MenuAddress(['Refactor', 'Inline Argument Default'], 'g', 1),
                             ['python']))
 actions.append(SimpleAction('module_to_package',
-                            ConfirmEditorsAreSaved(transform_module_to_package), None,
+                            ConfirmEditorsAreSaved(transform_module_to_package), 'C-c r 1 p',
                             MenuAddress(['Refactor', 'Transform Module to Package'], 't', 1),
                             ['python']))
 actions.append(SimpleAction('rename_current_module',

File ropetest/builtintest.py

View file
         a_var = pymod.get_attribute('a_var').get_object()
         self.assertTrue(a_var is not None)
 
+    def test_builtin_zip_function(self):
+        self.mod.write(
+            'class C1(object):\n    pass\nclass C2(object):\n    pass\n'
+            'c1_list = [C1()]\nc2_list = [C2()]\n'
+            'a, b = zip(c1_list, c2_list)[0]')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c1_class = pymod.get_attribute('C1').get_object()
+        c2_class = pymod.get_attribute('C2').get_object()
+        a_var = pymod.get_attribute('a').get_object()
+        b_var = pymod.get_attribute('b').get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+        self.assertEquals(c2_class, b_var.get_type())
+
+    def test_builtin_zip_function_with_more_than_two_args(self):
+        self.mod.write(
+            'class C1(object):\n    pass\nclass C2(object):\n    pass\n'
+            'c1_list = [C1()]\nc2_list = [C2()]\n'
+            'a, b, c = zip(c1_list, c2_list, c1_list)[0]')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c1_class = pymod.get_attribute('C1').get_object()
+        c2_class = pymod.get_attribute('C2').get_object()
+        a_var = pymod.get_attribute('a').get_object()
+        b_var = pymod.get_attribute('b').get_object()
+        c_var = pymod.get_attribute('c').get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+        self.assertEquals(c2_class, b_var.get_type())
+        self.assertEquals(c1_class, c_var.get_type())
+
+    def test_wrong_arguments_to_zip_function(self):
+        self.mod.write(
+            'class C1(object):\n    pass\nc1_list = [C1()]\n'
+            'a, b = zip(c1_list, 1)[0]')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c1_class = pymod.get_attribute('C1').get_object()
+        a_var = pymod.get_attribute('a').get_object()
+        b_var = pymod.get_attribute('b').get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+
+    def test_enumerate_builtin_function(self):
+        self.mod.write('class C(object):\n    pass\nl = [C()]\n'
+                       'for i, x in enumerate(l):\n    a_var = x\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod.get_attribute('C').get_object()
+        a_var = pymod.get_attribute('a_var').get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_enumerate_builtin_function(self):
+        self.mod.write('class C(object):\n    pass\nl = [C()]\n'
+                       'for i, x in enumerate(l):\n    a_var = x\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod.get_attribute('C').get_object()
+        a_var = pymod.get_attribute('a_var').get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
 
 if __name__ == '__main__':
     unittest.main()

File ropetest/refactor/__init__.py

View file
 import ropetest.refactor.renametest
 from rope.base.exceptions import RefactoringError
 from rope.base.project import Project
-from rope.refactor.encapsulate_field import EncapsulateFieldRefactoring
+from rope.refactor.encapsulate_field import EncapsulateField
 from rope.refactor.introduce_factory import IntroduceFactoryRefactoring
-from rope.refactor.localtofield import ConvertLocalToFieldRefactoring
+from rope.refactor.localtofield import LocalToField
 from rope.refactor.method_object import MethodObject
 from ropetest import testutils
 
         testutils.remove_recursively(self.project_root)
         self.project = Project(self.project_root)
         self.pycore = self.project.get_pycore()
+        self.mod = self.pycore.create_module(self.project.root, 'mod')
 
     def tearDown(self):
         testutils.remove_recursively(self.project_root)
         super(MethodObjectTest, self).tearDown()
 
     def test_empty_method(self):
-        mod = self.pycore.create_module(self.project.root, 'mod')
         code = 'def func():\n    pass\n'
-        mod.write(code)
-        replacer = MethodObject(self.project, mod, code.index('func'))
+        self.mod.write(code)
+        replacer = MethodObject(self.project, self.mod, code.index('func'))
         self.assertEquals(
             'class _New(object):\n\n    def __call__(self):\n        pass\n',
             replacer.get_new_class('_New'))
 
     def test_trivial_return(self):
-        mod = self.pycore.create_module(self.project.root, 'mod')
         code = 'def func():\n    return 1\n'
-        mod.write(code)
-        replacer = MethodObject(self.project, mod, code.index('func'))
+        self.mod.write(code)
+        replacer = MethodObject(self.project, self.mod, code.index('func'))
         self.assertEquals(
             'class _New(object):\n\n    def __call__(self):\n        return 1\n',
             replacer.get_new_class('_New'))
 
     def test_multi_line_header(self):
-        mod = self.pycore.create_module(self.project.root, 'mod')
         code = 'def func(\n    ):\n    return 1\n'
-        mod.write(code)
-        replacer = MethodObject(self.project, mod, code.index('func'))
+        self.mod.write(code)
+        replacer = MethodObject(self.project, self.mod, code.index('func'))
         self.assertEquals(
             'class _New(object):\n\n    def __call__(self):\n        return 1\n',
             replacer.get_new_class('_New'))
 
     def test_a_single_parameter(self):
-        mod = self.pycore.create_module(self.project.root, 'mod')
         code = 'def func(param):\n    return 1\n'
-        mod.write(code)
-        replacer = MethodObject(self.project, mod, code.index('func'))
+        self.mod.write(code)
+        replacer = MethodObject(self.project, self.mod, code.index('func'))
         self.assertEquals(
             'class _New(object):\n\n'
             '    def __init__(self, param):\n        self.param = param\n\n'
             replacer.get_new_class('_New'))
 
     def test_self_parameter(self):
-        mod = self.pycore.create_module(self.project.root, 'mod')
         code = 'def func(self):\n    return 1\n'
-        mod.write(code)
-        replacer = MethodObject(self.project, mod, code.index('func'))
+        self.mod.write(code)
+        replacer = MethodObject(self.project, self.mod, code.index('func'))
         self.assertEquals(
             'class _New(object):\n\n'
             '    def __init__(self, host):\n        self.self = host\n\n'
             '    def __call__(self):\n        return 1\n',
             replacer.get_new_class('_New'))
 
-    def test_self_parameter(self):
-        mod = self.pycore.create_module(self.project.root, 'mod')
+    def test_simple_using_passed_parameters(self):
         code = 'def func(param):\n    return param\n'
-        mod.write(code)
-        replacer = MethodObject(self.project, mod, code.index('func'))
+        self.mod.write(code)
+        replacer = MethodObject(self.project, self.mod, code.index('func'))
         self.assertEquals(
             'class _New(object):\n\n'
             '    def __init__(self, param):\n        self.param = param\n\n'
             replacer.get_new_class('_New'))
 
     def test_self_keywords_and_args_parameters(self):
-        mod = self.pycore.create_module(self.project.root, 'mod')
         code = 'def func(arg, *args, **kwds):\n' \
                '    result = arg + args[0] + kwds[arg]\n    return result\n'
-        mod.write(code)
-        replacer = MethodObject(self.project, mod, code.index('func'))
+        self.mod.write(code)
+        replacer = MethodObject(self.project, self.mod, code.index('func'))
         self.assertEquals(
             'class _New(object):\n\n'
             '    def __init__(self, arg, args, kwds):\n'
 
     @testutils.assert_raises(RefactoringError)
     def test_performing_on_not_a_function(self):
-        mod = self.pycore.create_module(self.project.root, 'mod')
         code = 'my_var = 10\n'
-        mod.write(code)
-        replacer = MethodObject(self.project, mod, code.index('my_var'))
+        self.mod.write(code)
+        replacer = MethodObject(self.project, self.mod, code.index('my_var'))
 
     def test_changing_the_module(self):
-        mod = self.pycore.create_module(self.project.root, 'mod')
         code = 'def func():\n    return 1\n'
-        mod.write(code)
-        replacer = MethodObject(self.project, mod, code.index('func'))
+        self.mod.write(code)
+        replacer = MethodObject(self.project, self.mod, code.index('func'))
         self.project.do(replacer.get_changes('_New'))
         self.assertEquals(
             'def func():\n    return _New()()\n\n\n'
             'class _New(object):\n\n    def __call__(self):\n        return 1\n',
-            mod.read())
+            self.mod.read())
 
     def test_changing_the_module_and_class_methods(self):
-        mod = self.pycore.create_module(self.project.root, 'mod')
         code = 'class C(object):\n\n    def a_func(self):\n        return 1\n\n' \
                '    def another_func(self):\n        pass\n'
-        mod.write(code)
-        replacer = MethodObject(self.project, mod, code.index('func'))
+        self.mod.write(code)
+        replacer = MethodObject(self.project, self.mod, code.index('func'))
         self.project.do(replacer.get_changes('_New'))
         self.assertEquals(
             'class C(object):\n\n    def a_func(self):\n        return _New(self)()\n\n'
             'class _New(object):\n\n'
             '    def __init__(self, host):\n        self.self = host\n\n'
             '    def __call__(self):\n        return 1\n',
-            mod.read())
+            self.mod.read())
 
 
 class IntroduceFactoryTest(unittest.TestCase):
                         'class C(object):\n    def create(self):\n        return create_c()\n'))
 
     def _transform_module_to_package(self, resource):
-        self.project.do(rope.refactor.TransformModuleToPackage(
+        self.project.do(rope.refactor.ModuleToPackage(
                         self.project, resource).get_changes())
 
     def test_transform_module_to_package(self):
         super(EncapsulateFieldTest, self).tearDown()
 
     def _perform_encapsulate_field(self, resource, offset):
-        changes = EncapsulateFieldRefactoring(self.project, resource, offset).\
+        changes = EncapsulateField(self.project, resource, offset).\
                   get_changes()
         self.project.do(changes)
 
         super(LocalToFieldTest, self).tearDown()
 
     def _perform_convert_local_variable_to_field(self, resource, offset):
-        changes = ConvertLocalToFieldRefactoring(
+        changes = LocalToField(
             self.project, resource, offset).get_changes()
         self.project.do(changes)
 
         self._perform_convert_local_variable_to_field(
             self.mod, self.mod.read().index('var') + 1)
 
-    @testutils.assert_raises(RefactoringError)
-    def test_raising_exception_when_there_is_a_field_with_the_same_name(self):
+    # NOTE: This situation happens alot and is normally not an error
+    #@testutils.assert_raises(RefactoringError)
+    def test_not_raising_exception_when_there_is_a_field_with_the_same_name(self):
         code = 'class A(object):\n    def __init__(self):\n        self.var = 1\n' \
                '    def a_func(self):\n        var = 10\n'
         self.mod.write(code)

File ropetest/refactor/change_signature_test.py

View file
         signature.apply_changers(changers).do()
         self.assertEquals('def a_func(p2, p3):\n    pass\na_func(2, 3)\n', self.mod.read())
 
+    def test_changing_signature_in_subclasses(self):
+        self.mod.write(
+            'class A(object):\n    def a_method(self):\n        pass\n'
+            'class B(A):\n    def a_method(self):\n        pass\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_method') + 1)
+        signature.apply_changers([change_signature.ArgumentAdder(1, 'p1')],
+                                 in_hierarchy=True).do()
+        self.assertEquals(
+            'class A(object):\n    def a_method(self, p1):\n        pass\n'
+            'class B(A):\n    def a_method(self, p1):\n        pass\n',
+            self.mod.read())
+
 
 if __name__ == '__main__':
     unittest.main()

File ropetest/refactor/extracttest.py

View file
     def do_extract_method(self, source_code, start, end, extracted):
         testmod = self.pycore.create_module(self.project.root, 'testmod')
         testmod.write(source_code)
-        self.project.do(extract.ExtractMethodRefactoring(
+        self.project.do(extract.ExtractMethod(
                         self.project, testmod, start, end).get_changes(extracted))
         return testmod.read()
 
     def do_extract_variable(self, source_code, start, end, extracted):
         testmod = self.pycore.create_module(self.project.root, 'testmod')
         testmod.write(source_code)
-        self.project.do(extract.ExtractVariableRefactoring(
+        self.project.do(extract.ExtractVariable(
                         self.project, testmod, start, end).get_changes(extracted))
         return testmod.read()
 

File ropetest/refactor/inlinetest.py

View file
 
 import rope.base.exceptions
 import rope.base.project
-from rope.refactor.inline import InlineRefactoring
+from rope.refactor.inline import Inline
 from ropetest import testutils
 
 
         return self.mod.read()
 
     def _inline2(self, resource, offset):
-        changes = InlineRefactoring(self.project, resource,
+        changes = Inline(self.project, resource,
                                     offset).get_changes()
         self.project.do(changes)
         return self.mod.read()

File ropetest/refactor/movetest.py

View file
         super(MoveRefactoringTest, self).tearDown()
 
     def _move(self, resource, offset, dest_resource):
-        changes = move.MoveRefactoring(self.project, resource, offset).\
+        changes = move.Move(self.project, resource, offset).\
                   get_changes(dest_resource)
         self.project.do(changes)
 
     def test_moving_resources_using_move_module_refactoring(self):
         self.mod1.write('a_var = 1')
         self.mod2.write('import mod1\nmy_var = mod1.a_var\n')
-        mover = move.MoveRefactoring(self.project, self.mod1)
+        mover = move.Move(self.project, self.mod1)
         mover.get_changes(self.pkg).do()
         self.assertEquals('import pkg.mod1\nmy_var = pkg.mod1.a_var\n', self.mod2.read())
         self.assertTrue(self.pkg.get_child('mod1.py') is not None)
     def test_moving_resources_using_move_module_refactoring_for_packages(self):
         self.mod1.write('import pkg\nmy_pkg = pkg')
         pkg2 = self.pycore.create_package(self.project.root, 'pkg2')
-        mover = move.MoveRefactoring(self.project, self.pkg)
+        mover = move.Move(self.project, self.pkg)
         mover.get_changes(pkg2).do()
         self.assertEquals('import pkg2.pkg\nmy_pkg = pkg2.pkg', self.mod1.read())
         self.assertTrue(pkg2.get_child('pkg') is not None)
     def test_moving_resources_using_move_module_refactoring_for_init_dot_py(self):
         self.mod1.write('import pkg\nmy_pkg = pkg')
         pkg2 = self.pycore.create_package(self.project.root, 'pkg2')
-        mover = move.MoveRefactoring(self.project, self.pkg.get_child('__init__.py'))
+        mover = move.Move(self.project, self.pkg.get_child('__init__.py'))
         mover.get_changes(pkg2).do()
         self.assertEquals('import pkg2.pkg\nmy_pkg = pkg2.pkg', self.mod1.read())
         self.assertTrue(pkg2.get_child('pkg') is not None)
     def test_moving_module_refactoring_and_star_imports(self):
         self.mod1.write('a_var = 1')
         self.mod2.write('from mod1 import *\na = a_var\n')
-        mover = move.MoveRefactoring(self.project, self.mod1)
+        mover = move.Move(self.project, self.mod1)
         mover.get_changes(self.pkg).do()
         self.assertEquals('from pkg.mod1 import *\na = a_var\n', self.mod2.read())
 
         self.mod4.write('a_var = 1')
         self.mod2.write('from pkg import mod4\n'
                         'import os\n\n\nprint mod4.a_var\n')
-        mover = move.MoveRefactoring(self.project, self.mod4)
+        mover = move.Move(self.project, self.mod4)
         mover.get_changes(self.project.root).do()
         self.assertEquals('import os\nimport mod4\n\n\n'
                           'print mod4.a_var\n', self.mod2.read())

File ropetest/refactor/renametest.py

View file
 import rope.refactor.occurrences
 import ropetest
 from rope.refactor import rename
-from rope.refactor.rename import RenameRefactoring
+from rope.refactor.rename import Rename
 
 
 class RenameRefactoringTest(unittest.TestCase):
     def _local_rename(self, source_code, offset, new_name):
         testmod = self.pycore.create_module(self.project.root, 'testmod')
         testmod.write(source_code)
-        changes = RenameRefactoring(self.project, testmod, offset).\
+        changes = Rename(self.project, testmod, offset).\
                   get_changes(new_name, in_file=True)
         self.project.do(changes)
         return testmod.read()
 
-    def _rename(self, resource, offset, new_name):
-        changes = RenameRefactoring(self.project, resource, offset).\
-                  get_changes(new_name)
+    def _rename(self, resource, offset, new_name, in_hierarchy=False):
+        changes = Rename(self.project, resource, offset).\
+                  get_changes(new_name, in_hierarchy=in_hierarchy)
         self.project.do(changes)
 
     def test_simple_global_variable_renaming(self):
         mod.write('class A(object):\n    def a_method(self):\n        pass\n'
                   'class B(A):\n    def a_method(self):\n        pass\n')
 
-        self._rename(mod, mod.read().rindex('a_method') + 1, 'new_method')
+        self._rename(mod, mod.read().rindex('a_method') + 1, 'new_method',
+                     in_hierarchy=True)
         self.assertEquals('class A(object):\n    def new_method(self):\n        pass\n'
                           'class B(A):\n    def new_method(self):\n        pass\n', mod.read())
 
                   'class B(A):\n    def a_method(self):\n        pass\n'
                   'class C(A):\n    def a_method(self):\n        pass\n')
 
-        self._rename(mod, mod.read().rindex('a_method') + 1, 'new_method')
+        self._rename(mod, mod.read().rindex('a_method') + 1, 'new_method',
+                     in_hierarchy=True)
         self.assertEquals('class A(object):\n    def new_method(self):\n        pass\n'
                   'class B(A):\n    def new_method(self):\n        pass\n'
                   'class C(A):\n    def new_method(self):\n        pass\n', mod.read())
 
+    def test_not_renaming_methods_in_hierarchies(self):
+        mod = self.pycore.create_module(self.project.root, 'mod1')
+        mod.write('class A(object):\n    def a_method(self):\n        pass\n'
+                  'class B(A):\n    def a_method(self):\n        pass\n')
+
+        self._rename(mod, mod.read().rindex('a_method') + 1, 'new_method',
+                     in_hierarchy=False)
+        self.assertEquals('class A(object):\n    def a_method(self):\n        pass\n'
+                          'class B(A):\n    def new_method(self):\n        pass\n', mod.read())
+
     def test_undoing_refactorings(self):
         mod1 = self.pycore.create_module(self.project.root, 'mod1')
         mod1.write('def a_func():\n    pass\na_func()\n')
         mod2 = self.pycore.create_module(self.project.root, 'mod2')
         mod1.write('a_var = 1')
         mod2.write('import mod1\nmy_var = mod1.a_var\n')
-        renamer = rename.RenameRefactoring(self.project, mod1)
+        renamer = rename.Rename(self.project, mod1)
         renamer.get_changes('newmod').do()
         self.assertEquals('import newmod\nmy_var = newmod.a_var\n', mod2.read())
 
         mod1 = self.pycore.create_module(self.project.root, 'mod1')
         pkg = self.pycore.create_package(self.project.root, 'pkg')
         mod1.write('import pkg\nmy_pkg = pkg')
-        renamer = rename.RenameRefactoring(self.project, pkg)
+        renamer = rename.Rename(self.project, pkg)
         renamer.get_changes('newpkg').do()
         self.assertEquals('import newpkg\nmy_pkg = newpkg', mod1.read())
 
         mod1 = self.pycore.create_module(self.project.root, 'mod1')
         pkg = self.pycore.create_package(self.project.root, 'pkg')
         mod1.write('import pkg\nmy_pkg = pkg')
-        renamer = rename.RenameRefactoring(self.project, pkg.get_child('__init__.py'))
+        renamer = rename.Rename(self.project, pkg.get_child('__init__.py'))
         renamer.get_changes('newpkg').do()
         self.assertEquals('import newpkg\nmy_pkg = newpkg', mod1.read())
 

File ropetest/testutils.py

View file
 
 def run_only_for_25(func):
     """Should be used as a decorator for a unittest.TestCase test method"""
-    major = sys.version_info[0]
-    minor = sys.version_info[1]
-    if major > 2 or minor > 4:
+    if sys.version_info >= (2, 5, 0):
         return func
     else:
         def do_nothing(self):

File ropetest/ui/mockeditortest.py

View file
 import unittest
 
-import rope.ui.editingtools
-from rope.ui import editingcontexts, editingtools
+from rope.ui import editingcontexts
+from rope.ui.editor import *
 from ropetest.ui.mockeditor import *
-from rope.ui.editor import *
+from rope.ui import core
+
 
 class TextEditorTest(unittest.TestCase):
 
         line_editor = self.editor.line_editor()
         self.assertEquals(1, line_editor.length())
 
+
 def get_sample_editingcontext():
+    editingcontexts.init_contexts(core.get_core())
     return editingcontexts.others
 
+
 def suite():
     result = unittest.TestSuite()
     import Tkinter