2016-06-07 9 views
10

Я построил простой текстовый редактор с некоторой возможностью доступа для программного обеспечения для чтения экрана. Я использую Python для .NET (pythonnet), чтобы показать форму, содержащую богатое текстовое поле. Когда пользователь нажимает вкладку после периода, она всплывает контекстное меню с пополнениями для выбранного элемента. Хорошо, он отлично работает с объектами Python, но он не работает с .net-живыми объектами, нет решения этой проблемы. Теперь я хочу создать объект TreeView со всеми именами и определениями модуля, который я редактирую.python jedi: как получить методы экземпляров?

Так, например, я типа:

import sys 
import os 
lst = list() 

и т.д ... Если я использую jedi.names моего источника, я могу восстановить ОС, SYS и LST. Для каждого имени я хочу получить вспомогательные определения, такие как функции для sys и os module, а также методы для lst. я не могу найти способ сделать это с джедая:

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(). 

Есть предложения? Я пытался использовать все больше и больше редакторов, но поддержка людей с ограниченными возможностями очень очень плохо ...

+0

Что такое объект 'MySource'? – denfromufa

+1

Вы не ожидаете увидеть какие-либо автозавершения для 'import sys', это полный оператор. Однако, если это было «от sys import», тогда вы ожидаете некоторые автоматические полные параметры. –

+1

@denfromufa, я думаю, 'MySource' - это просто строка, содержащая исходный код, показанный в первом блоке кода. –

ответ

6

Это выглядит как ошибка, где jedi.evaluate.representation.Instance.__getattr__() ошибочно блоков оценка .names_dict. Я добавил pull request в репозиторий jedi, чтобы исправить это. В то же время вы можете добавить «names_dict» в whitelist in Instance.__getattr__() в свою копию jedi/evaluate/representation.py или использовать следующий код для автоматического исправления этого метода для текущего сеанса.

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() 

Я должен отметить, что я не знаком с jedi, так что я не знаю defined_names() предполагается ли работать на определениях, которые создают экземпляры. В приведенном выше коде не будут исправлены ссылки, такие как jedi.names("lst = []")[0].defined_names(), и для этого нет очевидного патча. Так что может быть что-то более глубокое, о чем я не знаю. Надеюсь, разработчик поможет установить это прямо в ответ на этот запрос на растяжение.