mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/fanhuadesenlinnn/.emacs.d.git
synced 2026-09-20 08:03:37 +08:00
第二次提交
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
;;; anaconda-mode-autoloads.el --- automatically extracted autoloads
|
||||
;;
|
||||
;;; Code:
|
||||
|
||||
(add-to-list 'load-path (directory-file-name
|
||||
(or (file-name-directory #$) (car load-path))))
|
||||
|
||||
|
||||
;;;### (autoloads nil "anaconda-mode" "anaconda-mode.el" (0 0 0 0))
|
||||
;;; Generated autoloads from anaconda-mode.el
|
||||
|
||||
(autoload 'anaconda-mode "anaconda-mode" "\
|
||||
Code navigation, documentation lookup and completion for Python.
|
||||
|
||||
If called interactively, enable Anaconda mode if ARG is positive,
|
||||
and disable it if ARG is zero or negative. If called from Lisp,
|
||||
also enable the mode if ARG is omitted or nil, and toggle it if
|
||||
ARG is `toggle'; disable the mode otherwise.
|
||||
|
||||
\\{anaconda-mode-map}
|
||||
|
||||
\(fn &optional ARG)" t nil)
|
||||
|
||||
(autoload 'anaconda-eldoc-mode "anaconda-mode" "\
|
||||
Toggle echo area display of Python objects at point.
|
||||
|
||||
If called interactively, enable Anaconda-Eldoc mode if ARG is
|
||||
positive, and disable it if ARG is zero or negative. If called
|
||||
from Lisp, also enable the mode if ARG is omitted or nil, and
|
||||
toggle it if ARG is `toggle'; disable the mode otherwise.
|
||||
|
||||
\(fn &optional ARG)" t nil)
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "anaconda-mode" '("anaconda-" "turn-o")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil nil ("anaconda-mode-pkg.el") (0 0 0 0))
|
||||
|
||||
;;;***
|
||||
|
||||
;; Local Variables:
|
||||
;; version-control: never
|
||||
;; no-byte-compile: t
|
||||
;; no-update-autoloads: t
|
||||
;; coding: utf-8
|
||||
;; End:
|
||||
;;; anaconda-mode-autoloads.el ends here
|
||||
14
elpa-27.2/anaconda-mode-20211122.817/anaconda-mode-pkg.el
Normal file
14
elpa-27.2/anaconda-mode-20211122.817/anaconda-mode-pkg.el
Normal file
@@ -0,0 +1,14 @@
|
||||
(define-package "anaconda-mode" "20211122.817" "Code navigation, documentation lookup and completion for Python"
|
||||
'((emacs "25.1")
|
||||
(pythonic "0.1.0")
|
||||
(dash "2.6.0")
|
||||
(s "1.9")
|
||||
(f "0.16.2"))
|
||||
:commit "cbea0fb3182321d34ff93981c5a59f8dd72d82a5" :authors
|
||||
'(("Artem Malyshev" . "proofit404@gmail.com"))
|
||||
:maintainer
|
||||
'("Artem Malyshev" . "proofit404@gmail.com")
|
||||
:url "https://github.com/proofit404/anaconda-mode")
|
||||
;; Local Variables:
|
||||
;; no-byte-compile: t
|
||||
;; End:
|
||||
779
elpa-27.2/anaconda-mode-20211122.817/anaconda-mode.el
Normal file
779
elpa-27.2/anaconda-mode-20211122.817/anaconda-mode.el
Normal file
@@ -0,0 +1,779 @@
|
||||
;;; anaconda-mode.el --- Code navigation, documentation lookup and completion for Python -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2013-2018 by Artem Malyshev
|
||||
|
||||
;; Author: Artem Malyshev <proofit404@gmail.com>
|
||||
;; URL: https://github.com/proofit404/anaconda-mode
|
||||
;; Version: 0.1.15
|
||||
;; Package-Requires: ((emacs "25.1") (pythonic "0.1.0") (dash "2.6.0") (s "1.9") (f "0.16.2"))
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; See the README for more details.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'ansi-color)
|
||||
(require 'pythonic)
|
||||
(require 'tramp)
|
||||
(require 'xref)
|
||||
(require 'json)
|
||||
(require 'dash)
|
||||
(require 'url)
|
||||
(require 's)
|
||||
(require 'f)
|
||||
|
||||
(defgroup anaconda nil
|
||||
"Code navigation, documentation lookup and completion for Python."
|
||||
:group 'programming)
|
||||
|
||||
(defcustom anaconda-mode-installation-directory
|
||||
(locate-user-emacs-file "anaconda-mode")
|
||||
"Installation directory for `anaconda-mode' server."
|
||||
:type 'directory)
|
||||
|
||||
(defcustom anaconda-mode-eldoc-as-single-line nil
|
||||
"If not nil, trim eldoc string to frame width."
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom anaconda-mode-lighter " Anaconda"
|
||||
"Text displayed in the mode line when `anaconda-mode’ is active."
|
||||
:type 'sexp)
|
||||
|
||||
(defcustom anaconda-mode-localhost-address "127.0.0.1"
|
||||
"Address used by `anaconda-mode' to resolve localhost."
|
||||
:type 'string)
|
||||
|
||||
(defcustom anaconda-mode-doc-frame-background (face-attribute 'default :background)
|
||||
"Doc frame background color, default color is current theme's background."
|
||||
:type 'string)
|
||||
|
||||
(defcustom anaconda-mode-doc-frame-foreground (face-attribute 'default :foreground)
|
||||
"Doc frame foreground color, default color is current theme's foreground."
|
||||
:type 'string)
|
||||
|
||||
(defcustom anaconda-mode-use-posframe-show-doc nil
|
||||
"If the value is not nil, use posframe to show eldoc."
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom anaconda-mode-tunnel-setup-sleep 2
|
||||
"Time in seconds `anaconda-mode' waits after tunnel creation before first RPC call."
|
||||
:type 'integer)
|
||||
|
||||
(defcustom anaconda-mode-sync-request-timeout 2
|
||||
"Time in seconds `anaconda-mode' waits for a synchronous response."
|
||||
:type 'integer)
|
||||
|
||||
;;; Compatibility
|
||||
|
||||
;; Functions from posframe which is an optional dependency
|
||||
(declare-function posframe-workable-p "posframe")
|
||||
(declare-function posframe-hide "posframe")
|
||||
(declare-function posframe-show "posframe")
|
||||
|
||||
;;; Server.
|
||||
(defvar anaconda-mode-server-version "0.1.15"
|
||||
"Server version needed to run `anaconda-mode'.")
|
||||
|
||||
(defvar anaconda-mode-process-name "anaconda-mode"
|
||||
"Process name for `anaconda-mode' processes.")
|
||||
|
||||
(defvar anaconda-mode-process-buffer "*anaconda-mode*"
|
||||
"Buffer name for `anaconda-mode' process.")
|
||||
|
||||
(defvar anaconda-mode-process nil
|
||||
"Currently running `anaconda-mode' process.")
|
||||
|
||||
(defvar anaconda-mode-response-buffer "*anaconda-response*"
|
||||
"Buffer name for error report when `anaconda-mode' fail to read server response.")
|
||||
|
||||
(defvar anaconda-mode-socat-process-name "anaconda-socat"
|
||||
"Process name for `anaconda-mode' socat companion process.")
|
||||
|
||||
(defvar anaconda-mode-socat-process-buffer "*anaconda-socat*"
|
||||
"Buffer name for `anaconda-mode' socat companion process.")
|
||||
|
||||
(defvar anaconda-mode-socat-process nil
|
||||
"Currently running `anaconda-mode' socat companion process.")
|
||||
|
||||
(defvar anaconda-mode-ssh-process-name "anaconda-ssh"
|
||||
"Process name for `anaconda-mode' ssh port forward companion process.")
|
||||
|
||||
(defvar anaconda-mode-ssh-process-buffer "*anaconda-ssh*"
|
||||
"Buffer name for `anaconda-mode' ssh port forward companion process.")
|
||||
|
||||
(defvar anaconda-mode-ssh-process nil
|
||||
"Currently running `anaconda-mode' ssh port forward companion process.")
|
||||
|
||||
(defvar anaconda-mode-doc-frame-name "*Anaconda Posframe*"
|
||||
"The posframe to show anaconda documentation.")
|
||||
|
||||
(defvar anaconda-mode-frame-last-point 0
|
||||
"The last point of anaconda doc view frame, use for hide frame after move point.")
|
||||
|
||||
(defvar anaconda-mode-frame-last-scroll-offset 0
|
||||
"The last scroll offset when show doc view frame, use for hide frame after window scroll.")
|
||||
|
||||
(defun anaconda-mode-server-directory ()
|
||||
"Anaconda mode installation directory."
|
||||
(f-short (f-join anaconda-mode-installation-directory
|
||||
anaconda-mode-server-version)))
|
||||
|
||||
(defun anaconda-mode-host ()
|
||||
"Target host with `anaconda-mode' server."
|
||||
(cond
|
||||
((pythonic-remote-docker-p)
|
||||
anaconda-mode-localhost-address)
|
||||
((pythonic-remote-p)
|
||||
(pythonic-remote-host))
|
||||
(t
|
||||
anaconda-mode-localhost-address)))
|
||||
|
||||
(defun anaconda-mode-port ()
|
||||
"Port for `anaconda-mode' connection."
|
||||
(process-get anaconda-mode-process 'port))
|
||||
|
||||
(defun anaconda-mode-start (&optional callback)
|
||||
"Start `anaconda-mode' server.
|
||||
CALLBACK function will be called when `anaconda-mode-port' will
|
||||
be bound."
|
||||
(when (anaconda-mode-need-restart)
|
||||
(anaconda-mode-stop))
|
||||
(if (anaconda-mode-running-p)
|
||||
(and callback
|
||||
(anaconda-mode-bound-p)
|
||||
(funcall callback))
|
||||
(anaconda-mode-bootstrap callback)))
|
||||
|
||||
(defun anaconda-mode-stop ()
|
||||
"Stop `anaconda-mode' server."
|
||||
(when (anaconda-mode-running-p)
|
||||
(set-process-filter anaconda-mode-process nil)
|
||||
(set-process-sentinel anaconda-mode-process nil)
|
||||
(kill-process anaconda-mode-process)
|
||||
(setq anaconda-mode-process nil))
|
||||
(when (anaconda-mode-socat-running-p)
|
||||
(kill-process anaconda-mode-socat-process)
|
||||
(setq anaconda-mode-socat-process nil))
|
||||
(when (anaconda-mode-ssh-running-p)
|
||||
(kill-process anaconda-mode-ssh-process)
|
||||
(setq anaconda-mode-ssh-process nil)))
|
||||
|
||||
(defun anaconda-mode-running-p ()
|
||||
"Is `anaconda-mode' server running."
|
||||
(and anaconda-mode-process
|
||||
(process-live-p anaconda-mode-process)))
|
||||
|
||||
(defun anaconda-mode-socat-running-p ()
|
||||
"Is `anaconda-mode' socat companion process running."
|
||||
(and anaconda-mode-socat-process
|
||||
(process-live-p anaconda-mode-socat-process)))
|
||||
|
||||
(defun anaconda-mode-ssh-running-p ()
|
||||
"Is `anaconda-mode' ssh port forward companion process running."
|
||||
(and anaconda-mode-ssh-process
|
||||
(process-live-p anaconda-mode-ssh-process)))
|
||||
|
||||
(defun anaconda-mode-bound-p ()
|
||||
"Is `anaconda-mode' port bound."
|
||||
(numberp (anaconda-mode-port)))
|
||||
|
||||
(defun anaconda-mode-need-restart ()
|
||||
"Check if we need to restart `anaconda-mode-server'."
|
||||
(when (and (anaconda-mode-running-p)
|
||||
(anaconda-mode-bound-p))
|
||||
(not (and (equal (process-get anaconda-mode-process 'interpreter)
|
||||
python-shell-interpreter)
|
||||
(equal (process-get anaconda-mode-process 'virtualenv)
|
||||
python-shell-virtualenv-root)
|
||||
(equal (process-get anaconda-mode-process 'remote-p)
|
||||
(pythonic-remote-p))
|
||||
(if (pythonic-local-p)
|
||||
t
|
||||
(equal (process-get anaconda-mode-process 'remote-method)
|
||||
(pythonic-remote-method))
|
||||
(equal (process-get anaconda-mode-process 'remote-user)
|
||||
(pythonic-remote-user))
|
||||
(equal (process-get anaconda-mode-process 'remote-host)
|
||||
(pythonic-remote-host))
|
||||
(equal (process-get anaconda-mode-process 'remote-port)
|
||||
(pythonic-remote-port)))))))
|
||||
|
||||
(defun anaconda-mode-get-server-process-cwd ()
|
||||
"Get the working directory for starting the anaconda server process.
|
||||
|
||||
The current working directory ends up being on sys.path, which may
|
||||
result in conflicts with stdlib modules.
|
||||
|
||||
When running python from the local machine, we start the server
|
||||
process from `anaconda-mode-installation-directory'.
|
||||
This function creates that directory if it doesn't exist yet."
|
||||
(when (pythonic-local-p)
|
||||
(unless (file-directory-p anaconda-mode-installation-directory)
|
||||
(make-directory anaconda-mode-installation-directory t))
|
||||
anaconda-mode-installation-directory))
|
||||
|
||||
(defun anaconda-mode-server-command-args ()
|
||||
"Return list of arguments to start anaconda-mode server.
|
||||
|
||||
Passes local file anaconda-mode.py if local, or uses python
|
||||
module as string if connecting through TRAMP.
|
||||
|
||||
Arguments are:
|
||||
1. anaconda-mode.py (local) or -c anaconda-mode.py string (remote)
|
||||
2. anaconda-mode-server-directory
|
||||
3. anaconda-mode-localhost-address (local) or 0.0.0.0 (remote)
|
||||
4. python-shell-virtualenv-root or empty string if not set"
|
||||
(let ((server-command-file (concat (file-name-directory (locate-library "anaconda-mode")) "anaconda-mode.py"))
|
||||
(arg-list (list (anaconda-mode-server-directory)
|
||||
(if (pythonic-remote-p)
|
||||
"0.0.0.0"
|
||||
anaconda-mode-localhost-address)
|
||||
(or python-shell-virtualenv-root "") ))
|
||||
server-command)
|
||||
(if (pythonic-remote-p)
|
||||
(with-temp-buffer
|
||||
(insert-file-contents server-command-file)
|
||||
(setq server-command (list "-c" (buffer-string))))
|
||||
(setq server-command (list server-command-file)))
|
||||
(append server-command arg-list)))
|
||||
|
||||
|
||||
(defun anaconda-mode-bootstrap (&optional callback)
|
||||
"Run `anaconda-mode' server.
|
||||
CALLBACK function will be called when `anaconda-mode-port' will
|
||||
be bound."
|
||||
(setq anaconda-mode-process
|
||||
(pythonic-start-process :process anaconda-mode-process-name
|
||||
:cwd (anaconda-mode-get-server-process-cwd)
|
||||
:buffer (get-buffer-create anaconda-mode-process-buffer)
|
||||
:query-on-exit nil
|
||||
:filter (lambda (process output)
|
||||
(anaconda-mode-bootstrap-filter process output callback))
|
||||
:sentinel (lambda (_process _event))
|
||||
:args (anaconda-mode-server-command-args)))
|
||||
(process-put anaconda-mode-process 'interpreter python-shell-interpreter)
|
||||
(process-put anaconda-mode-process 'virtualenv python-shell-virtualenv-root)
|
||||
(process-put anaconda-mode-process 'port nil)
|
||||
(when (pythonic-remote-p)
|
||||
(process-put anaconda-mode-process 'remote-p t)
|
||||
(process-put anaconda-mode-process 'remote-method (pythonic-remote-method))
|
||||
(process-put anaconda-mode-process 'remote-user (pythonic-remote-user))
|
||||
(process-put anaconda-mode-process 'remote-host (pythonic-remote-host))
|
||||
(process-put anaconda-mode-process 'remote-port (pythonic-remote-port))))
|
||||
|
||||
(defun anaconda-jump-proxy-string ()
|
||||
"Create -J option string for SSH tunnel."
|
||||
(let ((dfn
|
||||
(tramp-dissect-file-name (pythonic-aliased-path default-directory))))
|
||||
(when (tramp-file-name-hop dfn)
|
||||
(let ((hop-list (split-string (tramp-file-name-hop dfn) "|"))
|
||||
(result "-J "))
|
||||
(delete "" hop-list) ;; remove empty string after final pipe
|
||||
(dolist (elt hop-list result)
|
||||
;; tramp-dissect-file-name expects a filename so give it dummy.file
|
||||
(let ((ts (tramp-dissect-file-name (concat "/" elt ":/dummy.file"))))
|
||||
(setq result (concat result
|
||||
(format "%s@%s:%s,"
|
||||
(tramp-file-name-user ts)
|
||||
(tramp-file-name-host ts)
|
||||
(or (tramp-file-name-port-or-default ts) 22))))))
|
||||
;; Remove final comma
|
||||
(substring result 0 -1)))))
|
||||
|
||||
(defun anaconda-mode-bootstrap-filter (process output &optional callback)
|
||||
"Set `anaconda-mode-port' from PROCESS OUTPUT.
|
||||
Connect to the `anaconda-mode' server. CALLBACK function will be
|
||||
called when `anaconda-mode-port' will be bound."
|
||||
;; Mimic default filter.
|
||||
(when (buffer-live-p (process-buffer process))
|
||||
(with-current-buffer (process-buffer process)
|
||||
(save-excursion
|
||||
(goto-char (process-mark process))
|
||||
(insert (ansi-color-apply output))
|
||||
(set-marker (process-mark process) (point)))))
|
||||
(unless (anaconda-mode-bound-p)
|
||||
(--when-let (s-match "anaconda_mode port \\([0-9]+\\)" output)
|
||||
(process-put anaconda-mode-process 'port (string-to-number (cadr it)))
|
||||
(cond ((pythonic-remote-docker-p)
|
||||
(let* ((container-raw-description (with-output-to-string
|
||||
(with-current-buffer
|
||||
standard-output
|
||||
(call-process "docker" nil t nil "inspect" (pythonic-remote-host)))))
|
||||
(container-description (let ((json-array-type 'list))
|
||||
(json-read-from-string container-raw-description)))
|
||||
(container-ip (cdr (assoc 'IPAddress
|
||||
(cdadr (assoc 'Networks
|
||||
(cdr (assoc 'NetworkSettings
|
||||
(car container-description)))))))))
|
||||
(setq anaconda-mode-socat-process
|
||||
(start-process anaconda-mode-socat-process-name
|
||||
anaconda-mode-socat-process-buffer
|
||||
"socat"
|
||||
(format "TCP4-LISTEN:%d" (anaconda-mode-port))
|
||||
(format "TCP4:%s:%d" container-ip (anaconda-mode-port))))
|
||||
(set-process-query-on-exit-flag anaconda-mode-socat-process nil)))
|
||||
((pythonic-remote-ssh-p)
|
||||
(let ((jump (anaconda-jump-proxy-string)))
|
||||
(message (format "Anaconda Jump Proxy: %s" jump))
|
||||
(setq anaconda-mode-ssh-process
|
||||
(if jump
|
||||
(start-process anaconda-mode-ssh-process-name
|
||||
anaconda-mode-ssh-process-buffer
|
||||
"ssh" jump "-nNT"
|
||||
"-L" (format "%s:localhost:%s" (anaconda-mode-port) (anaconda-mode-port))
|
||||
(format "%s@%s" (pythonic-remote-user) (pythonic-remote-host))
|
||||
"-p" (number-to-string (or (pythonic-remote-port) 22)))
|
||||
(start-process anaconda-mode-ssh-process-name
|
||||
anaconda-mode-ssh-process-buffer
|
||||
"ssh" "-nNT"
|
||||
"-L" (format "%s:localhost:%s" (anaconda-mode-port) (anaconda-mode-port))
|
||||
(if (pythonic-remote-user)
|
||||
(format "%s@%s" (pythonic-remote-user) (pythonic-remote-host))
|
||||
;; Asssume remote host is an ssh alias
|
||||
(pythonic-remote-host))
|
||||
"-p" (number-to-string (or (pythonic-remote-port) 22)))))
|
||||
;; prevent race condition between tunnel setup and first use
|
||||
(sleep-for anaconda-mode-tunnel-setup-sleep)
|
||||
(set-process-query-on-exit-flag anaconda-mode-ssh-process nil))))
|
||||
(when callback
|
||||
(funcall callback)))))
|
||||
|
||||
|
||||
;;; Interaction.
|
||||
|
||||
(defun anaconda-mode-call (command callback)
|
||||
"Make remote procedure call for COMMAND.
|
||||
Apply CALLBACK to the result asynchronously."
|
||||
(anaconda-mode-start
|
||||
(lambda () (anaconda-mode-jsonrpc command callback))))
|
||||
|
||||
(defun anaconda-mode-call-sync (command callback)
|
||||
"Make remote procedure call for COMMAND.
|
||||
Apply CALLBACK to the result synchronously."
|
||||
(let ((start-time (current-time))
|
||||
(result 'pending))
|
||||
(anaconda-mode-call
|
||||
command
|
||||
(lambda (r) (setq result r)))
|
||||
(while (eq result 'pending)
|
||||
(accept-process-output nil 0.01)
|
||||
(when (> (cadr (time-subtract (current-time) start-time))
|
||||
anaconda-mode-sync-request-timeout)
|
||||
(error "%s request timed out" command)))
|
||||
(funcall callback result)))
|
||||
|
||||
(defun anaconda-mode-jsonrpc (command callback)
|
||||
"Perform JSONRPC call for COMMAND.
|
||||
Apply CALLBACK to the call result when retrieve it. Remote
|
||||
COMMAND must expect four arguments: python buffer content, line
|
||||
number position, column number position and file path."
|
||||
(let ((url-request-method "POST")
|
||||
(url-request-data (anaconda-mode-jsonrpc-request command)))
|
||||
(url-retrieve
|
||||
(format "http://%s:%s" anaconda-mode-localhost-address (anaconda-mode-port))
|
||||
(anaconda-mode-create-response-handler callback)
|
||||
nil
|
||||
t)))
|
||||
|
||||
(defun anaconda-mode-jsonrpc-request (command)
|
||||
"Prepare JSON encoded buffer data for COMMAND call."
|
||||
(encode-coding-string (json-encode (anaconda-mode-jsonrpc-request-data command)) 'utf-8))
|
||||
|
||||
(defun anaconda-mode-jsonrpc-request-data (command)
|
||||
"Prepare buffer data for COMMAND call."
|
||||
`((jsonrpc . "2.0")
|
||||
(id . 1)
|
||||
(method . ,command)
|
||||
(params . ((source . ,(buffer-substring-no-properties (point-min) (point-max)))
|
||||
(line . ,(line-number-at-pos (point)))
|
||||
(column . ,(- (point) (line-beginning-position)))
|
||||
(path . ,(when (buffer-file-name)
|
||||
(pythonic-python-readable-file-name (buffer-file-name))))))))
|
||||
|
||||
(defun anaconda-mode-create-response-handler (callback)
|
||||
"Create server response handler based on CALLBACK function."
|
||||
(let ((anaconda-mode-request-point (point))
|
||||
(anaconda-mode-request-buffer (current-buffer))
|
||||
(anaconda-mode-request-window (selected-window))
|
||||
(anaconda-mode-request-tick (buffer-chars-modified-tick)))
|
||||
(lambda (status)
|
||||
(let ((http-buffer (current-buffer)))
|
||||
(unwind-protect
|
||||
(if (or (not (equal anaconda-mode-request-window (selected-window)))
|
||||
(with-current-buffer (window-buffer anaconda-mode-request-window)
|
||||
(or (not (equal anaconda-mode-request-buffer (current-buffer)))
|
||||
(not (equal anaconda-mode-request-point (point)))
|
||||
(not (equal anaconda-mode-request-tick (buffer-chars-modified-tick))))))
|
||||
nil
|
||||
(search-forward-regexp "\r?\n\r?\n" nil t)
|
||||
(let ((response (condition-case nil
|
||||
(json-read)
|
||||
((json-readtable-error json-end-of-file end-of-file)
|
||||
(let ((response (concat (format "# status: %s\n# point: %s\n" status (point))
|
||||
(buffer-string))))
|
||||
(with-current-buffer (get-buffer-create anaconda-mode-response-buffer)
|
||||
(erase-buffer)
|
||||
(insert response)
|
||||
(goto-char (point-min)))
|
||||
nil)))))
|
||||
(if (null response)
|
||||
(message "Cannot read anaconda-mode server response")
|
||||
(if (assoc 'error response)
|
||||
(let* ((error-structure (cdr (assoc 'error response)))
|
||||
(error-message (cdr (assoc 'message error-structure)))
|
||||
(error-data (cdr (assoc 'data error-structure)))
|
||||
(error-template (concat (if error-data "%s: %s" "%s")
|
||||
" - see " anaconda-mode-process-buffer
|
||||
" for more information.")))
|
||||
(apply 'message error-template (delq nil (list error-message error-data))))
|
||||
(with-current-buffer anaconda-mode-request-buffer
|
||||
(let ((result (cdr (assoc 'result response))))
|
||||
;; Terminate `apply' call with empty list so response
|
||||
;; will be treated as single argument.
|
||||
(condition-case nil
|
||||
(apply callback result nil)
|
||||
(quit nil))))))))
|
||||
(kill-buffer http-buffer))))))
|
||||
|
||||
|
||||
;;; Code completion.
|
||||
|
||||
(defun anaconda-mode-complete ()
|
||||
"Request completion candidates."
|
||||
(interactive)
|
||||
(unless (python-syntax-comment-or-string-p)
|
||||
(anaconda-mode-call "complete" 'anaconda-mode-complete-callback)))
|
||||
|
||||
(defun anaconda-mode-complete-callback (result)
|
||||
"Start interactive completion on RESULT receiving."
|
||||
(let* ((bounds (bounds-of-thing-at-point 'symbol))
|
||||
(start (or (car bounds) (point)))
|
||||
(stop (or (cdr bounds) (point)))
|
||||
(collection (anaconda-mode-complete-extract-names result))
|
||||
(completion-extra-properties '(:annotation-function anaconda-mode-complete-annotation)))
|
||||
(completion-in-region start stop collection)))
|
||||
|
||||
(defun anaconda-mode-complete-extract-names (result)
|
||||
"Extract completion names from `anaconda-mode' RESULT."
|
||||
(--map (let ((name (aref it 0))
|
||||
(type (aref it 1)))
|
||||
(put-text-property 0 1 'type type name)
|
||||
name)
|
||||
result))
|
||||
|
||||
(defun anaconda-mode-complete-annotation (candidate)
|
||||
"Get annotation for CANDIDATE."
|
||||
(--when-let (get-text-property 0 'type candidate)
|
||||
(concat " <" it ">")))
|
||||
|
||||
|
||||
;;; View documentation.
|
||||
|
||||
(defun anaconda-mode-show-doc ()
|
||||
"Show documentation for context at point."
|
||||
(interactive)
|
||||
(anaconda-mode-call "show_doc" 'anaconda-mode-show-doc-callback))
|
||||
|
||||
(defun anaconda-mode-show-doc-callback (result)
|
||||
"Process view doc RESULT."
|
||||
(if (> (length result) 0)
|
||||
(if (and anaconda-mode-use-posframe-show-doc
|
||||
(require 'posframe nil 'noerror)
|
||||
(posframe-workable-p))
|
||||
(anaconda-mode-documentation-posframe-view result)
|
||||
(pop-to-buffer (anaconda-mode-documentation-view result) t))
|
||||
(message "No documentation available")))
|
||||
|
||||
(defun anaconda-mode-documentation-view (result)
|
||||
"Show documentation view for rpc RESULT, and return buffer."
|
||||
(let ((buf (get-buffer-create "*Anaconda*")))
|
||||
(with-current-buffer buf
|
||||
(view-mode -1)
|
||||
(erase-buffer)
|
||||
(mapc
|
||||
(lambda (it)
|
||||
(insert (propertize (aref it 0) 'face 'bold))
|
||||
(insert "\n")
|
||||
(insert (s-trim-right (aref it 1)))
|
||||
(insert "\n\n"))
|
||||
result)
|
||||
(view-mode 1)
|
||||
(goto-char (point-min))
|
||||
buf)))
|
||||
|
||||
(defun anaconda-mode-documentation-posframe-view (result)
|
||||
"Show documentation view in posframe for rpc RESULT."
|
||||
(with-current-buffer (get-buffer-create anaconda-mode-doc-frame-name)
|
||||
(erase-buffer)
|
||||
(mapc
|
||||
(lambda (it)
|
||||
(insert (propertize (aref it 0) 'face 'bold))
|
||||
(insert "\n")
|
||||
(insert (s-trim-left (aref it 1)))
|
||||
(insert "\n\n"))
|
||||
result))
|
||||
(posframe-show anaconda-mode-doc-frame-name
|
||||
:position (point)
|
||||
:internal-border-width 10
|
||||
:background-color anaconda-mode-doc-frame-background
|
||||
:foreground-color anaconda-mode-doc-frame-foreground)
|
||||
(add-hook 'post-command-hook 'anaconda-mode-hide-frame)
|
||||
(setq anaconda-mode-frame-last-point (point))
|
||||
(setq anaconda-mode-frame-last-scroll-offset (window-start)))
|
||||
|
||||
(defun anaconda-mode-hide-frame ()
|
||||
"Hide posframe when window scroll or move point."
|
||||
(ignore-errors
|
||||
(when (get-buffer anaconda-mode-doc-frame-name)
|
||||
(unless (and (equal (point) anaconda-mode-frame-last-point)
|
||||
(equal (window-start) anaconda-mode-frame-last-scroll-offset))
|
||||
(posframe-hide anaconda-mode-doc-frame-name)
|
||||
(remove-hook 'post-command-hook 'anaconda-mode-hide-frame)))))
|
||||
|
||||
|
||||
;;; Find definitions.
|
||||
|
||||
(defun anaconda-mode-find-definitions ()
|
||||
"Find definitions for thing at point."
|
||||
(interactive)
|
||||
(anaconda-mode-call
|
||||
"infer"
|
||||
(lambda (result)
|
||||
(anaconda-mode-show-xrefs result nil "No definitions found"))))
|
||||
|
||||
(defun anaconda-mode-find-definitions-other-window ()
|
||||
"Find definitions for thing at point."
|
||||
(interactive)
|
||||
(anaconda-mode-call
|
||||
"infer"
|
||||
(lambda (result)
|
||||
(anaconda-mode-show-xrefs result 'window "No definitions found"))))
|
||||
|
||||
(defun anaconda-mode-find-definitions-other-frame ()
|
||||
"Find definitions for thing at point."
|
||||
(interactive)
|
||||
(anaconda-mode-call
|
||||
"infer"
|
||||
(lambda (result)
|
||||
(anaconda-mode-show-xrefs result 'frame "No definitions found"))))
|
||||
|
||||
|
||||
;;; Find assignments.
|
||||
|
||||
(defun anaconda-mode-find-assignments ()
|
||||
"Find assignments for thing at point."
|
||||
(interactive)
|
||||
(anaconda-mode-call
|
||||
"goto"
|
||||
(lambda (result)
|
||||
(anaconda-mode-show-xrefs result nil "No assignments found"))))
|
||||
|
||||
(defun anaconda-mode-find-assignments-other-window ()
|
||||
"Find assignments for thing at point."
|
||||
(interactive)
|
||||
(anaconda-mode-call
|
||||
"goto"
|
||||
(lambda (result)
|
||||
(anaconda-mode-show-xrefs result 'window "No assignments found"))))
|
||||
|
||||
(defun anaconda-mode-find-assignments-other-frame ()
|
||||
"Find assignments for thing at point."
|
||||
(interactive)
|
||||
(anaconda-mode-call
|
||||
"goto"
|
||||
(lambda (result)
|
||||
(anaconda-mode-show-xrefs result 'frame "No assignments found"))))
|
||||
|
||||
|
||||
;;; Find references.
|
||||
|
||||
(defun anaconda-mode-find-references ()
|
||||
"Find references for thing at point."
|
||||
(interactive)
|
||||
(anaconda-mode-call
|
||||
"get_references"
|
||||
(lambda (result)
|
||||
(anaconda-mode-show-xrefs result nil "No references found"))))
|
||||
|
||||
(defun anaconda-mode-find-references-other-window ()
|
||||
"Find references for thing at point."
|
||||
(interactive)
|
||||
(anaconda-mode-call
|
||||
"get_references"
|
||||
(lambda (result)
|
||||
(anaconda-mode-show-xrefs result 'window "No references found"))))
|
||||
|
||||
(defun anaconda-mode-find-references-other-frame ()
|
||||
"Find references for thing at point."
|
||||
(interactive)
|
||||
(anaconda-mode-call
|
||||
"get_references"
|
||||
(lambda (result)
|
||||
(anaconda-mode-show-xrefs result 'frame "No references found"))))
|
||||
|
||||
|
||||
;;; Xref.
|
||||
|
||||
(defun anaconda-mode-xref-backend ()
|
||||
"Integrate `anaconda-mode' with xref."
|
||||
'anaconda)
|
||||
|
||||
(cl-defmethod xref-backend-definitions ((_backend (eql anaconda)) _identifier)
|
||||
"Find definitions for thing at point."
|
||||
(anaconda-mode-call-sync
|
||||
"infer"
|
||||
(lambda (result)
|
||||
(if result
|
||||
(if (stringp result)
|
||||
(progn
|
||||
(message result)
|
||||
nil)
|
||||
(anaconda-mode-make-xrefs result))))))
|
||||
|
||||
(cl-defmethod xref-backend-references ((_backend (eql anaconda)) _identifier)
|
||||
"Find references for thing at point."
|
||||
(anaconda-mode-call-sync
|
||||
"get_references"
|
||||
(lambda (result)
|
||||
(if result
|
||||
(if (stringp result)
|
||||
(progn
|
||||
(message result)
|
||||
nil)
|
||||
(anaconda-mode-make-xrefs result))))))
|
||||
|
||||
(cl-defmethod xref-backend-apropos ((_backend (eql anaconda)) _pattern)
|
||||
"Not implemented."
|
||||
nil)
|
||||
|
||||
(cl-defmethod xref-backend-identifier-completion-table ((_backend (eql anaconda)))
|
||||
"Not implemented."
|
||||
nil)
|
||||
|
||||
(defun anaconda-mode-show-xrefs (result display-action error-message)
|
||||
"Show xref from RESULT using DISPLAY-ACTION.
|
||||
Show ERROR-MESSAGE if result is empty."
|
||||
(if result
|
||||
(if (stringp result)
|
||||
(message result)
|
||||
(let ((xrefs (anaconda-mode-make-xrefs result)))
|
||||
(if (not (cdr xrefs))
|
||||
(progn
|
||||
(xref-push-marker-stack)
|
||||
(funcall (if (fboundp 'xref-pop-to-location)
|
||||
'xref-pop-to-location
|
||||
'xref--pop-to-location)
|
||||
(cl-first xrefs)
|
||||
display-action))
|
||||
(xref--show-xrefs (if (functionp 'xref--create-fetcher)
|
||||
(lambda (&rest _) xrefs)
|
||||
xrefs)
|
||||
display-action))))
|
||||
(message error-message)))
|
||||
|
||||
(defun anaconda-mode-make-xrefs (result)
|
||||
"Return a list of x-reference candidates created from RESULT."
|
||||
(--map
|
||||
(xref-make
|
||||
(aref it 3)
|
||||
(xref-make-file-location (pythonic-emacs-readable-file-name (aref it 0)) (aref it 1) (aref it 2)))
|
||||
result))
|
||||
|
||||
|
||||
;;; Eldoc.
|
||||
|
||||
(defun anaconda-mode-eldoc-function ()
|
||||
"Show eldoc for context at point."
|
||||
(anaconda-mode-call "eldoc" 'anaconda-mode-eldoc-callback)
|
||||
;; Don't show response buffer name as ElDoc message.
|
||||
nil)
|
||||
|
||||
(defun anaconda-mode-eldoc-callback (result)
|
||||
"Display eldoc from server RESULT."
|
||||
(eldoc-message (anaconda-mode-eldoc-format result)))
|
||||
|
||||
(defun anaconda-mode-eldoc-format (result)
|
||||
"Format eldoc string from RESULT."
|
||||
(when result
|
||||
(let ((doc (anaconda-mode-eldoc-format-definition
|
||||
(aref result 0)
|
||||
(aref result 1)
|
||||
(aref result 2))))
|
||||
(if anaconda-mode-eldoc-as-single-line
|
||||
(substring doc 0 (min (frame-width) (length doc)))
|
||||
doc))))
|
||||
|
||||
(defun anaconda-mode-eldoc-format-definition (name index params)
|
||||
"Format function definition from NAME, INDEX and PARAMS."
|
||||
(when index
|
||||
(aset params index (propertize (aref params index) 'face 'eldoc-highlight-function-argument)))
|
||||
(concat (propertize name 'face 'font-lock-function-name-face) "(" (mapconcat 'identity params ", ") ")"))
|
||||
|
||||
|
||||
;;; Anaconda minor mode.
|
||||
|
||||
(defvar anaconda-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map (kbd "C-M-i") 'anaconda-mode-complete)
|
||||
(define-key map (kbd "M-.") 'anaconda-mode-find-definitions)
|
||||
(define-key map (kbd "C-x 4 .") 'anaconda-mode-find-definitions-other-window)
|
||||
(define-key map (kbd "C-x 5 .") 'anaconda-mode-find-definitions-other-frame)
|
||||
(define-key map (kbd "M-=") 'anaconda-mode-find-assignments)
|
||||
(define-key map (kbd "C-x 4 =") 'anaconda-mode-find-assignments-other-window)
|
||||
(define-key map (kbd "C-x 5 =") 'anaconda-mode-find-assignments-other-frame)
|
||||
(define-key map (kbd "M-r") 'anaconda-mode-find-references)
|
||||
(define-key map (kbd "C-x 4 r") 'anaconda-mode-find-references-other-window)
|
||||
(define-key map (kbd "C-x 5 r") 'anaconda-mode-find-references-other-frame)
|
||||
(define-key map (kbd "M-,") 'xref-pop-marker-stack)
|
||||
(define-key map (kbd "M-?") 'anaconda-mode-show-doc)
|
||||
map)
|
||||
"Keymap for `anaconda-mode'.")
|
||||
|
||||
;;;###autoload
|
||||
(define-minor-mode anaconda-mode
|
||||
"Code navigation, documentation lookup and completion for Python.
|
||||
|
||||
\\{anaconda-mode-map}"
|
||||
:lighter anaconda-mode-lighter
|
||||
:keymap anaconda-mode-map
|
||||
(setq-local url-http-attempt-keepalives nil)
|
||||
(if anaconda-mode
|
||||
(add-hook 'xref-backend-functions #'anaconda-mode-xref-backend nil t)
|
||||
(remove-hook 'xref-backend-functions #'anaconda-mode-xref-backend t)))
|
||||
|
||||
;;;###autoload
|
||||
(define-minor-mode anaconda-eldoc-mode
|
||||
"Toggle echo area display of Python objects at point."
|
||||
:lighter ""
|
||||
(if anaconda-eldoc-mode
|
||||
(turn-on-anaconda-eldoc-mode)
|
||||
(turn-off-anaconda-eldoc-mode)))
|
||||
|
||||
(defun turn-on-anaconda-eldoc-mode ()
|
||||
"Turn on `anaconda-eldoc-mode'."
|
||||
(make-local-variable 'eldoc-documentation-function)
|
||||
(setq-local eldoc-documentation-function 'anaconda-mode-eldoc-function)
|
||||
(eldoc-mode +1))
|
||||
|
||||
(defun turn-off-anaconda-eldoc-mode ()
|
||||
"Turn off `anaconda-eldoc-mode'."
|
||||
(kill-local-variable 'eldoc-documentation-function)
|
||||
(eldoc-mode -1))
|
||||
|
||||
(provide 'anaconda-mode)
|
||||
|
||||
;;; anaconda-mode.el ends here
|
||||
BIN
elpa-27.2/anaconda-mode-20211122.817/anaconda-mode.elc
Normal file
BIN
elpa-27.2/anaconda-mode-20211122.817/anaconda-mode.elc
Normal file
Binary file not shown.
194
elpa-27.2/anaconda-mode-20211122.817/anaconda-mode.py
Normal file
194
elpa-27.2/anaconda-mode-20211122.817/anaconda-mode.py
Normal file
@@ -0,0 +1,194 @@
|
||||
|
||||
from __future__ import print_function
|
||||
import sys
|
||||
import os
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
# CLI arguments.
|
||||
|
||||
assert len(sys.argv) > 3, 'CLI arguments: %s' % sys.argv
|
||||
|
||||
server_directory = sys.argv[-3]
|
||||
server_address = sys.argv[-2]
|
||||
virtual_environment = sys.argv[-1]
|
||||
|
||||
# Ensure directory.
|
||||
|
||||
server_directory = os.path.expanduser(server_directory)
|
||||
virtual_environment = os.path.expanduser(virtual_environment)
|
||||
|
||||
# Installation check.
|
||||
|
||||
IS_PY2 = sys.version_info[0] == 2
|
||||
|
||||
# jedi versions >= 0.18 don't support Python 2
|
||||
if IS_PY2:
|
||||
jedi_dep = ('jedi', '0.17.2')
|
||||
server_directory += '-py2'
|
||||
else:
|
||||
jedi_dep = ('jedi', '0.18.1')
|
||||
server_directory += '-py3'
|
||||
service_factory_dep = ('service_factory', '0.1.6')
|
||||
|
||||
if not os.path.exists(server_directory):
|
||||
os.makedirs(server_directory)
|
||||
sys.path.insert(1, server_directory)
|
||||
|
||||
missing_dependencies = []
|
||||
|
||||
|
||||
def is_package_dir(path):
|
||||
if os.path.isdir(path):
|
||||
if IS_PY2:
|
||||
return path.endswith(".egg")
|
||||
else:
|
||||
return not (path.endswith(".dist-info") or path.endswith(".egg-info"))
|
||||
return False
|
||||
|
||||
def instrument_installation():
|
||||
for package in (jedi_dep, service_factory_dep):
|
||||
package_is_installed = False
|
||||
for path in os.listdir(server_directory):
|
||||
path = os.path.join(server_directory, path)
|
||||
if is_package_dir(path):
|
||||
if path not in sys.path:
|
||||
sys.path.insert(0, path)
|
||||
if package[0] in path:
|
||||
package_is_installed = True
|
||||
if not package_is_installed:
|
||||
missing_dependencies.append('=='.join(package))
|
||||
|
||||
instrument_installation()
|
||||
|
||||
# Installation.
|
||||
|
||||
def install_deps_setuptools():
|
||||
import setuptools.command.easy_install
|
||||
cmd = ['--install-dir', server_directory,
|
||||
'--site-dirs', server_directory,
|
||||
'--always-copy', '--always-unzip']
|
||||
cmd.extend(missing_dependencies)
|
||||
setuptools.command.easy_install.main(cmd)
|
||||
instrument_installation()
|
||||
|
||||
def install_deps_pip():
|
||||
import subprocess
|
||||
cmd = [sys.executable, '-m', 'pip', 'install', '--target', server_directory]
|
||||
cmd.extend(missing_dependencies)
|
||||
subprocess.check_call(cmd)
|
||||
instrument_installation()
|
||||
|
||||
if missing_dependencies:
|
||||
if IS_PY2:
|
||||
install_deps_setuptools()
|
||||
else:
|
||||
install_deps_pip()
|
||||
|
||||
del missing_dependencies[:]
|
||||
|
||||
try:
|
||||
import jedi
|
||||
except ImportError:
|
||||
missing_dependencies.append('=='.join(jedi_dep))
|
||||
|
||||
try:
|
||||
import service_factory
|
||||
except ImportError:
|
||||
missing_dependencies.append('>='.join(service_factory_dep))
|
||||
|
||||
# Try one more time in case if anaconda installation gets broken somehow
|
||||
if missing_dependencies:
|
||||
if IS_PY2:
|
||||
install_deps_setuptools()
|
||||
else:
|
||||
install_deps_pip()
|
||||
import jedi
|
||||
import service_factory
|
||||
|
||||
# Setup server.
|
||||
|
||||
assert LooseVersion(jedi.__version__) >= LooseVersion(jedi_dep[1]), 'Jedi version should be >= %s, current version: %s' % (jedi_dep[1], jedi.__version__)
|
||||
|
||||
if virtual_environment:
|
||||
virtual_environment = jedi.create_environment(virtual_environment, safe=False)
|
||||
else:
|
||||
virtual_environment = None
|
||||
|
||||
# Define JSON-RPC application.
|
||||
|
||||
import functools
|
||||
import threading
|
||||
|
||||
def script_method(f):
|
||||
@functools.wraps(f)
|
||||
def wrapper(source, line, column, path):
|
||||
timer = threading.Timer(30.0, sys.exit)
|
||||
timer.start()
|
||||
result = f(jedi.Script(source, path=path, environment=virtual_environment), line, column)
|
||||
timer.cancel()
|
||||
return result
|
||||
return wrapper
|
||||
|
||||
def process_definitions(f):
|
||||
@functools.wraps(f)
|
||||
def wrapper(script, line, column):
|
||||
definitions = f(script, line, column)
|
||||
if len(definitions) == 1 and not definitions[0].module_path:
|
||||
return '%s is defined in %s compiled module' % (
|
||||
definitions[0].name, definitions[0].module_name)
|
||||
return [[str(definition.module_path),
|
||||
definition.line,
|
||||
definition.column,
|
||||
definition.get_line_code().strip()]
|
||||
for definition in definitions
|
||||
if definition.module_path] or None
|
||||
return wrapper
|
||||
|
||||
@script_method
|
||||
def complete(script, line, column):
|
||||
return [[definition.name, definition.type]
|
||||
for definition in script.complete(line, column)]
|
||||
|
||||
@script_method
|
||||
def company_complete(script, line, column):
|
||||
return [[definition.name,
|
||||
definition.type,
|
||||
definition.docstring(),
|
||||
str(definition.module_path),
|
||||
definition.line]
|
||||
for definition in script.complete(line, column)]
|
||||
|
||||
@script_method
|
||||
def show_doc(script, line, column):
|
||||
return [[definition.module_name, definition.docstring()]
|
||||
for definition in script.infer(line, column)]
|
||||
|
||||
@script_method
|
||||
@process_definitions
|
||||
def infer(script, line, column):
|
||||
return script.infer(line, column)
|
||||
|
||||
@script_method
|
||||
@process_definitions
|
||||
def goto(script, line, column):
|
||||
return script.goto(line, column)
|
||||
|
||||
@script_method
|
||||
@process_definitions
|
||||
def get_references(script, line, column):
|
||||
return script.get_references(line, column)
|
||||
|
||||
@script_method
|
||||
def eldoc(script, line, column):
|
||||
signatures = script.get_signatures(line, column)
|
||||
if len(signatures) == 1:
|
||||
signature = signatures[0]
|
||||
return [signature.name,
|
||||
signature.index,
|
||||
[param.description[6:] for param in signature.params]]
|
||||
|
||||
# Run.
|
||||
|
||||
app = [complete, company_complete, show_doc, infer, goto, get_references, eldoc]
|
||||
|
||||
service_factory.service_factory(app, server_address, 0, 'anaconda_mode port {port}')
|
||||
@@ -0,0 +1,29 @@
|
||||
;;; company-anaconda-autoloads.el --- automatically extracted autoloads
|
||||
;;
|
||||
;;; Code:
|
||||
|
||||
(add-to-list 'load-path (directory-file-name
|
||||
(or (file-name-directory #$) (car load-path))))
|
||||
|
||||
|
||||
;;;### (autoloads nil "company-anaconda" "company-anaconda.el" (0
|
||||
;;;;;; 0 0 0))
|
||||
;;; Generated autoloads from company-anaconda.el
|
||||
|
||||
(autoload 'company-anaconda "company-anaconda" "\
|
||||
Anaconda backend for company-mode.
|
||||
See `company-backends' for more info about COMMAND and ARG.
|
||||
|
||||
\(fn COMMAND &optional ARG &rest ARGS)" t nil)
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "company-anaconda" '("company-anaconda-")))
|
||||
|
||||
;;;***
|
||||
|
||||
;; Local Variables:
|
||||
;; version-control: never
|
||||
;; no-byte-compile: t
|
||||
;; no-update-autoloads: t
|
||||
;; coding: utf-8
|
||||
;; End:
|
||||
;;; company-anaconda-autoloads.el ends here
|
||||
@@ -0,0 +1,2 @@
|
||||
;;; Generated package description from company-anaconda.el -*- no-byte-compile: t -*-
|
||||
(define-package "company-anaconda" "20200404.1859" "Anaconda backend for company-mode" '((company "0.8.0") (anaconda-mode "0.1.1") (cl-lib "0.5.0") (dash "2.6.0") (s "1.9")) :commit "da1566db41a68809ef7f91ebf2de28118067c89b" :authors '(("Artem Malyshev" . "proofit404@gmail.com")) :maintainer '("Artem Malyshev" . "proofit404@gmail.com") :url "https://github.com/proofit404/anaconda-mode")
|
||||
155
elpa-27.2/company-anaconda-20200404.1859/company-anaconda.el
Normal file
155
elpa-27.2/company-anaconda-20200404.1859/company-anaconda.el
Normal file
@@ -0,0 +1,155 @@
|
||||
;;; company-anaconda.el --- Anaconda backend for company-mode -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2013-2018 by Artem Malyshev
|
||||
|
||||
;; Author: Artem Malyshev <proofit404@gmail.com>
|
||||
;; URL: https://github.com/proofit404/anaconda-mode
|
||||
;; Package-Version: 20200404.1859
|
||||
;; Package-Commit: da1566db41a68809ef7f91ebf2de28118067c89b
|
||||
;; Version: 0.2.0
|
||||
;; Package-Requires: ((company "0.8.0") (anaconda-mode "0.1.1") (cl-lib "0.5.0") (dash "2.6.0") (s "1.9"))
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; See the README for more details.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'anaconda-mode)
|
||||
(require 'company)
|
||||
(require 'python)
|
||||
(require 'cl-lib)
|
||||
(require 'rx)
|
||||
(require 'dash)
|
||||
(require 's)
|
||||
|
||||
(defgroup company-anaconda nil
|
||||
"Company back-end for Python code completion."
|
||||
:group 'programming)
|
||||
|
||||
(defcustom company-anaconda-annotation-function
|
||||
'company-anaconda-annotation
|
||||
"Function that returns candidate annotations."
|
||||
:group 'company-anaconda
|
||||
:type 'function)
|
||||
|
||||
(defcustom company-anaconda-case-insensitive t
|
||||
"Use case insensitive candidates match."
|
||||
:group 'company-anaconda
|
||||
:type 'boolean)
|
||||
|
||||
(defun company-anaconda-at-the-end-of-identifier ()
|
||||
"Check if the cursor at the end of completable identifier."
|
||||
(let ((limit (line-beginning-position)))
|
||||
(or
|
||||
;; We can't determine at this point if we can complete on a space
|
||||
(looking-back " " limit)
|
||||
;; At the end of the symbol, but not the end of int number
|
||||
(and (looking-at "\\_>")
|
||||
(not (looking-back "\\_<\\(0[bo]\\)?[[:digit:]]+" limit))
|
||||
(not (looking-back "\\_<0x[[:xdigit:]]+" limit)))
|
||||
;; After the dot, but not when it's a dot after int number
|
||||
;; Although identifiers like "foo1.", "foo111.", or "foo1baz2." are ok
|
||||
(and (looking-back "\\." (- (point) 1))
|
||||
(not (looking-back "\\_<[[:digit:]]+\\." limit)))
|
||||
;; After dot in float constant like "1.1." or ".1."
|
||||
(or (looking-back "\\_<[[:digit:]]+\\.[[:digit:]]+\\." limit)
|
||||
(looking-back "\\.[[:digit:]]+\\." limit)))))
|
||||
|
||||
(defun company-anaconda-prefix ()
|
||||
"Grab prefix at point."
|
||||
(and anaconda-mode
|
||||
(not (company-in-string-or-comment))
|
||||
(company-anaconda-at-the-end-of-identifier)
|
||||
(let* ((line-start (line-beginning-position))
|
||||
(start
|
||||
(save-excursion
|
||||
(if (not (re-search-backward
|
||||
(python-rx
|
||||
(or whitespace open-paren close-paren string-delimiter))
|
||||
line-start
|
||||
t 1))
|
||||
line-start
|
||||
(forward-char (length (match-string-no-properties 0)))
|
||||
(point))))
|
||||
(symbol (buffer-substring-no-properties start (point))))
|
||||
(if (or (s-ends-with-p "." symbol)
|
||||
(string-match-p
|
||||
(rx (* space) word-start (or "from" "import") word-end space)
|
||||
(buffer-substring-no-properties line-start (point))))
|
||||
(cons symbol t)
|
||||
(if (s-blank-p symbol)
|
||||
'stop
|
||||
symbol)))))
|
||||
|
||||
(defun company-anaconda-candidates (callback given-prefix)
|
||||
"Pass candidates list for GIVEN-PREFIX to the CALLBACK asynchronously."
|
||||
(anaconda-mode-call
|
||||
"company_complete"
|
||||
(lambda (result)
|
||||
(funcall callback
|
||||
(--map
|
||||
(let ((candidate (s-concat given-prefix (aref it 0))))
|
||||
(put-text-property 0 1 'struct it candidate)
|
||||
candidate)
|
||||
result)))))
|
||||
|
||||
(defun company-anaconda-annotation (candidate)
|
||||
"Return the description property of CANDIDATE inside chevrons."
|
||||
(--when-let (aref (get-text-property 0 'struct candidate) 1)
|
||||
(concat "<" it ">")))
|
||||
|
||||
(defun company-anaconda-doc-buffer (candidate)
|
||||
"Return documentation buffer for chosen CANDIDATE."
|
||||
(let ((docstring (aref (get-text-property 0 'struct candidate) 2)))
|
||||
(unless (s-blank? docstring)
|
||||
(anaconda-mode-documentation-view (vector (vector "" docstring))))))
|
||||
|
||||
(defun company-anaconda-meta (candidate)
|
||||
"Return short documentation string for chosen CANDIDATE."
|
||||
(let ((docstring (aref (get-text-property 0 'struct candidate) 2)))
|
||||
(unless (s-blank? docstring)
|
||||
(car (s-split-up-to "\n" docstring 1)))))
|
||||
|
||||
(defun company-anaconda-location (candidate)
|
||||
"Return location (path . line) for chosen CANDIDATE."
|
||||
(-when-let* ((struct (get-text-property 0 'struct candidate))
|
||||
(module-path (pythonic-emacs-readable-file-name (aref struct 3)))
|
||||
(line (aref struct 4)))
|
||||
(cons module-path line)))
|
||||
|
||||
;;;###autoload
|
||||
(defun company-anaconda (command &optional arg &rest _args)
|
||||
"Anaconda backend for company-mode.
|
||||
See `company-backends' for more info about COMMAND and ARG."
|
||||
(interactive (list 'interactive))
|
||||
(cl-case command
|
||||
(interactive (company-begin-backend 'company-anaconda))
|
||||
(prefix (company-anaconda-prefix))
|
||||
(candidates (cons :async
|
||||
(let ((given-prefix (s-chop-suffix (company-grab-symbol) arg)))
|
||||
(lambda (callback)
|
||||
(company-anaconda-candidates callback given-prefix)))))
|
||||
(doc-buffer (company-anaconda-doc-buffer arg))
|
||||
(meta (company-anaconda-meta arg))
|
||||
(annotation (funcall company-anaconda-annotation-function arg))
|
||||
(location (company-anaconda-location arg))
|
||||
(ignore-case company-anaconda-case-insensitive)
|
||||
(sorted t)))
|
||||
|
||||
(provide 'company-anaconda)
|
||||
|
||||
;;; company-anaconda.el ends here
|
||||
BIN
elpa-27.2/company-anaconda-20200404.1859/company-anaconda.elc
Normal file
BIN
elpa-27.2/company-anaconda-20200404.1859/company-anaconda.elc
Normal file
Binary file not shown.
92
elpa-27.2/elpy-20220203.108/elpy-autoloads.el
Normal file
92
elpa-27.2/elpy-20220203.108/elpy-autoloads.el
Normal file
@@ -0,0 +1,92 @@
|
||||
;;; elpy-autoloads.el --- automatically extracted autoloads
|
||||
;;
|
||||
;;; Code:
|
||||
|
||||
(add-to-list 'load-path (directory-file-name
|
||||
(or (file-name-directory #$) (car load-path))))
|
||||
|
||||
|
||||
;;;### (autoloads nil "elpy" "elpy.el" (0 0 0 0))
|
||||
;;; Generated autoloads from elpy.el
|
||||
|
||||
(autoload 'elpy-enable "elpy" "\
|
||||
Enable Elpy in all future Python buffers.
|
||||
|
||||
\(fn &optional IGNORED)" t nil)
|
||||
|
||||
(autoload 'elpy-mode "elpy" "\
|
||||
Minor mode in Python buffers for the Emacs Lisp Python Environment.
|
||||
|
||||
If called interactively, enable Elpy mode if ARG is positive, and
|
||||
disable it if ARG is zero or negative. If called from Lisp, also
|
||||
enable the mode if ARG is omitted or nil, and toggle it if ARG is
|
||||
`toggle'; disable the mode otherwise.
|
||||
|
||||
This mode fully supports virtualenvs. Once you switch a
|
||||
virtualenv using \\[pyvenv-workon], you can use
|
||||
\\[elpy-rpc-restart] to make the elpy Python process use your
|
||||
virtualenv.
|
||||
|
||||
\\{elpy-mode-map}
|
||||
|
||||
\(fn &optional ARG)" t nil)
|
||||
|
||||
(autoload 'elpy-config "elpy" "\
|
||||
Configure Elpy.
|
||||
|
||||
This function will pop up a configuration buffer, which is mostly
|
||||
a customize buffer, but has some more options." t nil)
|
||||
|
||||
(autoload 'elpy-version "elpy" "\
|
||||
Display the version of Elpy." t nil)
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "elpy" '("elpy-")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "elpy-django" "elpy-django.el" (0 0 0 0))
|
||||
;;; Generated autoloads from elpy-django.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "elpy-django" '("elpy-")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "elpy-profile" "elpy-profile.el" (0 0 0 0))
|
||||
;;; Generated autoloads from elpy-profile.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "elpy-profile" '("elpy-profile-")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "elpy-refactor" "elpy-refactor.el" (0 0 0 0))
|
||||
;;; Generated autoloads from elpy-refactor.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "elpy-refactor" '("elpy-refactor-")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "elpy-rpc" "elpy-rpc.el" (0 0 0 0))
|
||||
;;; Generated autoloads from elpy-rpc.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "elpy-rpc" '("elpy-" "with-elpy-rpc-virtualenv-activated")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "elpy-shell" "elpy-shell.el" (0 0 0 0))
|
||||
;;; Generated autoloads from elpy-shell.el
|
||||
|
||||
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "elpy-shell" '("elpy-")))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil nil ("elpy-pkg.el") (0 0 0 0))
|
||||
|
||||
;;;***
|
||||
|
||||
;; Local Variables:
|
||||
;; version-control: never
|
||||
;; no-byte-compile: t
|
||||
;; no-update-autoloads: t
|
||||
;; coding: utf-8
|
||||
;; End:
|
||||
;;; elpy-autoloads.el ends here
|
||||
335
elpa-27.2/elpy-20220203.108/elpy-django.el
Normal file
335
elpa-27.2/elpy-20220203.108/elpy-django.el
Normal file
@@ -0,0 +1,335 @@
|
||||
;;; elpy-django.el --- Django extension for elpy
|
||||
|
||||
;; Copyright (C) 2013-2019 Jorgen Schaefer
|
||||
|
||||
;; Author: Daniel Gopar <gopardaniel@gmail.com>
|
||||
;; URL: https://github.com/jorgenschaefer/elpy
|
||||
|
||||
;; This program is free software; you can redistribute it and/or
|
||||
;; modify it under the terms of the GNU General Public License
|
||||
;; as published by the Free Software Foundation; either version 3
|
||||
;; of the License, or (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This file serves as an extension to elpy by adding django support
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 's)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; User customization
|
||||
|
||||
(defcustom elpy-django-command "django-admin.py"
|
||||
"Command to use when running Django specific commands.
|
||||
Best to set it to full path to 'manage.py' if it's available."
|
||||
:type 'string
|
||||
:safe 'stringp
|
||||
:group 'elpy-django)
|
||||
(make-variable-buffer-local 'elpy-django-command)
|
||||
|
||||
(defcustom elpy-django-server-ipaddr "127.0.0.1"
|
||||
"What address Django will use when running the dev server."
|
||||
:type 'string
|
||||
:safe 'stringp
|
||||
:group 'elpy-django)
|
||||
(make-variable-buffer-local 'elpy-django-server-ipaddr)
|
||||
|
||||
(defcustom elpy-django-server-port "8000"
|
||||
"What port Django will use when running the dev server."
|
||||
:type 'string
|
||||
:safe 'stringp
|
||||
:group 'elpy-django)
|
||||
(make-variable-buffer-local 'elpy-django-server-port)
|
||||
|
||||
(defcustom elpy-django-server-command "runserver"
|
||||
"When executing `elpy-django-runserver' what should be the server
|
||||
command to use."
|
||||
:type 'string
|
||||
:safe 'stringp
|
||||
:group 'elpy-django)
|
||||
(make-variable-buffer-local 'elpy-django-server-command)
|
||||
|
||||
(defcustom elpy-django-always-prompt nil
|
||||
"When non-nil, it will always prompt for extra arguments
|
||||
to pass with the chosen command."
|
||||
:type 'boolean
|
||||
:safe 'booleanp
|
||||
:group 'elpy-django)
|
||||
(make-variable-buffer-local 'elpy-django-always-prompt)
|
||||
|
||||
(defcustom elpy-django-commands-with-req-arg '("startapp" "startproject"
|
||||
"loaddata" "sqlmigrate"
|
||||
"sqlsequencereset"
|
||||
"squashmigrations")
|
||||
"Used to determine if we should prompt for arguments. Some commands
|
||||
require arguments in order for it to work."
|
||||
:type 'list
|
||||
:safe 'listp
|
||||
:group 'elpy-django)
|
||||
(make-variable-buffer-local 'elpy-django-commands-with-req-arg)
|
||||
|
||||
(defcustom elpy-django-test-runner-formats '(("django_nose.NoseTestSuiteRunner" . ":")
|
||||
(".*" . "."))
|
||||
"List of test runners and their format for calling tests.
|
||||
|
||||
The keys are the regular expressions to match the runner used in test,
|
||||
while the values are the separators to use to build test target path.
|
||||
Some tests runners are called differently. For example, Nose requires a ':' when calling specific tests,
|
||||
but the default Django test runner uses '.'"
|
||||
:type 'list
|
||||
:safe 'listp
|
||||
:group 'elpy-django)
|
||||
(make-variable-buffer-local 'elpy-django-test-runner-formats)
|
||||
|
||||
(defcustom elpy-django-test-runner-args '("test" "--noinput")
|
||||
"Arguments to pass to the test runner when calling tests."
|
||||
:type '(repeat string)
|
||||
:group 'elpy-django)
|
||||
(make-variable-buffer-local 'elpy-django-test-runner-args)
|
||||
|
||||
(defcustom elpy-test-django-runner-command nil
|
||||
"Deprecated. Please define Django command in `elpy-django-command' and
|
||||
test arguments in `elpy-django-test-runner-args'"
|
||||
:type '(repeat string)
|
||||
:group 'elpy-django)
|
||||
(make-obsolete-variable 'elpy-test-django-runner-command nil "March 2018")
|
||||
|
||||
(defcustom elpy-test-django-runner-manage-command nil
|
||||
"Deprecated. Please define Django command in `elpy-django-command' and
|
||||
test arguments in `elpy-django-test-runner-args'."
|
||||
:type '(repeat string)
|
||||
:group 'elpy-django)
|
||||
(make-obsolete-variable 'elpy-test-django-runner-manage-command nil "March 2018")
|
||||
|
||||
(defcustom elpy-test-django-with-manage nil
|
||||
"Deprecated. Please define Django command in `elpy-django-command' and
|
||||
test arguments in `elpy-django-test-runner-args'."
|
||||
:type 'boolean
|
||||
:group 'elpy-django)
|
||||
(make-obsolete-variable 'elpy-test-django-with-manage nil "March 2018")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Key map
|
||||
|
||||
(defvar elpy-django-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map (kbd "c") 'elpy-django-command)
|
||||
(define-key map (kbd "r") 'elpy-django-runserver)
|
||||
map)
|
||||
"Key map for django extension")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; Helper Functions
|
||||
|
||||
(defun elpy-django-setup ()
|
||||
"Decides whether to start the minor mode or not."
|
||||
;; Make sure we're in an actual file and we can find
|
||||
;; manage.py. Otherwise user will have to manually
|
||||
;; start this mode if they're using 'django-admin.py'
|
||||
(when (locate-dominating-file default-directory "manage.py")
|
||||
;; Let's be nice and point to full path of 'manage.py'
|
||||
;; This only affects the buffer if there's no directory
|
||||
;; variable overwriting it.
|
||||
(setq elpy-django-command
|
||||
(expand-file-name (concat (locate-dominating-file default-directory "manage.py") "manage.py")))
|
||||
(elpy-django 1)))
|
||||
|
||||
(defun elpy-project-find-django-root ()
|
||||
"Return the current Django project root, if any.
|
||||
|
||||
This is marked with 'manage.py' or 'django-admin.py'."
|
||||
(or (locate-dominating-file default-directory "django-admin.py")
|
||||
(locate-dominating-file default-directory "manage.py")))
|
||||
|
||||
(defun elpy-django--get-commands ()
|
||||
"Return list of django commands."
|
||||
(let ((dj-commands-str nil)
|
||||
(help-output
|
||||
(shell-command-to-string (concat elpy-django-command " -h"))))
|
||||
(setq dj-commands-str
|
||||
(with-temp-buffer
|
||||
(progn
|
||||
(insert help-output)
|
||||
(goto-char (point-min))
|
||||
(delete-region (point) (search-forward "Available subcommands:" nil nil nil))
|
||||
;; cleanup [auth] and stuff
|
||||
(goto-char (point-min))
|
||||
(save-excursion
|
||||
(while (re-search-forward "\\[.*\\]" nil t)
|
||||
(replace-match "" nil nil)))
|
||||
(buffer-string))))
|
||||
;; get a list of commands from the output of manage.py -h
|
||||
;; What would be the pattern to optimize this ?
|
||||
(setq dj-commands-str (split-string dj-commands-str "\n"))
|
||||
(setq dj-commands-str (cl-remove-if (lambda (x) (string= x "")) dj-commands-str))
|
||||
(setq dj-commands-str (mapcar (lambda (x) (s-trim x)) dj-commands-str))
|
||||
(sort dj-commands-str 'string-lessp)))
|
||||
|
||||
|
||||
(defvar elpy-django--test-runner-cache nil
|
||||
"Internal cache for elpy-django--get-test-runner.
|
||||
The cache is keyed on project root and DJANGO_SETTINGS_MODULE env var")
|
||||
|
||||
(defvar elpy-django--test-runner-cache-max-size 100
|
||||
"Maximum number of entries in test runner cache")
|
||||
|
||||
|
||||
(defun elpy-django--get-test-runner ()
|
||||
"Return the name of the django test runner.
|
||||
Needs `DJANGO_SETTINGS_MODULE' to be set in order to work.
|
||||
The result is memoized on project root and `DJANGO_SETTINGS_MODULE'"
|
||||
(let ((django-import-cmd "import django;django.setup();from django.conf import settings;print(settings.TEST_RUNNER)")
|
||||
(django-settings-env (getenv "DJANGO_SETTINGS_MODULE"))
|
||||
(default-directory (elpy-project-root)))
|
||||
;; If no Django settings has been set, then nothing will work. Warn user
|
||||
(unless django-settings-env
|
||||
(error "Please set environment variable `DJANGO_SETTINGS_MODULE' if you'd like to run the test runner"))
|
||||
|
||||
(let* ((runner-key (list default-directory django-settings-env))
|
||||
(runner (or (elpy-django--get-test-runner-from-cache runner-key)
|
||||
(elpy-django--cache-test-runner
|
||||
runner-key
|
||||
(elpy-django--detect-test-runner django-settings-env)))))
|
||||
(elpy-django--limit-test-runner-cache-size)
|
||||
runner)))
|
||||
|
||||
|
||||
(defun elpy-django--get-test-format ()
|
||||
"When running a Django test, some test runners require a different format than others.
|
||||
Return the correct string format here."
|
||||
(let ((runner (elpy-django--get-test-runner))
|
||||
(found nil)
|
||||
(formats elpy-django-test-runner-formats))
|
||||
(while (and formats (not found))
|
||||
(let* ((entry (car formats)) (regex (car entry)))
|
||||
(when (string-match regex runner)
|
||||
(setq found (cdr entry))))
|
||||
(setq formats (cdr formats)))
|
||||
(or found (error (format "Unable to find test format for `%s'"
|
||||
(elpy-django--get-test-runner))))))
|
||||
|
||||
|
||||
(defun elpy-django--detect-test-runner (django-settings-env)
|
||||
"Detects django test runner in current configuration"
|
||||
;; We have to be able to import the DJANGO_SETTINGS_MODULE to detect test
|
||||
;; runner; if python process importing settings exits with error,
|
||||
;; then warn the user that settings is not valid
|
||||
(unless (= 0 (call-process elpy-rpc-python-command nil nil nil
|
||||
"-c" (format "import %s" django-settings-env)))
|
||||
(error (format "Unable to import DJANGO_SETTINGS_MODULE: '%s'"
|
||||
django-settings-env)))
|
||||
(s-trim (shell-command-to-string
|
||||
(format "%s -c '%s'" elpy-rpc-python-command
|
||||
django-import-cmd))))
|
||||
|
||||
|
||||
(defun elpy-django--get-test-runner-from-cache (key)
|
||||
"Retrieve from cache test runner with given caching key.
|
||||
Return nil if the runner is missing in cache"
|
||||
(let ((runner (cdr (assoc key elpy-django--test-runner-cache))))
|
||||
;; if present re-add to implement lru cache
|
||||
(when runner (elpy-django--cache-test-runner key runner))))
|
||||
|
||||
|
||||
(defun elpy-django--cache-test-runner (key runner)
|
||||
"Store in test runner cache a runner with a key"""
|
||||
(push (cons key runner) elpy-django--test-runner-cache)
|
||||
runner)
|
||||
|
||||
|
||||
(defun elpy-django--limit-test-runner-cache-size ()
|
||||
"Ensure elpy-django--test-runner-cache does not overflow a fixed size"
|
||||
(while (> (length elpy-django--test-runner-cache)
|
||||
elpy-django--test-runner-cache-max-size)
|
||||
(setq elpy-django--test-runner-cache (cdr elpy-django--test-runner-cache))))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; User Functions
|
||||
|
||||
(defun elpy-django-command (cmd)
|
||||
"Prompt user for Django command. If called with `C-u',
|
||||
it will prompt for other flags/arguments to run."
|
||||
(interactive (list (completing-read "Command: " (elpy-django--get-commands) nil nil)))
|
||||
;; Called with C-u, variable is set or is a cmd that requires an argument
|
||||
(when (or current-prefix-arg
|
||||
elpy-django-always-prompt
|
||||
(member cmd elpy-django-commands-with-req-arg))
|
||||
(setq cmd (concat cmd " " (read-shell-command (concat cmd ": ") "--noinput"))))
|
||||
;;
|
||||
(cond ((string= cmd "shell")
|
||||
(run-python (concat elpy-django-command " shell -i python") t t))
|
||||
(t
|
||||
(let* ((program (car (split-string elpy-django-command)))
|
||||
(args (cdr (split-string elpy-django-command)))
|
||||
(buffer-name (format "django-%s" (car (split-string cmd)))))
|
||||
(when (get-buffer (format "*%s*" buffer-name))
|
||||
(kill-buffer (format "*%s*" buffer-name)))
|
||||
(pop-to-buffer
|
||||
(apply 'make-comint buffer-name program nil
|
||||
(append args (split-string cmd))))))))
|
||||
|
||||
(defun elpy-django-runserver (arg)
|
||||
"Start the server and automatically add the ipaddr and port.
|
||||
Also create it's own special buffer so that we can have multiple
|
||||
servers running per project.
|
||||
|
||||
When called with a prefix (C-u), it will prompt for additional args."
|
||||
(interactive "P")
|
||||
(let* ((cmd (concat elpy-django-command " " elpy-django-server-command))
|
||||
(proj-root (if (elpy-project-root)
|
||||
(file-name-base (directory-file-name
|
||||
(elpy-project-root)))
|
||||
(message "Elpy cannot find the root of the current django project. Starting the server in the current directory: '%s'."
|
||||
default-directory)
|
||||
default-directory))
|
||||
(buff-name (format "*runserver[%s]*" proj-root)))
|
||||
;; Kill any previous instance of runserver since we might be doing something new
|
||||
(when (get-buffer buff-name)
|
||||
(kill-buffer buff-name))
|
||||
(setq cmd (concat cmd " " elpy-django-server-ipaddr ":" elpy-django-server-port))
|
||||
(when (or arg elpy-django-always-prompt)
|
||||
(setq cmd (concat cmd " "(read-shell-command (concat cmd ": ")))))
|
||||
(compile cmd)
|
||||
(with-current-buffer "*compilation*"
|
||||
(rename-buffer buff-name))))
|
||||
|
||||
(defun elpy-test-django-runner (top _file module test)
|
||||
"Test the project using the Django discover runner,
|
||||
or with manage.py if elpy-test-django-with-manage is true.
|
||||
|
||||
This requires Django 1.6 or the django-discover-runner package."
|
||||
(interactive (elpy-test-at-point))
|
||||
(if module
|
||||
(apply #'elpy-test-run
|
||||
top
|
||||
(append
|
||||
(list elpy-django-command)
|
||||
elpy-django-test-runner-args
|
||||
(list (if test
|
||||
(format "%s%s%s" module (elpy-django--get-test-format) test)
|
||||
module))))
|
||||
(apply #'elpy-test-run
|
||||
top
|
||||
(append
|
||||
(list elpy-django-command)
|
||||
elpy-django-test-runner-args))))
|
||||
(put 'elpy-test-django-runner 'elpy-test-runner-p t)
|
||||
|
||||
(define-minor-mode elpy-django
|
||||
"Minor mode for Django commands."
|
||||
:group 'elpy-django)
|
||||
|
||||
(provide 'elpy-django)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; elpy-django.el ends here
|
||||
BIN
elpa-27.2/elpy-20220203.108/elpy-django.elc
Normal file
BIN
elpa-27.2/elpy-20220203.108/elpy-django.elc
Normal file
Binary file not shown.
17
elpa-27.2/elpy-20220203.108/elpy-pkg.el
Normal file
17
elpa-27.2/elpy-20220203.108/elpy-pkg.el
Normal file
@@ -0,0 +1,17 @@
|
||||
(define-package "elpy" "20220203.108" "Emacs Python Development Environment"
|
||||
'((company "0.9.2")
|
||||
(emacs "24.4")
|
||||
(highlight-indentation "0.5.0")
|
||||
(pyvenv "1.3")
|
||||
(yasnippet "0.8.0")
|
||||
(s "1.11.0"))
|
||||
:commit "9b458c80dc1bcecb6345e157d8e921c1e4e8a7ea" :authors
|
||||
'(("Jorgen Schaefer <contact@jorgenschaefer.de>, Gaby Launay" . "gaby.launay@protonmail.com"))
|
||||
:maintainer
|
||||
'("Jorgen Schaefer <contact@jorgenschaefer.de>, Gaby Launay" . "gaby.launay@protonmail.com")
|
||||
:keywords
|
||||
'("python" "ide" "languages" "tools")
|
||||
:url "https://github.com/jorgenschaefer/elpy")
|
||||
;; Local Variables:
|
||||
;; no-byte-compile: t
|
||||
;; End:
|
||||
114
elpa-27.2/elpy-20220203.108/elpy-profile.el
Normal file
114
elpa-27.2/elpy-20220203.108/elpy-profile.el
Normal file
@@ -0,0 +1,114 @@
|
||||
;;; elpy-profile.el --- Profiling capabilitiss for elpy
|
||||
|
||||
;; Copyright (C) 2013-2019 Jorgen Schaefer
|
||||
|
||||
;; Author: Gaby Launay <gaby.launay@tutanota.com>
|
||||
;; URL: https://github.com/jorgenschaefer/elpy
|
||||
|
||||
;; This program is free software; you can redistribute it and/or
|
||||
;; modify it under the terms of the GNU General Public License
|
||||
;; as published by the Free Software Foundation; either version 3
|
||||
;; of the License, or (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This file serves as an extension to elpy by adding profiling capabilities
|
||||
|
||||
;;; Code:
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; User customization
|
||||
|
||||
(defcustom elpy-profile-visualizer "snakeviz"
|
||||
"Visualizer for elpy profile results."
|
||||
:type '(choice (const :tag "Snakeviz" "snakeviz")
|
||||
(const :tag "RunSnakeRun" "runsnake")
|
||||
(const :tag "pyprof2calltree" "pyprof2calltree -k -i")
|
||||
(string :tag "Other"))
|
||||
:group 'elpy)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; Helper Functions
|
||||
|
||||
(defun elpy-profile--display-profiling (file)
|
||||
"Display the profile result FILE using `elpy-profile-visualizer'."
|
||||
(let ((exec (car (split-string elpy-profile-visualizer " " t)))
|
||||
(args (append (cdr (split-string elpy-profile-visualizer " " t)) (list file))))
|
||||
(if (executable-find exec)
|
||||
(apply 'call-process exec nil 0 nil args)
|
||||
(message "Elpy profile visualizer '%s' not found" exec))))
|
||||
|
||||
(defun elpy-profile--sentinel (process string)
|
||||
"Elpy profile sentinel."
|
||||
(let ((filename (file-name-nondirectory (process-get process 'file)))
|
||||
(prof-file (process-get process 'prof-file))
|
||||
(dont-display (process-get process 'dont-display)))
|
||||
(with-current-buffer "*elpy-profile-log*"
|
||||
(view-mode))
|
||||
(if (not (string-equal string "finished\n"))
|
||||
(progn
|
||||
(message "[%s] Profiling failed" filename)
|
||||
(display-buffer "*elpy-profile-log*"))
|
||||
(message "[%s] Profiling succeeded" filename)
|
||||
(unless dont-display
|
||||
(elpy-profile--display-profiling prof-file)))))
|
||||
|
||||
(defun elpy-profile--file (file &optional in-dir dont-display)
|
||||
"Profile asynchronously FILE and display the result using
|
||||
`elpy-profile-visualizer'.
|
||||
|
||||
If IN-DIR is non nil, profile result is saved in the same
|
||||
directory as the script.
|
||||
If DONT-DISPLAY is non nil, don't display the profile results."
|
||||
(ignore-errors (kill-buffer "*elpy-profile-log*"))
|
||||
(let* ((prof-file (if in-dir
|
||||
(concat (file-name-sans-extension file) ".profile")
|
||||
(concat (make-temp-file "elpy-profile-" nil ".profile"))))
|
||||
(proc-name (format "elpy-profile-%s" file))
|
||||
(proc-cmd (list elpy-rpc-python-command "-m" "cProfile" "-o" prof-file file))
|
||||
(proc (make-process :name proc-name
|
||||
:buffer "*elpy-profile-log*"
|
||||
:sentinel 'elpy-profile--sentinel
|
||||
:command proc-cmd)))
|
||||
(message "[%s] Profiling ..." (file-name-nondirectory file))
|
||||
(process-put proc 'prof-file prof-file)
|
||||
(process-put proc 'file file)
|
||||
(process-put proc 'dont-display dont-display)
|
||||
prof-file))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; User Functions
|
||||
|
||||
(defun elpy-profile-buffer-or-region (&optional in-dir dont-display)
|
||||
"Profile asynchronously the active region or the current buffer
|
||||
and display the result using `elpy-profile-visualizer'.
|
||||
|
||||
If IN-DIR is non nil, profile result is saved in the same
|
||||
directory as the script.
|
||||
If DONT-DISPLAY is non nil, don't display the profile results."
|
||||
(interactive "P")
|
||||
(let* ((file-name (buffer-name))
|
||||
(file-dir (file-name-directory (buffer-file-name)))
|
||||
(beg (if (region-active-p) (region-beginning) (point-min)))
|
||||
(end (if (region-active-p) (region-end) (point-max)))
|
||||
(tmp-file-prefix (if (region-active-p) "_region_" ""))
|
||||
(tmp-file (if in-dir
|
||||
(concat file-dir "/" tmp-file-prefix file-name)
|
||||
(concat (make-temp-file "elpy-profile-" t) "/" tmp-file-prefix file-name)))
|
||||
(region (python-shell-buffer-substring beg end)))
|
||||
(with-temp-buffer
|
||||
(insert region)
|
||||
(write-region (point-min) (point-max) tmp-file nil t))
|
||||
(elpy-profile--file tmp-file t dont-display)))
|
||||
|
||||
(provide 'elpy-profile)
|
||||
;;; elpy-profile.el ends here
|
||||
BIN
elpa-27.2/elpy-20220203.108/elpy-profile.elc
Normal file
BIN
elpa-27.2/elpy-20220203.108/elpy-profile.elc
Normal file
Binary file not shown.
321
elpa-27.2/elpy-20220203.108/elpy-refactor.el
Normal file
321
elpa-27.2/elpy-20220203.108/elpy-refactor.el
Normal file
@@ -0,0 +1,321 @@
|
||||
;;; elpy-refactor.el --- Refactoring mode for Elpy
|
||||
|
||||
;; Copyright (C) 2020 Gaby Launay
|
||||
|
||||
;; Author: Gaby Launay <gaby.launay@protonmail.com>
|
||||
;; URL: https://github.com/jorgenschaefer/elpy
|
||||
|
||||
;; This program is free software; you can redistribute it and/or
|
||||
;; modify it under the terms of the GNU General Public License
|
||||
;; as published by the Free Software Foundation; either version 3
|
||||
;; of the License, or (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This file provides an interface, including a major mode, to use
|
||||
;; refactoring options provided by the Jedi library.
|
||||
|
||||
;;; Code:
|
||||
|
||||
;; We require elpy, but elpy loads us, so we shouldn't load it back.
|
||||
;; (require 'elpy)
|
||||
(require 'diff-mode)
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; Refactor mode (for applying diffs)
|
||||
|
||||
(defvar elpy-refactor--saved-window-configuration nil
|
||||
"Saved windows configuration, so that we can restore it after `elpy-refactor' has done its thing.")
|
||||
|
||||
(defvar elpy-refactor--saved-pos nil
|
||||
"Line and column number of the position we were at before starting refactoring.")
|
||||
|
||||
(defvar elpy-refactor--modified-buffers '()
|
||||
"Keep track of the buffers modified by the current refactoring sessions.")
|
||||
|
||||
(defun elpy-refactor--apply-diff (proj-path diff)
|
||||
"Apply DIFF, looking for the files in PROJ-PATH."
|
||||
(let ((current-line (line-number-at-pos (point)))
|
||||
(current-col (- (point) (line-beginning-position))))
|
||||
(with-current-buffer (get-buffer-create " *Elpy Refactor*")
|
||||
(elpy-refactor-mode)
|
||||
(let ((inhibit-read-only t))
|
||||
(erase-buffer)
|
||||
(insert diff))
|
||||
(setq default-directory proj-path)
|
||||
(goto-char (point-min))
|
||||
(elpy-refactor--apply-whole-diff))
|
||||
(condition-case nil
|
||||
(progn
|
||||
(goto-char (point-min))
|
||||
(forward-line (- current-line 1))
|
||||
(beginning-of-line)
|
||||
(forward-char current-col))
|
||||
(error))
|
||||
))
|
||||
|
||||
(defun elpy-refactor--display-diff (proj-path diff)
|
||||
"Display DIFF in a `diff-mode' window.
|
||||
|
||||
DIFF files should be relative to PROJ-PATH."
|
||||
(setq elpy-refactor--saved-window-configuration (current-window-configuration)
|
||||
elpy-refactor--saved-pos (list (line-number-at-pos (point) t)
|
||||
(- (point) (line-beginning-position)))
|
||||
elpy-refactor--modified-buffers '())
|
||||
(with-current-buffer (get-buffer-create "*Elpy Refactor*")
|
||||
(elpy-refactor-mode)
|
||||
(let ((inhibit-read-only t))
|
||||
(erase-buffer)
|
||||
(insert (propertize
|
||||
(substitute-command-keys
|
||||
(concat
|
||||
"\\[diff-file-next] and \\[diff-file-prev] -- Move between files\n"
|
||||
"\\[diff-hunk-next] and \\[diff-hunk-prev] -- Move between hunks\n"
|
||||
"\\[diff-split-hunk] -- Split the current hunk at point\n"
|
||||
"\\[elpy-refactor--apply-hunk] -- Apply the current hunk\n"
|
||||
"\\[diff-kill-hunk] -- Kill the current hunk\n"
|
||||
"\\[elpy-refactor--apply-whole-diff] -- Apply the whole diff\n"
|
||||
"\\[elpy-refactor--quit] -- Quit\n"))
|
||||
'face 'bold)
|
||||
"\n\n")
|
||||
(align-regexp (point-min) (point-max) "\\(\\s-*\\) -- ")
|
||||
(goto-char (point-min))
|
||||
(while (search-forward " -- " nil t)
|
||||
(replace-match " " nil t))
|
||||
(goto-char (point-max))
|
||||
(insert diff))
|
||||
(setq default-directory proj-path)
|
||||
(goto-char (point-min))
|
||||
(if (diff--some-hunks-p)
|
||||
(progn
|
||||
(select-window (display-buffer (current-buffer)))
|
||||
(diff-hunk-next))
|
||||
;; quit if not diff at all...
|
||||
(message "No differences to validate")
|
||||
(kill-buffer (current-buffer)))))
|
||||
|
||||
(defvar elpy-refactor-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map (kbd "C-c C-c") 'elpy-refactor--apply-hunk)
|
||||
(define-key map (kbd "C-c C-a") 'elpy-refactor--apply-whole-diff)
|
||||
(define-key map (kbd "C-c C-x") 'diff-kill-hunk)
|
||||
(define-key map (kbd "q") 'elpy-refactor--quit)
|
||||
(define-key map (kbd "C-c C-k") 'elpy-refactor--quit)
|
||||
(define-key map (kbd "h") 'describe-mode)
|
||||
(define-key map (kbd "?") 'describe-mode)
|
||||
map)
|
||||
"The key map for `elpy-refactor-mode'.")
|
||||
|
||||
(define-derived-mode elpy-refactor-mode diff-mode "Elpy Refactor"
|
||||
"Mode to display refactoring actions and ask confirmation from the user.
|
||||
|
||||
\\{elpy-refactor-mode-map}"
|
||||
:group 'elpy
|
||||
(view-mode 1))
|
||||
|
||||
(defun elpy-refactor--apply-hunk ()
|
||||
"Apply the current hunk."
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(diff-apply-hunk))
|
||||
;; keep track of modified buffers
|
||||
(let ((buf (find-buffer-visiting (diff-find-file-name))))
|
||||
(when buf
|
||||
(add-to-list 'elpy-refactor--modified-buffers buf)))
|
||||
;;
|
||||
(diff-hunk-kill)
|
||||
(unless (diff--some-hunks-p)
|
||||
(elpy-refactor--quit)))
|
||||
|
||||
(defun elpy-refactor--apply-whole-diff ()
|
||||
"Apply the whole diff and quit."
|
||||
(interactive)
|
||||
(goto-char (point-min))
|
||||
(diff-hunk-next)
|
||||
(while (diff--some-hunks-p)
|
||||
(let ((buf (find-buffer-visiting (diff-find-file-name))))
|
||||
(when buf
|
||||
(add-to-list 'elpy-refactor--modified-buffers buf)))
|
||||
(condition-case nil
|
||||
(progn
|
||||
(save-excursion
|
||||
(diff-apply-hunk))
|
||||
(diff-hunk-kill))
|
||||
(error (diff-hunk-next)))) ;; if a hunk fail, switch to the next one
|
||||
;; quit
|
||||
(elpy-refactor--quit))
|
||||
|
||||
(defun elpy-refactor--quit ()
|
||||
"Quit the refactoring session."
|
||||
(interactive)
|
||||
;; save modified buffers
|
||||
(dolist (buf elpy-refactor--modified-buffers)
|
||||
(with-current-buffer buf
|
||||
(basic-save-buffer)))
|
||||
(setq elpy-refactor--modified-buffers '())
|
||||
;; kill refactoring buffer
|
||||
(kill-buffer (current-buffer))
|
||||
;; Restore window configuration
|
||||
(when elpy-refactor--saved-window-configuration
|
||||
(set-window-configuration elpy-refactor--saved-window-configuration)
|
||||
(setq elpy-refactor--saved-window-configuration nil))
|
||||
;; Restore cursor position
|
||||
(when elpy-refactor--saved-pos
|
||||
(goto-char (point-min))
|
||||
(forward-line (- (car elpy-refactor--saved-pos) 1))
|
||||
(forward-char (car (cdr elpy-refactor--saved-pos)))
|
||||
(setq elpy-refactor--saved-pos nil)))
|
||||
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;
|
||||
;; User functions
|
||||
|
||||
(defun elpy-refactor-rename (new-name &optional dontask)
|
||||
"Rename the symbol at point to NEW-NAME.
|
||||
|
||||
With a prefix argument (or if DONTASK is non-nil),
|
||||
do not display the diff before applying."
|
||||
(interactive (list
|
||||
(let ((old-name (thing-at-point 'symbol)))
|
||||
(if (or (not old-name)
|
||||
(not (elpy-refactor--is-valid-symbol-p old-name)))
|
||||
(error "No symbol at point")
|
||||
(read-string
|
||||
(format "New name for '%s': "
|
||||
(thing-at-point 'symbol))
|
||||
(thing-at-point 'symbol))))))
|
||||
(unless (and new-name
|
||||
(elpy-refactor--is-valid-symbol-p new-name))
|
||||
(error "'%s' is not a valid python symbol"))
|
||||
(message "Gathering occurences of '%s'..."
|
||||
(thing-at-point 'symbol))
|
||||
(let* ((elpy-rpc-timeout 10) ;; refactoring can be long...
|
||||
(diff (elpy-rpc-get-rename-diff new-name))
|
||||
(proj-path (alist-get 'project_path diff))
|
||||
(success (alist-get 'success diff))
|
||||
(diff (alist-get 'diff diff)))
|
||||
(cond ((not success)
|
||||
(error "Refactoring failed for some reason"))
|
||||
((string= success "Not available")
|
||||
(error "This functionnality needs jedi > 0.17.0, please update"))
|
||||
((or dontask current-prefix-arg)
|
||||
(message "Replacing '%s' with '%s'..."
|
||||
(thing-at-point 'symbol)
|
||||
new-name)
|
||||
(elpy-refactor--apply-diff proj-path diff)
|
||||
(message "Done"))
|
||||
(t
|
||||
(elpy-refactor--display-diff proj-path diff)))))
|
||||
|
||||
(defun elpy-refactor-extract-variable (new-name)
|
||||
"Extract the current region to a new variable NEW-NAME."
|
||||
(interactive "sNew name: ")
|
||||
(let ((beg (if (region-active-p)
|
||||
(region-beginning)
|
||||
(car (or (bounds-of-thing-at-point 'symbol)
|
||||
(error "No symbol at point")))))
|
||||
(end (if (region-active-p)
|
||||
(region-end)
|
||||
(cdr (bounds-of-thing-at-point 'symbol)))))
|
||||
(when (or (elpy-refactor--is-valid-symbol-p new-name)
|
||||
(y-or-n-p "'%s' does not appear to be a valid python symbol. Are you sure you want to use it? "))
|
||||
(let* ((line-beg (save-excursion
|
||||
(goto-char beg)
|
||||
(line-number-at-pos)))
|
||||
(line-end (save-excursion
|
||||
(goto-char end)
|
||||
(line-number-at-pos)))
|
||||
(col-beg (save-excursion
|
||||
(goto-char beg)
|
||||
(- (point) (line-beginning-position))))
|
||||
(col-end (save-excursion
|
||||
(goto-char end)
|
||||
(- (point) (line-beginning-position))))
|
||||
(diff (elpy-rpc-get-extract-variable-diff
|
||||
new-name line-beg line-end col-beg col-end))
|
||||
(proj-path (alist-get 'project_path diff))
|
||||
(success (alist-get 'success diff))
|
||||
(diff (alist-get 'diff diff)))
|
||||
(cond ((not success)
|
||||
(error "We could not extract the selection as a variable"))
|
||||
((string= success "Not available")
|
||||
(error "This functionnality needs jedi > 0.17.0, please update"))
|
||||
(t
|
||||
(deactivate-mark)
|
||||
(elpy-refactor--apply-diff proj-path diff)))))))
|
||||
|
||||
(defun elpy-refactor-extract-function (new-name)
|
||||
"Extract the current region to a new function NEW-NAME."
|
||||
(interactive "sNew function name: ")
|
||||
(unless (region-active-p)
|
||||
(error "No selection"))
|
||||
(when (or (elpy-refactor--is-valid-symbol-p new-name)
|
||||
(y-or-n-p "'%s' does not appear to be a valid python symbol. Are you sure you want to use it? "))
|
||||
(let* ((line-beg (save-excursion
|
||||
(goto-char (region-beginning))
|
||||
(line-number-at-pos)))
|
||||
(line-end (save-excursion
|
||||
(goto-char (region-end))
|
||||
(line-number-at-pos)))
|
||||
(col-beg (save-excursion
|
||||
(goto-char (region-beginning))
|
||||
(- (point) (line-beginning-position))))
|
||||
(col-end (save-excursion
|
||||
(goto-char (region-end))
|
||||
(- (point) (line-beginning-position))))
|
||||
(diff (elpy-rpc-get-extract-function-diff
|
||||
new-name line-beg line-end col-beg col-end))
|
||||
(proj-path (alist-get 'project_path diff))
|
||||
(success (alist-get 'success diff))
|
||||
(diff (alist-get 'diff diff)))
|
||||
(cond ((not success)
|
||||
(error "We could not extract the selection as a function"))
|
||||
((string= success "Not available")
|
||||
(error "This functionnality needs jedi > 0.17.0, please update"))
|
||||
(t
|
||||
(deactivate-mark)
|
||||
(elpy-refactor--apply-diff proj-path diff))))))
|
||||
|
||||
(defun elpy-refactor-inline ()
|
||||
"Inline the variable at point."
|
||||
(interactive)
|
||||
(let* ((diff (elpy-rpc-get-inline-diff))
|
||||
(proj-path (alist-get 'project_path diff))
|
||||
(success (alist-get 'success diff))
|
||||
(diff (alist-get 'diff diff)))
|
||||
(cond ((not success)
|
||||
(error "We could not inline the variable '%s'"
|
||||
(thing-at-point 'symbol)))
|
||||
((string= success "Not available")
|
||||
(error "This functionnality needs jedi > 0.17.0, please update"))
|
||||
(t
|
||||
(elpy-refactor--apply-diff proj-path diff)))))
|
||||
|
||||
|
||||
;;;;;;;;;;;;
|
||||
;; Utilities
|
||||
|
||||
(defun elpy-refactor--is-valid-symbol-p (symbol)
|
||||
"Return t if SYMBOL is a valid python symbol."
|
||||
(eq 0 (string-match "^[a-zA-Z_][a-zA-Z0-9_]*$" symbol)))
|
||||
|
||||
;;;;;;;;;;;;
|
||||
;; Compatibility
|
||||
(unless (fboundp 'diff--some-hunks-p)
|
||||
(defun diff--some-hunks-p ()
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(re-search-forward diff-hunk-header-re nil t))))
|
||||
|
||||
(provide 'elpy-refactor)
|
||||
;;; elpy-refactor.el ends here
|
||||
BIN
elpa-27.2/elpy-20220203.108/elpy-refactor.elc
Normal file
BIN
elpa-27.2/elpy-20220203.108/elpy-refactor.elc
Normal file
Binary file not shown.
1193
elpa-27.2/elpy-20220203.108/elpy-rpc.el
Normal file
1193
elpa-27.2/elpy-20220203.108/elpy-rpc.el
Normal file
File diff suppressed because it is too large
Load Diff
BIN
elpa-27.2/elpy-20220203.108/elpy-rpc.elc
Normal file
BIN
elpa-27.2/elpy-20220203.108/elpy-rpc.elc
Normal file
Binary file not shown.
1358
elpa-27.2/elpy-20220203.108/elpy-shell.el
Normal file
1358
elpa-27.2/elpy-20220203.108/elpy-shell.el
Normal file
File diff suppressed because it is too large
Load Diff
BIN
elpa-27.2/elpy-20220203.108/elpy-shell.elc
Normal file
BIN
elpa-27.2/elpy-20220203.108/elpy-shell.elc
Normal file
Binary file not shown.
4066
elpa-27.2/elpy-20220203.108/elpy.el
Normal file
4066
elpa-27.2/elpy-20220203.108/elpy.el
Normal file
File diff suppressed because it is too large
Load Diff
BIN
elpa-27.2/elpy-20220203.108/elpy.elc
Normal file
BIN
elpa-27.2/elpy-20220203.108/elpy.elc
Normal file
Binary file not shown.
41
elpa-27.2/elpy-20220203.108/elpy/__init__.py
Normal file
41
elpa-27.2/elpy-20220203.108/elpy/__init__.py
Normal file
@@ -0,0 +1,41 @@
|
||||
# Elpy, the Emacs Lisp Python Environment
|
||||
|
||||
# Copyright (C) 2013-2019 Jorgen Schaefer
|
||||
|
||||
# Author: Jorgen Schaefer <contact@jorgenschaefer.de>
|
||||
# URL: http://github.com/jorgenschaefer/elpy
|
||||
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 3
|
||||
# of the License, or (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""The Emacs Lisp Python Environment.
|
||||
|
||||
Elpy is a mode for Emacs to support writing Python code. This package
|
||||
provides the backend within Python to support auto-completion,
|
||||
documentation extraction, and navigation.
|
||||
|
||||
Emacs will start the protocol by running the module itself, like so:
|
||||
|
||||
python -m elpy
|
||||
|
||||
This will emit a greeting string on a single line, and then wait for
|
||||
the protocol to start. Details of the protocol can be found in
|
||||
elpy.rpc.
|
||||
|
||||
This package is unlikely to be useful on its own.
|
||||
|
||||
"""
|
||||
|
||||
__author__ = "Jorgen Schaefer"
|
||||
__version__ = "1.35.0"
|
||||
__license__ = "GPL"
|
||||
25
elpa-27.2/elpy-20220203.108/elpy/__main__.py
Normal file
25
elpa-27.2/elpy-20220203.108/elpy/__main__.py
Normal file
@@ -0,0 +1,25 @@
|
||||
"""Main interface to the RPC server.
|
||||
|
||||
You should be able to just run the following to use this module:
|
||||
|
||||
python -m elpy
|
||||
|
||||
The first line should be "elpy-rpc ready". If it isn't, something
|
||||
broke.
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import elpy
|
||||
from elpy.server import ElpyRPCServer
|
||||
|
||||
if __name__ == '__main__':
|
||||
stdin = sys.stdin
|
||||
stdout = sys.stdout
|
||||
sys.stdout = sys.stderr = open(os.devnull, "w")
|
||||
stdout.write('elpy-rpc ready ({0})\n'
|
||||
.format(elpy.__version__))
|
||||
stdout.flush()
|
||||
ElpyRPCServer(stdin, stdout).serve_forever()
|
||||
Binary file not shown.
27
elpa-27.2/elpy-20220203.108/elpy/auto_pep8.py
Normal file
27
elpa-27.2/elpy-20220203.108/elpy/auto_pep8.py
Normal file
@@ -0,0 +1,27 @@
|
||||
"""Glue for the "autopep8" library.
|
||||
|
||||
"""
|
||||
|
||||
from elpy.rpc import Fault
|
||||
import os
|
||||
|
||||
|
||||
try:
|
||||
import autopep8
|
||||
except ImportError: # pragma: no cover
|
||||
autopep8 = None
|
||||
|
||||
|
||||
def fix_code(code, directory):
|
||||
"""Formats Python code to conform to the PEP 8 style guide.
|
||||
|
||||
"""
|
||||
if not autopep8:
|
||||
raise Fault('autopep8 not installed, cannot fix code.',
|
||||
code=400)
|
||||
old_dir = os.getcwd()
|
||||
try:
|
||||
os.chdir(directory)
|
||||
return autopep8.fix_code(code, apply_config=True)
|
||||
finally:
|
||||
os.chdir(old_dir)
|
||||
79
elpa-27.2/elpy-20220203.108/elpy/blackutil.py
Normal file
79
elpa-27.2/elpy-20220203.108/elpy/blackutil.py
Normal file
@@ -0,0 +1,79 @@
|
||||
"""Glue for the "black" library.
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
from elpy.rpc import Fault
|
||||
# in case pkg_resources is not properly installed
|
||||
# (see https://github.com/jorgenschaefer/elpy/issues/1674).
|
||||
try:
|
||||
from pkg_resources import parse_version
|
||||
except ImportError: # pragma: no cover
|
||||
def parse_version(*arg, **kwargs):
|
||||
raise Fault("`pkg_resources` could not be imported, "
|
||||
"please reinstall Elpy RPC virtualenv with"
|
||||
" `M-x elpy-rpc-reinstall-virtualenv`", code=400)
|
||||
|
||||
import os
|
||||
|
||||
try:
|
||||
import toml
|
||||
except ImportError:
|
||||
toml = None
|
||||
|
||||
|
||||
BLACK_NOT_SUPPORTED = sys.version_info < (3, 6)
|
||||
|
||||
try:
|
||||
if BLACK_NOT_SUPPORTED: # pragma: no cover
|
||||
black = None
|
||||
else:
|
||||
import black
|
||||
current_version = parse_version(black.__version__)
|
||||
if current_version >= parse_version("21.5b1"):
|
||||
from black.files import find_pyproject_toml
|
||||
elif current_version >= parse_version("20.8b0"):
|
||||
from black import find_pyproject_toml
|
||||
else:
|
||||
find_pyproject_toml = None
|
||||
|
||||
except ImportError: # pragma: no cover
|
||||
black = None
|
||||
|
||||
|
||||
def fix_code(code, directory):
|
||||
"""Formats Python code to conform to the PEP 8 style guide.
|
||||
|
||||
"""
|
||||
if not black:
|
||||
raise Fault("black not installed", code=400)
|
||||
# Get black config from pyproject.toml
|
||||
line_length = black.DEFAULT_LINE_LENGTH
|
||||
string_normalization = True
|
||||
if find_pyproject_toml:
|
||||
pyproject_path = find_pyproject_toml((directory,))
|
||||
else:
|
||||
pyproject_path = os.path.join(directory, "pyproject.toml")
|
||||
if toml and pyproject_path and os.path.exists(pyproject_path):
|
||||
pyproject_config = toml.load(pyproject_path)
|
||||
black_config = pyproject_config.get("tool", {}).get("black", {})
|
||||
if "line-length" in black_config:
|
||||
line_length = black_config["line-length"]
|
||||
if "skip-string-normalization" in black_config:
|
||||
string_normalization = not black_config["skip-string-normalization"]
|
||||
try:
|
||||
if parse_version(black.__version__) < parse_version("19.0"):
|
||||
reformatted_source = black.format_file_contents(
|
||||
src_contents=code, line_length=line_length, fast=False)
|
||||
else:
|
||||
fm = black.FileMode(
|
||||
line_length=line_length,
|
||||
string_normalization=string_normalization)
|
||||
reformatted_source = black.format_file_contents(
|
||||
src_contents=code, fast=False, mode=fm)
|
||||
return reformatted_source
|
||||
except black.NothingChanged:
|
||||
return code
|
||||
except Exception as e:
|
||||
raise Fault("Error during formatting: {}".format(e), code=400)
|
||||
33
elpa-27.2/elpy-20220203.108/elpy/compat.py
Normal file
33
elpa-27.2/elpy-20220203.108/elpy/compat.py
Normal file
@@ -0,0 +1,33 @@
|
||||
"""Python 2/3 compatibility definitions.
|
||||
|
||||
These are used by the rest of Elpy to keep compatibility definitions
|
||||
in one place.
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
if sys.version_info >= (3, 0):
|
||||
PYTHON3 = True
|
||||
|
||||
from io import StringIO
|
||||
|
||||
def ensure_not_unicode(obj):
|
||||
return obj
|
||||
else:
|
||||
PYTHON3 = False
|
||||
|
||||
from StringIO import StringIO # noqa
|
||||
|
||||
def ensure_not_unicode(obj):
|
||||
"""Return obj. If it's a unicode string, convert it to str first.
|
||||
|
||||
Pydoc functions simply don't find anything for unicode
|
||||
strings. No idea why.
|
||||
|
||||
"""
|
||||
if isinstance(obj, unicode):
|
||||
return obj.encode("utf-8")
|
||||
else:
|
||||
return obj
|
||||
738
elpa-27.2/elpy-20220203.108/elpy/jedibackend.py
Normal file
738
elpa-27.2/elpy-20220203.108/elpy/jedibackend.py
Normal file
@@ -0,0 +1,738 @@
|
||||
"""Elpy backend using the Jedi library.
|
||||
|
||||
This backend uses the Jedi library:
|
||||
|
||||
https://github.com/davidhalter/jedi
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
import traceback
|
||||
import re
|
||||
|
||||
import jedi
|
||||
|
||||
from elpy import rpc
|
||||
from elpy.rpc import Fault
|
||||
|
||||
# in case pkg_resources is not properly installed
|
||||
# (see https://github.com/jorgenschaefer/elpy/issues/1674).
|
||||
try:
|
||||
from pkg_resources import parse_version
|
||||
except ImportError: # pragma: no cover
|
||||
def parse_version(*arg, **kwargs):
|
||||
raise Fault("`pkg_resources` could not be imported, "
|
||||
"please reinstall Elpy RPC virtualenv with"
|
||||
" `M-x elpy-rpc-reinstall-virtualenv`", code=400)
|
||||
JEDISUP17 = parse_version(jedi.__version__) >= parse_version("0.17.0")
|
||||
JEDISUP18 = parse_version(jedi.__version__) >= parse_version("0.18.0")
|
||||
|
||||
|
||||
class JediBackend(object):
|
||||
"""The Jedi backend class.
|
||||
|
||||
Implements the RPC calls we can pass on to Jedi.
|
||||
|
||||
Documentation: http://jedi.jedidjah.ch/en/latest/docs/plugin-api.html
|
||||
|
||||
"""
|
||||
name = "jedi"
|
||||
|
||||
def __init__(self, project_root, environment_binaries_path):
|
||||
self.project_root = project_root
|
||||
self.environment = None
|
||||
if environment_binaries_path is not None:
|
||||
self.environment = jedi.create_environment(environment_binaries_path,
|
||||
safe=False)
|
||||
self.completions = {}
|
||||
sys.path.append(project_root)
|
||||
# Backward compatibility to jedi<17
|
||||
if not JEDISUP17: # pragma: no cover
|
||||
self.rpc_get_completions = self.rpc_get_completions_jedi16
|
||||
self.rpc_get_docstring = self.rpc_get_docstring_jedi16
|
||||
self.rpc_get_definition = self.rpc_get_definition_jedi16
|
||||
self.rpc_get_assignment = self.rpc_get_assignment_jedi16
|
||||
self.rpc_get_calltip = self.rpc_get_calltip_jedi16
|
||||
self.rpc_get_oneline_docstring = self.rpc_get_oneline_docstring_jedi16
|
||||
self.rpc_get_usages = self.rpc_get_usages_jedi16
|
||||
self.rpc_get_names = self.rpc_get_names_jedi16
|
||||
|
||||
def rpc_get_completions(self, filename, source, offset):
|
||||
line, column = pos_to_linecol(source, offset)
|
||||
proposals = run_with_debug(jedi, 'complete', code=source,
|
||||
path=filename,
|
||||
environment=self.environment,
|
||||
fun_kwargs={'line': line, 'column': column})
|
||||
self.completions = dict((proposal.name, proposal)
|
||||
for proposal in proposals)
|
||||
return [{'name': proposal.name.rstrip("="),
|
||||
'suffix': proposal.complete.rstrip("="),
|
||||
'annotation': proposal.type,
|
||||
'meta': proposal.description}
|
||||
for proposal in proposals]
|
||||
|
||||
def rpc_get_completions_jedi16(self, filename, source, offset):
|
||||
# Backward compatibility to jedi<17
|
||||
line, column = pos_to_linecol(source, offset)
|
||||
proposals = run_with_debug(jedi, 'completions',
|
||||
source=source, line=line, column=column,
|
||||
path=filename, encoding='utf-8',
|
||||
environment=self.environment)
|
||||
if proposals is None:
|
||||
return []
|
||||
self.completions = dict((proposal.name, proposal)
|
||||
for proposal in proposals)
|
||||
return [{'name': proposal.name.rstrip("="),
|
||||
'suffix': proposal.complete.rstrip("="),
|
||||
'annotation': proposal.type,
|
||||
'meta': proposal.description}
|
||||
for proposal in proposals]
|
||||
|
||||
def rpc_get_completion_docstring(self, completion):
|
||||
proposal = self.completions.get(completion)
|
||||
if proposal is None:
|
||||
return None
|
||||
else:
|
||||
return proposal.docstring(fast=False)
|
||||
|
||||
def rpc_get_completion_location(self, completion):
|
||||
proposal = self.completions.get(completion)
|
||||
if proposal is None:
|
||||
return None
|
||||
else:
|
||||
return (proposal.module_path, proposal.line)
|
||||
|
||||
def rpc_get_docstring(self, filename, source, offset):
|
||||
line, column = pos_to_linecol(source, offset)
|
||||
locations = run_with_debug(jedi, 'goto',
|
||||
code=source,
|
||||
path=filename,
|
||||
environment=self.environment,
|
||||
fun_kwargs={'line': line,
|
||||
'column': column,
|
||||
'follow_imports': True,
|
||||
'follow_builtin_imports': True})
|
||||
if not locations:
|
||||
return None
|
||||
# Filter uninteresting things
|
||||
if locations[-1].name in ["str", "int", "float", "bool", "tuple",
|
||||
"list", "dict"]:
|
||||
return None
|
||||
if locations[-1].docstring():
|
||||
return ('Documentation for {0}:\n\n'.format(
|
||||
locations[-1].full_name) + locations[-1].docstring())
|
||||
else:
|
||||
return None
|
||||
|
||||
def rpc_get_docstring_jedi16(self, filename, source, offset):
|
||||
# Backward compatibility to jedi<17
|
||||
line, column = pos_to_linecol(source, offset)
|
||||
locations = run_with_debug(jedi, 'goto_definitions',
|
||||
source=source, line=line, column=column,
|
||||
path=filename, encoding='utf-8',
|
||||
environment=self.environment)
|
||||
if not locations:
|
||||
return None
|
||||
# Filter uninteresting things
|
||||
if locations[-1].name in ["str", "int", "float", "bool", "tuple",
|
||||
"list", "dict"]:
|
||||
return None
|
||||
if locations[-1].docstring():
|
||||
return ('Documentation for {0}:\n\n'.format(
|
||||
locations[-1].full_name) + locations[-1].docstring())
|
||||
else:
|
||||
return None
|
||||
|
||||
def rpc_get_definition(self, filename, source, offset):
|
||||
line, column = pos_to_linecol(source, offset)
|
||||
locations = run_with_debug(jedi, 'goto',
|
||||
code=source,
|
||||
path=filename,
|
||||
environment=self.environment,
|
||||
fun_kwargs={'line': line,
|
||||
'column': column,
|
||||
'follow_imports': True,
|
||||
'follow_builtin_imports': True})
|
||||
if not locations:
|
||||
return None
|
||||
# goto_definitions() can return silly stuff like __builtin__
|
||||
# for int variables, so we remove them. See issue #76.
|
||||
locations = [
|
||||
loc for loc in locations
|
||||
if (loc.module_path is not None
|
||||
and loc.module_name != 'builtins'
|
||||
and loc.module_name != '__builtin__')]
|
||||
if len(locations) == 0:
|
||||
return None
|
||||
loc = locations[-1]
|
||||
try:
|
||||
if loc.module_path == filename:
|
||||
offset = linecol_to_pos(source,
|
||||
loc.line,
|
||||
loc.column)
|
||||
else:
|
||||
with open(loc.module_path) as f:
|
||||
offset = linecol_to_pos(f.read(),
|
||||
loc.line,
|
||||
loc.column)
|
||||
except IOError: # pragma: no cover
|
||||
return None
|
||||
return (loc.module_path, offset)
|
||||
|
||||
def rpc_get_definition_jedi16(self, filename, source, offset): # pragma: no cover
|
||||
# Backward compatibility to jedi<17
|
||||
line, column = pos_to_linecol(source, offset)
|
||||
locations = run_with_debug(jedi, 'goto_definitions',
|
||||
source=source, line=line, column=column,
|
||||
path=filename, encoding='utf-8',
|
||||
environment=self.environment)
|
||||
# goto_definitions() can return silly stuff like __builtin__
|
||||
# for int variables, so we fall back on goto() in those
|
||||
# cases. See issue #76.
|
||||
if (
|
||||
locations and
|
||||
(locations[0].module_path is None
|
||||
or locations[0].module_name == 'builtins'
|
||||
or locations[0].module_name == '__builtin__')
|
||||
):
|
||||
locations = run_with_debug(jedi, 'goto_assignments',
|
||||
source=source, line=line,
|
||||
column=column,
|
||||
path=filename,
|
||||
encoding='utf-8',
|
||||
environment=self.environment)
|
||||
if not locations:
|
||||
return None
|
||||
else:
|
||||
loc = locations[-1]
|
||||
try:
|
||||
if loc.module_path:
|
||||
if loc.module_path == filename:
|
||||
offset = linecol_to_pos(source,
|
||||
loc.line,
|
||||
loc.column)
|
||||
else:
|
||||
with open(loc.module_path) as f:
|
||||
offset = linecol_to_pos(f.read(),
|
||||
loc.line,
|
||||
loc.column)
|
||||
else:
|
||||
return None
|
||||
except IOError:
|
||||
return None
|
||||
return (loc.module_path, offset)
|
||||
|
||||
def rpc_get_assignment(self, filename, source, offset):
|
||||
raise Fault("Obsolete since jedi 17.0. Please use 'get_definition'.")
|
||||
|
||||
def rpc_get_assignment_jedi16(self, filename, source, offset): # pragma: no cover
|
||||
# Backward compatibility to jedi<17
|
||||
line, column = pos_to_linecol(source, offset)
|
||||
locations = run_with_debug(jedi, 'goto_assignments',
|
||||
source=source, line=line, column=column,
|
||||
path=filename, encoding='utf-8',
|
||||
environment=self.environment)
|
||||
|
||||
if not locations:
|
||||
return None
|
||||
else:
|
||||
loc = locations[-1]
|
||||
try:
|
||||
if loc.module_path:
|
||||
if loc.module_path == filename:
|
||||
offset = linecol_to_pos(source,
|
||||
loc.line,
|
||||
loc.column)
|
||||
else:
|
||||
with open(loc.module_path) as f:
|
||||
offset = linecol_to_pos(f.read(),
|
||||
loc.line,
|
||||
loc.column)
|
||||
else:
|
||||
return None
|
||||
except IOError:
|
||||
return None
|
||||
return (loc.module_path, offset)
|
||||
|
||||
def rpc_get_calltip(self, filename, source, offset):
|
||||
line, column = pos_to_linecol(source, offset)
|
||||
calls = run_with_debug(jedi, 'get_signatures',
|
||||
code=source,
|
||||
path=filename,
|
||||
environment=self.environment,
|
||||
fun_kwargs={'line': line,
|
||||
'column': column})
|
||||
if not calls:
|
||||
return None
|
||||
params = [re.sub("^param ", '', param.description)
|
||||
for param in calls[0].params]
|
||||
return {"name": calls[0].name,
|
||||
"index": calls[0].index,
|
||||
"params": params}
|
||||
|
||||
def rpc_get_calltip_jedi16(self, filename, source, offset): # pragma: no cover
|
||||
# Backward compatibility to jedi<17
|
||||
line, column = pos_to_linecol(source, offset)
|
||||
calls = run_with_debug(jedi, 'call_signatures',
|
||||
source=source, line=line, column=column,
|
||||
path=filename, encoding='utf-8',
|
||||
environment=self.environment)
|
||||
if calls:
|
||||
call = calls[0]
|
||||
else:
|
||||
call = None
|
||||
if not call:
|
||||
return None
|
||||
# Strip 'param' added by jedi at the beginning of
|
||||
# parameter names. Should be unecessary for jedi > 0.13.0
|
||||
params = [re.sub("^param ", '', param.description)
|
||||
for param in call.params]
|
||||
return {"name": call.name,
|
||||
"index": call.index,
|
||||
"params": params}
|
||||
|
||||
def rpc_get_calltip_or_oneline_docstring(self, filename, source, offset):
|
||||
"""
|
||||
Return the current function calltip or its oneline docstring.
|
||||
|
||||
Meant to be used with eldoc.
|
||||
"""
|
||||
# Try to get a oneline docstring then
|
||||
docs = self.rpc_get_oneline_docstring(filename=filename,
|
||||
source=source,
|
||||
offset=offset)
|
||||
if docs is not None:
|
||||
if docs['doc'] != "No documentation":
|
||||
docs['kind'] = 'oneline_doc'
|
||||
return docs
|
||||
# Try to get a calltip
|
||||
calltip = self.rpc_get_calltip(filename=filename, source=source,
|
||||
offset=offset)
|
||||
if calltip is not None:
|
||||
calltip['kind'] = 'calltip'
|
||||
return calltip
|
||||
# Ok, no calltip, just display the function name
|
||||
if docs is not None:
|
||||
docs['kind'] = 'oneline_doc'
|
||||
return docs
|
||||
# Giving up...
|
||||
return None
|
||||
|
||||
def rpc_get_oneline_docstring(self, filename, source, offset):
|
||||
"""Return a oneline docstring for the symbol at offset"""
|
||||
line, column = pos_to_linecol(source, offset)
|
||||
definitions = run_with_debug(jedi, 'goto',
|
||||
code=source,
|
||||
path=filename,
|
||||
environment=self.environment,
|
||||
fun_kwargs={'line': line,
|
||||
'column': column})
|
||||
if not definitions:
|
||||
return None
|
||||
# avoid unintersting stuff
|
||||
definitions = [defi for defi in definitions
|
||||
if defi.name not in
|
||||
["str", "int", "float", "bool", "tuple",
|
||||
"list", "dict"]]
|
||||
if len(definitions) == 0:
|
||||
return None
|
||||
definition = definitions[0]
|
||||
# Get name
|
||||
if definition.type in ['function', 'class']:
|
||||
raw_name = definition.name
|
||||
name = '{}()'.format(raw_name)
|
||||
doc = definition.docstring().split('\n')
|
||||
elif definition.type in ['module']:
|
||||
raw_name = definition.name
|
||||
name = '{} {}'.format(raw_name, definition.type)
|
||||
doc = definition.docstring().split('\n')
|
||||
elif (definition.type in ['instance']
|
||||
and hasattr(definition, "name")):
|
||||
raw_name = definition.name
|
||||
name = raw_name
|
||||
doc = definition.docstring().split('\n')
|
||||
else:
|
||||
return None
|
||||
# Keep only the first paragraph that is not a function declaration
|
||||
lines = []
|
||||
call = "{}(".format(raw_name)
|
||||
# last line
|
||||
doc.append('')
|
||||
for i in range(len(doc)):
|
||||
if doc[i] == '' and len(lines) != 0:
|
||||
paragraph = " ".join(lines)
|
||||
lines = []
|
||||
if call != paragraph[0:len(call)]:
|
||||
break
|
||||
paragraph = ""
|
||||
continue
|
||||
lines.append(doc[i])
|
||||
# Keep only the first sentence
|
||||
onelinedoc = paragraph.split('. ', 1)
|
||||
if len(onelinedoc) == 2:
|
||||
onelinedoc = onelinedoc[0] + '.'
|
||||
else:
|
||||
onelinedoc = onelinedoc[0]
|
||||
if onelinedoc == '':
|
||||
onelinedoc = "No documentation"
|
||||
return {"name": name,
|
||||
"doc": onelinedoc}
|
||||
|
||||
def rpc_get_oneline_docstring_jedi16(self, filename, source, offset): # pragma: no cover
|
||||
"""Return a oneline docstring for the symbol at offset"""
|
||||
# Backward compatibility to jedi<17
|
||||
line, column = pos_to_linecol(source, offset)
|
||||
definitions = run_with_debug(jedi, 'goto_definitions',
|
||||
source=source, line=line, column=column,
|
||||
path=filename, encoding='utf-8',
|
||||
environment=self.environment)
|
||||
# avoid unintersting stuff
|
||||
try:
|
||||
if definitions[0].name in ["str", "int", "float", "bool", "tuple",
|
||||
"list", "dict"]:
|
||||
return None
|
||||
except:
|
||||
pass
|
||||
assignments = run_with_debug(jedi, 'goto_assignments',
|
||||
source=source, line=line, column=column,
|
||||
path=filename, encoding='utf-8',
|
||||
environment=self.environment)
|
||||
|
||||
if definitions:
|
||||
definition = definitions[0]
|
||||
else:
|
||||
definition = None
|
||||
if assignments:
|
||||
assignment = assignments[0]
|
||||
else:
|
||||
assignment = None
|
||||
if definition:
|
||||
# Get name
|
||||
if definition.type in ['function', 'class']:
|
||||
raw_name = definition.name
|
||||
name = '{}()'.format(raw_name)
|
||||
doc = definition.docstring().split('\n')
|
||||
elif definition.type in ['module']:
|
||||
raw_name = definition.name
|
||||
name = '{} {}'.format(raw_name, definition.type)
|
||||
doc = definition.docstring().split('\n')
|
||||
elif (definition.type in ['instance']
|
||||
and hasattr(assignment, "name")):
|
||||
raw_name = assignment.name
|
||||
name = raw_name
|
||||
doc = assignment.docstring().split('\n')
|
||||
else:
|
||||
return None
|
||||
# Keep only the first paragraph that is not a function declaration
|
||||
lines = []
|
||||
call = "{}(".format(raw_name)
|
||||
# last line
|
||||
doc.append('')
|
||||
for i in range(len(doc)):
|
||||
if doc[i] == '' and len(lines) != 0:
|
||||
paragraph = " ".join(lines)
|
||||
lines = []
|
||||
if call != paragraph[0:len(call)]:
|
||||
break
|
||||
paragraph = ""
|
||||
continue
|
||||
lines.append(doc[i])
|
||||
# Keep only the first sentence
|
||||
onelinedoc = paragraph.split('. ', 1)
|
||||
if len(onelinedoc) == 2:
|
||||
onelinedoc = onelinedoc[0] + '.'
|
||||
else:
|
||||
onelinedoc = onelinedoc[0]
|
||||
if onelinedoc == '':
|
||||
onelinedoc = "No documentation"
|
||||
return {"name": name,
|
||||
"doc": onelinedoc}
|
||||
return None
|
||||
|
||||
def rpc_get_usages(self, filename, source, offset):
|
||||
"""Return the uses of the symbol at offset.
|
||||
|
||||
Returns a list of occurrences of the symbol, as dicts with the
|
||||
fields name, filename, and offset.
|
||||
|
||||
"""
|
||||
line, column = pos_to_linecol(source, offset)
|
||||
uses = run_with_debug(jedi, 'get_references',
|
||||
code=source,
|
||||
path=filename,
|
||||
environment=self.environment,
|
||||
fun_kwargs={'line': line,
|
||||
'column': column})
|
||||
if uses is None:
|
||||
return None
|
||||
result = []
|
||||
for use in uses:
|
||||
if use.module_path == filename:
|
||||
offset = linecol_to_pos(source, use.line, use.column)
|
||||
elif use.module_path is not None:
|
||||
with open(use.module_path) as f:
|
||||
text = f.read()
|
||||
offset = linecol_to_pos(text, use.line, use.column)
|
||||
result.append({"name": use.name,
|
||||
"filename": use.module_path,
|
||||
"offset": offset})
|
||||
return result
|
||||
|
||||
def rpc_get_usages_jedi16(self, filename, source, offset): # pragma: no cover
|
||||
"""Return the uses of the symbol at offset.
|
||||
|
||||
Returns a list of occurrences of the symbol, as dicts with the
|
||||
fields name, filename, and offset.
|
||||
|
||||
"""
|
||||
# Backward compatibility to jedi<17
|
||||
line, column = pos_to_linecol(source, offset)
|
||||
uses = run_with_debug(jedi, 'usages',
|
||||
source=source, line=line, column=column,
|
||||
path=filename, encoding='utf-8',
|
||||
environment=self.environment)
|
||||
if uses is None:
|
||||
return None
|
||||
result = []
|
||||
for use in uses:
|
||||
if use.module_path == filename:
|
||||
offset = linecol_to_pos(source, use.line, use.column)
|
||||
elif use.module_path is not None:
|
||||
with open(use.module_path) as f:
|
||||
text = f.read()
|
||||
offset = linecol_to_pos(text, use.line, use.column)
|
||||
|
||||
result.append({"name": use.name,
|
||||
"filename": use.module_path,
|
||||
"offset": offset})
|
||||
|
||||
return result
|
||||
|
||||
def rpc_get_names(self, filename, source, offset):
|
||||
"""Return the list of possible names"""
|
||||
names = run_with_debug(jedi, 'get_names',
|
||||
code=source,
|
||||
path=filename,
|
||||
environment=self.environment,
|
||||
fun_kwargs={'all_scopes': True,
|
||||
'definitions': True,
|
||||
'references': True})
|
||||
result = []
|
||||
for name in names:
|
||||
if name.module_path == filename:
|
||||
offset = linecol_to_pos(source, name.line, name.column)
|
||||
elif name.module_path is not None:
|
||||
with open(name.module_path) as f:
|
||||
text = f.read()
|
||||
offset = linecol_to_pos(text, name.line, name.column)
|
||||
result.append({"name": name.name,
|
||||
"filename": name.module_path,
|
||||
"offset": offset})
|
||||
return result
|
||||
|
||||
def rpc_get_names_jedi16(self, filename, source, offset): # pragma: no cover
|
||||
"""Return the list of possible names"""
|
||||
# Backward compatibility to jedi<17
|
||||
names = jedi.api.names(source=source,
|
||||
path=filename, encoding='utf-8',
|
||||
all_scopes=True,
|
||||
definitions=True,
|
||||
references=True)
|
||||
|
||||
result = []
|
||||
for name in names:
|
||||
if name.module_path == filename:
|
||||
offset = linecol_to_pos(source, name.line, name.column)
|
||||
elif name.module_path is not None:
|
||||
with open(name.module_path) as f:
|
||||
text = f.read()
|
||||
offset = linecol_to_pos(text, name.line, name.column)
|
||||
result.append({"name": name.name,
|
||||
"filename": name.module_path,
|
||||
"offset": offset})
|
||||
return result
|
||||
|
||||
def rpc_get_rename_diff(self, filename, source, offset, new_name):
|
||||
"""Get the diff resulting from renaming the thing at point"""
|
||||
if not hasattr(jedi.Script, "rename"): # pragma: no cover
|
||||
return {'success': "Not available"}
|
||||
line, column = pos_to_linecol(source, offset)
|
||||
ren = run_with_debug(jedi, 'rename', code=source,
|
||||
path=filename,
|
||||
environment=self.environment,
|
||||
fun_kwargs={'line': line,
|
||||
'column': column,
|
||||
'new_name': new_name})
|
||||
if ren is None:
|
||||
return {'success': False}
|
||||
else:
|
||||
return {'success': True,
|
||||
'project_path': ren._inference_state.project._path,
|
||||
'diff': ren.get_diff(),
|
||||
'changed_files': list(ren.get_changed_files().keys())}
|
||||
|
||||
def rpc_get_extract_variable_diff(self, filename, source, offset, new_name,
|
||||
line_beg, line_end, col_beg, col_end):
|
||||
"""Get the diff resulting from extracting the selected code"""
|
||||
if not hasattr(jedi.Script, "extract_variable"): # pragma: no cover
|
||||
return {'success': "Not available"}
|
||||
ren = run_with_debug(jedi, 'extract_variable', code=source,
|
||||
path=filename,
|
||||
environment=self.environment,
|
||||
fun_kwargs={'line': line_beg,
|
||||
'until_line': line_end,
|
||||
'column': col_beg,
|
||||
'until_column': col_end,
|
||||
'new_name': new_name})
|
||||
if ren is None:
|
||||
return {'success': False}
|
||||
else:
|
||||
return {'success': True,
|
||||
'project_path': ren._inference_state.project._path,
|
||||
'diff': ren.get_diff(),
|
||||
'changed_files': list(ren.get_changed_files().keys())}
|
||||
|
||||
def rpc_get_extract_function_diff(self, filename, source, offset, new_name,
|
||||
line_beg, line_end, col_beg, col_end):
|
||||
"""Get the diff resulting from extracting the selected code"""
|
||||
if not hasattr(jedi.Script, "extract_function"): # pragma: no cover
|
||||
return {'success': "Not available"}
|
||||
ren = run_with_debug(jedi, 'extract_function', code=source,
|
||||
path=filename,
|
||||
environment=self.environment,
|
||||
fun_kwargs={'line': line_beg,
|
||||
'until_line': line_end,
|
||||
'column': col_beg,
|
||||
'until_column': col_end,
|
||||
'new_name': new_name})
|
||||
if ren is None:
|
||||
return {'success': False}
|
||||
else:
|
||||
return {'success': True,
|
||||
'project_path': ren._inference_state.project._path,
|
||||
'diff': ren.get_diff(),
|
||||
'changed_files': list(ren.get_changed_files().keys())}
|
||||
|
||||
def rpc_get_inline_diff(self, filename, source, offset):
|
||||
"""Get the diff resulting from inlining the selected variable"""
|
||||
if not hasattr(jedi.Script, "inline"): # pragma: no cover
|
||||
return {'success': "Not available"}
|
||||
line, column = pos_to_linecol(source, offset)
|
||||
ren = run_with_debug(jedi, 'inline', code=source,
|
||||
path=filename,
|
||||
environment=self.environment,
|
||||
fun_kwargs={'line': line,
|
||||
'column': column})
|
||||
if ren is None:
|
||||
return {'success': False}
|
||||
else:
|
||||
return {'success': True,
|
||||
'project_path': ren._inference_state.project._path,
|
||||
'diff': ren.get_diff(),
|
||||
'changed_files': list(ren.get_changed_files().keys())}
|
||||
|
||||
|
||||
# From the Jedi documentation:
|
||||
#
|
||||
# line is the current line you want to perform actions on (starting
|
||||
# with line #1 as the first line). column represents the current
|
||||
# column/indent of the cursor (starting with zero). source_path
|
||||
# should be the path of your file in the file system.
|
||||
|
||||
def pos_to_linecol(text, pos):
|
||||
"""Return a tuple of line and column for offset pos in text.
|
||||
|
||||
Lines are one-based, columns zero-based.
|
||||
|
||||
This is how Jedi wants it. Don't ask me why.
|
||||
|
||||
"""
|
||||
line_start = text.rfind("\n", 0, pos) + 1
|
||||
line = text.count("\n", 0, line_start) + 1
|
||||
col = pos - line_start
|
||||
return line, col
|
||||
|
||||
|
||||
def linecol_to_pos(text, line, col):
|
||||
"""Return the offset of this line and column in text.
|
||||
|
||||
Lines are one-based, columns zero-based.
|
||||
|
||||
This is how Jedi wants it. Don't ask me why.
|
||||
|
||||
"""
|
||||
nth_newline_offset = 0
|
||||
for i in range(line - 1):
|
||||
new_offset = text.find("\n", nth_newline_offset)
|
||||
if new_offset < 0:
|
||||
raise ValueError("Text does not have {0} lines."
|
||||
.format(line))
|
||||
nth_newline_offset = new_offset + 1
|
||||
offset = nth_newline_offset + col
|
||||
if offset > len(text):
|
||||
raise ValueError("Line {0} column {1} is not within the text"
|
||||
.format(line, col))
|
||||
return offset
|
||||
|
||||
|
||||
def run_with_debug(jedi, name, fun_kwargs={}, *args, **kwargs):
|
||||
re_raise = kwargs.pop('re_raise', ())
|
||||
try:
|
||||
script = jedi.Script(*args, **kwargs)
|
||||
return getattr(script, name)(**fun_kwargs)
|
||||
except Exception as e:
|
||||
if isinstance(e, re_raise):
|
||||
raise
|
||||
if JEDISUP17:
|
||||
if isinstance(e, jedi.RefactoringError):
|
||||
return None
|
||||
# Bug jedi#485
|
||||
if (
|
||||
isinstance(e, ValueError) and
|
||||
"invalid \\x escape" in str(e)
|
||||
):
|
||||
return None
|
||||
# Bug jedi#485 in Python 3
|
||||
if (
|
||||
isinstance(e, SyntaxError) and
|
||||
"truncated \\xXX escape" in str(e)
|
||||
):
|
||||
return None
|
||||
|
||||
from jedi import debug
|
||||
|
||||
debug_info = []
|
||||
|
||||
def _debug(level, str_out):
|
||||
if level == debug.NOTICE:
|
||||
prefix = "[N]"
|
||||
elif level == debug.WARNING:
|
||||
prefix = "[W]"
|
||||
else:
|
||||
prefix = "[?]"
|
||||
debug_info.append(u"{0} {1}".format(prefix, str_out))
|
||||
|
||||
jedi.set_debug_function(_debug, speed=False)
|
||||
try:
|
||||
script = jedi.Script(*args, **kwargs)
|
||||
return getattr(script, name)()
|
||||
except Exception as e:
|
||||
source = kwargs.get('source')
|
||||
sc_args = []
|
||||
sc_args.extend(repr(arg) for arg in args)
|
||||
sc_args.extend("{0}={1}".format(k, "source" if k == "source"
|
||||
else repr(v))
|
||||
for (k, v) in kwargs.items())
|
||||
|
||||
data = {
|
||||
"traceback": traceback.format_exc(),
|
||||
"jedi_debug_info": {'script_args': ", ".join(sc_args),
|
||||
'source': source,
|
||||
'method': name,
|
||||
'debug_info': debug_info}
|
||||
}
|
||||
raise rpc.Fault(message=str(e),
|
||||
code=500,
|
||||
data=data)
|
||||
finally:
|
||||
jedi.set_debug_function(None)
|
||||
13
elpa-27.2/elpy-20220203.108/elpy/json_encoder.py
Normal file
13
elpa-27.2/elpy-20220203.108/elpy/json_encoder.py
Normal file
@@ -0,0 +1,13 @@
|
||||
import json
|
||||
|
||||
from elpy.jedibackend import JEDISUP18
|
||||
if JEDISUP18:
|
||||
import pathlib
|
||||
|
||||
|
||||
class JSONEncoder(json.JSONEncoder):
|
||||
def default(self, o):
|
||||
if JEDISUP18:
|
||||
if isinstance(o, pathlib.Path):
|
||||
return str(o)
|
||||
return super().default(o)
|
||||
91
elpa-27.2/elpy-20220203.108/elpy/pydocutils.py
Normal file
91
elpa-27.2/elpy-20220203.108/elpy/pydocutils.py
Normal file
@@ -0,0 +1,91 @@
|
||||
import sys
|
||||
import types
|
||||
|
||||
from pydoc import safeimport, resolve, ErrorDuringImport
|
||||
from pkgutil import iter_modules
|
||||
|
||||
from elpy import compat
|
||||
|
||||
# Types we want to recurse into (nodes).
|
||||
CONTAINER_TYPES = (type, types.ModuleType)
|
||||
# Types of attributes we can get documentation for (leaves).
|
||||
PYDOC_TYPES = (type,
|
||||
types.FunctionType,
|
||||
types.BuiltinFunctionType,
|
||||
types.BuiltinMethodType,
|
||||
types.MethodType,
|
||||
types.ModuleType)
|
||||
if not compat.PYTHON3: # pragma: nocover
|
||||
# Python 2 old style classes
|
||||
CONTAINER_TYPES = tuple(list(CONTAINER_TYPES) + [types.ClassType])
|
||||
PYDOC_TYPES = tuple(list(PYDOC_TYPES) + [types.ClassType])
|
||||
|
||||
|
||||
def get_pydoc_completions(modulename):
|
||||
"""Get possible completions for modulename for pydoc.
|
||||
|
||||
Returns a list of possible values to be passed to pydoc.
|
||||
|
||||
"""
|
||||
modulename = compat.ensure_not_unicode(modulename)
|
||||
modulename = modulename.rstrip(".")
|
||||
if modulename == "":
|
||||
return sorted(get_modules())
|
||||
candidates = get_completions(modulename)
|
||||
if candidates:
|
||||
return sorted(candidates)
|
||||
needle = modulename
|
||||
if "." in needle:
|
||||
modulename, part = needle.rsplit(".", 1)
|
||||
candidates = get_completions(modulename)
|
||||
else:
|
||||
candidates = get_modules()
|
||||
return sorted(candidate for candidate in candidates
|
||||
if candidate.startswith(needle))
|
||||
|
||||
|
||||
def get_completions(modulename):
|
||||
modules = set("{0}.{1}".format(modulename, module)
|
||||
for module in get_modules(modulename))
|
||||
|
||||
try:
|
||||
module, name = resolve(modulename)
|
||||
except ImportError:
|
||||
return modules
|
||||
if isinstance(module, CONTAINER_TYPES):
|
||||
modules.update("{0}.{1}".format(modulename, name)
|
||||
for name in dir(module)
|
||||
if not name.startswith("_") and
|
||||
isinstance(getattr(module, name),
|
||||
PYDOC_TYPES))
|
||||
return modules
|
||||
|
||||
|
||||
def get_modules(modulename=None):
|
||||
"""Return a list of modules and packages under modulename.
|
||||
|
||||
If modulename is not given, return a list of all top level modules
|
||||
and packages.
|
||||
|
||||
"""
|
||||
modulename = compat.ensure_not_unicode(modulename)
|
||||
if not modulename:
|
||||
try:
|
||||
return ([modname for (importer, modname, ispkg)
|
||||
in iter_modules()
|
||||
if not modname.startswith("_")] +
|
||||
list(sys.builtin_module_names))
|
||||
except OSError:
|
||||
# Bug in Python 2.6, see #275
|
||||
return list(sys.builtin_module_names)
|
||||
try:
|
||||
module = safeimport(modulename)
|
||||
except ErrorDuringImport:
|
||||
return []
|
||||
if module is None:
|
||||
return []
|
||||
if hasattr(module, "__path__"):
|
||||
return [modname for (importer, modname, ispkg)
|
||||
in iter_modules(module.__path__)
|
||||
if not modname.startswith("_")]
|
||||
return []
|
||||
153
elpa-27.2/elpy-20220203.108/elpy/rpc.py
Normal file
153
elpa-27.2/elpy-20220203.108/elpy/rpc.py
Normal file
@@ -0,0 +1,153 @@
|
||||
"""A simple JSON-RPC-like server.
|
||||
|
||||
The server will read and write lines of JSON-encoded method calls and
|
||||
responses.
|
||||
|
||||
See the documentation of the JSONRPCServer class for further details.
|
||||
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
|
||||
class JSONRPCServer(object):
|
||||
"""Simple JSON-RPC-like server.
|
||||
|
||||
This class will read single-line JSON expressions from stdin,
|
||||
decode them, and pass them to a handler. Return values from the
|
||||
handler will be JSON-encoded and written to stdout.
|
||||
|
||||
To implement a handler, you need to subclass this class and add
|
||||
methods starting with "rpc_". Methods then will be found.
|
||||
|
||||
Method calls should be encoded like this:
|
||||
|
||||
{"id": 23, "method": "method_name", "params": ["foo", "bar"]}
|
||||
|
||||
This will call self.rpc_method("foo", "bar").
|
||||
|
||||
Responses will be encoded like this:
|
||||
|
||||
{"id": 23, "result": "foo"}
|
||||
|
||||
Errors will be encoded like this:
|
||||
|
||||
{"id": 23, "error": "Simple error message"}
|
||||
|
||||
See http://www.jsonrpc.org/ for the inspiration of the protocol.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, stdin=None, stdout=None):
|
||||
"""Return a new JSON-RPC server object.
|
||||
|
||||
It will read lines of JSON data from stdin, and write the
|
||||
responses to stdout.
|
||||
|
||||
"""
|
||||
if stdin is None:
|
||||
self.stdin = sys.stdin
|
||||
else:
|
||||
self.stdin = stdin
|
||||
if stdout is None:
|
||||
self.stdout = sys.stdout
|
||||
else:
|
||||
self.stdout = stdout
|
||||
|
||||
def read_json(self):
|
||||
"""Read a single line and decode it as JSON.
|
||||
|
||||
Can raise an EOFError() when the input source was closed.
|
||||
|
||||
"""
|
||||
line = self.stdin.readline()
|
||||
if line == '':
|
||||
raise EOFError()
|
||||
return json.loads(line)
|
||||
|
||||
def write_json(self, **kwargs):
|
||||
"""Write an JSON object on a single line.
|
||||
|
||||
The keyword arguments are interpreted as a single JSON object.
|
||||
It's not possible with this method to write non-objects.
|
||||
|
||||
"""
|
||||
from elpy.json_encoder import JSONEncoder
|
||||
serialized_value = JSONEncoder().encode(kwargs)
|
||||
self.stdout.write(serialized_value + "\n")
|
||||
self.stdout.flush()
|
||||
|
||||
def handle_request(self):
|
||||
"""Handle a single JSON-RPC request.
|
||||
|
||||
Read a request, call the appropriate handler method, and
|
||||
return the encoded result. Errors in the handler method are
|
||||
caught and encoded as error objects. Errors in the decoding
|
||||
phase are not caught, as we can not respond with an error
|
||||
response to them.
|
||||
|
||||
"""
|
||||
request = self.read_json()
|
||||
if 'method' not in request:
|
||||
raise ValueError("Received a bad request: {0}"
|
||||
.format(request))
|
||||
method_name = request['method']
|
||||
request_id = request.get('id', None)
|
||||
params = request.get('params') or []
|
||||
try:
|
||||
method = getattr(self, "rpc_" + method_name, None)
|
||||
if method is not None:
|
||||
result = method(*params)
|
||||
else:
|
||||
result = self.handle(method_name, params)
|
||||
if request_id is not None:
|
||||
self.write_json(result=result,
|
||||
id=request_id)
|
||||
except Fault as fault:
|
||||
error = {"message": fault.message,
|
||||
"code": fault.code}
|
||||
if fault.data is not None:
|
||||
error["data"] = fault.data
|
||||
self.write_json(error=error, id=request_id)
|
||||
except Exception as e:
|
||||
error = {"message": str(e),
|
||||
"code": 500,
|
||||
"data": {"traceback": traceback.format_exc()}}
|
||||
self.write_json(error=error, id=request_id)
|
||||
|
||||
def handle(self, method_name, args):
|
||||
"""Handle the call to method_name.
|
||||
|
||||
You should overwrite this method in a subclass.
|
||||
"""
|
||||
raise Fault("Unknown method {0}".format(method_name))
|
||||
|
||||
def serve_forever(self):
|
||||
"""Serve requests forever.
|
||||
|
||||
Errors are not caught, so this is a slight misnomer.
|
||||
|
||||
"""
|
||||
while True:
|
||||
try:
|
||||
self.handle_request()
|
||||
except (KeyboardInterrupt, EOFError, SystemExit):
|
||||
break
|
||||
|
||||
|
||||
class Fault(Exception):
|
||||
"""RPC Fault instances.
|
||||
|
||||
code defines the severity of the warning.
|
||||
|
||||
2xx: Normal behavior lead to end of operation, i.e. a warning
|
||||
4xx: An expected error occurred
|
||||
5xx: An unexpected error occurred (usually includes a traceback)
|
||||
"""
|
||||
def __init__(self, message, code=500, data=None):
|
||||
super(Fault, self).__init__(message)
|
||||
self.message = message
|
||||
self.code = code
|
||||
self.data = data
|
||||
281
elpa-27.2/elpy-20220203.108/elpy/server.py
Normal file
281
elpa-27.2/elpy-20220203.108/elpy/server.py
Normal file
@@ -0,0 +1,281 @@
|
||||
"""Method implementations for the Elpy JSON-RPC server.
|
||||
|
||||
This file implements the methods exported by the JSON-RPC server. It
|
||||
handles backend selection and passes methods on to the selected
|
||||
backend.
|
||||
|
||||
"""
|
||||
import io
|
||||
import os
|
||||
import pydoc
|
||||
|
||||
from elpy.pydocutils import get_pydoc_completions
|
||||
from elpy.rpc import JSONRPCServer, Fault
|
||||
from elpy.auto_pep8 import fix_code
|
||||
from elpy.yapfutil import fix_code as fix_code_with_yapf
|
||||
from elpy.blackutil import fix_code as fix_code_with_black
|
||||
|
||||
|
||||
try:
|
||||
from elpy import jedibackend
|
||||
except ImportError: # pragma: no cover
|
||||
jedibackend = None
|
||||
|
||||
|
||||
class ElpyRPCServer(JSONRPCServer):
|
||||
"""The RPC server for elpy.
|
||||
|
||||
See the rpc_* methods for exported method documentation.
|
||||
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ElpyRPCServer, self).__init__(*args, **kwargs)
|
||||
self.backend = None
|
||||
self.project_root = None
|
||||
|
||||
def _call_backend(self, method, default, *args, **kwargs):
|
||||
"""Call the backend method with args.
|
||||
|
||||
If there is currently no backend, return default."""
|
||||
meth = getattr(self.backend, method, None)
|
||||
if meth is None:
|
||||
return default
|
||||
else:
|
||||
return meth(*args, **kwargs)
|
||||
|
||||
def rpc_echo(self, *args):
|
||||
"""Return the arguments.
|
||||
|
||||
This is a simple test method to see if the protocol is
|
||||
working.
|
||||
|
||||
"""
|
||||
return args
|
||||
|
||||
def rpc_init(self, options):
|
||||
self.project_root = options["project_root"]
|
||||
self.env = options["environment"]
|
||||
|
||||
if jedibackend:
|
||||
self.backend = jedibackend.JediBackend(self.project_root, self.env)
|
||||
else:
|
||||
self.backend = None
|
||||
|
||||
return {
|
||||
'jedi_available': (self.backend is not None)
|
||||
}
|
||||
|
||||
def rpc_get_calltip(self, filename, source, offset):
|
||||
"""Get the calltip for the function at the offset.
|
||||
|
||||
"""
|
||||
return self._call_backend("rpc_get_calltip", None, filename,
|
||||
get_source(source), offset)
|
||||
|
||||
def rpc_get_oneline_docstring(self, filename, source, offset):
|
||||
"""Get a oneline docstring for the symbol at the offset.
|
||||
|
||||
"""
|
||||
return self._call_backend("rpc_get_oneline_docstring", None, filename,
|
||||
get_source(source), offset)
|
||||
|
||||
def rpc_get_calltip_or_oneline_docstring(self, filename, source, offset):
|
||||
"""Get a calltip or a oneline docstring for the symbol at the offset.
|
||||
|
||||
"""
|
||||
return self._call_backend("rpc_get_calltip_or_oneline_docstring",
|
||||
None, filename,
|
||||
get_source(source), offset)
|
||||
|
||||
def rpc_get_completions(self, filename, source, offset):
|
||||
"""Get a list of completion candidates for the symbol at offset.
|
||||
|
||||
"""
|
||||
results = self._call_backend("rpc_get_completions", [], filename,
|
||||
get_source(source), offset)
|
||||
# Uniquify by name
|
||||
results = list(dict((res['name'], res) for res in results)
|
||||
.values())
|
||||
results.sort(key=lambda cand: _pysymbol_key(cand["name"]))
|
||||
return results
|
||||
|
||||
def rpc_get_completion_docstring(self, completion):
|
||||
"""Return documentation for a previously returned completion.
|
||||
|
||||
"""
|
||||
return self._call_backend("rpc_get_completion_docstring",
|
||||
None, completion)
|
||||
|
||||
def rpc_get_completion_location(self, completion):
|
||||
"""Return the location for a previously returned completion.
|
||||
|
||||
This returns a list of [file name, line number].
|
||||
|
||||
"""
|
||||
return self._call_backend("rpc_get_completion_location", None,
|
||||
completion)
|
||||
|
||||
def rpc_get_definition(self, filename, source, offset):
|
||||
"""Get the location of the definition for the symbol at the offset.
|
||||
|
||||
"""
|
||||
return self._call_backend("rpc_get_definition", None, filename,
|
||||
get_source(source), offset)
|
||||
|
||||
def rpc_get_assignment(self, filename, source, offset):
|
||||
"""Get the location of the assignment for the symbol at the offset.
|
||||
|
||||
"""
|
||||
return self._call_backend("rpc_get_assignment", None, filename,
|
||||
get_source(source), offset)
|
||||
|
||||
def rpc_get_docstring(self, filename, source, offset):
|
||||
"""Get the docstring for the symbol at the offset.
|
||||
|
||||
"""
|
||||
return self._call_backend("rpc_get_docstring", None, filename,
|
||||
get_source(source), offset)
|
||||
|
||||
def rpc_get_pydoc_completions(self, name=None):
|
||||
"""Return a list of possible strings to pass to pydoc.
|
||||
|
||||
If name is given, the strings are under name. If not, top
|
||||
level modules are returned.
|
||||
|
||||
"""
|
||||
return get_pydoc_completions(name)
|
||||
|
||||
def rpc_get_pydoc_documentation(self, symbol):
|
||||
"""Get the Pydoc documentation for the given symbol.
|
||||
|
||||
Uses pydoc and can return a string with backspace characters
|
||||
for bold highlighting.
|
||||
|
||||
"""
|
||||
try:
|
||||
docstring = pydoc.render_doc(str(symbol),
|
||||
"Elpy Pydoc Documentation for %s",
|
||||
False)
|
||||
except (ImportError, pydoc.ErrorDuringImport):
|
||||
return None
|
||||
else:
|
||||
if isinstance(docstring, bytes):
|
||||
docstring = docstring.decode("utf-8", "replace")
|
||||
return docstring
|
||||
|
||||
def rpc_get_usages(self, filename, source, offset):
|
||||
"""Get usages for the symbol at point.
|
||||
|
||||
"""
|
||||
source = get_source(source)
|
||||
|
||||
return self._call_backend("rpc_get_usages",
|
||||
None, filename, source, offset)
|
||||
|
||||
def rpc_get_names(self, filename, source, offset):
|
||||
"""Get all possible names
|
||||
|
||||
"""
|
||||
source = get_source(source)
|
||||
return self._call_backend("rpc_get_names",
|
||||
None, filename, source, offset)
|
||||
|
||||
def rpc_get_rename_diff(self, filename, source, offset, new_name):
|
||||
"""Get the diff resulting from renaming the thing at point
|
||||
|
||||
"""
|
||||
source = get_source(source)
|
||||
|
||||
return self._call_backend("rpc_get_rename_diff",
|
||||
None, filename, source, offset, new_name)
|
||||
|
||||
def rpc_get_extract_variable_diff(self, filename, source, offset, new_name,
|
||||
line_beg, line_end, col_beg, col_end):
|
||||
"""Get the diff resulting from extracting the selected code
|
||||
|
||||
"""
|
||||
source = get_source(source)
|
||||
return self._call_backend("rpc_get_extract_variable_diff",
|
||||
None, filename, source, offset,
|
||||
new_name, line_beg, line_end, col_beg,
|
||||
col_end)
|
||||
|
||||
def rpc_get_extract_function_diff(self, filename, source, offset, new_name,
|
||||
line_beg, line_end, col_beg, col_end):
|
||||
"""Get the diff resulting from extracting the selected code
|
||||
|
||||
"""
|
||||
source = get_source(source)
|
||||
return self._call_backend("rpc_get_extract_function_diff",
|
||||
None, filename, source, offset, new_name,
|
||||
line_beg, line_end, col_beg, col_end)
|
||||
|
||||
def rpc_get_inline_diff(self, filename, source, offset):
|
||||
"""Get the diff resulting from inlining the thing at point.
|
||||
|
||||
"""
|
||||
source = get_source(source)
|
||||
return self._call_backend("rpc_get_inline_diff",
|
||||
None, filename, source, offset)
|
||||
|
||||
def rpc_fix_code(self, source, directory):
|
||||
"""Formats Python code to conform to the PEP 8 style guide.
|
||||
|
||||
"""
|
||||
source = get_source(source)
|
||||
return fix_code(source, directory)
|
||||
|
||||
def rpc_fix_code_with_yapf(self, source, directory):
|
||||
"""Formats Python code to conform to the PEP 8 style guide.
|
||||
|
||||
"""
|
||||
source = get_source(source)
|
||||
return fix_code_with_yapf(source, directory)
|
||||
|
||||
def rpc_fix_code_with_black(self, source, directory):
|
||||
"""Formats Python code to conform to the PEP 8 style guide.
|
||||
|
||||
"""
|
||||
source = get_source(source)
|
||||
return fix_code_with_black(source, directory)
|
||||
|
||||
|
||||
def get_source(fileobj):
|
||||
"""Translate fileobj into file contents.
|
||||
|
||||
fileobj is either a string or a dict. If it's a string, that's the
|
||||
file contents. If it's a string, then the filename key contains
|
||||
the name of the file whose contents we are to use.
|
||||
|
||||
If the dict contains a true value for the key delete_after_use,
|
||||
the file should be deleted once read.
|
||||
|
||||
"""
|
||||
if not isinstance(fileobj, dict):
|
||||
return fileobj
|
||||
else:
|
||||
try:
|
||||
with io.open(fileobj["filename"], encoding="utf-8",
|
||||
errors="ignore") as f:
|
||||
return f.read()
|
||||
finally:
|
||||
if fileobj.get('delete_after_use'):
|
||||
try:
|
||||
os.remove(fileobj["filename"])
|
||||
except: # pragma: no cover
|
||||
pass
|
||||
|
||||
|
||||
def _pysymbol_key(name):
|
||||
"""Return a sortable key index for name.
|
||||
|
||||
Sorting is case-insensitive, with the first underscore counting as
|
||||
worse than any character, but subsequent underscores do not. This
|
||||
means that dunder symbols (like __init__) are sorted after symbols
|
||||
that start with an alphabetic character, but before those that
|
||||
start with only a single underscore.
|
||||
|
||||
"""
|
||||
if name.startswith("_"):
|
||||
name = "~" + name[1:]
|
||||
return name.lower()
|
||||
8
elpa-27.2/elpy-20220203.108/elpy/tests/__init__.py
Normal file
8
elpa-27.2/elpy-20220203.108/elpy/tests/__init__.py
Normal file
@@ -0,0 +1,8 @@
|
||||
"""Unit tests for elpy."""
|
||||
|
||||
try:
|
||||
import unittest2
|
||||
import sys
|
||||
sys.modules['unittest'] = unittest2
|
||||
except:
|
||||
pass
|
||||
18
elpa-27.2/elpy-20220203.108/elpy/tests/compat.py
Normal file
18
elpa-27.2/elpy-20220203.108/elpy/tests/compat.py
Normal file
@@ -0,0 +1,18 @@
|
||||
"""Python 2/3 compatibility definitions.
|
||||
|
||||
These are used by the rest of Elpy to keep compatibility definitions
|
||||
in one place.
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
if sys.version_info >= (3, 0):
|
||||
PYTHON3 = True
|
||||
import builtins
|
||||
from io import StringIO
|
||||
else:
|
||||
PYTHON3 = False
|
||||
import __builtin__ as builtins # noqa
|
||||
from StringIO import StringIO # noqa
|
||||
1078
elpa-27.2/elpy-20220203.108/elpy/tests/support.py
Normal file
1078
elpa-27.2/elpy-20220203.108/elpy/tests/support.py
Normal file
File diff suppressed because it is too large
Load Diff
21
elpa-27.2/elpy-20220203.108/elpy/tests/test_auto_pep8.py
Normal file
21
elpa-27.2/elpy-20220203.108/elpy/tests/test_auto_pep8.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""Tests for the elpy.autopep8 module"""
|
||||
|
||||
import unittest
|
||||
import os
|
||||
|
||||
from elpy import auto_pep8
|
||||
from elpy.tests.support import BackendTestCase
|
||||
|
||||
|
||||
class Autopep8TestCase(BackendTestCase):
|
||||
|
||||
def setUp(self):
|
||||
if not auto_pep8.autopep8:
|
||||
raise unittest.SkipTest
|
||||
|
||||
def test_fix_code(self):
|
||||
code_block = 'x= 123\n'
|
||||
new_block = auto_pep8.fix_code(code_block, os.getcwd())
|
||||
self.assertEqual(new_block, 'x = 123\n')
|
||||
64
elpa-27.2/elpy-20220203.108/elpy/tests/test_black.py
Normal file
64
elpa-27.2/elpy-20220203.108/elpy/tests/test_black.py
Normal file
@@ -0,0 +1,64 @@
|
||||
# coding: utf-8
|
||||
"""Tests for the elpy.black module"""
|
||||
|
||||
import unittest
|
||||
import os
|
||||
|
||||
from elpy import blackutil
|
||||
from elpy.rpc import Fault
|
||||
from elpy.tests.support import BackendTestCase
|
||||
|
||||
|
||||
@unittest.skipIf(blackutil.BLACK_NOT_SUPPORTED,
|
||||
'black not supported for current python version')
|
||||
class BLACKTestCase(BackendTestCase):
|
||||
def setUp(self):
|
||||
if blackutil.BLACK_NOT_SUPPORTED:
|
||||
raise unittest.SkipTest
|
||||
|
||||
def test_fix_code_should_throw_error_for_invalid_code(self):
|
||||
src = 'x = '
|
||||
self.assertRaises(Fault, blackutil.fix_code, src, os.getcwd())
|
||||
|
||||
def test_fix_code_should_throw_error_without_black_installed(self):
|
||||
black = blackutil.black
|
||||
blackutil.black = None
|
||||
src = 'x= 123\n', 'x = 123\n'
|
||||
with self.assertRaises(Fault):
|
||||
blackutil.fix_code(src, os.getcwd())
|
||||
blackutil.black = black
|
||||
|
||||
def test_fix_code(self):
|
||||
testdata = [
|
||||
('x= 123\n', 'x = 123\n'),
|
||||
('x=1; \ny=2 \n', 'x = 1\ny = 2\n'),
|
||||
]
|
||||
for src, expected in testdata:
|
||||
self._assert_format(src, expected)
|
||||
|
||||
def test_perfect_code(self):
|
||||
testdata = [
|
||||
('x = 123\n', 'x = 123\n'),
|
||||
('x = 1\ny = 2\n', 'x = 1\ny = 2\n'),
|
||||
]
|
||||
for src, expected in testdata:
|
||||
self._assert_format(src, expected)
|
||||
|
||||
def _assert_format(self, src, expected):
|
||||
new_block = blackutil.fix_code(src, os.getcwd())
|
||||
self.assertEqual(new_block, expected)
|
||||
|
||||
def test_should_read_options_from_pyproject_toml(self):
|
||||
with open('pyproject.toml', 'w') as f:
|
||||
f.write('[tool.black]\nline-length = 10')
|
||||
|
||||
self.addCleanup(os.remove, 'pyproject.toml')
|
||||
|
||||
testdata = [('x= 123\n', 'x = 123\n'),
|
||||
('x=1; \ny=2 \n', 'x = 1\ny = 2\n'),
|
||||
('x, y, z, a, b, c = 123, 124, 125, 126, 127, 128',
|
||||
'(\n x,\n y,\n z,\n a,\n b,\n c,\n)'
|
||||
' = (\n 123,\n 124,\n 125,'
|
||||
'\n 126,\n 127,\n 128,\n)\n')]
|
||||
for src, expected in testdata:
|
||||
self._assert_format(src, expected)
|
||||
383
elpa-27.2/elpy-20220203.108/elpy/tests/test_jedibackend.py
Normal file
383
elpa-27.2/elpy-20220203.108/elpy/tests/test_jedibackend.py
Normal file
@@ -0,0 +1,383 @@
|
||||
"""Tests for the elpy.jedibackend module."""
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
import jedi
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
import re
|
||||
|
||||
from elpy import jedibackend
|
||||
from elpy import rpc
|
||||
from elpy.tests import compat
|
||||
from elpy.tests.support import BackendTestCase
|
||||
from elpy.tests.support import RPCGetCompletionsTests
|
||||
from elpy.tests.support import RPCGetCompletionDocstringTests
|
||||
from elpy.tests.support import RPCGetCompletionLocationTests
|
||||
from elpy.tests.support import RPCGetDocstringTests
|
||||
from elpy.tests.support import RPCGetOnelineDocstringTests
|
||||
from elpy.tests.support import RPCGetDefinitionTests
|
||||
from elpy.tests.support import RPCGetCalltipTests
|
||||
from elpy.tests.support import RPCGetUsagesTests
|
||||
from elpy.tests.support import RPCGetNamesTests
|
||||
from elpy.tests.support import RPCGetRenameDiffTests
|
||||
from elpy.tests.support import RPCGetExtractFunctionDiffTests
|
||||
from elpy.tests.support import RPCGetExtractVariableDiffTests
|
||||
from elpy.tests.support import RPCGetInlineDiffTests
|
||||
from elpy.tests.support import RPCGetAssignmentTests
|
||||
|
||||
|
||||
class JediBackendTestCase(BackendTestCase):
|
||||
def setUp(self):
|
||||
super(JediBackendTestCase, self).setUp()
|
||||
env = jedi.get_default_environment().path
|
||||
self.backend = jedibackend.JediBackend(self.project_root, env)
|
||||
|
||||
|
||||
class TestInit(JediBackendTestCase):
|
||||
def test_should_have_jedi_as_name(self):
|
||||
self.assertEqual(self.backend.name, "jedi")
|
||||
|
||||
|
||||
class TestRPCGetCompletions(RPCGetCompletionsTests,
|
||||
JediBackendTestCase):
|
||||
BUILTINS = ['object', 'oct', 'open', 'ord', 'OSError', 'OverflowError']
|
||||
|
||||
|
||||
class TestRPCGetAssignment(RPCGetAssignmentTests,
|
||||
JediBackendTestCase):
|
||||
pass
|
||||
|
||||
|
||||
class TestRPCGetCompletionDocstring(RPCGetCompletionDocstringTests,
|
||||
JediBackendTestCase):
|
||||
pass
|
||||
|
||||
|
||||
class TestRPCGetCompletionLocation(RPCGetCompletionLocationTests,
|
||||
JediBackendTestCase):
|
||||
pass
|
||||
|
||||
|
||||
class TestRPCGetDocstring(RPCGetDocstringTests,
|
||||
JediBackendTestCase):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(TestRPCGetDocstring, self).__init__(*args, **kwargs)
|
||||
self.JSON_LOADS_REGEX = (
|
||||
r'loads\(s.*, encoding.*, cls.*, object_hook.*, parse_float.*, '
|
||||
r'parse_int.*, .*\)'
|
||||
)
|
||||
|
||||
def check_docstring(self, docstring):
|
||||
lines = docstring.splitlines()
|
||||
self.assertEqual(lines[0], 'Documentation for json.loads:')
|
||||
match = re.match(self.JSON_LOADS_REGEX, lines[2])
|
||||
self.assertIsNotNone(match)
|
||||
|
||||
@mock.patch("elpy.jedibackend.run_with_debug")
|
||||
def test_should_not_return_empty_docstring(self, run_with_debug):
|
||||
location = mock.MagicMock()
|
||||
location.full_name = "testthing"
|
||||
location.docstring.return_value = ""
|
||||
run_with_debug.return_value = [location]
|
||||
filename = self.project_file("test.py", "print")
|
||||
docstring = self.backend.rpc_get_docstring(filename, "print", 0)
|
||||
self.assertIsNone(docstring)
|
||||
|
||||
|
||||
class TestRPCGetOnelineDocstring(RPCGetOnelineDocstringTests,
|
||||
JediBackendTestCase):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(TestRPCGetOnelineDocstring, self).__init__(*args, **kwargs)
|
||||
if sys.version_info >= (3, 6):
|
||||
self.JSON_LOADS_DOCSTRING = (
|
||||
'Deserialize ``s`` (a ``str``, ``bytes`` or'
|
||||
' ``bytearray`` instance containing a JSON'
|
||||
' document) to a Python object.'
|
||||
)
|
||||
self.JSON_DOCSTRING = (
|
||||
"JSON (JavaScript Object Notation) <http://json.org>"
|
||||
" is a subset of JavaScript syntax (ECMA-262"
|
||||
" 3rd edition) used as a lightweight data interchange format.")
|
||||
elif sys.version_info >= (3, 0):
|
||||
self.JSON_LOADS_DOCSTRING = (
|
||||
'Deserialize ``s`` (a ``str`` instance '
|
||||
'containing a JSON document) to a Python object.'
|
||||
)
|
||||
self.JSON_DOCSTRING = (
|
||||
"JSON (JavaScript Object Notation) <http://json.org>"
|
||||
" is a subset of JavaScript syntax (ECMA-262"
|
||||
" 3rd edition) used as a lightweight data interchange format.")
|
||||
else:
|
||||
self.JSON_LOADS_DOCSTRING = (
|
||||
'Deserialize ``s`` (a ``str`` or ``unicode`` '
|
||||
'instance containing a JSON document) to a Python object.'
|
||||
)
|
||||
self.JSON_DOCSTRING = (
|
||||
"JSON (JavaScript Object Notation) <http://json.org>"
|
||||
" is a subset of JavaScript syntax (ECMA-262"
|
||||
" 3rd edition) used as a lightweight data interchange format.")
|
||||
|
||||
@mock.patch("elpy.jedibackend.run_with_debug")
|
||||
def test_should_not_return_empty_docstring(self, run_with_debug):
|
||||
location = mock.MagicMock()
|
||||
location.full_name = "testthing"
|
||||
location.docstring.return_value = ""
|
||||
run_with_debug.return_value = [location]
|
||||
filename = self.project_file("test.py", "print")
|
||||
docstring = self.backend.rpc_get_oneline_docstring(filename, "print", 0)
|
||||
self.assertIsNone(docstring)
|
||||
|
||||
|
||||
class TestRPCGetDefinition(RPCGetDefinitionTests,
|
||||
JediBackendTestCase):
|
||||
@mock.patch("jedi.Script")
|
||||
def test_should_not_fail_if_module_path_is_none(self, Script):
|
||||
"""Do not fail if loc.module_path is None.
|
||||
|
||||
This can happen under some circumstances I am unsure about.
|
||||
See #537 for the issue that reported this.
|
||||
|
||||
"""
|
||||
locations = [
|
||||
mock.Mock(module_path=None)
|
||||
]
|
||||
script = Script.return_value
|
||||
script.goto_definitions.return_value = locations
|
||||
script.goto_assignments.return_value = locations
|
||||
|
||||
location = self.rpc("", "", 0)
|
||||
|
||||
self.assertIsNone(location)
|
||||
|
||||
|
||||
class TestRPCGetRenameDiff(RPCGetRenameDiffTests,
|
||||
JediBackendTestCase):
|
||||
pass
|
||||
|
||||
|
||||
class TestRPCGetExtractFunctionDiff(RPCGetExtractFunctionDiffTests,
|
||||
JediBackendTestCase):
|
||||
pass
|
||||
|
||||
|
||||
class TestRPCGetExtractVariableDiff(RPCGetExtractVariableDiffTests,
|
||||
JediBackendTestCase):
|
||||
pass
|
||||
|
||||
|
||||
class TestRPCGetInlineDiff(RPCGetInlineDiffTests,
|
||||
JediBackendTestCase):
|
||||
pass
|
||||
|
||||
|
||||
class TestRPCGetCalltip(RPCGetCalltipTests,
|
||||
JediBackendTestCase):
|
||||
KEYS_CALLTIP = {'index': None,
|
||||
'params': [],
|
||||
'name': u'keys'}
|
||||
RADIX_CALLTIP = {'index': None,
|
||||
'params': [],
|
||||
'name': u'radix'}
|
||||
ADD_CALLTIP = {'index': 0,
|
||||
'params': [u'a', u'b'],
|
||||
'name': u'add'}
|
||||
if compat.PYTHON3:
|
||||
THREAD_CALLTIP = {'name': 'Thread',
|
||||
'index': 0,
|
||||
'params': ['group: None=...',
|
||||
'target: Optional[Callable[..., Any]]=...',
|
||||
'name: Optional[str]=...',
|
||||
'args: Iterable[Any]=...',
|
||||
'kwargs: Mapping[str, Any]=...',
|
||||
'daemon: Optional[bool]=...']}
|
||||
|
||||
else:
|
||||
THREAD_CALLTIP = {'index': 0,
|
||||
'name': u'Thread',
|
||||
'params': [u'group: None=...',
|
||||
u'target: Optional[Callable[..., Any]]=...',
|
||||
u'name: Optional[str]=...',
|
||||
u'args: Iterable[Any]=...',
|
||||
u'kwargs: Mapping[str, Any]=...']}
|
||||
|
||||
def test_should_not_fail_with_get_subscope_by_name(self):
|
||||
# Bug #677 / jedi#628
|
||||
source = (
|
||||
u"my_lambda = lambda x: x+1\n"
|
||||
u"my_lambda(1)"
|
||||
)
|
||||
filename = self.project_file("project.py", source)
|
||||
offset = 37
|
||||
|
||||
sigs = self.backend.rpc_get_calltip(filename, source, offset)
|
||||
sigs["index"]
|
||||
|
||||
|
||||
class TestRPCGetUsages(RPCGetUsagesTests,
|
||||
JediBackendTestCase):
|
||||
def test_should_not_fail_for_missing_module(self):
|
||||
# This causes use.module_path to be None
|
||||
source = "import sys\n\nsys.path.\n" # insert()"
|
||||
offset = 21
|
||||
filename = self.project_file("project.py", source)
|
||||
|
||||
self.rpc(filename, source, offset)
|
||||
|
||||
|
||||
class TestRPCGetNames(RPCGetNamesTests,
|
||||
JediBackendTestCase):
|
||||
pass
|
||||
|
||||
|
||||
class TestPosToLinecol(unittest.TestCase):
|
||||
def test_should_handle_beginning_of_string(self):
|
||||
self.assertEqual(jedibackend.pos_to_linecol("foo", 0),
|
||||
(1, 0))
|
||||
|
||||
def test_should_handle_end_of_line(self):
|
||||
self.assertEqual(jedibackend.pos_to_linecol("foo\nbar\nbaz\nqux", 9),
|
||||
(3, 1))
|
||||
|
||||
def test_should_handle_end_of_string(self):
|
||||
self.assertEqual(jedibackend.pos_to_linecol("foo\nbar\nbaz\nqux", 14),
|
||||
(4, 2))
|
||||
|
||||
|
||||
class TestLinecolToPos(unittest.TestCase):
|
||||
def test_should_handle_beginning_of_string(self):
|
||||
self.assertEqual(jedibackend.linecol_to_pos("foo", 1, 0),
|
||||
0)
|
||||
|
||||
def test_should_handle_end_of_string(self):
|
||||
self.assertEqual(jedibackend.linecol_to_pos("foo\nbar\nbaz\nqux",
|
||||
3, 1),
|
||||
9)
|
||||
|
||||
def test_should_return_offset(self):
|
||||
self.assertEqual(jedibackend.linecol_to_pos("foo\nbar\nbaz\nqux",
|
||||
4, 2),
|
||||
14)
|
||||
|
||||
def test_should_fail_for_line_past_text(self):
|
||||
self.assertRaises(ValueError,
|
||||
jedibackend.linecol_to_pos, "foo\n", 3, 1)
|
||||
|
||||
def test_should_fail_for_column_past_text(self):
|
||||
self.assertRaises(ValueError,
|
||||
jedibackend.linecol_to_pos, "foo\n", 1, 10)
|
||||
|
||||
|
||||
class TestRunWithDebug(unittest.TestCase):
|
||||
@mock.patch('jedi.Script')
|
||||
def test_should_call_method(self, Script):
|
||||
Script.return_value.test_method.return_value = "test-result"
|
||||
|
||||
result = jedibackend.run_with_debug(jedi, 'test_method', {}, 1, 2,
|
||||
arg=3)
|
||||
|
||||
Script.assert_called_with(1, 2, arg=3)
|
||||
self.assertEqual(result, 'test-result')
|
||||
|
||||
@mock.patch('jedi.Script')
|
||||
def test_should_re_raise(self, Script):
|
||||
Script.side_effect = RuntimeError
|
||||
|
||||
with self.assertRaises(RuntimeError):
|
||||
jedibackend.run_with_debug(jedi, 'test_method', 1, 2, arg=3,
|
||||
re_raise=(RuntimeError,))
|
||||
|
||||
@mock.patch('jedi.Script')
|
||||
@mock.patch('jedi.set_debug_function')
|
||||
def test_should_keep_debug_info(self, set_debug_function, Script):
|
||||
Script.side_effect = RuntimeError
|
||||
|
||||
try:
|
||||
jedibackend.run_with_debug(jedi, 'test_method', {}, 1, 2, arg=3)
|
||||
except rpc.Fault as e:
|
||||
self.assertGreaterEqual(e.code, 400)
|
||||
self.assertIsNotNone(e.data)
|
||||
self.assertIn("traceback", e.data)
|
||||
jedi_debug_info = e.data["jedi_debug_info"]
|
||||
self.assertIsNotNone(jedi_debug_info)
|
||||
self.assertEqual(jedi_debug_info["script_args"],
|
||||
"1, 2, arg=3")
|
||||
self.assertEqual(jedi_debug_info["source"], None)
|
||||
self.assertEqual(jedi_debug_info["method"], "test_method")
|
||||
self.assertEqual(jedi_debug_info["debug_info"], [])
|
||||
else:
|
||||
self.fail("Fault not thrown")
|
||||
|
||||
@mock.patch('jedi.Script')
|
||||
@mock.patch('jedi.set_debug_function')
|
||||
def test_should_keep_error_text(self, set_debug_function, Script):
|
||||
Script.side_effect = RuntimeError
|
||||
|
||||
try:
|
||||
jedibackend.run_with_debug(jedi, 'test_method', {}, 1, 2, arg=3)
|
||||
except rpc.Fault as e:
|
||||
self.assertEqual(str(e), str(RuntimeError()))
|
||||
self.assertEqual(e.message, str(RuntimeError()))
|
||||
else:
|
||||
self.fail("Fault not thrown")
|
||||
|
||||
@mock.patch('jedi.Script')
|
||||
@mock.patch('jedi.set_debug_function')
|
||||
def test_should_handle_source_special(self, set_debug_function, Script):
|
||||
Script.side_effect = RuntimeError
|
||||
|
||||
try:
|
||||
jedibackend.run_with_debug(jedi, 'test_method', source="foo")
|
||||
except rpc.Fault as e:
|
||||
self.assertEqual(e.data["jedi_debug_info"]["script_args"],
|
||||
"source=source")
|
||||
self.assertEqual(e.data["jedi_debug_info"]["source"], "foo")
|
||||
else:
|
||||
self.fail("Fault not thrown")
|
||||
|
||||
@mock.patch('jedi.Script')
|
||||
@mock.patch('jedi.set_debug_function')
|
||||
def test_should_set_debug_info(self, set_debug_function, Script):
|
||||
the_debug_function = [None]
|
||||
|
||||
def my_set_debug_function(debug_function, **kwargs):
|
||||
the_debug_function[0] = debug_function
|
||||
|
||||
def my_script(*args, **kwargs):
|
||||
the_debug_function[0](jedi.debug.NOTICE, "Notice")
|
||||
the_debug_function[0](jedi.debug.WARNING, "Warning")
|
||||
the_debug_function[0]("other", "Other")
|
||||
raise RuntimeError
|
||||
|
||||
set_debug_function.side_effect = my_set_debug_function
|
||||
Script.return_value.test_method = my_script
|
||||
|
||||
try:
|
||||
jedibackend.run_with_debug(jedi, 'test_method', source="foo")
|
||||
except rpc.Fault as e:
|
||||
self.assertEqual(e.data["jedi_debug_info"]["debug_info"],
|
||||
["[N] Notice",
|
||||
"[W] Warning",
|
||||
"[?] Other"])
|
||||
else:
|
||||
self.fail("Fault not thrown")
|
||||
|
||||
@mock.patch('jedi.set_debug_function')
|
||||
@mock.patch('jedi.Script')
|
||||
def test_should_not_fail_with_bad_data(self, Script, set_debug_function):
|
||||
import jedi.debug
|
||||
|
||||
def set_debug(function, speed=True):
|
||||
if function is not None:
|
||||
function(jedi.debug.NOTICE, u"\xab")
|
||||
|
||||
set_debug_function.side_effect = set_debug
|
||||
Script.return_value.test_method.side_effect = Exception
|
||||
|
||||
with self.assertRaises(rpc.Fault):
|
||||
jedibackend.run_with_debug(jedi, 'test_method', {}, 1, 2, arg=3)
|
||||
91
elpa-27.2/elpy-20220203.108/elpy/tests/test_pydocutils.py
Normal file
91
elpa-27.2/elpy-20220203.108/elpy/tests/test_pydocutils.py
Normal file
@@ -0,0 +1,91 @@
|
||||
import os
|
||||
import unittest
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
|
||||
import elpy.pydocutils
|
||||
|
||||
|
||||
class TestGetPydocCompletions(unittest.TestCase):
|
||||
def test_should_return_top_level_modules(self):
|
||||
modules = elpy.pydocutils.get_pydoc_completions("")
|
||||
self.assertIn('sys', modules)
|
||||
self.assertIn('json', modules)
|
||||
|
||||
def test_should_return_submodules(self):
|
||||
modules = elpy.pydocutils.get_pydoc_completions("elpy")
|
||||
self.assertIn("elpy.rpc", modules)
|
||||
self.assertIn("elpy.server", modules)
|
||||
modules = elpy.pydocutils.get_pydoc_completions("os")
|
||||
self.assertIn("os.path", modules)
|
||||
|
||||
def test_should_find_objects_in_module(self):
|
||||
self.assertIn("elpy.tests.test_pydocutils.TestGetPydocCompletions",
|
||||
elpy.pydocutils.get_pydoc_completions
|
||||
("elpy.tests.test_pydocutils"))
|
||||
|
||||
def test_should_find_attributes_of_objects(self):
|
||||
attribs = elpy.pydocutils.get_pydoc_completions(
|
||||
"elpy.tests.test_pydocutils.TestGetPydocCompletions")
|
||||
self.assertIn("elpy.tests.test_pydocutils.TestGetPydocCompletions."
|
||||
"test_should_find_attributes_of_objects",
|
||||
attribs)
|
||||
|
||||
def test_should_return_none_for_inexisting_module(self):
|
||||
self.assertEqual([],
|
||||
elpy.pydocutils.get_pydoc_completions
|
||||
("does_not_exist"))
|
||||
|
||||
def test_should_work_for_unicode_strings(self):
|
||||
self.assertIsNotNone(elpy.pydocutils.get_pydoc_completions
|
||||
(u"sys"))
|
||||
|
||||
def test_should_find_partial_completions(self):
|
||||
self.assertIn("multiprocessing",
|
||||
elpy.pydocutils.get_pydoc_completions
|
||||
("multiprocess"))
|
||||
self.assertIn("multiprocessing.util",
|
||||
elpy.pydocutils.get_pydoc_completions
|
||||
("multiprocessing.ut"))
|
||||
|
||||
def test_should_ignore_trailing_dot(self):
|
||||
self.assertIn("elpy.pydocutils",
|
||||
elpy.pydocutils.get_pydoc_completions
|
||||
("elpy."))
|
||||
|
||||
|
||||
class TestGetModules(unittest.TestCase):
|
||||
def test_should_return_top_level_modules(self):
|
||||
modules = elpy.pydocutils.get_modules()
|
||||
self.assertIn('sys', modules)
|
||||
self.assertIn('json', modules)
|
||||
|
||||
def test_should_return_submodules(self):
|
||||
modules = elpy.pydocutils.get_modules("elpy")
|
||||
self.assertIn("rpc", modules)
|
||||
self.assertIn("server", modules)
|
||||
|
||||
@mock.patch.object(elpy.pydocutils, 'safeimport')
|
||||
def test_should_catch_import_errors(self, safeimport):
|
||||
def raise_function(message):
|
||||
raise elpy.pydocutils.ErrorDuringImport(message,
|
||||
(None, None, None))
|
||||
safeimport.side_effect = raise_function
|
||||
self.assertEqual([], elpy.pydocutils.get_modules("foo.bar"))
|
||||
|
||||
def test_should_not_fail_for_permission_denied(self):
|
||||
tmpdir = tempfile.mkdtemp(prefix="test-elpy-get-modules-")
|
||||
sys.path.append(tmpdir)
|
||||
os.chmod(tmpdir, 0o000)
|
||||
try:
|
||||
elpy.pydocutils.get_modules()
|
||||
finally:
|
||||
os.chmod(tmpdir, 0o755)
|
||||
shutil.rmtree(tmpdir)
|
||||
sys.path.remove(tmpdir)
|
||||
209
elpa-27.2/elpy-20220203.108/elpy/tests/test_rpc.py
Normal file
209
elpa-27.2/elpy-20220203.108/elpy/tests/test_rpc.py
Normal file
@@ -0,0 +1,209 @@
|
||||
"""Tests for elpy.rpc."""
|
||||
|
||||
import json
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
from elpy import rpc
|
||||
from elpy.tests.compat import StringIO
|
||||
|
||||
|
||||
class TestFault(unittest.TestCase):
|
||||
def test_should_have_code_and_data(self):
|
||||
fault = rpc.Fault("Hello", code=250, data="Fnord")
|
||||
self.assertEqual(str(fault), "Hello")
|
||||
self.assertEqual(fault.code, 250)
|
||||
self.assertEqual(fault.data, "Fnord")
|
||||
|
||||
def test_should_have_defaults_for_code_and_data(self):
|
||||
fault = rpc.Fault("Hello")
|
||||
self.assertEqual(str(fault), "Hello")
|
||||
self.assertEqual(fault.code, 500)
|
||||
self.assertIsNone(fault.data)
|
||||
|
||||
|
||||
class TestJSONRPCServer(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.stdin = StringIO()
|
||||
self.stdout = StringIO()
|
||||
self.rpc = rpc.JSONRPCServer(self.stdin, self.stdout)
|
||||
|
||||
def write(self, s):
|
||||
self.stdin.seek(0)
|
||||
self.stdin.truncate()
|
||||
self.stdout.seek(0)
|
||||
self.stdout.truncate()
|
||||
self.stdin.write(s)
|
||||
self.stdin.seek(0)
|
||||
|
||||
def read(self):
|
||||
value = self.stdout.getvalue()
|
||||
self.stdin.seek(0)
|
||||
self.stdin.truncate()
|
||||
self.stdout.seek(0)
|
||||
self.stdout.truncate()
|
||||
return value
|
||||
|
||||
|
||||
class TestInit(TestJSONRPCServer):
|
||||
def test_should_use_arguments(self):
|
||||
self.assertEqual(self.rpc.stdin, self.stdin)
|
||||
self.assertEqual(self.rpc.stdout, self.stdout)
|
||||
|
||||
def test_should_default_to_sys(self):
|
||||
testrpc = rpc.JSONRPCServer()
|
||||
self.assertEqual(sys.stdin, testrpc.stdin)
|
||||
self.assertEqual(sys.stdout, testrpc.stdout)
|
||||
|
||||
|
||||
class TestReadJson(TestJSONRPCServer):
|
||||
def test_should_read_json(self):
|
||||
objlist = [{'foo': 'bar'},
|
||||
{'baz': 'qux', 'fnord': 'argl\nbargl'},
|
||||
"beep\r\nbeep\r\nbeep"]
|
||||
self.write("".join([(json.dumps(obj) + "\n")
|
||||
for obj in objlist]))
|
||||
for obj in objlist:
|
||||
self.assertEqual(self.rpc.read_json(),
|
||||
obj)
|
||||
|
||||
def test_should_raise_eof_on_eof(self):
|
||||
self.assertRaises(EOFError, self.rpc.read_json)
|
||||
|
||||
def test_should_fail_on_malformed_json(self):
|
||||
self.write("malformed json\n")
|
||||
self.assertRaises(ValueError,
|
||||
self.rpc.read_json)
|
||||
|
||||
|
||||
class TestWriteJson(TestJSONRPCServer):
|
||||
def test_should_write_json_line(self):
|
||||
objlist = [{'foo': 'bar'},
|
||||
{'baz': 'qux', 'fnord': 'argl\nbargl'},
|
||||
]
|
||||
for obj in objlist:
|
||||
self.rpc.write_json(**obj)
|
||||
self.assertEqual(json.loads(self.read()),
|
||||
obj)
|
||||
|
||||
|
||||
class TestHandleRequest(TestJSONRPCServer):
|
||||
def test_should_fail_if_json_does_not_contain_a_method(self):
|
||||
self.write(json.dumps(dict(params=[],
|
||||
id=23)))
|
||||
self.assertRaises(ValueError,
|
||||
self.rpc.handle_request)
|
||||
|
||||
def test_should_call_right_method(self):
|
||||
self.write(json.dumps(dict(method='foo',
|
||||
params=[1, 2, 3],
|
||||
id=23)))
|
||||
self.rpc.rpc_foo = lambda *params: params
|
||||
self.rpc.handle_request()
|
||||
self.assertEqual(json.loads(self.read()),
|
||||
dict(id=23,
|
||||
result=[1, 2, 3]))
|
||||
|
||||
def test_should_pass_defaults_for_missing_parameters(self):
|
||||
def test_method(*params):
|
||||
self.args = params
|
||||
|
||||
self.write(json.dumps(dict(method='foo')))
|
||||
self.rpc.rpc_foo = test_method
|
||||
self.rpc.handle_request()
|
||||
self.assertEqual(self.args, ())
|
||||
self.assertEqual(self.read(), "")
|
||||
|
||||
def test_should_return_error_for_missing_method(self):
|
||||
self.write(json.dumps(dict(method='foo',
|
||||
id=23)))
|
||||
self.rpc.handle_request()
|
||||
result = json.loads(self.read())
|
||||
|
||||
self.assertEqual(result["id"], 23)
|
||||
self.assertEqual(result["error"]["message"],
|
||||
"Unknown method foo")
|
||||
|
||||
def test_should_return_error_for_exception_in_method(self):
|
||||
def test_method():
|
||||
raise ValueError("An error was raised")
|
||||
|
||||
self.write(json.dumps(dict(method='foo',
|
||||
id=23)))
|
||||
self.rpc.rpc_foo = test_method
|
||||
|
||||
self.rpc.handle_request()
|
||||
result = json.loads(self.read())
|
||||
|
||||
self.assertEqual(result["id"], 23)
|
||||
self.assertEqual(result["error"]["message"], "An error was raised")
|
||||
self.assertIn("traceback", result["error"]["data"])
|
||||
|
||||
def test_should_not_include_traceback_for_faults(self):
|
||||
def test_method():
|
||||
raise rpc.Fault("This is a fault")
|
||||
|
||||
self.write(json.dumps(dict(method="foo",
|
||||
id=23)))
|
||||
self.rpc.rpc_foo = test_method
|
||||
|
||||
self.rpc.handle_request()
|
||||
result = json.loads(self.read())
|
||||
|
||||
self.assertEqual(result["id"], 23)
|
||||
self.assertEqual(result["error"]["message"], "This is a fault")
|
||||
self.assertNotIn("traceback", result["error"])
|
||||
|
||||
def test_should_add_data_for_faults(self):
|
||||
def test_method():
|
||||
raise rpc.Fault("St. Andreas' Fault",
|
||||
code=12345, data="Yippieh")
|
||||
|
||||
self.write(json.dumps(dict(method="foo", id=23)))
|
||||
self.rpc.rpc_foo = test_method
|
||||
|
||||
self.rpc.handle_request()
|
||||
result = json.loads(self.read())
|
||||
|
||||
self.assertEqual(result["error"]["data"], "Yippieh")
|
||||
|
||||
def test_should_call_handle_for_unknown_method(self):
|
||||
def test_handle(method_name, args):
|
||||
return "It works"
|
||||
self.write(json.dumps(dict(method="doesnotexist",
|
||||
id=23)))
|
||||
self.rpc.handle = test_handle
|
||||
self.rpc.handle_request()
|
||||
self.assertEqual(json.loads(self.read()),
|
||||
dict(id=23,
|
||||
result="It works"))
|
||||
|
||||
|
||||
class TestServeForever(TestJSONRPCServer):
|
||||
def handle_request(self):
|
||||
self.hr_called += 1
|
||||
if self.hr_called > 10:
|
||||
raise self.error()
|
||||
|
||||
def setUp(self):
|
||||
super(TestServeForever, self).setUp()
|
||||
self.hr_called = 0
|
||||
self.error = KeyboardInterrupt
|
||||
self.rpc.handle_request = self.handle_request
|
||||
|
||||
def test_should_call_handle_request_repeatedly(self):
|
||||
self.rpc.serve_forever()
|
||||
self.assertEqual(self.hr_called, 11)
|
||||
|
||||
def test_should_return_on_some_errors(self):
|
||||
self.error = KeyboardInterrupt
|
||||
self.rpc.serve_forever()
|
||||
self.error = EOFError
|
||||
self.rpc.serve_forever()
|
||||
self.error = SystemExit
|
||||
self.rpc.serve_forever()
|
||||
|
||||
def test_should_fail_on_most_errors(self):
|
||||
self.error = RuntimeError
|
||||
self.assertRaises(RuntimeError,
|
||||
self.rpc.serve_forever)
|
||||
384
elpa-27.2/elpy-20220203.108/elpy/tests/test_server.py
Normal file
384
elpa-27.2/elpy-20220203.108/elpy/tests/test_server.py
Normal file
@@ -0,0 +1,384 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""Tests for the elpy.server module"""
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
|
||||
from elpy import rpc
|
||||
from elpy import server
|
||||
from elpy.tests import compat
|
||||
from elpy.tests.support import BackendTestCase
|
||||
|
||||
|
||||
class ServerTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.srv = server.ElpyRPCServer()
|
||||
|
||||
|
||||
class BackendCallTestCase(ServerTestCase):
|
||||
def assert_calls_backend(self, method, add_args=[], add_kwargs={}):
|
||||
with mock.patch("elpy.server.get_source") as get_source:
|
||||
with mock.patch.object(self.srv, "backend") as backend:
|
||||
get_source.return_value = "transformed source"
|
||||
|
||||
getattr(self.srv, method)("filename", "source", "offset",
|
||||
*add_args,
|
||||
**add_kwargs)
|
||||
|
||||
get_source.assert_called_with("source")
|
||||
getattr(backend, method).assert_called_with(
|
||||
"filename", "transformed source", "offset",
|
||||
*add_args,
|
||||
**add_kwargs
|
||||
)
|
||||
|
||||
|
||||
class TestInit(ServerTestCase):
|
||||
def test_should_not_select_a_backend_by_default(self):
|
||||
self.assertIsNone(self.srv.backend)
|
||||
|
||||
|
||||
class TestRPCEcho(ServerTestCase):
|
||||
def test_should_return_arguments(self):
|
||||
self.assertEqual(("hello", "world"),
|
||||
self.srv.rpc_echo("hello", "world"))
|
||||
|
||||
|
||||
class TestRPCInit(ServerTestCase):
|
||||
@mock.patch("elpy.jedibackend.JediBackend")
|
||||
def test_should_set_project_root(self, JediBackend):
|
||||
self.srv.rpc_init({"project_root": "/project/root",
|
||||
"environment": "/project/env"})
|
||||
|
||||
self.assertEqual("/project/root", self.srv.project_root)
|
||||
|
||||
@mock.patch("jedi.create_environment")
|
||||
def test_should_set_project_env(self, create_environment):
|
||||
self.srv.rpc_init({"project_root": "/project/root",
|
||||
"environment": "/project/env"})
|
||||
|
||||
create_environment.assert_called_with("/project/env", safe=False)
|
||||
|
||||
@mock.patch("elpy.jedibackend.JediBackend")
|
||||
def test_should_initialize_jedi(self, JediBackend):
|
||||
self.srv.rpc_init({"project_root": "/project/root",
|
||||
"environment": "/project/env"})
|
||||
|
||||
JediBackend.assert_called_with("/project/root", "/project/env")
|
||||
|
||||
|
||||
@mock.patch("elpy.jedibackend.JediBackend")
|
||||
def test_should_use_jedi_if_available(self, JediBackend):
|
||||
JediBackend.return_value.name = "jedi"
|
||||
|
||||
self.srv.rpc_init({"project_root": "/project/root",
|
||||
"environment": "/project/env"})
|
||||
|
||||
self.assertEqual("jedi", self.srv.backend.name)
|
||||
|
||||
|
||||
@mock.patch("elpy.jedibackend.JediBackend")
|
||||
def test_should_use_none_if_nothing_available(
|
||||
self, JediBackend):
|
||||
JediBackend.return_value.name = "jedi"
|
||||
old_jedi = server.jedibackend
|
||||
server.jedibackend = None
|
||||
|
||||
try:
|
||||
self.srv.rpc_init({"project_root": "/project/root",
|
||||
"environment": "/project/env"})
|
||||
finally:
|
||||
server.jedibackend = old_jedi
|
||||
|
||||
self.assertIsNone(self.srv.backend)
|
||||
|
||||
|
||||
class TestRPCGetCalltip(BackendCallTestCase):
|
||||
def test_should_call_backend(self):
|
||||
self.assert_calls_backend("rpc_get_calltip")
|
||||
|
||||
def test_should_handle_no_backend(self):
|
||||
self.srv.backend = None
|
||||
self.assertIsNone(self.srv.rpc_get_calltip("filname", "source",
|
||||
"offset"))
|
||||
|
||||
|
||||
class TestRPCGetCompletions(BackendCallTestCase):
|
||||
def test_should_call_backend(self):
|
||||
self.assert_calls_backend("rpc_get_completions")
|
||||
|
||||
def test_should_handle_no_backend(self):
|
||||
self.srv.backend = None
|
||||
self.assertEqual([],
|
||||
self.srv.rpc_get_completions("filname", "source",
|
||||
"offset"))
|
||||
|
||||
def test_should_sort_results(self):
|
||||
with mock.patch.object(self.srv, 'backend') as backend:
|
||||
backend.rpc_get_completions.return_value = [
|
||||
{'name': '_e'},
|
||||
{'name': '__d'},
|
||||
{'name': 'c'},
|
||||
{'name': 'B'},
|
||||
{'name': 'a'},
|
||||
]
|
||||
expected = list(reversed(backend.rpc_get_completions.return_value))
|
||||
|
||||
actual = self.srv.rpc_get_completions("filename", "source",
|
||||
"offset")
|
||||
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_should_uniquify_results(self):
|
||||
with mock.patch.object(self.srv, 'backend') as backend:
|
||||
backend.rpc_get_completions.return_value = [
|
||||
{'name': 'a'},
|
||||
{'name': 'a'},
|
||||
]
|
||||
expected = [{'name': 'a'}]
|
||||
|
||||
actual = self.srv.rpc_get_completions("filename", "source",
|
||||
"offset")
|
||||
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
|
||||
class TestRPCGetCompletionDocs(ServerTestCase):
|
||||
def test_should_call_backend(self):
|
||||
with mock.patch.object(self.srv, "backend") as backend:
|
||||
self.srv.rpc_get_completion_docstring("completion")
|
||||
|
||||
(backend.rpc_get_completion_docstring
|
||||
.assert_called_with("completion"))
|
||||
|
||||
def test_should_handle_no_backend(self):
|
||||
self.srv.backend = None
|
||||
self.assertIsNone(self.srv.rpc_get_completion_docstring("foo"))
|
||||
|
||||
|
||||
class TestRPCGetCompletionLocation(ServerTestCase):
|
||||
def test_should_call_backend(self):
|
||||
with mock.patch.object(self.srv, "backend") as backend:
|
||||
self.srv.rpc_get_completion_location("completion")
|
||||
|
||||
(backend.rpc_get_completion_location
|
||||
.assert_called_with("completion"))
|
||||
|
||||
def test_should_handle_no_backend(self):
|
||||
self.srv.backend = None
|
||||
self.assertIsNone(self.srv.rpc_get_completion_location("foo"))
|
||||
|
||||
|
||||
class TestRPCGetDefinition(BackendCallTestCase):
|
||||
def test_should_call_backend(self):
|
||||
self.assert_calls_backend("rpc_get_definition")
|
||||
|
||||
def test_should_handle_no_backend(self):
|
||||
self.srv.backend = None
|
||||
self.assertIsNone(self.srv.rpc_get_definition("filname", "source",
|
||||
"offset"))
|
||||
|
||||
|
||||
class TestRPCGetDocstring(BackendCallTestCase):
|
||||
def test_should_call_backend(self):
|
||||
self.assert_calls_backend("rpc_get_docstring")
|
||||
|
||||
def test_should_handle_no_backend(self):
|
||||
self.srv.backend = None
|
||||
self.assertIsNone(self.srv.rpc_get_docstring("filname", "source",
|
||||
"offset"))
|
||||
|
||||
|
||||
class TestRPCGetOnelineDocstring(BackendCallTestCase):
|
||||
def test_should_call_backend(self):
|
||||
self.assert_calls_backend("rpc_get_oneline_docstring")
|
||||
|
||||
def test_should_handle_no_backend(self):
|
||||
self.srv.backend = None
|
||||
self.assertIsNone(self.srv.rpc_get_oneline_docstring("filname",
|
||||
"source",
|
||||
"offset"))
|
||||
|
||||
|
||||
class TestRPCGetCalltipOrOnelineDocstring(BackendCallTestCase):
|
||||
def test_should_call_backend(self):
|
||||
self.assert_calls_backend("rpc_get_calltip_or_oneline_docstring")
|
||||
|
||||
def test_should_handle_no_backend(self):
|
||||
self.srv.backend = None
|
||||
self.assertIsNone(
|
||||
self.srv.rpc_get_calltip_or_oneline_docstring("filname",
|
||||
"source",
|
||||
"offset"))
|
||||
|
||||
|
||||
class TestRPCGetRenameDiff(BackendCallTestCase):
|
||||
def test_should_call_backend(self):
|
||||
self.assert_calls_backend("rpc_get_rename_diff",
|
||||
add_args=['new_name'])
|
||||
|
||||
def test_should_handle_no_backend(self):
|
||||
self.srv.backend = None
|
||||
self.assertIsNone(self.srv.rpc_get_rename_diff("filname", "source",
|
||||
"offset", "new_name"))
|
||||
|
||||
|
||||
class TestRPCGetExtract_VariableDiff(BackendCallTestCase):
|
||||
def test_should_call_backend(self):
|
||||
self.assert_calls_backend("rpc_get_extract_variable_diff",
|
||||
add_args=['name', 12, 13, 3, 5])
|
||||
|
||||
def test_should_handle_no_backend(self):
|
||||
self.srv.backend = None
|
||||
self.assertIsNone(self.srv.rpc_get_extract_variable_diff(
|
||||
"filname", "source", "offset", "new_name", 1, 1, 0, 3))
|
||||
|
||||
|
||||
class TestRPCGetExtract_FunctionDiff(BackendCallTestCase):
|
||||
def test_should_call_backend(self):
|
||||
self.assert_calls_backend("rpc_get_extract_function_diff",
|
||||
add_args=['name', 12, 13, 3, 5])
|
||||
|
||||
|
||||
def test_should_handle_no_backend(self):
|
||||
self.srv.backend = None
|
||||
self.assertIsNone(self.srv.rpc_get_extract_function_diff(
|
||||
"filname", "source", "offset", "new_name", 1, 1, 0, 4))
|
||||
|
||||
|
||||
class TestRPCGetInlineDiff(BackendCallTestCase):
|
||||
def test_should_call_backend(self):
|
||||
self.assert_calls_backend("rpc_get_inline_diff")
|
||||
|
||||
def test_should_handle_no_backend(self):
|
||||
self.srv.backend = None
|
||||
self.assertIsNone(self.srv.rpc_get_inline_diff("filname", "source",
|
||||
"offset"))
|
||||
|
||||
|
||||
class TestRPCGetPydocCompletions(ServerTestCase):
|
||||
@mock.patch.object(server, 'get_pydoc_completions')
|
||||
def test_should_call_pydoc_completions(self, get_pydoc_completions):
|
||||
srv = server.ElpyRPCServer()
|
||||
srv.rpc_get_pydoc_completions()
|
||||
get_pydoc_completions.assert_called_with(None)
|
||||
srv.rpc_get_pydoc_completions("foo")
|
||||
get_pydoc_completions.assert_called_with("foo")
|
||||
|
||||
|
||||
class TestGetPydocDocumentation(ServerTestCase):
|
||||
@mock.patch("pydoc.render_doc")
|
||||
def test_should_find_documentation(self, render_doc):
|
||||
render_doc.return_value = "expected"
|
||||
|
||||
actual = self.srv.rpc_get_pydoc_documentation("open")
|
||||
|
||||
render_doc.assert_called_with("open",
|
||||
"Elpy Pydoc Documentation for %s",
|
||||
False)
|
||||
self.assertEqual("expected", actual)
|
||||
|
||||
def test_should_return_none_for_unknown_module(self):
|
||||
actual = self.srv.rpc_get_pydoc_documentation("frob.open")
|
||||
|
||||
self.assertIsNone(actual)
|
||||
|
||||
def test_should_return_valid_unicode(self):
|
||||
import json
|
||||
|
||||
docstring = self.srv.rpc_get_pydoc_documentation("tarfile")
|
||||
|
||||
json.dumps(docstring)
|
||||
|
||||
|
||||
class TestRPCGetUsages(BackendCallTestCase):
|
||||
def test_should_call_backend(self):
|
||||
self.assert_calls_backend("rpc_get_usages")
|
||||
|
||||
def test_should_handle_no_backend(self):
|
||||
self.srv.backend = None
|
||||
self.assertIsNone(self.srv.rpc_get_usages("filname", "source",
|
||||
"offset"))
|
||||
|
||||
|
||||
class TestRPCGetNames(BackendCallTestCase):
|
||||
def test_should_call_backend(self):
|
||||
self.assert_calls_backend("rpc_get_names")
|
||||
|
||||
def test_should_handle_no_backend(self):
|
||||
self.srv.backend = None
|
||||
self.assertIsNone(self.srv.rpc_get_names("filname", "source", 0))
|
||||
|
||||
|
||||
class TestGetSource(unittest.TestCase):
|
||||
def test_should_return_string_by_default(self):
|
||||
self.assertEqual(server.get_source("foo"),
|
||||
"foo")
|
||||
|
||||
def test_should_return_file_contents(self):
|
||||
fd, filename = tempfile.mkstemp(prefix="elpy-test-")
|
||||
self.addCleanup(os.remove, filename)
|
||||
with open(filename, "w") as f:
|
||||
f.write("file contents")
|
||||
|
||||
fileobj = {'filename': filename}
|
||||
|
||||
self.assertEqual(server.get_source(fileobj),
|
||||
"file contents")
|
||||
|
||||
def test_should_clean_up_tempfile(self):
|
||||
fd, filename = tempfile.mkstemp(prefix="elpy-test-")
|
||||
with open(filename, "w") as f:
|
||||
f.write("file contents")
|
||||
|
||||
fileobj = {'filename': filename,
|
||||
'delete_after_use': True}
|
||||
|
||||
self.assertEqual(server.get_source(fileobj),
|
||||
"file contents")
|
||||
self.assertFalse(os.path.exists(filename))
|
||||
|
||||
def test_should_support_utf8(self):
|
||||
fd, filename = tempfile.mkstemp(prefix="elpy-test-")
|
||||
self.addCleanup(os.remove, filename)
|
||||
with open(filename, "wb") as f:
|
||||
f.write(u"möp".encode("utf-8"))
|
||||
|
||||
source = server.get_source({'filename': filename})
|
||||
|
||||
self.assertEqual(source, u"möp")
|
||||
|
||||
|
||||
class TestPysymbolKey(BackendTestCase):
|
||||
def keyLess(self, a, b):
|
||||
self.assertLess(b, a)
|
||||
self.assertLess(server._pysymbol_key(a),
|
||||
server._pysymbol_key(b))
|
||||
|
||||
def test_should_be_case_insensitive(self):
|
||||
self.keyLess("bar", "Foo")
|
||||
|
||||
def test_should_sort_private_symbols_after_public_symbols(self):
|
||||
self.keyLess("foo", "_bar")
|
||||
|
||||
def test_should_sort_private_symbols_after_dunder_symbols(self):
|
||||
self.assertLess(server._pysymbol_key("__foo__"),
|
||||
server._pysymbol_key("_bar"))
|
||||
|
||||
def test_should_sort_dunder_symbols_after_public_symbols(self):
|
||||
self.keyLess("bar", "__foo")
|
||||
|
||||
|
||||
class Autopep8TestCase(ServerTestCase):
|
||||
|
||||
def test_rpc_fix_code_should_return_formatted_string(self):
|
||||
code_block = 'x= 123\n'
|
||||
new_block = self.srv.rpc_fix_code(code_block, os.getcwd())
|
||||
self.assertEqual(new_block, 'x = 123\n')
|
||||
19
elpa-27.2/elpy-20220203.108/elpy/tests/test_support.py
Normal file
19
elpa-27.2/elpy-20220203.108/elpy/tests/test_support.py
Normal file
@@ -0,0 +1,19 @@
|
||||
"""Tests for elpy.tests.support. Yep, we test test code."""
|
||||
|
||||
import unittest
|
||||
|
||||
from elpy.tests.support import source_and_offset
|
||||
|
||||
|
||||
class TestSourceAndOffset(unittest.TestCase):
|
||||
def test_should_return_source_and_offset(self):
|
||||
self.assertEqual(source_and_offset("hello, _|_world"),
|
||||
("hello, world", 7))
|
||||
|
||||
def test_should_handle_beginning_of_string(self):
|
||||
self.assertEqual(source_and_offset("_|_hello, world"),
|
||||
("hello, world", 0))
|
||||
|
||||
def test_should_handle_end_of_string(self):
|
||||
self.assertEqual(source_and_offset("hello, world_|_"),
|
||||
("hello, world", 12))
|
||||
41
elpa-27.2/elpy-20220203.108/elpy/tests/test_yapf.py
Normal file
41
elpa-27.2/elpy-20220203.108/elpy/tests/test_yapf.py
Normal file
@@ -0,0 +1,41 @@
|
||||
# coding: utf-8
|
||||
"""Tests for the elpy.yapf module"""
|
||||
|
||||
import unittest
|
||||
import os
|
||||
|
||||
from elpy import yapfutil
|
||||
from elpy.rpc import Fault
|
||||
from elpy.tests.support import BackendTestCase
|
||||
|
||||
|
||||
@unittest.skipIf(yapfutil.YAPF_NOT_SUPPORTED,
|
||||
'yapf not supported for current python version')
|
||||
class YAPFTestCase(BackendTestCase):
|
||||
def setUp(self):
|
||||
if yapfutil.YAPF_NOT_SUPPORTED:
|
||||
raise unittest.SkipTest
|
||||
|
||||
def test_fix_code_should_throw_error_for_invalid_code(self):
|
||||
src = 'x = '
|
||||
self.assertRaises(Fault, yapfutil.fix_code, src, os.getcwd())
|
||||
|
||||
def test_fix_code_should_throw_error_without_yapf_installed(self):
|
||||
yapf = yapfutil.yapf_api
|
||||
yapfutil.yapf_api = None
|
||||
src = 'x= 123\n', 'x = 123\n'
|
||||
with self.assertRaises(Fault):
|
||||
yapfutil.fix_code(src, os.getcwd())
|
||||
yapfutil.yapf_api = yapf
|
||||
|
||||
def test_fix_code(self):
|
||||
testdata = [
|
||||
('x= 123\n', 'x = 123\n'),
|
||||
('x=1; \ny=2 \n', 'x = 1\ny = 2\n'),
|
||||
]
|
||||
for src, expected in testdata:
|
||||
self._assert_format(src, expected)
|
||||
|
||||
def _assert_format(self, src, expected):
|
||||
new_block = yapfutil.fix_code(src, os.getcwd())
|
||||
self.assertEqual(new_block, expected)
|
||||
38
elpa-27.2/elpy-20220203.108/elpy/yapfutil.py
Normal file
38
elpa-27.2/elpy-20220203.108/elpy/yapfutil.py
Normal file
@@ -0,0 +1,38 @@
|
||||
"""Glue for the "yapf" library.
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from elpy.rpc import Fault
|
||||
|
||||
YAPF_NOT_SUPPORTED = sys.version_info < (2, 7) or (
|
||||
sys.version_info >= (3, 0) and sys.version_info < (3, 4))
|
||||
|
||||
try:
|
||||
if YAPF_NOT_SUPPORTED:
|
||||
yapf_api = None
|
||||
else:
|
||||
from yapf.yapflib import yapf_api
|
||||
from yapf.yapflib import file_resources
|
||||
except ImportError: # pragma: no cover
|
||||
yapf_api = None
|
||||
|
||||
|
||||
def fix_code(code, directory):
|
||||
"""Formats Python code to conform to the PEP 8 style guide.
|
||||
|
||||
"""
|
||||
if not yapf_api:
|
||||
raise Fault('yapf not installed', code=400)
|
||||
style_config = file_resources.GetDefaultStyleForDir(directory or os.getcwd())
|
||||
try:
|
||||
reformatted_source, _ = yapf_api.FormatCode(code,
|
||||
filename='<stdin>',
|
||||
style_config=style_config,
|
||||
verify=False)
|
||||
return reformatted_source
|
||||
except Exception as e:
|
||||
raise Fault("Error during formatting: {}".format(e),
|
||||
code=400)
|
||||
@@ -0,0 +1,74 @@
|
||||
(defvar elpy-snippet-split-arg-arg-regex
|
||||
"\\([[:alnum:]*]+\\)\\(:[[:blank:]]*[[:alpha:]]*\\)?\\([[:blank:]]*=[[:blank:]]*[[:alnum:]]*\\)?"
|
||||
"Regular expression matching an argument of a python function.
|
||||
First group should give the argument name.")
|
||||
|
||||
(defvar elpy-snippet-split-arg-separator
|
||||
"[[:blank:]]*,[[:blank:]]*"
|
||||
"Regular expression matching the separator in a list of argument.")
|
||||
|
||||
(defun elpy-snippet-split-args (arg-string)
|
||||
"Split the python argument string ARG-STRING into a tuple of argument names."
|
||||
(mapcar (lambda (x)
|
||||
(when (string-match elpy-snippet-split-arg-arg-regex x)
|
||||
(match-string-no-properties 1 x)))
|
||||
(split-string arg-string elpy-snippet-split-arg-separator t)))
|
||||
|
||||
(defun elpy-snippet-current-method-and-args ()
|
||||
"Return information on the current definition."
|
||||
(let ((current-defun (python-info-current-defun))
|
||||
(current-arglist
|
||||
(save-excursion
|
||||
(python-nav-beginning-of-defun)
|
||||
(when (re-search-forward "(" nil t)
|
||||
(let* ((start (point))
|
||||
(end (progn
|
||||
(forward-char -1)
|
||||
(forward-sexp)
|
||||
(- (point) 1))))
|
||||
(elpy-snippet-split-args
|
||||
(buffer-substring-no-properties start end))))))
|
||||
class method args)
|
||||
(unless current-arglist
|
||||
(setq current-arglist '("self")))
|
||||
(if (and current-defun
|
||||
(string-match "^\\(.*\\)\\.\\(.*\\)$" current-defun))
|
||||
(setq class (match-string 1 current-defun)
|
||||
method (match-string 2 current-defun))
|
||||
(setq class "Class"
|
||||
method "method"))
|
||||
(list class method current-arglist)))
|
||||
|
||||
(defun elpy-snippet-init-assignments (arg-string)
|
||||
"Return the typical __init__ assignments for arguments in ARG-STRING."
|
||||
(let ((indentation (make-string (save-excursion
|
||||
(goto-char start-point)
|
||||
(current-indentation))
|
||||
?\s)))
|
||||
(mapconcat (lambda (arg)
|
||||
(if (string-match "^\\*" arg)
|
||||
""
|
||||
(format "self.%s = %s\n%s" arg arg indentation)))
|
||||
(elpy-snippet-split-args arg-string)
|
||||
"")))
|
||||
|
||||
(defun elpy-snippet-super-form ()
|
||||
"Return (Class, first-arg).method if Py2.
|
||||
Else return ().method for Py3."
|
||||
(let* ((defun-info (elpy-snippet-current-method-and-args))
|
||||
(class (nth 0 defun-info))
|
||||
(method (nth 1 defun-info))
|
||||
(args (nth 2 defun-info))
|
||||
(first-arg (nth 0 args))
|
||||
(py-version-command " -c 'import sys ; print(sys.version_info.major)'")
|
||||
;; Get the python version. Either 2 or 3
|
||||
(py-version-num (substring (shell-command-to-string (concat elpy-rpc-python-command py-version-command))0 1)))
|
||||
(if (string-match py-version-num "2")
|
||||
(format "(%s, %s).%s" class first-arg method)
|
||||
(format "().%s" method))))
|
||||
|
||||
(defun elpy-snippet-super-arguments ()
|
||||
"Return the argument list for the current method."
|
||||
(mapconcat (lambda (x) x)
|
||||
(cdr (nth 2 (elpy-snippet-current-method-and-args)))
|
||||
", "))
|
||||
BIN
elpa-27.2/elpy-20220203.108/snippets/python-mode/.yas-setup.elc
Normal file
BIN
elpa-27.2/elpy-20220203.108/snippets/python-mode/.yas-setup.elc
Normal file
Binary file not shown.
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_abs
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_abs
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _abs
|
||||
# key: _abs
|
||||
# group: Special methods
|
||||
# --
|
||||
def __abs__(self):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_add
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_add
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _add
|
||||
# key: _add
|
||||
# group: Special methods
|
||||
# --
|
||||
def __add__(self, other):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_and
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_and
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _and
|
||||
# key: _and
|
||||
# group: Special methods
|
||||
# --
|
||||
def __and__(self, other):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_bool
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_bool
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _bool
|
||||
# key: _bool
|
||||
# group: Special methods
|
||||
# --
|
||||
def __bool__(self):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_call
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_call
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _call
|
||||
# key: _call
|
||||
# group: Special methods
|
||||
# --
|
||||
def __call__(self, ${1:*args}):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_cmp
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_cmp
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _cmp
|
||||
# key: _cmp
|
||||
# group: Special methods
|
||||
# --
|
||||
def __cmp__(self, other):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_coerce
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_coerce
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _coerce
|
||||
# key: _coerce
|
||||
# group: Special methods
|
||||
# --
|
||||
def __coerce__(self, other):
|
||||
return $0
|
||||
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _complex
|
||||
# key: _complex
|
||||
# group: Special methods
|
||||
# --
|
||||
def __complex__(self):
|
||||
return $0
|
||||
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _contains
|
||||
# key: _contains
|
||||
# group: Special methods
|
||||
# --
|
||||
def __contains__(self, item):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_del
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_del
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _del
|
||||
# key: _del
|
||||
# group: Special methods
|
||||
# --
|
||||
def __del__(self):
|
||||
$0
|
||||
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _delattr
|
||||
# key: _delattr
|
||||
# group: Special methods
|
||||
# --
|
||||
def __delattr__(self, name):
|
||||
$0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_delete
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_delete
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _delete
|
||||
# key: _delete
|
||||
# group: Special methods
|
||||
# --
|
||||
def __delete__(self, instance):
|
||||
$0
|
||||
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _delitem
|
||||
# key: _delitem
|
||||
# group: Special methods
|
||||
# --
|
||||
def __delitem__(self, key):
|
||||
$0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_div
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_div
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _div
|
||||
# key: _div
|
||||
# group: Special methods
|
||||
# --
|
||||
def __div__(self, other):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_divmod
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_divmod
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _divmod
|
||||
# key: _divmod
|
||||
# group: Special methods
|
||||
# --
|
||||
def __divmod__(self, other):
|
||||
return $0
|
||||
9
elpa-27.2/elpy-20220203.108/snippets/python-mode/_enter
Normal file
9
elpa-27.2/elpy-20220203.108/snippets/python-mode/_enter
Normal file
@@ -0,0 +1,9 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _enter
|
||||
# key: _enter
|
||||
# group: Special methods
|
||||
# --
|
||||
def __enter__(self):
|
||||
$0
|
||||
|
||||
return self
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_eq
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_eq
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _eq
|
||||
# key: _eq
|
||||
# group: Special methods
|
||||
# --
|
||||
def __eq__(self, other):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_exit
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_exit
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _exit
|
||||
# key: _exit
|
||||
# group: Special methods
|
||||
# --
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
$0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_float
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_float
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _float
|
||||
# key: _float
|
||||
# group: Special methods
|
||||
# --
|
||||
def __float__(self):
|
||||
return $0
|
||||
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _floordiv
|
||||
# key: _floordiv
|
||||
# group: Special methods
|
||||
# --
|
||||
def __floordiv__(self, other):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_ge
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_ge
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _ge
|
||||
# key: _ge
|
||||
# group: Special methods
|
||||
# --
|
||||
def __ge__(self, other):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_get
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_get
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _get
|
||||
# key: _get
|
||||
# group: Special methods
|
||||
# --
|
||||
def __get__(self, instance, owner):
|
||||
return $0
|
||||
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _getattr
|
||||
# key: _getattr
|
||||
# group: Special methods
|
||||
# --
|
||||
def __getattr__(self, name):
|
||||
return $0
|
||||
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _getattribute
|
||||
# key: _getattribute
|
||||
# group: Special methods
|
||||
# --
|
||||
def __getattribute__(self, name):
|
||||
return $0
|
||||
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _getitem
|
||||
# key: _getitem
|
||||
# group: Special methods
|
||||
# --
|
||||
def __getitem__(self, key):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_gt
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_gt
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _gt
|
||||
# key: _gt
|
||||
# group: Special methods
|
||||
# --
|
||||
def __gt__(self, other):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_hash
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_hash
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _hash
|
||||
# key: _hash
|
||||
# group: Special methods
|
||||
# --
|
||||
def __hash__(self):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_hex
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_hex
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _hex
|
||||
# key: _hex
|
||||
# group: Special methods
|
||||
# --
|
||||
def __hex__(self):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_iadd
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_iadd
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _iadd
|
||||
# key: _iadd
|
||||
# group: Special methods
|
||||
# --
|
||||
def __iadd__(self, other):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_iand
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_iand
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _iand
|
||||
# key: _iand
|
||||
# group: Special methods
|
||||
# --
|
||||
def __iand__(self, other):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_idiv
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_idiv
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _idiv
|
||||
# key: _idiv
|
||||
# group: Special methods
|
||||
# --
|
||||
def __idiv__(self, other):
|
||||
return $0
|
||||
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _ifloordiv
|
||||
# key: _ifloordiv
|
||||
# group: Special methods
|
||||
# --
|
||||
def __ifloordiv__(self, other):
|
||||
return $0
|
||||
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _ilshift
|
||||
# key: _ilshift
|
||||
# group: Special methods
|
||||
# --
|
||||
def __ilshift__(self, other):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_imod
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_imod
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _imod
|
||||
# key: _imod
|
||||
# group: Special methods
|
||||
# --
|
||||
def __imod__(self, other):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_imul
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_imul
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _imul
|
||||
# key: _imul
|
||||
# group: Special methods
|
||||
# --
|
||||
def __imul__(self, other):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_index
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_index
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _index
|
||||
# key: _index
|
||||
# group: Special methods
|
||||
# --
|
||||
def __index__(self):
|
||||
return $0
|
||||
10
elpa-27.2/elpy-20220203.108/snippets/python-mode/_init
Normal file
10
elpa-27.2/elpy-20220203.108/snippets/python-mode/_init
Normal file
@@ -0,0 +1,10 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _init with assignment
|
||||
# key: _init
|
||||
# group: Special methods
|
||||
# --
|
||||
def __init__(self${1:, args}):
|
||||
"""$2
|
||||
|
||||
"""
|
||||
${1:$(elpy-snippet-init-assignments yas-text)}
|
||||
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _instancecheck
|
||||
# key: _instancecheck
|
||||
# group: Special methods
|
||||
# --
|
||||
def __instancecheck__(self, instance):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_int
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_int
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _int
|
||||
# key: _int
|
||||
# group: Special methods
|
||||
# --
|
||||
def __int__(self):
|
||||
$0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_invert
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_invert
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _invert
|
||||
# key: _invert
|
||||
# group: Special methods
|
||||
# --
|
||||
def __invert__(self):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_ior
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_ior
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _ior
|
||||
# key: _ior
|
||||
# group: Special methods
|
||||
# --
|
||||
def __ior__(self, other):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_ipow
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_ipow
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _ipow
|
||||
# key: _ipow
|
||||
# group: Special methods
|
||||
# --
|
||||
def __ipow__(self, other):
|
||||
return $0
|
||||
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _irshift
|
||||
# key: _irshift
|
||||
# group: Special methods
|
||||
# --
|
||||
def __irshift__(self, other):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_isub
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_isub
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _isub
|
||||
# key: _isub
|
||||
# group: Special methods
|
||||
# --
|
||||
def __isub__(self, other):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_iter
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_iter
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _iter
|
||||
# key: _iter
|
||||
# group: Special methods
|
||||
# --
|
||||
def __iter__(self):
|
||||
$0
|
||||
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _itruediv
|
||||
# key: _itruediv
|
||||
# group: Special methods
|
||||
# --
|
||||
def __itruediv__(self, other):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_ixor
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_ixor
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _ixor
|
||||
# key: _ixor
|
||||
# group: Special methods
|
||||
# --
|
||||
def __ixor__(self, other):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_le
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_le
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _le
|
||||
# key: _le
|
||||
# group: Special methods
|
||||
# --
|
||||
def __le__(self, other):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_len
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_len
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _len
|
||||
# key: _len
|
||||
# group: Special methods
|
||||
# --
|
||||
def __len__(self):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_long
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_long
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _long
|
||||
# key: _long
|
||||
# group: Special methods
|
||||
# --
|
||||
def __long__(self):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_lshift
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_lshift
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _lshift
|
||||
# key: _lshift
|
||||
# group: Special methods
|
||||
# --
|
||||
def __lshift__(self, other):
|
||||
return $0
|
||||
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_lt
Normal file
7
elpa-27.2/elpy-20220203.108/snippets/python-mode/_lt
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: _lt
|
||||
# key: _lt
|
||||
# group: Special methods
|
||||
# --
|
||||
def __lt__(self, other):
|
||||
return $0
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user