-
-
Notifications
You must be signed in to change notification settings - Fork 711
Description
When jedi is activated, the IPython tab completion tries to access the __module__ attribute of the tab-completed object
sage: ip = get_ipython()
sage: ip.Completer.use_jedi = True
sage: cython("""
....: cdef class A(object):
....: def __getattr__(self, key):
....: print('getattr(key={})'.format(key))
....: raise AttributeError
....: """)
sage: my_custom_name = A()
sage: ip.Completer.all_completions("my_custo")
getattr(key=__module__)
getattr(key=__module__)
['my_custom_name']
Note that this is very specific to extension classes and works fine with plain Python classes.
You can see here that it is specific to jedi
sage: ip.Completer.use_jedi = False
sage: ip.Completer.all_completions("my_cu")
['my_custom_name']
This access to the __module__ attribute has dramatic consequence with lazily imported objects that gets imported when accessing any attribute including __module__. In the following example, it even leads to a Sage crash on 9.2.rc3 because of badly designed lazy import
sage: ip.Completer.all_completions("s")
Traceback (most recent call last):
...
AttributeError: module 'sage.coding.linear_code' has no attribute 'self_orthogonal_binary_codes'
Here is the full trace of the calls that lead to the access of __module__ in the first example above
File "/opt/sage/src/bin/sage-ipython", line 16, in <module>
app.start()
File "/opt/sage/local/lib/python3.9/site-packages/IPython/terminal/ipapp.py", line 356, in start
self.shell.mainloop()
File "/opt/sage/local/lib/python3.9/site-packages/IPython/terminal/interactiveshell.py", line 563, in mainloop
self.interact()
File "/opt/sage/local/lib/python3.9/site-packages/IPython/terminal/interactiveshell.py", line 554, in interact
self.run_cell(code, store_history=True)
File "/opt/sage/local/lib/python3.9/site-packages/IPython/core/interactiveshell.py", line 2866, in run_cell
result = self._run_cell(
File "/opt/sage/local/lib/python3.9/site-packages/IPython/core/interactiveshell.py", line 2895, in _run_cell
return runner(coro)
File "/opt/sage/local/lib/python3.9/site-packages/IPython/core/async_helpers.py", line 68, in _pseudo_sync_runner
coro.send(None)
File "/opt/sage/local/lib/python3.9/site-packages/IPython/core/interactiveshell.py", line 3071, in run_cell_async
has_raised = await self.run_ast_nodes(code_ast.body, cell_name,
File "/opt/sage/local/lib/python3.9/site-packages/IPython/core/interactiveshell.py", line 3263, in run_ast_nodes
if (await self.run_code(code, result, async_=asy)):
File "/opt/sage/local/lib/python3.9/site-packages/IPython/core/interactiveshell.py", line 3343, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-13-e16cd8a94897>", line 1, in <module>
ip.Completer.all_completions("my_cu")
File "/opt/sage/local/lib/python3.9/site-packages/IPython/core/completer.py", line 1148, in all_completions
return ['.'.join([prefix, c.text]) if prefix and self.use_jedi else c.text
File "/opt/sage/local/lib/python3.9/site-packages/IPython/core/completer.py", line 1148, in <listcomp>
return ['.'.join([prefix, c.text]) if prefix and self.use_jedi else c.text
File "/opt/sage/local/lib/python3.9/site-packages/IPython/core/completer.py", line 1818, in completions
for c in self._completions(text, offset, _timeout=self.jedi_compute_type_timeout/1000):
File "/opt/sage/local/lib/python3.9/site-packages/IPython/core/completer.py", line 1868, in _completions
type_ = jm.type
File "/opt/sage/local/lib/python3.9/site-packages/jedi/api/classes.py", line 759, in type
return super(Completion, self).type
File "/opt/sage/local/lib/python3.9/site-packages/jedi/api/classes.py", line 192, in type
return self._name.api_type
File "/opt/sage/local/lib/python3.9/site-packages/jedi/inference/names.py", line 612, in __getattr__
return getattr(self._wrapped_name, name)
File "/opt/sage/local/lib/python3.9/site-packages/jedi/inference/compiled/value.py", line 354, in api_type
api = self.infer()
File "/opt/sage/local/lib/python3.9/site-packages/jedi/cache.py", line 111, in wrapper
result = method(self, *args, **kwargs)
File "/opt/sage/local/lib/python3.9/site-packages/jedi/inference/compiled/value.py", line 362, in infer
return ValueSet([self.infer_compiled_value()])
File "/opt/sage/local/lib/python3.9/site-packages/jedi/inference/compiled/value.py", line 365, in infer_compiled_value
return create_from_name(self._inference_state, self._parent_value, self.string_name)
File "/opt/sage/local/lib/python3.9/site-packages/jedi/inference/compiled/value.py", line 591, in create_from_name
access_paths = compiled_value.access_handle.getattr_paths(name, default=None)
File "/opt/sage/local/lib/python3.9/site-packages/jedi/inference/compiled/subprocess/__init__.py", line 400, in _workaround
return self._cached_results(name, *args, **kwargs)
File "/opt/sage/local/lib/python3.9/site-packages/jedi/cache.py", line 111, in wrapper
result = method(self, *args, **kwargs)
File "/opt/sage/local/lib/python3.9/site-packages/jedi/inference/compiled/subprocess/__init__.py", line 404, in _cached_results
return self._subprocess.get_compiled_method_return(self.id, name, *args, **kwargs)
File "/opt/sage/local/lib/python3.9/site-packages/jedi/inference/compiled/subprocess/functions.py", line 24, in get_compiled_method_return
return getattr(handle.access, attribute)(*args, **kwargs)
File "/opt/sage/local/lib/python3.9/site-packages/jedi/inference/compiled/access.py", line 391, in getattr_paths
module = inspect.getmodule(return_obj)
File "/usr/lib/python3.9/inspect.py", line 731, in getmodule
if hasattr(object, '__module__'):
Upstream: Not yet reported upstream; Will do shortly.
CC: @kliem
Component: misc
Issue created by migration from https://trac.sagemath.org/ticket/31643