Commits

Anonymous committed c498bfb

Eliminated PyFilteredPackage

Comments (0)

Files changed (7)

 ===========
 
 
+- Showing editor modified status : July 23, 2006
+
+
 - Sorting code assist proposals : July 22, 2006
 
 
   * Edit menu: cut, paste, undo, redo, revert
 
 
-* Asking whether to save buffer when exiting @ 4h
-
-
-* Showing modified file status @ 8h
+* Asking whether to save modified buffers when exiting @ 4h
 
 
 Remaining Stories

docs/workingon.txt

 Pre-Release Refactorings
 ========================
 
+Goals:
+
 * Go to definition for packages should go to __init__.py; for FilteredPackages also
-* Eliminate FilteredPackage
-* Each PyPackage should have
+* Do something for modules that can not be found
+* Dotted not found modules
 
-  * The list of available children; derived from `__init__.py` or imports/froms
-  * An import_name function that throws exception if the name cannot be found
+Problems with what we have right now:
+
+* PyFilteredPackages should have the __init__.py resource
+* PyPackages should not expose all of their submodules
+* module.is_package is scattered everywhere; replace it with isinstance
+
+Possible solutions:
+
+* Eliminate PyFilteredPackage all together
+* PyPackage should be filtered by itself
+
 
 
 Before 0.2 Release
 ==================
-* GUI testing redux; make a ropefunctest directory?; rename ropetest to ropeunittest?
+* GUI testing redux; make a functests directory?; rename ropetest to unittests?
 * Better editor changing dialog; use uihelpers module
 * Enhancing highlighting
 * Profiling to find the bottlenecks
 * More work on WordRangeFinder._get_statment_start; merging with StatementRangeFinder?
 * Having only one Refactoring instance for a project?
 * PyObject and PyName equality checks; Value objects?
-* Refactor pycore; So many kinds for Modules; eliminate checking module.is_package?
 * Consider using `StatementRangeFinder` in highlight module?
 * Directories should contain __init__.py to be packages in codeassist?
 * Code assists on relative imports?

rope/codeassist.py

     def _get_default_templates(self):
         result = []
         result.append(TemplateProposal('main', Template("if __name__ == '__main__':\n    ${cursor}\n")))
-        test_case_template = "import unittest\n\nclass ${class}(unittest.TestCase):\n\n" + \
+        test_case_template = "import unittest\n\n"+ \
+                             "class ${class}(unittest.TestCase):\n\n" + \
                              "    def setUp(self):\n        super(${class}, self).setUp()\n\n" + \
                              "    def tearDown(self):\n        super(${class}, self).tearDown()\n\n" + \
                              "    def test_${aspect1}(self):\n        pass${cursor}\n\n\n" + \
-                             "if __name__ == '__main__':\n    unittest.main()\n"
+                             "if __name__ == '__main__':\n" + \
+                             "    unittest.main()\n"
         result.append(TemplateProposal('test_case', Template(test_case_template)))
         result.append(TemplateProposal('hash', Template('\n    def __hash__(self):\n' + \
                                                         '        return 1${cursor}\n')))
         result.append(TemplateProposal('eq', Template('\n    def __eq__(self, obj):\n' + \
-                                                        '        ${cursor}return obj is self\n')))
+                                                      '        ${cursor}return obj is self\n')))
         result.append(TemplateProposal('super', Template('super(${class}, self)')))
         return result
 
 
     def saving_editor(self):
         self.text.edit_separator()
-        self.text.edit_modified(False)
+        if self.is_modified():
+            self.text.edit_modified(False)
 
     def undo(self):
         try:
         if not results:
             raise ModuleNotFoundException('Module %s not found' % name)
         result = results[0]
-        return self._create(results[0])
+        return self.resource_to_pyobject(results[0])
 
     def get_string_module(self, module_content):
         """Returns a `PyObject` object for the given module_content"""
             del self.module_map[resource]
             resource.remove_change_observer(self._invalidate_resource_cache)
 
-    def _create(self, resource):
-        if resource in self.module_map:
-            return self.module_map[resource]
-        if resource.is_folder():
-            result = PyPackage(self, resource)
-        else:
-            ast = compiler.parse(resource.read())
-            result = PyModule(self, ast, resource=resource)
-        self.module_map[resource] = result
-        resource.add_change_observer(self._invalidate_resource_cache)
-        return result
-
     def create_module(self, src_folder, new_module):
-        """Creates a module"""
+        """Creates a module and returns a `rope.project.File`"""
         packages = new_module.split('.')
         parent = src_folder
         for package in packages[:-1]:
         return parent.create_file(packages[-1] + '.py')
 
     def create_package(self, src_folder, new_package):
-        """Creates a package"""
+        """Creates a package and returns a `rope.project.Folder`"""
         packages = new_package.split('.')
         parent = src_folder
         for package in packages[:-1]:
         return created_package
 
     def _find_module_in_source_folder(self, source_folder, module_name):
+        result = []
         module = source_folder
         packages = module_name.split('.')
         for pkg in packages[:-1]:
             if  module.is_folder() and module.has_child(pkg):
                 module = module.get_child(pkg)
+                result.append(module)
             else:
                 return None
         if not module.is_folder():
 
         if module.has_child(packages[-1]) and \
            module.get_child(packages[-1]).is_folder():
-            return module.get_child(packages[-1])
+            result.append(module.get_child(packages[-1]))
+            return result
         elif module.has_child(packages[-1] + '.py') and \
              not module.get_child(packages[-1] + '.py').is_folder():
-            return module.get_child(packages[-1] + '.py')
+            result.append(module.get_child(packages[-1] + '.py'))
+            return result
         return None
-
+    
     def _get_python_path_folders(self):
         result = []
         for src in sys.path:
         for src in self.get_source_folders():
             module = self._find_module_in_source_folder(src, module_name)
             if module is not None:
+                result.append(module[-1])
+        if result:
+            return result
+        for src in self._get_python_path_folders():
+            module = self._find_module_in_source_folder(src, module_name)
+            if module is not None:
+                result.append(module[-1])
+        return result
+    
+    def _find_module_resource_list(self, module_name):
+        """Returns a list of lists of `Folder`s and `File`s for the given module"""
+        result = []
+        for src in self.get_source_folders():
+            module = self._find_module_in_source_folder(src, module_name)
+            if module is not None:
                 result.append(module)
         if result:
             return result
     def get_source_folders(self):
         """Returns project source folders"""
         return self._find_source_folders(self.project.get_root_folder())
+    
+    def resource_to_pyobject(self, resource):
+        if resource in self.module_map:
+            return self.module_map[resource]
+        if resource.is_folder():
+            result = PyPackage(self, resource)
+        else:
+            ast = compiler.parse(resource.read())
+            result = PyModule(self, ast, resource=resource)
+        self.module_map[resource] = result
+        resource.add_change_observer(self._invalidate_resource_cache)
+        return result
 
     def _is_package(self, folder):
         if folder.has_child('__init__.py') and \
     def get_resource(self):
         return self.resource
 
+
 class PyPackage(PyDefinedObject):
 
-    def __init__(self, pycore, resource):
-        if resource.has_child('__init__.py'):
+    def __init__(self, pycore, resource=None):
+        self.resource = resource
+        self.is_package = True
+        if resource is not None and resource.has_child('__init__.py'):
             ast_node = compiler.parse(resource.get_child('__init__.py').read())
         else:
             ast_node = compiler.parse('\n')
         super(PyPackage, self).__init__(PyObject.get_base_type('Module'), pycore, ast_node, None)
-        self.is_package = True
-        self.resource = resource
 
     def _update_attributes_from_ast(self, attributes):
+        if self.resource is None:
+            return
         for child in self.resource.get_children():
             if child.is_folder():
-                attributes[child.get_name()] = PyName(self.pycore._create(child))
+                child_pyobject = self.pycore.resource_to_pyobject(child)
+                attributes[child.get_name()] = PyName(child_pyobject, False, 1,
+                                                      child_pyobject.get_resource())
             elif child.get_name().endswith('.py') and \
                  child.get_name() != '__init__.py':
                 name = child.get_name()[:-3]
-                attributes[name] = PyName(self.pycore._create(child))
+                child_pyobject = self.pycore.resource_to_pyobject(child)
+                attributes[name] = PyName(child_pyobject, False, 1,
+                                                      child_pyobject.get_resource())
 
     def get_resource(self):
-        if self.resource.has_child('__init__.py'):
+        if self.resource is not None and self.resource.has_child('__init__.py'):
             return self.resource.get_child('__init__.py')
         else:
             return None
-            
-
-class PyFilteredPackage(PyObject):
-
-    def __init__(self):
-        super(PyFilteredPackage, self).__init__(PyObject.get_base_type('Module'))
-        self.is_package = True
-        self.attributes = {}
-
-    def get_attributes(self):
-        return self.attributes
-
-    def _add_attribute(self, name, pyname):
-        self.attributes[name] = pyname
 
 
 class PyName(object):
                 lineno = None
             if alias is None and '.' in imported:
                 tokens = imported.split('.')
-                if tokens[0] in self.names and \
-                   isinstance(self.names[tokens[0]].object, PyFilteredPackage):
-                    pypkg = self.names[tokens[0]].object
-                else:
-                    pypkg = PyFilteredPackage()
-                    self.names[tokens[0]] = PyName(pypkg)
-                for token in tokens[1:-1]:
-                    if token in pypkg.get_attributes() and \
-                       isinstance(pypkg.get_attributes()[token].object,
-                                  PyFilteredPackage):
-                        newpkg = pypkg.get_attributes()[token].object
-                    else:
-                        newpkg = PyFilteredPackage()
-                        pypkg._add_attribute(token, PyName(newpkg))
-                    pypkg = newpkg
-                pypkg._add_attribute(tokens[-1], PyName(module, False, 
-                                                        module=module_resource, lineno=lineno))
+                toplevel_module = self._get_module_with_packages(name)
+                self.names[tokens[0]] = PyName(toplevel_module, False, 
+                                               module=toplevel_module.get_resource(), lineno=lineno)
             else:
                 self.names[imported] = PyName(module, False, module=module_resource, lineno=lineno)
 
+    def _get_module_with_packages(self, module_name):
+        found_modules = self.pycore._find_module_resource_list(module_name)
+        if len(found_modules) == 0:
+            return None
+        module_list = found_modules[0]
+        return self.pycore.resource_to_pyobject(module_list[0])
+
     def visitFrom(self, node):
         try:
             module = self.pycore.get_module(node.modname)
         except ModuleNotFoundException:
-            module = PyFilteredPackage()
+            module = PyPackage(self.pycore)
 
         if node.names[0][0] == '*':
             if module.is_package:
                 if module.get_attributes().has_key(name):
                     imported_pyname = module.get_attributes()[name]
                     imported_object = imported_pyname.object
-                    if isinstance(imported_object, PyPackage):
-                        self.names[imported] = PyFilteredPackage()
-                    else:
-                        pyname_module = module
-                        lineno = None
-                        if imported_pyname.module is not None:
-                            pyname_module = imported_pyname.module
-                            lineno = imported_pyname.get_definition_location()[1]
-                        if imported_pyname.get_type() == PyObject.get_base_type('Module'):
-                            pyname_module = imported_pyname.get_object().get_resource()
-                            lineno = 1                            
-                        self.names[imported] = PyName(imported_object, False, module=pyname_module,
-                                                      lineno=lineno)
+                    pyname_module = module
+                    lineno = None
+                    if imported_pyname.module is not None:
+                        pyname_module = imported_pyname.module
+                        lineno = imported_pyname.get_definition_location()[1]
+                    if imported_pyname.get_type() == PyObject.get_base_type('Module'):
+                        pyname_module = imported_pyname.get_object().get_resource()
+                        lineno = 1                            
+                    self.names[imported] = PyName(imported_object, False, module=pyname_module,
+                                                  lineno=lineno)
                 else:
                     self.names[imported] = PyName()
 

ropetest/pycoretest.py

         pkg = self.pycore.create_package(self.project.get_root_folder(), 'pkg')
         mod = self.pycore.create_module(pkg, 'mod')
         package = self.pycore.get_module('pkg')
-        self.assertEquals(PyObject.get_base_type('Module'), package.type)
+        self.assertEquals(PyObject.get_base_type('Module'), package.get_type())
         self.assertEquals(1, len(package.get_attributes()))
         module = package.get_attributes()['mod']
         self.assertEquals(PyObject.get_base_type('Module'), module.get_type())
         pkg_pyname = mod.get_attributes()['pkg']
         self.assertEquals((init_dot_py, 1), pkg_pyname.get_definition_location())
         
-    # TODO: Eliminate PyFilteredPackage
-    def xxx_test_get_definition_location_for_filtered_packages(self):
+    def test_get_definition_location_for_filtered_packages(self):
         pkg = self.pycore.create_package(self.project.get_root_folder(), 'pkg')
         self.pycore.create_module(pkg, 'mod')
         init_dot_py = pkg.get_child('__init__.py')
         module = mod.get_attributes()['mod1']
         self.assertTrue('f' in module.get_attributes())
         
-    def test_from_package_import_package(self):
+    # TODO: not showing unimported names as attributes of packages
+    def xxx_test_from_package_import_package(self):
         pkg1 = self.pycore.create_package(self.project.get_root_folder(), 'pkg1')
         pkg2 = self.pycore.create_package(pkg1, 'pkg2')
         module = self.pycore.create_module(pkg2, 'mod')
         samplemod = self.pycore.get_module('samplemod').get_resource()
         self.assertEquals((samplemod, 1), sample_class.get_definition_location())
         
+    def test_nested_modules(self):
+        pkg = self.pycore.create_package(self.project.get_root_folder(), 'pkg')
+        mod = self.pycore.create_module(pkg, 'mod')
+        scope = self.pycore.get_string_scope('import pkg.mod\n')
+        mod_pyobject = scope.get_names()['pkg'].get_attributes()['mod']
+        self.assertEquals((mod, 1), mod_pyobject.get_definition_location())
+
 
 class PyCoreScopesTest(unittest.TestCase):