Issue
I'm trying to test a jupyter notebook with nbval.
py.test --nbval ~/MyNotebook.ipynb
Howver, the notebook has a getpass() function in it. This blocks the test:
========================================================================================= FAILURES =========================================================================================
__________________________________________________________________________________ Untitled.ipynb::Cell 1 __________________________________________________________________________________
Notebook cell execution failed
Cell 1: Cell execution caused an exception
Input:
getpass.getpass()
Traceback:
---------------------------------------------------------------------------
StdinNotImplementedError Traceback (most recent call last)
<ipython-input-2-b4e90adc512e> in <module>
----> 1 getpass.getpass()
/opt/miniconda/lib/python3.8/site-packages/ipykernel/kernelbase.py in getpass(self, prompt, stream)
834 """
835 if not self._allow_stdin:
--> 836 raise StdinNotImplementedError(
837 "getpass was called, but this frontend does not support input requests."
838 )
StdinNotImplementedError: getpass was called, but this frontend does not support input requests.
I've tried to override the function, however it still prompts for input:
How can I override the getpass() function or provide Stdin so that it doesn't block for user input?
Solution
What you tried would seem work, here it is in the Python interpreter
>>> import getpass
>>> getpass.getpass = lambda: "abc"
>>> getpass.getpass()
'abc'
However, on Jupyter, IPython overrides getpass
between blocks.
The solution is either to monkeypatch at the start of every block, or monkeypatch IPython directly:
The IPython version of getpass is defined here and here, I hacked accordingly.
import IPython
from ipykernel.kernelapp import IPythonKernel
import builtins
# Modified version of original function
def _forward_input_hacked(self, allow_stdin=False):
"""Forward raw_input and getpass to the current frontend.
via input_request (hacked)
"""
self._allow_stdin = allow_stdin
self._sys_raw_input = builtins.input
builtins.input = self.raw_input
self._save_getpass = getpass.getpass
getpass.getpass = lambda: "xyz"
#getpass.getpass = self.getpass
ipyk = IPython.Application.instance().kernel
ipyk._forward_input = _forward_input_hacked.__get__(ipyk, IPythonKernel)
import getpass
This should persist across blocks.
Note: a previous version of my answer did not answer the question properly, this monkeypatch should do the trick.
Answered By - AlexApps99
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.