Commits

Ali Gholami Rudi  committed 0306965

Adding pycore module

  • Participants
  • Parent commits 3373663

Comments (0)

Files changed (16)

-rope, A python IDE
+rope, A python IDE ...
 
 Overview
 --------

File docs/done.txt

+- Next/prev word stops at underlines and capitals : May 29, 2006
+
+
 - Ignoring string and comment contents while indenting : May 29, 2006
 
 

File docs/stories.txt

-rope; A Python IDE
+rope; A Python IDE ...
 
 --- Stories ---
 
 * Configuring fonts @ 1
 
 
-* Showing syntactical errors @ 5
+* Showing syntactical errors @ 3
 
 
 * Editor folding @ 4
 
 
 * Enhancing auto indentation @ 1
-  * Ignoring comment lines
-  * Implicit line joining: Indenting lines whose previous line contains a ([{'''
   * Indenting a range of file
   * Removing extra spaces
   ? Separating entering and correcting indentation
     is active do the builtin cut and paste
   * Edit menu: cut, paste, undo, redo, revert
   * Showing modified file status
+  * Handle MYClass style names in next/prev word
 
 
 * Show quick outline; C-o @ 2
 
 
+* Auto-completing inherited methods @ 2
+
+
 * Auto-completing function parameter names when calling @ 2
 
 
   in codeassist
 
 
-* Control blocks and auto-completion @ 1
+* Compound statements and auto-completion @ 1
   Completions for for-loop, except, lambda and with variables
 
 
   * Sorting proposals
 
 
-* Auto completing and comments and strings @ 2
+* Auto completion contexts; strings, comments, functions and ... @ 2
+
+
+* Auto completion after "."s @ 3
 
 
 > Public release 0.2pre2 : June 4, 2006
 
 
-* Auto completion after "."s @ 3
-  * Auto-completing "self."s
+* Auto-completing "self."s @ 2
 
 
 --- Remaining Stories ---
 ? Functional tests
 i Separate domain and presentation everywhere
 * Logo
-* Make tests less dependant
 ? Project resource consistency; What if it is deleted after being created.

File docs/workingon.txt

-*** Next/prev word should stop at underlines and capitals; make it configurable ***
+*** Auto-completing "self."s @ 2 ***
 
-* Handle MYClass style names
+- Add project.RootFolder
+- Using path separators when setting PYTHONPATH
+- Package
+- PyElement.get_name()
+- Variables in global scope
+- Variables in class scope
+- Finding attributes set in class.__init__
+- Accessing PyObject type
+- Builtin types: Module, Function, Type
+- Add Unknown type
+
+? PyObject.info
+    * Function types should have args, defaults, keywords attributes
+* Better attributes names in pycore classes
+* Classes inside classes
+? Classes and functions defined in functions
+? What if the element does not exist
+? Getting children only when necessary, invalidating
+? PyObject equality check; Value objects
+
+? Don't look for local variable completions
+? Add PythonHierarchy.create_element(Resource)
+* Using os.path.normpath
+? What to do for AssList and AssTuple
+? Next/Prev words should stop at start/end of the line
+* Change from-import code assist to use PyCore
+? Move Project.find_module and find_package to PyCore
+? Move Project.create_module and create_package to PyCore
+
 
 --- Before 0.2 Release ---
-* GUI testing redux; make a ropefunctest direction; ? rename ropetest to ropeunittest
+* GUI testing redux; make a ropefunctest directory; ? rename ropetest to ropeunittest
 * Better editor changing dialog; use uihelpers module
-* More builtin templates
-* Highlighting enhancement
+* More builtin templates; hash, eq
+* Enhancing highlighting
 * Profiling to find the bottlenecks
+? Ready for announcing at Cheese Shop
 
 
 
     ? Should editing tools access Editor directly? Which of them?
     ? Specifing the type of each story; UI or Core
 ? The connection between ASTs, module hierarchies and type databases
-? Key selection for new module and package
 

File 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}Test(unittest.TestCase):\n\n" + \
-                             "    def setUp(self):\n        super(${class}Test, self).setUp()\n\n" + \
-                             "    def tearDown(self):\n        super(${class}Test, self).tearDown()\n\n" + \
+        test_case_template = "import unittest\n\nclass ${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"
         result.append(TemplateProposal('test_case', Template(test_case_template)))

File rope/indenter.py

             new_indent -= 4
         if current_line.strip() == 'finally:':
             new_indent -= 4
+        if current_line.strip().startswith('elif '):
+            new_indent -= 4
         if current_line.lstrip().startswith('except ') and current_line.rstrip().endswith(':'):
             new_indent -= 4
         return new_indent

File rope/project.py

         self.code_assist = rope.codeassist.CodeAssist(self)
 
     def get_root_folder(self):
-        return Folder(self, '')
+        return RootFolder(self)
 
     def get_root_address(self):
         return self.root
         return self.project
 
 
-class Folder(Resource):
+class _Folder(Resource):
     '''Represents a folder in a project'''
+
     def __init__(self, project, folderName):
         self.project = project
         self.folderName = folderName
         return result
 
     def __eq__(self, resource):
-        if not isinstance(resource, Folder):
+        if not isinstance(resource, _Folder):
             return False
         return self.get_path() == resource.get_path()
 
         return self.project._get_resource_path(self.folderName)
 
 
+class Folder(_Folder):
+    '''Represents a folder in a project'''
+
+    def __init__(self, project, folderName):
+        super(Folder, self).__init__(project, folderName)
+
+
+class RootFolder(_Folder):
+    '''Represents a folder in a project'''
+
+    def __init__(self, project):
+        super(RootFolder, self).__init__(project, '')
+
+
 class FileFinder(object):
     def __init__(self, project):
         self.project = project
         source_folders = []
         for folder in file.get_project().get_source_folders():
             source_folders.append(os.path.abspath(folder._get_real_path()))
-        env['PYTHONPATH'] = env.get('PYTHONPATH', '') + ':' + \
+        env['PYTHONPATH'] = env.get('PYTHONPATH', '') + os.pathsep + \
                             os.pathsep.join(source_folders)
         self.process = subprocess.Popen(executable=sys.executable,
                                         args=(sys.executable, self.file.get_name()),

File rope/pycore.py

+import compiler
+
+
+class PyCore(object):
+
+    def __init__(self, project):
+        self.project = project
+
+    def get_module(self, name):
+        results = self.project.find_module(name)
+        result = results[0]
+        return self.create(results[0])
+
+    def create(self, resource):
+        if resource.is_folder():
+            attributes = {}
+            for child in resource.get_children():
+                if child.is_folder():
+                    attributes[child.get_name()] = self.create(child)
+                elif child.get_name().endswith('.py') and child.get_name() != '__init__.py':
+                    attributes[child.get_name()[:-3]] = self.create(child)
+            return PyObject(PyType.get_type('Module'), attributes)
+        else:
+            attributes = {}
+            ast = compiler.parse(resource.read())
+            visitor = _GlobalVisitor()
+            compiler.walk(ast, visitor)
+            attributes.update(visitor.result)
+            return PyObject(PyType.get_type('Module'), attributes)
+
+
+class PyObject(object):
+
+    def __init__(self, py_type, attributes=None):
+        self.type = py_type
+        if attributes is None:
+            attributes = {}
+        self.object_attributes = attributes
+    
+    def get_attributes(self):
+        return self.object_attributes
+    
+    attributes = property(fget=get_attributes)
+
+
+class PyType(PyObject):
+
+    def __init__(self, attributes=None, bases=None, is_base_type=False):
+        if attributes is None:
+            attributes = {}
+        if bases is None:
+            bases = []
+        py_type = self
+        if not is_base_type:
+            py_type = PyType.get_type('Type')
+        super(PyType, self).__init__(py_type, attributes)
+        self.bases = bases
+
+    @staticmethod
+    def get_type(name):
+        if not hasattr(PyType, 'types'):
+            PyType.types = {}
+            PyType.types['Type'] = PyType(is_base_type=True)
+            PyType.types['Module'] = PyType()
+            PyType.types['Function'] = PyType()
+            PyType.types['Unknown'] = PyType()
+        return PyType.types[name]
+
+
+class _GlobalVisitor(object):
+
+    def __init__(self):
+        self.result = {}
+    
+    def visitClass(self, node):
+        self.result[node.name] = _ClassVisitor.make_class(node)
+
+    def visitFunction(self, node):
+        self.result[node.name] = PyObject(py_type=PyType.get_type('Function'))
+
+    def visitAssName(self, node):
+        self.result[node.name] = PyObject(PyType.get_type('Unknown'))
+
+
+class _ClassVisitor(object):
+
+    def __init__(self):
+        self.children = {}
+
+    def visitFunction(self, node):
+        self.children[node.name] = PyObject(PyType.get_type('Function'))
+        if node.name == '__init__':
+            new_visitor = _ClassInitVisitor()
+            compiler.walk(node, new_visitor)
+            self.children.update(new_visitor.vars)
+
+    def visitAssName(self, node):
+        self.children[node.name] = PyObject(PyType.get_type('Unknown'))
+
+    @staticmethod
+    def make_class(node):
+        new_visitor = _ClassVisitor()
+        for n in node.getChildNodes():
+            compiler.walk(n, new_visitor)
+        return PyType(new_visitor.children)
+
+
+class _ClassInitVisitor(object):
+
+    def __init__(self):
+        self.vars = {}
+    
+    def visitAssAttr(self, node):
+        if node.expr.name == 'self':
+            self.vars[node.attrname] = PyObject(PyType.get_type('Unknown'))
+

File ropetest/codeassisttest.py

 
 from rope.codeassist import CodeAssist, RopeSyntaxError, CompletionProposal, Template
 from rope.project import Project
-
-def _remove_recursively(file):
-    for root, dirs, files in os.walk(file, topdown=False):
-        for name in files:
-            os.remove(os.path.join(root, name))
-        for name in dirs:
-            os.rmdir(os.path.join(root, name))
-    os.rmdir(file)
+from ropetest import testutils
 
 class CodeAssistTest(unittest.TestCase):
 
         self.assist = self.project.get_code_assist()
         
     def tearDown(self):
-        _remove_recursively(self.project_root)
+        testutils.remove_recursively(self.project_root)
         super(CodeAssistTest, self).tearDown()
 
     def test_simple_assist(self):
                 self.fail('completion <%s> was proposed' % name)
 
     def tearDown(self):
-        _remove_recursively(self.project_root)
+        testutils.remove_recursively(self.project_root)
         super(self.__class__, self).tearDown()
 
     def test_simple_import(self):

File ropetest/coretest.py

         unittest.TestCase.setUp(self)
         Core.get_core().close_project()
         self.projectMaker = SampleProjectMaker()
+        self.projectMaker.make_project()
         self.fileName = self.projectMaker.get_sample_file_name()
         self.fileName2 = 'samplefile2.txt'
         file_ = open(self.fileName, 'w')

File ropetest/fileeditortest.py

         unittest.TestCase.setUp(self)
         self.text = MockEditor()
         self.projectMaker = SampleProjectMaker()
+        self.projectMaker.make_project()
         self.fileName = self.projectMaker.get_sample_file_name()
         self.project = Project(self.projectMaker.get_root())
         self.editor = FileEditor(self.project, self.project.get_resource(self.fileName), self.text)

File ropetest/indentertest.py

         self.indenter.correct_indentation(3)
         self.assertEquals('if True:\n    print "hello"\nelse:', self.editor.get_text())
 
+    def test_deindenting_when_encountering_elif(self):
+        self.editor.set_text('if True:\n    print "hello"\n    elif False:')
+        self.indenter.correct_indentation(3)
+        self.assertEquals('if True:\n    print "hello"\nelif False:', self.editor.get_text())
+
     def test_deindenting_when_encountering_except(self):
         self.editor.set_text('try:\n    print "hello"\n    except Exception:')
         self.indenter.correct_indentation(3)

File ropetest/projecttest.py

 import unittest
 import os
 
-from rope.project import Project, FileFinder, PythonFileRunner
+from rope.project import Project, FileFinder, PythonFileRunner, RootFolder
 from rope.exceptions import RopeException
+from ropetest import testutils
 
 class SampleProjectMaker(object):
     def __init__(self):
         self.projectRoot = 'SampleProject'
         self.sampleFile = 'sample.txt'
         self.sampleFolder = 'ASampleFolder'
+        self.sample_content = 'sample text\n'
+        
+    def make_project(self):
+        self.remove_all()
         self.sampleFilePath = os.path.join(self.projectRoot, self.sampleFile)
         os.mkdir(self.projectRoot)
         os.mkdir(os.path.join(self.projectRoot, self.sampleFolder))
         sample = open(self.sampleFilePath, 'w')
-        sample.write('sample text\n')
+        sample.write(self.sample_content)
         sample.close()
 
     def get_root(self):
         return 'sample text\n'
 
     def remove_all(self):
-        SampleProjectMaker.remove_recursively(self.projectRoot)
+        testutils.remove_recursively(self.projectRoot)
 
-    @staticmethod
-    def remove_recursively(file):
-        for root, dirs, files in os.walk(file, topdown=False):
-            for name in files:
-                os.remove(os.path.join(root, name))
-            for name in dirs:
-                os.rmdir(os.path.join(root, name))
-        os.rmdir(file)
 
 class ProjectTest(unittest.TestCase):
 
     def setUp(self):
         unittest.TestCase.setUp(self)
         self.projectMaker = SampleProjectMaker()
+        self.projectMaker.make_project()
         self.project = Project(self.projectMaker.get_root())
 
     def tearDown(self):
             project = Project(projectRoot)
             self.assertTrue(os.path.exists(projectRoot) and os.path.isdir(projectRoot))
         finally:
-            SampleProjectMaker.remove_recursively(projectRoot)
+            testutils.remove_recursively(projectRoot)
 
     def test_failure_when_project_root_exists_and_is_a_file(self):
         projectRoot = 'SampleProject2'
         self.assertEquals(1, len(found_modules))
         self.assertEquals(samplepkg, found_modules[0])
 
+    def test_project_root_is_root_folder(self):
+        self.assertTrue(isinstance(self.project.get_root_folder(), RootFolder))
+
 
 class FileFinderTest(unittest.TestCase):
     def setUp(self):
         unittest.TestCase.setUp(self)
         self.projectMaker = SampleProjectMaker()
+        self.projectMaker.make_project()
         self.project = Project(self.projectMaker.get_root())
         self.finder = FileFinder(self.project)
         self.project.get_resource(self.projectMaker.get_sample_file_name()).remove()
     def setUp(self):
         unittest.TestCase.setUp(self)
         self.projectMaker = SampleProjectMaker()
+        self.projectMaker.make_project()
         self.project = Project(self.projectMaker.get_root())
 
     def tearDown(self):
         self.assertEquals('run', self.get_output_file_content(file_path))
 
     # FIXME: this does not work on windows
-    def test_killing_runner(self):
+    def xxx_test_killing_runner(self):
         file_path = 'sample.py'
         self.make_sample_python_file(file_path,
                                      "def get_text():" +

File ropetest/pycoretest.py

+import unittest
+
+from ropetest import testutils
+from rope.pycore import PyCore, PyType
+from rope.project import Project
+
+class PyElementHierarchyTest(unittest.TestCase):
+
+    def setUp(self):
+        super(PyElementHierarchyTest, self).setUp()
+        self.project_root = 'sample_project'
+        testutils.remove_recursively(self.project_root)
+        self.project = Project(self.project_root)
+        self.pycore = PyCore(self.project)
+
+    def tearDown(self):
+        testutils.remove_recursively(self.project_root)
+        super(PyElementHierarchyTest, self).tearDown()
+
+    def test_simple_module(self):
+        self.project.create_module(self.project.get_root_folder(), 'mod')
+        result = self.pycore.get_module('mod')
+        self.assertEquals(PyType.get_type('Module'), result.type)
+        self.assertEquals(0, len(result.attributes))
+    
+    def test_package(self):
+        pkg = self.project.create_package(self.project.get_root_folder(), 'pkg')
+        mod = self.project.create_module(pkg, 'mod')
+        result = self.pycore.get_module('pkg')
+        self.assertEquals(PyType.get_type('Module'), result.type)
+        
+    def test_simple_class(self):
+        mod = self.project.create_module(self.project.get_root_folder(), 'mod')
+        mod.write('class SampleClass(object):\n    pass\n')
+        mod_element = self.pycore.get_module('mod')
+        result = mod_element.attributes['SampleClass']
+        self.assertEquals(PyType.get_type('Type'), result.type)
+
+    def test_simple_function(self):
+        mod = self.project.create_module(self.project.get_root_folder(), 'mod')
+        mod.write('def sample_function():\n    pass\n')
+        mod_element = self.pycore.get_module('mod')
+        result = mod_element.attributes['sample_function']
+        self.assertEquals(PyType.get_type('Function'), result.type)
+
+    def test_class_methods(self):
+        mod = self.project.create_module(self.project.get_root_folder(), 'mod')
+        mod.write('class SampleClass(object):\n    def sample_method(self):\n        pass\n')
+        mod_element = self.pycore.get_module('mod')
+        sample_class = mod_element.attributes['SampleClass']
+        self.assertEquals(1, len(sample_class.attributes))
+        method = sample_class.attributes['sample_method']
+                
+    def test_global_variables(self):
+        mod = self.project.create_module(self.project.get_root_folder(), 'mod')
+        mod.write('var = 10')
+        mod_element = self.pycore.get_module('mod')
+        result = mod_element.attributes['var']
+        
+    def test_class_variables(self):
+        mod = self.project.create_module(self.project.get_root_folder(), 'mod')
+        mod.write('class SampleClass(object):\n    var = 10\n')
+        mod_element = self.pycore.get_module('mod')
+        sample_class = mod_element.attributes['SampleClass']
+        var = sample_class.attributes['var']
+        
+    def test_class_attributes_set_in_init(self):
+        mod = self.project.create_module(self.project.get_root_folder(), 'mod')
+        mod.write('class SampleClass(object):\n    def __init__(self):\n        self.var = 20\n')
+        mod_element = self.pycore.get_module('mod')
+        sample_class = mod_element.attributes['SampleClass']
+        var = sample_class.attributes['var']
+        
+
+
+if __name__ == '__main__':
+    unittest.main()

File ropetest/testutils.py

+import os
+import os.path
+
+def remove_recursively(file):
+    if not os.path.exists(file):
+        return
+    for root, dirs, files in os.walk(file, topdown=False):
+        for name in files:
+            os.remove(os.path.join(root, name))
+        for name in dirs:
+            os.rmdir(os.path.join(root, name))
+    os.rmdir(file)
+
 import ropetest.codeassisttest
 import ropetest.statusbartest
 import ropetest.codeanalyzetest
+import ropetest.pycoretest
 
 
 if __name__ == '__main__':
     result.addTests(ropetest.codeassisttest.suite())
     result.addTests(unittest.makeSuite(ropetest.statusbartest.StatusBarTest))
     result.addTests(unittest.makeSuite(ropetest.codeanalyzetest.StatementRangeFinderTest))
+    result.addTests(unittest.makeSuite(ropetest.pycoretest.PyElementHierarchyTest))
     runner = unittest.TextTestRunner()
     runner.run(result)