Джедай Python: как получить методы экземпляров?

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

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

import sys
import os
lst = list()

и т.д... Если я использую jedi.name моего источника, я могу получить os, sys и lst. Для каждого имени я хочу получить подопределения, такие как функции для модуля sys и os и методы для 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().

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

1 ответ

Решение

Это похоже на ошибку, где jedi.evaluate.representation.Instance.__getattr__() ошибочно блокирует оценку .names_dict, Я добавил запрос на удаление в репозиторий джедаев, чтобы это исправить. В то же время, вы можете добавить 'names_dict' в белый список в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()и нет очевидного патча для этого. Так что, может быть, происходит нечто более глубокое, о чем я не знаю. Надеюсь, разработчик поможет исправить это в ответ на этот запрос.

Другие вопросы по тегам