Commits

Ali Gholami Rudi  committed 1bef792

Fixed problems with organize imports when there exists package docs

  • Participants
  • Parent commits bf8c09d

Comments (0)

Files changed (13)

File docs/dev/done.txt

 ===========
 
 
+- Supporting generator functions : March 9, 2007
+
+
 - Enhancing show pydoc to include docs from superclasses : March 8, 2007
 
 

File docs/dev/issues.txt

 Returned Object SOI
 -------------------
 
-Since we're passed the object parameters hold, we can perform a
+Since we're passed the objects parameters hold, we can perform a
 better returned object SOI.  We can do that by giving parameter
 objects passed and infer the object of local names once more.
 
 * Not ignoring the first argument for builtin types
 
 
-Supporting Generator Functions
-==============================
-
-The good thing about functions is that they can have either returns
-or yields but they cannot have both.
-
-For supporting generators in SOI we can hold yielded asts and we can
-do the same as what we did for normal function returns.
-
-For DOI I don't know how to make that work.  Maybe we can pass
-iterators back to rope.
-
-
 Better Concluded Data
 =====================
 

File docs/dev/stories.txt

 
 
 * Handling change method signature for constructors
-
-
-* Supporting generator functions

File docs/dev/workingon.txt

-Supporting Generator Functions
-==============================
+Change Method Signature For Constructors
+========================================
 
-- Update `rope.base.oi` docs
-- Not proposing invalid textuals in `_CallInformationOrganizer`
-- Removing duplication between `AssignedName`, `EvaluatedName`
-  and `PyFunction` for inferring objects
-- `Iterator_to_textual` and the reverse
-- Adding `Generator` builtin
-- `iter` builtin function
-- Refactoring builtin module a bit
+- Transforming more `PyObject`\s to textuals
+- Organize import problems in builtins module
 
-* Refactoring callinfo transformations
-* Transforming all `PyObject`\s to textuals; trying their super
-  classes till `PyObject`, giving up then.
-* Handling generators in DOI?
 * Returning a `Generator` for functions with unknown return type
-* Passing `iterators` in DOI?
 
-* Chaning `callinfo` to match not exactly the same but similar args
+* Binding keys in show pydoc
+* Changing `callinfo` to match not exactly the same but similar args
 * Is throwing `IsBeingInferredException` a good thing?  Can't we
   return `get_unknown()` instead?
 * Evaluate function parameter defaults in staticoi?

File docs/user/overview.txt

 ========
 
 The purpose of this file is to give an overview of some of rope's
-features.  It is incomplete.
+features.  It is incomplete.  Because rope is enhancing very fast
+some of the features shown here are old and do not show what rope
+can do in extremes.  So if you really want to feel the power of
+rope try its features and see its unit tests.
 
 
 Keybinding
 exit                        C-x C-c        C-W
 run active editor           C-c x p        M-X p
 run unit-tests              C-c x t        M-X t
+run SOI                     C-c x s
 --------------------------  -------------  -------------
 forward character           C-f
 backward character          C-b
 Show PyDoc
 ----------
 
+Try it!
+
 
 Goto Definition
 ---------------
 
+Try it!
+
 
 Refactorings
 ============
 
+This section shows some random refactorings you can do using rope.
+
+
 Renaming attributes
 -------------------
 
 length more than 27 characters to be long.
 
 
-Basic Type Inference
-====================
+Basic Object Inference
+======================
 
 ::
 
       return AClass()
 
   a_var = a_func()
-  a_var.${codeassist}
+  #a_var.${codeassist}
 
   another_var = a_var
-  another_var.${codeassist}
-  another_var.call_a_func().${codeassist}
+  #another_var.${codeassist}
+  #another_var.call_a_func().${codeassist}
 
 
 Basic support for builtin types::
 
   a_list = [AClass(), AClass()]
   for x in a_list:
-      x.${codeassist}
-  a_list.pop().${codeassist}
+      pass
+      #x.${codeassist}
+  #a_list.pop().${codeassist}
 
   a_dict = ['text': AClass()]
   for key, value in a_dict.items():
-      key.${codeassist}
-      value.${codeassist}
+      pass
+      #key.${codeassist}
+      #value.${codeassist}
 
 
-Dynamic Type Inference
-======================
+Dynamic Object Inference
+========================
 
 Dynamic type inference gets its needed information from running
 modules (``M-X p``) or unit tests (``M-X t``).  You open the module
 ``mod1.py``::
 
   def f1(param):
-      param.${codeassist}
-      f2(param).${codeassist}
+      pass
+      #param.${codeassist}
+      #f2(param).${codeassist}
 
   def f2(param):
-      param.${codeassist}
+      #param.${codeassist}
       return param
 
 Using code assist in specified places does not give any information
       return result
 
   returned = f()
-  returned[0].${codeassist}
+  #returned[0].${codeassist}
 
 Test the the proposed completions after running this module.
 

File rope/base/builtins.py

 functions.
 
 """
+import __builtin__
+import inspect
 
-from rope.base import pynames
-from rope.base import pyobjects
-from rope.base import evaluate
+from rope.base import pynames, pyobjects, evaluate
 
 
 def _create_builtin_type_getter(cls):
     'object': BuiltinName(BuiltinObject()),
     'type': BuiltinName(BuiltinType()),
     'iter': BuiltinName(BuiltinFunction(function=_iter_function, builtin=iter))}
+
+
+for name in dir(__builtin__):
+    if name not in builtins:
+        obj = getattr(__builtin__, name)
+        if inspect.isclass(obj):
+            builtins[name] = BuiltinName(BuiltinClass(obj, {}))
+        else:
+            builtins[name] = BuiltinName(BuiltinFunction(builtin=obj))

File rope/base/oi/callinfo.py

     def transform(self, textual):
         """Transform an object from textual form to `PyObject`"""
         type = textual[0]
-        method = getattr(self, type + '_to_pyobject')
-        return method(textual)
+        try:
+            method = getattr(self, type + '_to_pyobject')
+            return method(textual)
+        except AttributeError:
+            return None
 
     def module_to_pyobject(self, textual):
         path = textual[1]
         if name == 'generator':
             holding = self.transform(textual[2])
             return rope.base.builtins.get_generator(holding)
+        if name == 'file':
+            return rope.base.builtins.get_file()
+        if name == 'function':
+            if textual[2] in rope.base.builtins.builtins:
+                return rope.base.builtins.builtins[textual[2]].get_object()
         return None
 
     def unknown_to_pyobject(self, textual):
         if pyobject is None:
             return ('none',)
         object_type = type(pyobject)
-        method = getattr(self, object_type.__name__ + '_to_textual')
-        return method(pyobject)
+        try:
+            method = getattr(self, object_type.__name__ + '_to_textual')
+            return method(pyobject)
+        except AttributeError:
+            return ('unknown',)
 
     def PyObject_to_textual(self, pyobject):
         if type(pyobject.get_type()) != pyobjects.PyObject:
     def Str_to_textual(self, pyobject):
         return ('builtin', 'str')
 
+    def File_to_textual(self, pyobject):
+        return ('builtin', 'file')
+
+    def BuiltinFunction_to_textual(self, pyobject):
+        return ('builtin', 'function', pyobject.get_name())
+
     def _get_pymodule_path(self, pymodule):
         resource = pymodule.get_resource()
         resource_path = resource.path

File rope/refactor/__init__.py

    by it.
 4. perform the refactoring.
 
-
 """
 import rope.refactor.importutils
 from rope.base.change import ChangeSet, ChangeContents, MoveResource, CreateFolder

File rope/refactor/importutils/module_imports.py

         after_removing = self._remove_imports(imports)
         imports = [stmt for stmt in imports if not stmt.import_info.is_empty()]
 
+        first_non_blank = self._first_non_blank_line(after_removing, 0)
+        first_import = self._first_import_line() - 1
         result = []
-        last_index = self._first_non_blank_line(after_removing, 0)
+        # Writing module docs
+        result.extend(after_removing[first_non_blank:first_import])
+        # Writing imports
         sorted_imports = sorted(imports, self._compare_import_locations)
         for stmt in sorted_imports:
             start = self._get_import_location(stmt)
-            result.extend(after_removing[last_index:start - 1])
-            last_index = self._first_non_blank_line(after_removing, start - 1)
             if stmt != sorted_imports[0]:
                 result.append('\n' * stmt.blank_lines)
             result.append(stmt.get_import_statement() + '\n')
-        if sorted_imports and last_index < len(after_removing):
+        if sorted_imports and first_non_blank < len(after_removing):
             result.append('\n' * self.separating_lines)
-        result.extend(after_removing[last_index:])
+
+        # Writing the body
+        first_after_imports = self._first_non_blank_line(after_removing, first_import)
+        result.extend(after_removing[first_after_imports:])
         return ''.join(result)
 
     def _get_import_location(self, stmt):
         visitor = actions.SortingVisitor(self.pycore, self._current_folder())
         for import_statement in all_import_statements:
             import_statement.accept(visitor)
-        last_index = 1
-        if all_import_statements:
-            last_index = all_import_statements[0].start_line
         in_projects = sorted(visitor.in_project, self._compare_imports)
         third_party = sorted(visitor.third_party, self._compare_imports)
         standards = sorted(visitor.standard, self._compare_imports)
         blank_lines = 0
+        last_index = self._first_import_line()
         last_index = self._move_imports(standards, last_index, 0)
         last_index = self._move_imports(third_party, last_index, 1)
         last_index = self._move_imports(in_projects, last_index, 1)
         self.separating_lines = 2
 
+    def _first_import_line(self):
+        last_index = 1
+        # Getting the line of the first import fails when the first
+        # import is not in the first non doc line of module
+        nodes = self.pymodule.get_ast().node
+        if nodes.getChildNodes():
+            last_index = nodes.getChildNodes()[0].lineno
+        return last_index
+
     def _compare_imports(self, stmt1, stmt2):
         str1 = stmt1.get_import_statement()
         str2 = stmt2.get_import_statement()

File rope/refactor/move.py

+"""A module containing classes for move refactoring
+
+`create_move()` is a factory for creating move refactoring objects
+based on inputs.
+
+"""
 from rope.base import pyobjects, codeanalyze, exceptions, pynames
 from rope.base.change import ChangeSet, ChangeContents, MoveResource
 from rope.refactor import (importutils, rename, occurrences,

File rope/ui/dot_rope.py

     core.rebind_action('comment_region', None)
     core.rebind_action('run_module', 'M-X p')
     core.rebind_action('run_unit_tests', 'M-X t')
+    core.rebind_action('run_soi', None)
 
     core.rebind_action('rename', 'M-R')
     core.rebind_action('move', 'M-V')

File ropetest/objectinfertest.py

     def test_textual_transformations(self):
         mod = self.pycore.create_module(self.project.root, 'mod')
         code = 'class C(object):\n    pass\ndef f():\n    pass\na_var = C()\n' \
-               'a_list = [C()]\na_str = "hey"\n'
+               'a_list = [C()]\na_str = "hey"\na_file = open("file.txt")\n'
         mod.write(code)
         to_pyobject = callinfo._TextualToPyObject(self.project)
         to_textual = callinfo._PyObjectToTextual(self.project)
         def complex_to_textual(pyobject):
             return to_textual.transform(
                 to_pyobject.transform(to_textual.transform(pyobject)))
-        for name in ('C', 'f', 'a_var', 'a_list', 'a_str'):
+        for name in ('C', 'f', 'a_var', 'a_list', 'a_str', 'a_file'):
             var = pymod.get_attribute(name).get_object()
             self.assertEquals(to_textual.transform(var), complex_to_textual(var))
         self.assertEquals(to_textual.transform(pymod), complex_to_textual(pymod))
+        enumerate_func = rope.base.builtins.builtins['enumerate'].get_object()
+        self.assertEquals(to_textual.transform(enumerate_func),
+                          complex_to_textual(enumerate_func))
 
     def test_arguments_with_keywords(self):
         mod = self.pycore.create_module(self.project.root, 'mod')

File ropetest/refactor/importutilstest.py

     def test_import_get_names_with_alias(self):
         self.mod.write('import pkg1.mod1\n')
         pymod = self.pycore.get_module('mod')
-        module_with_imports = self.import_tools.get_module_with_imports(pymod)
+        module_with_imports = self.import_tools.get_module_imports(pymod)
         imports = module_with_imports.get_import_statements()
         self.assertEquals(['pkg1'], imports[0].import_info.get_imported_names())
 
-    def test_import_get_names_with_alias(self):
+    def test_import_get_names_with_alias2(self):
         self.mod1.write('def a_func():\n    pass\n')
         self.mod.write('from pkg1.mod1 import *\n')
         pymod = self.pycore.get_module('mod')
         self.mod1.write('def a_func():\n    pass\n')
         self.mod.write('from pkg1.mod1 import *\na_func()\n')
         pymod = self.pycore.get_module('mod')
-        changed_module = self.import_tools.transform_froms_to_normal_imports(pymod)
+        changed_module = self.import_tools.froms_to_imports(pymod)
         self.assertEquals('import pkg1.mod1\npkg1.mod1.a_func()\n', changed_module)
 
-    def test_transforming_froms_to_normal_from_stars(self):
+    def test_transforming_froms_to_normal_from_stars2(self):
         self.mod1.write('a_var = 10')
         self.mod.write('import pkg1.mod1\nfrom pkg1.mod1 import a_var\n' \
                        'def a_func():\n    print pkg1.mod1, a_var\n')
         self.assertEquals('a_var = 1\nprint a_var\n',
                           self.import_tools.organize_imports(pymod))
 
-    def test_removing_self_imports_for_froms3(self):
+    def test_removing_self_imports_for_froms4(self):
         self.mod.write('from mod import a_var as myvar\na_var = 1\nprint myvar\n')
         pymod = self.pycore.resource_to_pyobject(self.mod)
         self.assertEquals('a_var = 1\nprint a_var\n',
             self.import_tools.handle_long_imports(pymod, maxdots=3,
                                                   maxlength=20))
 
-    def test_handling_long_imports_for_many_dots(self):
+    def test_handling_long_imports_for_many_dots2(self):
         self.mod.write('import p1.p2.p3.m1\n\n\nm = p1.p2.p3.m1\n')
         pymod = self.pycore.resource_to_pyobject(self.mod)
         self.assertEquals(
         self.assertEquals('import pkg1\n\n\nprint pkg1\n',
                           module_with_imports.get_changed_source())
 
+    def test_sorting_imports_moving_to_top(self):
+        self.mod.write('import mod\ndef f():\n    print(mod, pkg1, pkg2)\nimport pkg1\nimport pkg2\n')
+        pymod = self.pycore.get_module('mod')
+        self.assertEquals('import mod\nimport pkg1\nimport pkg2\n\n\n'
+                          'def f():\n    print(mod, pkg1, pkg2)\n',
+                          self.import_tools.sort_imports(pymod))
+
+    def test_sorting_imports_moving_to_top2(self):
+        self.mod.write('def f():\n    print(mod)\nimport mod\n')
+        pymod = self.pycore.get_module('mod')
+        self.assertEquals('import mod\n\n\ndef f():\n    print(mod)\n',
+                          self.import_tools.sort_imports(pymod))
+
+    def test_sorting_imports_moving_to_top_and_module_docs(self):
+        self.mod.write('"""\ndocs\n"""\ndef f():\n    print(mod)\nimport mod\n')
+        pymod = self.pycore.get_module('mod')
+        self.assertEquals('"""\ndocs\n"""\nimport mod\n\n\ndef f():\n    print(mod)\n',
+                          self.import_tools.sort_imports(pymod))
+
 
 if __name__ == '__main__':
     unittest.main()