Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/IPython/core/magics/basic.py: 22%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

294 statements  

1"""Implementation of basic magic functions.""" 

2 

3 

4from logging import error 

5import io 

6import os 

7import platform 

8from pprint import pformat 

9import sys 

10from warnings import warn 

11 

12from traitlets.utils.importstring import import_item 

13from IPython.core import magic_arguments, page 

14from IPython.core.error import UsageError 

15from IPython.core.magic import Magics, magics_class, line_magic, magic_escapes 

16from IPython.utils.text import format_screen, dedent, indent 

17from IPython.testing.skipdoctest import skip_doctest 

18from IPython.utils.ipstruct import Struct 

19 

20 

21class MagicsDisplay: 

22 def __init__(self, magics_manager, ignore=None): 

23 self.ignore = ignore if ignore else [] 

24 self.magics_manager = magics_manager 

25 

26 def _lsmagic(self): 

27 """The main implementation of the %lsmagic""" 

28 mesc = magic_escapes['line'] 

29 cesc = magic_escapes['cell'] 

30 mman = self.magics_manager 

31 magics = mman.lsmagic() 

32 out = ['Available line magics:', 

33 mesc + (' '+mesc).join(sorted([m for m,v in magics['line'].items() if (v not in self.ignore)])), 

34 '', 

35 'Available cell magics:', 

36 cesc + (' '+cesc).join(sorted([m for m,v in magics['cell'].items() if (v not in self.ignore)])), 

37 '', 

38 mman.auto_status()] 

39 return '\n'.join(out) 

40 

41 def _repr_pretty_(self, p, cycle): 

42 p.text(self._lsmagic()) 

43 

44 def __repr__(self): 

45 return self.__str__() 

46 

47 def __str__(self): 

48 return self._lsmagic() 

49 

50 def _jsonable(self): 

51 """turn magics dict into jsonable dict of the same structure 

52 

53 replaces object instances with their class names as strings 

54 """ 

55 magic_dict = {} 

56 mman = self.magics_manager 

57 magics = mman.lsmagic() 

58 for key, subdict in magics.items(): 

59 d = {} 

60 magic_dict[key] = d 

61 for name, obj in subdict.items(): 

62 try: 

63 classname = obj.__self__.__class__.__name__ 

64 except AttributeError: 

65 classname = 'Other' 

66 

67 d[name] = classname 

68 return magic_dict 

69 

70 def _repr_json_(self): 

71 return self._jsonable() 

72 

73 

74@magics_class 

75class BasicMagics(Magics): 

76 """Magics that provide central IPython functionality. 

77 

78 These are various magics that don't fit into specific categories but that 

79 are all part of the base 'IPython experience'.""" 

80 

81 @skip_doctest 

82 @magic_arguments.magic_arguments() 

83 @magic_arguments.argument( 

84 '-l', '--line', action='store_true', 

85 help="""Create a line magic alias.""" 

86 ) 

87 @magic_arguments.argument( 

88 '-c', '--cell', action='store_true', 

89 help="""Create a cell magic alias.""" 

90 ) 

91 @magic_arguments.argument( 

92 'name', 

93 help="""Name of the magic to be created.""" 

94 ) 

95 @magic_arguments.argument( 

96 'target', 

97 help="""Name of the existing line or cell magic.""" 

98 ) 

99 @magic_arguments.argument( 

100 '-p', '--params', default=None, 

101 help="""Parameters passed to the magic function.""" 

102 ) 

103 @line_magic 

104 def alias_magic(self, line=''): 

105 """Create an alias for an existing line or cell magic. 

106 

107 Examples 

108 -------- 

109 :: 

110 

111 In [1]: %alias_magic t timeit 

112 Created `%t` as an alias for `%timeit`. 

113 Created `%%t` as an alias for `%%timeit`. 

114 

115 In [2]: %t -n1 pass 

116 107 ns ± 43.6 ns per loop (mean ± std. dev. of 7 runs, 1 loop each) 

117 

118 In [3]: %%t -n1 

119 ...: pass 

120 ...: 

121 107 ns ± 58.3 ns per loop (mean ± std. dev. of 7 runs, 1 loop each) 

122 

123 In [4]: %alias_magic --cell whereami pwd 

124 UsageError: Cell magic function `%%pwd` not found. 

125 In [5]: %alias_magic --line whereami pwd 

126 Created `%whereami` as an alias for `%pwd`. 

127 

128 In [6]: %whereami 

129 Out[6]: '/home/testuser' 

130 

131 In [7]: %alias_magic h history -p "-l 30" --line 

132 Created `%h` as an alias for `%history -l 30`. 

133 """ 

134 

135 args = magic_arguments.parse_argstring(self.alias_magic, line) 

136 shell = self.shell 

137 mman = self.shell.magics_manager 

138 escs = ''.join(magic_escapes.values()) 

139 

140 target = args.target.lstrip(escs) 

141 name = args.name.lstrip(escs) 

142 

143 params = args.params 

144 if (params and 

145 ((params.startswith('"') and params.endswith('"')) 

146 or (params.startswith("'") and params.endswith("'")))): 

147 params = params[1:-1] 

148 

149 # Find the requested magics. 

150 m_line = shell.find_magic(target, 'line') 

151 m_cell = shell.find_magic(target, 'cell') 

152 if args.line and m_line is None: 

153 raise UsageError('Line magic function `%s%s` not found.' % 

154 (magic_escapes['line'], target)) 

155 if args.cell and m_cell is None: 

156 raise UsageError('Cell magic function `%s%s` not found.' % 

157 (magic_escapes['cell'], target)) 

158 

159 # If --line and --cell are not specified, default to the ones 

160 # that are available. 

161 if not args.line and not args.cell: 

162 if not m_line and not m_cell: 

163 raise UsageError( 

164 'No line or cell magic with name `%s` found.' % target 

165 ) 

166 args.line = bool(m_line) 

167 args.cell = bool(m_cell) 

168 

169 params_str = "" if params is None else " " + params 

170 

171 if args.line: 

172 mman.register_alias(name, target, 'line', params) 

173 print('Created `%s%s` as an alias for `%s%s%s`.' % ( 

174 magic_escapes['line'], name, 

175 magic_escapes['line'], target, params_str)) 

176 

177 if args.cell: 

178 mman.register_alias(name, target, 'cell', params) 

179 print('Created `%s%s` as an alias for `%s%s%s`.' % ( 

180 magic_escapes['cell'], name, 

181 magic_escapes['cell'], target, params_str)) 

182 

183 @line_magic 

184 def lsmagic(self, parameter_s=''): 

185 """List currently available magic functions.""" 

186 return MagicsDisplay(self.shell.magics_manager, ignore=[]) 

187 

188 def _magic_docs(self, brief=False, rest=False): 

189 """Return docstrings from magic functions.""" 

190 mman = self.shell.magics_manager 

191 docs = mman.lsmagic_docs(brief, missing='No documentation') 

192 

193 if rest: 

194 format_string = '**%s%s**::\n\n%s\n\n' 

195 else: 

196 format_string = '%s%s:\n%s\n' 

197 

198 return ''.join( 

199 [format_string % (magic_escapes['line'], fname, 

200 indent(dedent(fndoc))) 

201 for fname, fndoc in sorted(docs['line'].items())] 

202 + 

203 [format_string % (magic_escapes['cell'], fname, 

204 indent(dedent(fndoc))) 

205 for fname, fndoc in sorted(docs['cell'].items())] 

206 ) 

207 

208 @line_magic 

209 def magic(self, parameter_s=''): 

210 """Print information about the magic function system. 

211 

212 Supported formats: -latex, -brief, -rest 

213 """ 

214 

215 mode = '' 

216 try: 

217 mode = parameter_s.split()[0][1:] 

218 except IndexError: 

219 pass 

220 

221 brief = (mode == 'brief') 

222 rest = (mode == 'rest') 

223 magic_docs = self._magic_docs(brief, rest) 

224 

225 if mode == 'latex': 

226 print(self.format_latex(magic_docs)) 

227 return 

228 else: 

229 magic_docs = format_screen(magic_docs) 

230 

231 out = [""" 

232IPython's 'magic' functions 

233=========================== 

234 

235The magic function system provides a series of functions which allow you to 

236control the behavior of IPython itself, plus a lot of system-type 

237features. There are two kinds of magics, line-oriented and cell-oriented. 

238 

239Line magics are prefixed with the % character and work much like OS 

240command-line calls: they get as an argument the rest of the line, where 

241arguments are passed without parentheses or quotes. For example, this will 

242time the given statement:: 

243 

244 %timeit range(1000) 

245 

246Cell magics are prefixed with a double %%, and they are functions that get as 

247an argument not only the rest of the line, but also the lines below it in a 

248separate argument. These magics are called with two arguments: the rest of the 

249call line and the body of the cell, consisting of the lines below the first. 

250For example:: 

251 

252 %%timeit x = numpy.random.randn((100, 100)) 

253 numpy.linalg.svd(x) 

254 

255will time the execution of the numpy svd routine, running the assignment of x 

256as part of the setup phase, which is not timed. 

257 

258In a line-oriented client (the terminal or Qt console IPython), starting a new 

259input with %% will automatically enter cell mode, and IPython will continue 

260reading input until a blank line is given. In the notebook, simply type the 

261whole cell as one entity, but keep in mind that the %% escape can only be at 

262the very start of the cell. 

263 

264NOTE: If you have 'automagic' enabled (via the command line option or with the 

265%automagic function), you don't need to type in the % explicitly for line 

266magics; cell magics always require an explicit '%%' escape. By default, 

267IPython ships with automagic on, so you should only rarely need the % escape. 

268 

269Example: typing '%cd mydir' (without the quotes) changes your working directory 

270to 'mydir', if it exists. 

271 

272For a list of the available magic functions, use %lsmagic. For a description 

273of any of them, type %magic_name?, e.g. '%cd?'. 

274 

275Currently the magic system has the following functions:""", 

276 magic_docs, 

277 "Summary of magic functions (from %slsmagic):" % magic_escapes['line'], 

278 str(self.lsmagic()), 

279 ] 

280 page.page('\n'.join(out)) 

281 

282 

283 @line_magic 

284 def page(self, parameter_s=''): 

285 """Pretty print the object and display it through a pager. 

286 

287 %page [options] OBJECT 

288 

289 If no object is given, use _ (last output). 

290 

291 Options: 

292 

293 -r: page str(object), don't pretty-print it.""" 

294 

295 # After a function contributed by Olivier Aubert, slightly modified. 

296 

297 # Process options/args 

298 opts, args = self.parse_options(parameter_s, 'r') 

299 raw = 'r' in opts 

300 

301 oname = args and args or '_' 

302 info = self.shell._ofind(oname) 

303 if info.found: 

304 if raw: 

305 txt = str(info.obj) 

306 else: 

307 txt = pformat(info.obj) 

308 page.page(txt) 

309 else: 

310 print('Object `%s` not found' % oname) 

311 

312 @line_magic 

313 def pprint(self, parameter_s=''): 

314 """Toggle pretty printing on/off.""" 

315 ptformatter = self.shell.display_formatter.formatters['text/plain'] 

316 ptformatter.pprint = bool(1 - ptformatter.pprint) 

317 print('Pretty printing has been turned', 

318 ['OFF','ON'][ptformatter.pprint]) 

319 

320 @line_magic 

321 def colors(self, parameter_s=''): 

322 """Switch color scheme/theme globally for IPython 

323 

324 Examples 

325 -------- 

326 To get a plain black and white terminal:: 

327 

328 %colors nocolor 

329 """ 

330 

331 

332 new_theme = parameter_s.strip() 

333 if not new_theme: 

334 from IPython.utils.PyColorize import theme_table 

335 

336 raise UsageError( 

337 "%colors: you must specify a color theme. See '%colors?'." 

338 f" Available themes: {list(theme_table.keys())}" 

339 ) 

340 

341 self.shell.colors = new_theme 

342 

343 @line_magic 

344 def xmode(self, parameter_s=''): 

345 """Switch modes for the exception handlers. 

346 

347 Valid modes: Plain, Context, Verbose, Minimal, and Docs. 

348 

349 - ``Plain``: similar to Python's default traceback. 

350 - ``Context``: shows several lines of surrounding context for each 

351 frame in the traceback. 

352 - ``Verbose``: like Context, but also displays local variable values 

353 in each frame. 

354 - ``Minimal``: shows only the exception type and message, without 

355 a traceback. 

356 - ``Docs``: a stripped-down version of Verbose, designed for use 

357 when running doctests. 

358 

359 If called without arguments, cycles through the available modes. 

360 

361 When in verbose mode the value ``--show`` (and ``--hide``) 

362 will respectively show (or hide) frames with ``__tracebackhide__ = 

363 True`` value set. 

364 """ 

365 

366 def xmode_switch_err(name): 

367 warn('Error changing %s exception modes.\n%s' % 

368 (name,sys.exc_info()[1])) 

369 

370 shell = self.shell 

371 if parameter_s.strip() == "--show": 

372 shell.InteractiveTB.skip_hidden = False 

373 return 

374 if parameter_s.strip() == "--hide": 

375 shell.InteractiveTB.skip_hidden = True 

376 return 

377 

378 new_mode = parameter_s.strip().capitalize() 

379 try: 

380 shell.InteractiveTB.set_mode(mode=new_mode) 

381 print('Exception reporting mode:',shell.InteractiveTB.mode) 

382 except: 

383 raise 

384 xmode_switch_err('user') 

385 

386 @line_magic 

387 def quickref(self, arg): 

388 """ Show a quick reference sheet """ 

389 from IPython.core.usage import quick_reference 

390 qr = quick_reference + self._magic_docs(brief=True) 

391 page.page(qr) 

392 

393 @line_magic 

394 def doctest_mode(self, parameter_s=''): 

395 """Toggle doctest mode on and off. 

396 

397 This mode is intended to make IPython behave as much as possible like a 

398 plain Python shell, from the perspective of how its prompts, exceptions 

399 and output look. This makes it easy to copy and paste parts of a 

400 session into doctests. It does so by: 

401 

402 - Changing the prompts to the classic ``>>>`` ones. 

403 - Changing the exception reporting mode to 'Plain'. 

404 - Disabling pretty-printing of output. 

405 

406 Note that IPython also supports the pasting of code snippets that have 

407 leading '>>>' and '...' prompts in them. This means that you can paste 

408 doctests from files or docstrings (even if they have leading 

409 whitespace), and the code will execute correctly. You can then use 

410 '%history -t' to see the translated history; this will give you the 

411 input after removal of all the leading prompts and whitespace, which 

412 can be pasted back into an editor. 

413 

414 With these features, you can switch into this mode easily whenever you 

415 need to do testing and changes to doctests, without having to leave 

416 your existing IPython session. 

417 """ 

418 

419 # Shorthands 

420 shell = self.shell 

421 meta = shell.meta 

422 disp_formatter = self.shell.display_formatter 

423 ptformatter = disp_formatter.formatters['text/plain'] 

424 # dstore is a data store kept in the instance metadata bag to track any 

425 # changes we make, so we can undo them later. 

426 dstore = meta.setdefault('doctest_mode',Struct()) 

427 save_dstore = dstore.setdefault 

428 

429 # save a few values we'll need to recover later 

430 mode = save_dstore('mode',False) 

431 save_dstore('rc_pprint',ptformatter.pprint) 

432 save_dstore('xmode',shell.InteractiveTB.mode) 

433 save_dstore('rc_separate_out',shell.separate_out) 

434 save_dstore('rc_separate_out2',shell.separate_out2) 

435 save_dstore('rc_separate_in',shell.separate_in) 

436 save_dstore('rc_active_types',disp_formatter.active_types) 

437 

438 if not mode: 

439 # turn on 

440 

441 # Prompt separators like plain python 

442 shell.separate_in = '' 

443 shell.separate_out = '' 

444 shell.separate_out2 = '' 

445 

446 

447 ptformatter.pprint = False 

448 disp_formatter.active_types = ['text/plain'] 

449 

450 shell.run_line_magic("xmode", "Plain") 

451 else: 

452 # turn off 

453 shell.separate_in = dstore.rc_separate_in 

454 

455 shell.separate_out = dstore.rc_separate_out 

456 shell.separate_out2 = dstore.rc_separate_out2 

457 

458 ptformatter.pprint = dstore.rc_pprint 

459 disp_formatter.active_types = dstore.rc_active_types 

460 

461 shell.run_line_magic("xmode", dstore.xmode) 

462 

463 # mode here is the state before we switch; switch_doctest_mode takes 

464 # the mode we're switching to. 

465 shell.switch_doctest_mode(not mode) 

466 

467 # Store new mode and inform 

468 dstore.mode = bool(not mode) 

469 mode_label = ['OFF','ON'][dstore.mode] 

470 print('Doctest mode is:', mode_label) 

471 

472 @line_magic 

473 def gui(self, parameter_s=''): 

474 """Enable or disable IPython GUI event loop integration. 

475 

476 %gui [GUINAME] 

477 

478 This magic replaces IPython's threaded shells that were activated 

479 using the (pylab/wthread/etc.) command line flags. GUI toolkits 

480 can now be enabled at runtime and keyboard 

481 interrupts should work without any problems. The following toolkits 

482 are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX):: 

483 

484 %gui wx # enable wxPython event loop integration 

485 %gui qt # enable PyQt/PySide event loop integration 

486 # with the latest version available. 

487 %gui qt6 # enable PyQt6/PySide6 event loop integration 

488 %gui qt5 # enable PyQt5/PySide2 event loop integration 

489 %gui gtk # enable PyGTK event loop integration 

490 %gui gtk3 # enable Gtk3 event loop integration 

491 %gui gtk4 # enable Gtk4 event loop integration 

492 %gui tk # enable Tk event loop integration 

493 %gui osx # enable Cocoa event loop integration 

494 # (requires %matplotlib 1.1) 

495 %gui # disable all event loop integration 

496 

497 WARNING: after any of these has been called you can simply create 

498 an application object, but DO NOT start the event loop yourself, as 

499 we have already handled that. 

500 """ 

501 opts, arg = self.parse_options(parameter_s, '') 

502 if arg=='': arg = None 

503 try: 

504 return self.shell.enable_gui(arg) 

505 except Exception as e: 

506 # print simple error message, rather than traceback if we can't 

507 # hook up the GUI 

508 error(str(e)) 

509 

510 @skip_doctest 

511 @line_magic 

512 def precision(self, s=''): 

513 """Set floating point precision for pretty printing. 

514 

515 Can set either integer precision or a format string. 

516 

517 If numpy has been imported and precision is an int, 

518 numpy display precision will also be set, via ``numpy.set_printoptions``. 

519 

520 If no argument is given, defaults will be restored. 

521 

522 Examples 

523 -------- 

524 :: 

525 

526 In [1]: from math import pi 

527 

528 In [2]: %precision 3 

529 Out[2]: '%.3f' 

530 

531 In [3]: pi 

532 Out[3]: 3.142 

533 

534 In [4]: %precision %i 

535 Out[4]: '%i' 

536 

537 In [5]: pi 

538 Out[5]: 3 

539 

540 In [6]: %precision %e 

541 Out[6]: '%e' 

542 

543 In [7]: pi**10 

544 Out[7]: 9.364805e+04 

545 

546 In [8]: %precision 

547 Out[8]: '%r' 

548 

549 In [9]: pi**10 

550 Out[9]: 93648.047476082982 

551 """ 

552 ptformatter = self.shell.display_formatter.formatters['text/plain'] 

553 ptformatter.float_precision = s 

554 return ptformatter.float_format 

555 

556 @magic_arguments.magic_arguments() 

557 @magic_arguments.argument( 

558 'filename', type=str, 

559 help='Notebook name or filename' 

560 ) 

561 @line_magic 

562 def notebook(self, s): 

563 """Export and convert IPython notebooks. 

564 

565 This function can export the current IPython history to a notebook file. 

566 For example, to export the history to "foo.ipynb" do "%notebook foo.ipynb". 

567 """ 

568 args = magic_arguments.parse_argstring(self.notebook, s) 

569 outfname = os.path.expanduser(args.filename) 

570 

571 from nbformat import write, v4 

572 from nbformat.sign import NotebookNotary 

573 

574 cells = [] 

575 hist = list(self.shell.history_manager.get_range()) 

576 outputs = self.shell.history_manager.outputs 

577 exceptions = self.shell.history_manager.exceptions 

578 

579 if(len(hist)<=1): 

580 raise ValueError('History is empty, cannot export') 

581 

582 for session, execution_count, source in hist[:-1]: 

583 cell = v4.new_code_cell(execution_count=execution_count, source=source) 

584 

585 for output in outputs[execution_count]: 

586 if output.output_type in {"out_stream", "err_stream"}: 

587 text_data = [] 

588 for mime_type, data in output.bundle.items(): 

589 if isinstance(data, list): 

590 text_data.extend(data) 

591 else: 

592 text_data.append(data) 

593 full_text = "".join(text_data) 

594 # Replace literal \n with actual newlines 

595 full_text = full_text.replace("\\n", "\n") 

596 normalized_text = [] 

597 lines = full_text.split("\n") 

598 for i, line in enumerate(lines): 

599 if i < len(lines) - 1: 

600 normalized_text.append(line + "\n") 

601 elif line: # Last line only if it's not empty 

602 normalized_text.append(line + "\n") 

603 stream_output = v4.new_output("stream", text=normalized_text) 

604 if output.output_type == "err_stream": 

605 stream_output.name = "stderr" 

606 cell.outputs.append(stream_output) 

607 

608 elif output.output_type == "execute_result": 

609 data_dict = {} 

610 for mime_type, data in output.bundle.items(): 

611 data_dict[mime_type] = data 

612 cell.outputs.append( 

613 v4.new_output( 

614 "execute_result", 

615 data=data_dict, 

616 execution_count=execution_count, 

617 ) 

618 ) 

619 

620 elif output.output_type == "display_data": 

621 # Collect all MIME types for this display_data into a single output 

622 data_dict = {} 

623 for mime_type, data in output.bundle.items(): 

624 data_dict[mime_type] = data 

625 cell.outputs.append( 

626 v4.new_output( 

627 "display_data", 

628 data=data_dict, 

629 ) 

630 ) 

631 else: 

632 raise ValueError(f"Unknown output type: {output.output_type}") 

633 

634 # Check if this execution_count is in exceptions (current session) 

635 if execution_count in exceptions: 

636 cell.outputs.append( 

637 v4.new_output("error", **exceptions[execution_count]) 

638 ) 

639 cells.append(cell) 

640 

641 kernel_language_info = self._get_kernel_language_info() 

642 

643 nb = v4.new_notebook( 

644 cells=cells, 

645 metadata={ 

646 "kernelspec": { 

647 "display_name": "Python 3 (ipykernel)", 

648 "language": "python", 

649 "name": "python3", 

650 }, 

651 "language_info": kernel_language_info 

652 or { 

653 "codemirror_mode": { 

654 "name": "ipython", 

655 "version": sys.version_info[0], 

656 }, 

657 "file_extension": ".py", 

658 "mimetype": "text/x-python", 

659 "name": "python", 

660 "nbconvert_exporter": "python", 

661 "pygments_lexer": "ipython3", 

662 "version": platform.python_version(), 

663 }, 

664 }, 

665 ) 

666 # Sign the notebook to make it trusted 

667 notary = NotebookNotary() 

668 notary.update_config(self.shell.config) 

669 notary.sign(nb) 

670 with io.open(outfname, "w", encoding="utf-8") as f: 

671 write(nb, f, version=4) 

672 

673 def _get_kernel_language_info(self) -> dict | None: 

674 """Get language info from kernel, useful when used in Jupyter Console where kernels exist.""" 

675 if not hasattr(self.shell, "kernel"): 

676 return 

677 if not hasattr(self.shell.kernel, "language_info"): 

678 return 

679 if not isinstance(self.shell.kernel.language_info, dict): 

680 return 

681 return self.shell.kernel.language_info 

682 

683@magics_class 

684class AsyncMagics(BasicMagics): 

685 

686 @line_magic 

687 def autoawait(self, parameter_s): 

688 """ 

689 Allow to change the status of the autoawait option. 

690 

691 This allow you to set a specific asynchronous code runner. 

692 

693 If no value is passed, print the currently used asynchronous integration 

694 and whether it is activated. 

695 

696 It can take a number of value evaluated in the following order: 

697 

698 - False/false/off deactivate autoawait integration 

699 - True/true/on activate autoawait integration using configured default 

700 loop 

701 - asyncio/curio/trio activate autoawait integration and use integration 

702 with said library. 

703 

704 - `sync` turn on the pseudo-sync integration (mostly used for 

705 `IPython.embed()` which does not run IPython with a real eventloop and 

706 deactivate running asynchronous code. Turning on Asynchronous code with 

707 the pseudo sync loop is undefined behavior and may lead IPython to crash. 

708 

709 If the passed parameter does not match any of the above and is a python 

710 identifier, get said object from user namespace and set it as the 

711 runner, and activate autoawait. 

712 

713 If the object is a fully qualified object name, attempt to import it and 

714 set it as the runner, and activate autoawait. 

715 

716 The exact behavior of autoawait is experimental and subject to change 

717 across version of IPython and Python. 

718 """ 

719 

720 param = parameter_s.strip() 

721 d = {True: "on", False: "off"} 

722 

723 if not param: 

724 print("IPython autoawait is `{}`, and set to use `{}`".format( 

725 d[self.shell.autoawait], 

726 self.shell.loop_runner 

727 )) 

728 return None 

729 

730 if param.lower() in ('false', 'off'): 

731 self.shell.autoawait = False 

732 return None 

733 if param.lower() in ('true', 'on'): 

734 self.shell.autoawait = True 

735 return None 

736 

737 if param in self.shell.loop_runner_map: 

738 self.shell.loop_runner, self.shell.autoawait = self.shell.loop_runner_map[param] 

739 return None 

740 

741 if param in self.shell.user_ns : 

742 self.shell.loop_runner = self.shell.user_ns[param] 

743 self.shell.autoawait = True 

744 return None 

745 

746 runner = import_item(param) 

747 

748 self.shell.loop_runner = runner 

749 self.shell.autoawait = True