Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix joining of source when source is an array of strings #186

Merged
merged 2 commits into from
Sep 29, 2023

Conversation

jtpio
Copy link
Member

@jtpio jtpio commented Sep 28, 2023

This should fix the issue noticed in jupyterlite/jupyterlite#1141 (comment).

As discussed in jupyterlite/jupyterlite#1141 (comment), loading notebooks which have cells with their source set to be a list of strings instead of a single string.

Example notebook: https://github.com/jupyterlite/jupyterlite/blob/main/examples/pyodide/ipycanvas.ipynb

Example cell:

{
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def life_step(x):\n",
    "    \"\"\"Game of life step\"\"\"\n",
    "    nbrs_count = sum(\n",
    "        np.roll(np.roll(x, i, 0), j, 1)\n",
    "        for i in (-1, 0, 1)\n",
    "        for j in (-1, 0, 1)\n",
    "        if (i != 0 or j != 0)\n",
    "    )\n",
    "    return (nbrs_count == 3) | (x & (nbrs_count == 2))"
   ]
  },

Which in JupyterLite renders as follows with extra line breaks:

image

Currently the server component in JupyterLite does not normalize the source to be a string. So it sends the array of strings to the frontend.


This is not an issue in stock JupyterLab because the response from the Jupyter Server already normalizes the source to be a single string:

image

This is likely because Jupyter Server uses nbformat to read the notebook: https://github.com/jupyter-server/jupyter_server/blob/3544deb53902cc02c9aa9d6513b3c30f1113896b/jupyter_server/services/contents/fileio.py#L264-L291

And the nbformat documentation mentions the following in https://nbformat.readthedocs.io/en/latest/format_description.html#cell-types:

On disk, multi-line strings MAY be split into lists of strings. When read with the nbformat Python API, these multi-line strings will always be a single string.

nbformat also joins the string with an empty string: https://github.com/jupyter/nbformat/blob/0a2942c8f77d33b43a327293c7a7596afcf4527d/nbformat/v4/rwbase.py#L38

for cell in nb.cells:
    if "source" in cell and isinstance(cell.source, list):
        cell.source = "".join(cell.source)

@jtpio jtpio added the bug Something isn't working label Sep 28, 2023
@jtpio jtpio changed the title Fix joining of source when source is an array of strings Fix joining of source when source is an array of strings Sep 28, 2023
@davidbrochart
Copy link
Collaborator

Jupyverse sends the cell source as-is, which also leads to extra newlines in JupyterLab. There is a fix in jupyter-server/jupyverse#354, but does it mean this issue is a JupyterLab frontend issue (not particularly an issue in jupyter-ydoc)? Meaning that JupyterLab should render the source correctly if in an array.

@jtpio
Copy link
Member Author

jtpio commented Sep 29, 2023

JupyterLab uses the @jupyter/ydoc package, so I would say this fix should be implemented in @jupyter/ydoc as proposed in this PR?

This means jupyter-server/jupyverse#354 would then not be necessary, as the frontend would handle reading an array of strings.

@davidbrochart
Copy link
Collaborator

But the issue also appears in non-collaborative mode.

@jtpio
Copy link
Member Author

jtpio commented Sep 29, 2023

Because JupyterLab still instantiates a sharedModel: https://github.com/jupyterlab/jupyterlab/blob/bd46c76046671ae375b3ddd207ca441841e57123/packages/docregistry/src/context.ts#L62-L73

And uses shared interfaces exposes by @jupyter/ydoc (search for @jupyter/ydoc in the JupyterLab code base).

@davidbrochart
Copy link
Collaborator

I see, thanks. Then I think this PR is good to go. I'll also merge jupyter-server/jupyverse#354 to better align with jupyter-server.

@jtpio
Copy link
Member Author

jtpio commented Sep 29, 2023

For reference I was able to verify this does fix the issue by modifying @jupyter/ydoc locally and testing with a local build of JupyterLite (which does not use collaboration):

image

@davidbrochart davidbrochart merged commit 9afd2c9 into jupyter-server:main Sep 29, 2023
8 checks passed
@davidbrochart
Copy link
Collaborator

Thanks @jtpio!

@jtpio
Copy link
Member Author

jtpio commented Sep 29, 2023

Thanks @davidbrochart for the review!

Would it be possible to get this in a patch release? 🙏

@jtpio jtpio deleted the fix-join-source branch September 29, 2023 08:03
@davidbrochart
Copy link
Collaborator

@jtpio
Copy link
Member Author

jtpio commented Sep 29, 2023

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants