I built simple text editor with some accessibility feature for screen reading software. I'm using Python for .NET (pythonnet) to show a form containing a rich text box. When user press tab after a period it pop-ups a context menu with completions for selected element. Ok, it works fine with Python objects, but it doesn't work with .net live objects, there is no solution to this problem. Now, I want build a TreeView object with all names and definitions of module I'm editing.
So, for example I type:
import sys
import os
lst = list()
etc... If I use jedi.names of my source, I can retrieve os, sys and lst. For each name, I want retrieve sub definitions, such as functions for sys and os module, and methods for lst. I can't find a way to do this with jedi:
names = jedi.names(MySource)
names[0].defined_names() # works for sys
names[1].defined_names() # works for os
names[2].defined_names() # doesn't work for lst instance of list().
Any suggestions? I tried to use more and more editors, but accessibility support is very very bad...
This looks like a bug, where jedi.evaluate.representation.Instance.__getattr__()
mistakenly blocks evaluation of .names_dict
. I added a pull request to the jedi repository to fix this. In the mean time, you can either add 'names_dict' to the whitelist in Instance.__getattr__()
in your copy of jedi/evaluate/representation.py
, or use the code below to patch this method automatically for the current session.
import jedi
def patch_jedi():
__old__getattr__ = jedi.evaluate.representation.Instance.__getattr__
def __patched__getattr__(self, name):
if name == 'names_dict':
# do a simplified version of __old__getattr__, bypassing the name check
return getattr(self.base, name)
else:
# use standard behavior
return __old__getattr__(self, name)
# test whether jedi has been updated to avoid the Instance.defined_names() bug
try:
jedi.names("lst = list()")[0].defined_names()
except AttributeError as e:
if e.args[0].startswith("Instance ") and e.args[0].endswith("Don't touch this (names_dict)!"):
# patch jedi to avoid this error
print "patching jedi"
jedi.evaluate.representation.Instance.__getattr__ = __patched__getattr__
else:
# something else strange is going on
raise
patch_jedi()
print jedi.names("lst = list()")[0].defined_names()
# or: print jedi.Script("lst = list()").goto_definitions()[0].defined_names()
I should note that I'm not familiar with jedi
, so I don't know whether defined_names()
is supposed to work for definitions that create instances. The code above won't fix references like jedi.names("lst = []")[0].defined_names()
, and there's no obvious patch to do that. So there may be something deeper going on that I don't know about. Hopefully the developer will help set this straight in response to that pull request.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With