Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(245)

Unified Diff: tools/telemetry/third_party/rope/docs/library.rst

Issue 1132103009: Example of refactoring using rope library. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/telemetry/third_party/rope/docs/done.rst ('k') | tools/telemetry/third_party/rope/docs/overview.rst » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/telemetry/third_party/rope/docs/library.rst
diff --git a/tools/telemetry/third_party/rope/docs/library.rst b/tools/telemetry/third_party/rope/docs/library.rst
new file mode 100644
index 0000000000000000000000000000000000000000..390b9c87c69aa25038acdf051446b76f27d2eb71
--- /dev/null
+++ b/tools/telemetry/third_party/rope/docs/library.rst
@@ -0,0 +1,890 @@
+=========================
+ Using Rope As A Library
+=========================
+
+If you need other features, send a feature request. Have a look at
+`contributing.rst`_.
+
+
+.. contents:: Table of Contents
+
+
+Quick Start
+===========
+
+This section will help you get started as soon as possible.
+
+
+Making A Project
+----------------
+
+The first thing you should do is make a project:
+
+.. code-block:: python
+
+ import rope.base.project
+
+
+ myproject = rope.base.project.Project('/path/to/myproject')
+
+It's good to know that:
+
+* A project is a folder in the file-system.
+* It can contain anything.
+* Rope searches for python modules and packages inside a project when
+ needed.
+* Refactorings only change files and folders inside the project that
+ has been passed to them.
+* Out of project modules that are imported from a module inside a
+ project are handled but never changed by refactorings.
+* Rope makes a rope folder inside projects. By default the name of this
+ folder is ``.ropeproject``, but that can be changed using the
+ constructor's ``ropefolder`` parameter. Passing ``None`` prevents rope
+ from making this folder.
+* Rope uses the ``.ropeproject`` folder for things like saving object
+ information and loading project configurations.
+* Project preferences can be configured by passing options to the
+ constructor or in ``.ropeproject/config.py``. See the default
+ ``config.py``, ``rope.base.default_config`` module, for more
+ information.
+* All configurations that are available in the ``config.py`` file can
+ be specified as keyword parameters to the ``Project`` constructor.
+ These parameters override the ones in the ``config.py`` file.
+* Each project has a set of ignored resource patterns. You can use it
+ to tell rope to ignore files and folders matching certain patterns.
+* The ``.ropeproject`` folder can be safely copied in other clones of
+ a project if you don't want to lose your objectdb and history.
+
+
+Library Utilities
+-----------------
+
+The `rope.base.libutils`_ module provides tools that make using rope as a
+library easier. We'll talk more about this module later.
+
+
+What Are These `Resource`\s?
+----------------------------
+
+In rope, files and folders in a project are accessed through
+``rope.base.resources.Resource`` objects. It has two subclasses
+``File`` and ``Folder``. What we care about is that refactorings and
+``Change``\s (we'll talk about them later) use resources.
+
+There are two options for creating a ``Resource`` for a path in a project.
+The first approach uses the `Project.get_resource()`_ method.
+
+.. code-block:: python
+
+ from rope.base import project
+
+
+ myresource = myproject.get_resource('/path/to/resource')
+
+However, it's preferable to use the ``libutils.path_to_resource()``
+function, because it's more flexible and offers a unified way to create
+resources. It takes a ``project`` and ``path`` as parameters with an
+optional ``type``. The ``type`` parameter, with values ``file`` or
+``folder``, can create a resource for an object that doesn't exist yet.
+
+.. code-block:: python
+
+ from rope.base import libutils
+
+
+ myresource = libutils.path_to_resource(myproject, '/path/to/resource')
+
+
+Consider we have a resource. How can we know anything about it? The
+answer is to use its ``path`` and ``real_path`` attributes.
+``Resource.real_path`` is the absolute path of the resource in the
+file-system. The ``Resource.path`` attribute contains the address of a
+resource relative to the project's root.
+
+
+Performing Refactorings
+-----------------------
+
+As a short example of performing refactorings, we'll show how to extract
+a variable from a file. First we need the ``Resource`` object that
+points to a file in a project:
+
+.. code-block:: python
+
+ resource = libutils.path_to_resource(myproject, '/path/to/my/module.py')
+
+Now we can make our Refactoring class:
+
+.. code-block:: python
+
+ from rope.refactor.extract import ExtractVariable
+
+
+ extractor = ExtractVariable(myproject, resource, start, end)
+
+Where ``start`` and ``end`` are the offsets of the region to extract in
+``resource``. Be careful when calculating the offsets. DOS
+line-endings and multi-byte characters are considered to be one
+character. This is actually easier for IDEs, since most GUI libraries
+handle those cases for you.
+
+Next, the IDE ask the user to configure refactoring options, like
+specifying the name of the extracted variable.
+
+After that, we can calculate the changes:
+
+.. code-block:: python
+
+ changes = extractor.get_changes('extracted_variable')
+
+Each refactoring returns a ``rope.base.change.Change`` object that holds
+the changes it made. Calculating those changes can be time consuming.
+See the `rope.base.taskhandle.TaskHandle`_ section for measuring its
+progress or interrupting it.
+
+
+Previewing And Performing Changes
+---------------------------------
+
+As mentioned in the last section each refactoring returns a
+``rope.base.change.Change`` object. Now how can we know what it
+contains and how to perform it?
+
+*Previewing*:
+
+You can use ``changes.get_description()`` to get a preview. It is useful
+when you don't care much about the format. Otherwise you can use the
+``changes`` object directly. See the documentation in
+``rope.base.change`` module.
+
+*Performing*:
+
+The easiest way for performing the refactoring is to use the
+`Project.do()`_ method:
+
+.. code-block:: python
+
+ myproject.do(changes)
+
+If you want to perform the changes yourself, you have two options.
+Note that the main reason for performing the changes manually is
+handling version control systems that are not supported by rope.
+
+1. The first approach is to use `rope.base.fscommands`_ (see `Writing A
+ FileSystemCommands`_). The changes can be performed as before using
+ `Project.do()`_.
+
+2. The second approach is to perform the changes manually based on the
+ returned ``changes`` object (again see the documentation in
+ ``rope.base.change`` module). If this approach is used you cannot undo
+ the refactoring using ``project.history.undo()``.
+
+*Updating Open Buffers In IDEs*:
+
+Usually editors need to reload the files changed by rope. You can use
+``Change.get_changed_resources()`` to get the list of resources that
+need to be reloaded.
+
+
+Validating The Project
+----------------------
+
+When using rope as a library, you probably change the files in it in
+parallel (for example in IDEs). To force rope to invalidate cached
+information about resources that have been removed or changed outside
+rope, you should call the `Project.validate()`_ method. You can pass a
+resource to this method. For example:
+
+.. code-block:: python
+
+ myproject.validate(resource)
+
+This validates all files and directories in resource. Call this
+function every time you want use rope (i.e., before performing
+refactorings).
+
+
+Performing Static Object Analysis
+---------------------------------
+
+One of the greatest strengths of rope is its Static Object Analysis
+(SOA). It analyzes function calls and assignments to collect the types
+of objects passed to the function. Rope uses the collected data to infer
+the type of function parameters, return values, and the objects stored
+in built-in containers. The function
+``rope.base.libutils.analyze_modules()`` performs SOA on all modules in
+the project. It is recommended that you call this function occasionally,
+and especially before performing large refactorings. Note that analyzing
+all modules of a project may take a long time.
+
+If you have ``automatic_soa`` set, which instructs rop to analyze the
+changed scopes of modules, then you should report the changes by calling
+``rope.base.libutils.report_change()`` when saving files, as follows:
+
+.. code-block:: python
+
+ # Save the new contents.
+ old_contents = resource.read()
+ resource.write(new_contents)
+
+ # Inform rope about the change.
+ libutils.report_change(myproject, path, old_contents)
+
+Note, however, that the use of ``automatic_soa`` is discouraged, because it may
+slow down saving considerably.
+
+
+Closing The Project
+-------------------
+
+`Project.close()`_ closes a project's open resources. Always call this
+function when you don't need a project anymore:
+
+.. code-block:: python
+
+ myproject.close()
+
+
+``rope.base.libutils``
+======================
+
+The ``rope.base.libutils`` module contains functions that make life
+easier for building refactoring tools. In some cases, the functions
+offer a unified way to access or create objects. You're encouraged to
+use ``rope.base.libutils`` functions whenever possible, because the APIs
+here may not be as volatile as class methods.
+
+
+``libutils.analyze_module()``
+------------------------------
+
+Perform static object analysis on a Python file in the project. Note,
+this may be a very time consuming task.
+
+.. code-block:: python
+
+ libutils.analyze_module(myproject, resource)
+
+
+``libutils.analyze_modules()``
+------------------------------
+
+Perform static object analysis on all Python files in the project. Note
+that it might take a long time to finish.
+
+.. code-block:: python
+
+ libutils.analyze_modules(myproject)
+
+
+``libutils.get_string_module()``
+--------------------------------
+
+Returns a ``rope.base.pyobjects.PyModule`` object for the code string.
+An optional ``resource`` argument can be specified for the resource this
+code is associated with. If ``force_errors` is ``True``, then
+``rope.base.exceptions.ModuleSyntaxError`` is raised when the code has
+syntax errors. Otherwise, syntax errors are silently ignored. Note that
+``force_errors`` overrides the ``ignore_syntax_errors`` project
+configuration flag.
+
+.. code-block:: python
+
+ pymodule = libutils.get_string_module(myproject, source)
+
+
+``libutils.get_string_scope()``
+-------------------------------
+
+Get the ``rope.base.pyscopes.GlobalScope`` object for the code string.
+This is the outermost scope of the code encompassing the whole module.
+
+.. code-block:: python
+
+ scope = libutils.get_string_scope(myproject, source)
+
+
+``libutils.is_python_file()``
+-----------------------------
+
+Returns ``True`` if the resource is a Python file.
+
+.. code-block:: python
+
+ libutils.is_python_file(myproject, resource)
+
+
+``libutils.modname()``
+----------------------
+
+Retrieves the dotted path string to the module that contains that given
+resource.
+
+.. code-block:: python
+
+ # If resource is 'path/to/resource.py' relative to the project's root
+ # directory, this returns the string: 'path.to.resource'.
+ module_name = libutils.modname(resource)
+
+
+``libutils.path_relative_to_project_root()``
+--------------------------------------------
+
+Retrieve the path relative to the project's root directory.
+
+.. code-block:: python
+
+ # Get the path relative to the project's root directory.
+ relpath = libutils.relative(myproject.address, path)
+
+
+``libutils.path_to_resource()``
+-------------------------------
+
+Get the resource --- a file or folder --- at the given path. An optional
+``type`` argument can be used if the resource doesn't yet exist. The
+values for ``type`` are the strings ``'file'`` or ``'folder'``.
+
+.. code-block:: python
+
+ # Resource for an existing file.
+ myfile = libutils.path_to_resource(myproject, '/path/to/file.py')
+
+ # Resource for a non-existing folder.
+ new_folder = libutils.path_to_resource(myproject, '/path/to/folder', type='folder')
+
+
+``rope.base.project.Project``
+=============================
+
+You can create a project by:
+
+.. code-block:: python
+
+ project = Project(root_address)
+
+Where the ``root_address`` is the root folder of your project.
+
+A project has some useful attributes. ``Project.address`` is the
+address of the root folder of a project. ``Project.root`` is a
+``Folder`` object that points to that folder.
+
+
+`Project.do()`
+--------------
+
+Used to commit changes returned by refactorings:
+
+.. code-block:: python
+
+ project.do(changes)
+
+
+`Project.history`
+-----------------
+
+A ``rope.base.history.History`` object. You can use its ``undo`` and
+``redo`` methods for undoing or redoing changes. Note that you can use
+this only if you have committed your changes using rope.
+
+
+`Project.validate()`
+--------------------
+
+When using rope as a library, you will probably change the files in that
+project in parallel (for example in IDEs). To force rope to validate
+cached information about resources that have been removed or changed
+outside rope, you should call ``Project.validate()``. You should pass a
+resource to this method. For example:
+
+.. code-block:: python
+
+ project.validate(project.root)
+
+This validates all files and directories in the project and clears the
+cache of all recorded changes.
+
+
+`Project.close()`
+-----------------
+
+Closes a project's open resources. Always call this function when you
+don't need a project anymore. Currently it closes the files used for
+storing object information and project history. Because some parts of
+these files are in memory for efficiency, not closing a project might
+put them in an inconsistent state.
+
+
+`rope.base.fscommands`
+======================
+
+The ``rope.base.fscommands`` module implements basic file system
+operations that rope needs to perform. The main reason for the
+existence of this module is supporting version control systems. Have a
+look at ``FileSystemCommands`` and ``SubversionCommands`` in the same
+module. If you need other version control systems you can write a new
+class that provides this interface. ``rope.base.project.Project``
+accepts an ``fscommands`` argument. You can use this argument to force
+rope to use your new class.
+
+
+``.ropeproject`` Folder
+=======================
+
+Since version ``0.5``, rope makes a ``.ropeproject`` folder in the
+project by default for saving project configurations and data. The name
+of this folder is passed to the constructor if you want to change that.
+You can force rope not to make such a folder by passing ``None``.
+
+If such a folder exists, rope loads the ``config.py`` file in that
+folder. It might also use it for storing object information and
+history.
+
+
+`rope.base.pycore.PyCore`
+=========================
+
+Provides useful methods for managing python modules and packages. Each
+project has a ``PyCore`` that can be accessed using the
+``Project.pycore`` attribute.
+
+``PyCore.run_module()`` runs a resource. When running, it collects type
+information to do dynamic object inference. For this reason modules
+run much slower.
+
+Also ``Pycore.analyze_module()`` collects object information for a
+module. The collected information can be used to enhance rope's
+static object inference.
+
+
+`rope.base.taskhandle.TaskHandle`
+=================================
+
+A TaskHandle can be used for stopping and monitoring the progress of
+time consuming tasks, like some refactorings. The ``Project.do()`` and
+``Refactoring.get_changes()`` methods for most refactorings take a
+keyword parameter called ``task_handle``. You can pass a ``TaskHandle``
+object to them. A ``TaskHandle`` can be used for interrupting or
+observing a task.
+
+Always pass ``task_handle`` as keyword argument. It will always be the
+last argument, and new arguments of the refactoring are added before it.
+
+A task might consist of a few ``JobSet``\s. Each ``JobSet`` performs a
+few jobs. For instance calculating the changes for renaming a method in
+a class hierarchy has two job sets: one to find the classes for
+constructing the class hierarchy and another to change the occurrences.
+
+The ``TaskHandle.current_jobset()`` returns the most recent ``JobSet``
+or ``None`` if none has been started. You can use the methods of
+``JobSet`` for obtaining information about the current job. So you
+might want to do something like:
+
+.. code-block:: python
+
+ import rope.base.taskhandle
+
+
+ handle = rope.base.taskhandle.TaskHandle("Test Task")
+
+ def update_progress():
+ jobset = handle.current_jobsets()
+ if jobset:
+ text = ''
+ # getting current job set name
+ if jobset.get_name() is not None:
+ text += jobset.get_name()
+ # getting active job name
+ if jobset.get_active_job_name() is not None:
+ text += ' : ' + jobset.get_active_job_name()
+ # adding done percent
+ percent = jobset.get_percent_done()
+ if percent is not None:
+ text += ' ... %s percent done' % percent
+ print text
+
+ handle.add_observer(update_progress)
+
+ changes = renamer.get_changes('new_name', task_handle=handle)
+
+Also you can use something like this for stopping the task:
+
+.. code-block:: python
+
+ def stop():
+ handle.stop()
+
+After calling ``stop()``, the thread that is executing the task will
+be interrupted by a ``rope.base.exceptions.InterruptedTaskError``
+exception.
+
+
+Refactorings
+============
+
+Have a look at ``rope.refactor`` package and its sub-modules. For
+example for performing a move refactoring you can create a ``Move``
+object like this:
+
+.. code-block:: python
+
+ mover = Move(project, resource, offset)
+
+Where ``resource`` and ``offset`` is the location to perform the
+refactoring.
+
+Then you can commit the changes by it using the ``get_changes()``
+method:
+
+.. code-block:: python
+
+ project.do(mover.get_changes(destination))
+
+Where the ``destination`` module/package is the destination resource for
+move refactoring. Other refactorings classes have a similar interface.
+
+
+List Of Refactorings
+--------------------
+
+Here is the list of refactorings rope provides. (Note that this list
+might be out of date.) For more information about these refactoring see
+pydocs in their modules and the unit-tests in the ``ropetest/refactor/``
+folder.
+
+* ``rope.refactor.rename``:
+ Rename something in the project. See the example below.
+
+* ``rope.refactor.move``:
+ Move a python element in the project.
+
+* ``rope.refactor.restructure``:
+ Restructure code. See the example below.
+
+* ``rope.refactor.extract``:
+ Extract methods/variables.
+
+* ``rope.refactor.inline``:
+ Inline occurrences of a method/variable/parameter.
+
+* ``rope.refactor.usefunction``:
+ Try to use a function wherever possible.
+
+* ``rope.refactor.method_object``:
+ Transform a function or a method to a method object.
+
+* ``rope.refactor.change_signature``:
+ Change the signature of a function/method.
+
+* ``rope.refactor.introduce_factory``:
+ Introduce a factory for a class and changes all constructors to use
+ it.
+
+* ``rope.refactor.introduce_parameter``:
+ Introduce a parameter in a function.
+
+* ``rope.refactor.encapsulate_field``:
+ Generate a getter/setter for a field and changes its occurrences to
+ use them.
+
+* ``rope.refactor.localtofield``:
+ Change a local variable to field.
+
+* ``rope.refactor.topackage``:
+ Transform a module to a package with the same name.
+
+* ``rope.refactor.importutils``:
+ Perform actions like organize imports.
+
+
+Refactoring Resources Parameter
+-------------------------------
+
+Some refactorings, restructure and find occurrences accept an argument
+called ``resources``. If it is a list of `File`\s, all other
+resources in the project are ignored and the refactoring only analyzes
+them. If it is ``None`` all python modules in the project will be
+analyzed. Using this parameter, IDEs can let the user limit the files
+on which a refactoring should be applied.
+
+
+Examples
+========
+
+Rename
+------
+
+Using rename refactoring:
+
+.. code-block:: python
+
+ # Creating a project
+ >>> from rope.base.project import Project
+ >>> project = Project('.')
+
+ # Working with files to create a module
+ >>> mod1 = project.root.create_file('mod1.py')
+ >>> mod1.write('a_var = 10\n')
+
+ # Alternatively you can use `generate` module.
+ # Creating modules and packages using `generate` module
+ >>> from rope.contrib import generate
+ >>> pkg = generate.create_package(project, 'pkg')
+ >>> mod2 = generate.create_module(project, 'mod2', pkg)
+ >>> mod2.write('import mod1\nprint mod1.a_var\n')
+
+ # We can use `Project.find_module` for finding modules, too
+ >>> assert mod2 == project.find_module('pkg.mod2')
+
+ # Performing rename refactoring on `mod1.a_var`
+ >>> from rope.refactor.rename import Rename
+ >>> changes = Rename(project, mod1, 1).get_changes('new_var')
+ >>> project.do(changes)
+ >>> mod1.read()
+ u'new_var = 10\n'
+ >>> mod2.read()
+ u'import mod1\nprint mod1.new_var\n'
+
+ # Undoing rename refactoring
+ >>> project.history.undo()
+ ...
+ >>> mod1.read()
+ u'a_var = 10\n'
+ >>> mod2.read()
+ u'import mod1\nprint mod1.a_var\n'
+
+ # Cleaning up
+ >>> pkg.remove()
+ >>> mod1.remove()
+ >>> project.close()
+
+
+Restructuring
+-------------
+
+The example for replacing occurrences of our ``pow`` function to ``**``
+operator (see the restructuring section of `overview.rst`_):
+
+.. code-block:: python
+
+ # Setting up the project
+ >>> from rope.base.project import Project
+ >>> project = Project('.')
+
+ >>> mod1 = project.root.create_file('mod1.py')
+ >>> mod1.write('def pow(x, y):\n result = 1\n'
+ ... ' for i in range(y):\n result *= x\n'
+ ... ' return result\n')
+ >>> mod2 = project.root.create_file('mod2.py')
+ >>> mod2.write('import mod1\nprint(mod1.pow(2, 3))\n')
+
+ >>> from rope.refactor import restructure
+
+ >>> pattern = '${pow_func}(${param1}, ${param2})'
+ >>> goal = '${param1} ** ${param2}'
+ >>> args = {'pow_func': 'name=mod1.pow'}
+
+ >>> restructuring = restructure.Restructure(project, pattern, goal, args)
+
+ >>> project.do(restructuring.get_changes())
+ >>> mod2.read()
+ u'import mod1\nprint(2 ** 3)\n'
+
+ # Cleaning up
+ >>> mod1.remove()
+ >>> mod2.remove()
+ >>> project.close()
+
+
+See code documentation and test suites for more information.
+
+.. _overview.rst: overview.rst
+.. _contributing.rst: contributing.rst
+
+
+Other Topics
+============
+
+
+Writing A `FileSystemCommands`
+------------------------------
+
+The ``get_changes()`` method of refactoring classes return a
+``rope.base.change.Change`` object. You perform these changes by
+calling ``Project.do()``. But as explained above some IDEs need to
+perform the changes themselves.
+
+Every change to the file-system in rope is commited using an object that
+provides a ``rope.base.fscommands.FileSystemCommands`` interface. As
+explained above in `rope.base.fscommands`_ section, rope uses this
+interface to handle different VCSs.
+
+You can implement your own fscommands object:
+
+.. code-block:: python
+
+ class MyFileSystemCommands(object):
+
+ def create_file(self, path):
+ """Create a new file"""
+ # ...
+
+ def create_folder(self, path):
+ """Create a new folder"""
+ # ...
+
+ def move(self, path, new_location):
+ """Move resource at `path` to `new_location`"""
+ # ...
+
+ def remove(self, path):
+ """Remove resource"""
+ # ...
+
+ def write(self, path, data):
+ """Write `data` to file at `path`"""
+ # ...
+
+And you can create a project like this:
+
+.. code-block:: python
+
+ my_fscommands = MyFileSystemCommands()
+ project = rope.base.project.Project('~/myproject',
+ fscommands=my_fscommands)
+
+
+`rope.contrib.codeassist`
+-------------------------
+
+The ``rope.contrib`` package contains modules that use rope base parts
+and provide useful features. ``rope.contrib.codeassist`` module can be
+used in IDEs:
+
+.. code-block:: python
+
+ from rope.ide import codeassist
+
+
+ # Get the proposals; you might want to pass a Resource
+ proposals = codeassist.code_assist(project, source_code, offset)
+
+ # Sorting proposals; for changing the order see pydoc
+ proposals = codeassist.sorted_proposals(proposals)
+
+ # Where to insert the completions
+ starting_offset = codeassist.starting_offset(source_code, offset)
+
+ # Applying a proposal
+ proposal = proposals[x]
+ replacement = proposal.name
+
+ new_source_code = (source_code[:starting_offset] +
+ replacement + source_code[offset:])
+
+``maxfixes`` parameter of ``code_assist`` decides how many syntax errors
+to fix. The default value is one. For instance:
+
+.. code-block:: python
+
+ def f():
+ g(my^
+
+ myvariable = None
+
+ def g(p):
+ invalid syntax ...
+
+will report ``myvariable``, only if ``maxfixes`` is greater than 1.
+
+``later_locals``, if ``True``, forces rope to propose names that are
+defined later in current scope. It is ``True`` by default. For
+instance:
+
+.. code-block:: python
+
+ def f():
+ my^
+ myvariable = None
+
+will not report ``myvariable``, if ``later_locals`` is ``False``.
+
+See pydocs and source code for more information (other functions in
+this module might be interesting, too; like ``get_doc``,
+``get_definition_location``).
+
+
+`rope.contrib.findit`
+---------------------
+
+``findit`` module provides ``find_occurrences()`` for finding
+occurrences of a name. Also the ``find_implementations()`` function
+finds the places in which a method is overridden.
+
+
+`rope.contrib.autoimport`
+-------------------------
+
+This module can be used to find the modules that provide a name. IDEs
+can use this module to auto-import names. ``AutoImport.get_modules()``
+returns the list of modules with the given global name.
+``AutoImport.import_assist()`` tries to find the modules that have a
+global name that starts with the given prefix.
+
+
+Cross-Project Refactorings
+--------------------------
+
+``rope.refactor.multiproject`` can be used to perform a refactoring
+across multiple projects.
+
+Usually refactorings have a main project. That is the project that
+contains the definition of the changing python name. Other projects
+depend on the main one, and the uses of the changed name in them should
+be updated.
+
+Each refactoring changes only one project (the project passed to its
+constructor). But we can use the ``MultiProjectRefactoring`` proxy to
+perform a refactoring on other projects, too.
+
+First we need to create a multi-project refactoring constructor. As
+an example consider that we want to perform a rename refactoring:
+
+.. code-block:: python
+
+ from rope.refactor import multiproject, rename
+
+
+ CrossRename = multiproject.MultiProjectRefactoring(rename.Rename,
+ projects)
+
+
+Here ``projects`` is the list of dependant projects. It does not
+include the main project. The first argument is the refactoring class
+(such as ``Rename``) or factory function (like ``create_move``).
+
+Next we can construct the refactoring:
+
+.. code-block:: python
+
+ renamer = CrossRename(project, resource, offset)
+
+We create the rename refactoring as we do for normal refactoings. Note
+that ``project`` is the main project.
+
+As mentioned above, other projects use the main project. Rope
+automatically adds the main project to the python path of other
+projects.
+
+Finally we can calculate the changes. But instead of calling
+``get_changes()`` (which returns main project changes only), we can
+call ``get_all_changes()`` with the same arguments. It returns a list
+of ``(project, changes)`` tuples. You can perform them manually by
+calling ``project.do(changes)`` for each tuple, or use
+``multiproject.perform()``:
+
+.. code-block:: python
+
+ project_and_changes = renamer.get_all_changes('newname')
+
+ multiproject.perform(project_and_changes)
« no previous file with comments | « tools/telemetry/third_party/rope/docs/done.rst ('k') | tools/telemetry/third_party/rope/docs/overview.rst » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698