##// END OF EJS Templates
support negative indexing
Matthias Bussonnier -
Show More
@@ -1,795 +1,797 b''
1 1 """Input transformer machinery to support IPython special syntax.
2 2
3 3 This includes the machinery to recognise and transform ``%magic`` commands,
4 4 ``!system`` commands, ``help?`` querying, prompt stripping, and so forth.
5 5
6 6 Added: IPython 7.0. Replaces inputsplitter and inputtransformer which were
7 7 deprecated in 7.0.
8 8 """
9 9
10 10 # Copyright (c) IPython Development Team.
11 11 # Distributed under the terms of the Modified BSD License.
12 12
13 13 import ast
14 14 from codeop import CommandCompiler, Compile
15 15 import re
16 16 import tokenize
17 17 from typing import List, Tuple, Optional, Any
18 18 import warnings
19 19
20 20 _indent_re = re.compile(r'^[ \t]+')
21 21
22 22 def leading_empty_lines(lines):
23 23 """Remove leading empty lines
24 24
25 25 If the leading lines are empty or contain only whitespace, they will be
26 26 removed.
27 27 """
28 28 if not lines:
29 29 return lines
30 30 for i, line in enumerate(lines):
31 31 if line and not line.isspace():
32 32 return lines[i:]
33 33 return lines
34 34
35 35 def leading_indent(lines):
36 36 """Remove leading indentation.
37 37
38 38 If the first line starts with a spaces or tabs, the same whitespace will be
39 39 removed from each following line in the cell.
40 40 """
41 41 if not lines:
42 42 return lines
43 43 m = _indent_re.match(lines[0])
44 44 if not m:
45 45 return lines
46 46 space = m.group(0)
47 47 n = len(space)
48 48 return [l[n:] if l.startswith(space) else l
49 49 for l in lines]
50 50
51 51 class PromptStripper:
52 52 """Remove matching input prompts from a block of input.
53 53
54 54 Parameters
55 55 ----------
56 56 prompt_re : regular expression
57 57 A regular expression matching any input prompt (including continuation,
58 58 e.g. ``...``)
59 59 initial_re : regular expression, optional
60 60 A regular expression matching only the initial prompt, but not continuation.
61 61 If no initial expression is given, prompt_re will be used everywhere.
62 62 Used mainly for plain Python prompts (``>>>``), where the continuation prompt
63 63 ``...`` is a valid Python expression in Python 3, so shouldn't be stripped.
64 64
65 65 Notes
66 66 -----
67 67
68 68 If initial_re and prompt_re differ,
69 69 only initial_re will be tested against the first line.
70 70 If any prompt is found on the first two lines,
71 71 prompts will be stripped from the rest of the block.
72 72 """
73 73 def __init__(self, prompt_re, initial_re=None):
74 74 self.prompt_re = prompt_re
75 75 self.initial_re = initial_re or prompt_re
76 76
77 77 def _strip(self, lines):
78 78 return [self.prompt_re.sub('', l, count=1) for l in lines]
79 79
80 80 def __call__(self, lines):
81 81 if not lines:
82 82 return lines
83 83 if self.initial_re.match(lines[0]) or \
84 84 (len(lines) > 1 and self.prompt_re.match(lines[1])):
85 85 return self._strip(lines)
86 86 return lines
87 87
88 88 classic_prompt = PromptStripper(
89 89 prompt_re=re.compile(r'^(>>>|\.\.\.)( |$)'),
90 90 initial_re=re.compile(r'^>>>( |$)')
91 91 )
92 92
93 93 ipython_prompt = PromptStripper(
94 94 re.compile(
95 95 r"""
96 96 ^( # Match from the beginning of a line, either:
97 97
98 98 # 1. First-line prompt:
99 99 ((\[nav\]|\[ins\])?\ )? # Vi editing mode prompt, if it's there
100 100 In\ # The 'In' of the prompt, with a space
101 101 \[\d+\]: # Command index, as displayed in the prompt
102 102 \ # With a mandatory trailing space
103 103
104 104 | # ... or ...
105 105
106 106 # 2. The three dots of the multiline prompt
107 107 \s* # All leading whitespace characters
108 108 \.{3,}: # The three (or more) dots
109 109 \ ? # With an optional trailing space
110 110
111 111 )
112 112 """,
113 113 re.VERBOSE,
114 114 )
115 115 )
116 116
117 117
118 118 def cell_magic(lines):
119 119 if not lines or not lines[0].startswith('%%'):
120 120 return lines
121 121 if re.match(r'%%\w+\?', lines[0]):
122 122 # This case will be handled by help_end
123 123 return lines
124 124 magic_name, _, first_line = lines[0][2:].rstrip().partition(' ')
125 125 body = ''.join(lines[1:])
126 126 return ['get_ipython().run_cell_magic(%r, %r, %r)\n'
127 127 % (magic_name, first_line, body)]
128 128
129 129
130 130 def _find_assign_op(token_line) -> Optional[int]:
131 131 """Get the index of the first assignment in the line ('=' not inside brackets)
132 132
133 133 Note: We don't try to support multiple special assignment (a = b = %foo)
134 134 """
135 135 paren_level = 0
136 136 for i, ti in enumerate(token_line):
137 137 s = ti.string
138 138 if s == '=' and paren_level == 0:
139 139 return i
140 140 if s in {'(','[','{'}:
141 141 paren_level += 1
142 142 elif s in {')', ']', '}'}:
143 143 if paren_level > 0:
144 144 paren_level -= 1
145 145 return None
146 146
147 147 def find_end_of_continued_line(lines, start_line: int):
148 148 """Find the last line of a line explicitly extended using backslashes.
149 149
150 150 Uses 0-indexed line numbers.
151 151 """
152 152 end_line = start_line
153 153 while lines[end_line].endswith('\\\n'):
154 154 end_line += 1
155 155 if end_line >= len(lines):
156 156 break
157 157 return end_line
158 158
159 159 def assemble_continued_line(lines, start: Tuple[int, int], end_line: int):
160 160 r"""Assemble a single line from multiple continued line pieces
161 161
162 162 Continued lines are lines ending in ``\``, and the line following the last
163 163 ``\`` in the block.
164 164
165 165 For example, this code continues over multiple lines::
166 166
167 167 if (assign_ix is not None) \
168 168 and (len(line) >= assign_ix + 2) \
169 169 and (line[assign_ix+1].string == '%') \
170 170 and (line[assign_ix+2].type == tokenize.NAME):
171 171
172 172 This statement contains four continued line pieces.
173 173 Assembling these pieces into a single line would give::
174 174
175 175 if (assign_ix is not None) and (len(line) >= assign_ix + 2) and (line[...
176 176
177 177 This uses 0-indexed line numbers. *start* is (lineno, colno).
178 178
179 179 Used to allow ``%magic`` and ``!system`` commands to be continued over
180 180 multiple lines.
181 181 """
182 182 parts = [lines[start[0]][start[1]:]] + lines[start[0]+1:end_line+1]
183 183 return ' '.join([p.rstrip()[:-1] for p in parts[:-1]] # Strip backslash+newline
184 184 + [parts[-1].rstrip()]) # Strip newline from last line
185 185
186 186 class TokenTransformBase:
187 187 """Base class for transformations which examine tokens.
188 188
189 189 Special syntax should not be transformed when it occurs inside strings or
190 190 comments. This is hard to reliably avoid with regexes. The solution is to
191 191 tokenise the code as Python, and recognise the special syntax in the tokens.
192 192
193 193 IPython's special syntax is not valid Python syntax, so tokenising may go
194 194 wrong after the special syntax starts. These classes therefore find and
195 195 transform *one* instance of special syntax at a time into regular Python
196 196 syntax. After each transformation, tokens are regenerated to find the next
197 197 piece of special syntax.
198 198
199 199 Subclasses need to implement one class method (find)
200 200 and one regular method (transform).
201 201
202 202 The priority attribute can select which transformation to apply if multiple
203 203 transformers match in the same place. Lower numbers have higher priority.
204 204 This allows "%magic?" to be turned into a help call rather than a magic call.
205 205 """
206 206 # Lower numbers -> higher priority (for matches in the same location)
207 207 priority = 10
208 208
209 209 def sortby(self):
210 210 return self.start_line, self.start_col, self.priority
211 211
212 212 def __init__(self, start):
213 213 self.start_line = start[0] - 1 # Shift from 1-index to 0-index
214 214 self.start_col = start[1]
215 215
216 216 @classmethod
217 217 def find(cls, tokens_by_line):
218 218 """Find one instance of special syntax in the provided tokens.
219 219
220 220 Tokens are grouped into logical lines for convenience,
221 221 so it is easy to e.g. look at the first token of each line.
222 222 *tokens_by_line* is a list of lists of tokenize.TokenInfo objects.
223 223
224 224 This should return an instance of its class, pointing to the start
225 225 position it has found, or None if it found no match.
226 226 """
227 227 raise NotImplementedError
228 228
229 229 def transform(self, lines: List[str]):
230 230 """Transform one instance of special syntax found by ``find()``
231 231
232 232 Takes a list of strings representing physical lines,
233 233 returns a similar list of transformed lines.
234 234 """
235 235 raise NotImplementedError
236 236
237 237 class MagicAssign(TokenTransformBase):
238 238 """Transformer for assignments from magics (a = %foo)"""
239 239 @classmethod
240 240 def find(cls, tokens_by_line):
241 241 """Find the first magic assignment (a = %foo) in the cell.
242 242 """
243 243 for line in tokens_by_line:
244 244 assign_ix = _find_assign_op(line)
245 245 if (assign_ix is not None) \
246 246 and (len(line) >= assign_ix + 2) \
247 247 and (line[assign_ix+1].string == '%') \
248 248 and (line[assign_ix+2].type == tokenize.NAME):
249 249 return cls(line[assign_ix+1].start)
250 250
251 251 def transform(self, lines: List[str]):
252 252 """Transform a magic assignment found by the ``find()`` classmethod.
253 253 """
254 254 start_line, start_col = self.start_line, self.start_col
255 255 lhs = lines[start_line][:start_col]
256 256 end_line = find_end_of_continued_line(lines, start_line)
257 257 rhs = assemble_continued_line(lines, (start_line, start_col), end_line)
258 258 assert rhs.startswith('%'), rhs
259 259 magic_name, _, args = rhs[1:].partition(' ')
260 260
261 261 lines_before = lines[:start_line]
262 262 call = "get_ipython().run_line_magic({!r}, {!r})".format(magic_name, args)
263 263 new_line = lhs + call + '\n'
264 264 lines_after = lines[end_line+1:]
265 265
266 266 return lines_before + [new_line] + lines_after
267 267
268 268
269 269 class SystemAssign(TokenTransformBase):
270 270 """Transformer for assignments from system commands (a = !foo)"""
271 271 @classmethod
272 272 def find(cls, tokens_by_line):
273 273 """Find the first system assignment (a = !foo) in the cell.
274 274 """
275 275 for line in tokens_by_line:
276 276 assign_ix = _find_assign_op(line)
277 277 if (assign_ix is not None) \
278 278 and not line[assign_ix].line.strip().startswith('=') \
279 279 and (len(line) >= assign_ix + 2) \
280 280 and (line[assign_ix + 1].type == tokenize.ERRORTOKEN):
281 281 ix = assign_ix + 1
282 282
283 283 while ix < len(line) and line[ix].type == tokenize.ERRORTOKEN:
284 284 if line[ix].string == '!':
285 285 return cls(line[ix].start)
286 286 elif not line[ix].string.isspace():
287 287 break
288 288 ix += 1
289 289
290 290 def transform(self, lines: List[str]):
291 291 """Transform a system assignment found by the ``find()`` classmethod.
292 292 """
293 293 start_line, start_col = self.start_line, self.start_col
294 294
295 295 lhs = lines[start_line][:start_col]
296 296 end_line = find_end_of_continued_line(lines, start_line)
297 297 rhs = assemble_continued_line(lines, (start_line, start_col), end_line)
298 298 assert rhs.startswith('!'), rhs
299 299 cmd = rhs[1:]
300 300
301 301 lines_before = lines[:start_line]
302 302 call = "get_ipython().getoutput({!r})".format(cmd)
303 303 new_line = lhs + call + '\n'
304 304 lines_after = lines[end_line + 1:]
305 305
306 306 return lines_before + [new_line] + lines_after
307 307
308 308 # The escape sequences that define the syntax transformations IPython will
309 309 # apply to user input. These can NOT be just changed here: many regular
310 310 # expressions and other parts of the code may use their hardcoded values, and
311 311 # for all intents and purposes they constitute the 'IPython syntax', so they
312 312 # should be considered fixed.
313 313
314 314 ESC_SHELL = '!' # Send line to underlying system shell
315 315 ESC_SH_CAP = '!!' # Send line to system shell and capture output
316 316 ESC_HELP = '?' # Find information about object
317 317 ESC_HELP2 = '??' # Find extra-detailed information about object
318 318 ESC_MAGIC = '%' # Call magic function
319 319 ESC_MAGIC2 = '%%' # Call cell-magic function
320 320 ESC_QUOTE = ',' # Split args on whitespace, quote each as string and call
321 321 ESC_QUOTE2 = ';' # Quote all args as a single string, call
322 322 ESC_PAREN = '/' # Call first argument with rest of line as arguments
323 323
324 324 ESCAPE_SINGLES = {'!', '?', '%', ',', ';', '/'}
325 325 ESCAPE_DOUBLES = {'!!', '??'} # %% (cell magic) is handled separately
326 326
327 327 def _make_help_call(target, esc):
328 328 """Prepares a pinfo(2)/psearch call from a target name and the escape
329 329 (i.e. ? or ??)"""
330 330 method = 'pinfo2' if esc == '??' \
331 331 else 'psearch' if '*' in target \
332 332 else 'pinfo'
333 333 arg = " ".join([method, target])
334 334 #Prepare arguments for get_ipython().run_line_magic(magic_name, magic_args)
335 335 t_magic_name, _, t_magic_arg_s = arg.partition(' ')
336 336 t_magic_name = t_magic_name.lstrip(ESC_MAGIC)
337 337 return "get_ipython().run_line_magic(%r, %r)" % (t_magic_name, t_magic_arg_s)
338 338
339 339
340 340 def _tr_help(content):
341 341 """Translate lines escaped with: ?
342 342
343 343 A naked help line should fire the intro help screen (shell.show_usage())
344 344 """
345 345 if not content:
346 346 return 'get_ipython().show_usage()'
347 347
348 348 return _make_help_call(content, '?')
349 349
350 350 def _tr_help2(content):
351 351 """Translate lines escaped with: ??
352 352
353 353 A naked help line should fire the intro help screen (shell.show_usage())
354 354 """
355 355 if not content:
356 356 return 'get_ipython().show_usage()'
357 357
358 358 return _make_help_call(content, '??')
359 359
360 360 def _tr_magic(content):
361 361 "Translate lines escaped with a percent sign: %"
362 362 name, _, args = content.partition(' ')
363 363 return 'get_ipython().run_line_magic(%r, %r)' % (name, args)
364 364
365 365 def _tr_quote(content):
366 366 "Translate lines escaped with a comma: ,"
367 367 name, _, args = content.partition(' ')
368 368 return '%s("%s")' % (name, '", "'.join(args.split()) )
369 369
370 370 def _tr_quote2(content):
371 371 "Translate lines escaped with a semicolon: ;"
372 372 name, _, args = content.partition(' ')
373 373 return '%s("%s")' % (name, args)
374 374
375 375 def _tr_paren(content):
376 376 "Translate lines escaped with a slash: /"
377 377 name, _, args = content.partition(' ')
378 378 return '%s(%s)' % (name, ", ".join(args.split()))
379 379
380 380 tr = { ESC_SHELL : 'get_ipython().system({!r})'.format,
381 381 ESC_SH_CAP : 'get_ipython().getoutput({!r})'.format,
382 382 ESC_HELP : _tr_help,
383 383 ESC_HELP2 : _tr_help2,
384 384 ESC_MAGIC : _tr_magic,
385 385 ESC_QUOTE : _tr_quote,
386 386 ESC_QUOTE2 : _tr_quote2,
387 387 ESC_PAREN : _tr_paren }
388 388
389 389 class EscapedCommand(TokenTransformBase):
390 390 """Transformer for escaped commands like %foo, !foo, or /foo"""
391 391 @classmethod
392 392 def find(cls, tokens_by_line):
393 393 """Find the first escaped command (%foo, !foo, etc.) in the cell.
394 394 """
395 395 for line in tokens_by_line:
396 396 if not line:
397 397 continue
398 398 ix = 0
399 399 ll = len(line)
400 400 while ll > ix and line[ix].type in {tokenize.INDENT, tokenize.DEDENT}:
401 401 ix += 1
402 402 if ix >= ll:
403 403 continue
404 404 if line[ix].string in ESCAPE_SINGLES:
405 405 return cls(line[ix].start)
406 406
407 407 def transform(self, lines):
408 408 """Transform an escaped line found by the ``find()`` classmethod.
409 409 """
410 410 start_line, start_col = self.start_line, self.start_col
411 411
412 412 indent = lines[start_line][:start_col]
413 413 end_line = find_end_of_continued_line(lines, start_line)
414 414 line = assemble_continued_line(lines, (start_line, start_col), end_line)
415 415
416 416 if len(line) > 1 and line[:2] in ESCAPE_DOUBLES:
417 417 escape, content = line[:2], line[2:]
418 418 else:
419 419 escape, content = line[:1], line[1:]
420 420
421 421 if escape in tr:
422 422 call = tr[escape](content)
423 423 else:
424 424 call = ''
425 425
426 426 lines_before = lines[:start_line]
427 427 new_line = indent + call + '\n'
428 428 lines_after = lines[end_line + 1:]
429 429
430 430 return lines_before + [new_line] + lines_after
431 431
432 432
433 433 _help_end_re = re.compile(
434 434 r"""(%{0,2}
435 (?!\d)[\w*]+ # Variable name
436 (\.(?!\d)[\w*]+|\[[0-9]+\])* # .etc.etc or [0], we only support literal integers.
437 )
438 (\?\??)$ # ? or ??
439 """,
440 re.VERBOSE)
435 (?!\d)[\w*]+ # Variable name
436 (\.(?!\d)[\w*]+|\[-?[0-9]+\])* # .etc.etc or [0], we only support literal integers.
437 )
438 (\?\??)$ # ? or ??
439 """,
440 re.VERBOSE,
441 )
442
441 443
442 444 class HelpEnd(TokenTransformBase):
443 445 """Transformer for help syntax: obj? and obj??"""
444 446 # This needs to be higher priority (lower number) than EscapedCommand so
445 447 # that inspecting magics (%foo?) works.
446 448 priority = 5
447 449
448 450 def __init__(self, start, q_locn):
449 451 super().__init__(start)
450 452 self.q_line = q_locn[0] - 1 # Shift from 1-indexed to 0-indexed
451 453 self.q_col = q_locn[1]
452 454
453 455 @classmethod
454 456 def find(cls, tokens_by_line):
455 457 """Find the first help command (foo?) in the cell.
456 458 """
457 459 for line in tokens_by_line:
458 460 # Last token is NEWLINE; look at last but one
459 461 if len(line) > 2 and line[-2].string == '?':
460 462 # Find the first token that's not INDENT/DEDENT
461 463 ix = 0
462 464 while line[ix].type in {tokenize.INDENT, tokenize.DEDENT}:
463 465 ix += 1
464 466 return cls(line[ix].start, line[-2].start)
465 467
466 468 def transform(self, lines):
467 469 """Transform a help command found by the ``find()`` classmethod.
468 470 """
469 471
470 472 piece = "".join(lines[self.start_line : self.q_line + 1])
471 473 indent, content = piece[: self.start_col], piece[self.start_col :]
472 474 lines_before = lines[: self.start_line]
473 475 lines_after = lines[self.q_line + 1 :]
474 476
475 477 m = _help_end_re.search(content)
476 478 if not m:
477 479 raise SyntaxError(content)
478 480 assert m is not None, content
479 481 target = m.group(1)
480 482 esc = m.group(3)
481 483
482 484
483 485 call = _make_help_call(target, esc)
484 486 new_line = indent + call + '\n'
485 487
486 488 return lines_before + [new_line] + lines_after
487 489
488 490 def make_tokens_by_line(lines:List[str]):
489 491 """Tokenize a series of lines and group tokens by line.
490 492
491 493 The tokens for a multiline Python string or expression are grouped as one
492 494 line. All lines except the last lines should keep their line ending ('\\n',
493 495 '\\r\\n') for this to properly work. Use `.splitlines(keeplineending=True)`
494 496 for example when passing block of text to this function.
495 497
496 498 """
497 499 # NL tokens are used inside multiline expressions, but also after blank
498 500 # lines or comments. This is intentional - see https://bugs.python.org/issue17061
499 501 # We want to group the former case together but split the latter, so we
500 502 # track parentheses level, similar to the internals of tokenize.
501 503
502 504 # reexported from token on 3.7+
503 505 NEWLINE, NL = tokenize.NEWLINE, tokenize.NL # type: ignore
504 506 tokens_by_line: List[List[Any]] = [[]]
505 507 if len(lines) > 1 and not lines[0].endswith(("\n", "\r", "\r\n", "\x0b", "\x0c")):
506 508 warnings.warn(
507 509 "`make_tokens_by_line` received a list of lines which do not have lineending markers ('\\n', '\\r', '\\r\\n', '\\x0b', '\\x0c'), behavior will be unspecified",
508 510 stacklevel=2,
509 511 )
510 512 parenlev = 0
511 513 try:
512 514 for token in tokenize.generate_tokens(iter(lines).__next__):
513 515 tokens_by_line[-1].append(token)
514 516 if (token.type == NEWLINE) \
515 517 or ((token.type == NL) and (parenlev <= 0)):
516 518 tokens_by_line.append([])
517 519 elif token.string in {'(', '[', '{'}:
518 520 parenlev += 1
519 521 elif token.string in {')', ']', '}'}:
520 522 if parenlev > 0:
521 523 parenlev -= 1
522 524 except tokenize.TokenError:
523 525 # Input ended in a multiline string or expression. That's OK for us.
524 526 pass
525 527
526 528
527 529 if not tokens_by_line[-1]:
528 530 tokens_by_line.pop()
529 531
530 532
531 533 return tokens_by_line
532 534
533 535
534 536 def has_sunken_brackets(tokens: List[tokenize.TokenInfo]):
535 537 """Check if the depth of brackets in the list of tokens drops below 0"""
536 538 parenlev = 0
537 539 for token in tokens:
538 540 if token.string in {"(", "[", "{"}:
539 541 parenlev += 1
540 542 elif token.string in {")", "]", "}"}:
541 543 parenlev -= 1
542 544 if parenlev < 0:
543 545 return True
544 546 return False
545 547
546 548
547 549 def show_linewise_tokens(s: str):
548 550 """For investigation and debugging"""
549 551 warnings.warn(
550 552 "show_linewise_tokens is deprecated since IPython 8.6",
551 553 DeprecationWarning,
552 554 stacklevel=2,
553 555 )
554 556 if not s.endswith("\n"):
555 557 s += "\n"
556 558 lines = s.splitlines(keepends=True)
557 559 for line in make_tokens_by_line(lines):
558 560 print("Line -------")
559 561 for tokinfo in line:
560 562 print(" ", tokinfo)
561 563
562 564 # Arbitrary limit to prevent getting stuck in infinite loops
563 565 TRANSFORM_LOOP_LIMIT = 500
564 566
565 567 class TransformerManager:
566 568 """Applies various transformations to a cell or code block.
567 569
568 570 The key methods for external use are ``transform_cell()``
569 571 and ``check_complete()``.
570 572 """
571 573 def __init__(self):
572 574 self.cleanup_transforms = [
573 575 leading_empty_lines,
574 576 leading_indent,
575 577 classic_prompt,
576 578 ipython_prompt,
577 579 ]
578 580 self.line_transforms = [
579 581 cell_magic,
580 582 ]
581 583 self.token_transformers = [
582 584 MagicAssign,
583 585 SystemAssign,
584 586 EscapedCommand,
585 587 HelpEnd,
586 588 ]
587 589
588 590 def do_one_token_transform(self, lines):
589 591 """Find and run the transform earliest in the code.
590 592
591 593 Returns (changed, lines).
592 594
593 595 This method is called repeatedly until changed is False, indicating
594 596 that all available transformations are complete.
595 597
596 598 The tokens following IPython special syntax might not be valid, so
597 599 the transformed code is retokenised every time to identify the next
598 600 piece of special syntax. Hopefully long code cells are mostly valid
599 601 Python, not using lots of IPython special syntax, so this shouldn't be
600 602 a performance issue.
601 603 """
602 604 tokens_by_line = make_tokens_by_line(lines)
603 605 candidates = []
604 606 for transformer_cls in self.token_transformers:
605 607 transformer = transformer_cls.find(tokens_by_line)
606 608 if transformer:
607 609 candidates.append(transformer)
608 610
609 611 if not candidates:
610 612 # Nothing to transform
611 613 return False, lines
612 614 ordered_transformers = sorted(candidates, key=TokenTransformBase.sortby)
613 615 for transformer in ordered_transformers:
614 616 try:
615 617 return True, transformer.transform(lines)
616 618 except SyntaxError:
617 619 pass
618 620 return False, lines
619 621
620 622 def do_token_transforms(self, lines):
621 623 for _ in range(TRANSFORM_LOOP_LIMIT):
622 624 changed, lines = self.do_one_token_transform(lines)
623 625 if not changed:
624 626 return lines
625 627
626 628 raise RuntimeError("Input transformation still changing after "
627 629 "%d iterations. Aborting." % TRANSFORM_LOOP_LIMIT)
628 630
629 631 def transform_cell(self, cell: str) -> str:
630 632 """Transforms a cell of input code"""
631 633 if not cell.endswith('\n'):
632 634 cell += '\n' # Ensure the cell has a trailing newline
633 635 lines = cell.splitlines(keepends=True)
634 636 for transform in self.cleanup_transforms + self.line_transforms:
635 637 lines = transform(lines)
636 638
637 639 lines = self.do_token_transforms(lines)
638 640 return ''.join(lines)
639 641
640 642 def check_complete(self, cell: str):
641 643 """Return whether a block of code is ready to execute, or should be continued
642 644
643 645 Parameters
644 646 ----------
645 647 cell : string
646 648 Python input code, which can be multiline.
647 649
648 650 Returns
649 651 -------
650 652 status : str
651 653 One of 'complete', 'incomplete', or 'invalid' if source is not a
652 654 prefix of valid code.
653 655 indent_spaces : int or None
654 656 The number of spaces by which to indent the next line of code. If
655 657 status is not 'incomplete', this is None.
656 658 """
657 659 # Remember if the lines ends in a new line.
658 660 ends_with_newline = False
659 661 for character in reversed(cell):
660 662 if character == '\n':
661 663 ends_with_newline = True
662 664 break
663 665 elif character.strip():
664 666 break
665 667 else:
666 668 continue
667 669
668 670 if not ends_with_newline:
669 671 # Append an newline for consistent tokenization
670 672 # See https://bugs.python.org/issue33899
671 673 cell += '\n'
672 674
673 675 lines = cell.splitlines(keepends=True)
674 676
675 677 if not lines:
676 678 return 'complete', None
677 679
678 680 if lines[-1].endswith('\\'):
679 681 # Explicit backslash continuation
680 682 return 'incomplete', find_last_indent(lines)
681 683
682 684 try:
683 685 for transform in self.cleanup_transforms:
684 686 if not getattr(transform, 'has_side_effects', False):
685 687 lines = transform(lines)
686 688 except SyntaxError:
687 689 return 'invalid', None
688 690
689 691 if lines[0].startswith('%%'):
690 692 # Special case for cell magics - completion marked by blank line
691 693 if lines[-1].strip():
692 694 return 'incomplete', find_last_indent(lines)
693 695 else:
694 696 return 'complete', None
695 697
696 698 try:
697 699 for transform in self.line_transforms:
698 700 if not getattr(transform, 'has_side_effects', False):
699 701 lines = transform(lines)
700 702 lines = self.do_token_transforms(lines)
701 703 except SyntaxError:
702 704 return 'invalid', None
703 705
704 706 tokens_by_line = make_tokens_by_line(lines)
705 707
706 708 # Bail if we got one line and there are more closing parentheses than
707 709 # the opening ones
708 710 if (
709 711 len(lines) == 1
710 712 and tokens_by_line
711 713 and has_sunken_brackets(tokens_by_line[0])
712 714 ):
713 715 return "invalid", None
714 716
715 717 if not tokens_by_line:
716 718 return 'incomplete', find_last_indent(lines)
717 719
718 720 if tokens_by_line[-1][-1].type != tokenize.ENDMARKER:
719 721 # We're in a multiline string or expression
720 722 return 'incomplete', find_last_indent(lines)
721 723
722 724 newline_types = {tokenize.NEWLINE, tokenize.COMMENT, tokenize.ENDMARKER} # type: ignore
723 725
724 726 # Pop the last line which only contains DEDENTs and ENDMARKER
725 727 last_token_line = None
726 728 if {t.type for t in tokens_by_line[-1]} in [
727 729 {tokenize.DEDENT, tokenize.ENDMARKER},
728 730 {tokenize.ENDMARKER}
729 731 ] and len(tokens_by_line) > 1:
730 732 last_token_line = tokens_by_line.pop()
731 733
732 734 while tokens_by_line[-1] and tokens_by_line[-1][-1].type in newline_types:
733 735 tokens_by_line[-1].pop()
734 736
735 737 if not tokens_by_line[-1]:
736 738 return 'incomplete', find_last_indent(lines)
737 739
738 740 if tokens_by_line[-1][-1].string == ':':
739 741 # The last line starts a block (e.g. 'if foo:')
740 742 ix = 0
741 743 while tokens_by_line[-1][ix].type in {tokenize.INDENT, tokenize.DEDENT}:
742 744 ix += 1
743 745
744 746 indent = tokens_by_line[-1][ix].start[1]
745 747 return 'incomplete', indent + 4
746 748
747 749 if tokens_by_line[-1][0].line.endswith('\\'):
748 750 return 'incomplete', None
749 751
750 752 # At this point, our checks think the code is complete (or invalid).
751 753 # We'll use codeop.compile_command to check this with the real parser
752 754 try:
753 755 with warnings.catch_warnings():
754 756 warnings.simplefilter('error', SyntaxWarning)
755 757 res = compile_command(''.join(lines), symbol='exec')
756 758 except (SyntaxError, OverflowError, ValueError, TypeError,
757 759 MemoryError, SyntaxWarning):
758 760 return 'invalid', None
759 761 else:
760 762 if res is None:
761 763 return 'incomplete', find_last_indent(lines)
762 764
763 765 if last_token_line and last_token_line[0].type == tokenize.DEDENT:
764 766 if ends_with_newline:
765 767 return 'complete', None
766 768 return 'incomplete', find_last_indent(lines)
767 769
768 770 # If there's a blank line at the end, assume we're ready to execute
769 771 if not lines[-1].strip():
770 772 return 'complete', None
771 773
772 774 return 'complete', None
773 775
774 776
775 777 def find_last_indent(lines):
776 778 m = _indent_re.match(lines[-1])
777 779 if not m:
778 780 return 0
779 781 return len(m.group(0).replace('\t', ' '*4))
780 782
781 783
782 784 class MaybeAsyncCompile(Compile):
783 785 def __init__(self, extra_flags=0):
784 786 super().__init__()
785 787 self.flags |= extra_flags
786 788
787 789
788 790 class MaybeAsyncCommandCompiler(CommandCompiler):
789 791 def __init__(self, extra_flags=0):
790 792 self.compiler = MaybeAsyncCompile(extra_flags=extra_flags)
791 793
792 794
793 795 _extra_flags = ast.PyCF_ALLOW_TOP_LEVEL_AWAIT
794 796
795 797 compile_command = MaybeAsyncCommandCompiler(extra_flags=_extra_flags)
@@ -1,3809 +1,3820 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Main IPython class."""
3 3
4 4 #-----------------------------------------------------------------------------
5 5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
6 6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
7 7 # Copyright (C) 2008-2011 The IPython Development Team
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13
14 14 import abc
15 15 import ast
16 16 import atexit
17 17 import bdb
18 18 import builtins as builtin_mod
19 19 import functools
20 20 import inspect
21 21 import os
22 22 import re
23 23 import runpy
24 24 import subprocess
25 25 import sys
26 26 import tempfile
27 27 import traceback
28 28 import types
29 29 import warnings
30 30 from ast import stmt
31 31 from io import open as io_open
32 32 from logging import error
33 33 from pathlib import Path
34 34 from typing import Callable
35 35 from typing import List as ListType
36 36 from typing import Optional, Tuple
37 37 from warnings import warn
38 38
39 39 from pickleshare import PickleShareDB
40 40 from tempfile import TemporaryDirectory
41 41 from traitlets import (
42 42 Any,
43 43 Bool,
44 44 CaselessStrEnum,
45 45 Dict,
46 46 Enum,
47 47 Instance,
48 48 Integer,
49 49 List,
50 50 Type,
51 51 Unicode,
52 52 default,
53 53 observe,
54 54 validate,
55 55 )
56 56 from traitlets.config.configurable import SingletonConfigurable
57 57 from traitlets.utils.importstring import import_item
58 58
59 59 import IPython.core.hooks
60 60 from IPython.core import magic, oinspect, page, prefilter, ultratb
61 61 from IPython.core.alias import Alias, AliasManager
62 62 from IPython.core.autocall import ExitAutocall
63 63 from IPython.core.builtin_trap import BuiltinTrap
64 64 from IPython.core.compilerop import CachingCompiler, check_linecache_ipython
65 65 from IPython.core.debugger import InterruptiblePdb
66 66 from IPython.core.display_trap import DisplayTrap
67 67 from IPython.core.displayhook import DisplayHook
68 68 from IPython.core.displaypub import DisplayPublisher
69 69 from IPython.core.error import InputRejected, UsageError
70 70 from IPython.core.events import EventManager, available_events
71 71 from IPython.core.extensions import ExtensionManager
72 72 from IPython.core.formatters import DisplayFormatter
73 73 from IPython.core.history import HistoryManager
74 74 from IPython.core.inputtransformer2 import ESC_MAGIC, ESC_MAGIC2
75 75 from IPython.core.logger import Logger
76 76 from IPython.core.macro import Macro
77 77 from IPython.core.payload import PayloadManager
78 78 from IPython.core.prefilter import PrefilterManager
79 79 from IPython.core.profiledir import ProfileDir
80 80 from IPython.core.usage import default_banner
81 81 from IPython.display import display
82 82 from IPython.paths import get_ipython_dir
83 83 from IPython.testing.skipdoctest import skip_doctest
84 84 from IPython.utils import PyColorize, io, openpy, py3compat
85 85 from IPython.utils.decorators import undoc
86 86 from IPython.utils.io import ask_yes_no
87 87 from IPython.utils.ipstruct import Struct
88 88 from IPython.utils.path import ensure_dir_exists, get_home_dir, get_py_filename
89 89 from IPython.utils.process import getoutput, system
90 90 from IPython.utils.strdispatch import StrDispatch
91 91 from IPython.utils.syspathcontext import prepended_to_syspath
92 92 from IPython.utils.text import DollarFormatter, LSString, SList, format_screen
93 93
94 94 sphinxify: Optional[Callable]
95 95
96 96 try:
97 97 import docrepr.sphinxify as sphx
98 98
99 99 def sphinxify(oinfo):
100 100 wrapped_docstring = sphx.wrap_main_docstring(oinfo)
101 101
102 102 def sphinxify_docstring(docstring):
103 103 with TemporaryDirectory() as dirname:
104 104 return {
105 105 "text/html": sphx.sphinxify(wrapped_docstring, dirname),
106 106 "text/plain": docstring,
107 107 }
108 108
109 109 return sphinxify_docstring
110 110 except ImportError:
111 111 sphinxify = None
112 112
113 113
114 114 class ProvisionalWarning(DeprecationWarning):
115 115 """
116 116 Warning class for unstable features
117 117 """
118 118 pass
119 119
120 120 from ast import Module
121 121
122 122 _assign_nodes = (ast.AugAssign, ast.AnnAssign, ast.Assign)
123 123 _single_targets_nodes = (ast.AugAssign, ast.AnnAssign)
124 124
125 125 #-----------------------------------------------------------------------------
126 126 # Await Helpers
127 127 #-----------------------------------------------------------------------------
128 128
129 129 # we still need to run things using the asyncio eventloop, but there is no
130 130 # async integration
131 131 from .async_helpers import (
132 132 _asyncio_runner,
133 133 _curio_runner,
134 134 _pseudo_sync_runner,
135 135 _should_be_async,
136 136 _trio_runner,
137 137 )
138 138
139 139 #-----------------------------------------------------------------------------
140 140 # Globals
141 141 #-----------------------------------------------------------------------------
142 142
143 143 # compiled regexps for autoindent management
144 144 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
145 145
146 146 #-----------------------------------------------------------------------------
147 147 # Utilities
148 148 #-----------------------------------------------------------------------------
149 149
150 def is_integer_string(s:str):
151 """
152 Variant of "str.isnumeric()" that allow negative values and other ints.
153 """
154 try:
155 int(s)
156 return True
157 except ValueError:
158 return False
159 raise ValueError('Unexpected error')
160
150 161 @undoc
151 162 def softspace(file, newvalue):
152 163 """Copied from code.py, to remove the dependency"""
153 164
154 165 oldvalue = 0
155 166 try:
156 167 oldvalue = file.softspace
157 168 except AttributeError:
158 169 pass
159 170 try:
160 171 file.softspace = newvalue
161 172 except (AttributeError, TypeError):
162 173 # "attribute-less object" or "read-only attributes"
163 174 pass
164 175 return oldvalue
165 176
166 177 @undoc
167 178 def no_op(*a, **kw):
168 179 pass
169 180
170 181
171 182 class SpaceInInput(Exception): pass
172 183
173 184
174 185 class SeparateUnicode(Unicode):
175 186 r"""A Unicode subclass to validate separate_in, separate_out, etc.
176 187
177 188 This is a Unicode based trait that converts '0'->'' and ``'\\n'->'\n'``.
178 189 """
179 190
180 191 def validate(self, obj, value):
181 192 if value == '0': value = ''
182 193 value = value.replace('\\n','\n')
183 194 return super(SeparateUnicode, self).validate(obj, value)
184 195
185 196
186 197 @undoc
187 198 class DummyMod(object):
188 199 """A dummy module used for IPython's interactive module when
189 200 a namespace must be assigned to the module's __dict__."""
190 201 __spec__ = None
191 202
192 203
193 204 class ExecutionInfo(object):
194 205 """The arguments used for a call to :meth:`InteractiveShell.run_cell`
195 206
196 207 Stores information about what is going to happen.
197 208 """
198 209 raw_cell = None
199 210 store_history = False
200 211 silent = False
201 212 shell_futures = True
202 213 cell_id = None
203 214
204 215 def __init__(self, raw_cell, store_history, silent, shell_futures, cell_id):
205 216 self.raw_cell = raw_cell
206 217 self.store_history = store_history
207 218 self.silent = silent
208 219 self.shell_futures = shell_futures
209 220 self.cell_id = cell_id
210 221
211 222 def __repr__(self):
212 223 name = self.__class__.__qualname__
213 224 raw_cell = (
214 225 (self.raw_cell[:50] + "..") if len(self.raw_cell) > 50 else self.raw_cell
215 226 )
216 227 return '<%s object at %x, raw_cell="%s" store_history=%s silent=%s shell_futures=%s cell_id=%s>' % (
217 228 name,
218 229 id(self),
219 230 raw_cell,
220 231 self.store_history,
221 232 self.silent,
222 233 self.shell_futures,
223 234 self.cell_id,
224 235 )
225 236
226 237
227 238 class ExecutionResult(object):
228 239 """The result of a call to :meth:`InteractiveShell.run_cell`
229 240
230 241 Stores information about what took place.
231 242 """
232 243 execution_count = None
233 244 error_before_exec = None
234 245 error_in_exec: Optional[BaseException] = None
235 246 info = None
236 247 result = None
237 248
238 249 def __init__(self, info):
239 250 self.info = info
240 251
241 252 @property
242 253 def success(self):
243 254 return (self.error_before_exec is None) and (self.error_in_exec is None)
244 255
245 256 def raise_error(self):
246 257 """Reraises error if `success` is `False`, otherwise does nothing"""
247 258 if self.error_before_exec is not None:
248 259 raise self.error_before_exec
249 260 if self.error_in_exec is not None:
250 261 raise self.error_in_exec
251 262
252 263 def __repr__(self):
253 264 name = self.__class__.__qualname__
254 265 return '<%s object at %x, execution_count=%s error_before_exec=%s error_in_exec=%s info=%s result=%s>' %\
255 266 (name, id(self), self.execution_count, self.error_before_exec, self.error_in_exec, repr(self.info), repr(self.result))
256 267
257 268
258 269 class InteractiveShell(SingletonConfigurable):
259 270 """An enhanced, interactive shell for Python."""
260 271
261 272 _instance = None
262 273
263 274 ast_transformers = List([], help=
264 275 """
265 276 A list of ast.NodeTransformer subclass instances, which will be applied
266 277 to user input before code is run.
267 278 """
268 279 ).tag(config=True)
269 280
270 281 autocall = Enum((0,1,2), default_value=0, help=
271 282 """
272 283 Make IPython automatically call any callable object even if you didn't
273 284 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
274 285 automatically. The value can be '0' to disable the feature, '1' for
275 286 'smart' autocall, where it is not applied if there are no more
276 287 arguments on the line, and '2' for 'full' autocall, where all callable
277 288 objects are automatically called (even if no arguments are present).
278 289 """
279 290 ).tag(config=True)
280 291
281 292 autoindent = Bool(True, help=
282 293 """
283 294 Autoindent IPython code entered interactively.
284 295 """
285 296 ).tag(config=True)
286 297
287 298 autoawait = Bool(True, help=
288 299 """
289 300 Automatically run await statement in the top level repl.
290 301 """
291 302 ).tag(config=True)
292 303
293 304 loop_runner_map ={
294 305 'asyncio':(_asyncio_runner, True),
295 306 'curio':(_curio_runner, True),
296 307 'trio':(_trio_runner, True),
297 308 'sync': (_pseudo_sync_runner, False)
298 309 }
299 310
300 311 loop_runner = Any(default_value="IPython.core.interactiveshell._asyncio_runner",
301 312 allow_none=True,
302 313 help="""Select the loop runner that will be used to execute top-level asynchronous code"""
303 314 ).tag(config=True)
304 315
305 316 @default('loop_runner')
306 317 def _default_loop_runner(self):
307 318 return import_item("IPython.core.interactiveshell._asyncio_runner")
308 319
309 320 @validate('loop_runner')
310 321 def _import_runner(self, proposal):
311 322 if isinstance(proposal.value, str):
312 323 if proposal.value in self.loop_runner_map:
313 324 runner, autoawait = self.loop_runner_map[proposal.value]
314 325 self.autoawait = autoawait
315 326 return runner
316 327 runner = import_item(proposal.value)
317 328 if not callable(runner):
318 329 raise ValueError('loop_runner must be callable')
319 330 return runner
320 331 if not callable(proposal.value):
321 332 raise ValueError('loop_runner must be callable')
322 333 return proposal.value
323 334
324 335 automagic = Bool(True, help=
325 336 """
326 337 Enable magic commands to be called without the leading %.
327 338 """
328 339 ).tag(config=True)
329 340
330 341 banner1 = Unicode(default_banner,
331 342 help="""The part of the banner to be printed before the profile"""
332 343 ).tag(config=True)
333 344 banner2 = Unicode('',
334 345 help="""The part of the banner to be printed after the profile"""
335 346 ).tag(config=True)
336 347
337 348 cache_size = Integer(1000, help=
338 349 """
339 350 Set the size of the output cache. The default is 1000, you can
340 351 change it permanently in your config file. Setting it to 0 completely
341 352 disables the caching system, and the minimum value accepted is 3 (if
342 353 you provide a value less than 3, it is reset to 0 and a warning is
343 354 issued). This limit is defined because otherwise you'll spend more
344 355 time re-flushing a too small cache than working
345 356 """
346 357 ).tag(config=True)
347 358 color_info = Bool(True, help=
348 359 """
349 360 Use colors for displaying information about objects. Because this
350 361 information is passed through a pager (like 'less'), and some pagers
351 362 get confused with color codes, this capability can be turned off.
352 363 """
353 364 ).tag(config=True)
354 365 colors = CaselessStrEnum(('Neutral', 'NoColor','LightBG','Linux'),
355 366 default_value='Neutral',
356 367 help="Set the color scheme (NoColor, Neutral, Linux, or LightBG)."
357 368 ).tag(config=True)
358 369 debug = Bool(False).tag(config=True)
359 370 disable_failing_post_execute = Bool(False,
360 371 help="Don't call post-execute functions that have failed in the past."
361 372 ).tag(config=True)
362 373 display_formatter = Instance(DisplayFormatter, allow_none=True)
363 374 displayhook_class = Type(DisplayHook)
364 375 display_pub_class = Type(DisplayPublisher)
365 376 compiler_class = Type(CachingCompiler)
366 377
367 378 sphinxify_docstring = Bool(False, help=
368 379 """
369 380 Enables rich html representation of docstrings. (This requires the
370 381 docrepr module).
371 382 """).tag(config=True)
372 383
373 384 @observe("sphinxify_docstring")
374 385 def _sphinxify_docstring_changed(self, change):
375 386 if change['new']:
376 387 warn("`sphinxify_docstring` is provisional since IPython 5.0 and might change in future versions." , ProvisionalWarning)
377 388
378 389 enable_html_pager = Bool(False, help=
379 390 """
380 391 (Provisional API) enables html representation in mime bundles sent
381 392 to pagers.
382 393 """).tag(config=True)
383 394
384 395 @observe("enable_html_pager")
385 396 def _enable_html_pager_changed(self, change):
386 397 if change['new']:
387 398 warn("`enable_html_pager` is provisional since IPython 5.0 and might change in future versions.", ProvisionalWarning)
388 399
389 400 data_pub_class = None
390 401
391 402 exit_now = Bool(False)
392 403 exiter = Instance(ExitAutocall)
393 404 @default('exiter')
394 405 def _exiter_default(self):
395 406 return ExitAutocall(self)
396 407 # Monotonically increasing execution counter
397 408 execution_count = Integer(1)
398 409 filename = Unicode("<ipython console>")
399 410 ipython_dir= Unicode('').tag(config=True) # Set to get_ipython_dir() in __init__
400 411
401 412 # Used to transform cells before running them, and check whether code is complete
402 413 input_transformer_manager = Instance('IPython.core.inputtransformer2.TransformerManager',
403 414 ())
404 415
405 416 @property
406 417 def input_transformers_cleanup(self):
407 418 return self.input_transformer_manager.cleanup_transforms
408 419
409 420 input_transformers_post = List([],
410 421 help="A list of string input transformers, to be applied after IPython's "
411 422 "own input transformations."
412 423 )
413 424
414 425 @property
415 426 def input_splitter(self):
416 427 """Make this available for backward compatibility (pre-7.0 release) with existing code.
417 428
418 429 For example, ipykernel ipykernel currently uses
419 430 `shell.input_splitter.check_complete`
420 431 """
421 432 from warnings import warn
422 433 warn("`input_splitter` is deprecated since IPython 7.0, prefer `input_transformer_manager`.",
423 434 DeprecationWarning, stacklevel=2
424 435 )
425 436 return self.input_transformer_manager
426 437
427 438 logstart = Bool(False, help=
428 439 """
429 440 Start logging to the default log file in overwrite mode.
430 441 Use `logappend` to specify a log file to **append** logs to.
431 442 """
432 443 ).tag(config=True)
433 444 logfile = Unicode('', help=
434 445 """
435 446 The name of the logfile to use.
436 447 """
437 448 ).tag(config=True)
438 449 logappend = Unicode('', help=
439 450 """
440 451 Start logging to the given file in append mode.
441 452 Use `logfile` to specify a log file to **overwrite** logs to.
442 453 """
443 454 ).tag(config=True)
444 455 object_info_string_level = Enum((0,1,2), default_value=0,
445 456 ).tag(config=True)
446 457 pdb = Bool(False, help=
447 458 """
448 459 Automatically call the pdb debugger after every exception.
449 460 """
450 461 ).tag(config=True)
451 462 display_page = Bool(False,
452 463 help="""If True, anything that would be passed to the pager
453 464 will be displayed as regular output instead."""
454 465 ).tag(config=True)
455 466
456 467
457 468 show_rewritten_input = Bool(True,
458 469 help="Show rewritten input, e.g. for autocall."
459 470 ).tag(config=True)
460 471
461 472 quiet = Bool(False).tag(config=True)
462 473
463 474 history_length = Integer(10000,
464 475 help='Total length of command history'
465 476 ).tag(config=True)
466 477
467 478 history_load_length = Integer(1000, help=
468 479 """
469 480 The number of saved history entries to be loaded
470 481 into the history buffer at startup.
471 482 """
472 483 ).tag(config=True)
473 484
474 485 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none', 'last_expr_or_assign'],
475 486 default_value='last_expr',
476 487 help="""
477 488 'all', 'last', 'last_expr' or 'none', 'last_expr_or_assign' specifying
478 489 which nodes should be run interactively (displaying output from expressions).
479 490 """
480 491 ).tag(config=True)
481 492
482 493 warn_venv = Bool(
483 494 True,
484 495 help="Warn if running in a virtual environment with no IPython installed (so IPython from the global environment is used).",
485 496 ).tag(config=True)
486 497
487 498 # TODO: this part of prompt management should be moved to the frontends.
488 499 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
489 500 separate_in = SeparateUnicode('\n').tag(config=True)
490 501 separate_out = SeparateUnicode('').tag(config=True)
491 502 separate_out2 = SeparateUnicode('').tag(config=True)
492 503 wildcards_case_sensitive = Bool(True).tag(config=True)
493 504 xmode = CaselessStrEnum(('Context', 'Plain', 'Verbose', 'Minimal'),
494 505 default_value='Context',
495 506 help="Switch modes for the IPython exception handlers."
496 507 ).tag(config=True)
497 508
498 509 # Subcomponents of InteractiveShell
499 510 alias_manager = Instance('IPython.core.alias.AliasManager', allow_none=True)
500 511 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
501 512 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap', allow_none=True)
502 513 display_trap = Instance('IPython.core.display_trap.DisplayTrap', allow_none=True)
503 514 extension_manager = Instance('IPython.core.extensions.ExtensionManager', allow_none=True)
504 515 payload_manager = Instance('IPython.core.payload.PayloadManager', allow_none=True)
505 516 history_manager = Instance('IPython.core.history.HistoryAccessorBase', allow_none=True)
506 517 magics_manager = Instance('IPython.core.magic.MagicsManager', allow_none=True)
507 518
508 519 profile_dir = Instance('IPython.core.application.ProfileDir', allow_none=True)
509 520 @property
510 521 def profile(self):
511 522 if self.profile_dir is not None:
512 523 name = os.path.basename(self.profile_dir.location)
513 524 return name.replace('profile_','')
514 525
515 526
516 527 # Private interface
517 528 _post_execute = Dict()
518 529
519 530 # Tracks any GUI loop loaded for pylab
520 531 pylab_gui_select = None
521 532
522 533 last_execution_succeeded = Bool(True, help='Did last executed command succeeded')
523 534
524 535 last_execution_result = Instance('IPython.core.interactiveshell.ExecutionResult', help='Result of executing the last command', allow_none=True)
525 536
526 537 def __init__(self, ipython_dir=None, profile_dir=None,
527 538 user_module=None, user_ns=None,
528 539 custom_exceptions=((), None), **kwargs):
529 540 # This is where traits with a config_key argument are updated
530 541 # from the values on config.
531 542 super(InteractiveShell, self).__init__(**kwargs)
532 543 if 'PromptManager' in self.config:
533 544 warn('As of IPython 5.0 `PromptManager` config will have no effect'
534 545 ' and has been replaced by TerminalInteractiveShell.prompts_class')
535 546 self.configurables = [self]
536 547
537 548 # These are relatively independent and stateless
538 549 self.init_ipython_dir(ipython_dir)
539 550 self.init_profile_dir(profile_dir)
540 551 self.init_instance_attrs()
541 552 self.init_environment()
542 553
543 554 # Check if we're in a virtualenv, and set up sys.path.
544 555 self.init_virtualenv()
545 556
546 557 # Create namespaces (user_ns, user_global_ns, etc.)
547 558 self.init_create_namespaces(user_module, user_ns)
548 559 # This has to be done after init_create_namespaces because it uses
549 560 # something in self.user_ns, but before init_sys_modules, which
550 561 # is the first thing to modify sys.
551 562 # TODO: When we override sys.stdout and sys.stderr before this class
552 563 # is created, we are saving the overridden ones here. Not sure if this
553 564 # is what we want to do.
554 565 self.save_sys_module_state()
555 566 self.init_sys_modules()
556 567
557 568 # While we're trying to have each part of the code directly access what
558 569 # it needs without keeping redundant references to objects, we have too
559 570 # much legacy code that expects ip.db to exist.
560 571 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
561 572
562 573 self.init_history()
563 574 self.init_encoding()
564 575 self.init_prefilter()
565 576
566 577 self.init_syntax_highlighting()
567 578 self.init_hooks()
568 579 self.init_events()
569 580 self.init_pushd_popd_magic()
570 581 self.init_user_ns()
571 582 self.init_logger()
572 583 self.init_builtins()
573 584
574 585 # The following was in post_config_initialization
575 586 self.init_inspector()
576 587 self.raw_input_original = input
577 588 self.init_completer()
578 589 # TODO: init_io() needs to happen before init_traceback handlers
579 590 # because the traceback handlers hardcode the stdout/stderr streams.
580 591 # This logic in in debugger.Pdb and should eventually be changed.
581 592 self.init_io()
582 593 self.init_traceback_handlers(custom_exceptions)
583 594 self.init_prompts()
584 595 self.init_display_formatter()
585 596 self.init_display_pub()
586 597 self.init_data_pub()
587 598 self.init_displayhook()
588 599 self.init_magics()
589 600 self.init_alias()
590 601 self.init_logstart()
591 602 self.init_pdb()
592 603 self.init_extension_manager()
593 604 self.init_payload()
594 605 self.events.trigger('shell_initialized', self)
595 606 atexit.register(self.atexit_operations)
596 607
597 608 # The trio runner is used for running Trio in the foreground thread. It
598 609 # is different from `_trio_runner(async_fn)` in `async_helpers.py`
599 610 # which calls `trio.run()` for every cell. This runner runs all cells
600 611 # inside a single Trio event loop. If used, it is set from
601 612 # `ipykernel.kernelapp`.
602 613 self.trio_runner = None
603 614
604 615 def get_ipython(self):
605 616 """Return the currently running IPython instance."""
606 617 return self
607 618
608 619 #-------------------------------------------------------------------------
609 620 # Trait changed handlers
610 621 #-------------------------------------------------------------------------
611 622 @observe('ipython_dir')
612 623 def _ipython_dir_changed(self, change):
613 624 ensure_dir_exists(change['new'])
614 625
615 626 def set_autoindent(self,value=None):
616 627 """Set the autoindent flag.
617 628
618 629 If called with no arguments, it acts as a toggle."""
619 630 if value is None:
620 631 self.autoindent = not self.autoindent
621 632 else:
622 633 self.autoindent = value
623 634
624 635 def set_trio_runner(self, tr):
625 636 self.trio_runner = tr
626 637
627 638 #-------------------------------------------------------------------------
628 639 # init_* methods called by __init__
629 640 #-------------------------------------------------------------------------
630 641
631 642 def init_ipython_dir(self, ipython_dir):
632 643 if ipython_dir is not None:
633 644 self.ipython_dir = ipython_dir
634 645 return
635 646
636 647 self.ipython_dir = get_ipython_dir()
637 648
638 649 def init_profile_dir(self, profile_dir):
639 650 if profile_dir is not None:
640 651 self.profile_dir = profile_dir
641 652 return
642 653 self.profile_dir = ProfileDir.create_profile_dir_by_name(
643 654 self.ipython_dir, "default"
644 655 )
645 656
646 657 def init_instance_attrs(self):
647 658 self.more = False
648 659
649 660 # command compiler
650 661 self.compile = self.compiler_class()
651 662
652 663 # Make an empty namespace, which extension writers can rely on both
653 664 # existing and NEVER being used by ipython itself. This gives them a
654 665 # convenient location for storing additional information and state
655 666 # their extensions may require, without fear of collisions with other
656 667 # ipython names that may develop later.
657 668 self.meta = Struct()
658 669
659 670 # Temporary files used for various purposes. Deleted at exit.
660 671 # The files here are stored with Path from Pathlib
661 672 self.tempfiles = []
662 673 self.tempdirs = []
663 674
664 675 # keep track of where we started running (mainly for crash post-mortem)
665 676 # This is not being used anywhere currently.
666 677 self.starting_dir = os.getcwd()
667 678
668 679 # Indentation management
669 680 self.indent_current_nsp = 0
670 681
671 682 # Dict to track post-execution functions that have been registered
672 683 self._post_execute = {}
673 684
674 685 def init_environment(self):
675 686 """Any changes we need to make to the user's environment."""
676 687 pass
677 688
678 689 def init_encoding(self):
679 690 # Get system encoding at startup time. Certain terminals (like Emacs
680 691 # under Win32 have it set to None, and we need to have a known valid
681 692 # encoding to use in the raw_input() method
682 693 try:
683 694 self.stdin_encoding = sys.stdin.encoding or 'ascii'
684 695 except AttributeError:
685 696 self.stdin_encoding = 'ascii'
686 697
687 698
688 699 @observe('colors')
689 700 def init_syntax_highlighting(self, changes=None):
690 701 # Python source parser/formatter for syntax highlighting
691 702 pyformat = PyColorize.Parser(style=self.colors, parent=self).format
692 703 self.pycolorize = lambda src: pyformat(src,'str')
693 704
694 705 def refresh_style(self):
695 706 # No-op here, used in subclass
696 707 pass
697 708
698 709 def init_pushd_popd_magic(self):
699 710 # for pushd/popd management
700 711 self.home_dir = get_home_dir()
701 712
702 713 self.dir_stack = []
703 714
704 715 def init_logger(self):
705 716 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
706 717 logmode='rotate')
707 718
708 719 def init_logstart(self):
709 720 """Initialize logging in case it was requested at the command line.
710 721 """
711 722 if self.logappend:
712 723 self.magic('logstart %s append' % self.logappend)
713 724 elif self.logfile:
714 725 self.magic('logstart %s' % self.logfile)
715 726 elif self.logstart:
716 727 self.magic('logstart')
717 728
718 729
719 730 def init_builtins(self):
720 731 # A single, static flag that we set to True. Its presence indicates
721 732 # that an IPython shell has been created, and we make no attempts at
722 733 # removing on exit or representing the existence of more than one
723 734 # IPython at a time.
724 735 builtin_mod.__dict__['__IPYTHON__'] = True
725 736 builtin_mod.__dict__['display'] = display
726 737
727 738 self.builtin_trap = BuiltinTrap(shell=self)
728 739
729 740 @observe('colors')
730 741 def init_inspector(self, changes=None):
731 742 # Object inspector
732 743 self.inspector = oinspect.Inspector(oinspect.InspectColors,
733 744 PyColorize.ANSICodeColors,
734 745 self.colors,
735 746 self.object_info_string_level)
736 747
737 748 def init_io(self):
738 749 # implemented in subclasses, TerminalInteractiveShell does call
739 750 # colorama.init().
740 751 pass
741 752
742 753 def init_prompts(self):
743 754 # Set system prompts, so that scripts can decide if they are running
744 755 # interactively.
745 756 sys.ps1 = 'In : '
746 757 sys.ps2 = '...: '
747 758 sys.ps3 = 'Out: '
748 759
749 760 def init_display_formatter(self):
750 761 self.display_formatter = DisplayFormatter(parent=self)
751 762 self.configurables.append(self.display_formatter)
752 763
753 764 def init_display_pub(self):
754 765 self.display_pub = self.display_pub_class(parent=self, shell=self)
755 766 self.configurables.append(self.display_pub)
756 767
757 768 def init_data_pub(self):
758 769 if not self.data_pub_class:
759 770 self.data_pub = None
760 771 return
761 772 self.data_pub = self.data_pub_class(parent=self)
762 773 self.configurables.append(self.data_pub)
763 774
764 775 def init_displayhook(self):
765 776 # Initialize displayhook, set in/out prompts and printing system
766 777 self.displayhook = self.displayhook_class(
767 778 parent=self,
768 779 shell=self,
769 780 cache_size=self.cache_size,
770 781 )
771 782 self.configurables.append(self.displayhook)
772 783 # This is a context manager that installs/revmoes the displayhook at
773 784 # the appropriate time.
774 785 self.display_trap = DisplayTrap(hook=self.displayhook)
775 786
776 787 @staticmethod
777 788 def get_path_links(p: Path):
778 789 """Gets path links including all symlinks
779 790
780 791 Examples
781 792 --------
782 793 In [1]: from IPython.core.interactiveshell import InteractiveShell
783 794
784 795 In [2]: import sys, pathlib
785 796
786 797 In [3]: paths = InteractiveShell.get_path_links(pathlib.Path(sys.executable))
787 798
788 799 In [4]: len(paths) == len(set(paths))
789 800 Out[4]: True
790 801
791 802 In [5]: bool(paths)
792 803 Out[5]: True
793 804 """
794 805 paths = [p]
795 806 while p.is_symlink():
796 807 new_path = Path(os.readlink(p))
797 808 if not new_path.is_absolute():
798 809 new_path = p.parent / new_path
799 810 p = new_path
800 811 paths.append(p)
801 812 return paths
802 813
803 814 def init_virtualenv(self):
804 815 """Add the current virtualenv to sys.path so the user can import modules from it.
805 816 This isn't perfect: it doesn't use the Python interpreter with which the
806 817 virtualenv was built, and it ignores the --no-site-packages option. A
807 818 warning will appear suggesting the user installs IPython in the
808 819 virtualenv, but for many cases, it probably works well enough.
809 820
810 821 Adapted from code snippets online.
811 822
812 823 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
813 824 """
814 825 if 'VIRTUAL_ENV' not in os.environ:
815 826 # Not in a virtualenv
816 827 return
817 828 elif os.environ["VIRTUAL_ENV"] == "":
818 829 warn("Virtual env path set to '', please check if this is intended.")
819 830 return
820 831
821 832 p = Path(sys.executable)
822 833 p_venv = Path(os.environ["VIRTUAL_ENV"])
823 834
824 835 # fallback venv detection:
825 836 # stdlib venv may symlink sys.executable, so we can't use realpath.
826 837 # but others can symlink *to* the venv Python, so we can't just use sys.executable.
827 838 # So we just check every item in the symlink tree (generally <= 3)
828 839 paths = self.get_path_links(p)
829 840
830 841 # In Cygwin paths like "c:\..." and '\cygdrive\c\...' are possible
831 842 if p_venv.parts[1] == "cygdrive":
832 843 drive_name = p_venv.parts[2]
833 844 p_venv = (drive_name + ":/") / Path(*p_venv.parts[3:])
834 845
835 846 if any(p_venv == p.parents[1] for p in paths):
836 847 # Our exe is inside or has access to the virtualenv, don't need to do anything.
837 848 return
838 849
839 850 if sys.platform == "win32":
840 851 virtual_env = str(Path(os.environ["VIRTUAL_ENV"], "Lib", "site-packages"))
841 852 else:
842 853 virtual_env_path = Path(
843 854 os.environ["VIRTUAL_ENV"], "lib", "python{}.{}", "site-packages"
844 855 )
845 856 p_ver = sys.version_info[:2]
846 857
847 858 # Predict version from py[thon]-x.x in the $VIRTUAL_ENV
848 859 re_m = re.search(r"\bpy(?:thon)?([23])\.(\d+)\b", os.environ["VIRTUAL_ENV"])
849 860 if re_m:
850 861 predicted_path = Path(str(virtual_env_path).format(*re_m.groups()))
851 862 if predicted_path.exists():
852 863 p_ver = re_m.groups()
853 864
854 865 virtual_env = str(virtual_env_path).format(*p_ver)
855 866 if self.warn_venv:
856 867 warn(
857 868 "Attempting to work in a virtualenv. If you encounter problems, "
858 869 "please install IPython inside the virtualenv."
859 870 )
860 871 import site
861 872 sys.path.insert(0, virtual_env)
862 873 site.addsitedir(virtual_env)
863 874
864 875 #-------------------------------------------------------------------------
865 876 # Things related to injections into the sys module
866 877 #-------------------------------------------------------------------------
867 878
868 879 def save_sys_module_state(self):
869 880 """Save the state of hooks in the sys module.
870 881
871 882 This has to be called after self.user_module is created.
872 883 """
873 884 self._orig_sys_module_state = {'stdin': sys.stdin,
874 885 'stdout': sys.stdout,
875 886 'stderr': sys.stderr,
876 887 'excepthook': sys.excepthook}
877 888 self._orig_sys_modules_main_name = self.user_module.__name__
878 889 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
879 890
880 891 def restore_sys_module_state(self):
881 892 """Restore the state of the sys module."""
882 893 try:
883 894 for k, v in self._orig_sys_module_state.items():
884 895 setattr(sys, k, v)
885 896 except AttributeError:
886 897 pass
887 898 # Reset what what done in self.init_sys_modules
888 899 if self._orig_sys_modules_main_mod is not None:
889 900 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
890 901
891 902 #-------------------------------------------------------------------------
892 903 # Things related to the banner
893 904 #-------------------------------------------------------------------------
894 905
895 906 @property
896 907 def banner(self):
897 908 banner = self.banner1
898 909 if self.profile and self.profile != 'default':
899 910 banner += '\nIPython profile: %s\n' % self.profile
900 911 if self.banner2:
901 912 banner += '\n' + self.banner2
902 913 return banner
903 914
904 915 def show_banner(self, banner=None):
905 916 if banner is None:
906 917 banner = self.banner
907 918 sys.stdout.write(banner)
908 919
909 920 #-------------------------------------------------------------------------
910 921 # Things related to hooks
911 922 #-------------------------------------------------------------------------
912 923
913 924 def init_hooks(self):
914 925 # hooks holds pointers used for user-side customizations
915 926 self.hooks = Struct()
916 927
917 928 self.strdispatchers = {}
918 929
919 930 # Set all default hooks, defined in the IPython.hooks module.
920 931 hooks = IPython.core.hooks
921 932 for hook_name in hooks.__all__:
922 933 # default hooks have priority 100, i.e. low; user hooks should have
923 934 # 0-100 priority
924 935 self.set_hook(hook_name, getattr(hooks, hook_name), 100)
925 936
926 937 if self.display_page:
927 938 self.set_hook('show_in_pager', page.as_hook(page.display_page), 90)
928 939
929 940 def set_hook(self, name, hook, priority=50, str_key=None, re_key=None):
930 941 """set_hook(name,hook) -> sets an internal IPython hook.
931 942
932 943 IPython exposes some of its internal API as user-modifiable hooks. By
933 944 adding your function to one of these hooks, you can modify IPython's
934 945 behavior to call at runtime your own routines."""
935 946
936 947 # At some point in the future, this should validate the hook before it
937 948 # accepts it. Probably at least check that the hook takes the number
938 949 # of args it's supposed to.
939 950
940 951 f = types.MethodType(hook,self)
941 952
942 953 # check if the hook is for strdispatcher first
943 954 if str_key is not None:
944 955 sdp = self.strdispatchers.get(name, StrDispatch())
945 956 sdp.add_s(str_key, f, priority )
946 957 self.strdispatchers[name] = sdp
947 958 return
948 959 if re_key is not None:
949 960 sdp = self.strdispatchers.get(name, StrDispatch())
950 961 sdp.add_re(re.compile(re_key), f, priority )
951 962 self.strdispatchers[name] = sdp
952 963 return
953 964
954 965 dp = getattr(self.hooks, name, None)
955 966 if name not in IPython.core.hooks.__all__:
956 967 print("Warning! Hook '%s' is not one of %s" % \
957 968 (name, IPython.core.hooks.__all__ ))
958 969
959 970 if name in IPython.core.hooks.deprecated:
960 971 alternative = IPython.core.hooks.deprecated[name]
961 972 raise ValueError(
962 973 "Hook {} has been deprecated since IPython 5.0. Use {} instead.".format(
963 974 name, alternative
964 975 )
965 976 )
966 977
967 978 if not dp:
968 979 dp = IPython.core.hooks.CommandChainDispatcher()
969 980
970 981 try:
971 982 dp.add(f,priority)
972 983 except AttributeError:
973 984 # it was not commandchain, plain old func - replace
974 985 dp = f
975 986
976 987 setattr(self.hooks,name, dp)
977 988
978 989 #-------------------------------------------------------------------------
979 990 # Things related to events
980 991 #-------------------------------------------------------------------------
981 992
982 993 def init_events(self):
983 994 self.events = EventManager(self, available_events)
984 995
985 996 self.events.register("pre_execute", self._clear_warning_registry)
986 997
987 998 def register_post_execute(self, func):
988 999 """DEPRECATED: Use ip.events.register('post_run_cell', func)
989 1000
990 1001 Register a function for calling after code execution.
991 1002 """
992 1003 raise ValueError(
993 1004 "ip.register_post_execute is deprecated since IPython 1.0, use "
994 1005 "ip.events.register('post_run_cell', func) instead."
995 1006 )
996 1007
997 1008 def _clear_warning_registry(self):
998 1009 # clear the warning registry, so that different code blocks with
999 1010 # overlapping line number ranges don't cause spurious suppression of
1000 1011 # warnings (see gh-6611 for details)
1001 1012 if "__warningregistry__" in self.user_global_ns:
1002 1013 del self.user_global_ns["__warningregistry__"]
1003 1014
1004 1015 #-------------------------------------------------------------------------
1005 1016 # Things related to the "main" module
1006 1017 #-------------------------------------------------------------------------
1007 1018
1008 1019 def new_main_mod(self, filename, modname):
1009 1020 """Return a new 'main' module object for user code execution.
1010 1021
1011 1022 ``filename`` should be the path of the script which will be run in the
1012 1023 module. Requests with the same filename will get the same module, with
1013 1024 its namespace cleared.
1014 1025
1015 1026 ``modname`` should be the module name - normally either '__main__' or
1016 1027 the basename of the file without the extension.
1017 1028
1018 1029 When scripts are executed via %run, we must keep a reference to their
1019 1030 __main__ module around so that Python doesn't
1020 1031 clear it, rendering references to module globals useless.
1021 1032
1022 1033 This method keeps said reference in a private dict, keyed by the
1023 1034 absolute path of the script. This way, for multiple executions of the
1024 1035 same script we only keep one copy of the namespace (the last one),
1025 1036 thus preventing memory leaks from old references while allowing the
1026 1037 objects from the last execution to be accessible.
1027 1038 """
1028 1039 filename = os.path.abspath(filename)
1029 1040 try:
1030 1041 main_mod = self._main_mod_cache[filename]
1031 1042 except KeyError:
1032 1043 main_mod = self._main_mod_cache[filename] = types.ModuleType(
1033 1044 modname,
1034 1045 doc="Module created for script run in IPython")
1035 1046 else:
1036 1047 main_mod.__dict__.clear()
1037 1048 main_mod.__name__ = modname
1038 1049
1039 1050 main_mod.__file__ = filename
1040 1051 # It seems pydoc (and perhaps others) needs any module instance to
1041 1052 # implement a __nonzero__ method
1042 1053 main_mod.__nonzero__ = lambda : True
1043 1054
1044 1055 return main_mod
1045 1056
1046 1057 def clear_main_mod_cache(self):
1047 1058 """Clear the cache of main modules.
1048 1059
1049 1060 Mainly for use by utilities like %reset.
1050 1061
1051 1062 Examples
1052 1063 --------
1053 1064 In [15]: import IPython
1054 1065
1055 1066 In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
1056 1067
1057 1068 In [17]: len(_ip._main_mod_cache) > 0
1058 1069 Out[17]: True
1059 1070
1060 1071 In [18]: _ip.clear_main_mod_cache()
1061 1072
1062 1073 In [19]: len(_ip._main_mod_cache) == 0
1063 1074 Out[19]: True
1064 1075 """
1065 1076 self._main_mod_cache.clear()
1066 1077
1067 1078 #-------------------------------------------------------------------------
1068 1079 # Things related to debugging
1069 1080 #-------------------------------------------------------------------------
1070 1081
1071 1082 def init_pdb(self):
1072 1083 # Set calling of pdb on exceptions
1073 1084 # self.call_pdb is a property
1074 1085 self.call_pdb = self.pdb
1075 1086
1076 1087 def _get_call_pdb(self):
1077 1088 return self._call_pdb
1078 1089
1079 1090 def _set_call_pdb(self,val):
1080 1091
1081 1092 if val not in (0,1,False,True):
1082 1093 raise ValueError('new call_pdb value must be boolean')
1083 1094
1084 1095 # store value in instance
1085 1096 self._call_pdb = val
1086 1097
1087 1098 # notify the actual exception handlers
1088 1099 self.InteractiveTB.call_pdb = val
1089 1100
1090 1101 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
1091 1102 'Control auto-activation of pdb at exceptions')
1092 1103
1093 1104 def debugger(self,force=False):
1094 1105 """Call the pdb debugger.
1095 1106
1096 1107 Keywords:
1097 1108
1098 1109 - force(False): by default, this routine checks the instance call_pdb
1099 1110 flag and does not actually invoke the debugger if the flag is false.
1100 1111 The 'force' option forces the debugger to activate even if the flag
1101 1112 is false.
1102 1113 """
1103 1114
1104 1115 if not (force or self.call_pdb):
1105 1116 return
1106 1117
1107 1118 if not hasattr(sys,'last_traceback'):
1108 1119 error('No traceback has been produced, nothing to debug.')
1109 1120 return
1110 1121
1111 1122 self.InteractiveTB.debugger(force=True)
1112 1123
1113 1124 #-------------------------------------------------------------------------
1114 1125 # Things related to IPython's various namespaces
1115 1126 #-------------------------------------------------------------------------
1116 1127 default_user_namespaces = True
1117 1128
1118 1129 def init_create_namespaces(self, user_module=None, user_ns=None):
1119 1130 # Create the namespace where the user will operate. user_ns is
1120 1131 # normally the only one used, and it is passed to the exec calls as
1121 1132 # the locals argument. But we do carry a user_global_ns namespace
1122 1133 # given as the exec 'globals' argument, This is useful in embedding
1123 1134 # situations where the ipython shell opens in a context where the
1124 1135 # distinction between locals and globals is meaningful. For
1125 1136 # non-embedded contexts, it is just the same object as the user_ns dict.
1126 1137
1127 1138 # FIXME. For some strange reason, __builtins__ is showing up at user
1128 1139 # level as a dict instead of a module. This is a manual fix, but I
1129 1140 # should really track down where the problem is coming from. Alex
1130 1141 # Schmolck reported this problem first.
1131 1142
1132 1143 # A useful post by Alex Martelli on this topic:
1133 1144 # Re: inconsistent value from __builtins__
1134 1145 # Von: Alex Martelli <aleaxit@yahoo.com>
1135 1146 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
1136 1147 # Gruppen: comp.lang.python
1137 1148
1138 1149 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
1139 1150 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
1140 1151 # > <type 'dict'>
1141 1152 # > >>> print type(__builtins__)
1142 1153 # > <type 'module'>
1143 1154 # > Is this difference in return value intentional?
1144 1155
1145 1156 # Well, it's documented that '__builtins__' can be either a dictionary
1146 1157 # or a module, and it's been that way for a long time. Whether it's
1147 1158 # intentional (or sensible), I don't know. In any case, the idea is
1148 1159 # that if you need to access the built-in namespace directly, you
1149 1160 # should start with "import __builtin__" (note, no 's') which will
1150 1161 # definitely give you a module. Yeah, it's somewhat confusing:-(.
1151 1162
1152 1163 # These routines return a properly built module and dict as needed by
1153 1164 # the rest of the code, and can also be used by extension writers to
1154 1165 # generate properly initialized namespaces.
1155 1166 if (user_ns is not None) or (user_module is not None):
1156 1167 self.default_user_namespaces = False
1157 1168 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
1158 1169
1159 1170 # A record of hidden variables we have added to the user namespace, so
1160 1171 # we can list later only variables defined in actual interactive use.
1161 1172 self.user_ns_hidden = {}
1162 1173
1163 1174 # Now that FakeModule produces a real module, we've run into a nasty
1164 1175 # problem: after script execution (via %run), the module where the user
1165 1176 # code ran is deleted. Now that this object is a true module (needed
1166 1177 # so doctest and other tools work correctly), the Python module
1167 1178 # teardown mechanism runs over it, and sets to None every variable
1168 1179 # present in that module. Top-level references to objects from the
1169 1180 # script survive, because the user_ns is updated with them. However,
1170 1181 # calling functions defined in the script that use other things from
1171 1182 # the script will fail, because the function's closure had references
1172 1183 # to the original objects, which are now all None. So we must protect
1173 1184 # these modules from deletion by keeping a cache.
1174 1185 #
1175 1186 # To avoid keeping stale modules around (we only need the one from the
1176 1187 # last run), we use a dict keyed with the full path to the script, so
1177 1188 # only the last version of the module is held in the cache. Note,
1178 1189 # however, that we must cache the module *namespace contents* (their
1179 1190 # __dict__). Because if we try to cache the actual modules, old ones
1180 1191 # (uncached) could be destroyed while still holding references (such as
1181 1192 # those held by GUI objects that tend to be long-lived)>
1182 1193 #
1183 1194 # The %reset command will flush this cache. See the cache_main_mod()
1184 1195 # and clear_main_mod_cache() methods for details on use.
1185 1196
1186 1197 # This is the cache used for 'main' namespaces
1187 1198 self._main_mod_cache = {}
1188 1199
1189 1200 # A table holding all the namespaces IPython deals with, so that
1190 1201 # introspection facilities can search easily.
1191 1202 self.ns_table = {'user_global':self.user_module.__dict__,
1192 1203 'user_local':self.user_ns,
1193 1204 'builtin':builtin_mod.__dict__
1194 1205 }
1195 1206
1196 1207 @property
1197 1208 def user_global_ns(self):
1198 1209 return self.user_module.__dict__
1199 1210
1200 1211 def prepare_user_module(self, user_module=None, user_ns=None):
1201 1212 """Prepare the module and namespace in which user code will be run.
1202 1213
1203 1214 When IPython is started normally, both parameters are None: a new module
1204 1215 is created automatically, and its __dict__ used as the namespace.
1205 1216
1206 1217 If only user_module is provided, its __dict__ is used as the namespace.
1207 1218 If only user_ns is provided, a dummy module is created, and user_ns
1208 1219 becomes the global namespace. If both are provided (as they may be
1209 1220 when embedding), user_ns is the local namespace, and user_module
1210 1221 provides the global namespace.
1211 1222
1212 1223 Parameters
1213 1224 ----------
1214 1225 user_module : module, optional
1215 1226 The current user module in which IPython is being run. If None,
1216 1227 a clean module will be created.
1217 1228 user_ns : dict, optional
1218 1229 A namespace in which to run interactive commands.
1219 1230
1220 1231 Returns
1221 1232 -------
1222 1233 A tuple of user_module and user_ns, each properly initialised.
1223 1234 """
1224 1235 if user_module is None and user_ns is not None:
1225 1236 user_ns.setdefault("__name__", "__main__")
1226 1237 user_module = DummyMod()
1227 1238 user_module.__dict__ = user_ns
1228 1239
1229 1240 if user_module is None:
1230 1241 user_module = types.ModuleType("__main__",
1231 1242 doc="Automatically created module for IPython interactive environment")
1232 1243
1233 1244 # We must ensure that __builtin__ (without the final 's') is always
1234 1245 # available and pointing to the __builtin__ *module*. For more details:
1235 1246 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1236 1247 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1237 1248 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1238 1249
1239 1250 if user_ns is None:
1240 1251 user_ns = user_module.__dict__
1241 1252
1242 1253 return user_module, user_ns
1243 1254
1244 1255 def init_sys_modules(self):
1245 1256 # We need to insert into sys.modules something that looks like a
1246 1257 # module but which accesses the IPython namespace, for shelve and
1247 1258 # pickle to work interactively. Normally they rely on getting
1248 1259 # everything out of __main__, but for embedding purposes each IPython
1249 1260 # instance has its own private namespace, so we can't go shoving
1250 1261 # everything into __main__.
1251 1262
1252 1263 # note, however, that we should only do this for non-embedded
1253 1264 # ipythons, which really mimic the __main__.__dict__ with their own
1254 1265 # namespace. Embedded instances, on the other hand, should not do
1255 1266 # this because they need to manage the user local/global namespaces
1256 1267 # only, but they live within a 'normal' __main__ (meaning, they
1257 1268 # shouldn't overtake the execution environment of the script they're
1258 1269 # embedded in).
1259 1270
1260 1271 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1261 1272 main_name = self.user_module.__name__
1262 1273 sys.modules[main_name] = self.user_module
1263 1274
1264 1275 def init_user_ns(self):
1265 1276 """Initialize all user-visible namespaces to their minimum defaults.
1266 1277
1267 1278 Certain history lists are also initialized here, as they effectively
1268 1279 act as user namespaces.
1269 1280
1270 1281 Notes
1271 1282 -----
1272 1283 All data structures here are only filled in, they are NOT reset by this
1273 1284 method. If they were not empty before, data will simply be added to
1274 1285 them.
1275 1286 """
1276 1287 # This function works in two parts: first we put a few things in
1277 1288 # user_ns, and we sync that contents into user_ns_hidden so that these
1278 1289 # initial variables aren't shown by %who. After the sync, we add the
1279 1290 # rest of what we *do* want the user to see with %who even on a new
1280 1291 # session (probably nothing, so they really only see their own stuff)
1281 1292
1282 1293 # The user dict must *always* have a __builtin__ reference to the
1283 1294 # Python standard __builtin__ namespace, which must be imported.
1284 1295 # This is so that certain operations in prompt evaluation can be
1285 1296 # reliably executed with builtins. Note that we can NOT use
1286 1297 # __builtins__ (note the 's'), because that can either be a dict or a
1287 1298 # module, and can even mutate at runtime, depending on the context
1288 1299 # (Python makes no guarantees on it). In contrast, __builtin__ is
1289 1300 # always a module object, though it must be explicitly imported.
1290 1301
1291 1302 # For more details:
1292 1303 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1293 1304 ns = {}
1294 1305
1295 1306 # make global variables for user access to the histories
1296 1307 ns['_ih'] = self.history_manager.input_hist_parsed
1297 1308 ns['_oh'] = self.history_manager.output_hist
1298 1309 ns['_dh'] = self.history_manager.dir_hist
1299 1310
1300 1311 # user aliases to input and output histories. These shouldn't show up
1301 1312 # in %who, as they can have very large reprs.
1302 1313 ns['In'] = self.history_manager.input_hist_parsed
1303 1314 ns['Out'] = self.history_manager.output_hist
1304 1315
1305 1316 # Store myself as the public api!!!
1306 1317 ns['get_ipython'] = self.get_ipython
1307 1318
1308 1319 ns['exit'] = self.exiter
1309 1320 ns['quit'] = self.exiter
1310 1321
1311 1322 # Sync what we've added so far to user_ns_hidden so these aren't seen
1312 1323 # by %who
1313 1324 self.user_ns_hidden.update(ns)
1314 1325
1315 1326 # Anything put into ns now would show up in %who. Think twice before
1316 1327 # putting anything here, as we really want %who to show the user their
1317 1328 # stuff, not our variables.
1318 1329
1319 1330 # Finally, update the real user's namespace
1320 1331 self.user_ns.update(ns)
1321 1332
1322 1333 @property
1323 1334 def all_ns_refs(self):
1324 1335 """Get a list of references to all the namespace dictionaries in which
1325 1336 IPython might store a user-created object.
1326 1337
1327 1338 Note that this does not include the displayhook, which also caches
1328 1339 objects from the output."""
1329 1340 return [self.user_ns, self.user_global_ns, self.user_ns_hidden] + \
1330 1341 [m.__dict__ for m in self._main_mod_cache.values()]
1331 1342
1332 1343 def reset(self, new_session=True, aggressive=False):
1333 1344 """Clear all internal namespaces, and attempt to release references to
1334 1345 user objects.
1335 1346
1336 1347 If new_session is True, a new history session will be opened.
1337 1348 """
1338 1349 # Clear histories
1339 1350 self.history_manager.reset(new_session)
1340 1351 # Reset counter used to index all histories
1341 1352 if new_session:
1342 1353 self.execution_count = 1
1343 1354
1344 1355 # Reset last execution result
1345 1356 self.last_execution_succeeded = True
1346 1357 self.last_execution_result = None
1347 1358
1348 1359 # Flush cached output items
1349 1360 if self.displayhook.do_full_cache:
1350 1361 self.displayhook.flush()
1351 1362
1352 1363 # The main execution namespaces must be cleared very carefully,
1353 1364 # skipping the deletion of the builtin-related keys, because doing so
1354 1365 # would cause errors in many object's __del__ methods.
1355 1366 if self.user_ns is not self.user_global_ns:
1356 1367 self.user_ns.clear()
1357 1368 ns = self.user_global_ns
1358 1369 drop_keys = set(ns.keys())
1359 1370 drop_keys.discard('__builtin__')
1360 1371 drop_keys.discard('__builtins__')
1361 1372 drop_keys.discard('__name__')
1362 1373 for k in drop_keys:
1363 1374 del ns[k]
1364 1375
1365 1376 self.user_ns_hidden.clear()
1366 1377
1367 1378 # Restore the user namespaces to minimal usability
1368 1379 self.init_user_ns()
1369 1380 if aggressive and not hasattr(self, "_sys_modules_keys"):
1370 1381 print("Cannot restore sys.module, no snapshot")
1371 1382 elif aggressive:
1372 1383 print("culling sys module...")
1373 1384 current_keys = set(sys.modules.keys())
1374 1385 for k in current_keys - self._sys_modules_keys:
1375 1386 if k.startswith("multiprocessing"):
1376 1387 continue
1377 1388 del sys.modules[k]
1378 1389
1379 1390 # Restore the default and user aliases
1380 1391 self.alias_manager.clear_aliases()
1381 1392 self.alias_manager.init_aliases()
1382 1393
1383 1394 # Now define aliases that only make sense on the terminal, because they
1384 1395 # need direct access to the console in a way that we can't emulate in
1385 1396 # GUI or web frontend
1386 1397 if os.name == 'posix':
1387 1398 for cmd in ('clear', 'more', 'less', 'man'):
1388 1399 if cmd not in self.magics_manager.magics['line']:
1389 1400 self.alias_manager.soft_define_alias(cmd, cmd)
1390 1401
1391 1402 # Flush the private list of module references kept for script
1392 1403 # execution protection
1393 1404 self.clear_main_mod_cache()
1394 1405
1395 1406 def del_var(self, varname, by_name=False):
1396 1407 """Delete a variable from the various namespaces, so that, as
1397 1408 far as possible, we're not keeping any hidden references to it.
1398 1409
1399 1410 Parameters
1400 1411 ----------
1401 1412 varname : str
1402 1413 The name of the variable to delete.
1403 1414 by_name : bool
1404 1415 If True, delete variables with the given name in each
1405 1416 namespace. If False (default), find the variable in the user
1406 1417 namespace, and delete references to it.
1407 1418 """
1408 1419 if varname in ('__builtin__', '__builtins__'):
1409 1420 raise ValueError("Refusing to delete %s" % varname)
1410 1421
1411 1422 ns_refs = self.all_ns_refs
1412 1423
1413 1424 if by_name: # Delete by name
1414 1425 for ns in ns_refs:
1415 1426 try:
1416 1427 del ns[varname]
1417 1428 except KeyError:
1418 1429 pass
1419 1430 else: # Delete by object
1420 1431 try:
1421 1432 obj = self.user_ns[varname]
1422 1433 except KeyError as e:
1423 1434 raise NameError("name '%s' is not defined" % varname) from e
1424 1435 # Also check in output history
1425 1436 ns_refs.append(self.history_manager.output_hist)
1426 1437 for ns in ns_refs:
1427 1438 to_delete = [n for n, o in ns.items() if o is obj]
1428 1439 for name in to_delete:
1429 1440 del ns[name]
1430 1441
1431 1442 # Ensure it is removed from the last execution result
1432 1443 if self.last_execution_result.result is obj:
1433 1444 self.last_execution_result = None
1434 1445
1435 1446 # displayhook keeps extra references, but not in a dictionary
1436 1447 for name in ('_', '__', '___'):
1437 1448 if getattr(self.displayhook, name) is obj:
1438 1449 setattr(self.displayhook, name, None)
1439 1450
1440 1451 def reset_selective(self, regex=None):
1441 1452 """Clear selective variables from internal namespaces based on a
1442 1453 specified regular expression.
1443 1454
1444 1455 Parameters
1445 1456 ----------
1446 1457 regex : string or compiled pattern, optional
1447 1458 A regular expression pattern that will be used in searching
1448 1459 variable names in the users namespaces.
1449 1460 """
1450 1461 if regex is not None:
1451 1462 try:
1452 1463 m = re.compile(regex)
1453 1464 except TypeError as e:
1454 1465 raise TypeError('regex must be a string or compiled pattern') from e
1455 1466 # Search for keys in each namespace that match the given regex
1456 1467 # If a match is found, delete the key/value pair.
1457 1468 for ns in self.all_ns_refs:
1458 1469 for var in ns:
1459 1470 if m.search(var):
1460 1471 del ns[var]
1461 1472
1462 1473 def push(self, variables, interactive=True):
1463 1474 """Inject a group of variables into the IPython user namespace.
1464 1475
1465 1476 Parameters
1466 1477 ----------
1467 1478 variables : dict, str or list/tuple of str
1468 1479 The variables to inject into the user's namespace. If a dict, a
1469 1480 simple update is done. If a str, the string is assumed to have
1470 1481 variable names separated by spaces. A list/tuple of str can also
1471 1482 be used to give the variable names. If just the variable names are
1472 1483 give (list/tuple/str) then the variable values looked up in the
1473 1484 callers frame.
1474 1485 interactive : bool
1475 1486 If True (default), the variables will be listed with the ``who``
1476 1487 magic.
1477 1488 """
1478 1489 vdict = None
1479 1490
1480 1491 # We need a dict of name/value pairs to do namespace updates.
1481 1492 if isinstance(variables, dict):
1482 1493 vdict = variables
1483 1494 elif isinstance(variables, (str, list, tuple)):
1484 1495 if isinstance(variables, str):
1485 1496 vlist = variables.split()
1486 1497 else:
1487 1498 vlist = variables
1488 1499 vdict = {}
1489 1500 cf = sys._getframe(1)
1490 1501 for name in vlist:
1491 1502 try:
1492 1503 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1493 1504 except:
1494 1505 print('Could not get variable %s from %s' %
1495 1506 (name,cf.f_code.co_name))
1496 1507 else:
1497 1508 raise ValueError('variables must be a dict/str/list/tuple')
1498 1509
1499 1510 # Propagate variables to user namespace
1500 1511 self.user_ns.update(vdict)
1501 1512
1502 1513 # And configure interactive visibility
1503 1514 user_ns_hidden = self.user_ns_hidden
1504 1515 if interactive:
1505 1516 for name in vdict:
1506 1517 user_ns_hidden.pop(name, None)
1507 1518 else:
1508 1519 user_ns_hidden.update(vdict)
1509 1520
1510 1521 def drop_by_id(self, variables):
1511 1522 """Remove a dict of variables from the user namespace, if they are the
1512 1523 same as the values in the dictionary.
1513 1524
1514 1525 This is intended for use by extensions: variables that they've added can
1515 1526 be taken back out if they are unloaded, without removing any that the
1516 1527 user has overwritten.
1517 1528
1518 1529 Parameters
1519 1530 ----------
1520 1531 variables : dict
1521 1532 A dictionary mapping object names (as strings) to the objects.
1522 1533 """
1523 1534 for name, obj in variables.items():
1524 1535 if name in self.user_ns and self.user_ns[name] is obj:
1525 1536 del self.user_ns[name]
1526 1537 self.user_ns_hidden.pop(name, None)
1527 1538
1528 1539 #-------------------------------------------------------------------------
1529 1540 # Things related to object introspection
1530 1541 #-------------------------------------------------------------------------
1531 1542
1532 1543 def _ofind(self, oname, namespaces=None):
1533 1544 """Find an object in the available namespaces.
1534 1545
1535 1546 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1536 1547
1537 1548 Has special code to detect magic functions.
1538 1549 """
1539 1550 oname = oname.strip()
1540 1551 raw_parts = oname.split(".")
1541 1552 parts = []
1542 1553 parts_ok = True
1543 1554 for p in raw_parts:
1544 1555 if p.endswith("]"):
1545 1556 var, *indices = p.split("[")
1546 1557 if not var.isidentifier():
1547 1558 parts_ok = False
1548 1559 break
1549 1560 parts.append(var)
1550 1561 for ind in indices:
1551 if ind[-1] != "]" and not ind[:-1].isnumeric():
1562 if ind[-1] != "]" and not is_integer_string(ind[:-1]):
1552 1563 parts_ok = False
1553 1564 break
1554 1565 parts.append(ind[:-1])
1555 1566 continue
1556 1567
1557 1568 if not p.isidentifier():
1558 1569 parts_ok = False
1559 1570 parts.append(p)
1560 1571
1561 1572 if (
1562 1573 not oname.startswith(ESC_MAGIC)
1563 1574 and not oname.startswith(ESC_MAGIC2)
1564 1575 and not parts_ok
1565 1576 ):
1566 1577 return {"found": False}
1567 1578
1568 1579 if namespaces is None:
1569 1580 # Namespaces to search in:
1570 1581 # Put them in a list. The order is important so that we
1571 1582 # find things in the same order that Python finds them.
1572 1583 namespaces = [ ('Interactive', self.user_ns),
1573 1584 ('Interactive (global)', self.user_global_ns),
1574 1585 ('Python builtin', builtin_mod.__dict__),
1575 1586 ]
1576 1587
1577 1588 ismagic = False
1578 1589 isalias = False
1579 1590 found = False
1580 1591 ospace = None
1581 1592 parent = None
1582 1593 obj = None
1583 1594
1584 1595
1585 1596 # Look for the given name by splitting it in parts. If the head is
1586 1597 # found, then we look for all the remaining parts as members, and only
1587 1598 # declare success if we can find them all.
1588 1599 oname_parts = parts
1589 1600 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1590 1601 for nsname,ns in namespaces:
1591 1602 try:
1592 1603 obj = ns[oname_head]
1593 1604 except KeyError:
1594 1605 continue
1595 1606 else:
1596 1607 for idx, part in enumerate(oname_rest):
1597 1608 try:
1598 1609 parent = obj
1599 1610 # The last part is looked up in a special way to avoid
1600 1611 # descriptor invocation as it may raise or have side
1601 1612 # effects.
1602 1613 if idx == len(oname_rest) - 1:
1603 1614 obj = self._getattr_property(obj, part)
1604 1615 else:
1605 if part.isnumeric():
1616 if is_integer_string(part):
1606 1617 obj = obj[int(part)]
1607 1618 else:
1608 1619 obj = getattr(obj, part)
1609 1620 except:
1610 1621 # Blanket except b/c some badly implemented objects
1611 1622 # allow __getattr__ to raise exceptions other than
1612 1623 # AttributeError, which then crashes IPython.
1613 1624 break
1614 1625 else:
1615 1626 # If we finish the for loop (no break), we got all members
1616 1627 found = True
1617 1628 ospace = nsname
1618 1629 break # namespace loop
1619 1630
1620 1631 # Try to see if it's magic
1621 1632 if not found:
1622 1633 obj = None
1623 1634 if oname.startswith(ESC_MAGIC2):
1624 1635 oname = oname.lstrip(ESC_MAGIC2)
1625 1636 obj = self.find_cell_magic(oname)
1626 1637 elif oname.startswith(ESC_MAGIC):
1627 1638 oname = oname.lstrip(ESC_MAGIC)
1628 1639 obj = self.find_line_magic(oname)
1629 1640 else:
1630 1641 # search without prefix, so run? will find %run?
1631 1642 obj = self.find_line_magic(oname)
1632 1643 if obj is None:
1633 1644 obj = self.find_cell_magic(oname)
1634 1645 if obj is not None:
1635 1646 found = True
1636 1647 ospace = 'IPython internal'
1637 1648 ismagic = True
1638 1649 isalias = isinstance(obj, Alias)
1639 1650
1640 1651 # Last try: special-case some literals like '', [], {}, etc:
1641 1652 if not found and oname_head in ["''",'""','[]','{}','()']:
1642 1653 obj = eval(oname_head)
1643 1654 found = True
1644 1655 ospace = 'Interactive'
1645 1656
1646 1657 return {
1647 1658 'obj':obj,
1648 1659 'found':found,
1649 1660 'parent':parent,
1650 1661 'ismagic':ismagic,
1651 1662 'isalias':isalias,
1652 1663 'namespace':ospace
1653 1664 }
1654 1665
1655 1666 @staticmethod
1656 1667 def _getattr_property(obj, attrname):
1657 1668 """Property-aware getattr to use in object finding.
1658 1669
1659 1670 If attrname represents a property, return it unevaluated (in case it has
1660 1671 side effects or raises an error.
1661 1672
1662 1673 """
1663 1674 if not isinstance(obj, type):
1664 1675 try:
1665 1676 # `getattr(type(obj), attrname)` is not guaranteed to return
1666 1677 # `obj`, but does so for property:
1667 1678 #
1668 1679 # property.__get__(self, None, cls) -> self
1669 1680 #
1670 1681 # The universal alternative is to traverse the mro manually
1671 1682 # searching for attrname in class dicts.
1672 if attrname.isnumeric():
1683 if is_integer_string(attrname):
1673 1684 return obj[int(attrname)]
1674 1685 else:
1675 1686 attr = getattr(type(obj), attrname)
1676 1687 except AttributeError:
1677 1688 pass
1678 1689 else:
1679 1690 # This relies on the fact that data descriptors (with both
1680 1691 # __get__ & __set__ magic methods) take precedence over
1681 1692 # instance-level attributes:
1682 1693 #
1683 1694 # class A(object):
1684 1695 # @property
1685 1696 # def foobar(self): return 123
1686 1697 # a = A()
1687 1698 # a.__dict__['foobar'] = 345
1688 1699 # a.foobar # == 123
1689 1700 #
1690 1701 # So, a property may be returned right away.
1691 1702 if isinstance(attr, property):
1692 1703 return attr
1693 1704
1694 1705 # Nothing helped, fall back.
1695 1706 return getattr(obj, attrname)
1696 1707
1697 1708 def _object_find(self, oname, namespaces=None):
1698 1709 """Find an object and return a struct with info about it."""
1699 1710 return Struct(self._ofind(oname, namespaces))
1700 1711
1701 1712 def _inspect(self, meth, oname, namespaces=None, **kw):
1702 1713 """Generic interface to the inspector system.
1703 1714
1704 1715 This function is meant to be called by pdef, pdoc & friends.
1705 1716 """
1706 1717 info = self._object_find(oname, namespaces)
1707 1718 docformat = (
1708 1719 sphinxify(self.object_inspect(oname)) if self.sphinxify_docstring else None
1709 1720 )
1710 1721 if info.found:
1711 1722 pmethod = getattr(self.inspector, meth)
1712 1723 # TODO: only apply format_screen to the plain/text repr of the mime
1713 1724 # bundle.
1714 1725 formatter = format_screen if info.ismagic else docformat
1715 1726 if meth == 'pdoc':
1716 1727 pmethod(info.obj, oname, formatter)
1717 1728 elif meth == 'pinfo':
1718 1729 pmethod(
1719 1730 info.obj,
1720 1731 oname,
1721 1732 formatter,
1722 1733 info,
1723 1734 enable_html_pager=self.enable_html_pager,
1724 1735 **kw,
1725 1736 )
1726 1737 else:
1727 1738 pmethod(info.obj, oname)
1728 1739 else:
1729 1740 print('Object `%s` not found.' % oname)
1730 1741 return 'not found' # so callers can take other action
1731 1742
1732 1743 def object_inspect(self, oname, detail_level=0):
1733 1744 """Get object info about oname"""
1734 1745 with self.builtin_trap:
1735 1746 info = self._object_find(oname)
1736 1747 if info.found:
1737 1748 return self.inspector.info(info.obj, oname, info=info,
1738 1749 detail_level=detail_level
1739 1750 )
1740 1751 else:
1741 1752 return oinspect.object_info(name=oname, found=False)
1742 1753
1743 1754 def object_inspect_text(self, oname, detail_level=0):
1744 1755 """Get object info as formatted text"""
1745 1756 return self.object_inspect_mime(oname, detail_level)['text/plain']
1746 1757
1747 1758 def object_inspect_mime(self, oname, detail_level=0, omit_sections=()):
1748 1759 """Get object info as a mimebundle of formatted representations.
1749 1760
1750 1761 A mimebundle is a dictionary, keyed by mime-type.
1751 1762 It must always have the key `'text/plain'`.
1752 1763 """
1753 1764 with self.builtin_trap:
1754 1765 info = self._object_find(oname)
1755 1766 if info.found:
1756 1767 docformat = (
1757 1768 sphinxify(self.object_inspect(oname))
1758 1769 if self.sphinxify_docstring
1759 1770 else None
1760 1771 )
1761 1772 return self.inspector._get_info(
1762 1773 info.obj,
1763 1774 oname,
1764 1775 info=info,
1765 1776 detail_level=detail_level,
1766 1777 formatter=docformat,
1767 1778 omit_sections=omit_sections,
1768 1779 )
1769 1780 else:
1770 1781 raise KeyError(oname)
1771 1782
1772 1783 #-------------------------------------------------------------------------
1773 1784 # Things related to history management
1774 1785 #-------------------------------------------------------------------------
1775 1786
1776 1787 def init_history(self):
1777 1788 """Sets up the command history, and starts regular autosaves."""
1778 1789 self.history_manager = HistoryManager(shell=self, parent=self)
1779 1790 self.configurables.append(self.history_manager)
1780 1791
1781 1792 #-------------------------------------------------------------------------
1782 1793 # Things related to exception handling and tracebacks (not debugging)
1783 1794 #-------------------------------------------------------------------------
1784 1795
1785 1796 debugger_cls = InterruptiblePdb
1786 1797
1787 1798 def init_traceback_handlers(self, custom_exceptions):
1788 1799 # Syntax error handler.
1789 1800 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor', parent=self)
1790 1801
1791 1802 # The interactive one is initialized with an offset, meaning we always
1792 1803 # want to remove the topmost item in the traceback, which is our own
1793 1804 # internal code. Valid modes: ['Plain','Context','Verbose','Minimal']
1794 1805 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1795 1806 color_scheme='NoColor',
1796 1807 tb_offset = 1,
1797 1808 check_cache=check_linecache_ipython,
1798 1809 debugger_cls=self.debugger_cls, parent=self)
1799 1810
1800 1811 # The instance will store a pointer to the system-wide exception hook,
1801 1812 # so that runtime code (such as magics) can access it. This is because
1802 1813 # during the read-eval loop, it may get temporarily overwritten.
1803 1814 self.sys_excepthook = sys.excepthook
1804 1815
1805 1816 # and add any custom exception handlers the user may have specified
1806 1817 self.set_custom_exc(*custom_exceptions)
1807 1818
1808 1819 # Set the exception mode
1809 1820 self.InteractiveTB.set_mode(mode=self.xmode)
1810 1821
1811 1822 def set_custom_exc(self, exc_tuple, handler):
1812 1823 """set_custom_exc(exc_tuple, handler)
1813 1824
1814 1825 Set a custom exception handler, which will be called if any of the
1815 1826 exceptions in exc_tuple occur in the mainloop (specifically, in the
1816 1827 run_code() method).
1817 1828
1818 1829 Parameters
1819 1830 ----------
1820 1831 exc_tuple : tuple of exception classes
1821 1832 A *tuple* of exception classes, for which to call the defined
1822 1833 handler. It is very important that you use a tuple, and NOT A
1823 1834 LIST here, because of the way Python's except statement works. If
1824 1835 you only want to trap a single exception, use a singleton tuple::
1825 1836
1826 1837 exc_tuple == (MyCustomException,)
1827 1838
1828 1839 handler : callable
1829 1840 handler must have the following signature::
1830 1841
1831 1842 def my_handler(self, etype, value, tb, tb_offset=None):
1832 1843 ...
1833 1844 return structured_traceback
1834 1845
1835 1846 Your handler must return a structured traceback (a list of strings),
1836 1847 or None.
1837 1848
1838 1849 This will be made into an instance method (via types.MethodType)
1839 1850 of IPython itself, and it will be called if any of the exceptions
1840 1851 listed in the exc_tuple are caught. If the handler is None, an
1841 1852 internal basic one is used, which just prints basic info.
1842 1853
1843 1854 To protect IPython from crashes, if your handler ever raises an
1844 1855 exception or returns an invalid result, it will be immediately
1845 1856 disabled.
1846 1857
1847 1858 Notes
1848 1859 -----
1849 1860 WARNING: by putting in your own exception handler into IPython's main
1850 1861 execution loop, you run a very good chance of nasty crashes. This
1851 1862 facility should only be used if you really know what you are doing.
1852 1863 """
1853 1864
1854 1865 if not isinstance(exc_tuple, tuple):
1855 1866 raise TypeError("The custom exceptions must be given as a tuple.")
1856 1867
1857 1868 def dummy_handler(self, etype, value, tb, tb_offset=None):
1858 1869 print('*** Simple custom exception handler ***')
1859 1870 print('Exception type :', etype)
1860 1871 print('Exception value:', value)
1861 1872 print('Traceback :', tb)
1862 1873
1863 1874 def validate_stb(stb):
1864 1875 """validate structured traceback return type
1865 1876
1866 1877 return type of CustomTB *should* be a list of strings, but allow
1867 1878 single strings or None, which are harmless.
1868 1879
1869 1880 This function will *always* return a list of strings,
1870 1881 and will raise a TypeError if stb is inappropriate.
1871 1882 """
1872 1883 msg = "CustomTB must return list of strings, not %r" % stb
1873 1884 if stb is None:
1874 1885 return []
1875 1886 elif isinstance(stb, str):
1876 1887 return [stb]
1877 1888 elif not isinstance(stb, list):
1878 1889 raise TypeError(msg)
1879 1890 # it's a list
1880 1891 for line in stb:
1881 1892 # check every element
1882 1893 if not isinstance(line, str):
1883 1894 raise TypeError(msg)
1884 1895 return stb
1885 1896
1886 1897 if handler is None:
1887 1898 wrapped = dummy_handler
1888 1899 else:
1889 1900 def wrapped(self,etype,value,tb,tb_offset=None):
1890 1901 """wrap CustomTB handler, to protect IPython from user code
1891 1902
1892 1903 This makes it harder (but not impossible) for custom exception
1893 1904 handlers to crash IPython.
1894 1905 """
1895 1906 try:
1896 1907 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1897 1908 return validate_stb(stb)
1898 1909 except:
1899 1910 # clear custom handler immediately
1900 1911 self.set_custom_exc((), None)
1901 1912 print("Custom TB Handler failed, unregistering", file=sys.stderr)
1902 1913 # show the exception in handler first
1903 1914 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1904 1915 print(self.InteractiveTB.stb2text(stb))
1905 1916 print("The original exception:")
1906 1917 stb = self.InteractiveTB.structured_traceback(
1907 1918 (etype,value,tb), tb_offset=tb_offset
1908 1919 )
1909 1920 return stb
1910 1921
1911 1922 self.CustomTB = types.MethodType(wrapped,self)
1912 1923 self.custom_exceptions = exc_tuple
1913 1924
1914 1925 def excepthook(self, etype, value, tb):
1915 1926 """One more defense for GUI apps that call sys.excepthook.
1916 1927
1917 1928 GUI frameworks like wxPython trap exceptions and call
1918 1929 sys.excepthook themselves. I guess this is a feature that
1919 1930 enables them to keep running after exceptions that would
1920 1931 otherwise kill their mainloop. This is a bother for IPython
1921 1932 which expects to catch all of the program exceptions with a try:
1922 1933 except: statement.
1923 1934
1924 1935 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1925 1936 any app directly invokes sys.excepthook, it will look to the user like
1926 1937 IPython crashed. In order to work around this, we can disable the
1927 1938 CrashHandler and replace it with this excepthook instead, which prints a
1928 1939 regular traceback using our InteractiveTB. In this fashion, apps which
1929 1940 call sys.excepthook will generate a regular-looking exception from
1930 1941 IPython, and the CrashHandler will only be triggered by real IPython
1931 1942 crashes.
1932 1943
1933 1944 This hook should be used sparingly, only in places which are not likely
1934 1945 to be true IPython errors.
1935 1946 """
1936 1947 self.showtraceback((etype, value, tb), tb_offset=0)
1937 1948
1938 1949 def _get_exc_info(self, exc_tuple=None):
1939 1950 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1940 1951
1941 1952 Ensures sys.last_type,value,traceback hold the exc_info we found,
1942 1953 from whichever source.
1943 1954
1944 1955 raises ValueError if none of these contain any information
1945 1956 """
1946 1957 if exc_tuple is None:
1947 1958 etype, value, tb = sys.exc_info()
1948 1959 else:
1949 1960 etype, value, tb = exc_tuple
1950 1961
1951 1962 if etype is None:
1952 1963 if hasattr(sys, 'last_type'):
1953 1964 etype, value, tb = sys.last_type, sys.last_value, \
1954 1965 sys.last_traceback
1955 1966
1956 1967 if etype is None:
1957 1968 raise ValueError("No exception to find")
1958 1969
1959 1970 # Now store the exception info in sys.last_type etc.
1960 1971 # WARNING: these variables are somewhat deprecated and not
1961 1972 # necessarily safe to use in a threaded environment, but tools
1962 1973 # like pdb depend on their existence, so let's set them. If we
1963 1974 # find problems in the field, we'll need to revisit their use.
1964 1975 sys.last_type = etype
1965 1976 sys.last_value = value
1966 1977 sys.last_traceback = tb
1967 1978
1968 1979 return etype, value, tb
1969 1980
1970 1981 def show_usage_error(self, exc):
1971 1982 """Show a short message for UsageErrors
1972 1983
1973 1984 These are special exceptions that shouldn't show a traceback.
1974 1985 """
1975 1986 print("UsageError: %s" % exc, file=sys.stderr)
1976 1987
1977 1988 def get_exception_only(self, exc_tuple=None):
1978 1989 """
1979 1990 Return as a string (ending with a newline) the exception that
1980 1991 just occurred, without any traceback.
1981 1992 """
1982 1993 etype, value, tb = self._get_exc_info(exc_tuple)
1983 1994 msg = traceback.format_exception_only(etype, value)
1984 1995 return ''.join(msg)
1985 1996
1986 1997 def showtraceback(self, exc_tuple=None, filename=None, tb_offset=None,
1987 1998 exception_only=False, running_compiled_code=False):
1988 1999 """Display the exception that just occurred.
1989 2000
1990 2001 If nothing is known about the exception, this is the method which
1991 2002 should be used throughout the code for presenting user tracebacks,
1992 2003 rather than directly invoking the InteractiveTB object.
1993 2004
1994 2005 A specific showsyntaxerror() also exists, but this method can take
1995 2006 care of calling it if needed, so unless you are explicitly catching a
1996 2007 SyntaxError exception, don't try to analyze the stack manually and
1997 2008 simply call this method."""
1998 2009
1999 2010 try:
2000 2011 try:
2001 2012 etype, value, tb = self._get_exc_info(exc_tuple)
2002 2013 except ValueError:
2003 2014 print('No traceback available to show.', file=sys.stderr)
2004 2015 return
2005 2016
2006 2017 if issubclass(etype, SyntaxError):
2007 2018 # Though this won't be called by syntax errors in the input
2008 2019 # line, there may be SyntaxError cases with imported code.
2009 2020 self.showsyntaxerror(filename, running_compiled_code)
2010 2021 elif etype is UsageError:
2011 2022 self.show_usage_error(value)
2012 2023 else:
2013 2024 if exception_only:
2014 2025 stb = ['An exception has occurred, use %tb to see '
2015 2026 'the full traceback.\n']
2016 2027 stb.extend(self.InteractiveTB.get_exception_only(etype,
2017 2028 value))
2018 2029 else:
2019 2030 try:
2020 2031 # Exception classes can customise their traceback - we
2021 2032 # use this in IPython.parallel for exceptions occurring
2022 2033 # in the engines. This should return a list of strings.
2023 2034 if hasattr(value, "_render_traceback_"):
2024 2035 stb = value._render_traceback_()
2025 2036 else:
2026 2037 stb = self.InteractiveTB.structured_traceback(
2027 2038 etype, value, tb, tb_offset=tb_offset
2028 2039 )
2029 2040
2030 2041 except Exception:
2031 2042 print(
2032 2043 "Unexpected exception formatting exception. Falling back to standard exception"
2033 2044 )
2034 2045 traceback.print_exc()
2035 2046 return None
2036 2047
2037 2048 self._showtraceback(etype, value, stb)
2038 2049 if self.call_pdb:
2039 2050 # drop into debugger
2040 2051 self.debugger(force=True)
2041 2052 return
2042 2053
2043 2054 # Actually show the traceback
2044 2055 self._showtraceback(etype, value, stb)
2045 2056
2046 2057 except KeyboardInterrupt:
2047 2058 print('\n' + self.get_exception_only(), file=sys.stderr)
2048 2059
2049 2060 def _showtraceback(self, etype, evalue, stb: str):
2050 2061 """Actually show a traceback.
2051 2062
2052 2063 Subclasses may override this method to put the traceback on a different
2053 2064 place, like a side channel.
2054 2065 """
2055 2066 val = self.InteractiveTB.stb2text(stb)
2056 2067 try:
2057 2068 print(val)
2058 2069 except UnicodeEncodeError:
2059 2070 print(val.encode("utf-8", "backslashreplace").decode())
2060 2071
2061 2072 def showsyntaxerror(self, filename=None, running_compiled_code=False):
2062 2073 """Display the syntax error that just occurred.
2063 2074
2064 2075 This doesn't display a stack trace because there isn't one.
2065 2076
2066 2077 If a filename is given, it is stuffed in the exception instead
2067 2078 of what was there before (because Python's parser always uses
2068 2079 "<string>" when reading from a string).
2069 2080
2070 2081 If the syntax error occurred when running a compiled code (i.e. running_compile_code=True),
2071 2082 longer stack trace will be displayed.
2072 2083 """
2073 2084 etype, value, last_traceback = self._get_exc_info()
2074 2085
2075 2086 if filename and issubclass(etype, SyntaxError):
2076 2087 try:
2077 2088 value.filename = filename
2078 2089 except:
2079 2090 # Not the format we expect; leave it alone
2080 2091 pass
2081 2092
2082 2093 # If the error occurred when executing compiled code, we should provide full stacktrace.
2083 2094 elist = traceback.extract_tb(last_traceback) if running_compiled_code else []
2084 2095 stb = self.SyntaxTB.structured_traceback(etype, value, elist)
2085 2096 self._showtraceback(etype, value, stb)
2086 2097
2087 2098 # This is overridden in TerminalInteractiveShell to show a message about
2088 2099 # the %paste magic.
2089 2100 def showindentationerror(self):
2090 2101 """Called by _run_cell when there's an IndentationError in code entered
2091 2102 at the prompt.
2092 2103
2093 2104 This is overridden in TerminalInteractiveShell to show a message about
2094 2105 the %paste magic."""
2095 2106 self.showsyntaxerror()
2096 2107
2097 2108 @skip_doctest
2098 2109 def set_next_input(self, s, replace=False):
2099 2110 """ Sets the 'default' input string for the next command line.
2100 2111
2101 2112 Example::
2102 2113
2103 2114 In [1]: _ip.set_next_input("Hello Word")
2104 2115 In [2]: Hello Word_ # cursor is here
2105 2116 """
2106 2117 self.rl_next_input = s
2107 2118
2108 2119 def _indent_current_str(self):
2109 2120 """return the current level of indentation as a string"""
2110 2121 return self.input_splitter.get_indent_spaces() * ' '
2111 2122
2112 2123 #-------------------------------------------------------------------------
2113 2124 # Things related to text completion
2114 2125 #-------------------------------------------------------------------------
2115 2126
2116 2127 def init_completer(self):
2117 2128 """Initialize the completion machinery.
2118 2129
2119 2130 This creates completion machinery that can be used by client code,
2120 2131 either interactively in-process (typically triggered by the readline
2121 2132 library), programmatically (such as in test suites) or out-of-process
2122 2133 (typically over the network by remote frontends).
2123 2134 """
2124 2135 from IPython.core.completer import IPCompleter
2125 2136 from IPython.core.completerlib import (
2126 2137 cd_completer,
2127 2138 magic_run_completer,
2128 2139 module_completer,
2129 2140 reset_completer,
2130 2141 )
2131 2142
2132 2143 self.Completer = IPCompleter(shell=self,
2133 2144 namespace=self.user_ns,
2134 2145 global_namespace=self.user_global_ns,
2135 2146 parent=self,
2136 2147 )
2137 2148 self.configurables.append(self.Completer)
2138 2149
2139 2150 # Add custom completers to the basic ones built into IPCompleter
2140 2151 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
2141 2152 self.strdispatchers['complete_command'] = sdisp
2142 2153 self.Completer.custom_completers = sdisp
2143 2154
2144 2155 self.set_hook('complete_command', module_completer, str_key = 'import')
2145 2156 self.set_hook('complete_command', module_completer, str_key = 'from')
2146 2157 self.set_hook('complete_command', module_completer, str_key = '%aimport')
2147 2158 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
2148 2159 self.set_hook('complete_command', cd_completer, str_key = '%cd')
2149 2160 self.set_hook('complete_command', reset_completer, str_key = '%reset')
2150 2161
2151 2162 @skip_doctest
2152 2163 def complete(self, text, line=None, cursor_pos=None):
2153 2164 """Return the completed text and a list of completions.
2154 2165
2155 2166 Parameters
2156 2167 ----------
2157 2168 text : string
2158 2169 A string of text to be completed on. It can be given as empty and
2159 2170 instead a line/position pair are given. In this case, the
2160 2171 completer itself will split the line like readline does.
2161 2172 line : string, optional
2162 2173 The complete line that text is part of.
2163 2174 cursor_pos : int, optional
2164 2175 The position of the cursor on the input line.
2165 2176
2166 2177 Returns
2167 2178 -------
2168 2179 text : string
2169 2180 The actual text that was completed.
2170 2181 matches : list
2171 2182 A sorted list with all possible completions.
2172 2183
2173 2184 Notes
2174 2185 -----
2175 2186 The optional arguments allow the completion to take more context into
2176 2187 account, and are part of the low-level completion API.
2177 2188
2178 2189 This is a wrapper around the completion mechanism, similar to what
2179 2190 readline does at the command line when the TAB key is hit. By
2180 2191 exposing it as a method, it can be used by other non-readline
2181 2192 environments (such as GUIs) for text completion.
2182 2193
2183 2194 Examples
2184 2195 --------
2185 2196 In [1]: x = 'hello'
2186 2197
2187 2198 In [2]: _ip.complete('x.l')
2188 2199 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
2189 2200 """
2190 2201
2191 2202 # Inject names into __builtin__ so we can complete on the added names.
2192 2203 with self.builtin_trap:
2193 2204 return self.Completer.complete(text, line, cursor_pos)
2194 2205
2195 2206 def set_custom_completer(self, completer, pos=0) -> None:
2196 2207 """Adds a new custom completer function.
2197 2208
2198 2209 The position argument (defaults to 0) is the index in the completers
2199 2210 list where you want the completer to be inserted.
2200 2211
2201 2212 `completer` should have the following signature::
2202 2213
2203 2214 def completion(self: Completer, text: string) -> List[str]:
2204 2215 raise NotImplementedError
2205 2216
2206 2217 It will be bound to the current Completer instance and pass some text
2207 2218 and return a list with current completions to suggest to the user.
2208 2219 """
2209 2220
2210 2221 newcomp = types.MethodType(completer, self.Completer)
2211 2222 self.Completer.custom_matchers.insert(pos,newcomp)
2212 2223
2213 2224 def set_completer_frame(self, frame=None):
2214 2225 """Set the frame of the completer."""
2215 2226 if frame:
2216 2227 self.Completer.namespace = frame.f_locals
2217 2228 self.Completer.global_namespace = frame.f_globals
2218 2229 else:
2219 2230 self.Completer.namespace = self.user_ns
2220 2231 self.Completer.global_namespace = self.user_global_ns
2221 2232
2222 2233 #-------------------------------------------------------------------------
2223 2234 # Things related to magics
2224 2235 #-------------------------------------------------------------------------
2225 2236
2226 2237 def init_magics(self):
2227 2238 from IPython.core import magics as m
2228 2239 self.magics_manager = magic.MagicsManager(shell=self,
2229 2240 parent=self,
2230 2241 user_magics=m.UserMagics(self))
2231 2242 self.configurables.append(self.magics_manager)
2232 2243
2233 2244 # Expose as public API from the magics manager
2234 2245 self.register_magics = self.magics_manager.register
2235 2246
2236 2247 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2237 2248 m.ConfigMagics, m.DisplayMagics, m.ExecutionMagics,
2238 2249 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2239 2250 m.NamespaceMagics, m.OSMagics, m.PackagingMagics,
2240 2251 m.PylabMagics, m.ScriptMagics,
2241 2252 )
2242 2253 self.register_magics(m.AsyncMagics)
2243 2254
2244 2255 # Register Magic Aliases
2245 2256 mman = self.magics_manager
2246 2257 # FIXME: magic aliases should be defined by the Magics classes
2247 2258 # or in MagicsManager, not here
2248 2259 mman.register_alias('ed', 'edit')
2249 2260 mman.register_alias('hist', 'history')
2250 2261 mman.register_alias('rep', 'recall')
2251 2262 mman.register_alias('SVG', 'svg', 'cell')
2252 2263 mman.register_alias('HTML', 'html', 'cell')
2253 2264 mman.register_alias('file', 'writefile', 'cell')
2254 2265
2255 2266 # FIXME: Move the color initialization to the DisplayHook, which
2256 2267 # should be split into a prompt manager and displayhook. We probably
2257 2268 # even need a centralize colors management object.
2258 2269 self.run_line_magic('colors', self.colors)
2259 2270
2260 2271 # Defined here so that it's included in the documentation
2261 2272 @functools.wraps(magic.MagicsManager.register_function)
2262 2273 def register_magic_function(self, func, magic_kind='line', magic_name=None):
2263 2274 self.magics_manager.register_function(
2264 2275 func, magic_kind=magic_kind, magic_name=magic_name
2265 2276 )
2266 2277
2267 2278 def _find_with_lazy_load(self, /, type_, magic_name: str):
2268 2279 """
2269 2280 Try to find a magic potentially lazy-loading it.
2270 2281
2271 2282 Parameters
2272 2283 ----------
2273 2284
2274 2285 type_: "line"|"cell"
2275 2286 the type of magics we are trying to find/lazy load.
2276 2287 magic_name: str
2277 2288 The name of the magic we are trying to find/lazy load
2278 2289
2279 2290
2280 2291 Note that this may have any side effects
2281 2292 """
2282 2293 finder = {"line": self.find_line_magic, "cell": self.find_cell_magic}[type_]
2283 2294 fn = finder(magic_name)
2284 2295 if fn is not None:
2285 2296 return fn
2286 2297 lazy = self.magics_manager.lazy_magics.get(magic_name)
2287 2298 if lazy is None:
2288 2299 return None
2289 2300
2290 2301 self.run_line_magic("load_ext", lazy)
2291 2302 res = finder(magic_name)
2292 2303 return res
2293 2304
2294 2305 def run_line_magic(self, magic_name: str, line, _stack_depth=1):
2295 2306 """Execute the given line magic.
2296 2307
2297 2308 Parameters
2298 2309 ----------
2299 2310 magic_name : str
2300 2311 Name of the desired magic function, without '%' prefix.
2301 2312 line : str
2302 2313 The rest of the input line as a single string.
2303 2314 _stack_depth : int
2304 2315 If run_line_magic() is called from magic() then _stack_depth=2.
2305 2316 This is added to ensure backward compatibility for use of 'get_ipython().magic()'
2306 2317 """
2307 2318 fn = self._find_with_lazy_load("line", magic_name)
2308 2319 if fn is None:
2309 2320 lazy = self.magics_manager.lazy_magics.get(magic_name)
2310 2321 if lazy:
2311 2322 self.run_line_magic("load_ext", lazy)
2312 2323 fn = self.find_line_magic(magic_name)
2313 2324 if fn is None:
2314 2325 cm = self.find_cell_magic(magic_name)
2315 2326 etpl = "Line magic function `%%%s` not found%s."
2316 2327 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2317 2328 'did you mean that instead?)' % magic_name )
2318 2329 raise UsageError(etpl % (magic_name, extra))
2319 2330 else:
2320 2331 # Note: this is the distance in the stack to the user's frame.
2321 2332 # This will need to be updated if the internal calling logic gets
2322 2333 # refactored, or else we'll be expanding the wrong variables.
2323 2334
2324 2335 # Determine stack_depth depending on where run_line_magic() has been called
2325 2336 stack_depth = _stack_depth
2326 2337 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2327 2338 # magic has opted out of var_expand
2328 2339 magic_arg_s = line
2329 2340 else:
2330 2341 magic_arg_s = self.var_expand(line, stack_depth)
2331 2342 # Put magic args in a list so we can call with f(*a) syntax
2332 2343 args = [magic_arg_s]
2333 2344 kwargs = {}
2334 2345 # Grab local namespace if we need it:
2335 2346 if getattr(fn, "needs_local_scope", False):
2336 2347 kwargs['local_ns'] = self.get_local_scope(stack_depth)
2337 2348 with self.builtin_trap:
2338 2349 result = fn(*args, **kwargs)
2339 2350 return result
2340 2351
2341 2352 def get_local_scope(self, stack_depth):
2342 2353 """Get local scope at given stack depth.
2343 2354
2344 2355 Parameters
2345 2356 ----------
2346 2357 stack_depth : int
2347 2358 Depth relative to calling frame
2348 2359 """
2349 2360 return sys._getframe(stack_depth + 1).f_locals
2350 2361
2351 2362 def run_cell_magic(self, magic_name, line, cell):
2352 2363 """Execute the given cell magic.
2353 2364
2354 2365 Parameters
2355 2366 ----------
2356 2367 magic_name : str
2357 2368 Name of the desired magic function, without '%' prefix.
2358 2369 line : str
2359 2370 The rest of the first input line as a single string.
2360 2371 cell : str
2361 2372 The body of the cell as a (possibly multiline) string.
2362 2373 """
2363 2374 fn = self._find_with_lazy_load("cell", magic_name)
2364 2375 if fn is None:
2365 2376 lm = self.find_line_magic(magic_name)
2366 2377 etpl = "Cell magic `%%{0}` not found{1}."
2367 2378 extra = '' if lm is None else (' (But line magic `%{0}` exists, '
2368 2379 'did you mean that instead?)'.format(magic_name))
2369 2380 raise UsageError(etpl.format(magic_name, extra))
2370 2381 elif cell == '':
2371 2382 message = '%%{0} is a cell magic, but the cell body is empty.'.format(magic_name)
2372 2383 if self.find_line_magic(magic_name) is not None:
2373 2384 message += ' Did you mean the line magic %{0} (single %)?'.format(magic_name)
2374 2385 raise UsageError(message)
2375 2386 else:
2376 2387 # Note: this is the distance in the stack to the user's frame.
2377 2388 # This will need to be updated if the internal calling logic gets
2378 2389 # refactored, or else we'll be expanding the wrong variables.
2379 2390 stack_depth = 2
2380 2391 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2381 2392 # magic has opted out of var_expand
2382 2393 magic_arg_s = line
2383 2394 else:
2384 2395 magic_arg_s = self.var_expand(line, stack_depth)
2385 2396 kwargs = {}
2386 2397 if getattr(fn, "needs_local_scope", False):
2387 2398 kwargs['local_ns'] = self.user_ns
2388 2399
2389 2400 with self.builtin_trap:
2390 2401 args = (magic_arg_s, cell)
2391 2402 result = fn(*args, **kwargs)
2392 2403 return result
2393 2404
2394 2405 def find_line_magic(self, magic_name):
2395 2406 """Find and return a line magic by name.
2396 2407
2397 2408 Returns None if the magic isn't found."""
2398 2409 return self.magics_manager.magics['line'].get(magic_name)
2399 2410
2400 2411 def find_cell_magic(self, magic_name):
2401 2412 """Find and return a cell magic by name.
2402 2413
2403 2414 Returns None if the magic isn't found."""
2404 2415 return self.magics_manager.magics['cell'].get(magic_name)
2405 2416
2406 2417 def find_magic(self, magic_name, magic_kind='line'):
2407 2418 """Find and return a magic of the given type by name.
2408 2419
2409 2420 Returns None if the magic isn't found."""
2410 2421 return self.magics_manager.magics[magic_kind].get(magic_name)
2411 2422
2412 2423 def magic(self, arg_s):
2413 2424 """
2414 2425 DEPRECATED
2415 2426
2416 2427 Deprecated since IPython 0.13 (warning added in
2417 2428 8.1), use run_line_magic(magic_name, parameter_s).
2418 2429
2419 2430 Call a magic function by name.
2420 2431
2421 2432 Input: a string containing the name of the magic function to call and
2422 2433 any additional arguments to be passed to the magic.
2423 2434
2424 2435 magic('name -opt foo bar') is equivalent to typing at the ipython
2425 2436 prompt:
2426 2437
2427 2438 In[1]: %name -opt foo bar
2428 2439
2429 2440 To call a magic without arguments, simply use magic('name').
2430 2441
2431 2442 This provides a proper Python function to call IPython's magics in any
2432 2443 valid Python code you can type at the interpreter, including loops and
2433 2444 compound statements.
2434 2445 """
2435 2446 warnings.warn(
2436 2447 "`magic(...)` is deprecated since IPython 0.13 (warning added in "
2437 2448 "8.1), use run_line_magic(magic_name, parameter_s).",
2438 2449 DeprecationWarning,
2439 2450 stacklevel=2,
2440 2451 )
2441 2452 # TODO: should we issue a loud deprecation warning here?
2442 2453 magic_name, _, magic_arg_s = arg_s.partition(' ')
2443 2454 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2444 2455 return self.run_line_magic(magic_name, magic_arg_s, _stack_depth=2)
2445 2456
2446 2457 #-------------------------------------------------------------------------
2447 2458 # Things related to macros
2448 2459 #-------------------------------------------------------------------------
2449 2460
2450 2461 def define_macro(self, name, themacro):
2451 2462 """Define a new macro
2452 2463
2453 2464 Parameters
2454 2465 ----------
2455 2466 name : str
2456 2467 The name of the macro.
2457 2468 themacro : str or Macro
2458 2469 The action to do upon invoking the macro. If a string, a new
2459 2470 Macro object is created by passing the string to it.
2460 2471 """
2461 2472
2462 2473 from IPython.core import macro
2463 2474
2464 2475 if isinstance(themacro, str):
2465 2476 themacro = macro.Macro(themacro)
2466 2477 if not isinstance(themacro, macro.Macro):
2467 2478 raise ValueError('A macro must be a string or a Macro instance.')
2468 2479 self.user_ns[name] = themacro
2469 2480
2470 2481 #-------------------------------------------------------------------------
2471 2482 # Things related to the running of system commands
2472 2483 #-------------------------------------------------------------------------
2473 2484
2474 2485 def system_piped(self, cmd):
2475 2486 """Call the given cmd in a subprocess, piping stdout/err
2476 2487
2477 2488 Parameters
2478 2489 ----------
2479 2490 cmd : str
2480 2491 Command to execute (can not end in '&', as background processes are
2481 2492 not supported. Should not be a command that expects input
2482 2493 other than simple text.
2483 2494 """
2484 2495 if cmd.rstrip().endswith('&'):
2485 2496 # this is *far* from a rigorous test
2486 2497 # We do not support backgrounding processes because we either use
2487 2498 # pexpect or pipes to read from. Users can always just call
2488 2499 # os.system() or use ip.system=ip.system_raw
2489 2500 # if they really want a background process.
2490 2501 raise OSError("Background processes not supported.")
2491 2502
2492 2503 # we explicitly do NOT return the subprocess status code, because
2493 2504 # a non-None value would trigger :func:`sys.displayhook` calls.
2494 2505 # Instead, we store the exit_code in user_ns.
2495 2506 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2496 2507
2497 2508 def system_raw(self, cmd):
2498 2509 """Call the given cmd in a subprocess using os.system on Windows or
2499 2510 subprocess.call using the system shell on other platforms.
2500 2511
2501 2512 Parameters
2502 2513 ----------
2503 2514 cmd : str
2504 2515 Command to execute.
2505 2516 """
2506 2517 cmd = self.var_expand(cmd, depth=1)
2507 2518 # warn if there is an IPython magic alternative.
2508 2519 main_cmd = cmd.split()[0]
2509 2520 has_magic_alternatives = ("pip", "conda", "cd")
2510 2521
2511 2522 if main_cmd in has_magic_alternatives:
2512 2523 warnings.warn(
2513 2524 (
2514 2525 "You executed the system command !{0} which may not work "
2515 2526 "as expected. Try the IPython magic %{0} instead."
2516 2527 ).format(main_cmd)
2517 2528 )
2518 2529
2519 2530 # protect os.system from UNC paths on Windows, which it can't handle:
2520 2531 if sys.platform == 'win32':
2521 2532 from IPython.utils._process_win32 import AvoidUNCPath
2522 2533 with AvoidUNCPath() as path:
2523 2534 if path is not None:
2524 2535 cmd = '"pushd %s &&"%s' % (path, cmd)
2525 2536 try:
2526 2537 ec = os.system(cmd)
2527 2538 except KeyboardInterrupt:
2528 2539 print('\n' + self.get_exception_only(), file=sys.stderr)
2529 2540 ec = -2
2530 2541 else:
2531 2542 # For posix the result of the subprocess.call() below is an exit
2532 2543 # code, which by convention is zero for success, positive for
2533 2544 # program failure. Exit codes above 128 are reserved for signals,
2534 2545 # and the formula for converting a signal to an exit code is usually
2535 2546 # signal_number+128. To more easily differentiate between exit
2536 2547 # codes and signals, ipython uses negative numbers. For instance
2537 2548 # since control-c is signal 2 but exit code 130, ipython's
2538 2549 # _exit_code variable will read -2. Note that some shells like
2539 2550 # csh and fish don't follow sh/bash conventions for exit codes.
2540 2551 executable = os.environ.get('SHELL', None)
2541 2552 try:
2542 2553 # Use env shell instead of default /bin/sh
2543 2554 ec = subprocess.call(cmd, shell=True, executable=executable)
2544 2555 except KeyboardInterrupt:
2545 2556 # intercept control-C; a long traceback is not useful here
2546 2557 print('\n' + self.get_exception_only(), file=sys.stderr)
2547 2558 ec = 130
2548 2559 if ec > 128:
2549 2560 ec = -(ec - 128)
2550 2561
2551 2562 # We explicitly do NOT return the subprocess status code, because
2552 2563 # a non-None value would trigger :func:`sys.displayhook` calls.
2553 2564 # Instead, we store the exit_code in user_ns. Note the semantics
2554 2565 # of _exit_code: for control-c, _exit_code == -signal.SIGNIT,
2555 2566 # but raising SystemExit(_exit_code) will give status 254!
2556 2567 self.user_ns['_exit_code'] = ec
2557 2568
2558 2569 # use piped system by default, because it is better behaved
2559 2570 system = system_piped
2560 2571
2561 2572 def getoutput(self, cmd, split=True, depth=0):
2562 2573 """Get output (possibly including stderr) from a subprocess.
2563 2574
2564 2575 Parameters
2565 2576 ----------
2566 2577 cmd : str
2567 2578 Command to execute (can not end in '&', as background processes are
2568 2579 not supported.
2569 2580 split : bool, optional
2570 2581 If True, split the output into an IPython SList. Otherwise, an
2571 2582 IPython LSString is returned. These are objects similar to normal
2572 2583 lists and strings, with a few convenience attributes for easier
2573 2584 manipulation of line-based output. You can use '?' on them for
2574 2585 details.
2575 2586 depth : int, optional
2576 2587 How many frames above the caller are the local variables which should
2577 2588 be expanded in the command string? The default (0) assumes that the
2578 2589 expansion variables are in the stack frame calling this function.
2579 2590 """
2580 2591 if cmd.rstrip().endswith('&'):
2581 2592 # this is *far* from a rigorous test
2582 2593 raise OSError("Background processes not supported.")
2583 2594 out = getoutput(self.var_expand(cmd, depth=depth+1))
2584 2595 if split:
2585 2596 out = SList(out.splitlines())
2586 2597 else:
2587 2598 out = LSString(out)
2588 2599 return out
2589 2600
2590 2601 #-------------------------------------------------------------------------
2591 2602 # Things related to aliases
2592 2603 #-------------------------------------------------------------------------
2593 2604
2594 2605 def init_alias(self):
2595 2606 self.alias_manager = AliasManager(shell=self, parent=self)
2596 2607 self.configurables.append(self.alias_manager)
2597 2608
2598 2609 #-------------------------------------------------------------------------
2599 2610 # Things related to extensions
2600 2611 #-------------------------------------------------------------------------
2601 2612
2602 2613 def init_extension_manager(self):
2603 2614 self.extension_manager = ExtensionManager(shell=self, parent=self)
2604 2615 self.configurables.append(self.extension_manager)
2605 2616
2606 2617 #-------------------------------------------------------------------------
2607 2618 # Things related to payloads
2608 2619 #-------------------------------------------------------------------------
2609 2620
2610 2621 def init_payload(self):
2611 2622 self.payload_manager = PayloadManager(parent=self)
2612 2623 self.configurables.append(self.payload_manager)
2613 2624
2614 2625 #-------------------------------------------------------------------------
2615 2626 # Things related to the prefilter
2616 2627 #-------------------------------------------------------------------------
2617 2628
2618 2629 def init_prefilter(self):
2619 2630 self.prefilter_manager = PrefilterManager(shell=self, parent=self)
2620 2631 self.configurables.append(self.prefilter_manager)
2621 2632 # Ultimately this will be refactored in the new interpreter code, but
2622 2633 # for now, we should expose the main prefilter method (there's legacy
2623 2634 # code out there that may rely on this).
2624 2635 self.prefilter = self.prefilter_manager.prefilter_lines
2625 2636
2626 2637 def auto_rewrite_input(self, cmd):
2627 2638 """Print to the screen the rewritten form of the user's command.
2628 2639
2629 2640 This shows visual feedback by rewriting input lines that cause
2630 2641 automatic calling to kick in, like::
2631 2642
2632 2643 /f x
2633 2644
2634 2645 into::
2635 2646
2636 2647 ------> f(x)
2637 2648
2638 2649 after the user's input prompt. This helps the user understand that the
2639 2650 input line was transformed automatically by IPython.
2640 2651 """
2641 2652 if not self.show_rewritten_input:
2642 2653 return
2643 2654
2644 2655 # This is overridden in TerminalInteractiveShell to use fancy prompts
2645 2656 print("------> " + cmd)
2646 2657
2647 2658 #-------------------------------------------------------------------------
2648 2659 # Things related to extracting values/expressions from kernel and user_ns
2649 2660 #-------------------------------------------------------------------------
2650 2661
2651 2662 def _user_obj_error(self):
2652 2663 """return simple exception dict
2653 2664
2654 2665 for use in user_expressions
2655 2666 """
2656 2667
2657 2668 etype, evalue, tb = self._get_exc_info()
2658 2669 stb = self.InteractiveTB.get_exception_only(etype, evalue)
2659 2670
2660 2671 exc_info = {
2661 2672 "status": "error",
2662 2673 "traceback": stb,
2663 2674 "ename": etype.__name__,
2664 2675 "evalue": py3compat.safe_unicode(evalue),
2665 2676 }
2666 2677
2667 2678 return exc_info
2668 2679
2669 2680 def _format_user_obj(self, obj):
2670 2681 """format a user object to display dict
2671 2682
2672 2683 for use in user_expressions
2673 2684 """
2674 2685
2675 2686 data, md = self.display_formatter.format(obj)
2676 2687 value = {
2677 2688 'status' : 'ok',
2678 2689 'data' : data,
2679 2690 'metadata' : md,
2680 2691 }
2681 2692 return value
2682 2693
2683 2694 def user_expressions(self, expressions):
2684 2695 """Evaluate a dict of expressions in the user's namespace.
2685 2696
2686 2697 Parameters
2687 2698 ----------
2688 2699 expressions : dict
2689 2700 A dict with string keys and string values. The expression values
2690 2701 should be valid Python expressions, each of which will be evaluated
2691 2702 in the user namespace.
2692 2703
2693 2704 Returns
2694 2705 -------
2695 2706 A dict, keyed like the input expressions dict, with the rich mime-typed
2696 2707 display_data of each value.
2697 2708 """
2698 2709 out = {}
2699 2710 user_ns = self.user_ns
2700 2711 global_ns = self.user_global_ns
2701 2712
2702 2713 for key, expr in expressions.items():
2703 2714 try:
2704 2715 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2705 2716 except:
2706 2717 value = self._user_obj_error()
2707 2718 out[key] = value
2708 2719 return out
2709 2720
2710 2721 #-------------------------------------------------------------------------
2711 2722 # Things related to the running of code
2712 2723 #-------------------------------------------------------------------------
2713 2724
2714 2725 def ex(self, cmd):
2715 2726 """Execute a normal python statement in user namespace."""
2716 2727 with self.builtin_trap:
2717 2728 exec(cmd, self.user_global_ns, self.user_ns)
2718 2729
2719 2730 def ev(self, expr):
2720 2731 """Evaluate python expression expr in user namespace.
2721 2732
2722 2733 Returns the result of evaluation
2723 2734 """
2724 2735 with self.builtin_trap:
2725 2736 return eval(expr, self.user_global_ns, self.user_ns)
2726 2737
2727 2738 def safe_execfile(self, fname, *where, exit_ignore=False, raise_exceptions=False, shell_futures=False):
2728 2739 """A safe version of the builtin execfile().
2729 2740
2730 2741 This version will never throw an exception, but instead print
2731 2742 helpful error messages to the screen. This only works on pure
2732 2743 Python files with the .py extension.
2733 2744
2734 2745 Parameters
2735 2746 ----------
2736 2747 fname : string
2737 2748 The name of the file to be executed.
2738 2749 *where : tuple
2739 2750 One or two namespaces, passed to execfile() as (globals,locals).
2740 2751 If only one is given, it is passed as both.
2741 2752 exit_ignore : bool (False)
2742 2753 If True, then silence SystemExit for non-zero status (it is always
2743 2754 silenced for zero status, as it is so common).
2744 2755 raise_exceptions : bool (False)
2745 2756 If True raise exceptions everywhere. Meant for testing.
2746 2757 shell_futures : bool (False)
2747 2758 If True, the code will share future statements with the interactive
2748 2759 shell. It will both be affected by previous __future__ imports, and
2749 2760 any __future__ imports in the code will affect the shell. If False,
2750 2761 __future__ imports are not shared in either direction.
2751 2762
2752 2763 """
2753 2764 fname = Path(fname).expanduser().resolve()
2754 2765
2755 2766 # Make sure we can open the file
2756 2767 try:
2757 2768 with fname.open("rb"):
2758 2769 pass
2759 2770 except:
2760 2771 warn('Could not open file <%s> for safe execution.' % fname)
2761 2772 return
2762 2773
2763 2774 # Find things also in current directory. This is needed to mimic the
2764 2775 # behavior of running a script from the system command line, where
2765 2776 # Python inserts the script's directory into sys.path
2766 2777 dname = str(fname.parent)
2767 2778
2768 2779 with prepended_to_syspath(dname), self.builtin_trap:
2769 2780 try:
2770 2781 glob, loc = (where + (None, ))[:2]
2771 2782 py3compat.execfile(
2772 2783 fname, glob, loc,
2773 2784 self.compile if shell_futures else None)
2774 2785 except SystemExit as status:
2775 2786 # If the call was made with 0 or None exit status (sys.exit(0)
2776 2787 # or sys.exit() ), don't bother showing a traceback, as both of
2777 2788 # these are considered normal by the OS:
2778 2789 # > python -c'import sys;sys.exit(0)'; echo $?
2779 2790 # 0
2780 2791 # > python -c'import sys;sys.exit()'; echo $?
2781 2792 # 0
2782 2793 # For other exit status, we show the exception unless
2783 2794 # explicitly silenced, but only in short form.
2784 2795 if status.code:
2785 2796 if raise_exceptions:
2786 2797 raise
2787 2798 if not exit_ignore:
2788 2799 self.showtraceback(exception_only=True)
2789 2800 except:
2790 2801 if raise_exceptions:
2791 2802 raise
2792 2803 # tb offset is 2 because we wrap execfile
2793 2804 self.showtraceback(tb_offset=2)
2794 2805
2795 2806 def safe_execfile_ipy(self, fname, shell_futures=False, raise_exceptions=False):
2796 2807 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2797 2808
2798 2809 Parameters
2799 2810 ----------
2800 2811 fname : str
2801 2812 The name of the file to execute. The filename must have a
2802 2813 .ipy or .ipynb extension.
2803 2814 shell_futures : bool (False)
2804 2815 If True, the code will share future statements with the interactive
2805 2816 shell. It will both be affected by previous __future__ imports, and
2806 2817 any __future__ imports in the code will affect the shell. If False,
2807 2818 __future__ imports are not shared in either direction.
2808 2819 raise_exceptions : bool (False)
2809 2820 If True raise exceptions everywhere. Meant for testing.
2810 2821 """
2811 2822 fname = Path(fname).expanduser().resolve()
2812 2823
2813 2824 # Make sure we can open the file
2814 2825 try:
2815 2826 with fname.open("rb"):
2816 2827 pass
2817 2828 except:
2818 2829 warn('Could not open file <%s> for safe execution.' % fname)
2819 2830 return
2820 2831
2821 2832 # Find things also in current directory. This is needed to mimic the
2822 2833 # behavior of running a script from the system command line, where
2823 2834 # Python inserts the script's directory into sys.path
2824 2835 dname = str(fname.parent)
2825 2836
2826 2837 def get_cells():
2827 2838 """generator for sequence of code blocks to run"""
2828 2839 if fname.suffix == ".ipynb":
2829 2840 from nbformat import read
2830 2841 nb = read(fname, as_version=4)
2831 2842 if not nb.cells:
2832 2843 return
2833 2844 for cell in nb.cells:
2834 2845 if cell.cell_type == 'code':
2835 2846 yield cell.source
2836 2847 else:
2837 2848 yield fname.read_text(encoding="utf-8")
2838 2849
2839 2850 with prepended_to_syspath(dname):
2840 2851 try:
2841 2852 for cell in get_cells():
2842 2853 result = self.run_cell(cell, silent=True, shell_futures=shell_futures)
2843 2854 if raise_exceptions:
2844 2855 result.raise_error()
2845 2856 elif not result.success:
2846 2857 break
2847 2858 except:
2848 2859 if raise_exceptions:
2849 2860 raise
2850 2861 self.showtraceback()
2851 2862 warn('Unknown failure executing file: <%s>' % fname)
2852 2863
2853 2864 def safe_run_module(self, mod_name, where):
2854 2865 """A safe version of runpy.run_module().
2855 2866
2856 2867 This version will never throw an exception, but instead print
2857 2868 helpful error messages to the screen.
2858 2869
2859 2870 `SystemExit` exceptions with status code 0 or None are ignored.
2860 2871
2861 2872 Parameters
2862 2873 ----------
2863 2874 mod_name : string
2864 2875 The name of the module to be executed.
2865 2876 where : dict
2866 2877 The globals namespace.
2867 2878 """
2868 2879 try:
2869 2880 try:
2870 2881 where.update(
2871 2882 runpy.run_module(str(mod_name), run_name="__main__",
2872 2883 alter_sys=True)
2873 2884 )
2874 2885 except SystemExit as status:
2875 2886 if status.code:
2876 2887 raise
2877 2888 except:
2878 2889 self.showtraceback()
2879 2890 warn('Unknown failure executing module: <%s>' % mod_name)
2880 2891
2881 2892 def run_cell(
2882 2893 self,
2883 2894 raw_cell,
2884 2895 store_history=False,
2885 2896 silent=False,
2886 2897 shell_futures=True,
2887 2898 cell_id=None,
2888 2899 ):
2889 2900 """Run a complete IPython cell.
2890 2901
2891 2902 Parameters
2892 2903 ----------
2893 2904 raw_cell : str
2894 2905 The code (including IPython code such as %magic functions) to run.
2895 2906 store_history : bool
2896 2907 If True, the raw and translated cell will be stored in IPython's
2897 2908 history. For user code calling back into IPython's machinery, this
2898 2909 should be set to False.
2899 2910 silent : bool
2900 2911 If True, avoid side-effects, such as implicit displayhooks and
2901 2912 and logging. silent=True forces store_history=False.
2902 2913 shell_futures : bool
2903 2914 If True, the code will share future statements with the interactive
2904 2915 shell. It will both be affected by previous __future__ imports, and
2905 2916 any __future__ imports in the code will affect the shell. If False,
2906 2917 __future__ imports are not shared in either direction.
2907 2918
2908 2919 Returns
2909 2920 -------
2910 2921 result : :class:`ExecutionResult`
2911 2922 """
2912 2923 result = None
2913 2924 try:
2914 2925 result = self._run_cell(
2915 2926 raw_cell, store_history, silent, shell_futures, cell_id
2916 2927 )
2917 2928 finally:
2918 2929 self.events.trigger('post_execute')
2919 2930 if not silent:
2920 2931 self.events.trigger('post_run_cell', result)
2921 2932 return result
2922 2933
2923 2934 def _run_cell(
2924 2935 self,
2925 2936 raw_cell: str,
2926 2937 store_history: bool,
2927 2938 silent: bool,
2928 2939 shell_futures: bool,
2929 2940 cell_id: str,
2930 2941 ) -> ExecutionResult:
2931 2942 """Internal method to run a complete IPython cell."""
2932 2943
2933 2944 # we need to avoid calling self.transform_cell multiple time on the same thing
2934 2945 # so we need to store some results:
2935 2946 preprocessing_exc_tuple = None
2936 2947 try:
2937 2948 transformed_cell = self.transform_cell(raw_cell)
2938 2949 except Exception:
2939 2950 transformed_cell = raw_cell
2940 2951 preprocessing_exc_tuple = sys.exc_info()
2941 2952
2942 2953 assert transformed_cell is not None
2943 2954 coro = self.run_cell_async(
2944 2955 raw_cell,
2945 2956 store_history=store_history,
2946 2957 silent=silent,
2947 2958 shell_futures=shell_futures,
2948 2959 transformed_cell=transformed_cell,
2949 2960 preprocessing_exc_tuple=preprocessing_exc_tuple,
2950 2961 cell_id=cell_id,
2951 2962 )
2952 2963
2953 2964 # run_cell_async is async, but may not actually need an eventloop.
2954 2965 # when this is the case, we want to run it using the pseudo_sync_runner
2955 2966 # so that code can invoke eventloops (for example via the %run , and
2956 2967 # `%paste` magic.
2957 2968 if self.trio_runner:
2958 2969 runner = self.trio_runner
2959 2970 elif self.should_run_async(
2960 2971 raw_cell,
2961 2972 transformed_cell=transformed_cell,
2962 2973 preprocessing_exc_tuple=preprocessing_exc_tuple,
2963 2974 ):
2964 2975 runner = self.loop_runner
2965 2976 else:
2966 2977 runner = _pseudo_sync_runner
2967 2978
2968 2979 try:
2969 2980 return runner(coro)
2970 2981 except BaseException as e:
2971 2982 info = ExecutionInfo(
2972 2983 raw_cell, store_history, silent, shell_futures, cell_id
2973 2984 )
2974 2985 result = ExecutionResult(info)
2975 2986 result.error_in_exec = e
2976 2987 self.showtraceback(running_compiled_code=True)
2977 2988 return result
2978 2989
2979 2990 def should_run_async(
2980 2991 self, raw_cell: str, *, transformed_cell=None, preprocessing_exc_tuple=None
2981 2992 ) -> bool:
2982 2993 """Return whether a cell should be run asynchronously via a coroutine runner
2983 2994
2984 2995 Parameters
2985 2996 ----------
2986 2997 raw_cell : str
2987 2998 The code to be executed
2988 2999
2989 3000 Returns
2990 3001 -------
2991 3002 result: bool
2992 3003 Whether the code needs to be run with a coroutine runner or not
2993 3004 .. versionadded:: 7.0
2994 3005 """
2995 3006 if not self.autoawait:
2996 3007 return False
2997 3008 if preprocessing_exc_tuple is not None:
2998 3009 return False
2999 3010 assert preprocessing_exc_tuple is None
3000 3011 if transformed_cell is None:
3001 3012 warnings.warn(
3002 3013 "`should_run_async` will not call `transform_cell`"
3003 3014 " automatically in the future. Please pass the result to"
3004 3015 " `transformed_cell` argument and any exception that happen"
3005 3016 " during the"
3006 3017 "transform in `preprocessing_exc_tuple` in"
3007 3018 " IPython 7.17 and above.",
3008 3019 DeprecationWarning,
3009 3020 stacklevel=2,
3010 3021 )
3011 3022 try:
3012 3023 cell = self.transform_cell(raw_cell)
3013 3024 except Exception:
3014 3025 # any exception during transform will be raised
3015 3026 # prior to execution
3016 3027 return False
3017 3028 else:
3018 3029 cell = transformed_cell
3019 3030 return _should_be_async(cell)
3020 3031
3021 3032 async def run_cell_async(
3022 3033 self,
3023 3034 raw_cell: str,
3024 3035 store_history=False,
3025 3036 silent=False,
3026 3037 shell_futures=True,
3027 3038 *,
3028 3039 transformed_cell: Optional[str] = None,
3029 3040 preprocessing_exc_tuple: Optional[Any] = None,
3030 3041 cell_id=None,
3031 3042 ) -> ExecutionResult:
3032 3043 """Run a complete IPython cell asynchronously.
3033 3044
3034 3045 Parameters
3035 3046 ----------
3036 3047 raw_cell : str
3037 3048 The code (including IPython code such as %magic functions) to run.
3038 3049 store_history : bool
3039 3050 If True, the raw and translated cell will be stored in IPython's
3040 3051 history. For user code calling back into IPython's machinery, this
3041 3052 should be set to False.
3042 3053 silent : bool
3043 3054 If True, avoid side-effects, such as implicit displayhooks and
3044 3055 and logging. silent=True forces store_history=False.
3045 3056 shell_futures : bool
3046 3057 If True, the code will share future statements with the interactive
3047 3058 shell. It will both be affected by previous __future__ imports, and
3048 3059 any __future__ imports in the code will affect the shell. If False,
3049 3060 __future__ imports are not shared in either direction.
3050 3061 transformed_cell: str
3051 3062 cell that was passed through transformers
3052 3063 preprocessing_exc_tuple:
3053 3064 trace if the transformation failed.
3054 3065
3055 3066 Returns
3056 3067 -------
3057 3068 result : :class:`ExecutionResult`
3058 3069
3059 3070 .. versionadded:: 7.0
3060 3071 """
3061 3072 info = ExecutionInfo(raw_cell, store_history, silent, shell_futures, cell_id)
3062 3073 result = ExecutionResult(info)
3063 3074
3064 3075 if (not raw_cell) or raw_cell.isspace():
3065 3076 self.last_execution_succeeded = True
3066 3077 self.last_execution_result = result
3067 3078 return result
3068 3079
3069 3080 if silent:
3070 3081 store_history = False
3071 3082
3072 3083 if store_history:
3073 3084 result.execution_count = self.execution_count
3074 3085
3075 3086 def error_before_exec(value):
3076 3087 if store_history:
3077 3088 self.execution_count += 1
3078 3089 result.error_before_exec = value
3079 3090 self.last_execution_succeeded = False
3080 3091 self.last_execution_result = result
3081 3092 return result
3082 3093
3083 3094 self.events.trigger('pre_execute')
3084 3095 if not silent:
3085 3096 self.events.trigger('pre_run_cell', info)
3086 3097
3087 3098 if transformed_cell is None:
3088 3099 warnings.warn(
3089 3100 "`run_cell_async` will not call `transform_cell`"
3090 3101 " automatically in the future. Please pass the result to"
3091 3102 " `transformed_cell` argument and any exception that happen"
3092 3103 " during the"
3093 3104 "transform in `preprocessing_exc_tuple` in"
3094 3105 " IPython 7.17 and above.",
3095 3106 DeprecationWarning,
3096 3107 stacklevel=2,
3097 3108 )
3098 3109 # If any of our input transformation (input_transformer_manager or
3099 3110 # prefilter_manager) raises an exception, we store it in this variable
3100 3111 # so that we can display the error after logging the input and storing
3101 3112 # it in the history.
3102 3113 try:
3103 3114 cell = self.transform_cell(raw_cell)
3104 3115 except Exception:
3105 3116 preprocessing_exc_tuple = sys.exc_info()
3106 3117 cell = raw_cell # cell has to exist so it can be stored/logged
3107 3118 else:
3108 3119 preprocessing_exc_tuple = None
3109 3120 else:
3110 3121 if preprocessing_exc_tuple is None:
3111 3122 cell = transformed_cell
3112 3123 else:
3113 3124 cell = raw_cell
3114 3125
3115 3126 # Store raw and processed history
3116 3127 if store_history and raw_cell.strip(" %") != "paste":
3117 3128 self.history_manager.store_inputs(self.execution_count, cell, raw_cell)
3118 3129 if not silent:
3119 3130 self.logger.log(cell, raw_cell)
3120 3131
3121 3132 # Display the exception if input processing failed.
3122 3133 if preprocessing_exc_tuple is not None:
3123 3134 self.showtraceback(preprocessing_exc_tuple)
3124 3135 if store_history:
3125 3136 self.execution_count += 1
3126 3137 return error_before_exec(preprocessing_exc_tuple[1])
3127 3138
3128 3139 # Our own compiler remembers the __future__ environment. If we want to
3129 3140 # run code with a separate __future__ environment, use the default
3130 3141 # compiler
3131 3142 compiler = self.compile if shell_futures else self.compiler_class()
3132 3143
3133 3144 _run_async = False
3134 3145
3135 3146 with self.builtin_trap:
3136 3147 cell_name = compiler.cache(cell, self.execution_count, raw_code=raw_cell)
3137 3148
3138 3149 with self.display_trap:
3139 3150 # Compile to bytecode
3140 3151 try:
3141 3152 code_ast = compiler.ast_parse(cell, filename=cell_name)
3142 3153 except self.custom_exceptions as e:
3143 3154 etype, value, tb = sys.exc_info()
3144 3155 self.CustomTB(etype, value, tb)
3145 3156 return error_before_exec(e)
3146 3157 except IndentationError as e:
3147 3158 self.showindentationerror()
3148 3159 return error_before_exec(e)
3149 3160 except (OverflowError, SyntaxError, ValueError, TypeError,
3150 3161 MemoryError) as e:
3151 3162 self.showsyntaxerror()
3152 3163 return error_before_exec(e)
3153 3164
3154 3165 # Apply AST transformations
3155 3166 try:
3156 3167 code_ast = self.transform_ast(code_ast)
3157 3168 except InputRejected as e:
3158 3169 self.showtraceback()
3159 3170 return error_before_exec(e)
3160 3171
3161 3172 # Give the displayhook a reference to our ExecutionResult so it
3162 3173 # can fill in the output value.
3163 3174 self.displayhook.exec_result = result
3164 3175
3165 3176 # Execute the user code
3166 3177 interactivity = "none" if silent else self.ast_node_interactivity
3167 3178
3168 3179 has_raised = await self.run_ast_nodes(code_ast.body, cell_name,
3169 3180 interactivity=interactivity, compiler=compiler, result=result)
3170 3181
3171 3182 self.last_execution_succeeded = not has_raised
3172 3183 self.last_execution_result = result
3173 3184
3174 3185 # Reset this so later displayed values do not modify the
3175 3186 # ExecutionResult
3176 3187 self.displayhook.exec_result = None
3177 3188
3178 3189 if store_history:
3179 3190 # Write output to the database. Does nothing unless
3180 3191 # history output logging is enabled.
3181 3192 self.history_manager.store_output(self.execution_count)
3182 3193 # Each cell is a *single* input, regardless of how many lines it has
3183 3194 self.execution_count += 1
3184 3195
3185 3196 return result
3186 3197
3187 3198 def transform_cell(self, raw_cell):
3188 3199 """Transform an input cell before parsing it.
3189 3200
3190 3201 Static transformations, implemented in IPython.core.inputtransformer2,
3191 3202 deal with things like ``%magic`` and ``!system`` commands.
3192 3203 These run on all input.
3193 3204 Dynamic transformations, for things like unescaped magics and the exit
3194 3205 autocall, depend on the state of the interpreter.
3195 3206 These only apply to single line inputs.
3196 3207
3197 3208 These string-based transformations are followed by AST transformations;
3198 3209 see :meth:`transform_ast`.
3199 3210 """
3200 3211 # Static input transformations
3201 3212 cell = self.input_transformer_manager.transform_cell(raw_cell)
3202 3213
3203 3214 if len(cell.splitlines()) == 1:
3204 3215 # Dynamic transformations - only applied for single line commands
3205 3216 with self.builtin_trap:
3206 3217 # use prefilter_lines to handle trailing newlines
3207 3218 # restore trailing newline for ast.parse
3208 3219 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
3209 3220
3210 3221 lines = cell.splitlines(keepends=True)
3211 3222 for transform in self.input_transformers_post:
3212 3223 lines = transform(lines)
3213 3224 cell = ''.join(lines)
3214 3225
3215 3226 return cell
3216 3227
3217 3228 def transform_ast(self, node):
3218 3229 """Apply the AST transformations from self.ast_transformers
3219 3230
3220 3231 Parameters
3221 3232 ----------
3222 3233 node : ast.Node
3223 3234 The root node to be transformed. Typically called with the ast.Module
3224 3235 produced by parsing user input.
3225 3236
3226 3237 Returns
3227 3238 -------
3228 3239 An ast.Node corresponding to the node it was called with. Note that it
3229 3240 may also modify the passed object, so don't rely on references to the
3230 3241 original AST.
3231 3242 """
3232 3243 for transformer in self.ast_transformers:
3233 3244 try:
3234 3245 node = transformer.visit(node)
3235 3246 except InputRejected:
3236 3247 # User-supplied AST transformers can reject an input by raising
3237 3248 # an InputRejected. Short-circuit in this case so that we
3238 3249 # don't unregister the transform.
3239 3250 raise
3240 3251 except Exception:
3241 3252 warn("AST transformer %r threw an error. It will be unregistered." % transformer)
3242 3253 self.ast_transformers.remove(transformer)
3243 3254
3244 3255 if self.ast_transformers:
3245 3256 ast.fix_missing_locations(node)
3246 3257 return node
3247 3258
3248 3259 async def run_ast_nodes(
3249 3260 self,
3250 3261 nodelist: ListType[stmt],
3251 3262 cell_name: str,
3252 3263 interactivity="last_expr",
3253 3264 compiler=compile,
3254 3265 result=None,
3255 3266 ):
3256 3267 """Run a sequence of AST nodes. The execution mode depends on the
3257 3268 interactivity parameter.
3258 3269
3259 3270 Parameters
3260 3271 ----------
3261 3272 nodelist : list
3262 3273 A sequence of AST nodes to run.
3263 3274 cell_name : str
3264 3275 Will be passed to the compiler as the filename of the cell. Typically
3265 3276 the value returned by ip.compile.cache(cell).
3266 3277 interactivity : str
3267 3278 'all', 'last', 'last_expr' , 'last_expr_or_assign' or 'none',
3268 3279 specifying which nodes should be run interactively (displaying output
3269 3280 from expressions). 'last_expr' will run the last node interactively
3270 3281 only if it is an expression (i.e. expressions in loops or other blocks
3271 3282 are not displayed) 'last_expr_or_assign' will run the last expression
3272 3283 or the last assignment. Other values for this parameter will raise a
3273 3284 ValueError.
3274 3285
3275 3286 compiler : callable
3276 3287 A function with the same interface as the built-in compile(), to turn
3277 3288 the AST nodes into code objects. Default is the built-in compile().
3278 3289 result : ExecutionResult, optional
3279 3290 An object to store exceptions that occur during execution.
3280 3291
3281 3292 Returns
3282 3293 -------
3283 3294 True if an exception occurred while running code, False if it finished
3284 3295 running.
3285 3296 """
3286 3297 if not nodelist:
3287 3298 return
3288 3299
3289 3300
3290 3301 if interactivity == 'last_expr_or_assign':
3291 3302 if isinstance(nodelist[-1], _assign_nodes):
3292 3303 asg = nodelist[-1]
3293 3304 if isinstance(asg, ast.Assign) and len(asg.targets) == 1:
3294 3305 target = asg.targets[0]
3295 3306 elif isinstance(asg, _single_targets_nodes):
3296 3307 target = asg.target
3297 3308 else:
3298 3309 target = None
3299 3310 if isinstance(target, ast.Name):
3300 3311 nnode = ast.Expr(ast.Name(target.id, ast.Load()))
3301 3312 ast.fix_missing_locations(nnode)
3302 3313 nodelist.append(nnode)
3303 3314 interactivity = 'last_expr'
3304 3315
3305 3316 _async = False
3306 3317 if interactivity == 'last_expr':
3307 3318 if isinstance(nodelist[-1], ast.Expr):
3308 3319 interactivity = "last"
3309 3320 else:
3310 3321 interactivity = "none"
3311 3322
3312 3323 if interactivity == 'none':
3313 3324 to_run_exec, to_run_interactive = nodelist, []
3314 3325 elif interactivity == 'last':
3315 3326 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
3316 3327 elif interactivity == 'all':
3317 3328 to_run_exec, to_run_interactive = [], nodelist
3318 3329 else:
3319 3330 raise ValueError("Interactivity was %r" % interactivity)
3320 3331
3321 3332 try:
3322 3333
3323 3334 def compare(code):
3324 3335 is_async = inspect.CO_COROUTINE & code.co_flags == inspect.CO_COROUTINE
3325 3336 return is_async
3326 3337
3327 3338 # refactor that to just change the mod constructor.
3328 3339 to_run = []
3329 3340 for node in to_run_exec:
3330 3341 to_run.append((node, "exec"))
3331 3342
3332 3343 for node in to_run_interactive:
3333 3344 to_run.append((node, "single"))
3334 3345
3335 3346 for node, mode in to_run:
3336 3347 if mode == "exec":
3337 3348 mod = Module([node], [])
3338 3349 elif mode == "single":
3339 3350 mod = ast.Interactive([node])
3340 3351 with compiler.extra_flags(
3341 3352 getattr(ast, "PyCF_ALLOW_TOP_LEVEL_AWAIT", 0x0)
3342 3353 if self.autoawait
3343 3354 else 0x0
3344 3355 ):
3345 3356 code = compiler(mod, cell_name, mode)
3346 3357 asy = compare(code)
3347 3358 if await self.run_code(code, result, async_=asy):
3348 3359 return True
3349 3360
3350 3361 # Flush softspace
3351 3362 if softspace(sys.stdout, 0):
3352 3363 print()
3353 3364
3354 3365 except:
3355 3366 # It's possible to have exceptions raised here, typically by
3356 3367 # compilation of odd code (such as a naked 'return' outside a
3357 3368 # function) that did parse but isn't valid. Typically the exception
3358 3369 # is a SyntaxError, but it's safest just to catch anything and show
3359 3370 # the user a traceback.
3360 3371
3361 3372 # We do only one try/except outside the loop to minimize the impact
3362 3373 # on runtime, and also because if any node in the node list is
3363 3374 # broken, we should stop execution completely.
3364 3375 if result:
3365 3376 result.error_before_exec = sys.exc_info()[1]
3366 3377 self.showtraceback()
3367 3378 return True
3368 3379
3369 3380 return False
3370 3381
3371 3382 async def run_code(self, code_obj, result=None, *, async_=False):
3372 3383 """Execute a code object.
3373 3384
3374 3385 When an exception occurs, self.showtraceback() is called to display a
3375 3386 traceback.
3376 3387
3377 3388 Parameters
3378 3389 ----------
3379 3390 code_obj : code object
3380 3391 A compiled code object, to be executed
3381 3392 result : ExecutionResult, optional
3382 3393 An object to store exceptions that occur during execution.
3383 3394 async_ : Bool (Experimental)
3384 3395 Attempt to run top-level asynchronous code in a default loop.
3385 3396
3386 3397 Returns
3387 3398 -------
3388 3399 False : successful execution.
3389 3400 True : an error occurred.
3390 3401 """
3391 3402 # special value to say that anything above is IPython and should be
3392 3403 # hidden.
3393 3404 __tracebackhide__ = "__ipython_bottom__"
3394 3405 # Set our own excepthook in case the user code tries to call it
3395 3406 # directly, so that the IPython crash handler doesn't get triggered
3396 3407 old_excepthook, sys.excepthook = sys.excepthook, self.excepthook
3397 3408
3398 3409 # we save the original sys.excepthook in the instance, in case config
3399 3410 # code (such as magics) needs access to it.
3400 3411 self.sys_excepthook = old_excepthook
3401 3412 outflag = True # happens in more places, so it's easier as default
3402 3413 try:
3403 3414 try:
3404 3415 if async_:
3405 3416 await eval(code_obj, self.user_global_ns, self.user_ns)
3406 3417 else:
3407 3418 exec(code_obj, self.user_global_ns, self.user_ns)
3408 3419 finally:
3409 3420 # Reset our crash handler in place
3410 3421 sys.excepthook = old_excepthook
3411 3422 except SystemExit as e:
3412 3423 if result is not None:
3413 3424 result.error_in_exec = e
3414 3425 self.showtraceback(exception_only=True)
3415 3426 warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
3416 3427 except bdb.BdbQuit:
3417 3428 etype, value, tb = sys.exc_info()
3418 3429 if result is not None:
3419 3430 result.error_in_exec = value
3420 3431 # the BdbQuit stops here
3421 3432 except self.custom_exceptions:
3422 3433 etype, value, tb = sys.exc_info()
3423 3434 if result is not None:
3424 3435 result.error_in_exec = value
3425 3436 self.CustomTB(etype, value, tb)
3426 3437 except:
3427 3438 if result is not None:
3428 3439 result.error_in_exec = sys.exc_info()[1]
3429 3440 self.showtraceback(running_compiled_code=True)
3430 3441 else:
3431 3442 outflag = False
3432 3443 return outflag
3433 3444
3434 3445 # For backwards compatibility
3435 3446 runcode = run_code
3436 3447
3437 3448 def check_complete(self, code: str) -> Tuple[str, str]:
3438 3449 """Return whether a block of code is ready to execute, or should be continued
3439 3450
3440 3451 Parameters
3441 3452 ----------
3442 3453 code : string
3443 3454 Python input code, which can be multiline.
3444 3455
3445 3456 Returns
3446 3457 -------
3447 3458 status : str
3448 3459 One of 'complete', 'incomplete', or 'invalid' if source is not a
3449 3460 prefix of valid code.
3450 3461 indent : str
3451 3462 When status is 'incomplete', this is some whitespace to insert on
3452 3463 the next line of the prompt.
3453 3464 """
3454 3465 status, nspaces = self.input_transformer_manager.check_complete(code)
3455 3466 return status, ' ' * (nspaces or 0)
3456 3467
3457 3468 #-------------------------------------------------------------------------
3458 3469 # Things related to GUI support and pylab
3459 3470 #-------------------------------------------------------------------------
3460 3471
3461 3472 active_eventloop = None
3462 3473
3463 3474 def enable_gui(self, gui=None):
3464 3475 raise NotImplementedError('Implement enable_gui in a subclass')
3465 3476
3466 3477 def enable_matplotlib(self, gui=None):
3467 3478 """Enable interactive matplotlib and inline figure support.
3468 3479
3469 3480 This takes the following steps:
3470 3481
3471 3482 1. select the appropriate eventloop and matplotlib backend
3472 3483 2. set up matplotlib for interactive use with that backend
3473 3484 3. configure formatters for inline figure display
3474 3485 4. enable the selected gui eventloop
3475 3486
3476 3487 Parameters
3477 3488 ----------
3478 3489 gui : optional, string
3479 3490 If given, dictates the choice of matplotlib GUI backend to use
3480 3491 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3481 3492 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3482 3493 matplotlib (as dictated by the matplotlib build-time options plus the
3483 3494 user's matplotlibrc configuration file). Note that not all backends
3484 3495 make sense in all contexts, for example a terminal ipython can't
3485 3496 display figures inline.
3486 3497 """
3487 3498 from matplotlib_inline.backend_inline import configure_inline_support
3488 3499
3489 3500 from IPython.core import pylabtools as pt
3490 3501 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
3491 3502
3492 3503 if gui != 'inline':
3493 3504 # If we have our first gui selection, store it
3494 3505 if self.pylab_gui_select is None:
3495 3506 self.pylab_gui_select = gui
3496 3507 # Otherwise if they are different
3497 3508 elif gui != self.pylab_gui_select:
3498 3509 print('Warning: Cannot change to a different GUI toolkit: %s.'
3499 3510 ' Using %s instead.' % (gui, self.pylab_gui_select))
3500 3511 gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
3501 3512
3502 3513 pt.activate_matplotlib(backend)
3503 3514 configure_inline_support(self, backend)
3504 3515
3505 3516 # Now we must activate the gui pylab wants to use, and fix %run to take
3506 3517 # plot updates into account
3507 3518 self.enable_gui(gui)
3508 3519 self.magics_manager.registry['ExecutionMagics'].default_runner = \
3509 3520 pt.mpl_runner(self.safe_execfile)
3510 3521
3511 3522 return gui, backend
3512 3523
3513 3524 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
3514 3525 """Activate pylab support at runtime.
3515 3526
3516 3527 This turns on support for matplotlib, preloads into the interactive
3517 3528 namespace all of numpy and pylab, and configures IPython to correctly
3518 3529 interact with the GUI event loop. The GUI backend to be used can be
3519 3530 optionally selected with the optional ``gui`` argument.
3520 3531
3521 3532 This method only adds preloading the namespace to InteractiveShell.enable_matplotlib.
3522 3533
3523 3534 Parameters
3524 3535 ----------
3525 3536 gui : optional, string
3526 3537 If given, dictates the choice of matplotlib GUI backend to use
3527 3538 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3528 3539 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3529 3540 matplotlib (as dictated by the matplotlib build-time options plus the
3530 3541 user's matplotlibrc configuration file). Note that not all backends
3531 3542 make sense in all contexts, for example a terminal ipython can't
3532 3543 display figures inline.
3533 3544 import_all : optional, bool, default: True
3534 3545 Whether to do `from numpy import *` and `from pylab import *`
3535 3546 in addition to module imports.
3536 3547 welcome_message : deprecated
3537 3548 This argument is ignored, no welcome message will be displayed.
3538 3549 """
3539 3550 from IPython.core.pylabtools import import_pylab
3540 3551
3541 3552 gui, backend = self.enable_matplotlib(gui)
3542 3553
3543 3554 # We want to prevent the loading of pylab to pollute the user's
3544 3555 # namespace as shown by the %who* magics, so we execute the activation
3545 3556 # code in an empty namespace, and we update *both* user_ns and
3546 3557 # user_ns_hidden with this information.
3547 3558 ns = {}
3548 3559 import_pylab(ns, import_all)
3549 3560 # warn about clobbered names
3550 3561 ignored = {"__builtins__"}
3551 3562 both = set(ns).intersection(self.user_ns).difference(ignored)
3552 3563 clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ]
3553 3564 self.user_ns.update(ns)
3554 3565 self.user_ns_hidden.update(ns)
3555 3566 return gui, backend, clobbered
3556 3567
3557 3568 #-------------------------------------------------------------------------
3558 3569 # Utilities
3559 3570 #-------------------------------------------------------------------------
3560 3571
3561 3572 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
3562 3573 """Expand python variables in a string.
3563 3574
3564 3575 The depth argument indicates how many frames above the caller should
3565 3576 be walked to look for the local namespace where to expand variables.
3566 3577
3567 3578 The global namespace for expansion is always the user's interactive
3568 3579 namespace.
3569 3580 """
3570 3581 ns = self.user_ns.copy()
3571 3582 try:
3572 3583 frame = sys._getframe(depth+1)
3573 3584 except ValueError:
3574 3585 # This is thrown if there aren't that many frames on the stack,
3575 3586 # e.g. if a script called run_line_magic() directly.
3576 3587 pass
3577 3588 else:
3578 3589 ns.update(frame.f_locals)
3579 3590
3580 3591 try:
3581 3592 # We have to use .vformat() here, because 'self' is a valid and common
3582 3593 # name, and expanding **ns for .format() would make it collide with
3583 3594 # the 'self' argument of the method.
3584 3595 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
3585 3596 except Exception:
3586 3597 # if formatter couldn't format, just let it go untransformed
3587 3598 pass
3588 3599 return cmd
3589 3600
3590 3601 def mktempfile(self, data=None, prefix='ipython_edit_'):
3591 3602 """Make a new tempfile and return its filename.
3592 3603
3593 3604 This makes a call to tempfile.mkstemp (created in a tempfile.mkdtemp),
3594 3605 but it registers the created filename internally so ipython cleans it up
3595 3606 at exit time.
3596 3607
3597 3608 Optional inputs:
3598 3609
3599 3610 - data(None): if data is given, it gets written out to the temp file
3600 3611 immediately, and the file is closed again."""
3601 3612
3602 3613 dir_path = Path(tempfile.mkdtemp(prefix=prefix))
3603 3614 self.tempdirs.append(dir_path)
3604 3615
3605 3616 handle, filename = tempfile.mkstemp(".py", prefix, dir=str(dir_path))
3606 3617 os.close(handle) # On Windows, there can only be one open handle on a file
3607 3618
3608 3619 file_path = Path(filename)
3609 3620 self.tempfiles.append(file_path)
3610 3621
3611 3622 if data:
3612 3623 file_path.write_text(data, encoding="utf-8")
3613 3624 return filename
3614 3625
3615 3626 def ask_yes_no(self, prompt, default=None, interrupt=None):
3616 3627 if self.quiet:
3617 3628 return True
3618 3629 return ask_yes_no(prompt,default,interrupt)
3619 3630
3620 3631 def show_usage(self):
3621 3632 """Show a usage message"""
3622 3633 page.page(IPython.core.usage.interactive_usage)
3623 3634
3624 3635 def extract_input_lines(self, range_str, raw=False):
3625 3636 """Return as a string a set of input history slices.
3626 3637
3627 3638 Parameters
3628 3639 ----------
3629 3640 range_str : str
3630 3641 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
3631 3642 since this function is for use by magic functions which get their
3632 3643 arguments as strings. The number before the / is the session
3633 3644 number: ~n goes n back from the current session.
3634 3645
3635 3646 If empty string is given, returns history of current session
3636 3647 without the last input.
3637 3648
3638 3649 raw : bool, optional
3639 3650 By default, the processed input is used. If this is true, the raw
3640 3651 input history is used instead.
3641 3652
3642 3653 Notes
3643 3654 -----
3644 3655 Slices can be described with two notations:
3645 3656
3646 3657 * ``N:M`` -> standard python form, means including items N...(M-1).
3647 3658 * ``N-M`` -> include items N..M (closed endpoint).
3648 3659 """
3649 3660 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
3650 3661 text = "\n".join(x for _, _, x in lines)
3651 3662
3652 3663 # Skip the last line, as it's probably the magic that called this
3653 3664 if not range_str:
3654 3665 if "\n" not in text:
3655 3666 text = ""
3656 3667 else:
3657 3668 text = text[: text.rfind("\n")]
3658 3669
3659 3670 return text
3660 3671
3661 3672 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True, search_ns=False):
3662 3673 """Get a code string from history, file, url, or a string or macro.
3663 3674
3664 3675 This is mainly used by magic functions.
3665 3676
3666 3677 Parameters
3667 3678 ----------
3668 3679 target : str
3669 3680 A string specifying code to retrieve. This will be tried respectively
3670 3681 as: ranges of input history (see %history for syntax), url,
3671 3682 corresponding .py file, filename, or an expression evaluating to a
3672 3683 string or Macro in the user namespace.
3673 3684
3674 3685 If empty string is given, returns complete history of current
3675 3686 session, without the last line.
3676 3687
3677 3688 raw : bool
3678 3689 If true (default), retrieve raw history. Has no effect on the other
3679 3690 retrieval mechanisms.
3680 3691
3681 3692 py_only : bool (default False)
3682 3693 Only try to fetch python code, do not try alternative methods to decode file
3683 3694 if unicode fails.
3684 3695
3685 3696 Returns
3686 3697 -------
3687 3698 A string of code.
3688 3699 ValueError is raised if nothing is found, and TypeError if it evaluates
3689 3700 to an object of another type. In each case, .args[0] is a printable
3690 3701 message.
3691 3702 """
3692 3703 code = self.extract_input_lines(target, raw=raw) # Grab history
3693 3704 if code:
3694 3705 return code
3695 3706 try:
3696 3707 if target.startswith(('http://', 'https://')):
3697 3708 return openpy.read_py_url(target, skip_encoding_cookie=skip_encoding_cookie)
3698 3709 except UnicodeDecodeError as e:
3699 3710 if not py_only :
3700 3711 # Deferred import
3701 3712 from urllib.request import urlopen
3702 3713 response = urlopen(target)
3703 3714 return response.read().decode('latin1')
3704 3715 raise ValueError(("'%s' seem to be unreadable.") % target) from e
3705 3716
3706 3717 potential_target = [target]
3707 3718 try :
3708 3719 potential_target.insert(0,get_py_filename(target))
3709 3720 except IOError:
3710 3721 pass
3711 3722
3712 3723 for tgt in potential_target :
3713 3724 if os.path.isfile(tgt): # Read file
3714 3725 try :
3715 3726 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
3716 3727 except UnicodeDecodeError as e:
3717 3728 if not py_only :
3718 3729 with io_open(tgt,'r', encoding='latin1') as f :
3719 3730 return f.read()
3720 3731 raise ValueError(("'%s' seem to be unreadable.") % target) from e
3721 3732 elif os.path.isdir(os.path.expanduser(tgt)):
3722 3733 raise ValueError("'%s' is a directory, not a regular file." % target)
3723 3734
3724 3735 if search_ns:
3725 3736 # Inspect namespace to load object source
3726 3737 object_info = self.object_inspect(target, detail_level=1)
3727 3738 if object_info['found'] and object_info['source']:
3728 3739 return object_info['source']
3729 3740
3730 3741 try: # User namespace
3731 3742 codeobj = eval(target, self.user_ns)
3732 3743 except Exception as e:
3733 3744 raise ValueError(("'%s' was not found in history, as a file, url, "
3734 3745 "nor in the user namespace.") % target) from e
3735 3746
3736 3747 if isinstance(codeobj, str):
3737 3748 return codeobj
3738 3749 elif isinstance(codeobj, Macro):
3739 3750 return codeobj.value
3740 3751
3741 3752 raise TypeError("%s is neither a string nor a macro." % target,
3742 3753 codeobj)
3743 3754
3744 3755 def _atexit_once(self):
3745 3756 """
3746 3757 At exist operation that need to be called at most once.
3747 3758 Second call to this function per instance will do nothing.
3748 3759 """
3749 3760
3750 3761 if not getattr(self, "_atexit_once_called", False):
3751 3762 self._atexit_once_called = True
3752 3763 # Clear all user namespaces to release all references cleanly.
3753 3764 self.reset(new_session=False)
3754 3765 # Close the history session (this stores the end time and line count)
3755 3766 # this must be *before* the tempfile cleanup, in case of temporary
3756 3767 # history db
3757 3768 self.history_manager.end_session()
3758 3769 self.history_manager = None
3759 3770
3760 3771 #-------------------------------------------------------------------------
3761 3772 # Things related to IPython exiting
3762 3773 #-------------------------------------------------------------------------
3763 3774 def atexit_operations(self):
3764 3775 """This will be executed at the time of exit.
3765 3776
3766 3777 Cleanup operations and saving of persistent data that is done
3767 3778 unconditionally by IPython should be performed here.
3768 3779
3769 3780 For things that may depend on startup flags or platform specifics (such
3770 3781 as having readline or not), register a separate atexit function in the
3771 3782 code that has the appropriate information, rather than trying to
3772 3783 clutter
3773 3784 """
3774 3785 self._atexit_once()
3775 3786
3776 3787 # Cleanup all tempfiles and folders left around
3777 3788 for tfile in self.tempfiles:
3778 3789 try:
3779 3790 tfile.unlink()
3780 3791 self.tempfiles.remove(tfile)
3781 3792 except FileNotFoundError:
3782 3793 pass
3783 3794 del self.tempfiles
3784 3795 for tdir in self.tempdirs:
3785 3796 try:
3786 3797 tdir.rmdir()
3787 3798 self.tempdirs.remove(tdir)
3788 3799 except FileNotFoundError:
3789 3800 pass
3790 3801 del self.tempdirs
3791 3802
3792 3803 # Restore user's cursor
3793 3804 if hasattr(self, "editing_mode") and self.editing_mode == "vi":
3794 3805 sys.stdout.write("\x1b[0 q")
3795 3806 sys.stdout.flush()
3796 3807
3797 3808 def cleanup(self):
3798 3809 self.restore_sys_module_state()
3799 3810
3800 3811
3801 3812 # Overridden in terminal subclass to change prompts
3802 3813 def switch_doctest_mode(self, mode):
3803 3814 pass
3804 3815
3805 3816
3806 3817 class InteractiveShellABC(metaclass=abc.ABCMeta):
3807 3818 """An abstract base class for InteractiveShell."""
3808 3819
3809 3820 InteractiveShellABC.register(InteractiveShell)
@@ -1,527 +1,540 b''
1 1 """Tests for the object inspection functionality.
2 2 """
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7
8 8 from contextlib import contextmanager
9 9 from inspect import signature, Signature, Parameter
10 10 import inspect
11 11 import os
12 12 import pytest
13 13 import re
14 14 import sys
15 15
16 16 from .. import oinspect
17 17
18 18 from decorator import decorator
19 19
20 20 from IPython.testing.tools import AssertPrints, AssertNotPrints
21 21 from IPython.utils.path import compress_user
22 22
23 23
24 24 #-----------------------------------------------------------------------------
25 25 # Globals and constants
26 26 #-----------------------------------------------------------------------------
27 27
28 28 inspector = None
29 29
30 30 def setup_module():
31 31 global inspector
32 32 inspector = oinspect.Inspector()
33 33
34 34
35 35 class SourceModuleMainTest:
36 36 __module__ = "__main__"
37 37
38 38
39 39 #-----------------------------------------------------------------------------
40 40 # Local utilities
41 41 #-----------------------------------------------------------------------------
42 42
43 43 # WARNING: since this test checks the line number where a function is
44 44 # defined, if any code is inserted above, the following line will need to be
45 45 # updated. Do NOT insert any whitespace between the next line and the function
46 46 # definition below.
47 47 THIS_LINE_NUMBER = 47 # Put here the actual number of this line
48 48
49 49
50 50 def test_find_source_lines():
51 51 assert oinspect.find_source_lines(test_find_source_lines) == THIS_LINE_NUMBER + 3
52 52 assert oinspect.find_source_lines(type) is None
53 53 assert oinspect.find_source_lines(SourceModuleMainTest) is None
54 54 assert oinspect.find_source_lines(SourceModuleMainTest()) is None
55 55
56 56
57 57 def test_getsource():
58 58 assert oinspect.getsource(type) is None
59 59 assert oinspect.getsource(SourceModuleMainTest) is None
60 60 assert oinspect.getsource(SourceModuleMainTest()) is None
61 61
62 62
63 63 def test_inspect_getfile_raises_exception():
64 64 """Check oinspect.find_file/getsource/find_source_lines expectations"""
65 65 with pytest.raises(TypeError):
66 66 inspect.getfile(type)
67 67 with pytest.raises(OSError if sys.version_info >= (3, 10) else TypeError):
68 68 inspect.getfile(SourceModuleMainTest)
69 69
70 70
71 71 # A couple of utilities to ensure these tests work the same from a source or a
72 72 # binary install
73 73 def pyfile(fname):
74 74 return os.path.normcase(re.sub('.py[co]$', '.py', fname))
75 75
76 76
77 77 def match_pyfiles(f1, f2):
78 78 assert pyfile(f1) == pyfile(f2)
79 79
80 80
81 81 def test_find_file():
82 82 match_pyfiles(oinspect.find_file(test_find_file), os.path.abspath(__file__))
83 83 assert oinspect.find_file(type) is None
84 84 assert oinspect.find_file(SourceModuleMainTest) is None
85 85 assert oinspect.find_file(SourceModuleMainTest()) is None
86 86
87 87
88 88 def test_find_file_decorated1():
89 89
90 90 @decorator
91 91 def noop1(f):
92 92 def wrapper(*a, **kw):
93 93 return f(*a, **kw)
94 94 return wrapper
95 95
96 96 @noop1
97 97 def f(x):
98 98 "My docstring"
99 99
100 100 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
101 101 assert f.__doc__ == "My docstring"
102 102
103 103
104 104 def test_find_file_decorated2():
105 105
106 106 @decorator
107 107 def noop2(f, *a, **kw):
108 108 return f(*a, **kw)
109 109
110 110 @noop2
111 111 @noop2
112 112 @noop2
113 113 def f(x):
114 114 "My docstring 2"
115 115
116 116 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
117 117 assert f.__doc__ == "My docstring 2"
118 118
119 119
120 120 def test_find_file_magic():
121 121 run = ip.find_line_magic('run')
122 122 assert oinspect.find_file(run) is not None
123 123
124 124
125 125 # A few generic objects we can then inspect in the tests below
126 126
127 127 class Call(object):
128 128 """This is the class docstring."""
129 129
130 130 def __init__(self, x, y=1):
131 131 """This is the constructor docstring."""
132 132
133 133 def __call__(self, *a, **kw):
134 134 """This is the call docstring."""
135 135
136 136 def method(self, x, z=2):
137 137 """Some method's docstring"""
138 138
139 139 class HasSignature(object):
140 140 """This is the class docstring."""
141 141 __signature__ = Signature([Parameter('test', Parameter.POSITIONAL_OR_KEYWORD)])
142 142
143 143 def __init__(self, *args):
144 144 """This is the init docstring"""
145 145
146 146
147 147 class SimpleClass(object):
148 148 def method(self, x, z=2):
149 149 """Some method's docstring"""
150 150
151 151
152 152 class Awkward(object):
153 153 def __getattr__(self, name):
154 154 raise Exception(name)
155 155
156 156 class NoBoolCall:
157 157 """
158 158 callable with `__bool__` raising should still be inspect-able.
159 159 """
160 160
161 161 def __call__(self):
162 162 """does nothing"""
163 163 pass
164 164
165 165 def __bool__(self):
166 166 """just raise NotImplemented"""
167 167 raise NotImplementedError('Must be implemented')
168 168
169 169
170 170 class SerialLiar(object):
171 171 """Attribute accesses always get another copy of the same class.
172 172
173 173 unittest.mock.call does something similar, but it's not ideal for testing
174 174 as the failure mode is to eat all your RAM. This gives up after 10k levels.
175 175 """
176 176 def __init__(self, max_fibbing_twig, lies_told=0):
177 177 if lies_told > 10000:
178 178 raise RuntimeError('Nose too long, honesty is the best policy')
179 179 self.max_fibbing_twig = max_fibbing_twig
180 180 self.lies_told = lies_told
181 181 max_fibbing_twig[0] = max(max_fibbing_twig[0], lies_told)
182 182
183 183 def __getattr__(self, item):
184 184 return SerialLiar(self.max_fibbing_twig, self.lies_told + 1)
185 185
186 186 #-----------------------------------------------------------------------------
187 187 # Tests
188 188 #-----------------------------------------------------------------------------
189 189
190 190 def test_info():
191 191 "Check that Inspector.info fills out various fields as expected."
192 192 i = inspector.info(Call, oname="Call")
193 193 assert i["type_name"] == "type"
194 194 expected_class = str(type(type)) # <class 'type'> (Python 3) or <type 'type'>
195 195 assert i["base_class"] == expected_class
196 196 assert re.search(
197 197 "<class 'IPython.core.tests.test_oinspect.Call'( at 0x[0-9a-f]{1,9})?>",
198 198 i["string_form"],
199 199 )
200 200 fname = __file__
201 201 if fname.endswith(".pyc"):
202 202 fname = fname[:-1]
203 203 # case-insensitive comparison needed on some filesystems
204 204 # e.g. Windows:
205 205 assert i["file"].lower() == compress_user(fname).lower()
206 206 assert i["definition"] == None
207 207 assert i["docstring"] == Call.__doc__
208 208 assert i["source"] == None
209 209 assert i["isclass"] is True
210 210 assert i["init_definition"] == "Call(x, y=1)"
211 211 assert i["init_docstring"] == Call.__init__.__doc__
212 212
213 213 i = inspector.info(Call, detail_level=1)
214 214 assert i["source"] is not None
215 215 assert i["docstring"] == None
216 216
217 217 c = Call(1)
218 218 c.__doc__ = "Modified instance docstring"
219 219 i = inspector.info(c)
220 220 assert i["type_name"] == "Call"
221 221 assert i["docstring"] == "Modified instance docstring"
222 222 assert i["class_docstring"] == Call.__doc__
223 223 assert i["init_docstring"] == Call.__init__.__doc__
224 224 assert i["call_docstring"] == Call.__call__.__doc__
225 225
226 226
227 227 def test_class_signature():
228 228 info = inspector.info(HasSignature, "HasSignature")
229 229 assert info["init_definition"] == "HasSignature(test)"
230 230 assert info["init_docstring"] == HasSignature.__init__.__doc__
231 231
232 232
233 233 def test_info_awkward():
234 234 # Just test that this doesn't throw an error.
235 235 inspector.info(Awkward())
236 236
237 237 def test_bool_raise():
238 238 inspector.info(NoBoolCall())
239 239
240 240 def test_info_serialliar():
241 241 fib_tracker = [0]
242 242 inspector.info(SerialLiar(fib_tracker))
243 243
244 244 # Nested attribute access should be cut off at 100 levels deep to avoid
245 245 # infinite loops: https://github.com/ipython/ipython/issues/9122
246 246 assert fib_tracker[0] < 9000
247 247
248 248 def support_function_one(x, y=2, *a, **kw):
249 249 """A simple function."""
250 250
251 251 def test_calldef_none():
252 252 # We should ignore __call__ for all of these.
253 253 for obj in [support_function_one, SimpleClass().method, any, str.upper]:
254 254 i = inspector.info(obj)
255 255 assert i["call_def"] is None
256 256
257 257
258 258 def f_kwarg(pos, *, kwonly):
259 259 pass
260 260
261 261 def test_definition_kwonlyargs():
262 262 i = inspector.info(f_kwarg, oname="f_kwarg") # analysis:ignore
263 263 assert i["definition"] == "f_kwarg(pos, *, kwonly)"
264 264
265 265
266 266 def test_getdoc():
267 267 class A(object):
268 268 """standard docstring"""
269 269 pass
270 270
271 271 class B(object):
272 272 """standard docstring"""
273 273 def getdoc(self):
274 274 return "custom docstring"
275 275
276 276 class C(object):
277 277 """standard docstring"""
278 278 def getdoc(self):
279 279 return None
280 280
281 281 a = A()
282 282 b = B()
283 283 c = C()
284 284
285 285 assert oinspect.getdoc(a) == "standard docstring"
286 286 assert oinspect.getdoc(b) == "custom docstring"
287 287 assert oinspect.getdoc(c) == "standard docstring"
288 288
289 289
290 290 def test_empty_property_has_no_source():
291 291 i = inspector.info(property(), detail_level=1)
292 292 assert i["source"] is None
293 293
294 294
295 295 def test_property_sources():
296 296 # A simple adder whose source and signature stays
297 297 # the same across Python distributions
298 298 def simple_add(a, b):
299 299 "Adds two numbers"
300 300 return a + b
301 301
302 302 class A(object):
303 303 @property
304 304 def foo(self):
305 305 return 'bar'
306 306
307 307 foo = foo.setter(lambda self, v: setattr(self, 'bar', v))
308 308
309 309 dname = property(oinspect.getdoc)
310 310 adder = property(simple_add)
311 311
312 312 i = inspector.info(A.foo, detail_level=1)
313 313 assert "def foo(self):" in i["source"]
314 314 assert "lambda self, v:" in i["source"]
315 315
316 316 i = inspector.info(A.dname, detail_level=1)
317 317 assert "def getdoc(obj)" in i["source"]
318 318
319 319 i = inspector.info(A.adder, detail_level=1)
320 320 assert "def simple_add(a, b)" in i["source"]
321 321
322 322
323 323 def test_property_docstring_is_in_info_for_detail_level_0():
324 324 class A(object):
325 325 @property
326 326 def foobar(self):
327 327 """This is `foobar` property."""
328 328 pass
329 329
330 330 ip.user_ns["a_obj"] = A()
331 331 assert (
332 332 "This is `foobar` property."
333 333 == ip.object_inspect("a_obj.foobar", detail_level=0)["docstring"]
334 334 )
335 335
336 336 ip.user_ns["a_cls"] = A
337 337 assert (
338 338 "This is `foobar` property."
339 339 == ip.object_inspect("a_cls.foobar", detail_level=0)["docstring"]
340 340 )
341 341
342 342
343 343 def test_pdef():
344 344 # See gh-1914
345 345 def foo(): pass
346 346 inspector.pdef(foo, 'foo')
347 347
348 348
349 349 @contextmanager
350 350 def cleanup_user_ns(**kwargs):
351 351 """
352 352 On exit delete all the keys that were not in user_ns before entering.
353 353
354 354 It does not restore old values !
355 355
356 356 Parameters
357 357 ----------
358 358
359 359 **kwargs
360 360 used to update ip.user_ns
361 361
362 362 """
363 363 try:
364 364 known = set(ip.user_ns.keys())
365 365 ip.user_ns.update(kwargs)
366 366 yield
367 367 finally:
368 368 added = set(ip.user_ns.keys()) - known
369 369 for k in added:
370 370 del ip.user_ns[k]
371 371
372 372
373 373 def test_pinfo_getindex():
374 374 def dummy():
375 375 """
376 376 MARKER
377 377 """
378 378
379 379 container = [dummy]
380 380 with cleanup_user_ns(container=container):
381 381 with AssertPrints("MARKER"):
382 382 ip._inspect("pinfo", "container[0]", detail_level=0)
383 383 assert "container" not in ip.user_ns.keys()
384 384
385 385
386 386 def test_qmark_getindex():
387 387 def dummy():
388 388 """
389 389 MARKER 2
390 390 """
391 391
392 392 container = [dummy]
393 393 with cleanup_user_ns(container=container):
394 394 with AssertPrints("MARKER 2"):
395 395 ip.run_cell("container[0]?")
396 396 assert "container" not in ip.user_ns.keys()
397 397
398 def test_qmark_getindex_negatif():
399 def dummy():
400 """
401 MARKER 3
402 """
403
404 container = [dummy]
405 with cleanup_user_ns(container=container):
406 with AssertPrints("MARKER 3"):
407 ip.run_cell("container[-1]?")
408 assert "container" not in ip.user_ns.keys()
409
410
398 411
399 412 def test_pinfo_nonascii():
400 413 # See gh-1177
401 414 from . import nonascii2
402 415 ip.user_ns['nonascii2'] = nonascii2
403 416 ip._inspect('pinfo', 'nonascii2', detail_level=1)
404 417
405 418 def test_pinfo_type():
406 419 """
407 420 type can fail in various edge case, for example `type.__subclass__()`
408 421 """
409 422 ip._inspect('pinfo', 'type')
410 423
411 424
412 425 def test_pinfo_docstring_no_source():
413 426 """Docstring should be included with detail_level=1 if there is no source"""
414 427 with AssertPrints('Docstring:'):
415 428 ip._inspect('pinfo', 'str.format', detail_level=0)
416 429 with AssertPrints('Docstring:'):
417 430 ip._inspect('pinfo', 'str.format', detail_level=1)
418 431
419 432
420 433 def test_pinfo_no_docstring_if_source():
421 434 """Docstring should not be included with detail_level=1 if source is found"""
422 435 def foo():
423 436 """foo has a docstring"""
424 437
425 438 ip.user_ns['foo'] = foo
426 439
427 440 with AssertPrints('Docstring:'):
428 441 ip._inspect('pinfo', 'foo', detail_level=0)
429 442 with AssertPrints('Source:'):
430 443 ip._inspect('pinfo', 'foo', detail_level=1)
431 444 with AssertNotPrints('Docstring:'):
432 445 ip._inspect('pinfo', 'foo', detail_level=1)
433 446
434 447
435 448 def test_pinfo_docstring_if_detail_and_no_source():
436 449 """ Docstring should be displayed if source info not available """
437 450 obj_def = '''class Foo(object):
438 451 """ This is a docstring for Foo """
439 452 def bar(self):
440 453 """ This is a docstring for Foo.bar """
441 454 pass
442 455 '''
443 456
444 457 ip.run_cell(obj_def)
445 458 ip.run_cell('foo = Foo()')
446 459
447 460 with AssertNotPrints("Source:"):
448 461 with AssertPrints('Docstring:'):
449 462 ip._inspect('pinfo', 'foo', detail_level=0)
450 463 with AssertPrints('Docstring:'):
451 464 ip._inspect('pinfo', 'foo', detail_level=1)
452 465 with AssertPrints('Docstring:'):
453 466 ip._inspect('pinfo', 'foo.bar', detail_level=0)
454 467
455 468 with AssertNotPrints('Docstring:'):
456 469 with AssertPrints('Source:'):
457 470 ip._inspect('pinfo', 'foo.bar', detail_level=1)
458 471
459 472
460 473 def test_pinfo_magic():
461 474 with AssertPrints('Docstring:'):
462 475 ip._inspect('pinfo', 'lsmagic', detail_level=0)
463 476
464 477 with AssertPrints('Source:'):
465 478 ip._inspect('pinfo', 'lsmagic', detail_level=1)
466 479
467 480
468 481 def test_init_colors():
469 482 # ensure colors are not present in signature info
470 483 info = inspector.info(HasSignature)
471 484 init_def = info["init_definition"]
472 485 assert "[0m" not in init_def
473 486
474 487
475 488 def test_builtin_init():
476 489 info = inspector.info(list)
477 490 init_def = info['init_definition']
478 491 assert init_def is not None
479 492
480 493
481 494 def test_render_signature_short():
482 495 def short_fun(a=1): pass
483 496 sig = oinspect._render_signature(
484 497 signature(short_fun),
485 498 short_fun.__name__,
486 499 )
487 500 assert sig == "short_fun(a=1)"
488 501
489 502
490 503 def test_render_signature_long():
491 504 from typing import Optional
492 505
493 506 def long_function(
494 507 a_really_long_parameter: int,
495 508 and_another_long_one: bool = False,
496 509 let_us_make_sure_this_is_looong: Optional[str] = None,
497 510 ) -> bool: pass
498 511
499 512 sig = oinspect._render_signature(
500 513 signature(long_function),
501 514 long_function.__name__,
502 515 )
503 516 assert sig in [
504 517 # Python >=3.9
505 518 '''\
506 519 long_function(
507 520 a_really_long_parameter: int,
508 521 and_another_long_one: bool = False,
509 522 let_us_make_sure_this_is_looong: Optional[str] = None,
510 523 ) -> bool\
511 524 ''',
512 525 # Python >=3.7
513 526 '''\
514 527 long_function(
515 528 a_really_long_parameter: int,
516 529 and_another_long_one: bool = False,
517 530 let_us_make_sure_this_is_looong: Union[str, NoneType] = None,
518 531 ) -> bool\
519 532 ''', # Python <=3.6
520 533 '''\
521 534 long_function(
522 535 a_really_long_parameter:int,
523 536 and_another_long_one:bool=False,
524 537 let_us_make_sure_this_is_looong:Union[str, NoneType]=None,
525 538 ) -> bool\
526 539 ''',
527 540 ]
General Comments 0
You need to be logged in to leave comments. Login now