[PATCHES] Jupyter Notebook: Enable tests.

  • Done
  • quality assurance status badge
Details
One participant
  • Lars-Dominik Braun
Owner
unassigned
Submitted by
Lars-Dominik Braun
Severity
normal
L
L
Lars-Dominik Braun wrote on 20 Apr 2021 11:49
(address . guix-patches@gnu.org)
YH6jjE1PqhJGM6E3@noor.fritz.box
Hi,

this patch series is mostly a QA patchset and enables tests on most of
Jupyter Notebook’s components. There are also two possibly controversial
changes:

- It moves the definition of JUPYTER_PATH to jupyter-core. I’d argue
this is the more correct approach, because that package actually deals
with this search path and installing any Jupyter package makes it work
out of the box without installing the strange jupyter meta-package.
- It enables pandoc/LaTeX for nbconvert. The Notebook lists PDF output
in its “Export as” menu and I feel both are useful, even though they
increase the closure.

You can also pull the patchset here:

Cheers,
Lars

Lars-Dominik Braun (12):
gnu: Move search path JUPYTER_PATH.
gnu: python-jupyter-core: Enable tests.
gnu: Add python-json-spec.
gnu: Add python-fastjsonschema.
gnu: python-nbformat: Enable tests.
gnu: Add python-jupyter-client-bootstrap.
gnu: Add python-ipykernel-bootstrap.
gnu: python-jupyter-client: Enable tests.
gnu: python-ipykernel: Add missing inputs.
gnu: Add python-pytest-dependency.
gnu: python-nbconvert: Enable more tests.
gnu: python-notebook: Fix tests.

gnu/packages/check.scm | 23 +++
gnu/packages/python-xyz.scm | 281 ++++++++++++++++++++++++++++++------
2 files changed, 256 insertions(+), 48 deletions(-)

--
2.26.3
From 59ad11057adaf3b17a1b6f00ec7d71875fa92203 Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <lars@6xq.net>
Date: Tue, 20 Apr 2021 08:57:14 +0200
Subject: [PATCH 02/12] gnu: python-jupyter-core: Enable tests.

* gnu/packages/python-xyz.scm (python-jupyter-core) [arguments]: Enable
tests.
[native-inputs]: Add test dependencies.
---
gnu/packages/python-xyz.scm | 27 +++++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)

Toggle diff (42 lines)
diff --git a/gnu/packages/python-xyz.scm b/gnu/packages/python-xyz.scm
index b9586b4154..29f2e4ed7b 100644
--- a/gnu/packages/python-xyz.scm
+++ b/gnu/packages/python-xyz.scm
@@ -7383,10 +7383,33 @@ without using the configuration machinery.")
(base32
"1d12j5hkff0xiax87pnhmzbsph3jqqzhz16h8xld7z2y4armq0kr"))))
(build-system python-build-system)
- ;; FIXME: not sure how to run the tests
- (arguments `(#:tests? #f))
+ (arguments
+ `(#:phases
+ (modify-phases %standard-phases
+ (replace 'check
+ (lambda* (#:key inputs outputs tests? #:allow-other-keys)
+ (if tests?
+ (begin
+ ; Some tests write to $HOME.
+ (setenv "HOME" "/tmp")
+ ; Some tests load the installed package.
+ (add-installed-pythonpath inputs outputs)
+ (invoke "pytest" "-vv")))))
+ (add-after 'unpack 'patch-testsuite
+ (lambda _
+ ;; test_not_on_path() and test_path_priority() try to run a test
+ ;; that loads jupyter_core, so we need PYTHONPATH
+ (substitute* "jupyter_core/tests/test_command.py"
+ (("env = \\{'PATH': ''\\}")
+ "env = {'PATH': '', 'PYTHONPATH': os.environ['PYTHONPATH']}")
+ (("env = \\{'PATH': str\\(b\\)\\}")
+ "env = {'PATH': str(b), 'PYTHONPATH': os.environ['PYTHONPATH']}"))
+ #t)))))
(propagated-inputs
`(("python-traitlets" ,python-traitlets)))
+ (native-inputs
+ `(("python-six" ,python-six)
+ ("python-pytest" ,python-pytest)))
;; This package provides the `jupyter` binary and thus also exports the
;; search paths.
(native-search-paths
--
2.26.3
From eea14eb98921bbeb19c9fbed86cf6111ba27d24d Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <lars@6xq.net>
Date: Tue, 20 Apr 2021 11:15:30 +0200
Subject: [PATCH 12/12] gnu: python-notebook: Fix tests.

They failed because JUPYTER_PATH was set in commit
6c26561be57b0195b14a1ff37e65c82d3bc70b2d.

* gnu/packages/python-xyz.scm (python-notebook) [#:phases]: Unset
JUPYTER_PATH in 'check.
---
gnu/packages/python-xyz.scm | 3 +++
1 file changed, 3 insertions(+)

Toggle diff (16 lines)
diff --git a/gnu/packages/python-xyz.scm b/gnu/packages/python-xyz.scm
index 4202e2de17..f4aee61c00 100644
--- a/gnu/packages/python-xyz.scm
+++ b/gnu/packages/python-xyz.scm
@@ -10810,6 +10810,9 @@ convert an @code{.ipynb} notebook file into various static formats including:
(delete-file-recursively "notebook/tests/selenium")
(when tests?
(add-installed-pythonpath inputs outputs)
+ ;; Some tests do not expect all files to be installed in the
+ ;; same directory, but JUPYTER_PATH contains multiple entries.
+ (unsetenv "JUPYTER_PATH")
;; Some tests need HOME
(setenv "HOME" "/tmp")
(with-directory-excursion "/tmp"
--
2.26.3
From 8f5e4f2d3ebd8ab16da33e82fcc255957a0929a3 Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <lars@6xq.net>
Date: Tue, 20 Apr 2021 09:15:04 +0200
Subject: [PATCH 04/12] gnu: Add python-fastjsonschema.

* gnu/packages/python-xyz.scm (python-fastjsonschema): New variable.
---
gnu/packages/python-xyz.scm | 40 +++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)

Toggle diff (53 lines)
diff --git a/gnu/packages/python-xyz.scm b/gnu/packages/python-xyz.scm
index 98f8537041..cdf13624f1 100644
--- a/gnu/packages/python-xyz.scm
+++ b/gnu/packages/python-xyz.scm
@@ -10372,6 +10372,46 @@ Debian-related files, such as:
JSON Reference and JSON Pointer.")
(license license:bsd-3)))
+(define-public python-fastjsonschema
+ (package
+ (name "python-fastjsonschema")
+ (version "2.15.0")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (pypi-uri "fastjsonschema" version))
+ (sha256
+ (base32
+ "0xknp399gpdjf08lrq2yvv66s7nsc51fgbm6vph7vyyg1ckbmv71"))))
+ (build-system python-build-system)
+ (arguments
+ `(#:tests? #f ; Fail with a strange backtrace ending in importlib.
+ #:phases
+ (modify-phases %standard-phases
+ (replace 'check
+ (lambda* (#:key inputs outputs tests? #:allow-other-keys)
+ (if tests?
+ (begin
+ (invoke "pytest" "-vv" "-m" "not benchmark"))))))))
+ (native-inputs
+ `(("python-colorama" ,python-colorama)
+ ("python-json-spec" ,python-json-spec)
+ ("python-jsonschema" ,python-jsonschema)
+ ("python-pylint" ,python-pylint)
+ ("python-pytest" ,python-pytest-6)
+ ("python-pytest-benchmark"
+ ,python-pytest-benchmark)
+ ("python-pytest-cache" ,python-pytest-cache)
+ ("python-validictory" ,python-validictory)))
+ (home-page
+ "https://github.com/horejsek/python-fastjsonschema")
+ (synopsis
+ "Fast Python implementation of JSON schema")
+ (description
+ "This library implements validation of JSON documents by JSON schema for
+drafts 04, 06 and 07.")
+ (license license:bsd-3)))
+
(define-public python-nbformat
(package
(name "python-nbformat")
--
2.26.3
From 6c26561be57b0195b14a1ff37e65c82d3bc70b2d Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <lars@6xq.net>
Date: Tue, 20 Apr 2021 08:54:00 +0200
Subject: [PATCH 01/12] gnu: Move search path JUPYTER_PATH.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

python-jupyter-core provides the `jupyter` binary as well as generic
functions to discover the search path for all Jupyter subprojects. Thus
it should provide the search paths too.

* gnu/packages/python-xyz.scm (jupyter): From here…
(python-jupyter-core): …to here.
[native-search-paths]: Add JUPYTER_CONFIG_DIR, because some Jupyter
projects install config files to their etc/ directory and expect them to
be loaded automatically.
---
gnu/packages/python-xyz.scm | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)

Toggle diff (33 lines)
diff --git a/gnu/packages/python-xyz.scm b/gnu/packages/python-xyz.scm
index 5cf0b61c68..b9586b4154 100644
--- a/gnu/packages/python-xyz.scm
+++ b/gnu/packages/python-xyz.scm
@@ -7387,6 +7387,15 @@ without using the configuration machinery.")
(arguments `(#:tests? #f))
(propagated-inputs
`(("python-traitlets" ,python-traitlets)))
+ ;; This package provides the `jupyter` binary and thus also exports the
+ ;; search paths.
+ (native-search-paths
+ (list (search-path-specification
+ (variable "JUPYTER_CONFIG_DIR")
+ (files '("etc/jupyter")))
+ (search-path-specification
+ (variable "JUPYTER_PATH")
+ (files '("share/jupyter")))))
(home-page "https://jupyter.org/")
(synopsis "Jupyter base package")
(description
@@ -10878,10 +10887,6 @@ popular online obfuscators.")
("python-nbconvert" ,python-nbconvert)
("python-notebook" ,python-notebook)
("python-qtconsole" ,python-qtconsole)))
- (native-search-paths
- (list (search-path-specification
- (variable "JUPYTER_PATH")
- (files '("share/jupyter")))))
(home-page "https://jupyter.org")
(synopsis "Web application for interactive documents")
(description
--
2.26.3
From 8ebfe9283fd171320381cc2e8c37e431f16478d3 Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <lars@6xq.net>
Date: Tue, 20 Apr 2021 09:49:32 +0200
Subject: [PATCH 06/12] gnu: Add python-jupyter-client-bootstrap.

* gnu/packages/python-xyz.scm (python-jupyter-client-bootstrap): New
variable.
---
gnu/packages/python-xyz.scm | 14 ++++++++++++++
1 file changed, 14 insertions(+)

Toggle diff (27 lines)
diff --git a/gnu/packages/python-xyz.scm b/gnu/packages/python-xyz.scm
index 18e4c565ab..4c00d3d602 100644
--- a/gnu/packages/python-xyz.scm
+++ b/gnu/packages/python-xyz.scm
@@ -7469,6 +7469,20 @@ for working with kernels, and the @code{jupyter kernelspec} entrypoint for
installing @code{kernelspec}s for use with Jupyter frontends.")
(license license:bsd-3)))
+;; Bootstrap variant of jupyter-client, which breaks the loop between ipykernel
+;; and jupyter-client by removing the former from its native-inputs and
+;; disabling tests.
+(define-public python-jupyter-client-bootstrap
+ (let ((base python-jupyter-client))
+ (hidden-package
+ (package
+ (inherit base)
+ (name "python-jupyter-client-bootstrap")
+ (arguments
+ `(#:tests? #f
+ ,@(package-arguments base)))
+ (native-inputs `())))))
+
(define-public python2-jupyter-client
(package-with-python2 python-jupyter-client))
--
2.26.3
From 08131b7be297a5b2111023114f987741733373c2 Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <lars@6xq.net>
Date: Tue, 20 Apr 2021 09:53:31 +0200
Subject: [PATCH 09/12] gnu: python-ipykernel: Add missing inputs.

* gnu/packages/python-xyz.scm (python-ipykernel) [propagated-inputs]:
Add tornado and traitlets.
---
gnu/packages/python-xyz.scm | 2 ++
1 file changed, 2 insertions(+)

Toggle diff (15 lines)
diff --git a/gnu/packages/python-xyz.scm b/gnu/packages/python-xyz.scm
index 62c61e1c21..a49a395900 100644
--- a/gnu/packages/python-xyz.scm
+++ b/gnu/packages/python-xyz.scm
@@ -7528,6 +7528,8 @@ installing @code{kernelspec}s for use with Jupyter frontends.")
#t))))))
(propagated-inputs
`(("python-ipython" ,python-ipython)
+ ("python-tornado" ,python-tornado-6)
+ ("python-traitlets" ,python-traitlets)
;; imported at runtime during connect
("python-jupyter-client" ,python-jupyter-client)))
(native-inputs
--
2.26.3
From 7aadcfac8b18314b021c48c9c6aa031c027f67bd Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <lars@6xq.net>
Date: Tue, 20 Apr 2021 11:03:13 +0200
Subject: [PATCH 10/12] gnu: Add python-pytest-dependency.

* gnu/packages/check.scm (python-pytest-dependency): New variable.
---
gnu/packages/check.scm | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)

Toggle diff (33 lines)
diff --git a/gnu/packages/check.scm b/gnu/packages/check.scm
index 2ad4de55f8..6641a0de58 100644
--- a/gnu/packages/check.scm
+++ b/gnu/packages/check.scm
@@ -2915,3 +2915,26 @@ system. The code under test requires no modification to work with pyfakefs.")
(description "Aiounittest is a library that helps write tests using
asynchronous code in Python (asyncio).")
(license license:expat)))
+
+(define-public python-pytest-dependency
+ (package
+ (name "python-pytest-dependency")
+ (version "0.5.1")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (pypi-uri "pytest-dependency" version))
+ (sha256
+ (base32
+ "0swl3mxca7nnjbb5grfzrm3fa2750h9vjsha0f2kyrljc6895a62"))))
+ (build-system python-build-system)
+ (propagated-inputs
+ `(("python-pytest" ,python-pytest)))
+ (home-page
+ "https://github.com/RKrahl/pytest-dependency")
+ (synopsis "Manage dependencies of tests")
+ (description "This pytest plugin manages dependencies of tests. It allows
+to mark some tests as dependent from other tests. These tests will then be
+skipped if any of the dependencies did fail or has been skipped.")
+ (license license:asl2.0)))
+
--
2.26.3
From b9de8b935048b631269032bd7f104dcb999caa85 Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <lars@6xq.net>
Date: Tue, 20 Apr 2021 09:15:42 +0200
Subject: [PATCH 05/12] gnu: python-nbformat: Enable tests.

* gnu/packages/python-xyz.scm (python-nbformat) [source]: Use git
repository, which has more complete test data.
[arguments]: Run pytest during 'check.
[native-inputs]: Add dependencies required to do that.
---
gnu/packages/python-xyz.scm | 31 +++++++++++++++++++++++--------
1 file changed, 23 insertions(+), 8 deletions(-)

Toggle diff (51 lines)
diff --git a/gnu/packages/python-xyz.scm b/gnu/packages/python-xyz.scm
index cdf13624f1..18e4c565ab 100644
--- a/gnu/packages/python-xyz.scm
+++ b/gnu/packages/python-xyz.scm
@@ -10416,21 +10416,36 @@ drafts 04, 06 and 07.")
(package
(name "python-nbformat")
(version "5.1.3")
- (source
- (origin
- (method url-fetch)
- (uri (pypi-uri "nbformat" version))
- (sha256
- (base32
- "1j6idwsw59cslsssvlkg2bkfpvd6ri7kghbp14jwcw87sy57h5mm"))))
+ ;; The PyPi release tarball lacks some test cases and test data.
+ (source (origin
+ (method git-fetch)
+ (uri (git-reference
+ (url "https://github.com/jupyter/nbformat.git")
+ (commit version)))
+ (sha256
+ (base32
+ "033v16cfmxzh3jn5phnil4p3silr49iwh9wiigzhv0crc6sanvwz"))
+ (file-name (git-file-name name version))))
(build-system python-build-system)
+ (arguments
+ `(#:phases
+ (modify-phases %standard-phases
+ (replace 'check
+ (lambda* (#:key inputs outputs tests? #:allow-other-keys)
+ (if tests?
+ (begin
+ (invoke "pytest" "-vv"))))))))
(propagated-inputs
`(("python-ipython-genutils" ,python-ipython-genutils)
("python-jsonschema" ,python-jsonschema)
("python-jupyter-core" ,python-jupyter-core)
("python-traitlets" ,python-traitlets)))
(native-inputs
- `(("python-pytest" ,python-pytest)))
+ `(("python-pytest" ,python-pytest)
+ ("python-fastjsonschema" ,python-fastjsonschema) ; This is only active
+ ; when setting NBFORMAT_VALIDATOR="fastjsonschema", so include it for
+ ; testing only.
+ ("python-testpath" ,python-testpath)))
(home-page "https://jupyter.org")
(synopsis "Jupyter Notebook format")
(description "This package provides the reference implementation of the
--
2.26.3
From fa8538dd93b8ebdb14cc46d1e1bc07a385f9332e Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <lars@6xq.net>
Date: Tue, 20 Apr 2021 09:14:00 +0200
Subject: [PATCH 03/12] gnu: Add python-json-spec.

* gnu/packages/python-xyz.scm (python-json-spec): New variable.
---
gnu/packages/python-xyz.scm | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)

Toggle diff (38 lines)
diff --git a/gnu/packages/python-xyz.scm b/gnu/packages/python-xyz.scm
index 29f2e4ed7b..98f8537041 100644
--- a/gnu/packages/python-xyz.scm
+++ b/gnu/packages/python-xyz.scm
@@ -10347,6 +10347,31 @@ Debian-related files, such as:
;; Modules are either GPLv2+ or GPLv3+.
(license license:gpl3+)))
+(define-public python-json-spec
+ (package
+ (name "python-json-spec")
+ (version "0.10.1")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (pypi-uri "json-spec" version))
+ (sha256
+ (base32
+ "06dpbsq61ja9r89wpa2pzdii47qh3xri9ajdrgn1awfl102znchb"))))
+ (build-system python-build-system)
+ (propagated-inputs
+ `(("python-pathlib" ,python-pathlib)
+ ("python-six" ,python-six)))
+ (native-inputs
+ `(("python-pytest" ,python-pytest)))
+ (home-page "http://py.errorist.io/json-spec")
+ (synopsis
+ "JSON Schema, JSON Pointer and JSON Reference for Python")
+ (description
+ "This Python library implements several JSON specs, like JSON Schema,
+JSON Reference and JSON Pointer.")
+ (license license:bsd-3)))
+
(define-public python-nbformat
(package
(name "python-nbformat")
--
2.26.3
From aab2dbd5adf8ca75addeb3e692a16f8532171694 Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <lars@6xq.net>
Date: Tue, 20 Apr 2021 09:50:12 +0200
Subject: [PATCH 07/12] gnu: Add python-ipykernel-bootstrap.

* gnu/packages/python-xyz.scm (python-ipykernel-bootstrap): New
variable.
---
gnu/packages/python-xyz.scm | 13 +++++++++++++
1 file changed, 13 insertions(+)

Toggle diff (26 lines)
diff --git a/gnu/packages/python-xyz.scm b/gnu/packages/python-xyz.scm
index 4c00d3d602..83d1b956ca 100644
--- a/gnu/packages/python-xyz.scm
+++ b/gnu/packages/python-xyz.scm
@@ -7529,6 +7529,19 @@ installing @code{kernelspec}s for use with Jupyter frontends.")
"This package provides the IPython kernel for Jupyter.")
(license license:bsd-3)))
+;; Bootstrap variant of ipykernel, which uses the bootstrap jupyter-client to
+;; break the cycle between ipykernel and jupyter-client.
+(define-public python-ipykernel-bootstrap
+ (let ((parent python-ipykernel))
+ (hidden-package
+ (package
+ (inherit parent)
+ (name "python-ipykernel-bootstrap")
+ (propagated-inputs
+ `(("python-jupyter-client" ,python-jupyter-client-bootstrap)
+ ,@(fold alist-delete (package-propagated-inputs parent)
+ '("python-jupyter-client"))))))))
+
(define-public python-pari-jupyter
(package
(name "python-pari-jupyter")
--
2.26.3
From 936b8ad14e8d1ef1b5939a42c5ed8f2b44abd1f1 Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <lars@6xq.net>
Date: Tue, 20 Apr 2021 09:51:25 +0200
Subject: [PATCH 08/12] gnu: python-jupyter-client: Enable tests.

* gnu/packages/python-xyz.scm (python-jupyter-client) [arguments]:
Enable tests. Run pytest during 'check.
[native-inputs]: Add missing test inputs.
---
gnu/packages/python-xyz.scm | 37 ++++++++++++++++++++++++-------------
1 file changed, 24 insertions(+), 13 deletions(-)

Toggle diff (58 lines)
diff --git a/gnu/packages/python-xyz.scm b/gnu/packages/python-xyz.scm
index 83d1b956ca..62c61e1c21 100644
--- a/gnu/packages/python-xyz.scm
+++ b/gnu/packages/python-xyz.scm
@@ -7437,19 +7437,23 @@ without using the configuration machinery.")
(base32
"10p7fcgvv9hvz9zical9wk68ks5ssak2ykbzx65wm1k1hk8a3g64"))))
(build-system python-build-system)
- ;; Tests fail because of missing native python kernel which I assume is
- ;; provided by the ipython package, which we cannot use because it would
- ;; cause a dependency cycle.
(arguments
- `(#:tests? #f
- #:phases (modify-phases %standard-phases
- (add-after 'unpack 'set-tool-file-names
- (lambda* (#:key inputs #:allow-other-keys)
- (let ((iproute (assoc-ref inputs "iproute")))
- (substitute* "jupyter_client/localinterfaces.py"
- (("'ip'")
- (string-append "'" iproute "/sbin/ip'")))
- #t))))))
+ `(#:phases
+ (modify-phases %standard-phases
+ (add-after 'unpack 'set-tool-file-names
+ (lambda* (#:key inputs #:allow-other-keys)
+ (let ((iproute (assoc-ref inputs "iproute")))
+ (substitute* "jupyter_client/localinterfaces.py"
+ (("'ip'")
+ (string-append "'" iproute "/sbin/ip'")))
+ #t)))
+ (replace 'check
+ (lambda* (#:key tests? #:allow-other-keys)
+ (if tests?
+ (begin
+ ;; Some tests try to write to $HOME.
+ (setenv "HOME" "/tmp")
+ (invoke "pytest" "-vv"))))))))
(inputs
`(("iproute" ,iproute)))
(propagated-inputs
@@ -7459,7 +7463,14 @@ without using the configuration machinery.")
("python-tornado" ,python-tornado-6)
("python-traitlets" ,python-traitlets)))
(native-inputs
- `(("python-pytest" ,python-pytest)))
+ `(("python-pytest" ,python-pytest)
+ ("python-pytest-asyncio" ,python-pytest-asyncio)
+ ("python-pytest-timeout" ,python-pytest-timeout)
+ ("python-async-generator" ,python-async-generator)
+ ("python-mock" ,python-mock)
+ ("python-msgpack" ,python-msgpack)
+ ("python-ipython" ,python-ipython)
+ ("python-ipykernel" ,python-ipykernel-bootstrap)))
(home-page "https://jupyter.org/")
(synopsis "Jupyter protocol implementation and client libraries")
(description
--
2.26.3
L
L
Lars-Dominik Braun wrote on 26 Apr 2021 10:39
(address . 47907-done@debbugs.gnu.org)
YIZ8S88uM6yoi2DX@noor.fritz.box
Hi,

I merged them with minor modifications based on Ricardo’s suggestions as
2209e5c7531bfe5e81c86f0a581d16569ee9b719 and preceding.
Closed
?