Commits

Anonymous committed 55488c8

Changing Resource to be value object

  • Participants
  • Parent commits 2d5828a

Comments (0)

Files changed (11)

docs/dev/issues.txt

 folder have been changed.  This is different from invalidation which
 means this file or folder no longer exists.
 
-Maybe we can do what eclipse does.  The resources only hold an
-address and the address might or might not exist.  The main difference
-between resources in rope and eclipse is that resources in rope are
-reference objects and in eclipse they are value objects.  That means
-when we invalidate a resource another resource with the same address
-might be made in future.  What's more the old observer are no longer
-notified when that resource changes.
+Todo:
+
+* Fixing resource moving and file editor title changing
+* `Project.validate_resource`
+* Using last changed time in `Project.validate_resource`
+* Revalidate the whole project
+
+Decisions to make:
+
+* Resource observing interface
+* General or per-resource observers
+
+General guidelines:
+
+Do not waste your time speculating.  Start coding and refactor if
+there are any problems.  Remember the goal; We should make it work
+using small steps.
+
 
 Can We Use Value Objects?
 -------------------------
 consider value objects once more.  If resources are going to be value
 objects they should not hold any information about the state of the
 resource.  Right know the only piece of information that resources
-hold are observers.  These observers can be held in the project.
+hold are observers.  These observers can be held in projects.
 
 The other issue is equality check.  We can easily change resources to
 compare their addresses for equality.
 
-Reference to value transition:
 
-* Moving observers to projects to make resources immutable
-* __eq__
-* __hash__
+Introducing Invalidation Observers
+----------------------------------
 
+Moving files makes fileeditors update the name of editors.  If we
+change resources to be value objects there seems to be no way for
+informing observers about the new location of the resource.  So
+we either have to close the editor or tell the location of the moved
+resource to the fileeditor.
 
-Changing Observers
-------------------
+To overcome this problem we can have a set of invalidation
+observers for each resource.  When a resource is invalidated we inform
+these ovservers.  We can add an optional argument for passing the new
+location location of the resource if we know it.  This case occurs
+only when we are moving resources.  For moving files the new resource
+can be found trivially, but for children of folders it needs a bit of
+work.
 
-We are going to move observers from `Resource` to `Project`.  So there
-does not seem to be much interest toward having observers that are
-interested only in a certain resource.
+Now that we have two kinds of observers for each resource we can
+classify the situations in which they are called.  Maybe we can make
+a new `ResourceObserver` interface.::
+  
+  class ResourceObserver(object):
+      
+      def resource_changed(self, resource):
+          """Is called when the content of `resource` changes"""
+      
+      def resource_removed(self, resource, new_resource):
+          """Is called when `resource` no longer exists"""
+
+Or maybe we can have a single interface but the observer should
+determine either the resource is changed or it is invalidated.::
+  
+  class ResourceObserver(object):
+  
+      def resource_changed(self, resource, new_resource=None):
+          if resource.exists():
+              # resource is changed
+          else:
+              # resource is invalidated
+  
+This approach seem to require less modification to adapt a new
+interface that supports invalidation.
+
+
+Changing Resource Observing Interface
+-------------------------------------
+
+We are going to move observers from `Resource` to `Project`.  Now
+let's consider observers that are interested in changes to all of
+the resources.
+
+* We can have a list of general observers in `Project`.  When a
+  resource changes we inform these observers.  If this resource
+  is a folder the observer should check whether the file or folder
+  it is interested in is a child of this folder or not.
+  
+  In this approach we should change the old observers.  This class
+  might work as an adapter: ::
+    
+    class IndividualResourceObserver(object):
+    
+        def __init__(self, resource, observer):
+            self.resource = resource
+            self.observer = observer
+        
+        def resource_changed(self, resource):
+            if resource == self.resource:
+                self.observer.resource_changed()
+        
+        def resource_removed(self, resource, new_location):
+            if resource == self.resource:
+                self.observer.resource_invalidated(new_location)
+            elif resource.is_folder() and resource.contain(self.resource):
+                new_location = self._calculate(resource, new_location)
+                self.observer.resource_invalidated(new_location)
+
+
+* We can have a list of observers for individual resources in
+  `Project`.  When a resource is changed we check to see whether
+  there are any observers for that resource or not.  This seems
+  a bit tricky, since when folders invalidate, all of its children
+  are invalidated, too.::
+    
+    def resource_changed(self, resource):
+        if resource in self.observers:
+            for observer in self.observers[resource]:
+                observer.resource_changed(resource)
+    
+    def resource_removed(self, resource, new_resource):
+        if resource in self.observers:
+            for observer in self.observers[resource]:
+                observer.resource_invalidated(resource, new_resource)
+        if resource.is_folder():
+            for observed in self.observers:
+                if resource.contains(observed):
+                    new_observed = self._calculate(...)
+                    for observer in self.observers[observed]:
+                        observer.resource_invalidated(observed, new_observed)
 
 
 Holding Last Changed Time For Resources
 ---------------------------------------
 
+In order to be notified about the changes made by others we need to
+save the last time a file was changed by rope.
+
 
 Inline Method
 =============

docs/dev/stories.txt

 * Find occurances
 
 
+> Public Release 0.4m3 : December 17, 2006
+
+
 * Introduce parameter
   Change global accesses or attributes accesses to parameters
+
+
+* Extending and having more control on file reading and writing
+
+
+* Better support for other version control systems
+
+
+* Removing 4-space tabs and no hard tabs assumption in `rope.base`
+
+
+* Updating files that are changed outside rope

docs/dev/workingon.txt

-Change Method Signature
-=======================
+Enhancing Base
+==============
 
-- Adding ``docs/index.txt`` to help menu
+- `__eq__` and `__hash__`
+- Moving observers to projects to make resources immutable
+- Adding `Resource.exists`
+- Adding `Folder.contains`
+- Per project observers
+- Removing ``resource.get_parent().child_changed(...)``
+- Fixing the UI; resource moving and file editor title changing
+
+* Fix marked tests in `projecttest`
+* Moving observing implementation from resources to projects
+* Allowing non-existance resources?
+* `Project.validate_resource`
+* Using last changed time in `Project.validate_resource`
+* Revalidate the whole project
+* Testing svn for moving folders
+
+
+Remaining Stories
+=================
 
 * Changing signature in class hierarchies
 * Adding ignored file patterns in projects
 * Problems for inside generator assists
 * Performing actions on individual functions or imports
-* Distinction between refactorings that can be used by other
-  refactorings; should they operate on pymodules?
-
-
-Remaining Stories
-=================
-
 * `PyClass.superclasses` should be concluded data
 * Better `ropetest` package structure
 * Decide when to use `difflib` in `Editor.set_text`
 """rope, a python refactoring IDE"""
 
-VERSION = '0.4m2'
+VERSION = '0.4m3'

rope/base/project.py

 class _Project(object):
     
     def __init__(self, fscommands):
-        self.resources = {}
         self.fscommands = fscommands
+        self.robservers = {}
+        self.observers = set()
+    
+    def add_observer(self, observer):
+        self.observers.add(observer)
+    
+    def remove_observer(self, observer):
+        if observer in self.observers:
+            self.observers.remove(observer)
 
     def get_resource(self, resource_name):
-        if resource_name not in self.resources:
-            path = self._get_resource_path(resource_name)
-            if not os.path.exists(path):
-                raise RopeException('Resource %s does not exist' % resource_name)
-            elif os.path.isfile(path):
-                self.resources[resource_name] = File(self, resource_name)
-            elif os.path.isdir(path):
-                self.resources[resource_name] = Folder(self, resource_name)
-            else:
-                raise RopeException('Unknown resource ' + resource_name)
-        return self.resources[resource_name]
+        path = self._get_resource_path(resource_name)
+        if not os.path.exists(path):
+            raise RopeException('Resource %s does not exist' % resource_name)
+        elif os.path.isfile(path):
+            return File(self, resource_name)
+        elif os.path.isdir(path):
+            return Folder(self, resource_name)
+        else:
+            raise RopeException('Unknown resource ' + resource_name)
 
     def _create_file(self, file_name):
         file_path = self._get_resource_path(file_name)
     def _get_resource_path(self, name):
         pass
 
-    def _update_resource_location(self, resource, new_location=None):
-        del self.resources[resource.get_path()]
-        if new_location is not None:
-            self.resources[new_location] = resource
-
     def remove_recursively(self, path):
         self.fscommands.remove(path)
 
         fscommands = rope.base.fscommands.create_fscommands(self.root)
         super(Project, self).__init__(fscommands)
         self.pycore = rope.base.pycore.PyCore(self)
-        self.resources[''] = Folder(self, '')
         self.no_project = NoProject()
 
     def get_root_folder(self):
     def __init__(self, project, name):
         self.project = project
         self.name = name
-        self.observers = []
+        
+    def _get_observers(self):
+        return self.project.observers
+    
+    observers = property(_get_observers)
 
     def get_path(self):
         """Return the path of this resource relative to the project root
         """Return the name of this resource"""
         return self.name.split('/')[-1]
     
+    def move(self, new_location):
+        """Move resource to new_lcation"""
+        destination = self._get_destination_for_move(new_location)
+        self.project.fscommands.move(self._get_real_path(),
+                                     self.project._get_resource_path(destination))
+        new_resource = self.project.get_resource(destination)
+        for observer in list(self.observers):
+            observer.resource_removed(self, new_resource)
+    
     def remove(self):
         """Remove resource from the project"""
+        self.project.remove_recursively(self._get_real_path())
+        for observer in list(self.observers):
+            observer.resource_removed(self)
     
-    def move(self, new_location):
-        """Move resource to new_lcation"""
-
     def is_folder(self):
         """Return true if the resource is a folder"""
-
-    def add_change_observer(self, observer):
-        self.observers.append(observer)
-
-    def remove_change_observer(self, observer):
-        if observer in self.observers:
-            self.observers.remove(observer)
+    
+    def exists(self):
+        os.path.exists(self._get_real_path())
 
     def get_parent(self):
         parent = '/'.join(self.name.split('/')[0:-1])
             else:
                 return self.get_name()
         return destination
+    
+    def __eq__(self, obj):
+        return self.__class__ == obj.__class__ and self.name == obj.name
+    
+    def __hash__(self):
+        return hash(self.name)
 
 
 class File(Resource):
     def read(self):
         source_bytes = open(self._get_real_path()).read()
         return self._file_data_to_unicode(source_bytes)
-        
+    
     def _file_data_to_unicode(self, data):
         encoding = self._conclude_file_encoding(data)
         if encoding is not None:
         file_.write(contents)
         file_.close()
         for observer in list(self.observers):
-            observer(self)
-        self.get_parent()._child_changed(self)
+            observer.resource_changed(self)
 
     def is_folder(self):
         return False
 
-    def remove(self):
-        self.project.remove_recursively(self._get_real_path())
-        self.project._update_resource_location(self)
-        for observer in list(self.observers):
-            observer(self)
-        self.get_parent()._child_changed(self)
-
-    def move(self, new_location):
-        destination = self._get_destination_for_move(new_location)
-        self.project.fscommands.move(self._get_real_path(),
-                                     self.project._get_resource_path(destination))
-        self.project._update_resource_location(self, destination)
-        self.get_parent()._child_changed(self)
-        self.name = destination
-        self.get_parent()._child_changed(self)
-        for observer in list(self.observers):
-            observer(self)
-    
 
 class Folder(Resource):
     """Represents a folder"""
             file_path = file_name
         self.project._create_file(file_path)
         child = self.get_child(file_name)
-        self._child_changed(child)
+        for observer in list(self.observers):
+            observer.resource_changed(child)
         return child
 
     def create_folder(self, folder_name):
             folder_path = folder_name
         self.project._create_folder(folder_path)
         child = self.get_child(folder_name)
-        self._child_changed(child)
+        for observer in list(self.observers):
+            observer.resource_changed(child)
         return child
 
     def get_child(self, name):
             if resource.is_folder():
                 result.append(resource)
         return result
+    
+    def contains(self, resource):
+        return self != resource and resource.get_path().startswith(self.get_path())
 
-    def remove(self):
-        for child in self.get_children():
-            child.remove()
-        self.project.remove_recursively(self._get_real_path())
-        self.project._update_resource_location(self)
-        self.get_parent()._child_changed(self)
-
-    def move(self, new_location):
-        destination = self._get_destination_for_move(new_location)
-        self.project.fscommands.create_folder(self.project._get_resource_path(destination))
-        for child in self.get_children():
-            if not (child.is_folder() and child.get_name() == '.svn'):
-                child.move(destination + '/' + child.get_name())
-        self.project.fscommands.remove(self._get_real_path())
-        self.project._update_resource_location(self, destination)
-        self.get_parent()._child_changed(self)
-        self.name = destination
-        self.get_parent()._child_changed(self)
-    
     def _child_changed(self, child):
         if child != self:
             for observer in list(self.observers):
-                observer(self)
+                observer.resource_changed(self)
+
+
+class ResourceObserver(object):
+    """Provides the interface observing resources
+    
+    `ResourceObserver` s can be registered using `Resource.add_observer`.
+    """
+    
+    def __init__(self, changed, removed):
+        self.changed = changed
+        self.removed = removed
+    
+    def resource_changed(self, resource):
+        """It is called when the resource changes"""
+        self.changed(resource)
+    
+    def resource_removed(self, resource, new_resource=None):
+        """It is called when a resource no longer exists
+        
+        `new_resource` is the destination if we know it, otherwise it
+        is None.
+        """
+        self.removed(resource, new_resource)
+
+
+class FilteredResourceObserver(object):
+    
+    def __init__(self, resources_getter, resource_observer):
+        self._resources_getter = resources_getter
+        self.observer = resource_observer
+    
+    def _get_resources(self):
+        return self._resources_getter()
+    
+    resources = property(_get_resources)
+    
+    def resource_changed(self, changed):
+        if changed in self.resources:
+            self.observer.resource_changed(changed)
+        self._parents_changed(changed)
+    
+    def resource_removed(self, resource, new_resource=None):
+        if resource in self.resources:
+            self.observer.resource_removed(resource, new_resource)
+        if resource.is_folder():
+            for file in self.resources:
+                if resource.contains(file):
+                    new_file = self._calculate_new_resource(resource, new_resource, file)
+                    self.observer.resource_removed(file, new_file)
+        self._parents_changed(resource)
+        if new_resource is not None:
+            self._parents_changed(new_resource)
+    
+    def _parents_changed(self, child):
+        for resource in self.resources:
+            if resource.is_folder() and child.get_parent() == resource:
+                self.observer.resource_changed(resource)
+
+    def _calculate_new_resource(self, main, new_main, resource):
+        if new_main is None:
+            return None
+        diff = resource.get_path()[:len(main.get_path())]
+        return new_main.get_path() + diff

rope/base/pycore.py

 import re
 import sys
 
+import rope.base.project
 import rope.base.oi.objectinfer
 import rope.refactor
 import rope.base.oi.dynamicoi
         self.refactoring = rope.refactor.PythonRefactoring(self)
         self.dynamicoi = rope.base.oi.dynamicoi.DynamicObjectInference(self)
         self.classes = None
+        observer = rope.base.project.ResourceObserver(
+            self._invalidate_resource_cache, self._invalidate_resource_cache)
+        filtered_observer = rope.base.project.FilteredResourceObserver(
+            self.module_map.keys, observer)
+        self.project.add_observer(filtered_observer)
 
     def get_module(self, name, current_folder=None):
         """Returns a `PyObject` if the module was found."""
         """Returns a `Scope` object for the given module_content"""
         return self.get_string_module(module_content, resource).get_scope()
 
-    def _invalidate_resource_cache(self, resource):
+    def _invalidate_resource_cache(self, resource, new_resource=None):
         self.classes = None
         if resource in self.module_map:
             local_module = self.module_map[resource]
             del self.module_map[resource]
-            resource.remove_change_observer(self._invalidate_resource_cache)
             local_module._invalidate_concluded_data()
 
     def create_module(self, src_folder, new_module):
         else:
             result = PyModule(self, resource.read(), resource=resource)
         self.module_map[resource] = result
-        resource.add_change_observer(self._invalidate_resource_cache)
         return result
     
     def get_python_files(self):

rope/refactor/change.py

 class MoveResource(Change):
     
     def __init__(self, resource, new_location):
-        self.resource = resource
+        self.project = resource.project
         self.new_location = new_location
-        self.old_location = None
+        self.old_location = resource.get_path()
     
     def do(self):
-        self.old_location = self.resource.get_path()
-        self.resource.move(self.new_location)
+        resource = self.project.get_resource(self.old_location)
+        resource.move(self.new_location)
     
     def undo(self):
-        self.resource.move(self.old_location)
+        resource = self.project.get_resource(self.new_location)
+        resource.move(self.old_location)
 
     def __str__(self):
-        return 'Move <%s>' % self.resource.get_path()
+        return 'Move <%s>' % self.old_location
 
     def get_description(self):
-        return 'Move <%s> to <%s>' % (self.resource.get_path(), self.new_location)
+        return 'Move <%s> to <%s>' % (self.old_location, self.new_location)
 
 
 class CreateFolder(Change):

rope/ui/fileeditor.py

 import Tkinter
 
 import rope.base.exceptions
+from rope.base.project import ResourceObserver, FilteredResourceObserver
 from rope.ui import editingcontexts
 
 class FileEditor(object):
         self.editor.set_text(self.file.read())
         self.modification_observers = []
         self.editor.add_modification_observer(self._editor_was_modified)
-        self.file.get_parent().add_change_observer(self._editor_was_modified)
-        self.file.add_change_observer(self._file_was_modified)
+        self._register_observers()
         self.saving = False
         self.readonly = readonly
         #if readonly:
         #    self.editor.getWidget()['state'] = Tkinter.DISABLED
     
+    def _register_observers(self):
+        self.observer = FilteredResourceObserver(
+            lambda: [self.file],
+            ResourceObserver(self._file_was_modified, self._file_was_removed))
+        self.project.add_observer(self.observer)
+    
+    def _remove_observers(self):
+        self.project.remove_observer(self.observer)
+    
     def _editor_was_modified(self, *args):
         for observer in list(self.modification_observers):
             observer(self)
     
+    def _file_was_removed(self, file, new_file=None):
+        self._remove_observers()
+        self.file = new_file
+        self._register_observers()
+        self._editor_was_modified()
+    
     def _file_was_modified(self, file_):
         if not self.saving:
             self.editor.set_text(file_.read())
         return self.file
     
     def close(self):
-        self.file.remove_change_observer(self._file_was_modified)
+        self._remove_observers()
 

ropetest/projecttest.py

 import unittest
 import os
 
-from rope.base.project import Project
+from rope.base.project import Project, FilteredResourceObserver
 from rope.base.exceptions import RopeException
 from ropetest import testutils
 
     def test_resource_change_observer(self):
         sample_file = self.project.get_root_folder().create_file('my_file.txt')
         sample_file.write('a sample file version 1')
-        sample_observer = SampleObserver()
-        sample_file.add_change_observer(sample_observer.changed)
+        sample_observer = _SampleObserver()
+        self.project.add_observer(sample_observer)
         sample_file.write('a sample file version 2')
         self.assertEquals(1, sample_observer.change_count)
         self.assertEquals(sample_file, sample_observer.last_changed)
 
     def test_resource_change_observer_after_removal(self):
         sample_file = self.project.get_root_folder().create_file('my_file.txt')
-        sample_file.write('a sample file version 1')
-        sample_observer = SampleObserver()
-        sample_file.add_change_observer(sample_observer.changed)
+        sample_file.write('text')
+        sample_observer = _SampleObserver()
+        self.project.add_observer(FilteredResourceObserver(lambda: [sample_file],
+                                                           sample_observer))
         sample_file.remove()
         self.assertEquals(1, sample_observer.change_count)
         self.assertEquals(sample_file, sample_observer.last_changed)
 
-    def test_resource_change_observer(self):
+    def test_resource_change_observer2(self):
         sample_file = self.project.get_root_folder().create_file('my_file.txt')
-        sample_observer = SampleObserver()
-        sample_file.add_change_observer(sample_observer.changed)
-        sample_file.remove_change_observer(sample_observer.changed)
+        sample_observer = _SampleObserver()
+        self.project.add_observer(sample_observer)
+        self.project.remove_observer(sample_observer)
         sample_file.write('a sample file version 2')
         self.assertEquals(0, sample_observer.change_count)
 
     def test_resource_change_observer_for_folders(self):
         root_folder = self.project.get_root_folder()
         my_folder = root_folder.create_folder('my_folder')
-        my_folder_observer = SampleObserver()
-        root_folder_observer = SampleObserver()
-        my_folder.add_change_observer(my_folder_observer.changed)
-        root_folder.add_change_observer(root_folder_observer.changed)
+        my_folder_observer = _SampleObserver()
+        root_folder_observer = _SampleObserver()
+        self.project.add_observer(FilteredResourceObserver(
+                                  lambda: [my_folder], my_folder_observer))
+        self.project.add_observer(FilteredResourceObserver(
+                                  lambda: [root_folder], root_folder_observer))
         my_file = my_folder.create_file('my_file.txt')
         self.assertEquals(1, my_folder_observer.change_count)
         my_file.move('another_file.txt')
         self.assertEquals(2, my_folder_observer.change_count)
         self.assertEquals(1, root_folder_observer.change_count)
-        my_file.remove()
+        moved_file = self.project.get_resource('another_file.txt')
+        moved_file.remove()
         self.assertEquals(2, my_folder_observer.change_count)
         self.assertEquals(2, root_folder_observer.change_count)
 
         root_folder = self.project.get_root_folder()
         my_file = root_folder.create_file('my_file.txt')
         my_file.move('my_other_file.txt')
-        self.assertFalse(root_folder.has_child('my_file.txt'))
-        self.assertEquals(my_file, root_folder.get_child('my_other_file.txt'))
-        self.assertEquals('my_other_file.txt', my_file.get_path())
+        self.assertFalse(my_file.exists())
+        root_folder.get_child('my_other_file.txt')
                           
-    def test_moving_folders(self):
+    # XXX: Make it work after making resources value objects
+    def xxx_test_moving_folders(self):
         root_folder = self.project.get_root_folder()
         my_folder = root_folder.create_folder('my_folder')
         my_file = my_folder.create_file('my_file.txt')
         my_file = root_folder.create_file('my_file.txt')
         my_file.move('my_folder')
         self.assertFalse(root_folder.has_child('my_file.txt'))
-        self.assertEquals(my_file, my_folder.get_child('my_file.txt'))
-        self.assertEquals('my_folder/my_file.txt', my_file.get_path())
+        self.assertFalse(my_file.exists())
+        my_folder.get_child('my_file.txt')
                           
-    def test_moving_files_and_reference_objects(self):
+    # XXX: Make it work after making resources value objects
+    def xxx_test_moving_files_and_resource_objects(self):
         root_folder = self.project.get_root_folder()
         my_file = root_folder.create_file('my_file.txt')
         old_hash = hash(my_file)
         my_file.move('my_other_file.txt')
         self.assertEquals(old_hash, hash(my_file))
                           
-    def test_resource_change_observer_after_moving(self):
+    # XXX: Make it work after making resources value objects
+    def xxx_test_resource_change_observer_after_moving(self):
         sample_file = self.project.get_root_folder().create_file('my_file.txt')
-        sample_observer = SampleObserver()
-        sample_file.add_change_observer(sample_observer.changed)
+        sample_observer = _SampleObserver()
+        sample_file.add_observer(sample_observer)
         sample_file.move('new_file.txt')
         self.assertEquals(1, sample_observer.change_count)
         self.assertEquals(sample_file, sample_observer.last_changed)
         self.assertEquals(contents, sample_file.read())
 
 
-class SampleObserver(object):
+class _SampleObserver(object):
+    
     def __init__(self):
         self.change_count = 0
         self.last_changed = None
 
-    def changed(self, resource):
+    def resource_changed(self, resource):
+        self.last_changed = resource
+        self.change_count += 1
+    
+    def resource_removed(self, resource, new_resource=None):
         self.last_changed = resource
         self.change_count += 1
 

ropetest/refactor/movetest.py

         self.mod2.write('import mod1\nprint mod1')
         self.refactoring.move(self.mod2, self.mod2.read().index('mod1') + 1, self.pkg)
         self.assertEquals('import pkg.mod1\nprint pkg.mod1', self.mod2.read())
-        self.assertEquals('pkg/mod1.py', self.mod1.get_path())
+        self.assertTrue(not self.mod1.exists() and
+                        self.pycore.find_module('pkg.mod1') is not None)
         
     def test_moving_modules_and_removing_out_of_date_imports(self):
         self.mod2.write('import pkg.mod4\nprint pkg.mod4')
         self.refactoring.move(self.mod2, self.mod2.read().index('mod4') + 1,
                               self.project.get_root_folder())
         self.assertEquals('import mod4\nprint mod4', self.mod2.read())
-        self.assertEquals('mod4.py', self.mod4.get_path())
+        self.assertTrue(self.pycore.find_module('mod4') is not None)
     
     def test_moving_modules_and_removing_out_of_date_froms(self):
         self.mod2.write('from pkg import mod4\nprint mod4')
         self.refactoring.move(self.mod2, self.mod2.read().index('mod4') + 1,
                               self.project.get_root_folder())
         self.assertEquals('import mod4\nprint mod4', self.mod2.read())
-        self.assertEquals('mod4.py', self.mod4.get_path())
     
     def test_moving_modules_and_removing_out_of_date_froms2(self):
         self.mod4.write('a_var = 10')
         self.mod2.write('import pkg.mod4\nprint pkg.mod4')
         self.refactoring.move(self.mod2, self.mod2.read().index('mod4') + 1,
                               self.project.get_root_folder())
-        self.assertEquals('import pkg.mod5\nprint pkg.mod5\n', self.mod4.read())
+        moved = self.pycore.find_module('mod4')
+        self.assertEquals('import pkg.mod5\nprint pkg.mod5\n', moved.read())
 
     def test_moving_packages(self):
         pkg2 = self.pycore.create_package(self.project.get_root_folder(), 'pkg2')
         self.mod1.write('import pkg.mod4\nprint pkg.mod4')
         self.refactoring.move(self.mod1, self.mod1.read().index('pkg') + 1, pkg2)
-        self.assertEquals('pkg2/pkg', self.pkg.get_path())
-        self.assertEquals('pkg2/pkg/mod4.py', self.mod4.get_path())
-        self.assertEquals('pkg2/pkg/mod5.py', self.mod5.get_path())
+        self.assertFalse(self.pkg.exists())
+        self.assertTrue(self.pycore.find_module('pkg2.pkg.mod4') is not None)
+        self.assertTrue(self.pycore.find_module('pkg2.pkg.mod4') is not None)
+        self.assertTrue(self.pycore.find_module('pkg2.pkg.mod5') is not None)
         self.assertEquals('import pkg2.pkg.mod4\nprint pkg2.pkg.mod4', self.mod1.read())
 
     def test_moving_modules_with_self_imports(self):
         self.mod1.write('import mod1\nprint mod1\n')
         self.mod2.write('import mod1\n')
         self.refactoring.move(self.mod2, self.mod2.read().index('mod1') + 1, self.pkg)
-        self.assertEquals('import pkg.mod1\nprint pkg.mod1\n', self.mod1.read())
+        moved = self.pycore.find_module('pkg.mod1')
+        self.assertEquals('import pkg.mod1\nprint pkg.mod1\n', moved.read())
     
     # TODO: moving fields
     def xxx_test_moving_fields(self):

ropetest/refactor/renametest.py

         mod1.write('def a_func():\n    pass\n')
         mod2 = self.pycore.create_module(self.project.get_root_folder(), 'mod2')
         mod2.write('from mod1 import a_func\n')
-        self.refactoring.rename(mod2, 6, 'newmod')
-        self.assertEquals('newmod.py', mod1.get_path())
+        self.refactoring.rename(mod2, mod2.read().index('mod1') + 1, 'newmod')
+        self.assertTrue(not mod1.exists() and
+                        self.pycore.find_module('newmod') is not None)
         self.assertEquals('from newmod import a_func\n', mod2.read())
 
     def test_renaming_packages(self):
         mod2 = self.pycore.create_module(pkg, 'mod2')
         mod2.write('from pkg.mod1 import a_func\n')
         self.refactoring.rename(mod2, 6, 'newpkg')
-        self.assertEquals('newpkg/mod1.py', mod1.get_path())
-        self.assertEquals('from newpkg.mod1 import a_func\n', mod2.read())
+        self.assertTrue(self.pycore.find_module('newpkg.mod1') is not None)
+        new_mod2 = self.pycore.find_module('newpkg.mod2')
+        self.assertEquals('from newpkg.mod1 import a_func\n', new_mod2.read())
 
     def test_module_dependencies(self):
         mod1 = self.pycore.create_module(self.project.get_root_folder(), 'mod1')