| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | import sys | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-02 10:36:04 +01:00
										 |  |  | from typing import  List | 
					
						
							|  |  |  | from traitlets import Bool | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | from yap4py.yapi import * | 
					
						
							| 
									
										
										
										
											2018-06-02 10:36:04 +01:00
										 |  |  | from yap_ipython.core.completer import Completer | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | # import yap_ipython.core | 
					
						
							|  |  |  | from traitlets import Instance | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  | from yap_ipython.core.inputsplitter import * | 
					
						
							|  |  |  | from yap_ipython.core.inputtransformer import * | 
					
						
							| 
									
										
										
										
											2018-03-02 21:18:24 +00:00
										 |  |  | from yap_ipython.core.interactiveshell import * | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-02 21:18:24 +00:00
										 |  |  | from yap_ipython.core import interactiveshell | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | from collections import namedtuple | 
					
						
							| 
									
										
										
										
											2018-07-23 17:13:51 +01:00
										 |  |  | import traceback | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | use_module = namedtuple('use_module', 'file') | 
					
						
							|  |  |  | bindvars = namedtuple('bindvars', 'list') | 
					
						
							|  |  |  | library = namedtuple('library', 'list') | 
					
						
							|  |  |  | v = namedtuple('_', 'slot') | 
					
						
							|  |  |  | load_files = namedtuple('load_files', 'file ofile args') | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  | python_query = namedtuple('python_query', 'query_mgr string') | 
					
						
							| 
									
										
										
										
											2018-07-10 23:21:19 +01:00
										 |  |  | jupyter_query = namedtuple('jupyter_query', 'self text query') | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | enter_cell = namedtuple('enter_cell', 'self' ) | 
					
						
							|  |  |  | exit_cell = namedtuple('exit_cell', 'self' ) | 
					
						
							|  |  |  | completions = namedtuple('completions', 'txt self' ) | 
					
						
							| 
									
										
										
										
											2018-07-10 23:21:19 +01:00
										 |  |  | errors = namedtuple('errors', 'self text' ) | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  | streams = namedtuple('streams', ' text' ) | 
					
						
							| 
									
										
										
										
											2018-06-02 10:36:04 +01:00
										 |  |  | nostreams = namedtuple('nostreams', ' text' ) | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-17 10:38:56 +00:00
										 |  |  | global  engine | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-01 08:37:25 +01:00
										 |  |  | def tracefunc(frame, event, arg, indent=[0]): | 
					
						
							|  |  |  |     if event == "call": | 
					
						
							|  |  |  |         indent[0] += 2 | 
					
						
							|  |  |  |         print( "-" * indent[0] + "> call function", frame.f_code.co_name ) | 
					
						
							|  |  |  |     elif event == "return": | 
					
						
							|  |  |  |         print( "<" + "-" * indent[0], "exit function", frame.f_code.co_name ) | 
					
						
							|  |  |  |         indent[0] -= 2 | 
					
						
							|  |  |  |     return tracefunc | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  | class YAPInputSplitter(InputSplitter): | 
					
						
							|  |  |  |     """An input splitter that recognizes all of iyap's special syntax.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # String with raw, untransformed input. | 
					
						
							|  |  |  |     source_raw = '' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Flag to track when a transformer has stored input that it hasn't given | 
					
						
							|  |  |  |     # back yet. | 
					
						
							|  |  |  |     transformer_accumulating = False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Flag to track when assemble_yap_lines has stored input that it hasn't | 
					
						
							|  |  |  |     # given back yet. | 
					
						
							|  |  |  |     within_yap_line = False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Private attributes | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # List with lines of raw input accumulated so far. | 
					
						
							|  |  |  |     _buffer_raw = None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-14 00:41:05 +00:00
										 |  |  |     def __init__(self, engine=None, shell=None, line_input_checker=True, physical_line_transforms=None, | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |                     logical_line_transforms=None): | 
					
						
							|  |  |  |         self._buffer_raw = [] | 
					
						
							| 
									
										
										
										
											2018-01-29 15:24:32 +00:00
										 |  |  |         self._validate = True | 
					
						
							| 
									
										
										
										
											2018-03-14 00:41:05 +00:00
										 |  |  |         self.yapeng = engine | 
					
						
							|  |  |  |         self.shell = shell | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if physical_line_transforms is not None: | 
					
						
							|  |  |  |             self.physical_line_transforms = physical_line_transforms | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.physical_line_transforms = [ | 
					
						
							|  |  |  |                                              leading_indent(), | 
					
						
							|  |  |  |                                              classic_prompt(), | 
					
						
							|  |  |  |                                              ipy_prompt(), | 
					
						
							|  |  |  |                                              cellmagic(end_on_blank_line=line_input_checker), | 
					
						
							|  |  |  |                                             ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assemble_logical_lines = assemble_logical_lines() | 
					
						
							|  |  |  |         if logical_line_transforms is not None: | 
					
						
							|  |  |  |             self.logical_line_transforms = logical_line_transforms | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.logical_line_transforms = [ | 
					
						
							|  |  |  |                                             help_end(), | 
					
						
							|  |  |  |                                             escaped_commands(), | 
					
						
							|  |  |  |                                             assign_from_magic(), | 
					
						
							|  |  |  |                                             assign_from_system(), | 
					
						
							|  |  |  |                                            ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @property | 
					
						
							|  |  |  |     def transforms(self): | 
					
						
							|  |  |  |         "Quick access to all transformers." | 
					
						
							|  |  |  |         return self.physical_line_transforms + \ | 
					
						
							|  |  |  |             [self.assemble_logical_lines] + self.logical_line_transforms | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @property | 
					
						
							|  |  |  |     def transforms_in_use(self): | 
					
						
							|  |  |  |         """Transformers, excluding logical line transformers if we're in a
 | 
					
						
							|  |  |  |         Python line."""
 | 
					
						
							|  |  |  |         t = self.physical_line_transforms + \ | 
					
						
							|  |  |  |         [self.assemble_logical_lines] + self.logical_line_transforms | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  |         return t | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-14 00:41:05 +00:00
										 |  |  |     def validQuery(self, text, engine, shell, line=None): | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |         """Return whether a legal query
 | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2018-03-17 10:38:56 +00:00
										 |  |  |         if shell and text == shell.os: | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  |             return True | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |         if not  line: | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  |             line = text.rstrip() | 
					
						
							| 
									
										
										
										
											2018-07-21 01:56:48 +01:00
										 |  |  |         self.errors = [] | 
					
						
							|  |  |  |         engine.mgoal(errors(self, line),"user",True) | 
					
						
							|  |  |  |         return self.errors != [] | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def reset(self): | 
					
						
							|  |  |  |         """Reset the input buffer and associated state.""" | 
					
						
							|  |  |  |         #super(YAPInputSplitter, self).reset() | 
					
						
							|  |  |  |         self._buffer_raw[:] = [] | 
					
						
							|  |  |  |         self.source_raw = '' | 
					
						
							|  |  |  |         self.transformer_accumulating = False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for t in self.transforms: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 t.reset() | 
					
						
							|  |  |  |             except SyntaxError: | 
					
						
							|  |  |  |                 # Nothing that calls reset() expects to handle transformer | 
					
						
							|  |  |  |                 # errors | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def flush_transformers(self): | 
					
						
							|  |  |  |         def _flush(transform, outs): | 
					
						
							|  |  |  |             """yield transformed lines
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             always strings, never None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             transform: the current transform | 
					
						
							|  |  |  |             outs: an iterable of previously transformed inputs. | 
					
						
							|  |  |  |                  Each may be multiline, which will be passed | 
					
						
							|  |  |  |                  one line at a time to transform. | 
					
						
							|  |  |  |             """
 | 
					
						
							|  |  |  |             for out in outs: | 
					
						
							|  |  |  |                 for line in out.splitlines(): | 
					
						
							|  |  |  |                     # push one line at a time | 
					
						
							|  |  |  |                     tmp = transform.push(line) | 
					
						
							|  |  |  |                     if tmp is not None: | 
					
						
							|  |  |  |                         yield tmp | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # reset the transform | 
					
						
							|  |  |  |             tmp = transform.reset() | 
					
						
							|  |  |  |             if tmp is not None: | 
					
						
							|  |  |  |                 yield tmp | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         out = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for t in self.transforms: | 
					
						
							|  |  |  |             out = _flush(t, out) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         out = list(out) | 
					
						
							|  |  |  |         if out: | 
					
						
							|  |  |  |             self._store('\n'.join(out)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def raw_reset(self): | 
					
						
							|  |  |  |         """Return raw input only and perform a full reset.
 | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         out = self.source_raw | 
					
						
							|  |  |  |         self.reset() | 
					
						
							|  |  |  |         return out | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def source_reset(self): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             self.flush_transformers() | 
					
						
							|  |  |  |             return self.source | 
					
						
							|  |  |  |         finally: | 
					
						
							|  |  |  |             self.reset() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def push_accepts_more(self): | 
					
						
							|  |  |  |         if self.transformer_accumulating: | 
					
						
							|  |  |  |             return True | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2018-03-17 10:38:56 +00:00
										 |  |  |             return self.validQuery(self.source, engine, self.shell) | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def transform_cell(self, cell): | 
					
						
							|  |  |  |         """Process and translate a cell of input.
 | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.reset() | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             self.push(cell) | 
					
						
							|  |  |  |             self.flush_transformers() | 
					
						
							|  |  |  |             return self.source | 
					
						
							|  |  |  |         finally: | 
					
						
							|  |  |  |             self.reset() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def push(self, lines): | 
					
						
							|  |  |  |         """Push one or more lines of yap_ipython input.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         This stores the given lines and returns a status code indicating | 
					
						
							|  |  |  |         whether the code forms a complete Python block or not, after processing | 
					
						
							|  |  |  |         all input lines for special yap_ipython syntax. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Any exceptions generated in compilation are swallowed, but if an | 
					
						
							|  |  |  |         exception was produced, the method returns True. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Parameters | 
					
						
							|  |  |  |         ---------- | 
					
						
							|  |  |  |         lines : string | 
					
						
							|  |  |  |           One or more lines of Python input. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Returns | 
					
						
							|  |  |  |         ------- | 
					
						
							|  |  |  |         is_complete : boolean | 
					
						
							|  |  |  |           True if the current input source (the result of the current input | 
					
						
							|  |  |  |           plus prior inputs) forms a complete Python execution block.  Note that | 
					
						
							|  |  |  |           this value is also stored as a private attribute (_is_complete), so it | 
					
						
							|  |  |  |           can be queried at any time. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # We must ensure all input is pure unicode | 
					
						
							|  |  |  |         lines = cast_unicode(lines, self.encoding) | 
					
						
							|  |  |  |         # ''.splitlines() --> [], but we need to push the empty line to transformers | 
					
						
							|  |  |  |         lines_list = lines.splitlines() | 
					
						
							|  |  |  |         if not lines_list: | 
					
						
							|  |  |  |             lines_list = [''] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Store raw source before applying any transformations to it.  Note | 
					
						
							|  |  |  |         # that this must be done *after* the reset() call that would otherwise | 
					
						
							|  |  |  |         # flush the buffer. | 
					
						
							|  |  |  |         self._store(lines, self._buffer_raw, 'source_raw') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         transformed_lines_list = [] | 
					
						
							|  |  |  |         for line in lines_list: | 
					
						
							|  |  |  |             transformed = self._transform_line(line) | 
					
						
							|  |  |  |             if transformed is not None: | 
					
						
							|  |  |  |                 transformed_lines_list.append(transformed) | 
					
						
							|  |  |  |         if transformed_lines_list: | 
					
						
							|  |  |  |             transformed_lines = '\n'.join(transformed_lines_list) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             # Got nothing back from transformers - they must be waiting for | 
					
						
							|  |  |  |             # more input. | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _transform_line(self, line): | 
					
						
							|  |  |  |         """Push a line of input code through the various transformers.
 | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |         Returns any output from the transformers, or None if a transformer | 
					
						
							|  |  |  |         is accumulating lines. | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |         Sets self.transformer_accumulating as a side effect. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         def _accumulating(dbg): | 
					
						
							|  |  |  |             #print(dbg) | 
					
						
							|  |  |  |             self.transformer_accumulating = True | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for transformer in self.physical_line_transforms: | 
					
						
							|  |  |  |             line = transformer.push(line) | 
					
						
							|  |  |  |             if line is None: | 
					
						
							|  |  |  |                 return _accumulating(transformer) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for transformer in self.logical_line_transforms: | 
					
						
							|  |  |  |             line = transformer.push(line) | 
					
						
							|  |  |  |             if line is None: | 
					
						
							|  |  |  |                 return _accumulating(transformer) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         #print("transformers clear") #debug | 
					
						
							|  |  |  |         self.transformer_accumulating = False | 
					
						
							|  |  |  |         return line | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class YAPCompleter(Completer): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     greedy = Bool(False, | 
					
						
							|  |  |  |                   help="""Activate greedy completion
 | 
					
						
							|  |  |  |         PENDING DEPRECTION. this is now mostly taken care of with Jedi. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-02 21:18:24 +00:00
										 |  |  |         This will enable completion on elements of lists, self.results of function calls, etc., | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |         but can be unsafe because the code is actually evaluated on TAB. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |                   ).tag(config=True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     debug = Bool(default_value=False, | 
					
						
							|  |  |  |                  help='Enable debug for the Completer. Mostly print extra ' | 
					
						
							|  |  |  |                       'information for experimental jedi integration.') \ | 
					
						
							|  |  |  |         .tag(config=True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     backslash_combining_completions = Bool(True, | 
					
						
							|  |  |  |                                            help="Enable unicode completions, e.g. \\alpha<tab> . " | 
					
						
							|  |  |  |                                                 "Includes completion of latex commands, unicode names, and expanding " | 
					
						
							|  |  |  |                                                 "unicode characters back to latex commands.").tag(config=True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, namespace=None, global_namespace=None, shell=None, **kwargs): | 
					
						
							|  |  |  |         """Create a new completer for the command line.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Completer(namespace=ns, global_namespace=ns2) -> completer instance. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.shell = shell | 
					
						
							|  |  |  |         self.magic_escape = ESC_MAGIC | 
					
						
							|  |  |  |         super(Completer, self).__init__(**kwargs) | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def complete(self, text, line=None, cursor_pos=None): | 
					
						
							|  |  |  |         """Return the completed text and a list of completions.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Parameters | 
					
						
							|  |  |  |         ---------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            text : string | 
					
						
							|  |  |  |              A string of text to be completed on.  It can be given as empty and | 
					
						
							|  |  |  |              instead a line/position pair are given.  In this case, the | 
					
						
							|  |  |  |              completer itself will split the line like readline does. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |        This is called successively with state == 0, 1, 2, ... until it | 
					
						
							|  |  |  |         returns None.  The completion should begin with 'text'. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |            line : string, optional | 
					
						
							|  |  |  |              The complete line that text is part of. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            cursor_pos : int, optional | 
					
						
							|  |  |  |              The position of the cursor on the input line. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Returns | 
					
						
							|  |  |  |         ------- | 
					
						
							|  |  |  |           text : string | 
					
						
							|  |  |  |             The actual text that was completed. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           matches : list | 
					
						
							|  |  |  |             A sorted list with all possible completions. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         The optional arguments allow the completion to take more context into | 
					
						
							|  |  |  |         account, and are part of the low-level completion API. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         This is a wrapper around the completion mechanism, similar to what | 
					
						
							|  |  |  |         readline does at the command line when the TAB key is hit.  By | 
					
						
							|  |  |  |         exposing it as a method, it can be used by other non-readline | 
					
						
							|  |  |  |         environments (such as GUIs) for text completion. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Simple usage example: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         In [1]: x = 'hello' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         In [2]: _ip.complete('x.l') | 
					
						
							|  |  |  |         Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip']) | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         if not  text: | 
					
						
							|  |  |  |             text = line[:cursor_pos] | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |         return self.completions(text, cursor_pos) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def magic_matches(self, text): | 
					
						
							|  |  |  |         """Match magics""" | 
					
						
							|  |  |  |         # Get all shell magics now rather than statically, so magics loaded at | 
					
						
							|  |  |  |         # runtime show up too. | 
					
						
							|  |  |  |         lsm = self.shell.magics_manager.lsmagic() | 
					
						
							|  |  |  |         line_magics = lsm['line'] | 
					
						
							|  |  |  |         cell_magics = lsm['cell'] | 
					
						
							|  |  |  |         pre = self.magic_escape | 
					
						
							|  |  |  |         pre2 = pre+pre | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         explicit_magic = text.startswith(pre) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Completion logic: | 
					
						
							|  |  |  |         # - user gives %%: only do cell magics | 
					
						
							|  |  |  |         # - user gives %: do both line and cell magics | 
					
						
							|  |  |  |         # - no prefix: do both | 
					
						
							|  |  |  |         # In other words, line magics are skipped if the user gives %% explicitly | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         # We also exclude magics that match any currently visible names: | 
					
						
							|  |  |  |         # https://github.com/ipython/ipython/issues/4877, unless the user has | 
					
						
							|  |  |  |         # typed a %: | 
					
						
							|  |  |  |         # https://github.com/ipython/ipython/issues/10754 | 
					
						
							|  |  |  |         bare_text = text.lstrip(pre) | 
					
						
							|  |  |  |         global_matches = [] | 
					
						
							|  |  |  |         if not explicit_magic: | 
					
						
							|  |  |  |             def matches(magic): | 
					
						
							|  |  |  |                 """
 | 
					
						
							|  |  |  |                 Filter magics, in particular remove magics that match | 
					
						
							|  |  |  |                 a name present in global namespace. | 
					
						
							|  |  |  |                 """
 | 
					
						
							|  |  |  |                 return ( magic.startswith(bare_text) and | 
					
						
							|  |  |  |                          magic not in global_matches ) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             def matches(magic): | 
					
						
							|  |  |  |                 return magic.startswith(bare_text) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         comp = [ pre2+m for m in cell_magics if matches(m)] | 
					
						
							|  |  |  |         if not text.startswith(pre2): | 
					
						
							|  |  |  |             comp += [ pre+m for m in line_magics if matches(m)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return comp | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def magic_config_matches(self, text:str) -> List[str]: | 
					
						
							|  |  |  |         """ Match class names and attributes for %config magic """ | 
					
						
							|  |  |  |         texts = text.strip().split() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if len(texts) > 0 and (texts[0] == 'config' or texts[0] == '%config'): | 
					
						
							|  |  |  |             # get all configuration classes | 
					
						
							|  |  |  |             classes = sorted(set([ c for c in self.shell.configurables | 
					
						
							|  |  |  |                                    if c.__class__.class_traits(config=True) | 
					
						
							|  |  |  |                                    ]), key=lambda x: x.__class__.__name__) | 
					
						
							|  |  |  |             classnames = [ c.__class__.__name__ for c in classes ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # return all classnames if config or %config is given | 
					
						
							|  |  |  |             if len(texts) == 1: | 
					
						
							|  |  |  |                 return classnames | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # match classname | 
					
						
							|  |  |  |             classname_texts = texts[1].split('.') | 
					
						
							|  |  |  |             classname = classname_texts[0] | 
					
						
							|  |  |  |             classname_matches = [ c for c in classnames | 
					
						
							|  |  |  |                                   if c.startswith(classname) ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # return matched classes or the matched class with attributes | 
					
						
							|  |  |  |             if texts[1].find('.') < 0: | 
					
						
							|  |  |  |                 return classname_matches | 
					
						
							|  |  |  |             elif len(classname_matches) == 1 and \ | 
					
						
							|  |  |  |                     classname_matches[0] == classname: | 
					
						
							|  |  |  |                 cls = classes[classnames.index(classname)].__class__ | 
					
						
							|  |  |  |                 help = cls.class_get_help() | 
					
						
							|  |  |  |                 # strip leading '--' from cl-args: | 
					
						
							|  |  |  |                 help = re.sub(re.compile(r'^--', re.MULTILINE), '', help) | 
					
						
							|  |  |  |                 return [ attr.split('=')[0] | 
					
						
							|  |  |  |                          for attr in help.strip().splitlines() | 
					
						
							|  |  |  |                          if attr.startswith(texts[1]) ] | 
					
						
							|  |  |  |         return [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def magic_color_matches(self, text:str) -> List[str] : | 
					
						
							|  |  |  |         """ Match color schemes for %colors magic""" | 
					
						
							|  |  |  |         texts = text.split() | 
					
						
							|  |  |  |         if text.endswith(' '): | 
					
						
							|  |  |  |             # .split() strips off the trailing whitespace. Add '' back | 
					
						
							|  |  |  |             # so that: '%colors ' -> ['%colors', ''] | 
					
						
							|  |  |  |             texts.append('') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if len(texts) == 2 and (texts[0] == 'colors' or texts[0] == '%colors'): | 
					
						
							|  |  |  |             prefix = texts[1] | 
					
						
							|  |  |  |             return [ color for color in InspectColors.keys() | 
					
						
							|  |  |  |                      if color.startswith(prefix) ] | 
					
						
							|  |  |  |         return [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def completions(self, text, offset): | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         Returns an iterator over the possible completions | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |         .. warning:: Unstable | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |             This function is unstable, API may change without warning. | 
					
						
							|  |  |  |             It will also raise unless use in proper context manager. | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |         Parameters | 
					
						
							|  |  |  |         ---------- | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |         text:str | 
					
						
							|  |  |  |             Full text of the current input, multi line string. | 
					
						
							|  |  |  |         offset:int | 
					
						
							|  |  |  |             Integer representing the position of the cursor in ``text``. Offset | 
					
						
							|  |  |  |             is 0-based indexed. | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |         Yields | 
					
						
							|  |  |  |         ------ | 
					
						
							|  |  |  |             :any:`Completion` object | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         The cursor on a text can either be seen as being "in between" | 
					
						
							|  |  |  |         characters or "On" a character depending on the interface visible to | 
					
						
							|  |  |  |         the user. For consistency the cursor being on "in between" characters X | 
					
						
							|  |  |  |         and Y is equivalent to the cursor being "on" character Y, that is to say | 
					
						
							|  |  |  |         the character the cursor is on is considered as being after the cursor. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Combining characters may span more that one position in the | 
					
						
							|  |  |  |         text. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .. note:: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             If ``IPCompleter.debug`` is :any:`True` will yield a ``--jedi/ipython--`` | 
					
						
							|  |  |  |             fake Completion token to distinguish completion returned by Jedi | 
					
						
							|  |  |  |             and usual yap_ipython completion. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .. note:: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             Completions are not completely deduplicated yet. If identical | 
					
						
							|  |  |  |             completions are coming from different sources this function does not | 
					
						
							|  |  |  |             ensure that each completion object will only be present once. | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |         self.matches = [] | 
					
						
							| 
									
										
										
										
											2018-07-21 01:56:48 +01:00
										 |  |  |         prolog_res = self.shell.yapeng.mgoal(completions(text, self), "user",True) | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  |         if self.matches: | 
					
						
							|  |  |  |             return text, self.matches | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |         magic_res = self.magic_matches(text) | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  |         return text,  magic_res | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  | class YAPRun: | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |     """An enhanced, interactive shell for YAP.""" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |     def __init__(self, shell): | 
					
						
							|  |  |  |         self.shell = shell | 
					
						
							| 
									
										
										
										
											2018-07-10 23:21:19 +01:00
										 |  |  |         self.yapeng = JupyterEngine() | 
					
						
							| 
									
										
										
										
											2018-03-17 10:38:56 +00:00
										 |  |  |         global engine | 
					
						
							|  |  |  |         engine = self.yapeng | 
					
						
							| 
									
										
										
										
											2018-07-27 11:11:04 +01:00
										 |  |  |         self.errors = [] | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  |         self.query = None | 
					
						
							| 
									
										
										
										
											2018-03-02 21:18:24 +00:00
										 |  |  |         self.os = None | 
					
						
							|  |  |  |         self.it = None | 
					
						
							| 
									
										
										
										
											2018-07-23 17:13:51 +01:00
										 |  |  |         self.port = None | 
					
						
							|  |  |  |         self.answers = None | 
					
						
							|  |  |  |         self.bindings = dicts = [] | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |         self.shell.yapeng = self.yapeng | 
					
						
							|  |  |  |         self._get_exc_info = shell._get_exc_info | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-21 23:29:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-23 17:13:51 +01:00
										 |  |  |     def showtraceback(self, exc_info): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             (etype, value, tb) = e | 
					
						
							|  |  |  |             traceback.print_exception(etype, value, tb) | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             print(e) | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-10 23:21:19 +01:00
										 |  |  |     def syntaxErrors(self, text): | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |         """Return whether a legal query
 | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         if not  text: | 
					
						
							|  |  |  |             return [] | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  |         if text == self.os: | 
					
						
							| 
									
										
										
										
											2018-07-21 01:56:48 +01:00
										 |  |  |             return self.errors | 
					
						
							|  |  |  |         self.errors=[] | 
					
						
							| 
									
										
										
										
											2018-07-10 23:21:19 +01:00
										 |  |  |         (text,_,_,_) = self.clean_end(text) | 
					
						
							| 
									
										
										
										
											2018-07-21 01:56:48 +01:00
										 |  |  |         self.yapeng.mgoal(errors(self,text),"user",True) | 
					
						
							|  |  |  |         return self.errors | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-02 21:18:24 +00:00
										 |  |  |     def jupyter_query(self, s): | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |         # | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  |         # construct a self.queryuery from a one-line string | 
					
						
							|  |  |  |         # self.query is opaque to Python | 
					
						
							|  |  |  |         try: | 
					
						
							| 
									
										
										
										
											2018-06-01 08:37:25 +01:00
										 |  |  |             program,squery,stop,howmany = self.prolog_cell(s) | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  |             found = False | 
					
						
							| 
									
										
										
										
											2018-06-01 08:37:25 +01:00
										 |  |  |             # sys.settrace(tracefunc) | 
					
						
							| 
									
										
										
										
											2018-06-14 11:27:43 +01:00
										 |  |  |             if self.query and self.os == program+squery: | 
					
						
							| 
									
										
										
										
											2018-06-01 08:37:25 +01:00
										 |  |  |                 howmany += self.iterations | 
					
						
							| 
									
										
										
										
											2018-07-23 17:13:51 +01:00
										 |  |  |                 found = howmany != 0 | 
					
						
							| 
									
										
										
										
											2018-06-01 08:37:25 +01:00
										 |  |  |             else: | 
					
						
							|  |  |  |                 if self.query: | 
					
						
							|  |  |  |                     self.query.close() | 
					
						
							| 
									
										
										
										
											2018-07-23 17:13:51 +01:00
										 |  |  |                     self.query = None | 
					
						
							|  |  |  |                     self.port = None | 
					
						
							|  |  |  |                     self.answers = None | 
					
						
							| 
									
										
										
										
											2018-06-14 11:27:43 +01:00
										 |  |  |                 self.os = program+squery | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  |                 self.iterations = 0 | 
					
						
							| 
									
										
										
										
											2018-06-01 08:37:25 +01:00
										 |  |  |                 pg = jupyter_query( self, program, squery) | 
					
						
							|  |  |  |                 self.query =  self.yapeng.query(pg) | 
					
						
							| 
									
										
										
										
											2018-07-23 17:13:51 +01:00
										 |  |  |                 self.answers = [] | 
					
						
							| 
									
										
										
										
											2018-07-24 20:18:41 +01:00
										 |  |  |             self.port =  "call" | 
					
						
							|  |  |  |             self.answer =  {} | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  |             while self.query.next(): | 
					
						
							| 
									
										
										
										
											2018-07-23 17:13:51 +01:00
										 |  |  |                 #sys.stderr.write('B '+str( self.answer) +'\n') | 
					
						
							|  |  |  |                 #sys.stderr.write('C '+ str(self.port) +'\n'+'\n') | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  |                 found = True | 
					
						
							| 
									
										
										
										
											2018-07-23 17:13:51 +01:00
										 |  |  |                 self.answers += [self.answer] | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  |                 self.iterations += 1 | 
					
						
							| 
									
										
										
										
											2018-07-23 17:13:51 +01:00
										 |  |  |                 if self.port  == "exit": | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  |                     self.os = None | 
					
						
							| 
									
										
										
										
											2018-07-27 11:11:04 +01:00
										 |  |  |                     #sys.stderr.write('Done, with'+str(self.answers)+'\n') | 
					
						
							| 
									
										
										
										
											2018-07-24 20:18:41 +01:00
										 |  |  |                     self.result.result = True,self.bindings | 
					
						
							|  |  |  |                     return self.result | 
					
						
							| 
									
										
										
										
											2018-06-01 08:37:25 +01:00
										 |  |  |                 if stop or howmany == self.iterations: | 
					
						
							| 
									
										
										
										
											2018-07-24 20:18:41 +01:00
										 |  |  |                     self.result.result = True, self.answers | 
					
						
							|  |  |  |                     return self.result | 
					
						
							| 
									
										
										
										
											2018-03-26 11:03:08 +01:00
										 |  |  |             if found: | 
					
						
							| 
									
										
										
										
											2018-07-23 17:13:51 +01:00
										 |  |  |                 sys.stderr.write('Done, with '+str(self.answers)+'\n') | 
					
						
							| 
									
										
										
										
											2018-03-19 11:43:14 +00:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2018-06-01 08:37:25 +01:00
										 |  |  |                 self.os = None | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  |                 self.query.close() | 
					
						
							| 
									
										
										
										
											2018-06-02 10:36:04 +01:00
										 |  |  |                 self.query = None | 
					
						
							| 
									
										
										
										
											2018-03-19 11:43:14 +00:00
										 |  |  |                 sys.stderr.write('Fail\n') | 
					
						
							| 
									
										
										
										
											2018-07-24 20:18:41 +01:00
										 |  |  |                 self.result.result = True,self.bindings | 
					
						
							|  |  |  |                 return self.result | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  |         except Exception as e: | 
					
						
							| 
									
										
										
										
											2018-07-23 17:13:51 +01:00
										 |  |  |             sys.stderr.write('Exception '+str(e)+' after '+str( self.bindings)+ '\n') | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  |             has_raised = True | 
					
						
							| 
									
										
										
										
											2018-07-24 20:18:41 +01:00
										 |  |  |             self.result.result = False | 
					
						
							|  |  |  |             return self.result | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _yrun_cell(self, raw_cell, store_history=True, silent=False, | 
					
						
							|  |  |  |                  shell_futures=True): | 
					
						
							|  |  |  |         """Run a complete IPython cell.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Parameters | 
					
						
							|  |  |  |                    ---------- | 
					
						
							|  |  |  |                    raw_cell : str | 
					
						
							|  |  |  |                    The code (including IPython code such as | 
					
						
							|  |  |  |                    %magic functions) to run. | 
					
						
							|  |  |  |                    store_history : bool | 
					
						
							|  |  |  |           If True, the raw and translated cell will be stored in IPython's | 
					
						
							|  |  |  |                    history. For user code calling back into | 
					
						
							|  |  |  |                    IPython's machinery, this | 
					
						
							|  |  |  |                    should be set to False. | 
					
						
							|  |  |  |                    silent : bool | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  |           If True, avoid side-effects, such as implicit displayhooks and | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |                    and logging.  silent=True forces store_history=False. | 
					
						
							|  |  |  |                    shell_futures : bool | 
					
						
							|  |  |  |           If True, the code will share future statements with the interactive | 
					
						
							|  |  |  |                    shell. It will both be affected by previous | 
					
						
							|  |  |  |                     __future__ imports, and any __future__ imports in the code | 
					
						
							|  |  |  |                      will affect the shell. If False, | 
					
						
							|  |  |  |                    __future__ imports are not shared in either direction. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Returns | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                    ------- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-02 21:18:24 +00:00
										 |  |  | `self.result : :class:`Executionself.result` | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |                    """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # construct a query from a one-line string | 
					
						
							|  |  |  |         # q is opaque to Python | 
					
						
							|  |  |  |         # vs is the list of variables | 
					
						
							|  |  |  |         # you can print it out, the left-side is the variable name, | 
					
						
							|  |  |  |         # the right side wraps a handle to a variable | 
					
						
							| 
									
										
										
										
											2018-03-19 11:43:14 +00:00
										 |  |  |         #import pdb; pdb.set_trace() | 
					
						
							| 
									
										
										
										
											2018-07-21 01:56:48 +01:00
										 |  |  |         #     #pdb.set_trace() | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |         # atom match either symbols, or if no symbol exists, strings, In this case | 
					
						
							|  |  |  |         # variable names should match strings | 
					
						
							|  |  |  |         # ask = True | 
					
						
							|  |  |  |         # launch the query | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-01 13:22:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |         info = interactiveshell.ExecutionInfo( | 
					
						
							|  |  |  |             raw_cell, store_history, silent, shell_futures) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-02 21:18:24 +00:00
										 |  |  |         self.result = interactiveshell.ExecutionResult(info) | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (raw_cell == "") or raw_cell.isspace(): | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |             self.shell.last_execution_succeeded = True | 
					
						
							| 
									
										
										
										
											2018-03-02 21:18:24 +00:00
										 |  |  |             return self.result | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if silent: | 
					
						
							|  |  |  |             store_history = False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if store_history: | 
					
						
							| 
									
										
										
										
											2018-06-01 08:37:25 +01:00
										 |  |  |             self.result.execution_count = self.shell.execution_count+1 | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-27 11:11:04 +01:00
										 |  |  |         def error_before_exec(self, value): | 
					
						
							| 
									
										
										
										
											2018-06-01 08:37:25 +01:00
										 |  |  |             self.result.error_before_exec = value | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |             self.shell.last_execution_succeeded = False | 
					
						
							| 
									
										
										
										
											2018-03-02 21:18:24 +00:00
										 |  |  |             return self.result | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |         self.shell.events.trigger('pre_execute') | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |         if not silent: | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |             self.shell.events.trigger('pre_run_cell') | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |         # If any of our input transformation (input_transformer_manager or | 
					
						
							|  |  |  |         # prefilter_manager) raises an exception, we store it in this variable | 
					
						
							|  |  |  |         # so that we can display the error after logging the input and storing | 
					
						
							|  |  |  |         # it in the history. | 
					
						
							|  |  |  |         preprocessing_exc_tuple = None | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |         # try: | 
					
						
							|  |  |  |         #     # Static input transformations | 
					
						
							|  |  |  |         #     cell = self.shell.input_transformer_manager.transform_cell(raw_cell) | 
					
						
							|  |  |  |         # except SyntaxError: | 
					
						
							|  |  |  |         #     preprocessing_exc_tuple = self.shell.syntax_error() # sys.exc_info() | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |         cell = raw_cell  # cell has to exist so it can be stored/logged | 
					
						
							| 
									
										
										
										
											2018-07-27 11:11:04 +01:00
										 |  |  |         for i in self.errors: | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2018-07-27 11:11:04 +01:00
										 |  |  |                 (_,lin,pos,text) = i | 
					
						
							|  |  |  |                 e = SyntaxError(what, (self.cell_name, lin, pos, text+'\n')) | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |                 raise e | 
					
						
							|  |  |  |             except SyntaxError: | 
					
						
							|  |  |  |                 self.shell.showsyntaxerror(  ) | 
					
						
							|  |  |  |                 preprocessing_exc_tuple = sys.exc_info() | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |         # Store raw and processed history | 
					
						
							|  |  |  |         if store_history: | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |             self.shell.history_manager.store_inputs(self.shell.execution_count, | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |                                               cell, raw_cell) | 
					
						
							|  |  |  |         if not silent: | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |             self.shell.logger.log(cell, raw_cell) | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |         # # Display the exception if input processing failed. | 
					
						
							| 
									
										
										
										
											2018-03-19 11:43:14 +00:00
										 |  |  |         if preprocessing_exc_tuple is not None: | 
					
						
							|  |  |  |             self.showtraceback(preprocessing_exc_tuple) | 
					
						
							|  |  |  |             if store_history: | 
					
						
							|  |  |  |                 self.shell.execution_count += 1 | 
					
						
							| 
									
										
										
										
											2018-07-27 11:11:04 +01:00
										 |  |  |             return self.error_before_exec(preprocessing_exc_tuple[2]) | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # Our own compiler remembers the __future__ environment. If we want to | 
					
						
							|  |  |  |         # run code with a separate __future__ environment, use the default | 
					
						
							|  |  |  |         # compiler | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |         # compiler = self.shell.compile if shell_futures else CachingCompiler() | 
					
						
							| 
									
										
										
										
											2018-07-27 11:11:04 +01:00
										 |  |  |         self.cell_name = str( self.shell.execution_count) | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |         if cell[0] == '%': | 
					
						
							|  |  |  |             if cell[1] == '%': | 
					
						
							|  |  |  |                 linec = False | 
					
						
							|  |  |  |                 mcell = cell.lstrip('%%') | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 linec = True | 
					
						
							|  |  |  |                 mcell = cell.lstrip('%') | 
					
						
							|  |  |  |             txt0 = mcell.split(maxsplit = 2, sep = '\n') | 
					
						
							|  |  |  |             txt = txt0[0].split(maxsplit = 2) | 
					
						
							| 
									
										
										
										
											2018-02-01 01:44:34 +00:00
										 |  |  |             magic = txt[0] | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |             if len(txt) == 2: | 
					
						
							|  |  |  |                 line = txt[1] | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 line = "" | 
					
						
							|  |  |  |             if linec: | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |                 self.shell.run_line_magic(magic, line) | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2018-03-19 11:43:14 +00:00
										 |  |  |                 if len(txt0) == 1: | 
					
						
							|  |  |  |                     cell = "" | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     body = txt0[1]+'\n'+txt0[2] | 
					
						
							| 
									
										
										
										
											2018-07-24 20:18:41 +01:00
										 |  |  |                 self.result = True, self.shell.run_cell_magic(magic, line, body) | 
					
						
							|  |  |  |                 return self.result | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |         # Give the displayhook a reference to our ExecutionResult so it | 
					
						
							|  |  |  |         # can fill in the output value. | 
					
						
							| 
									
										
										
										
											2018-03-02 21:18:24 +00:00
										 |  |  |         self.shell.displayhook.exec_result = self.result | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |         has_raised = False | 
					
						
							|  |  |  |         try: | 
					
						
							| 
									
										
										
										
											2018-07-21 01:56:48 +01:00
										 |  |  |             self.yapeng.mgoal(streams(True),"user", True) | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  |             if cell.strip('\n \t'): | 
					
						
							| 
									
										
										
										
											2018-06-01 08:37:25 +01:00
										 |  |  |                 #create a Trace object, telling it what to ignore, and whether to | 
					
						
							|  |  |  |                 # do tracing or line-counting or both. | 
					
						
							|  |  |  |                 # tracer = trace.Trace( | 
					
						
							|  |  |  |                 #     ignoredirs=[sys.prefix, sys.exec_prefix], | 
					
						
							|  |  |  |                 #     trace=1, | 
					
						
							|  |  |  |                 #     count=0) | 
					
						
							|  |  |  |                 # | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 # def f(self, cell, state): | 
					
						
							|  |  |  |                 #     state = self.jupyter_query( cell ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 # run the new command using the given tracer | 
					
						
							|  |  |  |                 # | 
					
						
							|  |  |  |                 # tracer.runfunc(f,self,cell,state) | 
					
						
							|  |  |  |                 self.jupyter_query( cell ) | 
					
						
							| 
									
										
										
										
											2018-06-02 10:36:04 +01:00
										 |  |  |                 # state = tracer.runfunc(jupyter_query( self, cell ) ) | 
					
						
							| 
									
										
										
										
											2018-06-01 08:37:25 +01:00
										 |  |  |             self.shell.last_execution_succeeded = True | 
					
						
							| 
									
										
										
										
											2018-07-06 16:51:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |         except Exception as e: | 
					
						
							|  |  |  |             has_raised = True | 
					
						
							| 
									
										
										
										
											2018-03-02 21:18:24 +00:00
										 |  |  |             self.result.result = False | 
					
						
							| 
									
										
										
										
											2018-07-23 17:13:51 +01:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 (etype, value, tb) = e | 
					
						
							|  |  |  |                 traceback.print_exception(etype, value, tb) | 
					
						
							|  |  |  |             except: | 
					
						
							|  |  |  |                 print(e) | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |         self.shell.last_execution_succeeded = not has_raised | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # Reset this so later displayed values do not modify the | 
					
						
							|  |  |  |         # ExecutionResult | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |         self.shell.displayhook.exec_result = None | 
					
						
							|  |  |  |         self.shell.events.trigger('post_execute') | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |         if not silent: | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |             self.shell.events.trigger('post_run_cell') | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if store_history: | 
					
						
							|  |  |  |             # Write output to the database. Does nothing unless | 
					
						
							|  |  |  |             # history output logging is enabled. | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |             self.shell.history_manager.store_output(self.shell.execution_count) | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |             # Each cell is a *single* input, regardless of how many lines it has | 
					
						
							| 
									
										
										
										
											2018-01-18 14:47:27 +00:00
										 |  |  |             self.shell.execution_count += 1 | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-23 17:13:51 +01:00
										 |  |  |         self.yapeng.mgoal(streams(False),"user", True) | 
					
						
							| 
									
										
										
										
											2018-03-02 21:18:24 +00:00
										 |  |  |         return self.result | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  |     def    clean_end(self,s): | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         Look at the query suffix and return | 
					
						
							|  |  |  |             - whatever is left | 
					
						
							|  |  |  |             - how much was taken | 
					
						
							|  |  |  |             - whether to stop | 
					
						
							|  |  |  |             - when to stop | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2018-06-01 08:37:25 +01:00
										 |  |  |         l0 = len(s) | 
					
						
							|  |  |  |         i = s.rfind(";") | 
					
						
							|  |  |  |         if i < 0: | 
					
						
							|  |  |  |             its = 1 | 
					
						
							|  |  |  |             stop = True | 
					
						
							|  |  |  |             taken = 0 | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             taken = l0-(i-1) | 
					
						
							|  |  |  |             n = s[i+1:].strip() | 
					
						
							| 
									
										
										
										
											2018-07-06 16:51:19 +01:00
										 |  |  |             s = s[:i] | 
					
						
							| 
									
										
										
										
											2018-06-01 08:37:25 +01:00
										 |  |  |             if n: | 
					
						
							|  |  |  |                 its = 0 | 
					
						
							|  |  |  |                 for ch in n: | 
					
						
							|  |  |  |                     if not ch.isdigit(): | 
					
						
							| 
									
										
										
										
											2018-07-27 11:11:04 +01:00
										 |  |  |                         raise SyntaxError("expected positive number", (self.cellname,s.strip.lines()+1,s.count('\n'),n)) | 
					
						
							| 
									
										
										
										
											2018-06-01 08:37:25 +01:00
										 |  |  |                     its =  its*10+ (ord(ch) - ord('0')) | 
					
						
							|  |  |  |                 stop = False | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 stop = False | 
					
						
							|  |  |  |                 its = -1 | 
					
						
							|  |  |  |                 # one solution, stop | 
					
						
							|  |  |  |         return s, taken, stop, its | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |     def    prolog_cell(self,s): | 
					
						
							| 
									
										
										
										
											2018-03-02 21:18:24 +00:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  |         Trasform a text into program+query. A query is the | 
					
						
							|  |  |  |         last line if the last line is non-empty and does not terminate | 
					
						
							|  |  |  |         on a dot. You can also finish with | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-23 17:13:51 +01:00
										 |  |  |             - `*`: you request all solutions | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  |             - ';'[N]: you want an answer; optionally you want N answers | 
					
						
							| 
									
										
										
										
											2018-01-05 16:57:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             If the line terminates on a `*/` or starts on a `%` we assume the line | 
					
						
							|  |  |  |         is a comment. | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2018-03-12 15:11:59 +00:00
										 |  |  |         s0 = s.rstrip(' \n\t\i') | 
					
						
							|  |  |  |         [program,x,query] = s0.rpartition('\n') | 
					
						
							|  |  |  |         if query[-1] == '.': | 
					
						
							|  |  |  |             return s,'',False,0 | 
					
						
							|  |  |  |         (query, _,loop, sols) = self.clean_end(query) | 
					
						
							|  |  |  |         return (program, query, loop, sols) |