Cleanup text and code in the Python package installation section

This commit is contained in:
Gerard Vermeulen 2023-03-05 10:53:38 +01:00
parent ae396be077
commit 9560eadb5d

View File

@ -4977,6 +4977,11 @@ ruff "$@" | cat
:header-args: :eval never-export :header-args: :eval never-export
:END: :END:
Listing [[lst:shell-pip-list-outdated]] and [[lst:shell-pip-index-versions]] are two
examples of invoking [[https://pip.pypa.io/en/stable/][pip]] in =org-mode= =shell= source blocks with the respective
results in listing [[lst:shell-pip-list-outdated-results]] and
[[lst:shell-pip-index-versions-results]].
#+caption[Show how to use =pip list --outdated=]: #+caption[Show how to use =pip list --outdated=]:
#+caption: Show how to use =pip list --outdated=. #+caption: Show how to use =pip list --outdated=.
#+header: :wrap src text #+header: :wrap src text
@ -4988,6 +4993,7 @@ pip list --outdated
#+caption[The result of =pip list --outdated=]: #+caption[The result of =pip list --outdated=]:
#+caption: The result of =pip list --outdated=. #+caption: The result of =pip list --outdated=.
#+name: lst:shell-pip-list-outdated-results
#+RESULTS: lst:shell-pip-list-outdated #+RESULTS: lst:shell-pip-list-outdated
#+begin_src text #+begin_src text
Package Version Latest Type Package Version Latest Type
@ -5010,6 +5016,7 @@ pip index versions circular-buffer --no-color
#+caption[The result of =pip index versions=]: #+caption[The result of =pip index versions=]:
#+caption: The result of =pip index versions=. #+caption: The result of =pip index versions=.
#+name: lst:shell-pip-index-versions-results
#+RESULTS: lst:shell-pip-index-versions #+RESULTS: lst:shell-pip-index-versions
#+begin_src text #+begin_src text
circular-buffer (0.2.0) circular-buffer (0.2.0)
@ -5057,13 +5064,21 @@ This invokes an asynchonous process and finishes with a message."
#+caption: Emacs interface to upgrade outdated unfrozen Python packages. #+caption: Emacs interface to upgrade outdated unfrozen Python packages.
#+name: lst:pip-upgrade-maybe #+name: lst:pip-upgrade-maybe
#+begin_src emacs-lisp -n :results silent #+begin_src emacs-lisp -n :results silent
(defcustom pip-frozen-packages '("aiofiles" (defgroup pip nil
"Client for accessing the \"Package Installer for Python\" and \"PyPI\"."
:group 'applications)
(defcustom pip-frozen-packages nil
"Frozen Python packages."
:group 'pip
:type '(repeat string))
;; Frozen until the release of jupyterlab-4.0.0.
(setopt pip-frozen-packages '("aiofiles"
"jupyter-server-ydoc" "jupyter-server-ydoc"
"jupyter-ydoc" "jupyter-ydoc"
"y-py" "y-py"
"ypy-websocket") "ypy-websocket"))
"Frozen Python packages (until jupyterlab-4.0.0)"
:type '(repeat string))
(defun pip--upgrade-maybe-sentinel (process event) (defun pip--upgrade-maybe-sentinel (process event)
(when (and (eq (process-status process) 'exit) (when (and (eq (process-status process) 'exit)
@ -5096,16 +5111,72 @@ buffer to check whether upgrading has made the dependencies incompatible."
#+caption[Emacs interface to the =PyPI= simple =JSON= =API=]: #+caption[Emacs interface to the =PyPI= simple =JSON= =API=]:
#+caption: Emacs interface to the =PyPI= simple =JSON= =API=. #+caption: Emacs interface to the =PyPI= simple =JSON= =API=.
#+name: lst:pip-pypi-simple-json-apip #+name: lst:pip-pypi-simple-json-api
#+begin_src emacs-lisp -n :results silent #+begin_src emacs-lisp -n :lexical t :results silent
(defun pip-simple-json-project-details (name) ;; https://emacs.stackexchange.com/questions/61754/
;; "How can I enable lexical binding for elisp code in Org mode?"
(defvar pip--simple-details-cache (make-hash-table :test 'equal)
"Cache for PyPI project details")
(defun pip-simple-get-json ()
(save-excursion
(goto-char (point-min))
(and (re-search-forward "^HTTP/.+ 200 OK$" nil (line-end-position))
(search-forward "\n\n" nil t)
(json-parse-buffer :array-type 'list))))
(defun pip-simple-details-retrieve (name callback &optional cbargs)
(pip--simple-details-prune-cache)
(if-let ((cached (gethash name pip--simple-details-cache)))
(apply callback (cdr cached) cbargs)
(let ((url (format "https://pypi.org/simple/%s" name)) (let ((url (format "https://pypi.org/simple/%s" name))
(url-request-method "GET") (url-request-method "GET")
(url-mime-accept-string "application/vnd.pypi.simple.latest+json")) (url-mime-accept-string "application/vnd.pypi.simple.latest+json"))
(url-retrieve url (url-retrieve
(lambda (status) (switch-to-buffer (current-buffer)))))) url
(lambda (status)
(let ((details (and (not (plist-get status :error))
(pip-simple-get-json))))
(when details
(setf (gethash name pip--simple-details-cache)
(cons (time-convert nil 'integer) details)))
(prog1
(apply callback (or details 'error) cbargs)
(kill-buffer))))
nil t))))
(defun pip-simple-json-project-list () (defun pip--simple-details-prune-cache ()
(let ((expired nil)
(time (- (time-convert nil 'integer)
;; Ten minutes
(* 10 60))))
(maphash (lambda (key val)
(when (< (car val) time)
(push key expired)))
pip--simple-details-cache)
(dolist (key expired)
(remhash key pip--simple-details-cache))))
#+end_src
#+caption[Using the Emacs interface to the =PyPI= simple =JSON= =API=]:
#+caption: Using the Emacs interface to the =PyPI= simple =JSON= =API=.
#+name: lst:using-pip-pypi-simple-json-api
#+begin_src emacs-lisp -n :lexical t :results silent
;; https://emacs.stackexchange.com/questions/61754/
;; "How can I enable lexical binding for elisp code in Org mode?"
(defun pip-simple-project-versions (name)
"Return the versions of Python package NAME."
(interactive "sPython package name: ")
(pip-simple-details-retrieve
name
(lambda (details)
(when-let ((versions (reverse (cdr (gethash "versions" details)))))
(message "`%s' versions: %S" name versions)))))
(defun pip-simple-project-list ()
"Get the Python package project list (PEP-691 and PEP-700)."
(interactive) (interactive)
(let ((url-request-method "GET") (let ((url-request-method "GET")
(url-mime-accept-string "application/vnd.pypi.simple.latest+json")) (url-mime-accept-string "application/vnd.pypi.simple.latest+json"))