waldyrious / rst-playground

Browser-based reStructuredText playground, built on Pyodide and docutils.
https://waldyrious.github.io/rst-playground
ISC License
1 stars 4 forks source link

Allow specifying the version of docutils to use #2

Closed waldyrious closed 1 year ago

waldyrious commented 1 year ago

Pinning the docutils package to a fixed version allows us to make sure that updates to it (which are automatically picked up as Pyodide updates their package distribution) won't break the playground.

Relevant code to change:

https://github.com/waldyrious/rst-playground/blob/f8698e0d0c33e1bfe324e1e126884e388bacf6d3/index.html#L65

waldyrious commented 1 year ago

Another approach could be to offer the user the ability to select their preferred version of docutils, but I don't know if that's worth the additional complexity.

waldyrious commented 1 year ago

Slightly related: commit f003e4fdd1fedca5982704576672c6fa6c01fb97 bumped Pyodide from 0.21.3 to 0.22.0. Perhaps we should figure out a way to get Dependabot or some other automated tool propose version updates automatically. These could even be applied automatically if we add a test suite (#24).

waldyrious commented 1 year ago

Hmm, neither the Loading packages page nor the loadPackage() documentation seem to make any reference to loading specific versions. So we might have to stick with the version of docutils provided by Pyodide (which, at the time of writing, is v0.19). It may not be a big deal, but it would be nice to have a way to control the version explicitly.

For reference, see the list of releases of docutils at PyPI, and the list of release notes for each version, as well as the changelog.

waldyrious commented 1 year ago

Update: I tried specifying a pinned version of docutils using the == operator

pyodide.loadPackage("docutils==0.19")

...but that fails with the error

No known package with name 'docutils==0.19'

...which makes sense since the docs for loadPackage() indeed mention that it loads packages from the Pyodide distribution, which seems to only host one version of each package.

However, that syntax appears to be accepted if we use the micropip.install() instead of loadPackage():

await pyodide.loadPackage("micropip");
const micropip = pyodide.pyimport("micropip");
await micropip.install('docutils==0.19');

This can be checked with the following:

// Print the installed version of docutils
const docutils = pyodide.pyimport("docutils");
console.log(`docutils version: ${docutils.__version__}`); // Outputs "docutils version: 0.19"

That said, the loadPackage() docs also say that it supports wheel URLs, so something like this also works:

await pyodide.loadPackage("https://files.pythonhosted.org/packages/93/69/e391bd51bc08ed9141ecd899a0ddb61ab6465309f1eb470905c0c8868081/docutils-0.19-py3-none-any.whl");

(URL obtained from here.)

It is both more compact and more verbose. I suppose the micropip may be more readable/maintainable...

waldyrious commented 1 year ago

Mulling over this some more, I realized that supporting a docutils version picker would require us to either keep a hardcoded list of past docutils releases[1] (which is not something I'd like to maintain manually), or fetch the data dynamically from PyPI (which I don't particularly like either).

1. Such a list would need to contain either the version number, for use with micropip.install(), or the wheel URL, for use with loadPackage().

To be honest (and following up on my comment above), I suspect this is such a niche need (e.g. one could want this to compare the result of processing the same rst content in two versions of docutils), that the added code complexity and network calls is not justified.

The other use case for specifying versions would be to avoid unintended updates and possible breakage whenever Pyodide's distribution is updated (case in point: the version of docutils currently included in Pyodide is now 0.20.1). But this is not such a pressing issue, because:

  1. docutils' parsing of rst isn't changing that much, and new versions typically fix bugs rather than modify the output;
  2. upgrades to docutils will only happen if we upgrade Pyodide. In other words, the packages included in the Pyodide distribution are, well, bundled with it, rather than hosted separately. So for example, doing pyodide.loadPackage("docutils") in the latest version of Pyodide (at the time of writing) will import docutils v0.20.1, but doing it in Pyodide 0.21 (as was the case in the first version of this project) still imports docutils v0.19

So we have control over the upgrades, and even if we implement some dependabot workflow, as suggested above, we don't have to merge those updates if we don't want to, and we can revert them if anything breaks.

There's the hypothetical case where we might want a Pyodide upgrade but not the associated docutils upgrade, or vice-versa; but if that ever happens, we can use the wheel or micropip approaches listed above to declare the explicit version of docutils we want; but until that need arises, fixing a version is premature optimization.

So I'll go ahead and close this issue as wontfix. We can reconsider later if any of the above changes.