diff --git a/elpy/jedibackend.py b/elpy/jedibackend.py index e33d3e8a2..940ffbd74 100644 --- a/elpy/jedibackend.py +++ b/elpy/jedibackend.py @@ -46,7 +46,7 @@ def rpc_get_completions(self, filename, source, offset): for proposal in proposals) return [{'name': proposal.name.rstrip("="), 'suffix': proposal.complete.rstrip("="), - 'annotation': proposal.type, + 'annotation': get_annotation(proposal), 'meta': proposal.description} for proposal in proposals] @@ -263,7 +263,13 @@ def rpc_get_oneline_docstring(self, filename, source, offset): else: onelinedoc = onelinedoc[0] if onelinedoc == '': - onelinedoc = "No documentation" + if definition.type == "instance": + try: + onelinedoc = definition.get_type_hint() + except AttributeError: + onelinedoc = "No documentation" + else: + onelinedoc = "No documentation" return {"name": name, "doc": onelinedoc} return None @@ -362,6 +368,17 @@ def linecol_to_pos(text, line, col): return offset +def get_annotation(proposal): + if proposal.type in ("instance", "statement", "param", "function"): + try: + hint = " ({})".format(proposal.get_type_hint()) + except (AttributeError, TypeError, NotImplementedError, NameError): + hint = "" + return proposal.type + hint + else: + return proposal.type + + def run_with_debug(jedi, name, *args, **kwargs): re_raise = kwargs.pop('re_raise', ()) try: diff --git a/requirements-rpc.txt b/requirements-rpc.txt index c34c65a47..4a78b466f 100644 --- a/requirements-rpc.txt +++ b/requirements-rpc.txt @@ -1,4 +1,4 @@ -jedi==0.16.0 +jedi==0.17.0 rope==0.16.0 autopep8==1.5 yapf==0.29 diff --git a/test/elpy-rpc-get-completions-test.el b/test/elpy-rpc-get-completions-test.el index 86443b008..e84f9a399 100644 --- a/test/elpy-rpc-get-completions-test.el +++ b/test/elpy-rpc-get-completions-test.el @@ -1,3 +1,29 @@ +(defsubst elpy-rpc-get-completions--type-hints-supported () + (if (boundp '*elpy-rpc-get-completions--type-hints-supported*) + *elpy-rpc-get-completions--type-hints-supported* + (setq *elpy-rpc-get-completions--type-hints-supported* + (not (string< (or (getenv "TRAVIS_PYTHON_VERSION") + (with-temp-buffer + (call-process elpy-rpc-python-command + nil '(t t) nil "--version") + (goto-char (point-min)) + (re-search-forward "\\([0-9.]+\\)" nil t) + (or (match-string 1) ""))) + "3.6"))))) + +(defsubst elpy-rpc-get-completions--python-2 () + (if (boundp '*elpy-rpc-get-completions--python-2*) + *elpy-rpc-get-completions--python-2* + (setq *elpy-rpc-get-completions--python-2* + (string< (or (getenv "TRAVIS_PYTHON_VERSION") + (with-temp-buffer + (call-process elpy-rpc-python-command + nil '(t t) nil "--version") + (goto-char (point-min)) + (re-search-forward "\\([0-9.]+\\)" nil t) + (or (match-string 1) ""))) + "3.5")))) + (ert-deftest elpy-rpc-get-completions () (elpy-testcase () (mletf* ((called-args nil) @@ -10,6 +36,14 @@ (nil "" 0) nil nil)))))) +;; temporary workaround for bug in jedi==0.17.0 +;; see https://github.com/davidhalter/jedi/pull/1589 +(setq annot1 "function (addition(x, y))" + annot2 "function (addition2(x, y))") +(when (elpy-rpc-get-completions--python-2) + (setq annot1 "function" + annot2 "function")) + (ert-deftest elpy-rpc-get-completions-should-return-completion () (elpy-testcase ((:project project-root "test.py") (:emacs-required "25.1")) @@ -27,11 +61,28 @@ (should (string= (alist-get 'name compl1) "addition")) (should (string= (alist-get 'suffix compl1) "ition")) (should (string= (alist-get 'meta compl1) "def addition")) - (should (string= (alist-get 'annotation compl1) "function")) + (should (string= (alist-get 'annotation compl1) annot1)) (should (string= (alist-get 'name compl2) "addition2")) (should (string= (alist-get 'suffix compl2) "ition2")) (should (string= (alist-get 'meta compl2) "def addition2")) - (should (string= (alist-get 'annotation compl2) "function"))))) + (should (string= (alist-get 'annotation compl2) annot2))))) + + +(when (elpy-rpc-get-completions--type-hints-supported) + (ert-deftest elpy-rpc-get-completions-should-include-type-hints () + (elpy-testcase ((:project project-root "test.py") + (:emacs-required "25.1")) + (find-file (f-join project-root "test.py")) + (elpy-enable) + (python-mode) + (insert "test_var: int = 3\n" + "test_") + (let ((compl (car (elpy-rpc-get-completions)))) + (should (string= (alist-get 'name compl) "test_var")) + (should (string= (alist-get 'suffix compl) "var")) + (should (string= (alist-get 'meta compl) "test_var: int = 3")) + (should (string= (alist-get 'annotation compl) "statement (int)")))))) + (ert-deftest elpy-rpc-get-completions-should-not-return-completion-for-numbers () (elpy-testcase ((:project project-root "test.py") @@ -45,6 +96,12 @@ (let ((compl (elpy-rpc-get-completions))) (should (equal compl nil))))) +;; temporary workaround for bug in jedi==0.17.0 +;; see https://github.com/davidhalter/jedi/pull/1589 +(setq annot3 "function (foo12345(x, y))") +(when (elpy-rpc-get-completions--python-2) + (setq annot3 "function")) + (ert-deftest elpy-rpc-get-completions-should-return-completion-for-variable-with-numbers () (elpy-testcase ((:project project-root "test.py") (:emacs-required "25.1")) @@ -58,4 +115,4 @@ (should (string= (alist-get 'name compl) "foo12345")) (should (string= (alist-get 'suffix compl) "345")) (should (string= (alist-get 'meta compl) "def foo12345")) - (should (string= (alist-get 'annotation compl) "function"))))) + (should (string= (alist-get 'annotation compl) annot3)))))