Show More
@@ -98,6 +98,10 b' class Kernel(Configurable):' | |||||
98 | """ |
|
98 | """ | |
99 | ) |
|
99 | ) | |
100 |
|
100 | |||
|
101 | # track associations with current request | |||
|
102 | _allow_stdin = Bool(False) | |||
|
103 | _parent_header = Dict() | |||
|
104 | _parent_ident = Any(b'') | |||
101 | # Time to sleep after flushing the stdout/err buffers in each execute |
|
105 | # Time to sleep after flushing the stdout/err buffers in each execute | |
102 | # cycle. While this introduces a hard limit on the minimal latency of the |
|
106 | # cycle. While this introduces a hard limit on the minimal latency of the | |
103 | # execute cycle, it helps prevent output synchronization problems for |
|
107 | # execute cycle, it helps prevent output synchronization problems for | |
@@ -335,34 +339,26 b' class Kernel(Configurable):' | |||||
335 | ident=self._topic('status'), |
|
339 | ident=self._topic('status'), | |
336 | ) |
|
340 | ) | |
337 |
|
341 | |||
338 |
def _forward_ |
|
342 | def _forward_input(self, allow_stdin=False): | |
339 | """Replace raw_input. Note that is not sufficient to replace |
|
343 | """Forward raw_input and getpass to the current frontend. | |
340 | raw_input in the user namespace. |
|
344 | ||
|
345 | via input_request | |||
341 | """ |
|
346 | """ | |
|
347 | self._allow_stdin = allow_stdin | |||
342 |
|
348 | |||
343 | if allow_stdin: |
|
|||
344 | raw_input = lambda prompt='': self._raw_input(prompt, ident, parent) |
|
|||
345 | input = lambda prompt='': eval(raw_input(prompt)) |
|
|||
346 | _getpass = lambda prompt='', stream=None: self._raw_input( |
|
|||
347 | prompt, ident, parent, password=True |
|
|||
348 | ) |
|
|||
349 | else: |
|
|||
350 | _getpass = raw_input = input = lambda prompt='' : self._no_raw_input() |
|
|||
351 |
|
||||
352 |
|
||||
353 | if py3compat.PY3: |
|
349 | if py3compat.PY3: | |
354 | self._sys_raw_input = builtin_mod.input |
|
350 | self._sys_raw_input = builtin_mod.input | |
355 | builtin_mod.input = raw_input |
|
351 | builtin_mod.input = self.raw_input | |
356 | else: |
|
352 | else: | |
357 | self._sys_raw_input = builtin_mod.raw_input |
|
353 | self._sys_raw_input = builtin_mod.raw_input | |
358 | self._sys_eval_input = builtin_mod.input |
|
354 | self._sys_eval_input = builtin_mod.input | |
359 | builtin_mod.raw_input = raw_input |
|
355 | builtin_mod.raw_input = self.raw_input | |
360 | builtin_mod.input = input |
|
356 | builtin_mod.input = lambda prompt='': eval(self.raw_input(prompt)) | |
361 | self._save_getpass = getpass.getpass |
|
357 | self._save_getpass = getpass.getpass | |
362 |
getpass.getpass = |
|
358 | getpass.getpass = self.getpass | |
363 |
|
359 | |||
364 |
def _restore_ |
|
360 | def _restore_input(self): | |
365 |
|
|
361 | """Restore raw_input, getpass""" | |
366 | if py3compat.PY3: |
|
362 | if py3compat.PY3: | |
367 | builtin_mod.input = self._sys_raw_input |
|
363 | builtin_mod.input = self._sys_raw_input | |
368 | else: |
|
364 | else: | |
@@ -370,7 +366,16 b' class Kernel(Configurable):' | |||||
370 | builtin_mod.input = self._sys_eval_input |
|
366 | builtin_mod.input = self._sys_eval_input | |
371 |
|
367 | |||
372 | getpass.getpass = self._save_getpass |
|
368 | getpass.getpass = self._save_getpass | |
373 |
|
369 | |||
|
370 | def set_parent(self, ident, parent): | |||
|
371 | """Record the parent state | |||
|
372 | ||||
|
373 | For associating side effects with their requests. | |||
|
374 | """ | |||
|
375 | self._parent_ident = ident | |||
|
376 | self._parent_header = parent | |||
|
377 | self.shell.set_parent(parent) | |||
|
378 | ||||
374 | def execute_request(self, stream, ident, parent): |
|
379 | def execute_request(self, stream, ident, parent): | |
375 | """handle an execute_request""" |
|
380 | """handle an execute_request""" | |
376 |
|
381 | |||
@@ -387,14 +392,13 b' class Kernel(Configurable):' | |||||
387 | return |
|
392 | return | |
388 |
|
393 | |||
389 | md = self._make_metadata(parent['metadata']) |
|
394 | md = self._make_metadata(parent['metadata']) | |
390 |
|
395 | |||
391 | shell = self.shell # we'll need this a lot here |
|
396 | shell = self.shell # we'll need this a lot here | |
392 |
|
397 | |||
393 |
self._forward_ |
|
398 | self._forward_input(content.get('allow_stdin', False)) | |
394 |
|
||||
395 | # Set the parent message of the display hook and out streams. |
|
399 | # Set the parent message of the display hook and out streams. | |
396 |
s |
|
400 | self.set_parent(ident, parent) | |
397 |
|
401 | |||
398 | # Re-broadcast our input for the benefit of listening clients, and |
|
402 | # Re-broadcast our input for the benefit of listening clients, and | |
399 | # start computing output |
|
403 | # start computing output | |
400 | if not silent: |
|
404 | if not silent: | |
@@ -419,7 +423,7 b' class Kernel(Configurable):' | |||||
419 | else: |
|
423 | else: | |
420 | status = u'ok' |
|
424 | status = u'ok' | |
421 | finally: |
|
425 | finally: | |
422 |
self._restore_ |
|
426 | self._restore_input() | |
423 |
|
427 | |||
424 | reply_content[u'status'] = status |
|
428 | reply_content[u'status'] = status | |
425 |
|
429 | |||
@@ -744,7 +748,41 b' class Kernel(Configurable):' | |||||
744 | raise StdinNotImplementedError("raw_input was called, but this " |
|
748 | raise StdinNotImplementedError("raw_input was called, but this " | |
745 | "frontend does not support stdin.") |
|
749 | "frontend does not support stdin.") | |
746 |
|
750 | |||
747 | def _raw_input(self, prompt, ident, parent, password=False): |
|
751 | def getpass(self, prompt=''): | |
|
752 | """Forward getpass to frontends | |||
|
753 | ||||
|
754 | Raises | |||
|
755 | ------ | |||
|
756 | StdinNotImplentedError if active frontend doesn't support stdin. | |||
|
757 | """ | |||
|
758 | if not self._allow_stdin: | |||
|
759 | raise StdinNotImplementedError( | |||
|
760 | "getpass was called, but this frontend does not support input requests." | |||
|
761 | ) | |||
|
762 | return self._input_request(prompt, | |||
|
763 | self._parent_ident, | |||
|
764 | self._parent_header, | |||
|
765 | password=True, | |||
|
766 | ) | |||
|
767 | ||||
|
768 | def raw_input(self, prompt=''): | |||
|
769 | """Forward raw_input to frontends | |||
|
770 | ||||
|
771 | Raises | |||
|
772 | ------ | |||
|
773 | StdinNotImplentedError if active frontend doesn't support stdin. | |||
|
774 | """ | |||
|
775 | if not self._allow_stdin: | |||
|
776 | raise StdinNotImplementedError( | |||
|
777 | "raw_input was called, but this frontend does not support input requests." | |||
|
778 | ) | |||
|
779 | return self._input_request(prompt, | |||
|
780 | self._parent_ident, | |||
|
781 | self._parent_header, | |||
|
782 | password=False, | |||
|
783 | ) | |||
|
784 | ||||
|
785 | def _input_request(self, prompt, ident, parent, password=False): | |||
748 | # Flush output before making the request. |
|
786 | # Flush output before making the request. | |
749 | sys.stderr.flush() |
|
787 | sys.stderr.flush() | |
750 | sys.stdout.flush() |
|
788 | sys.stdout.flush() | |
@@ -777,8 +815,7 b' class Kernel(Configurable):' | |||||
777 | try: |
|
815 | try: | |
778 | value = py3compat.unicode_to_str(reply['content']['value']) |
|
816 | value = py3compat.unicode_to_str(reply['content']['value']) | |
779 | except: |
|
817 | except: | |
780 |
self.log.error(" |
|
818 | self.log.error("Bad input_reply: %s", parent) | |
781 | self.log.error("%s", parent) |
|
|||
782 | value = '' |
|
819 | value = '' | |
783 | if value == '\x04': |
|
820 | if value == '\x04': | |
784 | # EOF |
|
821 | # EOF |
General Comments 0
You need to be logged in to leave comments.
Login now