Commits

Ali Gholami Rudi  committed 6c55b3c

Moving rope.refactor.change to rope.base
Handling global keyword

  • Participants
  • Parent commits 979e5e3

Comments (0)

Files changed (20)

File docs/dev/done.txt

 ===========
 
 
+- Handling ``global`` keywords : January 22, 2007
+
+
 - Undoing everything; Project history : January 21, 2007
 
 

File docs/dev/stories.txt

 
 
 * Commanding buffer
-
-
-* ``global`` keyword issues for pycore

File docs/dev/workingon.txt

-Project History
-===============
+Remaining Small Stories
+=======================
 
-- Undo/redo list underflow
-- Limiting the number of changes in the undo list
-- Not proposing class variable in methods as local variables
-- Separating undos; Editing history and file history
-- Fixed an old defect for invalidating resources in `PyCore`
-- Showing the description of a change when undoing/redoing
+- Moving `rope.refactor.change` to `rope.base`
+- Handling ``global`` keyword
 
 * Adding imports eats the blank lines after it
-* Moving `rope.refactor.change` to `rope.base`
 
 
 Remaining Small Stories

File rope/base/change.py

+import difflib
+import os
+
+from rope.base.exceptions import RopeError
+
+
+class Change(object):
+
+    def do(self, resource_operations):
+        pass
+
+    def undo(self, resource_operations):
+        pass
+
+    def get_description(self):
+        return str(self)
+
+
+class ChangeSet(Change):
+
+    def __init__(self, description):
+        self.changes = []
+        self.description = description
+
+    def do(self):
+        try:
+            done = []
+            for change in self.changes:
+                change.do()
+                done.append(change)
+        except Exception:
+            for change in done:
+                change.undo()
+            raise
+
+    def undo(self):
+        try:
+            done = []
+            for change in reversed(self.changes):
+                change.undo()
+                done.append(change)
+        except Exception:
+            for change in done:
+                change.do()
+            raise
+
+    def add_change(self, change):
+        self.changes.append(change)
+
+    def get_description(self):
+        return self.description
+
+
+class ChangeContents(Change):
+
+    def __init__(self, resource, new_content):
+        self.resource = resource
+        self.new_content = new_content
+        self.old_content = None
+        self.operations = self.resource.project.operations
+
+    def do(self):
+        self.old_content = self.resource.read()
+        self.operations.write_file(self.resource, self.new_content)
+
+    def undo(self):
+        self.operations.write_file(self.resource, self.old_content)
+
+    def __str__(self):
+        return 'Change <%s>' % self.resource.path
+
+    def get_description(self):
+        differ = difflib.Differ()
+        result = list(differ.compare(self.resource.read().splitlines(True),
+                                     self.new_content.splitlines(True)))
+        return ''.join(result)
+
+
+class MoveResource(Change):
+
+    def __init__(self, resource, new_location):
+        self.project = resource.project
+        self.new_location = _get_destination_for_move(resource, new_location)
+        self.old_location = resource.path
+        self.operations = resource.project.operations
+
+    def do(self):
+        resource = self.project.get_resource(self.old_location)
+        self.operations.move(resource, self.new_location)
+
+    def undo(self):
+        resource = self.project.get_resource(self.new_location)
+        self.operations.move(resource, self.old_location)
+
+    def __str__(self):
+        return 'Move <%s>' % self.old_location
+
+    def get_description(self):
+        return 'Move <%s> to <%s>' % (self.old_location, self.new_location)
+
+
+class _CreateResource(Change):
+
+    def __init__(self, parent, name):
+        self.parent = parent
+        self.name = name
+        self.new_resource = None
+        self.operations = self.parent.project.operations
+
+    def undo(self):
+        self.operations.remove(self.new_resource)
+
+    def __str__(self):
+        return 'Create <%s>' % (self.parent.path + '/' + self.name)
+
+
+class CreateFolder(_CreateResource):
+
+    def do(self):
+        self.new_resource = self.operations.create_folder(self.parent,
+                                                          self.name)
+
+
+class CreateFile(_CreateResource):
+
+    def do(self):
+        self.new_resource = self.operations.create_file(self.parent,
+                                                        self.name)
+
+
+class RemoveResource(Change):
+
+    def __init__(self, resource):
+        self.resource = resource
+        self.operations = resource.project.operations
+
+    def do(self):
+        self.operations.remove(self.resource)
+
+    # TODO: Undoing remove operations
+    def undo(self):
+        pass
+
+    def __str__(self):
+        return 'Remove <%s>' % (self.resource.path)
+
+
+class _ResourceOperations(object):
+
+    def __init__(self, project, fscommands):
+        self.project = project
+        self.fscommands = fscommands
+
+    def write_file(self, resource, contents):
+        self.project.file_access.write(resource.real_path, contents)
+        for observer in list(self.project.observers):
+            observer.resource_changed(resource)
+
+    def move(self, resource, new_location):
+        destination = _get_destination_for_move(resource, new_location)
+        self.fscommands.move(resource.real_path,
+                             self.project._get_resource_path(destination))
+        new_resource = self.project.get_resource(destination)
+        for observer in list(self.project.observers):
+            observer.resource_removed(resource, new_resource)
+
+    def create_file(self, folder, file_name):
+        if folder.path:
+            file_path = folder.path + '/' + file_name
+        else:
+            file_path = file_name
+        self._create_file(file_path)
+        child = folder.get_child(file_name)
+        for observer in list(self.project.observers):
+            observer.resource_changed(child)
+        return child
+
+    def create_folder(self, folder, folder_name):
+        if folder.path:
+            folder_path = folder.path + '/' + folder_name
+        else:
+            folder_path = folder_name
+        self._create_folder(folder_path)
+        child = folder.get_child(folder_name)
+        for observer in list(self.project.observers):
+            observer.resource_changed(child)
+        return child
+
+    def remove(self, resource):
+        self.fscommands.remove(resource.real_path)
+        for observer in list(self.project.observers):
+            observer.resource_removed(resource)
+
+    def _create_file(self, file_name):
+        file_path = self.project._get_resource_path(file_name)
+        if os.path.exists(file_path):
+            if os.path.isfile(file_path):
+                raise RopeError('File already exists')
+            else:
+                raise RopeError('A folder with the same name'
+                                    ' as this file already exists')
+        try:
+            self.fscommands.create_file(file_path)
+        except IOError, e:
+            raise RopeError(e)
+
+    def _create_folder(self, folder_name):
+        folder_path = self.project._get_resource_path(folder_name)
+        if os.path.exists(folder_path):
+            if not os.path.isdir(folder_path):
+                raise RopeError('A file with the same name as'
+                                    ' this folder already exists')
+            else:
+                raise RopeError('Folder already exists')
+        self.fscommands.create_folder(folder_path)
+
+
+def _get_destination_for_move(resource, destination):
+    dest_path = resource.project._get_resource_path(destination)
+    if os.path.isdir(dest_path):
+        if destination != '':
+            return destination + '/' + resource.name
+        else:
+            return resource.name
+    return destination
+

File rope/base/project.py

 import os
 
+import rope.base.change
 import rope.base.fscommands
+import rope.base.history
 import rope.base.pycore
-import rope.base.history
 from rope.base.exceptions import RopeError
-from rope.refactor import change
 
 
 class _Project(object):
         self.observers = set()
         self.file_access = rope.base.fscommands.FileAccess()
         self._history = rope.base.history.History(maxundos=100)
-        self.operations = change._ResourceOperations(self, fscommands)
+        self.operations = rope.base.change._ResourceOperations(self, fscommands)
 
     def get_resource(self, resource_name):
         """Get a resource in a project.
 
     def move(self, new_location):
         """Move resource to `new_location`"""
-        self._perform_change(change.MoveResource(self, new_location),
+        self._perform_change(rope.base.change.MoveResource(self, new_location),
                              'Moving <%s> to <%s>' % (self.path, new_location))
 
     def remove(self):
         """Remove resource from the project"""
-        self._perform_change(change.RemoveResource(self),
+        self._perform_change(rope.base.change.RemoveResource(self),
                              'Removing <%s>' % self.path)
 
     def is_folder(self):
         return hash(self.path)
 
     def _perform_change(self, change_, description):
-        changes = change.ChangeSet(description)
+        changes = rope.base.change.ChangeSet(description)
         changes.add_change(change_)
         self.project.do(changes)
 
         return self.project.file_access.read(self.real_path)
 
     def write(self, contents):
-        self._perform_change(change.ChangeContents(self, contents),
+        self._perform_change(rope.base.change.ChangeContents(self, contents),
                              'Writing file <%s>' % self.path)
 
     def is_folder(self):
 
     def create_file(self, file_name):
         self._perform_change(
-            change.CreateFile(self, file_name),
+            rope.base.change.CreateFile(self, file_name),
             'Creating file <%s>' % (self.path + '/' + file_name))
         return self.get_child(file_name)
 
     def create_folder(self, folder_name):
         self._perform_change(
-            change.CreateFolder(self, folder_name),
+            rope.base.change.CreateFolder(self, folder_name),
             'Creating golder <%s>' % (self.path + '/' + folder_name))
         return self.get_child(folder_name)
 

File rope/base/pyobjects.py

             module_name, alias = import_pair
             first_package = module_name.split('.')[0]
             if alias is not None:
-                self.names[alias] = ImportedModule(self.get_module(), module_name)
+                self.names[alias] = ImportedModule(self.get_module(),
+                                                   module_name)
             else:
-                self.names[first_package] = ImportedModule(self.get_module(), first_package)
+                self.names[first_package] = ImportedModule(self.get_module(),
+                                                           first_package)
 
     def visitFrom(self, node):
         level = 0
         if hasattr(node, 'level'):
             level = node.level
-        imported_module = ImportedModule(self.get_module(), node.modname, level)
+        imported_module = ImportedModule(self.get_module(),
+                                         node.modname, level)
         if node.names[0][0] == '*':
             self.owner_object.star_imports.append(StarImport(imported_module))
         else:
                     imported = alias
                 self.names[imported] = ImportedName(imported_module, name)
 
+    def visitGlobal(self, node):
+        module = self.get_module()
+        for name in node.names:
+            if module is not None:
+                try:
+                    pyname = module.get_attribute(name)
+                except AttributeNotFoundError:
+                    pyname = pynames.AssignedName(node.lineno)
+            self.names[name] = pyname
+
 
 class _GlobalVisitor(_ScopeVisitor):
 

File rope/refactor/__init__.py

 
 """
 import rope.refactor.importutils
-from rope.refactor.change import ChangeSet, ChangeContents, MoveResource, CreateFolder
+from rope.base.change import ChangeSet, ChangeContents, MoveResource, CreateFolder
 from rope.refactor.importutils import module_imports
 
 

File rope/refactor/change.py

-import difflib
-import os
-
-from rope.base.exceptions import RopeError
-
-
-class Change(object):
-
-    def do(self, resource_operations):
-        pass
-
-    def undo(self, resource_operations):
-        pass
-
-    def get_description(self):
-        return str(self)
-
-
-class ChangeSet(Change):
-
-    def __init__(self, description):
-        self.changes = []
-        self.description = description
-
-    def do(self):
-        try:
-            done = []
-            for change in self.changes:
-                change.do()
-                done.append(change)
-        except Exception:
-            for change in done:
-                change.undo()
-            raise
-
-    def undo(self):
-        try:
-            done = []
-            for change in reversed(self.changes):
-                change.undo()
-                done.append(change)
-        except Exception:
-            for change in done:
-                change.do()
-            raise
-
-    def add_change(self, change):
-        self.changes.append(change)
-
-    def get_description(self):
-        return self.description
-
-
-class ChangeContents(Change):
-
-    def __init__(self, resource, new_content):
-        self.resource = resource
-        self.new_content = new_content
-        self.old_content = None
-        self.operations = self.resource.project.operations
-
-    def do(self):
-        self.old_content = self.resource.read()
-        self.operations.write_file(self.resource, self.new_content)
-
-    def undo(self):
-        self.operations.write_file(self.resource, self.old_content)
-
-    def __str__(self):
-        return 'Change <%s>' % self.resource.path
-
-    def get_description(self):
-        differ = difflib.Differ()
-        result = list(differ.compare(self.resource.read().splitlines(True),
-                                     self.new_content.splitlines(True)))
-        return ''.join(result)
-
-
-class MoveResource(Change):
-
-    def __init__(self, resource, new_location):
-        self.project = resource.project
-        self.new_location = _get_destination_for_move(resource, new_location)
-        self.old_location = resource.path
-        self.operations = resource.project.operations
-
-    def do(self):
-        resource = self.project.get_resource(self.old_location)
-        self.operations.move(resource, self.new_location)
-
-    def undo(self):
-        resource = self.project.get_resource(self.new_location)
-        self.operations.move(resource, self.old_location)
-
-    def __str__(self):
-        return 'Move <%s>' % self.old_location
-
-    def get_description(self):
-        return 'Move <%s> to <%s>' % (self.old_location, self.new_location)
-
-
-class _CreateResource(Change):
-
-    def __init__(self, parent, name):
-        self.parent = parent
-        self.name = name
-        self.new_resource = None
-        self.operations = self.parent.project.operations
-
-    def undo(self):
-        self.operations.remove(self.new_resource)
-
-    def __str__(self):
-        return 'Create <%s>' % (self.parent.path + '/' + self.name)
-
-
-class CreateFolder(_CreateResource):
-
-    def do(self):
-        self.new_resource = self.operations.create_folder(self.parent,
-                                                          self.name)
-
-
-class CreateFile(_CreateResource):
-
-    def do(self):
-        self.new_resource = self.operations.create_file(self.parent,
-                                                        self.name)
-
-
-class RemoveResource(Change):
-
-    def __init__(self, resource):
-        self.resource = resource
-        self.operations = resource.project.operations
-
-    def do(self):
-        self.operations.remove(self.resource)
-
-    # TODO: Undoing remove operations
-    def undo(self):
-        pass
-
-    def __str__(self):
-        return 'Remove <%s>' % (self.resource.path)
-
-
-class _ResourceOperations(object):
-
-    def __init__(self, project, fscommands):
-        self.project = project
-        self.fscommands = fscommands
-
-    def write_file(self, resource, contents):
-        self.project.file_access.write(resource.real_path, contents)
-        for observer in list(self.project.observers):
-            observer.resource_changed(resource)
-
-    def move(self, resource, new_location):
-        destination = _get_destination_for_move(resource, new_location)
-        self.fscommands.move(resource.real_path,
-                             self.project._get_resource_path(destination))
-        new_resource = self.project.get_resource(destination)
-        for observer in list(self.project.observers):
-            observer.resource_removed(resource, new_resource)
-
-    def create_file(self, folder, file_name):
-        if folder.path:
-            file_path = folder.path + '/' + file_name
-        else:
-            file_path = file_name
-        self._create_file(file_path)
-        child = folder.get_child(file_name)
-        for observer in list(self.project.observers):
-            observer.resource_changed(child)
-        return child
-
-    def create_folder(self, folder, folder_name):
-        if folder.path:
-            folder_path = folder.path + '/' + folder_name
-        else:
-            folder_path = folder_name
-        self._create_folder(folder_path)
-        child = folder.get_child(folder_name)
-        for observer in list(self.project.observers):
-            observer.resource_changed(child)
-        return child
-
-    def remove(self, resource):
-        self.fscommands.remove(resource.real_path)
-        for observer in list(self.project.observers):
-            observer.resource_removed(resource)
-
-    def _create_file(self, file_name):
-        file_path = self.project._get_resource_path(file_name)
-        if os.path.exists(file_path):
-            if os.path.isfile(file_path):
-                raise RopeError('File already exists')
-            else:
-                raise RopeError('A folder with the same name'
-                                    ' as this file already exists')
-        try:
-            self.fscommands.create_file(file_path)
-        except IOError, e:
-            raise RopeError(e)
-
-    def _create_folder(self, folder_name):
-        folder_path = self.project._get_resource_path(folder_name)
-        if os.path.exists(folder_path):
-            if not os.path.isdir(folder_path):
-                raise RopeError('A file with the same name as'
-                                    ' this folder already exists')
-            else:
-                raise RopeError('Folder already exists')
-        self.fscommands.create_folder(folder_path)
-
-
-def _get_destination_for_move(resource, destination):
-    dest_path = resource.project._get_resource_path(destination)
-    if os.path.isdir(dest_path):
-        if destination != '':
-            return destination + '/' + resource.name
-        else:
-            return resource.name
-    return destination
-

File rope/refactor/change_signature.py

 import rope.base.pyobjects
 from rope.base import codeanalyze
 from rope.refactor import sourceutils, functionutils
-from rope.refactor.change import ChangeContents, ChangeSet
+from rope.base.change import ChangeContents, ChangeSet
 
 
 class ChangeSignature(object):

File rope/refactor/encapsulate_field.py

 from rope.refactor import occurrences
 
 from rope.refactor import sourceutils
-from rope.refactor.change import ChangeSet, ChangeContents
+from rope.base.change import ChangeSet, ChangeContents
 
 
 class EncapsulateFieldRefactoring(object):

File rope/refactor/extract.py

 from rope.base import codeanalyze
 from rope.base.exceptions import RefactoringError
 from rope.refactor import sourceutils
-from rope.refactor.change import ChangeSet, ChangeContents
+from rope.base.change import ChangeSet, ChangeContents
 
 
 class _ExtractRefactoring(object):

File rope/refactor/inline.py

 from rope.refactor import occurrences
 from rope.refactor import rename
 from rope.refactor import sourceutils
-from rope.refactor.change import ChangeSet, ChangeContents
+from rope.base.change import ChangeSet, ChangeContents
 
 
 class InlineRefactoring(object):

File rope/refactor/introduce_factory.py

 from rope.refactor import occurrences
 from rope.refactor import sourceutils
 
-from rope.refactor.change import (ChangeSet, ChangeContents)
+from rope.base.change import (ChangeSet, ChangeContents)
 
 
 class IntroduceFactoryRefactoring(object):

File rope/refactor/introduce_parameter.py

-from rope.refactor import functionutils
-from rope.base import codeanalyze
-from rope.refactor import sourceutils
-from rope.refactor import occurrences
-from rope.refactor import change
-from rope.base import exceptions
+import rope.base.change
+from rope.base import codeanalyze, exceptions
+from rope.refactor import functionutils, sourceutils, occurrences
 
 
 class IntroduceParameter(object):
         change_collector.add_change(start, header_end, definition_info.to_string())
         self._change_function_occurances(change_collector, header_end,
                                          end, new_parameter)
-        changes = change.ChangeSet('Introduce parameter <%s>' % new_parameter)
-        changes.add_change(change.ChangeContents(self.resource,
+        changes = rope.base.change.ChangeSet('Introduce parameter <%s>' % new_parameter)
+        changes.add_change(rope.base.change.ChangeContents(self.resource,
                                                  change_collector.get_changed()))
         return changes
 

File rope/refactor/move.py

 import rope.base.codeanalyze
 import rope.base.exceptions
 import rope.base.pyobjects
-from rope.refactor import importutils
-from rope.refactor import rename
-from rope.refactor import occurrences
-from rope.refactor.change import (ChangeSet, ChangeContents,
-                                  MoveResource, CreateFolder)
+from rope.base.change import ChangeSet, ChangeContents, MoveResource
+from rope.refactor import importutils, rename, occurrences
 
 
 class MoveRefactoring(object):

File rope/refactor/rename.py

 import rope.base.pynames
 import rope.base.pyobjects
 from rope.refactor import occurrences, sourceutils
-from rope.refactor.change import ChangeSet, ChangeContents, MoveResource
+from rope.base.change import ChangeSet, ChangeContents, MoveResource
 
 
 class RenameRefactoring(object):
             if not resource.is_folder() and resource.name == '__init__.py':
                 resource = resource.parent
             dummy_pymodule = self.pycore.get_string_module('')
-            self.old_pyname = rope.base.pynames.ImportedModule(dummy_pymodule, resource=resource)
+            self.old_pyname = rope.base.pynames.ImportedModule(
+                dummy_pymodule, resource=resource)
             if resource.is_folder():
                 self.old_name = resource.name
             else:
         old_pynames = self._get_old_pynames(in_file)
         if not old_pynames:
             return None
-        # HACK: Do a local rename for names defined in function scopes.
-        # XXX: This might cause problems for global keyword usages.
         if not in_file and len(old_pynames) == 1 and \
            self._is_renaming_a_function_local_name():
             in_file = True
         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))
+                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))
+            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)
+        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))
+            methods.update(self._get_all_methods_in_subclasses(
+                           superclass, attr_name))
         return methods
 
     def _rename_module(self, pyobject, new_name):

File rope/ui/codeassist.py

         editor.get_text(), editor.get_current_offset(), context.resource)
     toplevel = Tkinter.Toplevel()
     toplevel.title('Code Assist Proposals')
-    enhanced_list = EnhancedList(toplevel, _CompletionListHandle(editor, toplevel, result),
-                                 title='Code Assist Proposals')
+    enhanced_list = EnhancedList(
+        toplevel, _CompletionListHandle(editor, toplevel, result),
+        title='Code Assist Proposals')
     proposals = rope.ide.codeassist.ProposalSorter(result).get_sorted_proposal_list()
     for proposal in proposals:
         enhanced_list.add_entry(proposal)

File ropetest/historytest.py

 
 import rope.base.history
 from rope.base import exceptions, project
-from rope.refactor.change import *
+from rope.base.change import *
 from ropetest import testutils
 
 

File ropetest/pycoretest.py

         mod.write(contents)
         self.pycore.get_module('mod')
 
+    def test_file_encoding_reading(self):
+        contents = 'a_var = 1\ndef a_func():\n    global a_var\n'
+        mod = self.pycore.get_string_module(contents)
+        global_var = mod.get_attribute('a_var')
+        func_scope = mod.get_attribute('a_func').get_object().get_scope()
+        local_var = func_scope.get_name('a_var')
+        self.assertEquals(global_var, local_var)
+
 
 class PyCoreInProjectsTest(unittest.TestCase):
 

File ropetest/refactor/renametest.py

         self.assertEquals('new_var = 20\n', refactored)
 
     def test_variable_renaming_only_in_its_scope(self):
-        refactored = self._local_rename('a_var = 20\ndef a_func():\n    a_var = 10\n',
-                                          32, 'new_var')
-        self.assertEquals('a_var = 20\ndef a_func():\n    new_var = 10\n', refactored)
+        refactored = self._local_rename(
+            'a_var = 20\ndef a_func():\n    a_var = 10\n', 32, 'new_var')
+        self.assertEquals('a_var = 20\ndef a_func():\n    new_var = 10\n',
+                          refactored)
 
     def test_not_renaming_dot_name(self):
-        refactored = self._local_rename("replace = True\n'aaa'.replace('a', 'b')\n", 1, 'new_var')
+        refactored = self._local_rename(
+            "replace = True\n'aaa'.replace('a', 'b')\n", 1, 'new_var')
         self.assertEquals("new_var = True\n'aaa'.replace('a', 'b')\n", refactored)
 
     def test_renaming_multiple_names_in_the_same_line(self):
-        refactored = self._local_rename('a_var = 10\na_var = 10 + a_var / 2\n', 2, 'new_var')
+        refactored = self._local_rename(
+            'a_var = 10\na_var = 10 + a_var / 2\n', 2, 'new_var')
         self.assertEquals('new_var = 10\nnew_var = 10 + new_var / 2\n', refactored)
 
     def test_renaming_names_when_getting_some_attribute(self):
-        refactored = self._local_rename("a_var = 'a b c'\na_var.split('\\n')\n", 2, 'new_var')
+        refactored = self._local_rename(
+            "a_var = 'a b c'\na_var.split('\\n')\n", 2, 'new_var')
         self.assertEquals("new_var = 'a b c'\nnew_var.split('\\n')\n", refactored)
 
     def test_renaming_names_when_getting_some_attribute2(self):
-        refactored = self._local_rename("a_var = 'a b c'\na_var.split('\\n')\n", 20, 'new_var')
+        refactored = self._local_rename(
+            "a_var = 'a b c'\na_var.split('\\n')\n", 20, 'new_var')
         self.assertEquals("new_var = 'a b c'\nnew_var.split('\\n')\n", refactored)
 
     def test_renaming_function_parameters1(self):
-        refactored = self._local_rename("def f(a_param):\n    print a_param\n", 8, 'new_param')
+        refactored = self._local_rename(
+            "def f(a_param):\n    print a_param\n", 8, 'new_param')
         self.assertEquals("def f(new_param):\n    print new_param\n", refactored)
 
     def test_renaming_function_parameters2(self):
         renamer.get_changes('newpkg').do()
         self.assertEquals('import newpkg\nmy_pkg = newpkg', mod1.read())
 
+    def test_renaming_global_variables(self):
+        code = 'a_var = 1\ndef a_func():\n    global a_var\n    var = a_var\n'
+        refactored = self._local_rename(code, code.index('a_var'), 'new_var')
+        self.assertEquals(
+            'new_var = 1\ndef a_func():\n    global new_var\n    var = new_var\n',
+            refactored)
+
+    def test_renaming_global_variables2(self):
+        code = 'a_var = 1\ndef a_func():\n    global a_var\n    var = a_var\n'
+        refactored = self._local_rename(code, code.rindex('a_var'), 'new_var')
+        self.assertEquals(
+            'new_var = 1\ndef a_func():\n    global new_var\n    var = new_var\n',
+            refactored)
+
+
 if __name__ == '__main__':
     unittest.main()