jupyterlite / pyodide-kernel

Python kernel for JupyterLite powered by Pyodide
https://jupyterlite-pyodide-kernel.readthedocs.io/en/latest/_static/
BSD 3-Clause "New" or "Revised" License
46 stars 25 forks source link

OSError when calling %run or %load #95

Closed Bartvvenrooij closed 8 months ago

Bartvvenrooij commented 8 months ago

Description

An OSError occurs when calling a python script with %load or %run from a notebook. It was working before and somewhere in the last 2 weeks it broke without making changes. This is happening on a docker hosted version but also the online example platform on https://jupyterlite.readthedocs.io

Reproduce

To reproduce the error you need to create a simple python file and simple notebook

  1. Go to https://jupyterlite.readthedocs.io/en/stable/try/lab
  2. Create a new python file and save it as test.py
  3. Add a simple print statement: print("Hello world")
  4. Create a new notebook
  5. Add the following run statement to the first cell: %run test.py
  6. Run the first cell of the notebook

I created a jupyter-lite image 2 weeks ago and wanted to use it again but it suddenly failed. I have searched for the error but could not find any information about this error

Expected behavior

It should just run the python script and print Hello world

Context

Browser Output
---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
Cell In[1], line 1
----> 1 get_ipython().run_line_magic('run', 'test.py')

File /lib/python3.11/site-packages/IPython/core/interactiveshell.py:2480, in InteractiveShell.run_line_magic(self, magic_name, line, _stack_depth)
   2478     kwargs['local_ns'] = self.get_local_scope(stack_depth)
   2479 with self.builtin_trap:
-> 2480     result = fn(*args, **kwargs)
   2482 # The code below prevents the output from being displayed
   2483 # when using magics with decorator @output_can_be_silenced
   2484 # when the last Python token in the expression is a ';'.
   2485 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False):

File /lib/python3.11/site-packages/IPython/core/magics/execution.py:703, in ExecutionMagics.run(self, parameter_s, runner, file_finder)
    700     parameter_s = ' '.join(shlex.quote(arg) for arg in argv)
    702 # get arguments and set sys.argv for program to be run.
--> 703 opts, arg_lst = self.parse_options(parameter_s,
    704                                    'nidtN:b:pD:l:rs:T:em:G',
    705                                    mode='list', list_all=1)
    706 if "m" in opts:
    707     modulename = opts["m"][0]

File /lib/python3.11/site-packages/IPython/core/magic.py:672, in Magics.parse_options(self, arg_str, opt_str, *long_opts, **kw)
    668 args = arg_str.split()
    669 if len(args) >= 1:
    670     # If the list of inputs only has 0 or 1 thing in it, there's no
    671     # need to look for options
--> 672     argv = arg_split(arg_str, posix, strict)
    673     # Do regular option processing
    674     try:

File /lib/python3.11/site-packages/IPython/utils/_process_emscripten.py:21, in arg_split(s, posix, strict)
     19 def arg_split(s, posix=False, strict=True):
     20     """This one could be made to work but it's not clear if it would be useful..."""
---> 21     raise OSError("Not available")

OSError: Not available
bollwyvl commented 8 months ago

See also: https://github.com/jupyterlite/demo/issues/139

bollwyvl commented 8 months ago

The nickle fix for now would be to explicitly pin a working version of IPython to the PyPI wheel URL, a la in jupyter_lite_config.json:

{
  "PipliteAddon": {
    "piplite_urls": [
      "https://files.pythonhosted.org/packages/47/6b/d9fdcdef2eb6a23f391251fde8781c38d42acd82abe84d054cb74f7863b0/ipython-8.18.1-py3-none-any.whl"
    ]
  }
}
Bartvvenrooij commented 8 months ago

Thank you! This fix works for now

pierre-haessig commented 8 months ago

Just a small remark: the bug can be reproduced in less steps:

  1. Go to https://jupyterlite.readthedocs.io/en/stable/try/lab
  2. Create a new notebook
  3. Add the following run statement to the first cell: %run test.py
  4. Run the first cell of the notebook

Indeed, no need to create the test.py script, since the OSError happens so early in the process of the %run magic that its existence isn't yet checked.

Also, here is a summary of what I got from https://github.com/jupyterlite/demo/issues/139 mentioned by @bollwyvl: for any Jupyterlite deployment derived from the demo, this issue will be only be fixed by the upcoming IPython 8.22.2 release (scheduled for end of March but may arrive sooner), since pinning to an older IPython version is not possible with that setup.

pierre-haessig commented 8 months ago

For the reference, IPython 8.22.2 just got released and fixes the problem. Thanks @Carreau!