Giter VIP home page Giter VIP logo

rope's Introduction

rope -- the world's most advanced open source Python refactoring library

Build Status Latest version Download count Documentation Status Codecov

Overview

Rope is the world's most advanced open source Python refactoring library (yes, I totally stole that tagline from Postgres).

Most Python syntax up to Python 3.10 is supported. Please file bugs and contribute patches if you encounter gaps.

Since version 1.0.0, rope no longer support running on Python 2. If you need Python 2 support, then check out the python2 branch or the 0.x.x releases.

Getting Started

Why use Rope?

  • Rope aims to provide powerful and safe refactoring
  • Rope is light on dependency, Rope only depends on Python itself
  • Unlike PyRight or PyLance, Rope does not depend on Node.js
  • Unlike PyLance or PyCharm, Rope is open source.
  • Unlike PyRight and PyLance, Rope is written in Python itself, so if you experience problems, you would be able to debug and hack it yourself in a language that you are already familiar with
  • In comparison to Jedi, Rope is focused on refactoring. While Jedi provides some basic refactoring capabilities, Rope supports many more advanced refactoring operations and options that Jedi does not.

Bug Reports

Send your bug reports and feature requests at python-rope's issue tracker in GitHub.

Maintainers

Current active maintainer of Rope is Lie Ryan (@lieryan).

Special Thanks

Many thanks the following people:

Packaging Status

Packaging status

Packaging status

License

This program is under the terms of LGPL v3+ (GNU Lesser General Public License). Have a look at COPYING for more information.

rope's People

Contributors

aligrudi avatar allcontributors[bot] avatar apmorton avatar bagel897 avatar brendanator avatar bwendling avatar climbus avatar digenis avatar dryobates avatar dsyzling avatar edreamleo avatar emacsway avatar enomado avatar ferada avatar fervidnerd avatar hayd avatar jorgenschaefer avatar levitanus avatar lieryan avatar mattst88 avatar mcepl avatar orestis avatar raymyers avatar rdbisme avatar sergeyglazyrindev avatar soupytwist avatar stpierre avatar timgates42 avatar tkrabel avatar tzing avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rope's Issues

rope for modules in non-standard environments

Hi,

This is not a bug report but a question. (The bug is that [email protected] pointed to by http://rope.sourceforge.net/ does not seem to exist)

I would like to use rope in an IDE for code completion and call tips. However, my python code will be compiled within an environment that has some standard symbols predefined (i.e. without using the import statement in the module). Is there a way to tell rope about those symbols?

Cheers,
Christoph

Uncaught IndentationError in get_calltip

This file generates an IndentationError. I would expect Rope to catch this error and either try to fix it using the usual maxfixes semantics, or throw a ModuleSyntaxError like for other such errors.

import shutil
import tempfile

import rope.base.project
import rope.contrib.codeassist


project_root = tempfile.mkdtemp()
try:

    project = rope.base.project.Project(project_root)
    rope.contrib.codeassist.get_calltip(
        project, """\
def foo():
       print(23)
      print(17)
        """, 24
    )

finally:
    shutil.rmtree(project_root)

Backtrace:

Traceback (most recent call last):
  File "foo.py", line 17, in <module>
    """, 24
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/contrib/codeassist.py", line 92, in get_calltip
    pyname = fixer.pyname_at(offset)
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/contrib/fixsyntax.py", line 46, in pyname_at
    pymodule = self.get_pymodule()
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/base/utils.py", line 11, in _wrapper
    setattr(self, name, func(self, *args, **kwds))
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/contrib/fixsyntax.py", line 34, in get_pymodule
    self.commenter.comment(e.lineno)
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/contrib/fixsyntax.py", line 78, in comment
    start = _logical_start(self.lines, lineno, check_prev=True) - 1
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/contrib/fixsyntax.py", line 172, in _logical_start
    return logical_finder.logical_line_in(lineno)[0]
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/base/codeanalyze.py", line 183, in logical_line_in
    raise e
  File "<tokenize>", line 3
    print(17)
    ^
IndentationError: unindent does not match any outer indentation level

make #79 pull request more robust

@jorgenschaefer I have probably screwed up something, but your tests from #79 seem to be a little bit too fragile:

======================================================================
ERROR: test_does_not_fail_for_permission_denied (ropetest.projecttest.ProjectTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/matej/archiv/knihovna/repos/rope/ropetest/projecttest.py", line 228, in test_does_not_fail_for_permission_denied
    os.makedirs(bad_dir)
  File "/usr/lib64/python2.7/os.py", line 157, in makedirs
    mkdir(name, mode)
OSError: [Errno 17] File exists: 'sample_folder/bad_dir'

----------------------------------------------------------------------

Could you make your tests a bit more robust, please, and survive some files existing?

"TypeError: must be str, not unicode" from Mercurial while renaming package

I tried to rename a Python package, and got the following crash from the Mercurial library: presumably from a path being passed as unicode somewhere, instead of str.

I'm not certain whether this is a Rope issue, or a Mercurial library issue: if it turns out to be the latter, i'll take the issue upstream.

Versions:

  • Python 2.7.4
  • Vim 7.3 (patches 1-547)
  • python-mode 0.6.18
  • ropemode 0.2
  • rope 0.9.4
  • Mercurial 2.6.1

Traceback:

      Error detected while processing function RopeRename:
    line    1:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "[...]/ropemode/decorators.py", line 53, in newfunc
        return func(*args, **kwds)
      File "[...]/ropemode/interface.py", line 49, in do_refactor
        refactoring(self, self.env).show(initial_asking=initial_asking)
      File "[...]/ropemode/refactor.py", line 45, in show
        self._perform(changes)
      File "[...]/ropemode/refactor.py", line 94, in _perform
        interrupts=False)
      File "[...]/ropemode/refactor.py", line 472, in runtask
        return RunTask(env, command, name, interrupts)()
      File "[...]/ropemode/refactor.py", line 492, in __call__
        result = self.task(handle)
      File "[...]/ropemode/refactor.py", line 90, in perform
        self.project.do(changes, task_handle=handle)
      File "[...]/rope/base/project.py", line 72, in do
        self.history.do(changes, task_handle=task_handle)
      File "[...]/rope/base/history.py", line 36, in do
        changes.do(change.create_job_set(task_handle, changes))
      File "[...]/rope/base/change.py", line 66, in do
        change.do(job_set)
      File "[...]/rope/base/change.py", line 126, in call
        function(self)
      File "[...]/rope/base/change.py", line 201, in do
        self._operations.move(self.resource, self.new_resource)
      File "[...]/rope/base/change.py", line 337, in move
        fscommands.move(resource.real_path, new_resource.real_path)
      File "[...]/rope/base/fscommands.py", line 115, in move
        new_location, after=False)
      File "/usr/lib/python2.7/dist-packages/mercurial/commands.py", line 4808, in rename
        return cmdutil.copy(ui, repo, pats, opts, rename=True)
      File "/usr/lib/python2.7/dist-packages/mercurial/cmdutil.py", line 459, in copy
        if copyfile(abssrc, relsrc, targetpath(abssrc), exact):
      File "/usr/lib/python2.7/dist-packages/mercurial/cmdutil.py", line 357, in copyfile
        dryrun=dryrun, cwd=cwd)
      File "/usr/lib/python2.7/dist-packages/mercurial/scmutil.py", line 764, in dirstatecopy
        wctx.copy(origsrc, dst)
      File "/usr/lib/python2.7/dist-packages/mercurial/context.py", line 1135, in copy
        self._repo.dirstate.add(dest)
      File "/usr/lib/python2.7/dist-packages/mercurial/dirstate.py", line 384, in add
        self._addpath(f, 'a', 0, -1, -1)
      File "/usr/lib/python2.7/dist-packages/mercurial/dirstate.py", line 333, in _addpath
        self._dirs.addpath(f)
    TypeError: must be str, not unicode

BuiltinUnknown does not have a get_returned_object method, but it's called

(The file as added in commit 1567: 6d2d20208eeb)

Here's a partial stack trace of the call tree, as provided when ropemacs tries to create a completion proposition:

    return rope.base.oi.soi.infer_assigned_object(self)
  File "/Library/Python/2.6/site-packages/rope-0.9.3-py2.6.egg/rope/base/utils.py", line 37, in newfunc
    return func(*args, **kwds)
  File "/Library/Python/2.6/site-packages/rope-0.9.3-py2.6.egg/rope/base/oi/soi.py", line 61, in infer_assigned_object
    result = _infer_assignment(assignment, pyname.module)
  File "/Library/Python/2.6/site-packages/rope-0.9.3-py2.6.egg/rope/base/utils.py", line 37, in newfunc
    return func(*args, **kwds)
  File "/Library/Python/2.6/site-packages/rope-0.9.3-py2.6.egg/rope/base/oi/soi.py", line 110, in _infer_assignment
    result = _follow_pyname(assignment, pymodule)
  File "/Library/Python/2.6/site-packages/rope-0.9.3-py2.6.egg/rope/base/utils.py", line 37, in newfunc
    return func(*args, **kwds)
  File "/Library/Python/2.6/site-packages/rope-0.9.3-py2.6.egg/rope/base/oi/soi.py", line 141, in _follow_pyname
    pyname = evaluate.eval_node(holding_scope, assign_node)
  File "/Library/Python/2.6/site-packages/rope-0.9.3-py2.6.egg/rope/base/evaluate.py", line 25, in eval_node
    return eval_node2(scope, node)[1]
  File "/Library/Python/2.6/site-packages/rope-0.9.3-py2.6.egg/rope/base/evaluate.py", line 30, in eval_node2
    ast.walk(node, evaluator)
  File "/Library/Python/2.6/site-packages/rope-0.9.3-py2.6.egg/rope/base/ast.py", line 30, in walk
    return method(node)
  File "/Library/Python/2.6/site-packages/rope-0.9.3-py2.6.egg/rope/base/evaluate.py", line 286, in _Subscript
    self._call_function(node.value, '__getslice__')
  File "/Library/Python/2.6/site-packages/rope-0.9.3-py2.6.egg/rope/base/evaluate.py", line 301, in _call_function
    pyobject=call_function.get_returned_object(arguments_))
AttributeError: 'BuiltinUnknown' object has no attribute 'get_returned_object'

https://gist.github.com/7761139
https://gist.github.com/7761140

Rope does not comply with the MRO

When looking for the definition of a method invoked with super,
Rope seem to perform a depth-first search in the inheritance graph of the class,
while Python actually does a breadth-first search (the so called MRO).

The code below demonstrate the problem:

# diamond inheritance
#
#   A
#  / \
#  B C
#  \ /
#   D

class A(object):
    def method(self):
        return "I'm an A"

class B(A):
    # do not override method
    pass

class C(A):
    def method(self):
        return "I'm a C"

class D(B, C):
    def method(self):
        return super(D, self).method() + " and a D"
        # the super method above is C.method,
        # but rope will send me to A.method
        # when I ask to go to the definition


print D().method()
# will display  "I'm a C and a D"

pip install broken with python 3

The pip installation do not work because of cPickle import:

sudo pip install rope                                                                                                                                                         :(
Downloading/unpacking rope
  Downloading rope-0.10.2.tar.gz (221kB): 221kB downloaded
  Running setup.py (path:/tmp/pip_build_root/rope/setup.py) egg_info for package rope
    Traceback (most recent call last):
      File "<string>", line 17, in <module>
      File "/tmp/pip_build_root/rope/setup.py", line 5, in <module>
        import ropetest
      File "/tmp/pip_build_root/rope/ropetest/__init__.py", line 4, in <module>
        import ropetest.projecttest
      File "/tmp/pip_build_root/rope/ropetest/projecttest.py", line 9, in <module>
        from rope.base.libutils import path_to_resource
      File "/tmp/pip_build_root/rope/rope/base/libutils.py", line 4, in <module>
        import rope.base.project
      File "/tmp/pip_build_root/rope/rope/base/project.py", line 1, in <module>
        import cPickle as pickle
    ImportError: No module named 'cPickle'
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):

  File "<string>", line 17, in <module>

  File "/tmp/pip_build_root/rope/setup.py", line 5, in <module>

    import ropetest

  File "/tmp/pip_build_root/rope/ropetest/__init__.py", line 4, in <module>

    import ropetest.projecttest

  File "/tmp/pip_build_root/rope/ropetest/projecttest.py", line 9, in <module>

    from rope.base.libutils import path_to_resource

  File "/tmp/pip_build_root/rope/rope/base/libutils.py", line 4, in <module>

    import rope.base.project

  File "/tmp/pip_build_root/rope/rope/base/project.py", line 1, in <module>

    import cPickle as pickle

ImportError: No module named 'cPickle'

see this report:
https://groups.google.com/forum/#!topic/rope-dev/Hq_MfuYmWQc

Breaks on python 2.4

Not sure if we care:

[test@hp-dc5700-02 rope]$ python setup.py test
running test
running egg_info
creating rope.egg-info
writing rope.egg-info/PKG-INFO
writing top-level names to rope.egg-info/top_level.txt
writing dependency_links to rope.egg-info/dependency_links.txt
writing manifest file 'rope.egg-info/SOURCES.txt'
reading manifest file 'rope.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'rope.egg-info/SOURCES.txt'
running build_ext
Traceback (most recent call last):
  File "setup.py", line 44, in ?
    classifiers=classifiers,
  File "/usr/lib64/python2.4/distutils/core.py", line 149, in setup
    dist.run_commands()
  File "/usr/lib64/python2.4/distutils/dist.py", line 946, in run_commands
    self.run_command(cmd)
  File "/usr/lib64/python2.4/distutils/dist.py", line 966, in run_command
    cmd_obj.run()
  File "/usr/lib/python2.4/site-packages/setuptools/command/test.py", line 137,   in run
    self.with_project_on_sys_path(self.run_tests)
  File "/usr/lib/python2.4/site-packages/setuptools/command/test.py", line 117,   in with_project_on_sys_path
    func()
  File "/usr/lib/python2.4/site-packages/setuptools/command/test.py", line 146,   in run_tests
    testLoader = loader_class()
  File "/usr/lib64/python2.4/unittest.py", line 758, in __init__
    self.parseArgs(argv)
  File "/usr/lib64/python2.4/unittest.py", line 785, in parseArgs
    self.createTests()
  File "/usr/lib64/python2.4/unittest.py", line 791, in createTests
    self.module)
  File "/usr/lib64/python2.4/unittest.py", line 556, in loadTestsFromNames
    suites = [self.loadTestsFromName(name, module) for name in names]
  File "/usr/lib64/python2.4/unittest.py", line 524, in loadTestsFromName
    module = __import__('.'.join(parts_copy))
  File "/home/test/rope/ropetest/__init__.py", line 4, in ?
    import ropetest.projecttest
  File "/home/test/rope/ropetest/projecttest.py", line 6, in ?
    from rope.base.libutils import path_to_resource
  File "/home/test/rope/rope/base/libutils.py", line 4, in ?
    import rope.base.project
  File "/home/test/rope/rope/base/project.py", line 8, in ?
    from rope.base import exceptions, taskhandle, prefs, history, pycore, utils
  File "/home/test/rope/rope/base/pycore.py", line 7, in ?
    import rope.base.oi.objectinfo
  File "/home/test/rope/rope/base/oi/objectinfo.py", line 4, in ?
    from rope.base.oi import objectdb, memorydb, transform
  File "/home/test/rope/rope/base/oi/transform.py", line 5, in ?
    import rope.base.builtins
  File "/home/test/rope/rope/base/builtins.py", line 4, in ?
    import rope.base.evaluate
  File "/home/test/rope/rope/base/evaluate.py", line 246
    return pyname.get_object() if pyname is not None else None
                                ^
SyntaxError: invalid syntax
[test@hp-dc5700-02 rope]$

'move' refactoring doesn't retain 'from' imports

If you run the program below from the top-level rope directory, you'll see that the 'from' import statements aren't retained. For example, this is what I get as part of the output:

--- a/build/lib.linux-x86_64-2.7/rope/contrib/codeassist.py
+++ b/build/lib.linux-x86_64-2.7/rope/contrib/codeassist.py
@@ -10,11 +10,11 @@
 from rope.base import pynames
 from rope.base import pynamesdef
 from rope.base import pyobjects
-from rope.base import pyobjectsdef
 from rope.base import pyscopes
 from rope.base import worder
 from rope.contrib import fixsyntax
 from rope.refactor import functionutils
+import rope.base.tmp.pyobjectsdef

I expect the new 'import' statement to be something like:

from rope.base.tmp import pyobjectsdef

Is this intentional?

#!/usr/bin/python

import os
import sys
from rope.base import fscommands
from rope.base import libutils
from rope.base import project
from rope.contrib import generate
from rope.refactor import move

ROOT = os.getcwd()

src_name = sys.argv[1]
dst_dir = sys.argv[2]
p = project.Project(ROOT, fscommands.create_fscommands(ROOT))
dst = libutils.path_to_resource(p, dst_dir)
if not dst.exists():
  dst = generate.create_package(p, PackageFromFolder(dst_dir))
print '*' * 10, src_name, '*' * 10
src = libutils.path_to_resource(p, src_name)
mover = move.create_move(p, src)
changes = mover.get_changes(dst)
print('changes:\n{}'.format(changes.get_description()))
$ python ./myrope.py rope/base/pyobjectsdef.py rope/base/tmp

crashes with "AttributeError: __abstractmethods__"

Running the attached script will reproduce the crash shown below. I'm using python 2.7.2 and rope tip (revision f5eb880e0be2).

Traceback (most recent call last):
  File "./ropebug.py", line 30, in <module>
    main()
  File "./ropebug.py", line 26, in main
    project.do(changes)
  File "/usr/lib/python2.7/site-packages/rope/base/project.py", line 72, in do
    self.history.do(changes, task_handle=task_handle)
  File "/usr/lib/python2.7/site-packages/rope/base/history.py", line 36, in do
    changes.do(change.create_job_set(task_handle, changes))
  File "/usr/lib/python2.7/site-packages/rope/base/change.py", line 66, in do
    change.do(job_set)
  File "/usr/lib/python2.7/site-packages/rope/base/change.py", line 126, in call
    function(self)
  File "/usr/lib/python2.7/site-packages/rope/base/change.py", line 150, in do
    self._operations.write_file(self.resource, self.new_contents)
  File "/usr/lib/python2.7/site-packages/rope/base/change.py", line 333, in write_file
    observer.resource_changed(resource)
  File "/usr/lib/python2.7/site-packages/rope/base/resourceobserver.py", line 30, in resource_changed
    self.changed(resource)
  File "/usr/lib/python2.7/site-packages/rope/base/pycore.py", line 67, in _file_changed_for_soa
    perform_soa_on_changed_scopes(self.project, resource, old_contents)
  File "/usr/lib/python2.7/site-packages/rope/base/pycore.py", line 365, in perform_soa_on_changed_scopes
    pycore.analyze_module(resource, should_analyze, search_subscopes)
  File "/usr/lib/python2.7/site-packages/rope/base/pycore.py", line 262, in analyze_module
    self, pymodule, should_analyze, search_subscopes, followed_calls)
  File "/usr/lib/python2.7/site-packages/rope/base/oi/soa.py", line 16, in analyze_module
    search_subscopes, followed_calls)
  File "/usr/lib/python2.7/site-packages/rope/base/oi/soa.py", line 36, in _analyze_node
    rope.base.ast.walk(child, visitor)
  File "/usr/lib/python2.7/site-packages/rope/base/ast.py", line 36, in walk
    walk(child, walker)
  File "/usr/lib/python2.7/site-packages/rope/base/ast.py", line 36, in walk
    walk(child, walker)
  File "/usr/lib/python2.7/site-packages/rope/base/ast.py", line 34, in walk
    return method(node)
  File "/usr/lib/python2.7/site-packages/rope/base/oi/soa.py", line 69, in _Call
    elif '__call__' in pyfunction:
  File "/usr/lib/python2.7/site-packages/rope/base/pyobjects.py", line 32, in __contains__
    return key in self.get_attributes()
  File "/usr/lib/python2.7/site-packages/rope/base/utils.py", line 10, in _wrapper
    setattr(self, name, func(self, *args, **kwds))
  File "/usr/lib/python2.7/site-packages/rope/base/builtins.py", line 81, in get_attributes
    result = _object_attributes(self.builtin, self)
  File "/usr/lib/python2.7/site-packages/rope/base/builtins.py", line 126, in _object_attributes
    child = getattr(obj, name)
AttributeError: __abstractmethods__

https://gist.github.com/7761145
https://gist.github.com/7761146

profile auto-completion

By @JulianEberius
The main changes I made to Rope concern auto-completion. It is very, very slow on large code bases (just try Rope’s completions on Rope’s code itself). I used Python’s profile module to track where the time is spent on a single completion request, and it was mainly file system related stuff that is called a lot of times for a single request. I added a lot of caching to my branch of Rope, but I didn’t fully check whether I introduced subtle bugs or changed semantics this way. It improved latency by several orders of magnitude, which was important as Sublime Text does „as-you-type“ autocompletion, so the operation needs to be performed in milliseconds (on almost every keystroke) even on large code bases.

Please see my commit on SublimePythonIDE for details, if you’re interested on tackling this problem (JulianEberius/SublimePythonIDE@85c490cd64). Sadly the commit intermingles the caching with a second, minor, issue: case-insensitive completions. Some people prefer to just type, and not to worry about lower/upper case if the completion engine can return the right thing anyway. As I said, this is minor, compared to the performance issues.

To tackle the problems systematically, it’s probably best if you to some profiling of your own, I just used cProfile and gprof2dot to make graphs… If the completion performance is improved I would love to just add Rope as a submodule, instead of maintaining my own fork.

Wheel packaging format for pypi.org

Would it be possible to get a .whl universal package on Pypi ?

If I'm right, it's just a matter of adding a setup.cfg file at root level with

[wheel]
universal = 1

and then doing this to upload to pypi

python setup.py sdist bdist_wheel upload -r pypi

AbstractFunction not defined

Using the current version:

    return rope.base.oi.soi.infer_assigned_object(self)
  File "/Library/Python/2.6/site-packages/rope-0.9.3-py2.6.egg/rope/base/utils.py", line 37, in newfunc
    return func(_args, *_kwds)
  File "/Library/Python/2.6/site-packages/rope-0.9.3-py2.6.egg/rope/base/oi/soi.py", line 61, in infer_assigned_object
    result = _infer_assignment(assignment, pyname.module)
  File "/Library/Python/2.6/site-packages/rope-0.9.3-py2.6.egg/rope/base/utils.py", line 37, in newfunc
    return func(_args, *_kwds)
  File "/Library/Python/2.6/site-packages/rope-0.9.3-py2.6.egg/rope/base/oi/soi.py", line 110, in _infer_assignment
    result = _follow_pyname(assignment, pymodule)
  File "/Library/Python/2.6/site-packages/rope-0.9.3-py2.6.egg/rope/base/utils.py", line 37, in newfunc
    return func(_args, *_kwds)
  File "/Library/Python/2.6/site-packages/rope-0.9.3-py2.6.egg/rope/base/oi/soi.py", line 141, in _follow_pyname
    pyname = evaluate.eval_node(holding_scope, assign_node)
  File "/Library/Python/2.6/site-packages/rope-0.9.3-py2.6.egg/rope/base/evaluate.py", line 25, in eval_node
    return eval_node2(scope, node)[1]
  File "/Library/Python/2.6/site-packages/rope-0.9.3-py2.6.egg/rope/base/evaluate.py", line 30, in eval_node2
    ast.walk(node, evaluator)
  File "/Library/Python/2.6/site-packages/rope-0.9.3-py2.6.egg/rope/base/ast.py", line 30, in walk
    return method(node)
  File "/Library/Python/2.6/site-packages/rope-0.9.3-py2.6.egg/rope/base/evaluate.py", line 286, in _Subscript
    self._call_function(node.value, '__getslice__')
  File "/Library/Python/2.6/site-packages/rope-0.9.3-py2.6.egg/rope/base/evaluate.py", line 296, in _call_function
    if not called or not isinstance(called, AbstractFunction):
NameError: global name 'AbstractFunction' is not defined

Ignored an exception in ropemode hook: NameError: global name 'AbstractFunction' is not defined

Rope 0.9.3 barfs on set-expressions

When using Python 2.7.1, and trying to rename a method, a ModuleSyntaxError is thrown.

Traceback (most recent call last):
  File "/Users/mahmoud/.emacs.d/languages/python/ropemode/decorators.py", line 53, in newfunc
    return func(*args, **kwds)
  File "/Users/mahmoud/.emacs.d/languages/python/ropemode/interface.py", line 52, in do_refactor
    refactoring(self, self.env).show(initial_asking=initial_asking)
  File "/Users/mahmoud/.emacs.d/languages/python/ropemode/refactor.py", line 43, in show
    changes = runtask(self.env, calculate, name=name)
  File "/Users/mahmoud/.emacs.d/languages/python/ropemode/refactor.py", line 469, in runtask
    return RunTask(env, command, name, interrupts)()
  File "/Users/mahmoud/.emacs.d/languages/python/ropemode/refactor.py", line 489, in __call__
    result = self.task(handle)
  File "/Users/mahmoud/.emacs.d/languages/python/ropemode/refactor.py", line 41, in calculate
    return self._calculate_changes(result, handle)
  File "/Users/mahmoud/.emacs.d/languages/python/ropemode/refactor.py", line 122, in _calculate_changes
    return self.renamer.get_changes(task_handle=task_handle, **values)
  File "/Users/mahmoud/.emacs.d/languages/python/rope/refactor/rename.py", line 95, in get_changes
    new_content = rename_in_module(finder, new_name, resource=file_)
  File "/Users/mahmoud/.emacs.d/languages/python/rope/refactor/rename.py", line 192, in rename_in_module
    for occurrence in occurrences_finder.find_occurrences(resource, pymodule):
  File "/Users/mahmoud/.emacs.d/languages/python/rope/refactor/occurrences.py", line 36, in find_occurrences
    result = filter(occurrence)
  File "/Users/mahmoud/.emacs.d/languages/python/rope/refactor/occurrences.py", line 160, in __call__
    if same_pyname(self.pyname, occurrence.get_pyname()):
  File "/Users/mahmoud/.emacs.d/languages/python/rope/base/utils.py", line 10, in _wrapper
    setattr(self, name, func(self, *args, **kwds))
  File "/Users/mahmoud/.emacs.d/languages/python/rope/refactor/occurrences.py", line 92, in get_pyname
    return self.tools.name_finder.get_pyname_at(self.offset)
  File "/Users/mahmoud/.emacs.d/languages/python/rope/base/utils.py", line 10, in _wrapper
    setattr(self, name, func(self, *args, **kwds))
  File "/Users/mahmoud/.emacs.d/languages/python/rope/refactor/occurrences.py", line 306, in name_finder
    return evaluate.ScopeNameFinder(self.pymodule)
  File "/Users/mahmoud/.emacs.d/languages/python/rope/base/utils.py", line 10, in _wrapper
    setattr(self, name, func(self, *args, **kwds))
  File "/Users/mahmoud/.emacs.d/languages/python/rope/refactor/occurrences.py", line 334, in pymodule
    return self.pycore.resource_to_pyobject(self.resource)
  File "/Users/mahmoud/.emacs.d/languages/python/rope/base/pycore.py", line 194, in resource_to_pyobject
    return self.module_cache.get_pymodule(resource, force_errors)
  File "/Users/mahmoud/.emacs.d/languages/python/rope/base/pycore.py", line 320, in get_pymodule
    force_errors=force_errors)
  File "/Users/mahmoud/.emacs.d/languages/python/rope/base/pyobjectsdef.py", line 152, in __init__
    source, node = self._init_source(pycore, source, resource)
  File "/Users/mahmoud/.emacs.d/languages/python/rope/base/pyobjectsdef.py", line 180, in _init_source
    raise exceptions.ModuleSyntaxError(filename, e.lineno, e.msg)
ModuleSyntaxError: Syntax error in file <tests/integration/controllers/test_users.py> line <272>: invalid syntax

When going to look at line 272 in test_users.py, it is a simple test case that's using set-expressions. I am documenting this here but I will most likely get around to either submitting a fix.

class TestUserControllerIndex(self):
    def setUp(self):
          self.user = make_user_fixture()

    def test_user_scores(self):
          self.assertEqual({score.id for score in self.user.scores}, {1})   # barfs here.

MismatchedTokenError when using "except ... as" syntax.

When trying to refactor in a file containing an except clause using the 'except ... as' syntax, Rope throws a MismatchedTokenError while parsing.

In the code sample below, attempting to extract line 3 (foo = [...]) as a method produces the given traceback.

Code sample:

class A:
    def spam(self):
        foo = [x**2 for x in range(10)]
        foo.reverse()
        return foo

try:
    print A().spam()
except Exception as e:
    print e

Environment:

  • Windows 7 32-bit
  • Python 2.7.2
  • EMACS 23.2
  • Rope 0.9.3
  • Pymacs 0.24b2 (g016b0bc)
  • ropemacs 0.6 (7af544334b85)
  • ropemode 0.1rc2 (584d3eba7ca6)

Traceback (from EMACS's Messages buffer):

Traceback (most recent call last):
  File "c:\Python27\lib\site-packages\ropemode\decorators.py", line 53, in newfunc
    return func(*args, **kwds)
  File "c:\Python27\lib\site-packages\ropemode\interface.py", line 52, in do_refactor
    refactoring(self, self.env).show(initial_asking=initial_asking)
  File "c:\Python27\lib\site-packages\ropemode\refactor.py", line 43, in show
    changes = runtask(self.env, calculate, name=name)
  File "c:\Python27\lib\site-packages\ropemode\refactor.py", line 469, in runtask
    return RunTask(env, command, name, interrupts)()
  File "c:\Python27\lib\site-packages\ropemode\refactor.py", line 489, in __call__
    result = self.task(handle)
  File "c:\Python27\lib\site-packages\ropemode\refactor.py", line 41, in calculate
    return self._calculate_changes(result, handle)
  File "c:\Python27\lib\site-packages\ropemode\refactor.py", line 298, in _calculate_changes
    global_=global_)
  File "c:\Python27\lib\site-packages\rope\refactor\extract.py", line 68, in get_changes
    new_contents = _ExtractPerformer(info).extract()
  File "c:\Python27\lib\site-packages\rope\refactor\extract.py", line 214, in extract
    extract_info = self._collect_info()
  File "c:\Python27\lib\site-packages\rope\refactor\extract.py", line 243, in _collect_info
    self._find_matches(extract_collector)
  File "c:\Python27\lib\site-packages\rope\refactor\extract.py", line 249, in _find_matches
    finder = similarfinder.SimilarFinder(self.info.pymodule)
  File "c:\Python27\lib\site-packages\rope\refactor\similarfinder.py", line 26, in __init__
    pymodule.source_code, pymodule.get_ast(), self._does_match)
  File "c:\Python27\lib\site-packages\rope\refactor\similarfinder.py", line 72, in __init__
    self._init_using_ast(node, source)
  File "c:\Python27\lib\site-packages\rope\refactor\similarfinder.py", line 81, in _init_using_ast
    patchedast.patch_ast(node, source)
  File "c:\Python27\lib\site-packages\rope\refactor\patchedast.py", line 33, in patch_ast
    ast.call_for_nodes(node, walker)
  File "c:\Python27\lib\site-packages\rope\base\ast.py", line 53, in call_for_nodes
    result = callback(node)
  File "c:\Python27\lib\site-packages\rope\refactor\patchedast.py", line 75, in __call__
    return method(node)
  File "c:\Python27\lib\site-packages\rope\refactor\patchedast.py", line 483, in _Module
    self._handle(node, list(node.body), eat_spaces=True)
  File "c:\Python27\lib\site-packages\rope\refactor\patchedast.py", line 103, in _handle
    ast.call_for_nodes(child, self)
  File "c:\Python27\lib\site-packages\rope\base\ast.py", line 53, in call_for_nodes
    result = callback(node)
  File "c:\Python27\lib\site-packages\rope\refactor\patchedast.py", line 75, in __call__
    return method(node)
  File "c:\Python27\lib\site-packages\rope\refactor\patchedast.py", line 563, in _TryExcept
    self._handle(node, children)
  File "c:\Python27\lib\site-packages\rope\refactor\patchedast.py", line 103, in _handle
    ast.call_for_nodes(child, self)
  File "c:\Python27\lib\site-packages\rope\base\ast.py", line 53, in call_for_nodes
    result = callback(node)
  File "c:\Python27\lib\site-packages\rope\refactor\patchedast.py", line 75, in __call__
    return method(node)
  File "c:\Python27\lib\site-packages\rope\refactor\patchedast.py", line 566, in _ExceptHandler
    self._excepthandler(node)
  File "c:\Python27\lib\site-packages\rope\refactor\patchedast.py", line 576, in _excepthandler
    self._handle(node, children)
  File "c:\Python27\lib\site-packages\rope\refactor\patchedast.py", line 115, in _handle
    region = self.source.consume(child)
  File "c:\Python27\lib\site-packages\rope\refactor\patchedast.py", line 638, in consume
    (token, self._get_location()))
MismatchedTokenError: Token <,> at (9, 16) cannot be matched

distutils is not part of Python's standard library.

Changeset [[https://bitbucket.org/agr/rope/changeset/b4e28f313b17|b4e28f313b17]] assumes distutils is installed, and that's not always the case, as distutils is not part of Python's standard library.

The change was for OS X specific workaround, but it should be enabled only for that platform (where distutils seems to be installed by default).

The older code was not ideal either, because it reported back the path to the stdlib of the interpreter actually running that function, and not the system wide interpreter.

Point in case: An editor that has an embedded Python interpreter, for which a plugin adds rope's support, would report, on Windows, for example, "python26.zip", while it would be better if it reported "c:\python26\libs" instead.

Maybe rope should allow this setting to be changed from the .ropeproject.py file. That seems the most general solution to me.

codeassist.code_assist will find spurious members of the os module

For a random module

#!python

>>> [proposal for proposal in codeassist.code_assist(proj, "import os\nos.", 13\
) if proposal.name in ['os2', 'ce', 'riscos', 'posix', 'nt']]
[os2 (imported, module), ce (imported, module), riscos (imported, module), posi\
x (imported, module), nt (imported, module)]

These are not actually defined in os.*. They are conditionally imported and deleted depending on which platform Python is run on. Rope finds them even though they are not exported from the os module.

I would not have expected to get completion proposals for symbols not actually defined.

(This is a minor concern, I am not sure how much effort it would be to fix.)

remove testutil.assert_raises

While working on PEP8ization of the code, I repeatedly hit testutil.assert_raises decorator. What is its purpose?

Unit tests should be clear and simple, easy to understand. I would remove testutil.assert_raises and just use plain self.assertRaises instead.

MismatchedTokenError when matching keyword splats

As far as I can tell, this only occurs when the code has a keyword splat after a regular splat and an explicit keyword argument in a function call. For example, when running a refactor on the file:

bar(*a, b=5, **c)

rope produces the error:

rope.refactor.patchedast.MismatchedTokenError: Token <a> at (1, 14) cannot be matched

which corresponds to the location of the ** keyword splat

If you remove the explicit keyword and run it on bar(*a, **c), everything is fine. If you remove the first splat (bar(a, b=5, **c)), it also works fine.

Environment:

  • Ubuntu 14.10
  • Python 2.7.8
  • master branch of Rope (installed via pip from github)

ImportError: could not import name UserDict

I was working with ropemacs and I got a traceback to the file /usr/lib/python2.7/site-packages/rope/base/oi/objectdb.py complaining that it couldn't import UserDict.

That file starts with "from collections import UserDict, MutableMapping". "from collections import UserDict" raises an exception on my machine (Fedora 16, python 2.7.2) so I changed the first lines of that file to:

from collections import MutableMapping

from UserDict import UserDict

And everything works fine so far.

Uncaught IndexError in code_assist

This code generates an IndexError. I would expect Rope to simply not return any completions.

import shutil
import tempfile

import rope.base.project
import rope.contrib.codeassist


project_root = tempfile.mkdtemp()
try:

    project = rope.base.project.Project(project_root)
    rope.contrib.codeassist.code_assist(
        project, """\                                                           
from .. import foo                                                              
        """, 18
    )

finally:
    shutil.rmtree(project_root)

Backtrace:

Traceback (most recent call last):
  File "foo.py", line 15, in <module>
    """, 18
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/contrib/codeassist.py", line 33, in code_assist
    return assist()
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/contrib/codeassist.py", line 321, in __call__
    completions = list(self._code_completions().values())
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/contrib/codeassist.py", line 399, in _code_completions
    return self._from_import_completions(pymodule)
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/contrib/codeassist.py", line 363, in _from_import_completions
    pymodule = self._find_module(pymodule, module_name)
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/contrib/codeassist.py", line 373, in _find_module
    while module_name[dots] == '.':
IndexError: string index out of range

[TEST] rename renames keyword args in function calls

hello,

I've written a test for rope that fails when a keyword argument to a function is the same as the name of the variable to be renamed, like this:

a = 10
foo = dict(a=a)

when a is renamed to new_a, the result will look like this:

new_a = 10
foo = dict(new_a=new_a)

This is the test case:

diff -r 1c100ebabc16 ropetest/refactor/renametest.py
--- a/ropetest/refactor/renametest.py   Sat Apr 09 17:20:27 2011 +0200
+++ b/ropetest/refactor/renametest.py   Tue May 10 00:48:39 2011 +0200
@@ -32,6 +32,11 @@
                   get_changes(new_name, **kwds)
         self.project.do(changes)

+    def test_local_variable_but_not_parameter(self):
+        code = "a = 10\nfoo = dict(a=a)"
+        refactored = self._local_rename(code, 1, "new_a")
+        self.assertEquals(refactored, "new_a = 10\nfoo = dict(a=new_a)")
+
     def test_simple_global_variable_renaming(self):
         refactored = self._local_rename('a_var = 20\n', 2, 'new_var')
         self.assertEquals('new_var = 20\n', refactored)

Thank you for this most excellent tool :)

  • Timo

ropemode is unusable with unicode

source files are with encoding: utf8

most docstrings contains utf and specified like u"""юникод"""

emacs command rope-move-current-module -- review fails:
{{{
File "/usr/lib/python2.7/dist-packages/ropemode/refactor.py", line 48, in show
diffs = str(changes.get_description())
UnicodeEncodeError: 'ascii' codec can't encode characters in position 1669-1682: ordinal not in range(128)
}}}

Uncaught LookupError with an unknown coding: line

The following code produces an uncaught LookupError. I would expect Rope to produce a ModuleSyntaxError, as it does when the string passed to code_assist is str and not unicode.

import shutil
import tempfile

import rope.base.project
import rope.contrib.codeassist


project_root = tempfile.mkdtemp()
try:

    project = rope.base.project.Project(project_root)
    rope.contrib.codeassist.code_assist(
        project, u"""\                                                          
# coding: utf-8X                                                                
        """, 0, maxfixes=5
    )

finally:
    shutil.rmtree(project_root)

Backtrace:

Traceback (most recent call last):
  File "foo.py", line 15, in <module>
    """, 0, maxfixes=5
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/contrib/codeassist.py", line 33, in code_assist
    return assist()
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/contrib/codeassist.py", line 321, in __call__
    completions = list(self._code_completions().values())
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/contrib/codeassist.py", line 390, in _code_completions
    pymodule = fixer.get_pymodule()
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/base/utils.py", line 11, in _wrapper
    setattr(self, name, func(self, *args, **kwds))
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/contrib/fixsyntax.py", line 28, in get_pymodule
    code, resource=self.resource, force_errors=True)
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/base/pycore.py", line 114, in get_string_module
    return PyModule(self, code, resource, force_errors=force_errors)
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/base/pyobjectsdef.py", line 155, in __init__
    source, node = self._init_source(pycore, source, resource)
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/base/pyobjectsdef.py", line 179, in _init_source
    source_bytes = fscommands.unicode_to_file_data(source_code)
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/base/fscommands.py", line 196, in unicode_to_file_data
    return contents.encode(encoding)
LookupError: unknown encoding: utf-8X

ImportedModule always assumes paths to be relative to current resource

I'm using rope inside SublimeRope and have a project that consists of several namespaces, all available on python path. While rope properly indexes those, it cannot resolve ImportedModule nodes pointing from one package to another as with a non-zero level only a relative import will be attempted.

I have changed the local implementation to instead try relative first and fall back to absolute if needed:

class ImportedModule(PyName):

    # ...

    def _get_pymodule(self):
        if self.pymodule.get() is None:
            pycore = self.importing_module.pycore
            if self.resource is not None:
                self.pymodule.set(pycore.resource_to_pyobject(self.resource))
            elif self.module_name is not None:
                try:
                    pymodule = None
                    if self.level > 0:
                        try:
                            pymodule = pycore.get_relative_module(
                                self.module_name, self._current_folder(),
                                self.level)
                        except exceptions.ModuleNotFoundError:
                            pass
                    if pymodule is None:
                        pymodule = pycore.get_module(self.module_name,
                                                     self._current_folder())
                    self.pymodule.set(pymodule)
                except exceptions.ModuleNotFoundError:
                    pass
        return self.pymodule.get()

AttributeError: 'NoneType' object has no attribute 'parent' in get_calltip

The following code generates an AttributeError. I would expect Rope to simply not return any call tips.

import shutil
import tempfile

import rope.base.project
import rope.contrib.codeassist


project_root = tempfile.mkdtemp()
try:

    project = rope.base.project.Project(project_root)
    rope.contrib.codeassist.get_calltip(
        project, """\                                                           
from .. import foo                                                              
        """, 18
    )

finally:
    shutil.rmtree(project_root)

Backtrace:

Traceback (most recent call last):
  File "foo.py", line 15, in <module>
    """, 18
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/contrib/codeassist.py", line 95, in get_calltip
    pyobject = pyname.get_object()
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/base/utils.py", line 28, in newfunc
    return func(self, *args, **kwds)
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/base/pynames.py", line 159, in get_object
    return self._get_imported_pyname().get_object()
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/base/pynames.py", line 150, in _get_imported_pyname
    result = self.imported_module.get_object()[self.imported_name]
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/base/pynames.py", line 131, in get_object
    if self._get_pymodule() is None:
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/base/pynames.py", line 124, in _get_pymodule
    self.level)
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/base/pycore.py", line 101, in get_relative_module
    module = self.find_relative_module(name, folder, level)
  File "/home/forcer/.virtualenvs/elpy/local/lib/python2.7/site-packages/rope/base/pycore.py", line 161, in find_relative_module
    folder = folder.parent
AttributeError: 'NoneType' object has no attribute 'parent'

0.10.1 doesn't install: can't find README.rst

I attempted to install the latest rope from PyPI:

georgevreilly@georges-mbp:~/src/main$ (feature/recipe-eagerload) pip install -U rope
Downloading/unpacking rope from https://pypi.python.org/packages/source/r/rope/rope-0.10.1.tar.gz#md5=0a89f6ae0f95a802ac7d8cf27523964d
  Downloading rope-0.10.1.tar.gz (197kB): 197kB downloaded
  Running setup.py (path:/private/var/folders/2t/tx6brjtj21vfs98xcmfq1jvr0000gn/T/pip_build_georgevreilly/rope/setup.py) egg_info for package rope
    Traceback (most recent call last):
      File "<string>", line 17, in <module>
      File "/private/var/folders/2t/tx6brjtj21vfs98xcmfq1jvr0000gn/T/pip_build_georgevreilly/rope/setup.py", line 50, in <module>
        long_description=get_long_description(),
      File "/private/var/folders/2t/tx6brjtj21vfs98xcmfq1jvr0000gn/T/pip_build_georgevreilly/rope/setup.py", line 43, in get_long_description
        lines = open('README.rst').read().splitlines(False)
    IOError: [Errno 2] No such file or directory: 'README.rst'
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):

  File "<string>", line 17, in <module>

  File "/private/var/folders/2t/tx6brjtj21vfs98xcmfq1jvr0000gn/T/pip_build_georgevreilly/rope/setup.py", line 50, in <module>

    long_description=get_long_description(),

  File "/private/var/folders/2t/tx6brjtj21vfs98xcmfq1jvr0000gn/T/pip_build_georgevreilly/rope/setup.py", line 43, in get_long_description

    lines = open('README.rst').read().splitlines(False)

IOError: [Errno 2] No such file or directory: 'README.rst'

----------------------------------------
Cleaning up...
Command python setup.py egg_info failed with error code 1 in /private/var/folders/2t/tx6brjtj21vfs98xcmfq1jvr0000gn/T/pip_build_georgevreilly/rope

I cloned the repo and ran python setup.py install; 0.10.2 installed successfully.

Support Python 3.3+

Modernize rope to install and run on Python 3 versions 3.3 and newer. See python-future (prefered) or six for a single-codebase route to support Python 2 and Python 3.

undefined name 'ModuleSkipHandle'

In move.py we have:

class ModuleSkipRenamer(object):                                                
    """Rename occurrences in a module                                           

    This class can be used when you want to treat a region in a file            
    separately from other parts when renaming.                                  

    """                                                                         

    def __init__(self, occurrence_finder, resource, handle=None,                
                 skip_start=0, skip_end=0, replacement=''):                     
        """Constructor                                                          

        if replacement is `None` the region is not changed.  Otherwise          
        it is replaced with `replacement`.                                      

        """                                                                     
        self.occurrence_finder = occurrence_finder                              
        self.resource = resource                                                
        self.skip_start = skip_start                                            
        self.skip_end = skip_end                                                
        self.replacement = replacement                                          
        self.handle = handle                                                    
        if self.handle is None:                                                 
            # ERROR: ModuleSkipHandle is UNDEFINED!!!                           
            self.handle = ModuleSkipHandle()                                    

source_folders config does not work with symlinks

Since making rope-auto-import work with stuff outside of the project folder has been impossible for me so far, I've tried instead using the source_folders config to add more stuff to the project.

I tried to do this using symlinks (because folders cannot be hardlinked and I don't want to copy them), but this didn't work.

It turns out that symlinks are simply ignored by rope. If I copy the code to a subfolder of the project and add that folder to source_folders, it works.

My current workaround is to make a directory hardlink, which however is not possible with the default ln command (at least under OS X) so I have to resort to http://stackoverflow.com/questions/1432540/creating-directory-hard-links-in-macos-x.

non-testing tests

We have many many tests like:

    def test_validation_problems_for_changing_builtin_types(self):
        mod1 = testutils.create_module(self.project, 'mod1')
        mod1.write('l = []\nl.append("")\n')
        self.pycore.analyze_module(mod1)

        mod1.write('l = {}\nv = l["key"]\n')
        pymod1 = self.pycore.resource_to_pyobject(mod1)  # noqa
        var = pymod1['v'].get_object()

They actually don't test anything, only that the run code won’t crash, but even if it doesn’t generate any (or faulty) results, it would pass.

Allow PEP8 import re-organization

PEP8 should be followed when re-organizing imports, meaning that if there are lots of imports, they shouldn't exceed the 80 character limit.

Also, there should be a configuration option that allows a one-import per line.

goto definition misses package with common namespace in a different egg

In the attached example, we have two packages, in two different eggs, sharing a common namespace:

  • base.one (in egg //one//)
  • base.two (in egg //two//)

We configured the ropeproject to include both their directories in the python_path by adding to src/.ropeproject/config.py:

def set_prefs(prefs):
(...)
    prefs.add('python_path', '/home/mazza/work/bug_ropemacs/one')
    prefs.add('python_path', '/home/mazza/work/bug_ropemacs/two')

Then, in the module //sample.py//, that imports both //one// and //two//, we try the operation "go to definition" (in emacs //M-x rope-goto-definition//) on each of them. But it only works for the first one added to //python_path//

For the config.py lines above, //rope-goto-definition// will only work over //one//. If you swap the lines in config.py:

def set_prefs(prefs):
(...)
    prefs.add('python_path', '/home/mazza/work/bug_ropemacs/two')
    prefs.add('python_path', '/home/mazza/work/bug_ropemacs/one')

then //rope-goto-definition// will only work over //two//.

Note:

In the attached source tar, you should change the absolute paths for packages "one" and "two" in the files:

  • bug_ropemacs/src/sample.py
  • bug_ropemacs/src/.ropeproject/config.py

(I filed the bug here and not in ropemacs, because I feel it to be related to rope itself.)

http://mcepl.fedorapeople.org/tmp/bug_ropemacs.mazza-laptop.2012-03-25.1947.tar

test ropetest.refactor.importutilstest.ImportUtilsTest.test_sorting_imports_and_standard_modules2 fails

Run

$ python -munittest -v \
ropetest.refactor.importutilstest.ImportUtilsTest.test_sorting_imports_and_standard_modules2

The test fails (with additional debugging logs):

matej@wycliff: rope (fix_ImportUtilsTest)$ python -munittest -v ropetest.refactor.importutilstest.ImportUtilsTest.test_sorting_imports_and_standard_modules2
test_sorting_imports_and_standard_modules2 (ropetest.refactor.importutilstest.ImportUtilsTest) ... DEBUG:test_sorting_imports_and_standard_modules2:pymod = dir [&lt;_ast.Import object at 0x240e5d0&gt;, &lt;_ast.Import object at 0x240e650&gt; ]
DEBUG:get_changed_source:first_non_blank = 3
DEBUG:get_changed_source:result = []
DEBUG:get_changed_source:sorted_imports = [&lt;rope.refactor.importutils.importinfo.ImportStatement object at 0x240e990&gt;, &lt;rope.refactor.importutils.importinfo.ImportStatement object at 0x240ea10&gt;]
DEBUG:get_changed_source:result = [u'import sys\n', '\n', u'import time\n']
DEBUG:get_changed_source:first_after_imports = 3
DEBUG:get_changed_source:result = [u'import sys\n', '\n', u'import time\n']
expected:
import sys
import time

observed:
import sys

import time

FAIL

======================================================================
FAIL: test_sorting_imports_and_standard_modules2 (ropetest.refactor.importutilstest.ImportUtilsTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "ropetest/refactor/importutilstest.py", line 719, in test_sorting_imports_and_standard_modules2
    self.assertEquals(expected, observed)
AssertionError: 'import sys\nimport time\n' != u'import sys\n\nimport time\n'

----------------------------------------------------------------------
Ran 1 test in 0.039s

FAILED (failures=1)
matej@wycliff: rope (fix_ImportUtilsTest)$

It really looks to me like if the problem was with tests and the expected string.

OrganizeImports removes entire lines

This is what Rope (using the Vim plugin) does when applying the RopeOrganizeImports command:

 import re
 from datetime import datetime
+
+from django.core.exceptions import ObjectDoesNotExist
 from django.db import models
-from djangosphinx.models import SphinxSearch
-from django.core.exceptions import ObjectDoesNotExist
 from django.db.models import Q
-from django.contrib.auth.models import User
+from django.template.loader import render_to_string
 from django.utils.safestring import mark_safe
 from django.utils.translation import ugettext as _
-from apps.users import signals
-from django.template.loader import render_to_string
+from djangosphinx.models import SphinxSearch

If you look at the changes, you can see that "from django.contrib.auth.models import User" as well as "from apps.users import signals" were completely removed instead of moved.

  • The signals import was removed because it wasn't used. I don't want it to be removed though, as the import has intentional side effects.
  • The User import was removed even though the User module is used in the code.

JobSet.finished_job incriments self.done too late

While no one was looking, Lex Luthor took JobSet's ability to be 100% done in the eyes of observing functions. He took JobSet's ability to be one hundred percent done in the eyes of observing functions. That's as many as ten ten percents. And that's terrible.

Read: Because self.done is incremented after self.handle._inform_observers() an observing function will never see JobSet.get_percent_done() == 100.

https://gist.github.com/7761137

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.