An embedded IPython instance to run inside Sphinx
| 339 | |
| 340 | |
| 341 | class EmbeddedSphinxShell: |
| 342 | """An embedded IPython instance to run inside Sphinx""" |
| 343 | |
| 344 | def __init__(self, exec_lines=None): |
| 345 | |
| 346 | self.cout = StringIO() |
| 347 | |
| 348 | if exec_lines is None: |
| 349 | exec_lines = [] |
| 350 | |
| 351 | # Create config object for IPython |
| 352 | config = Config() |
| 353 | config.HistoryManager.hist_file = ':memory:' |
| 354 | config.InteractiveShell.autocall = False |
| 355 | config.InteractiveShell.autoindent = False |
| 356 | config.InteractiveShell.colors = "nocolor" |
| 357 | |
| 358 | # create a profile so instance history isn't saved |
| 359 | tmp_profile_dir = tempfile.mkdtemp(prefix='profile_') |
| 360 | profname = 'auto_profile_sphinx_build' |
| 361 | pdir = os.path.join(tmp_profile_dir,profname) |
| 362 | profile = ProfileDir.create_profile_dir(pdir) |
| 363 | |
| 364 | # Create and initialize global ipython, but don't start its mainloop. |
| 365 | # This will persist across different EmbeddedSphinxShell instances. |
| 366 | IP = InteractiveShell.instance(config=config, profile_dir=profile) |
| 367 | atexit.register(self.cleanup) |
| 368 | |
| 369 | # Store a few parts of IPython we'll need. |
| 370 | self.IP = IP |
| 371 | self.user_ns = self.IP.user_ns |
| 372 | self.user_global_ns = self.IP.user_global_ns |
| 373 | |
| 374 | self.input = '' |
| 375 | self.output = '' |
| 376 | self.tmp_profile_dir = tmp_profile_dir |
| 377 | |
| 378 | self.is_verbatim = False |
| 379 | self.is_doctest = False |
| 380 | self.is_suppress = False |
| 381 | |
| 382 | # Optionally, provide more detailed information to shell. |
| 383 | # this is assigned by the SetUp method of IPythonDirective |
| 384 | # to point at itself. |
| 385 | # |
| 386 | # So, you can access handy things at self.directive.state |
| 387 | self.directive = None |
| 388 | |
| 389 | # on the first call to the savefig decorator, we'll import |
| 390 | # pyplot as plt so we can make a call to the plt.gcf().savefig |
| 391 | self._pyplot_imported = False |
| 392 | |
| 393 | # Prepopulate the namespace. |
| 394 | for line in exec_lines: |
| 395 | self.process_input_line(line, store_history=False) |
| 396 | |
| 397 | def cleanup(self): |
| 398 | shutil.rmtree(self.tmp_profile_dir, ignore_errors=True) |
no outgoing calls
no test coverage detected
searching dependent graphs…