2016-06-07 12 views
10

Zbudowałem prosty edytor tekstu z pewną dostępną funkcją do odczytu ekranu. Korzystam z Python dla .NET (pythonnet), aby wyświetlić formularz zawierający pole tekstowe. Po naciśnięciu klawisza tabulacji po kropce pojawia się menu kontekstowe z uzupełnieniami dla wybranego elementu. Ok, działa dobrze z obiektami Python, ale nie działa z obiektami żywymi .net, nie ma rozwiązania tego problemu. Teraz chcę zbudować obiekt TreeView ze wszystkimi nazwami i definicjami modułu, który edytuję.python jedi: jak odzyskać metody instancji?

Tak więc, na przykład I typ:

import sys 
import os 
lst = list() 

etc ... Jeśli używam jedi.names mojego źródła, mogę odzyskać OS, SYS i LST. Dla każdej nazwy chcę pobrać definicje podrzędne, takie jak funkcje dla modułu sys i os oraz metody dla lst. nie mogę znaleźć sposób, aby to zrobić z 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(). 

sugestie? Próbowałem używać coraz więcej edytorów, ale obsługa dostępności jest bardzo zła ...

+0

Co to jest obiekt "MySource"? – denfromufa

+1

Nie spodziewałbyś się żadnych automatycznych uzupełnień dla 'import sys', To kompletna instrukcja. Jednak jeśli był "od sys import", to można oczekiwać niektórych opcji automatycznego uzupełniania. –

+1

@denfromufa, myślę, że 'MySource' to tylko ciąg zawierający kod źródłowy pokazany w pierwszym bloku kodu. –

Odpowiedz

6

To wygląda jak błąd, gdzie jedi.evaluate.representation.Instance.__getattr__() omyłkowo blokuje ocenę .names_dict. Dodałem pull request do repozytorium jedi, aby to naprawić. W międzyczasie możesz dodać "names_dict" do whitelist in Instance.__getattr__() w swojej kopii jedi/evaluate/representation.py lub użyć poniższego kodu, aby automatycznie zaszyfrować tę metodę dla bieżącej sesji.

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

Należy zauważyć, że nie jestem zaznajomiony z jedi, więc nie wiem, czy defined_names() ma pracować na definicjach, które tworzą instancje. Powyższy kod nie naprawi odwołań takich jak jedi.names("lst = []")[0].defined_names() i nie ma na to oczywistej łatki. Więc może być coś głębszego, o czym nie wiem. Mam nadzieję, że programista pomoże to ustawić w odpowiedzi na żądanie ściągnięcia.