python-rope / rope Goto Github PK
View Code? Open in Web Editor NEWa python refactoring library
License: GNU Lesser General Public License v3.0
a python refactoring library
License: GNU Lesser General Public License v3.0
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
test_new_style_relative_imports fails with Python 2.7 (and passes with Python 2.6).
The code that reads the "source_folders" preference expects a list of Folder objects, rather than the path strings the example suggests.
We have on the Bitbucket also:
Not much to be added.
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 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
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
(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
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()
They should point to the right places (mostly here on GitHub).
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.
Exit status of ropetest/init.py should be non-zero when there have been any test failures.
Misreported by an anonymous party in the tracker for Bitbucket itself:
http://bitbucket.org/jespern/bitbucket/issue/571/python-error-while-aborting-the-open-project
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()
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 :)
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
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.
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.
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
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
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:
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
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.
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.
In the attached example, we have two packages, in two different eggs, sharing a common namespace:
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:
(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
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.
i just noticed that the inline refactoring doesnt touch unused imports, even if the function/constant they import got inlined
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
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.
@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?
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
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"
If there are non-ascii chars in a docstring you'll get a unicode error. jedi-vim seems to know how manipulate the unicode repr:
https://github.com/davidhalter/jedi-vim/blob/master/plugin/jedi_vim.py#L16
(I'm using rope in the context of vim python mode and it appears to be up to date
https://github.com/klen/python-mode)
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.
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:
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
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]$
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:
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'
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
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.
Say your project only has 1 test.py file that looks like this:
from package import some_name
__all__ = ["some_name"]
After reorganizing imports the from ... import ... line is gone. It should stay.
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.
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.)
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)
}}}
in one of my projects we use some custom import statement ordering,
the inline refactoring just reordering those it doesn't need to touch seems invasive
Download them here as a branch and present them to the group.
I'd like to add a link to the traad project from the rope home page. Traad is here:
https://github.com/abingham/traad
It's a client-server API on top of traad, bundled with emacs lisp client code (with hopefully more coming in the future.)
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 [<_ast.Import object at 0x240e5d0>, <_ast.Import object at 0x240e650> ]
DEBUG:get_changed_source:first_non_blank = 3
DEBUG:get_changed_source:result = []
DEBUG:get_changed_source:sorted_imports = [<rope.refactor.importutils.importinfo.ImportStatement object at 0x240e990>, <rope.refactor.importutils.importinfo.ImportStatement object at 0x240ea10>]
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.
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
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.