Emacs autocomplete and Dependency injection (DI)

В пассивных классах, которым зависимости внедряет программа, возникают трудности с автокомплитом в emacs с elpy-mode.

Вариантов решения здесь несколько.

  1. Устанавливать зависимости через конструктор класса, учитывая, что бэкенд jedi учитывает типы аргументов функций и возвращаемых значений, указанных в строках документирования.
  2. Устанавливать зависимость через метод установки (setter). Причем, не обязательно, чтобы этот метод использовался, достаточно просто объявить его в классе и прописать в строке документирования тип аргумента.
  3. Получать зависимость через метод доступа (getter). В отличии от первых двух вариантов, работать будет декларация типов возвращаемых значений, а не аргументов.
  4. Использовать Service Locator или паттерн Plugin, которые инициируют запрос и делегируют его исполнение резольверу зависимостей.

В случае с rope вместо декларации типов аргументов в строках документирования можно использовать Dynamic Object Analysis.

Но мы пойдем самым сложным путем, и заставим emacs решать эту проблему.

Итак.

1. Стартуем интерпретатор M-x run-python (предварительно настраиваем elpy на использование ipython чтобы автокомплит работал и в шеле тоже):

(when (executable-find "ipython") (elpy-use-ipython))

2. посылаем в интерпретатор файл с которым работаем: M-x python-shell-send-file.

3. определяем в интерпретаторе переменную, которая нужна. В моем случае нужна self.dao.engine. Делаем в шелле что-то типа self = StatsFactory().make_api() у которого по счастливому стечению обстоятельств есть атрибут .dao.engine, который мне и нужен.

В итоге в интерпретаторе будет объявлена переменная self.dao.engine.

4. Поскольку elpy заглушает вызов completion-at-point в выпадающем окне company-mode, вызываем вручную M-x completion-at-point или M-x python-shell-completion-complete-or-indent.

Чтобы не вызывать вручную, биндим их на любую удобную комбинацию клавиш, например “C-c TAB”.

5. Таким образом можно автокомплитить любые недостающие переменные, - просто объявляем их в интерпретаторе, и они будут подсказываться в буфере редактирования файла.

P.S.: это старейшая возможность питон-мода, которая лего забывается из-за наличия jedi и rope)) IDLE работает по аналогичному принципу.

P.P.S.: ropemacs-mode должен быть выключен, если он установлен. Можно не выключать, а просто снять 'ropemacs-completion-at-point с 'ropemacs-mode-hook:

(add-hook 'ropemacs-mode-hook (lambda ()
  (if ropemacs-mode
      (remove-hook 'completion-at-point-functions 'ropemacs-completion-at-point t))
))

Updated on Jan 03, 2016

Добавил в forked rope поддержку подсказок типов в строках документирования для параметров функций, возвращаемого значения и атрибутов класса.

Updated on Jan 05, 2016

Добавил в forked rope поддержку подсказок типов на основании комментирования типов согласно PEP 0484 для присваиваний.

Updated on Feb 16, 2016

Форк принят в мастер (bd89775).

Updated on Nov 29, 2016

Реализация Type Hinting существенно переработана.

Comments