Show More
@@ -0,0 +1,25 b'' | |||
|
1 | History Range Glob feature | |
|
2 | ========================== | |
|
3 | ||
|
4 | Previously, when using ``%history``, users could specify either | |
|
5 | a range of sessions and lines, for example: | |
|
6 | ||
|
7 | .. code-block:: python | |
|
8 | ||
|
9 | ~8/1-~6/5 # see history from the first line of 8 sessions ago, | |
|
10 | # to the fifth line of 6 sessions ago.`` | |
|
11 | ||
|
12 | Or users could specify a glob pattern: | |
|
13 | ||
|
14 | .. code-block:: python | |
|
15 | ||
|
16 | -g <pattern> # glob ALL history for the specified pattern. | |
|
17 | ||
|
18 | However users could *not* specify both. | |
|
19 | ||
|
20 | If a user *did* specify both a range and a glob pattern, | |
|
21 | then the glob pattern would be used (globbing *all* history) *and the range would be ignored*. | |
|
22 | ||
|
23 | --- | |
|
24 | ||
|
25 | With this enhancment, if a user specifies both a range and a glob pattern, then the glob pattern will be applied to the specified range of history. |
@@ -0,0 +1,7 b'' | |||
|
1 | Don't start a multiline cell with sunken parenthesis | |
|
2 | ---------------------------------------------------- | |
|
3 | ||
|
4 | From now on IPython will not ask for the next line of input when given a single | |
|
5 | line with more closing than opening brackets. For example, this means that if | |
|
6 | you (mis)type ']]' instead of '[]', a ``SyntaxError`` will show up, instead of | |
|
7 | the ``...:`` prompt continuation. |
@@ -2,9 +2,9 b' name: Run MyPy' | |||
|
2 | 2 | |
|
3 | 3 | on: |
|
4 | 4 | push: |
|
5 | branches: [ master ] | |
|
5 | branches: [ master, 7.x] | |
|
6 | 6 | pull_request: |
|
7 | branches: [ master ] | |
|
7 | branches: [ master, 7.x] | |
|
8 | 8 | |
|
9 | 9 | jobs: |
|
10 | 10 | build: |
@@ -5,9 +5,9 b' name: Python package' | |||
|
5 | 5 | |
|
6 | 6 | on: |
|
7 | 7 | push: |
|
8 | branches: [ master ] | |
|
8 | branches: [ master, 7.x ] | |
|
9 | 9 | pull_request: |
|
10 | branches: [ master ] | |
|
10 | branches: [ master, 7.x ] | |
|
11 | 11 | |
|
12 | 12 | jobs: |
|
13 | 13 | build: |
@@ -37,7 +37,7 b' install:' | |||
|
37 | 37 | - pip install -e file://$PWD#egg=ipython[test] --upgrade |
|
38 | 38 | - pip install trio curio --upgrade --upgrade-strategy eager |
|
39 | 39 | - pip install 'pytest' 'matplotlib !=3.2.0' |
|
40 |
- pip install codecov check-manifest pytest-cov --upgrade anyio pytest- |
|
|
40 | - pip install codecov check-manifest pytest-cov --upgrade anyio pytest-trio | |
|
41 | 41 | |
|
42 | 42 | |
|
43 | 43 | script: |
@@ -99,7 +99,7 b' class CachingCompiler(codeop.Compile):' | |||
|
99 | 99 | Arguments are exactly the same as ast.parse (in the standard library), |
|
100 | 100 | and are passed to the built-in compile function.""" |
|
101 | 101 | return compile(source, filename, symbol, self.flags | PyCF_ONLY_AST, 1) |
|
102 | ||
|
102 | ||
|
103 | 103 | def reset_compiler_flags(self): |
|
104 | 104 | """Reset compiler flags to default state.""" |
|
105 | 105 | # This value is copied from codeop.Compile.__init__, so if that ever |
@@ -112,25 +112,53 b' class CachingCompiler(codeop.Compile):' | |||
|
112 | 112 | """ |
|
113 | 113 | return self.flags |
|
114 | 114 | |
|
115 |
def |
|
|
115 | def get_code_name(self, raw_code, transformed_code, number): | |
|
116 | """Compute filename given the code, and the cell number. | |
|
117 | ||
|
118 | Parameters | |
|
119 | ---------- | |
|
120 | raw_code : str | |
|
121 | The raw cell code. | |
|
122 | transformed_code : str | |
|
123 | The executable Python source code to cache and compile. | |
|
124 | number : int | |
|
125 | A number which forms part of the code's name. Used for the execution | |
|
126 | counter. | |
|
127 | ||
|
128 | Returns | |
|
129 | ------- | |
|
130 | The computed filename. | |
|
131 | """ | |
|
132 | return code_name(transformed_code, number) | |
|
133 | ||
|
134 | def cache(self, transformed_code, number=0, raw_code=None): | |
|
116 | 135 | """Make a name for a block of code, and cache the code. |
|
117 | 136 | |
|
118 | 137 | Parameters |
|
119 | 138 | ---------- |
|
120 | code : str | |
|
121 | The Python source code to cache. | |
|
139 | transformed_code : str | |
|
140 | The executable Python source code to cache and compile. | |
|
122 | 141 | number : int |
|
123 | 142 | A number which forms part of the code's name. Used for the execution |
|
124 | 143 | counter. |
|
144 | raw_code : str | |
|
145 | The raw code before transformation, if None, set to `transformed_code`. | |
|
125 | 146 | |
|
126 | 147 | Returns |
|
127 | 148 | ------- |
|
128 | 149 | The name of the cached code (as a string). Pass this as the filename |
|
129 | 150 | argument to compilation, so that tracebacks are correctly hooked up. |
|
130 | 151 | """ |
|
131 | name = code_name(code, number) | |
|
132 | entry = (len(code), time.time(), | |
|
133 | [line+'\n' for line in code.splitlines()], name) | |
|
152 | if raw_code is None: | |
|
153 | raw_code = transformed_code | |
|
154 | ||
|
155 | name = self.get_code_name(raw_code, transformed_code, number) | |
|
156 | entry = ( | |
|
157 | len(transformed_code), | |
|
158 | time.time(), | |
|
159 | [line + "\n" for line in transformed_code.splitlines()], | |
|
160 | name, | |
|
161 | ) | |
|
134 | 162 | linecache.cache[name] = entry |
|
135 | 163 | linecache._ipython_cache[name] = entry |
|
136 | 164 | return name |
@@ -146,7 +174,7 b' class CachingCompiler(codeop.Compile):' | |||
|
146 | 174 | yield |
|
147 | 175 | finally: |
|
148 | 176 | # turn off only the bits we turned on so that something like |
|
149 |
# __future__ that set flags stays. |
|
|
177 | # __future__ that set flags stays. | |
|
150 | 178 | self.flags &= ~turn_on_bits |
|
151 | 179 | |
|
152 | 180 |
@@ -201,7 +201,9 b" def provisionalcompleter(action='ignore'):" | |||
|
201 | 201 | |
|
202 | 202 | >>> completer.do_experimental_things() # raises. |
|
203 | 203 | |
|
204 |
.. note:: |
|
|
204 | .. note:: | |
|
205 | ||
|
206 | Unstable | |
|
205 | 207 | |
|
206 | 208 | By using this context manager you agree that the API in use may change |
|
207 | 209 | without warning, and that you won't complain if they do so. |
@@ -356,7 +358,9 b' class Completion:' | |||
|
356 | 358 | """ |
|
357 | 359 | Completion object used and return by IPython completers. |
|
358 | 360 | |
|
359 |
.. warning:: |
|
|
361 | .. warning:: | |
|
362 | ||
|
363 | Unstable | |
|
360 | 364 | |
|
361 | 365 | This function is unstable, API may change without warning. |
|
362 | 366 | It will also raise unless use in proper context manager. |
@@ -419,7 +423,9 b' def _deduplicate_completions(text: str, completions: _IC)-> _IC:' | |||
|
419 | 423 | """ |
|
420 | 424 | Deduplicate a set of completions. |
|
421 | 425 | |
|
422 |
.. warning:: |
|
|
426 | .. warning:: | |
|
427 | ||
|
428 | Unstable | |
|
423 | 429 | |
|
424 | 430 | This function is unstable, API may change without warning. |
|
425 | 431 | |
@@ -459,7 +465,9 b' def rectify_completions(text: str, completions: _IC, *, _debug=False)->_IC:' | |||
|
459 | 465 | """ |
|
460 | 466 | Rectify a set of completions to all have the same ``start`` and ``end`` |
|
461 | 467 | |
|
462 |
.. warning:: |
|
|
468 | .. warning:: | |
|
469 | ||
|
470 | Unstable | |
|
463 | 471 | |
|
464 | 472 | This function is unstable, API may change without warning. |
|
465 | 473 | It will also raise unless use in proper context manager. |
@@ -1837,7 +1845,9 b' class IPCompleter(Completer):' | |||
|
1837 | 1845 | """ |
|
1838 | 1846 | Returns an iterator over the possible completions |
|
1839 | 1847 | |
|
1840 |
.. warning:: |
|
|
1848 | .. warning:: | |
|
1849 | ||
|
1850 | Unstable | |
|
1841 | 1851 | |
|
1842 | 1852 | This function is unstable, API may change without warning. |
|
1843 | 1853 | It will also raise unless use in proper context manager. |
@@ -23,6 +23,7 b' import os' | |||
|
23 | 23 | import sys |
|
24 | 24 | import traceback |
|
25 | 25 | from pprint import pformat |
|
26 | from pathlib import Path | |
|
26 | 27 | |
|
27 | 28 | from IPython.core import ultratb |
|
28 | 29 | from IPython.core.release import author_email |
@@ -151,10 +152,10 b' class CrashHandler(object):' | |||
|
151 | 152 | try: |
|
152 | 153 | rptdir = self.app.ipython_dir |
|
153 | 154 | except: |
|
154 |
rptdir = |
|
|
155 |
if rptdir is None or not |
|
|
156 |
rptdir = |
|
|
157 |
report_name = |
|
|
155 | rptdir = Path.cwd() | |
|
156 | if rptdir is None or not Path.is_dir(rptdir): | |
|
157 | rptdir = Path.cwd() | |
|
158 | report_name = rptdir / self.crash_report_fname | |
|
158 | 159 | # write the report filename into the instance dict so it can get |
|
159 | 160 | # properly expanded out in the user message template |
|
160 | 161 | self.crash_report_fname = report_name |
@@ -43,13 +43,14 b' from IPython.testing.skipdoctest import skip_doctest' | |||
|
43 | 43 | |
|
44 | 44 | prompt = 'ipdb> ' |
|
45 | 45 | |
|
46 | #We have to check this directly from sys.argv, config struct not yet available | |
|
46 | # We have to check this directly from sys.argv, config struct not yet available | |
|
47 | 47 | from pdb import Pdb as OldPdb |
|
48 | 48 | |
|
49 | 49 | # Allow the set_trace code to operate outside of an ipython instance, even if |
|
50 | 50 | # it does so with some limitations. The rest of this support is implemented in |
|
51 | 51 | # the Tracer constructor. |
|
52 | 52 | |
|
53 | ||
|
53 | 54 | def make_arrow(pad): |
|
54 | 55 | """generate the leading arrow in front of traceback or debugger""" |
|
55 | 56 | if pad >= 2: |
@@ -67,16 +68,16 b' def BdbQuit_excepthook(et, ev, tb, excepthook=None):' | |||
|
67 | 68 | """ |
|
68 | 69 | warnings.warn("`BdbQuit_excepthook` is deprecated since version 5.1", |
|
69 | 70 | DeprecationWarning, stacklevel=2) |
|
70 | if et==bdb.BdbQuit: | |
|
71 | if et == bdb.BdbQuit: | |
|
71 | 72 | print('Exiting Debugger.') |
|
72 | 73 | elif excepthook is not None: |
|
73 | 74 | excepthook(et, ev, tb) |
|
74 | 75 | else: |
|
75 | 76 | # Backwards compatibility. Raise deprecation warning? |
|
76 | BdbQuit_excepthook.excepthook_ori(et,ev,tb) | |
|
77 | BdbQuit_excepthook.excepthook_ori(et, ev, tb) | |
|
77 | 78 | |
|
78 | 79 | |
|
79 | def BdbQuit_IPython_excepthook(self,et,ev,tb,tb_offset=None): | |
|
80 | def BdbQuit_IPython_excepthook(self, et, ev, tb, tb_offset=None): | |
|
80 | 81 | warnings.warn( |
|
81 | 82 | "`BdbQuit_IPython_excepthook` is deprecated since version 5.1", |
|
82 | 83 | DeprecationWarning, stacklevel=2) |
@@ -203,7 +204,7 b' class Pdb(OldPdb):' | |||
|
203 | 204 | def __init__(self, color_scheme=None, completekey=None, |
|
204 | 205 | stdin=None, stdout=None, context=5, **kwargs): |
|
205 | 206 | """Create a new IPython debugger. |
|
206 | ||
|
207 | ||
|
207 | 208 | :param color_scheme: Deprecated, do not use. |
|
208 | 209 | :param completekey: Passed to pdb.Pdb. |
|
209 | 210 | :param stdin: Passed to pdb.Pdb. |
@@ -237,7 +238,7 b' class Pdb(OldPdb):' | |||
|
237 | 238 | self.shell = TerminalInteractiveShell.instance() |
|
238 | 239 | # needed by any code which calls __import__("__main__") after |
|
239 | 240 | # the debugger was entered. See also #9941. |
|
240 |
sys.modules[ |
|
|
241 | sys.modules["__main__"] = save_main | |
|
241 | 242 | |
|
242 | 243 | if color_scheme is not None: |
|
243 | 244 | warnings.warn( |
@@ -272,7 +273,6 b' class Pdb(OldPdb):' | |||
|
272 | 273 | cst['Neutral'].colors.breakpoint_enabled = C.LightRed |
|
273 | 274 | cst['Neutral'].colors.breakpoint_disabled = C.Red |
|
274 | 275 | |
|
275 | ||
|
276 | 276 | # Add a python parser so we can syntax highlight source while |
|
277 | 277 | # debugging. |
|
278 | 278 | self.parser = PyColorize.Parser(style=color_scheme) |
@@ -320,13 +320,25 b' class Pdb(OldPdb):' | |||
|
320 | 320 | except KeyboardInterrupt: |
|
321 | 321 | self.stdout.write("\n" + self.shell.get_exception_only()) |
|
322 | 322 | |
|
323 | def precmd(self, line): | |
|
324 | """Perform useful escapes on the command before it is executed.""" | |
|
325 | ||
|
326 | if line.endswith("??"): | |
|
327 | line = "pinfo2 " + line[:-2] | |
|
328 | elif line.endswith("?"): | |
|
329 | line = "pinfo " + line[:-1] | |
|
330 | ||
|
331 | line = super().precmd(line) | |
|
332 | ||
|
333 | return line | |
|
334 | ||
|
323 | 335 | def new_do_frame(self, arg): |
|
324 | 336 | OldPdb.do_frame(self, arg) |
|
325 | 337 | |
|
326 | 338 | def new_do_quit(self, arg): |
|
327 | 339 | |
|
328 | 340 | if hasattr(self, 'old_all_completions'): |
|
329 | self.shell.Completer.all_completions=self.old_all_completions | |
|
341 | self.shell.Completer.all_completions = self.old_all_completions | |
|
330 | 342 | |
|
331 | 343 | return OldPdb.do_quit(self, arg) |
|
332 | 344 | |
@@ -344,7 +356,7 b' class Pdb(OldPdb):' | |||
|
344 | 356 | if context is None: |
|
345 | 357 | context = self.context |
|
346 | 358 | try: |
|
347 | context=int(context) | |
|
359 | context = int(context) | |
|
348 | 360 | if context <= 0: |
|
349 | 361 | raise ValueError("Context must be a positive integer") |
|
350 | 362 | except (TypeError, ValueError) as e: |
@@ -373,7 +385,7 b' class Pdb(OldPdb):' | |||
|
373 | 385 | if context is None: |
|
374 | 386 | context = self.context |
|
375 | 387 | try: |
|
376 | context=int(context) | |
|
388 | context = int(context) | |
|
377 | 389 | if context <= 0: |
|
378 | 390 | raise ValueError("Context must be a positive integer") |
|
379 | 391 | except (TypeError, ValueError) as e: |
@@ -390,7 +402,7 b' class Pdb(OldPdb):' | |||
|
390 | 402 | if context is None: |
|
391 | 403 | context = self.context |
|
392 | 404 | try: |
|
393 | context=int(context) | |
|
405 | context = int(context) | |
|
394 | 406 | if context <= 0: |
|
395 | 407 | print("Context must be a positive integer", file=self.stdout) |
|
396 | 408 | except (TypeError, ValueError): |
@@ -402,11 +414,10 b' class Pdb(OldPdb):' | |||
|
402 | 414 | |
|
403 | 415 | Colors = self.color_scheme_table.active_colors |
|
404 | 416 | ColorsNormal = Colors.Normal |
|
405 |
tpl_link = |
|
|
406 |
tpl_call = |
|
|
407 |
tpl_line = |
|
|
408 |
tpl_line_em = |
|
|
409 | ColorsNormal) | |
|
417 | tpl_link = "%s%%s%s" % (Colors.filenameEm, ColorsNormal) | |
|
418 | tpl_call = "%s%%s%s%%s%s" % (Colors.vName, Colors.valEm, ColorsNormal) | |
|
419 | tpl_line = "%%s%s%%s %s%%s" % (Colors.lineno, ColorsNormal) | |
|
420 | tpl_line_em = "%%s%s%%s %s%%s%s" % (Colors.linenoEm, Colors.line, ColorsNormal) | |
|
410 | 421 | |
|
411 | 422 | frame, lineno = frame_lineno |
|
412 | 423 | |
@@ -439,8 +450,8 b' class Pdb(OldPdb):' | |||
|
439 | 450 | if frame is self.curframe: |
|
440 | 451 | ret.append('> ') |
|
441 | 452 | else: |
|
442 |
ret.append( |
|
|
443 |
ret.append( |
|
|
453 | ret.append(" ") | |
|
454 | ret.append("%s(%s)%s\n" % (link, lineno, call)) | |
|
444 | 455 | |
|
445 | 456 | start = lineno - 1 - context//2 |
|
446 | 457 | lines = linecache.getlines(filename) |
@@ -448,17 +459,17 b' class Pdb(OldPdb):' | |||
|
448 | 459 | start = max(start, 0) |
|
449 | 460 | lines = lines[start : start + context] |
|
450 | 461 | |
|
451 | for i,line in enumerate(lines): | |
|
452 |
show_arrow = |
|
|
453 |
linetpl = (frame is self.curframe or show_arrow) |
|
|
454 | and tpl_line_em \ | |
|
455 |
|
|
|
456 | ret.append(self.__format_line(linetpl, filename, | |
|
457 | start + 1 + i, line, | |
|
458 | arrow = show_arrow) ) | |
|
459 |
return |
|
|
460 | ||
|
461 |
def __format_line(self, tpl_line, filename, lineno, line, arrow |
|
|
462 | for i, line in enumerate(lines): | |
|
463 | show_arrow = start + 1 + i == lineno | |
|
464 | linetpl = (frame is self.curframe or show_arrow) and tpl_line_em or tpl_line | |
|
465 | ret.append( | |
|
466 | self.__format_line( | |
|
467 | linetpl, filename, start + 1 + i, line, arrow=show_arrow | |
|
468 | ) | |
|
469 | ) | |
|
470 | return "".join(ret) | |
|
471 | ||
|
472 | def __format_line(self, tpl_line, filename, lineno, line, arrow=False): | |
|
462 | 473 | bp_mark = "" |
|
463 | 474 | bp_mark_color = "" |
|
464 | 475 | |
@@ -488,7 +499,6 b' class Pdb(OldPdb):' | |||
|
488 | 499 | |
|
489 | 500 | return tpl_line % (bp_mark_color + bp_mark, num, line) |
|
490 | 501 | |
|
491 | ||
|
492 | 502 | def print_list_lines(self, filename, first, last): |
|
493 | 503 | """The printing (as opposed to the parsing part of a 'list' |
|
494 | 504 | command.""" |
@@ -507,9 +517,13 b' class Pdb(OldPdb):' | |||
|
507 | 517 | break |
|
508 | 518 | |
|
509 | 519 | if lineno == self.curframe.f_lineno: |
|
510 |
line = self.__format_line( |
|
|
520 | line = self.__format_line( | |
|
521 | tpl_line_em, filename, lineno, line, arrow=True | |
|
522 | ) | |
|
511 | 523 | else: |
|
512 |
line = self.__format_line( |
|
|
524 | line = self.__format_line( | |
|
525 | tpl_line, filename, lineno, line, arrow=False | |
|
526 | ) | |
|
513 | 527 | |
|
514 | 528 | src.append(line) |
|
515 | 529 | self.lineno = lineno |
@@ -706,7 +720,7 b' class Pdb(OldPdb):' | |||
|
706 | 720 | |
|
707 | 721 | Will skip hidden frames. |
|
708 | 722 | """ |
|
709 |
|
|
|
723 | # modified version of upstream that skips | |
|
710 | 724 | # frames with __tracebackide__ |
|
711 | 725 | if self.curindex == 0: |
|
712 | 726 | self.error("Oldest frame") |
@@ -720,11 +734,9 b' class Pdb(OldPdb):' | |||
|
720 | 734 | if count < 0: |
|
721 | 735 | _newframe = 0 |
|
722 | 736 | else: |
|
723 | _newindex = self.curindex | |
|
724 | 737 | counter = 0 |
|
725 | 738 | hidden_frames = self.hidden_frames(self.stack) |
|
726 | 739 | for i in range(self.curindex - 1, -1, -1): |
|
727 | frame = self.stack[i][0] | |
|
728 | 740 | if hidden_frames[i] and self.skip_hidden: |
|
729 | 741 | skipped += 1 |
|
730 | 742 | continue |
@@ -765,12 +777,10 b' class Pdb(OldPdb):' | |||
|
765 | 777 | if count < 0: |
|
766 | 778 | _newframe = len(self.stack) - 1 |
|
767 | 779 | else: |
|
768 | _newindex = self.curindex | |
|
769 | 780 | counter = 0 |
|
770 | 781 | skipped = 0 |
|
771 | 782 | hidden_frames = self.hidden_frames(self.stack) |
|
772 | 783 | for i in range(self.curindex + 1, len(self.stack)): |
|
773 | frame = self.stack[i][0] | |
|
774 | 784 | if hidden_frames[i] and self.skip_hidden: |
|
775 | 785 | skipped += 1 |
|
776 | 786 | continue |
@@ -796,6 +806,20 b' class Pdb(OldPdb):' | |||
|
796 | 806 | do_d = do_down |
|
797 | 807 | do_u = do_up |
|
798 | 808 | |
|
809 | def do_context(self, context): | |
|
810 | """context number_of_lines | |
|
811 | Set the number of lines of source code to show when displaying | |
|
812 | stacktrace information. | |
|
813 | """ | |
|
814 | try: | |
|
815 | new_context = int(context) | |
|
816 | if new_context <= 0: | |
|
817 | raise ValueError() | |
|
818 | self.context = new_context | |
|
819 | except ValueError: | |
|
820 | self.error("The 'context' command requires a positive integer argument.") | |
|
821 | ||
|
822 | ||
|
799 | 823 | class InterruptiblePdb(Pdb): |
|
800 | 824 | """Version of debugger where KeyboardInterrupt exits the debugger altogether.""" |
|
801 | 825 |
@@ -567,7 +567,7 b' class JSON(DisplayObject):' | |||
|
567 | 567 | Path to a local file to load the data from. |
|
568 | 568 | expanded : boolean |
|
569 | 569 | Metadata to control whether a JSON display component is expanded. |
|
570 | metadata: dict | |
|
570 | metadata : dict | |
|
571 | 571 | Specify extra metadata to attach to the json display object. |
|
572 | 572 | root : str |
|
573 | 573 | The name of the root element of the JSON tree |
@@ -651,12 +651,11 b' class GeoJSON(JSON):' | |||
|
651 | 651 | A URL to download the data from. |
|
652 | 652 | filename : unicode |
|
653 | 653 | Path to a local file to load the data from. |
|
654 | metadata: dict | |
|
654 | metadata : dict | |
|
655 | 655 | Specify extra metadata to attach to the json display object. |
|
656 | 656 | |
|
657 | 657 | Examples |
|
658 | 658 | -------- |
|
659 | ||
|
660 | 659 | The following will display an interactive map of Mars with a point of |
|
661 | 660 | interest on frontend that do support GeoJSON display. |
|
662 | 661 | |
@@ -723,7 +722,7 b' class Javascript(TextDisplayObject):' | |||
|
723 | 722 | running the source code. The full URLs of the libraries should |
|
724 | 723 | be given. A single Javascript library URL can also be given as a |
|
725 | 724 | string. |
|
726 |
css |
|
|
725 | css : list or str | |
|
727 | 726 | A sequence of css files to load before running the source code. |
|
728 | 727 | The full URLs of the css files should be given. A single css URL |
|
729 | 728 | can also be given as a string. |
@@ -844,25 +843,33 b' class Image(DisplayObject):' | |||
|
844 | 843 | from image data. |
|
845 | 844 | For non-embedded images, you can just set the desired display width |
|
846 | 845 | and height directly. |
|
847 | unconfined: bool | |
|
846 | unconfined : bool | |
|
848 | 847 | Set unconfined=True to disable max-width confinement of the image. |
|
849 | metadata: dict | |
|
848 | metadata : dict | |
|
850 | 849 | Specify extra metadata to attach to the image. |
|
851 | 850 | |
|
852 | 851 | Examples |
|
853 | 852 | -------- |
|
854 |
|
|
|
855 |
|
|
|
856 |
|
|
|
857 |
|
|
|
858 | Image('http://www.google.fr/images/srpr/logo3w.png') | |
|
859 | Image('/path/to/image.jpg') | |
|
860 | Image(b'RAW_PNG_DATA...') | |
|
861 | ||
|
862 | # Specifying Image(url=...) does not embed the image data, | |
|
863 | # it only generates `<img>` tag with a link to the source. | |
|
864 | # This will not work in the qtconsole or offline. | |
|
865 | Image(url='http://www.google.fr/images/srpr/logo3w.png') | |
|
853 | embedded image data, works in qtconsole and notebook | |
|
854 | when passed positionally, the first arg can be any of raw image data, | |
|
855 | a URL, or a filename from which to load image data. | |
|
856 | The result is always embedding image data for inline images. | |
|
857 | ||
|
858 | >>> Image('http://www.google.fr/images/srpr/logo3w.png') | |
|
859 | <IPython.core.display.Image object> | |
|
860 | ||
|
861 | >>> Image('/path/to/image.jpg') | |
|
862 | <IPython.core.display.Image object> | |
|
863 | ||
|
864 | >>> Image(b'RAW_PNG_DATA...') | |
|
865 | <IPython.core.display.Image object> | |
|
866 | ||
|
867 | Specifying Image(url=...) does not embed the image data, | |
|
868 | it only generates ``<img>`` tag with a link to the source. | |
|
869 | This will not work in the qtconsole or offline. | |
|
870 | ||
|
871 | >>> Image(url='http://www.google.fr/images/srpr/logo3w.png') | |
|
872 | <IPython.core.display.Image object> | |
|
866 | 873 | |
|
867 | 874 | """ |
|
868 | 875 | if isinstance(data, (Path, PurePath)): |
@@ -1036,25 +1043,24 b' class Video(DisplayObject):' | |||
|
1036 | 1043 | ---------- |
|
1037 | 1044 | data : unicode, str or bytes |
|
1038 | 1045 | The raw video data or a URL or filename to load the data from. |
|
1039 | Raw data will require passing `embed=True`. | |
|
1046 | Raw data will require passing ``embed=True``. | |
|
1040 | 1047 | url : unicode |
|
1041 | A URL for the video. If you specify `url=`, | |
|
1048 | A URL for the video. If you specify ``url=``, | |
|
1042 | 1049 | the image data will not be embedded. |
|
1043 | 1050 | filename : unicode |
|
1044 | 1051 | Path to a local file containing the video. |
|
1045 | Will be interpreted as a local URL unless `embed=True`. | |
|
1052 | Will be interpreted as a local URL unless ``embed=True``. | |
|
1046 | 1053 | embed : bool |
|
1047 | 1054 | Should the video be embedded using a data URI (True) or be |
|
1048 | 1055 | loaded using a <video> tag (False). |
|
1049 | 1056 | |
|
1050 | 1057 | Since videos are large, embedding them should be avoided, if possible. |
|
1051 | You must confirm embedding as your intention by passing `embed=True`. | |
|
1058 | You must confirm embedding as your intention by passing ``embed=True``. | |
|
1052 | 1059 | |
|
1053 | 1060 | Local files can be displayed with URLs without embedding the content, via:: |
|
1054 | 1061 | |
|
1055 | 1062 | Video('./video.mp4') |
|
1056 | ||
|
1057 | mimetype: unicode | |
|
1063 | mimetype : unicode | |
|
1058 | 1064 | Specify the mimetype for embedded videos. |
|
1059 | 1065 | Default will be guessed from file extension, if available. |
|
1060 | 1066 | width : int |
@@ -1064,14 +1070,13 b' class Video(DisplayObject):' | |||
|
1064 | 1070 | Height in pixels to which to constrain the video in html. |
|
1065 | 1071 | If not supplied, defaults to the height of the video. |
|
1066 | 1072 | html_attributes : str |
|
1067 | Attributes for the HTML `<video>` block. | |
|
1068 | Default: `"controls"` to get video controls. | |
|
1069 | Other examples: `"controls muted"` for muted video with controls, | |
|
1070 | `"loop autoplay"` for looping autoplaying video without controls. | |
|
1073 | Attributes for the HTML ``<video>`` block. | |
|
1074 | Default: ``"controls"`` to get video controls. | |
|
1075 | Other examples: ``"controls muted"`` for muted video with controls, | |
|
1076 | ``"loop autoplay"`` for looping autoplaying video without controls. | |
|
1071 | 1077 | |
|
1072 | 1078 | Examples |
|
1073 | 1079 | -------- |
|
1074 | ||
|
1075 | 1080 | :: |
|
1076 | 1081 | |
|
1077 | 1082 | Video('https://archive.org/download/Sita_Sings_the_Blues/Sita_Sings_the_Blues_small.mp4') |
@@ -1165,7 +1170,7 b' def set_matplotlib_formats(*formats, **kwargs):' | |||
|
1165 | 1170 | ---------- |
|
1166 | 1171 | *formats : strs |
|
1167 | 1172 | One or more figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'. |
|
1168 |
**kwargs |
|
|
1173 | **kwargs | |
|
1169 | 1174 | Keyword args will be relayed to ``figure.canvas.print_figure``. |
|
1170 | 1175 | """ |
|
1171 | 1176 | from IPython.core.interactiveshell import InteractiveShell |
@@ -508,6 +508,20 b' def make_tokens_by_line(lines:List[str]):' | |||
|
508 | 508 | |
|
509 | 509 | return tokens_by_line |
|
510 | 510 | |
|
511 | ||
|
512 | def has_sunken_brackets(tokens: List[tokenize.TokenInfo]): | |
|
513 | """Check if the depth of brackets in the list of tokens drops below 0""" | |
|
514 | parenlev = 0 | |
|
515 | for token in tokens: | |
|
516 | if token.string in {"(", "[", "{"}: | |
|
517 | parenlev += 1 | |
|
518 | elif token.string in {")", "]", "}"}: | |
|
519 | parenlev -= 1 | |
|
520 | if parenlev < 0: | |
|
521 | return True | |
|
522 | return False | |
|
523 | ||
|
524 | ||
|
511 | 525 | def show_linewise_tokens(s: str): |
|
512 | 526 | """For investigation and debugging""" |
|
513 | 527 | if not s.endswith('\n'): |
@@ -662,6 +676,15 b' class TransformerManager:' | |||
|
662 | 676 | |
|
663 | 677 | tokens_by_line = make_tokens_by_line(lines) |
|
664 | 678 | |
|
679 | # Bail if we got one line and there are more closing parentheses than | |
|
680 | # the opening ones | |
|
681 | if ( | |
|
682 | len(lines) == 1 | |
|
683 | and tokens_by_line | |
|
684 | and has_sunken_brackets(tokens_by_line[0]) | |
|
685 | ): | |
|
686 | return "invalid", None | |
|
687 | ||
|
665 | 688 | if not tokens_by_line: |
|
666 | 689 | return 'incomplete', find_last_indent(lines) |
|
667 | 690 |
@@ -340,7 +340,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
340 | 340 | """An enhanced, interactive shell for Python.""" |
|
341 | 341 | |
|
342 | 342 | _instance = None |
|
343 | ||
|
343 | ||
|
344 | 344 | ast_transformers = List([], help= |
|
345 | 345 | """ |
|
346 | 346 | A list of ast.NodeTransformer subclass instances, which will be applied |
@@ -407,7 +407,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
407 | 407 | Enable magic commands to be called without the leading %. |
|
408 | 408 | """ |
|
409 | 409 | ).tag(config=True) |
|
410 | ||
|
410 | ||
|
411 | 411 | banner1 = Unicode(default_banner, |
|
412 | 412 | help="""The part of the banner to be printed before the profile""" |
|
413 | 413 | ).tag(config=True) |
@@ -443,7 +443,8 b' class InteractiveShell(SingletonConfigurable):' | |||
|
443 | 443 | display_formatter = Instance(DisplayFormatter, allow_none=True) |
|
444 | 444 | displayhook_class = Type(DisplayHook) |
|
445 | 445 | display_pub_class = Type(DisplayPublisher) |
|
446 | ||
|
446 | compiler_class = Type(CachingCompiler) | |
|
447 | ||
|
447 | 448 | sphinxify_docstring = Bool(False, help= |
|
448 | 449 | """ |
|
449 | 450 | Enables rich html representation of docstrings. (This requires the |
@@ -534,7 +535,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
534 | 535 | ).tag(config=True) |
|
535 | 536 | |
|
536 | 537 | # deprecated prompt traits: |
|
537 | ||
|
538 | ||
|
538 | 539 | prompt_in1 = Unicode('In [\\#]: ', |
|
539 | 540 | help="Deprecated since IPython 4.0 and ignored since 5.0, set TerminalInteractiveShell.prompts object directly." |
|
540 | 541 | ).tag(config=True) |
@@ -547,14 +548,14 b' class InteractiveShell(SingletonConfigurable):' | |||
|
547 | 548 | prompts_pad_left = Bool(True, |
|
548 | 549 | help="Deprecated since IPython 4.0 and ignored since 5.0, set TerminalInteractiveShell.prompts object directly." |
|
549 | 550 | ).tag(config=True) |
|
550 | ||
|
551 | ||
|
551 | 552 | @observe('prompt_in1', 'prompt_in2', 'prompt_out', 'prompt_pad_left') |
|
552 | 553 | def _prompt_trait_changed(self, change): |
|
553 | 554 | name = change['name'] |
|
554 | 555 | warn("InteractiveShell.{name} is deprecated since IPython 4.0" |
|
555 | 556 | " and ignored since 5.0, set TerminalInteractiveShell.prompts" |
|
556 | 557 | " object directly.".format(name=name)) |
|
557 | ||
|
558 | ||
|
558 | 559 | # protect against weird cases where self.config may not exist: |
|
559 | 560 | |
|
560 | 561 | show_rewritten_input = Bool(True, |
@@ -638,7 +639,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
638 | 639 | self.init_profile_dir(profile_dir) |
|
639 | 640 | self.init_instance_attrs() |
|
640 | 641 | self.init_environment() |
|
641 | ||
|
642 | ||
|
642 | 643 | # Check if we're in a virtualenv, and set up sys.path. |
|
643 | 644 | self.init_virtualenv() |
|
644 | 645 | |
@@ -748,7 +749,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
748 | 749 | self.more = False |
|
749 | 750 | |
|
750 | 751 | # command compiler |
|
751 |
self.compile = |
|
|
752 | self.compile = self.compiler_class() | |
|
752 | 753 | |
|
753 | 754 | # Make an empty namespace, which extension writers can rely on both |
|
754 | 755 | # existing and NEVER being used by ipython itself. This gives them a |
@@ -931,17 +932,27 b' class InteractiveShell(SingletonConfigurable):' | |||
|
931 | 932 | # Our exe is inside or has access to the virtualenv, don't need to do anything. |
|
932 | 933 | return |
|
933 | 934 | |
|
934 | warn("Attempting to work in a virtualenv. If you encounter problems, please " | |
|
935 | "install IPython inside the virtualenv.") | |
|
936 | 935 | if sys.platform == "win32": |
|
937 |
virtual_env = Path(os.environ["VIRTUAL_ENV"]) |
|
|
938 | "Lib", "site-packages" | |
|
939 | ) | |
|
936 | virtual_env = Path(os.environ["VIRTUAL_ENV"], "Lib", "site-packages") | |
|
940 | 937 | else: |
|
941 |
virtual_env = Path( |
|
|
942 |
"lib", "python{}.{}" |
|
|
938 | virtual_env_path = Path( | |
|
939 | os.environ["VIRTUAL_ENV"], "lib", "python{}.{}", "site-packages" | |
|
943 | 940 | ) |
|
944 | ||
|
941 | p_ver = sys.version_info[:2] | |
|
942 | ||
|
943 | # Predict version from py[thon]-x.x in the $VIRTUAL_ENV | |
|
944 | re_m = re.search(r"\bpy(?:thon)?([23])\.(\d+)\b", os.environ["VIRTUAL_ENV"]) | |
|
945 | if re_m: | |
|
946 | predicted_path = Path(str(virtual_env_path).format(*re_m.groups())) | |
|
947 | if predicted_path.exists(): | |
|
948 | p_ver = re_m.groups() | |
|
949 | ||
|
950 | virtual_env = str(virtual_env_path).format(*p_ver) | |
|
951 | ||
|
952 | warn( | |
|
953 | "Attempting to work in a virtualenv. If you encounter problems, " | |
|
954 | "please install IPython inside the virtualenv." | |
|
955 | ) | |
|
945 | 956 | import site |
|
946 | 957 | sys.path.insert(0, virtual_env) |
|
947 | 958 | site.addsitedir(virtual_env) |
@@ -976,7 +987,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
976 | 987 | #------------------------------------------------------------------------- |
|
977 | 988 | # Things related to the banner |
|
978 | 989 | #------------------------------------------------------------------------- |
|
979 | ||
|
990 | ||
|
980 | 991 | @property |
|
981 | 992 | def banner(self): |
|
982 | 993 | banner = self.banner1 |
@@ -990,7 +1001,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
990 | 1001 | if banner is None: |
|
991 | 1002 | banner = self.banner |
|
992 | 1003 | sys.stdout.write(banner) |
|
993 | ||
|
1004 | ||
|
994 | 1005 | #------------------------------------------------------------------------- |
|
995 | 1006 | # Things related to hooks |
|
996 | 1007 | #------------------------------------------------------------------------- |
@@ -1007,10 +1018,10 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1007 | 1018 | # default hooks have priority 100, i.e. low; user hooks should have |
|
1008 | 1019 | # 0-100 priority |
|
1009 | 1020 | self.set_hook(hook_name,getattr(hooks,hook_name), 100, _warn_deprecated=False) |
|
1010 | ||
|
1021 | ||
|
1011 | 1022 | if self.display_page: |
|
1012 | 1023 | self.set_hook('show_in_pager', page.as_hook(page.display_page), 90) |
|
1013 | ||
|
1024 | ||
|
1014 | 1025 | def set_hook(self,name,hook, priority=50, str_key=None, re_key=None, |
|
1015 | 1026 | _warn_deprecated=True): |
|
1016 | 1027 | """set_hook(name,hook) -> sets an internal IPython hook. |
@@ -1074,7 +1085,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1074 | 1085 | warn("ip.register_post_execute is deprecated, use " |
|
1075 | 1086 | "ip.events.register('post_run_cell', func) instead.", stacklevel=2) |
|
1076 | 1087 | self.events.register('post_run_cell', func) |
|
1077 | ||
|
1088 | ||
|
1078 | 1089 | def _clear_warning_registry(self): |
|
1079 | 1090 | # clear the warning registry, so that different code blocks with |
|
1080 | 1091 | # overlapping line number ranges don't cause spurious suppression of |
@@ -1116,12 +1127,12 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1116 | 1127 | else: |
|
1117 | 1128 | main_mod.__dict__.clear() |
|
1118 | 1129 | main_mod.__name__ = modname |
|
1119 | ||
|
1130 | ||
|
1120 | 1131 | main_mod.__file__ = filename |
|
1121 | 1132 | # It seems pydoc (and perhaps others) needs any module instance to |
|
1122 | 1133 | # implement a __nonzero__ method |
|
1123 | 1134 | main_mod.__nonzero__ = lambda : True |
|
1124 | ||
|
1135 | ||
|
1125 | 1136 | return main_mod |
|
1126 | 1137 | |
|
1127 | 1138 | def clear_main_mod_cache(self): |
@@ -1273,7 +1284,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1273 | 1284 | 'user_local':self.user_ns, |
|
1274 | 1285 | 'builtin':builtin_mod.__dict__ |
|
1275 | 1286 | } |
|
1276 | ||
|
1287 | ||
|
1277 | 1288 | @property |
|
1278 | 1289 | def user_global_ns(self): |
|
1279 | 1290 | return self.user_module.__dict__ |
@@ -1306,17 +1317,17 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1306 | 1317 | user_ns.setdefault("__name__", "__main__") |
|
1307 | 1318 | user_module = DummyMod() |
|
1308 | 1319 | user_module.__dict__ = user_ns |
|
1309 | ||
|
1320 | ||
|
1310 | 1321 | if user_module is None: |
|
1311 | 1322 | user_module = types.ModuleType("__main__", |
|
1312 | 1323 | doc="Automatically created module for IPython interactive environment") |
|
1313 | ||
|
1324 | ||
|
1314 | 1325 | # We must ensure that __builtin__ (without the final 's') is always |
|
1315 | 1326 | # available and pointing to the __builtin__ *module*. For more details: |
|
1316 | 1327 | # http://mail.python.org/pipermail/python-dev/2001-April/014068.html |
|
1317 | 1328 | user_module.__dict__.setdefault('__builtin__', builtin_mod) |
|
1318 | 1329 | user_module.__dict__.setdefault('__builtins__', builtin_mod) |
|
1319 | ||
|
1330 | ||
|
1320 | 1331 | if user_ns is None: |
|
1321 | 1332 | user_ns = user_module.__dict__ |
|
1322 | 1333 | |
@@ -1372,7 +1383,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1372 | 1383 | # For more details: |
|
1373 | 1384 | # http://mail.python.org/pipermail/python-dev/2001-April/014068.html |
|
1374 | 1385 | ns = {} |
|
1375 | ||
|
1386 | ||
|
1376 | 1387 | # make global variables for user access to the histories |
|
1377 | 1388 | ns['_ih'] = self.history_manager.input_hist_parsed |
|
1378 | 1389 | ns['_oh'] = self.history_manager.output_hist |
@@ -1385,7 +1396,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1385 | 1396 | |
|
1386 | 1397 | # Store myself as the public api!!! |
|
1387 | 1398 | ns['get_ipython'] = self.get_ipython |
|
1388 | ||
|
1399 | ||
|
1389 | 1400 | ns['exit'] = self.exiter |
|
1390 | 1401 | ns['quit'] = self.exiter |
|
1391 | 1402 | |
@@ -1399,7 +1410,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1399 | 1410 | |
|
1400 | 1411 | # Finally, update the real user's namespace |
|
1401 | 1412 | self.user_ns.update(ns) |
|
1402 | ||
|
1413 | ||
|
1403 | 1414 | @property |
|
1404 | 1415 | def all_ns_refs(self): |
|
1405 | 1416 | """Get a list of references to all the namespace dictionaries in which |
@@ -1425,7 +1436,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1425 | 1436 | # Reset last execution result |
|
1426 | 1437 | self.last_execution_succeeded = True |
|
1427 | 1438 | self.last_execution_result = None |
|
1428 | ||
|
1439 | ||
|
1429 | 1440 | # Flush cached output items |
|
1430 | 1441 | if self.displayhook.do_full_cache: |
|
1431 | 1442 | self.displayhook.flush() |
@@ -1490,7 +1501,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1490 | 1501 | raise ValueError("Refusing to delete %s" % varname) |
|
1491 | 1502 | |
|
1492 | 1503 | ns_refs = self.all_ns_refs |
|
1493 | ||
|
1504 | ||
|
1494 | 1505 | if by_name: # Delete by name |
|
1495 | 1506 | for ns in ns_refs: |
|
1496 | 1507 | try: |
@@ -1765,8 +1776,14 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1765 | 1776 | if meth == 'pdoc': |
|
1766 | 1777 | pmethod(info.obj, oname, formatter) |
|
1767 | 1778 | elif meth == 'pinfo': |
|
1768 | pmethod(info.obj, oname, formatter, info, | |
|
1769 | enable_html_pager=self.enable_html_pager, **kw) | |
|
1779 | pmethod( | |
|
1780 | info.obj, | |
|
1781 | oname, | |
|
1782 | formatter, | |
|
1783 | info, | |
|
1784 | enable_html_pager=self.enable_html_pager, | |
|
1785 | **kw | |
|
1786 | ) | |
|
1770 | 1787 | else: |
|
1771 | 1788 | pmethod(info.obj, oname) |
|
1772 | 1789 | else: |
@@ -1890,7 +1907,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1890 | 1907 | print('Exception type :', etype) |
|
1891 | 1908 | print('Exception value:', value) |
|
1892 | 1909 | print('Traceback :', tb) |
|
1893 | ||
|
1910 | ||
|
1894 | 1911 | def validate_stb(stb): |
|
1895 | 1912 | """validate structured traceback return type |
|
1896 | 1913 | |
@@ -1919,7 +1936,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1919 | 1936 | else: |
|
1920 | 1937 | def wrapped(self,etype,value,tb,tb_offset=None): |
|
1921 | 1938 | """wrap CustomTB handler, to protect IPython from user code |
|
1922 | ||
|
1939 | ||
|
1923 | 1940 | This makes it harder (but not impossible) for custom exception |
|
1924 | 1941 | handlers to crash IPython. |
|
1925 | 1942 | """ |
@@ -1968,10 +1985,10 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1968 | 1985 | |
|
1969 | 1986 | def _get_exc_info(self, exc_tuple=None): |
|
1970 | 1987 | """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc. |
|
1971 | ||
|
1988 | ||
|
1972 | 1989 | Ensures sys.last_type,value,traceback hold the exc_info we found, |
|
1973 | 1990 | from whichever source. |
|
1974 | ||
|
1991 | ||
|
1975 | 1992 | raises ValueError if none of these contain any information |
|
1976 | 1993 | """ |
|
1977 | 1994 | if exc_tuple is None: |
@@ -1983,10 +2000,10 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1983 | 2000 | if hasattr(sys, 'last_type'): |
|
1984 | 2001 | etype, value, tb = sys.last_type, sys.last_value, \ |
|
1985 | 2002 | sys.last_traceback |
|
1986 | ||
|
2003 | ||
|
1987 | 2004 | if etype is None: |
|
1988 | 2005 | raise ValueError("No exception to find") |
|
1989 | ||
|
2006 | ||
|
1990 | 2007 | # Now store the exception info in sys.last_type etc. |
|
1991 | 2008 | # WARNING: these variables are somewhat deprecated and not |
|
1992 | 2009 | # necessarily safe to use in a threaded environment, but tools |
@@ -1995,16 +2012,16 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1995 | 2012 | sys.last_type = etype |
|
1996 | 2013 | sys.last_value = value |
|
1997 | 2014 | sys.last_traceback = tb |
|
1998 | ||
|
2015 | ||
|
1999 | 2016 | return etype, value, tb |
|
2000 | ||
|
2017 | ||
|
2001 | 2018 | def show_usage_error(self, exc): |
|
2002 | 2019 | """Show a short message for UsageErrors |
|
2003 | ||
|
2020 | ||
|
2004 | 2021 | These are special exceptions that shouldn't show a traceback. |
|
2005 | 2022 | """ |
|
2006 | 2023 | print("UsageError: %s" % exc, file=sys.stderr) |
|
2007 | ||
|
2024 | ||
|
2008 | 2025 | def get_exception_only(self, exc_tuple=None): |
|
2009 | 2026 | """ |
|
2010 | 2027 | Return as a string (ending with a newline) the exception that |
@@ -2118,7 +2135,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2118 | 2135 | |
|
2119 | 2136 | def init_readline(self): |
|
2120 | 2137 | """DEPRECATED |
|
2121 | ||
|
2138 | ||
|
2122 | 2139 | Moved to terminal subclass, here only to simplify the init logic.""" |
|
2123 | 2140 | # Set a number of methods that depend on readline to be no-op |
|
2124 | 2141 | warnings.warn('`init_readline` is no-op since IPython 5.0 and is Deprecated', |
@@ -2285,12 +2302,13 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2285 | 2302 | # should be split into a prompt manager and displayhook. We probably |
|
2286 | 2303 | # even need a centralize colors management object. |
|
2287 | 2304 | self.run_line_magic('colors', self.colors) |
|
2288 | ||
|
2305 | ||
|
2289 | 2306 | # Defined here so that it's included in the documentation |
|
2290 | 2307 | @functools.wraps(magic.MagicsManager.register_function) |
|
2291 | 2308 | def register_magic_function(self, func, magic_kind='line', magic_name=None): |
|
2292 |
self.magics_manager.register_function( |
|
|
2293 |
|
|
|
2309 | self.magics_manager.register_function( | |
|
2310 | func, magic_kind=magic_kind, magic_name=magic_name | |
|
2311 | ) | |
|
2294 | 2312 | |
|
2295 | 2313 | def run_line_magic(self, magic_name, line, _stack_depth=1): |
|
2296 | 2314 | """Execute the given line magic. |
@@ -2521,7 +2539,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2521 | 2539 | ec = 130 |
|
2522 | 2540 | if ec > 128: |
|
2523 | 2541 | ec = -(ec - 128) |
|
2524 | ||
|
2542 | ||
|
2525 | 2543 | # We explicitly do NOT return the subprocess status code, because |
|
2526 | 2544 | # a non-None value would trigger :func:`sys.displayhook` calls. |
|
2527 | 2545 | # Instead, we store the exit_code in user_ns. Note the semantics |
@@ -2584,7 +2602,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2584 | 2602 | def init_payload(self): |
|
2585 | 2603 | self.payload_manager = PayloadManager(parent=self) |
|
2586 | 2604 | self.configurables.append(self.payload_manager) |
|
2587 | ||
|
2605 | ||
|
2588 | 2606 | #------------------------------------------------------------------------- |
|
2589 | 2607 | # Things related to the prefilter |
|
2590 | 2608 | #------------------------------------------------------------------------- |
@@ -2624,13 +2642,13 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2624 | 2642 | |
|
2625 | 2643 | def _user_obj_error(self): |
|
2626 | 2644 | """return simple exception dict |
|
2627 | ||
|
2645 | ||
|
2628 | 2646 | for use in user_expressions |
|
2629 | 2647 | """ |
|
2630 | ||
|
2648 | ||
|
2631 | 2649 | etype, evalue, tb = self._get_exc_info() |
|
2632 | 2650 | stb = self.InteractiveTB.get_exception_only(etype, evalue) |
|
2633 | ||
|
2651 | ||
|
2634 | 2652 | exc_info = { |
|
2635 | 2653 | "status": "error", |
|
2636 | 2654 | "traceback": stb, |
@@ -2639,13 +2657,13 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2639 | 2657 | } |
|
2640 | 2658 | |
|
2641 | 2659 | return exc_info |
|
2642 | ||
|
2660 | ||
|
2643 | 2661 | def _format_user_obj(self, obj): |
|
2644 | 2662 | """format a user object to display dict |
|
2645 | ||
|
2663 | ||
|
2646 | 2664 | for use in user_expressions |
|
2647 | 2665 | """ |
|
2648 | ||
|
2666 | ||
|
2649 | 2667 | data, md = self.display_formatter.format(obj) |
|
2650 | 2668 | value = { |
|
2651 | 2669 | 'status' : 'ok', |
@@ -2653,7 +2671,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2653 | 2671 | 'metadata' : md, |
|
2654 | 2672 | } |
|
2655 | 2673 | return value |
|
2656 | ||
|
2674 | ||
|
2657 | 2675 | def user_expressions(self, expressions): |
|
2658 | 2676 | """Evaluate a dict of expressions in the user's namespace. |
|
2659 | 2677 | |
@@ -2672,7 +2690,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2672 | 2690 | out = {} |
|
2673 | 2691 | user_ns = self.user_ns |
|
2674 | 2692 | global_ns = self.user_global_ns |
|
2675 | ||
|
2693 | ||
|
2676 | 2694 | for key, expr in expressions.items(): |
|
2677 | 2695 | try: |
|
2678 | 2696 | value = self._format_user_obj(eval(expr, global_ns, user_ns)) |
@@ -3086,12 +3104,14 b' class InteractiveShell(SingletonConfigurable):' | |||
|
3086 | 3104 | # Our own compiler remembers the __future__ environment. If we want to |
|
3087 | 3105 | # run code with a separate __future__ environment, use the default |
|
3088 | 3106 | # compiler |
|
3089 |
compiler = self.compile if shell_futures else |
|
|
3107 | compiler = self.compile if shell_futures else self.compiler_class() | |
|
3090 | 3108 | |
|
3091 | 3109 | _run_async = False |
|
3092 | 3110 | |
|
3093 | 3111 | with self.builtin_trap: |
|
3094 |
cell_name = self.compile.cache( |
|
|
3112 | cell_name = self.compile.cache( | |
|
3113 | cell, self.execution_count, raw_code=raw_cell | |
|
3114 | ) | |
|
3095 | 3115 | |
|
3096 | 3116 | with self.display_trap: |
|
3097 | 3117 | # Compile to bytecode |
@@ -3197,13 +3217,13 b' class InteractiveShell(SingletonConfigurable):' | |||
|
3197 | 3217 | |
|
3198 | 3218 | def transform_ast(self, node): |
|
3199 | 3219 | """Apply the AST transformations from self.ast_transformers |
|
3200 | ||
|
3220 | ||
|
3201 | 3221 | Parameters |
|
3202 | 3222 | ---------- |
|
3203 | 3223 | node : ast.Node |
|
3204 | 3224 | The root node to be transformed. Typically called with the ast.Module |
|
3205 | 3225 | produced by parsing user input. |
|
3206 | ||
|
3226 | ||
|
3207 | 3227 | Returns |
|
3208 | 3228 | ------- |
|
3209 | 3229 | An ast.Node corresponding to the node it was called with. Note that it |
@@ -3250,7 +3270,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
3250 | 3270 | Experimental value: 'async' Will try to run top level interactive |
|
3251 | 3271 | async/await code in default runner, this will not respect the |
|
3252 | 3272 | interactivity setting and will only run the last node if it is an |
|
3253 |
expression. |
|
|
3273 | expression. | |
|
3254 | 3274 | |
|
3255 | 3275 | compiler : callable |
|
3256 | 3276 | A function with the same interface as the built-in compile(), to turn |
@@ -3471,17 +3491,17 b' class InteractiveShell(SingletonConfigurable):' | |||
|
3471 | 3491 | |
|
3472 | 3492 | def enable_gui(self, gui=None): |
|
3473 | 3493 | raise NotImplementedError('Implement enable_gui in a subclass') |
|
3474 | ||
|
3494 | ||
|
3475 | 3495 | def enable_matplotlib(self, gui=None): |
|
3476 | 3496 | """Enable interactive matplotlib and inline figure support. |
|
3477 | ||
|
3497 | ||
|
3478 | 3498 | This takes the following steps: |
|
3479 | ||
|
3499 | ||
|
3480 | 3500 | 1. select the appropriate eventloop and matplotlib backend |
|
3481 | 3501 | 2. set up matplotlib for interactive use with that backend |
|
3482 | 3502 | 3. configure formatters for inline figure display |
|
3483 | 3503 | 4. enable the selected gui eventloop |
|
3484 | ||
|
3504 | ||
|
3485 | 3505 | Parameters |
|
3486 | 3506 | ---------- |
|
3487 | 3507 | gui : optional, string |
@@ -3495,7 +3515,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
3495 | 3515 | """ |
|
3496 | 3516 | from IPython.core import pylabtools as pt |
|
3497 | 3517 | gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select) |
|
3498 | ||
|
3518 | ||
|
3499 | 3519 | if gui != 'inline': |
|
3500 | 3520 | # If we have our first gui selection, store it |
|
3501 | 3521 | if self.pylab_gui_select is None: |
@@ -3505,16 +3525,16 b' class InteractiveShell(SingletonConfigurable):' | |||
|
3505 | 3525 | print('Warning: Cannot change to a different GUI toolkit: %s.' |
|
3506 | 3526 | ' Using %s instead.' % (gui, self.pylab_gui_select)) |
|
3507 | 3527 | gui, backend = pt.find_gui_and_backend(self.pylab_gui_select) |
|
3508 | ||
|
3528 | ||
|
3509 | 3529 | pt.activate_matplotlib(backend) |
|
3510 | 3530 | pt.configure_inline_support(self, backend) |
|
3511 | ||
|
3531 | ||
|
3512 | 3532 | # Now we must activate the gui pylab wants to use, and fix %run to take |
|
3513 | 3533 | # plot updates into account |
|
3514 | 3534 | self.enable_gui(gui) |
|
3515 | 3535 | self.magics_manager.registry['ExecutionMagics'].default_runner = \ |
|
3516 | 3536 | pt.mpl_runner(self.safe_execfile) |
|
3517 | ||
|
3537 | ||
|
3518 | 3538 | return gui, backend |
|
3519 | 3539 | |
|
3520 | 3540 | def enable_pylab(self, gui=None, import_all=True, welcome_message=False): |
@@ -3524,7 +3544,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
3524 | 3544 | namespace all of numpy and pylab, and configures IPython to correctly |
|
3525 | 3545 | interact with the GUI event loop. The GUI backend to be used can be |
|
3526 | 3546 | optionally selected with the optional ``gui`` argument. |
|
3527 | ||
|
3547 | ||
|
3528 | 3548 | This method only adds preloading the namespace to InteractiveShell.enable_matplotlib. |
|
3529 | 3549 | |
|
3530 | 3550 | Parameters |
@@ -3544,9 +3564,9 b' class InteractiveShell(SingletonConfigurable):' | |||
|
3544 | 3564 | This argument is ignored, no welcome message will be displayed. |
|
3545 | 3565 | """ |
|
3546 | 3566 | from IPython.core.pylabtools import import_pylab |
|
3547 | ||
|
3567 | ||
|
3548 | 3568 | gui, backend = self.enable_matplotlib(gui) |
|
3549 | ||
|
3569 | ||
|
3550 | 3570 | # We want to prevent the loading of pylab to pollute the user's |
|
3551 | 3571 | # namespace as shown by the %who* magics, so we execute the activation |
|
3552 | 3572 | # code in an empty namespace, and we update *both* user_ns and |
@@ -20,7 +20,7 b' import re' | |||
|
20 | 20 | import sys |
|
21 | 21 | import ast |
|
22 | 22 | from itertools import chain |
|
23 | from urllib.request import urlopen | |
|
23 | from urllib.request import Request, urlopen | |
|
24 | 24 | from urllib.parse import urlencode |
|
25 | 25 | from pathlib import Path |
|
26 | 26 | |
@@ -29,6 +29,7 b' from IPython.core.error import TryNext, StdinNotImplementedError, UsageError' | |||
|
29 | 29 | from IPython.core.macro import Macro |
|
30 | 30 | from IPython.core.magic import Magics, magics_class, line_magic |
|
31 | 31 | from IPython.core.oinspect import find_file, find_source_lines |
|
32 | from IPython.core.release import version | |
|
32 | 33 | from IPython.testing.skipdoctest import skip_doctest |
|
33 | 34 | from IPython.utils.contexts import preserve_keys |
|
34 | 35 | from IPython.utils.path import get_py_filename |
@@ -245,7 +246,7 b' class CodeMagics(Magics):' | |||
|
245 | 246 | |
|
246 | 247 | @line_magic |
|
247 | 248 | def pastebin(self, parameter_s=''): |
|
248 |
"""Upload code to dpaste |
|
|
249 | """Upload code to dpaste.com, returning the URL. | |
|
249 | 250 | |
|
250 | 251 | Usage:\\ |
|
251 | 252 | %pastebin [-d "Custom description"] 1-7 |
@@ -255,7 +256,7 b' class CodeMagics(Magics):' | |||
|
255 | 256 | |
|
256 | 257 | Options: |
|
257 | 258 | |
|
258 |
-d: Pass a custom description |
|
|
259 | -d: Pass a custom description. The default will say | |
|
259 | 260 | "Pasted from IPython". |
|
260 | 261 | """ |
|
261 | 262 | opts, args = self.parse_options(parameter_s, 'd:') |
@@ -266,13 +267,19 b' class CodeMagics(Magics):' | |||
|
266 | 267 | print(e.args[0]) |
|
267 | 268 | return |
|
268 | 269 | |
|
269 |
post_data = urlencode( |
|
|
270 | "title": opts.get('d', "Pasted from IPython"), | |
|
271 | "syntax": "python3", | |
|
272 | "content": code | |
|
273 | }).encode('utf-8') | |
|
274 | ||
|
275 | response = urlopen("http://dpaste.com/api/v2/", post_data) | |
|
270 | post_data = urlencode( | |
|
271 | { | |
|
272 | "title": opts.get("d", "Pasted from IPython"), | |
|
273 | "syntax": "python", | |
|
274 | "content": code, | |
|
275 | } | |
|
276 | ).encode("utf-8") | |
|
277 | ||
|
278 | request = Request( | |
|
279 | "http://dpaste.com/api/v2/", | |
|
280 | headers={"User-Agent": "IPython v{}".format(version)}, | |
|
281 | ) | |
|
282 | response = urlopen(request, post_data) | |
|
276 | 283 | return response.headers.get('Location') |
|
277 | 284 | |
|
278 | 285 | @line_magic |
@@ -16,6 +16,7 b'' | |||
|
16 | 16 | import os |
|
17 | 17 | import sys |
|
18 | 18 | from io import open as io_open |
|
19 | import fnmatch | |
|
19 | 20 | |
|
20 | 21 | # Our own packages |
|
21 | 22 | from IPython.core.error import StdinNotImplementedError |
@@ -170,7 +171,8 b' class HistoryMagics(Magics):' | |||
|
170 | 171 | pattern = None |
|
171 | 172 | limit = None if args.limit is _unspecified else args.limit |
|
172 | 173 | |
|
173 |
|
|
|
174 | range_pattern = False | |
|
175 | if args.pattern is not None and not args.range: | |
|
174 | 176 | if args.pattern: |
|
175 | 177 | pattern = "*" + " ".join(args.pattern) + "*" |
|
176 | 178 | else: |
@@ -183,6 +185,9 b' class HistoryMagics(Magics):' | |||
|
183 | 185 | hist = history_manager.get_tail(n, raw=raw, output=get_output) |
|
184 | 186 | else: |
|
185 | 187 | if args.range: # Get history by ranges |
|
188 | if args.pattern: | |
|
189 | range_pattern = "*" + " ".join(args.pattern) + "*" | |
|
190 | print_nums = True | |
|
186 | 191 | hist = history_manager.get_range_by_str(" ".join(args.range), |
|
187 | 192 | raw, get_output) |
|
188 | 193 | else: # Just get history for the current session |
@@ -200,6 +205,9 b' class HistoryMagics(Magics):' | |||
|
200 | 205 | # into an editor. |
|
201 | 206 | if get_output: |
|
202 | 207 | inline, output = inline |
|
208 | if range_pattern: | |
|
209 | if not fnmatch.fnmatch(inline, range_pattern): | |
|
210 | continue | |
|
203 | 211 | inline = inline.expandtabs(4).rstrip() |
|
204 | 212 | |
|
205 | 213 | multiline = "\n" in inline |
@@ -13,7 +13,6 b' import shlex' | |||
|
13 | 13 | import sys |
|
14 | 14 | from pathlib import Path |
|
15 | 15 | |
|
16 | from pathlib import Path | |
|
17 | 16 | from IPython.core.magic import Magics, magics_class, line_magic |
|
18 | 17 | |
|
19 | 18 | |
@@ -28,7 +27,7 b' def _get_conda_executable():' | |||
|
28 | 27 | # Check if there is a conda executable in the same directory as the Python executable. |
|
29 | 28 | # This is the case within conda's root environment. |
|
30 | 29 | conda = Path(sys.executable).parent / "conda" |
|
31 | if conda.isfile(): | |
|
30 | if conda.is_file(): | |
|
32 | 31 | return str(conda) |
|
33 | 32 | |
|
34 | 33 | # Otherwise, attempt to extract the executable from conda history. |
@@ -41,7 +40,7 b' def _get_conda_executable():' | |||
|
41 | 40 | ) |
|
42 | 41 | if match: |
|
43 | 42 | return match.groupdict()["command"] |
|
44 | ||
|
43 | ||
|
45 | 44 | # Fallback: assume conda is available on the system path. |
|
46 | 45 | return "conda" |
|
47 | 46 | |
@@ -73,18 +72,19 b' class PackagingMagics(Magics):' | |||
|
73 | 72 | @line_magic |
|
74 | 73 | def conda(self, line): |
|
75 | 74 | """Run the conda package manager within the current kernel. |
|
76 | ||
|
75 | ||
|
77 | 76 | Usage: |
|
78 | 77 | %conda install [pkgs] |
|
79 | 78 | """ |
|
80 | 79 | if not _is_conda_environment(): |
|
81 | 80 | raise ValueError("The python kernel does not appear to be a conda environment. " |
|
82 | 81 | "Please use ``%pip install`` instead.") |
|
83 | ||
|
82 | ||
|
84 | 83 | conda = _get_conda_executable() |
|
85 | 84 | args = shlex.split(line) |
|
86 | command = args[0] | |
|
87 | args = args[1:] | |
|
85 | command = args[0] if len(args) > 0 else "" | |
|
86 | args = args[1:] if len(args) > 1 else [""] | |
|
87 | ||
|
88 | 88 | extra_args = [] |
|
89 | 89 | |
|
90 | 90 | # When the subprocess does not allow us to respond "yes" during the installation, |
@@ -183,7 +183,7 b' def test_set_matplotlib_formats_kwargs():' | |||
|
183 | 183 | ip = get_ipython() |
|
184 | 184 | cfg = _get_inline_config() |
|
185 | 185 | cfg.print_figure_kwargs.update(dict(foo='bar')) |
|
186 |
kwargs = dict( |
|
|
186 | kwargs = dict(dpi=150) | |
|
187 | 187 | display.set_matplotlib_formats('png', **kwargs) |
|
188 | 188 | formatter = ip.display_formatter.formatters['image/png'] |
|
189 | 189 | f = formatter.lookup_by_type(Figure) |
@@ -255,18 +255,18 b' def test_find_assign_op_dedent():' | |||
|
255 | 255 | |
|
256 | 256 | def test_check_complete(): |
|
257 | 257 | cc = ipt2.TransformerManager().check_complete |
|
258 |
nt.assert_equal(cc("a = 1"), ( |
|
|
259 |
nt.assert_equal(cc("for a in range(5):"), ( |
|
|
260 |
nt.assert_equal(cc("for a in range(5):\n if a > 0:"), ( |
|
|
261 |
nt.assert_equal(cc("raise = 2"), ( |
|
|
262 |
nt.assert_equal(cc("a = [1,\n2,"), ( |
|
|
263 |
nt.assert_equal(cc(")"), ( |
|
|
264 |
nt.assert_equal(cc("\\\r\n"), ( |
|
|
265 |
nt.assert_equal(cc("a = '''\n hi"), ( |
|
|
266 |
nt.assert_equal(cc("def a():\n x=1\n global x"), ( |
|
|
267 |
nt.assert_equal(cc("a \\ "), ( |
|
|
268 |
nt.assert_equal(cc("1\\\n+2"), ( |
|
|
269 |
nt.assert_equal(cc("exit"), ( |
|
|
258 | nt.assert_equal(cc("a = 1"), ("complete", None)) | |
|
259 | nt.assert_equal(cc("for a in range(5):"), ("incomplete", 4)) | |
|
260 | nt.assert_equal(cc("for a in range(5):\n if a > 0:"), ("incomplete", 8)) | |
|
261 | nt.assert_equal(cc("raise = 2"), ("invalid", None)) | |
|
262 | nt.assert_equal(cc("a = [1,\n2,"), ("incomplete", 0)) | |
|
263 | nt.assert_equal(cc("(\n))"), ("incomplete", 0)) | |
|
264 | nt.assert_equal(cc("\\\r\n"), ("incomplete", 0)) | |
|
265 | nt.assert_equal(cc("a = '''\n hi"), ("incomplete", 3)) | |
|
266 | nt.assert_equal(cc("def a():\n x=1\n global x"), ("invalid", None)) | |
|
267 | nt.assert_equal(cc("a \\ "), ("invalid", None)) # Nothing allowed after backslash | |
|
268 | nt.assert_equal(cc("1\\\n+2"), ("complete", None)) | |
|
269 | nt.assert_equal(cc("exit"), ("complete", None)) | |
|
270 | 270 | |
|
271 | 271 | example = dedent(""" |
|
272 | 272 | if True: |
@@ -297,6 +297,24 b' def test_check_complete_II():' | |||
|
297 | 297 | nt.assert_equal(cc('''def foo():\n """'''), ('incomplete', 4)) |
|
298 | 298 | |
|
299 | 299 | |
|
300 | def test_check_complete_invalidates_sunken_brackets(): | |
|
301 | """ | |
|
302 | Test that a single line with more closing brackets than the opening ones is | |
|
303 | interpretted as invalid | |
|
304 | """ | |
|
305 | cc = ipt2.TransformerManager().check_complete | |
|
306 | nt.assert_equal(cc(")"), ("invalid", None)) | |
|
307 | nt.assert_equal(cc("]"), ("invalid", None)) | |
|
308 | nt.assert_equal(cc("}"), ("invalid", None)) | |
|
309 | nt.assert_equal(cc(")("), ("invalid", None)) | |
|
310 | nt.assert_equal(cc("]["), ("invalid", None)) | |
|
311 | nt.assert_equal(cc("}{"), ("invalid", None)) | |
|
312 | nt.assert_equal(cc("]()("), ("invalid", None)) | |
|
313 | nt.assert_equal(cc("())("), ("invalid", None)) | |
|
314 | nt.assert_equal(cc(")[]("), ("invalid", None)) | |
|
315 | nt.assert_equal(cc("()]("), ("invalid", None)) | |
|
316 | ||
|
317 | ||
|
300 | 318 | def test_null_cleanup_transformer(): |
|
301 | 319 | manager = ipt2.TransformerManager() |
|
302 | 320 | manager.cleanup_transforms.insert(0, null_cleanup_transformer) |
@@ -117,84 +117,91 b' ZeroDivisionError Traceback (most recent call last)' | |||
|
117 | 117 | ZeroDivisionError: ... |
|
118 | 118 | """ |
|
119 | 119 | |
|
120 | def doctest_tb_sysexit(): | |
|
121 | """ | |
|
122 | In [17]: %xmode plain | |
|
123 | Exception reporting mode: Plain | |
|
124 | ||
|
125 | In [18]: %run simpleerr.py exit | |
|
126 | An exception has occurred, use %tb to see the full traceback. | |
|
127 | SystemExit: (1, 'Mode = exit') | |
|
128 | ||
|
129 | In [19]: %run simpleerr.py exit 2 | |
|
130 | An exception has occurred, use %tb to see the full traceback. | |
|
131 | SystemExit: (2, 'Mode = exit') | |
|
132 | ||
|
133 | In [20]: %tb | |
|
134 | Traceback (most recent call last): | |
|
135 | File ... in <module> | |
|
136 | bar(mode) | |
|
137 | File ... line 22, in bar | |
|
138 | sysexit(stat, mode) | |
|
139 | File ... line 11, in sysexit | |
|
140 | raise SystemExit(stat, 'Mode = %s' % mode) | |
|
141 | SystemExit: (2, 'Mode = exit') | |
|
142 | ||
|
143 | In [21]: %xmode context | |
|
144 | Exception reporting mode: Context | |
|
145 | ||
|
146 | In [22]: %tb | |
|
147 | --------------------------------------------------------------------------- | |
|
148 | SystemExit Traceback (most recent call last) | |
|
149 | <BLANKLINE> | |
|
150 | ...<module> | |
|
151 | 29 except IndexError: | |
|
152 | 30 mode = 'div' | |
|
153 | ---> 32 bar(mode) | |
|
154 | <BLANKLINE> | |
|
155 | ...bar(mode) | |
|
156 | 20 except: | |
|
157 | 21 stat = 1 | |
|
158 | ---> 22 sysexit(stat, mode) | |
|
159 | 23 else: | |
|
160 | 24 raise ValueError('Unknown mode') | |
|
161 | <BLANKLINE> | |
|
162 | ...sysexit(stat, mode) | |
|
163 | 10 def sysexit(stat, mode): | |
|
164 | ---> 11 raise SystemExit(stat, 'Mode = %s' % mode) | |
|
165 | <BLANKLINE> | |
|
166 | SystemExit: (2, 'Mode = exit') | |
|
167 | ||
|
168 | In [23]: %xmode verbose | |
|
169 | Exception reporting mode: Verbose | |
|
170 | ||
|
171 | In [24]: %tb | |
|
172 | --------------------------------------------------------------------------- | |
|
173 | SystemExit Traceback (most recent call last) | |
|
174 | <BLANKLINE> | |
|
175 | ... in <module> | |
|
176 | 29 except IndexError: | |
|
177 | 30 mode = 'div' | |
|
178 | ---> 32 bar(mode) | |
|
179 | mode = 'exit' | |
|
180 | <BLANKLINE> | |
|
181 | ... in bar(mode='exit') | |
|
182 | 20 except: | |
|
183 | 21 stat = 1 | |
|
184 | ---> 22 sysexit(stat, mode) | |
|
185 | mode = 'exit' | |
|
186 | stat = 2 | |
|
187 | 23 else: | |
|
188 | 24 raise ValueError('Unknown mode') | |
|
189 | <BLANKLINE> | |
|
190 | ... in sysexit(stat=2, mode='exit') | |
|
191 |
|
|
|
192 | ---> 11 raise SystemExit(stat, 'Mode = %s' % mode) | |
|
193 | stat = 2 | |
|
194 | mode = 'exit' | |
|
195 | <BLANKLINE> | |
|
196 | SystemExit: (2, 'Mode = exit') | |
|
197 | """ | |
|
120 | # TODO : Marc 2021 – this seem to fail due | |
|
121 | # to upstream changes in CI for whatever reason. | |
|
122 | # Commenting for now, to revive someday (maybe?) | |
|
123 | # nose won't work in 3.10 anyway and we'll have to disable iptest. | |
|
124 | # thus this likely need to bemigrated to pytest. | |
|
125 | ||
|
126 | ||
|
127 | # def doctest_tb_sysexit(): | |
|
128 | # """ | |
|
129 | # In [17]: %xmode plain | |
|
130 | # Exception reporting mode: Plain | |
|
131 | # | |
|
132 | # In [18]: %run simpleerr.py exit | |
|
133 | # An exception has occurred, use %tb to see the full traceback. | |
|
134 | # SystemExit: (1, 'Mode = exit') | |
|
135 | # | |
|
136 | # In [19]: %run simpleerr.py exit 2 | |
|
137 | # An exception has occurred, use %tb to see the full traceback. | |
|
138 | # SystemExit: (2, 'Mode = exit') | |
|
139 | # | |
|
140 | # In [20]: %tb | |
|
141 | # Traceback (most recent call last): | |
|
142 | # File ... in <module> | |
|
143 | # bar(mode) | |
|
144 | # File ... line 22, in bar | |
|
145 | # sysexit(stat, mode) | |
|
146 | # File ... line 11, in sysexit | |
|
147 | # raise SystemExit(stat, 'Mode = %s' % mode) | |
|
148 | # SystemExit: (2, 'Mode = exit') | |
|
149 | # | |
|
150 | # In [21]: %xmode context | |
|
151 | # Exception reporting mode: Context | |
|
152 | # | |
|
153 | # In [22]: %tb | |
|
154 | # --------------------------------------------------------------------------- | |
|
155 | # SystemExit Traceback (most recent call last) | |
|
156 | # <BLANKLINE> | |
|
157 | # ...<module> | |
|
158 | # 29 except IndexError: | |
|
159 | # 30 mode = 'div' | |
|
160 | # ---> 32 bar(mode) | |
|
161 | # <BLANKLINE> | |
|
162 | # ...bar(mode) | |
|
163 | # 20 except: | |
|
164 | # 21 stat = 1 | |
|
165 | # ---> 22 sysexit(stat, mode) | |
|
166 | # 23 else: | |
|
167 | # 24 raise ValueError('Unknown mode') | |
|
168 | # <BLANKLINE> | |
|
169 | # ...sysexit(stat, mode) | |
|
170 | # 10 def sysexit(stat, mode): | |
|
171 | # ---> 11 raise SystemExit(stat, 'Mode = %s' % mode) | |
|
172 | # <BLANKLINE> | |
|
173 | # SystemExit: (2, 'Mode = exit') | |
|
174 | # | |
|
175 | # In [23]: %xmode verbose | |
|
176 | # Exception reporting mode: Verbose | |
|
177 | # | |
|
178 | # In [24]: %tb | |
|
179 | # --------------------------------------------------------------------------- | |
|
180 | # SystemExit Traceback (most recent call last) | |
|
181 | # <BLANKLINE> | |
|
182 | # ... in <module> | |
|
183 | # 29 except IndexError: | |
|
184 | # 30 mode = 'div' | |
|
185 | # ---> 32 bar(mode) | |
|
186 | # mode = 'exit' | |
|
187 | # <BLANKLINE> | |
|
188 | # ... in bar(mode='exit') | |
|
189 | # 20 except: | |
|
190 | # 21 stat = 1 | |
|
191 | # ---> 22 sysexit(stat, mode) | |
|
192 | # mode = 'exit' | |
|
193 | # stat = 2 | |
|
194 | # 23 else: | |
|
195 | # 24 raise ValueError('Unknown mode') | |
|
196 | # <BLANKLINE> | |
|
197 | # ... in sysexit(stat=2, mode='exit') | |
|
198 | # 10 def sysexit(stat, mode): | |
|
199 | # ---> 11 raise SystemExit(stat, 'Mode = %s' % mode) | |
|
200 | # stat = 2 | |
|
201 | # mode = 'exit' | |
|
202 | # <BLANKLINE> | |
|
203 | # SystemExit: (2, 'Mode = exit') | |
|
204 | # """ | |
|
198 | 205 | |
|
199 | 206 | |
|
200 | 207 | def test_run_cell(): |
@@ -35,6 +35,8 b' from IPython.utils.tempdir import (TemporaryDirectory,' | |||
|
35 | 35 | from IPython.utils.process import find_cmd |
|
36 | 36 | from .test_debugger import PdbTestInput |
|
37 | 37 | |
|
38 | import pytest | |
|
39 | ||
|
38 | 40 | |
|
39 | 41 | @magic.magics_class |
|
40 | 42 | class DummyMagics(magic.Magics): pass |
@@ -954,7 +956,6 b' async def test_script_bg_out():' | |||
|
954 | 956 | nt.assert_equal((await ip.user_ns["output"].read()), b"hi\n") |
|
955 | 957 | ip.user_ns['output'].close() |
|
956 | 958 | |
|
957 | ||
|
958 | 959 | @dec.skip_win32 |
|
959 | 960 | async def test_script_bg_err(): |
|
960 | 961 | ip = get_ipython() |
@@ -8,6 +8,8 b' from os import walk, sep, fsdecode' | |||
|
8 | 8 | |
|
9 | 9 | from IPython.core.display import DisplayObject, TextDisplayObject |
|
10 | 10 | |
|
11 | from typing import Tuple | |
|
12 | ||
|
11 | 13 | __all__ = ['Audio', 'IFrame', 'YouTubeVideo', 'VimeoVideo', 'ScribdDocument', |
|
12 | 14 | 'FileLink', 'FileLinks', 'Code'] |
|
13 | 15 | |
@@ -70,13 +72,13 b' class Audio(DisplayObject):' | |||
|
70 | 72 | ... framerate = 44100 |
|
71 | 73 | ... t = np.linspace(0,5,framerate*5) |
|
72 | 74 | ... data = np.sin(2*np.pi*220*t) + np.sin(2*np.pi*224*t) |
|
73 | ... Audio(data,rate=framerate) | |
|
75 | ... Audio(data, rate=framerate) | |
|
74 | 76 | |
|
75 | 77 | Can also do stereo or more channels |
|
76 | 78 | |
|
77 | 79 | >>> dataleft = np.sin(2*np.pi*220*t) |
|
78 | 80 | ... dataright = np.sin(2*np.pi*224*t) |
|
79 | ... Audio([dataleft, dataright],rate=framerate) | |
|
81 | ... Audio([dataleft, dataright], rate=framerate) | |
|
80 | 82 | |
|
81 | 83 | From URL: |
|
82 | 84 | |
@@ -159,7 +161,7 b' class Audio(DisplayObject):' | |||
|
159 | 161 | return val |
|
160 | 162 | |
|
161 | 163 | @staticmethod |
|
162 | def _validate_and_normalize_with_numpy(data, normalize): | |
|
164 | def _validate_and_normalize_with_numpy(data, normalize) -> Tuple[bytes, int]: | |
|
163 | 165 | import numpy as np |
|
164 | 166 | |
|
165 | 167 | data = np.array(data, dtype=float) |
@@ -178,8 +180,7 b' class Audio(DisplayObject):' | |||
|
178 | 180 | max_abs_value = np.max(np.abs(data)) |
|
179 | 181 | normalization_factor = Audio._get_normalization_factor(max_abs_value, normalize) |
|
180 | 182 | scaled = data / normalization_factor * 32767 |
|
181 |
return scaled.astype( |
|
|
182 | ||
|
183 | return scaled.astype("<h").tobytes(), nchan | |
|
183 | 184 | |
|
184 | 185 | @staticmethod |
|
185 | 186 | def _validate_and_normalize_without_numpy(data, normalize): |
@@ -1,5 +1,4 b'' | |||
|
1 | 1 | import asyncio |
|
2 | import signal | |
|
3 | 2 | import sys |
|
4 | 3 | import threading |
|
5 | 4 | |
@@ -7,13 +6,8 b' from IPython.core.debugger import Pdb' | |||
|
7 | 6 | |
|
8 | 7 | from IPython.core.completer import IPCompleter |
|
9 | 8 | from .ptutils import IPythonPTCompleter |
|
10 |
from .shortcuts import create_ipython_shortcuts |
|
|
9 | from .shortcuts import create_ipython_shortcuts | |
|
11 | 10 | |
|
12 | from prompt_toolkit.enums import DEFAULT_BUFFER | |
|
13 | from prompt_toolkit.filters import (Condition, has_focus, has_selection, | |
|
14 | vi_insert_mode, emacs_insert_mode) | |
|
15 | from prompt_toolkit.key_binding import KeyBindings | |
|
16 | from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline | |
|
17 | 11 | from pygments.token import Token |
|
18 | 12 | from prompt_toolkit.shortcuts.prompt import PromptSession |
|
19 | 13 | from prompt_toolkit.enums import EditingMode |
@@ -34,22 +28,20 b' class TerminalPdb(Pdb):' | |||
|
34 | 28 | def pt_init(self, pt_session_options=None): |
|
35 | 29 | """Initialize the prompt session and the prompt loop |
|
36 | 30 | and store them in self.pt_app and self.pt_loop. |
|
37 | ||
|
31 | ||
|
38 | 32 | Additional keyword arguments for the PromptSession class |
|
39 | 33 | can be specified in pt_session_options. |
|
40 | 34 | """ |
|
41 | 35 | if pt_session_options is None: |
|
42 | 36 | pt_session_options = {} |
|
43 | ||
|
37 | ||
|
44 | 38 | def get_prompt_tokens(): |
|
45 | 39 | return [(Token.Prompt, self.prompt)] |
|
46 | 40 | |
|
47 | 41 | if self._ptcomp is None: |
|
48 |
compl = IPCompleter( |
|
|
49 | namespace={}, | |
|
50 | global_namespace={}, | |
|
51 | parent=self.shell, | |
|
52 | ) | |
|
42 | compl = IPCompleter( | |
|
43 | shell=self.shell, namespace={}, global_namespace={}, parent=self.shell | |
|
44 | ) | |
|
53 | 45 | # add a completer for all the do_ methods |
|
54 | 46 | methods_names = [m[3:] for m in dir(self) if m.startswith("do_")] |
|
55 | 47 |
@@ -41,7 +41,7 b" CoreFoundation = ctypes.cdll.LoadLibrary(ctypes.util.find_library('CoreFoundatio" | |||
|
41 | 41 | |
|
42 | 42 | CFFileDescriptorCreate = CoreFoundation.CFFileDescriptorCreate |
|
43 | 43 | CFFileDescriptorCreate.restype = void_p |
|
44 | CFFileDescriptorCreate.argtypes = [void_p, ctypes.c_int, ctypes.c_bool, void_p] | |
|
44 | CFFileDescriptorCreate.argtypes = [void_p, ctypes.c_int, ctypes.c_bool, void_p, void_p] | |
|
45 | 45 | |
|
46 | 46 | CFFileDescriptorGetNativeDescriptor = CoreFoundation.CFFileDescriptorGetNativeDescriptor |
|
47 | 47 | CFFileDescriptorGetNativeDescriptor.restype = ctypes.c_int |
@@ -77,24 +77,42 b" kCFRunLoopCommonModes = void_p.in_dll(CoreFoundation, 'kCFRunLoopCommonModes')" | |||
|
77 | 77 | |
|
78 | 78 | def _NSApp(): |
|
79 | 79 | """Return the global NSApplication instance (NSApp)""" |
|
80 | objc.objc_msgSend.argtypes = [void_p, void_p] | |
|
80 | 81 | return msg(C('NSApplication'), n('sharedApplication')) |
|
81 | 82 | |
|
82 | 83 | |
|
83 | 84 | def _wake(NSApp): |
|
84 | 85 | """Wake the Application""" |
|
85 | event = msg(C('NSEvent'), | |
|
86 | n('otherEventWithType:location:modifierFlags:' | |
|
87 | 'timestamp:windowNumber:context:subtype:data1:data2:'), | |
|
88 | 15, # Type | |
|
89 | 0, # location | |
|
90 | 0, # flags | |
|
91 | 0, # timestamp | |
|
92 | 0, # window | |
|
93 | None, # context | |
|
94 | 0, # subtype | |
|
95 | 0, # data1 | |
|
96 | 0, # data2 | |
|
86 | objc.objc_msgSend.argtypes = [ | |
|
87 | void_p, | |
|
88 | void_p, | |
|
89 | void_p, | |
|
90 | void_p, | |
|
91 | void_p, | |
|
92 | void_p, | |
|
93 | void_p, | |
|
94 | void_p, | |
|
95 | void_p, | |
|
96 | void_p, | |
|
97 | void_p, | |
|
98 | ] | |
|
99 | event = msg( | |
|
100 | C("NSEvent"), | |
|
101 | n( | |
|
102 | "otherEventWithType:location:modifierFlags:" | |
|
103 | "timestamp:windowNumber:context:subtype:data1:data2:" | |
|
104 | ), | |
|
105 | 15, # Type | |
|
106 | 0, # location | |
|
107 | 0, # flags | |
|
108 | 0, # timestamp | |
|
109 | 0, # window | |
|
110 | None, # context | |
|
111 | 0, # subtype | |
|
112 | 0, # data1 | |
|
113 | 0, # data2 | |
|
97 | 114 | ) |
|
115 | objc.objc_msgSend.argtypes = [void_p, void_p, void_p, void_p] | |
|
98 | 116 | msg(NSApp, n('postEvent:atStart:'), void_p(event), True) |
|
99 | 117 | |
|
100 | 118 | |
@@ -106,6 +124,7 b' def _input_callback(fdref, flags, info):' | |||
|
106 | 124 | CFFileDescriptorInvalidate(fdref) |
|
107 | 125 | CFRelease(fdref) |
|
108 | 126 | NSApp = _NSApp() |
|
127 | objc.objc_msgSend.argtypes = [void_p, void_p, void_p] | |
|
109 | 128 | msg(NSApp, n('stop:'), NSApp) |
|
110 | 129 | _wake(NSApp) |
|
111 | 130 | |
@@ -128,6 +147,7 b' def inputhook(context):' | |||
|
128 | 147 | """Inputhook for Cocoa (NSApp)""" |
|
129 | 148 | NSApp = _NSApp() |
|
130 | 149 | _stop_on_read(context.fileno()) |
|
150 | objc.objc_msgSend.argtypes = [void_p, void_p] | |
|
131 | 151 | msg(NSApp, n('run')) |
|
132 | 152 | if not _triggered.is_set(): |
|
133 | 153 | # app closed without firing callback, |
@@ -1,6 +1,7 b'' | |||
|
1 | 1 | import sys |
|
2 | 2 | import os |
|
3 | 3 | from IPython.external.qt_for_kernel import QtCore, QtGui |
|
4 | from IPython import get_ipython | |
|
4 | 5 | |
|
5 | 6 | # If we create a QApplication, keep a reference to it so that it doesn't get |
|
6 | 7 | # garbage collected. |
@@ -8,6 +9,12 b' _appref = None' | |||
|
8 | 9 | _already_warned = False |
|
9 | 10 | |
|
10 | 11 | |
|
12 | def _reclaim_excepthook(): | |
|
13 | shell = get_ipython() | |
|
14 | if shell is not None: | |
|
15 | sys.excepthook = shell.excepthook | |
|
16 | ||
|
17 | ||
|
11 | 18 | def inputhook(context): |
|
12 | 19 | global _appref |
|
13 | 20 | app = QtCore.QCoreApplication.instance() |
@@ -27,6 +34,13 b' def inputhook(context):' | |||
|
27 | 34 | return |
|
28 | 35 | QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling) |
|
29 | 36 | _appref = app = QtGui.QApplication([" "]) |
|
37 | ||
|
38 | # "reclaim" IPython sys.excepthook after event loop starts | |
|
39 | # without this, it defaults back to BaseIPythonApplication.excepthook | |
|
40 | # and exceptions in the Qt event loop are rendered without traceback | |
|
41 | # formatting and look like "bug in IPython". | |
|
42 | QtCore.QTimer.singleShot(0, _reclaim_excepthook) | |
|
43 | ||
|
30 | 44 | event_loop = QtCore.QEventLoop(app) |
|
31 | 45 | |
|
32 | 46 | if sys.platform == 'win32': |
@@ -9,6 +9,7 b' Module to define and register Terminal IPython shortcuts with' | |||
|
9 | 9 | import warnings |
|
10 | 10 | import signal |
|
11 | 11 | import sys |
|
12 | import re | |
|
12 | 13 | from typing import Callable |
|
13 | 14 | |
|
14 | 15 |
@@ -153,6 +153,14 b' Here is a full example of a magic package. You can distribute magics using' | |||
|
153 | 153 | setuptools, distutils, or any other distribution tools like `flit |
|
154 | 154 | <http://flit.readthedocs.io>`_ for pure Python packages. |
|
155 | 155 | |
|
156 | When distributing magics as part of a package, recommended best practice is to | |
|
157 | execute the registration inside the `load_ipython_extension` as demonstrated in | |
|
158 | the example below, instead of directly in the module (as in the initial example | |
|
159 | with the ``@register_*`` decorators). This means a user will need to explicitly | |
|
160 | choose to load your magic with ``%load_ext``. instead implicitly getting it when | |
|
161 | importing the module. This is particularly relevant if loading your magic has | |
|
162 | side effects, if it is slow to load, or if it might override another magic with | |
|
163 | the same name. | |
|
156 | 164 | |
|
157 | 165 | .. sourcecode:: bash |
|
158 | 166 |
@@ -119,11 +119,6 b' which adds a directory called ``profile_<name>`` to your IPython directory. Then' | |||
|
119 | 119 | you can load this profile by adding ``--profile=<name>`` to your command line |
|
120 | 120 | options. Profiles are supported by all IPython applications. |
|
121 | 121 | |
|
122 | IPython ships with some sample profiles in :file:`IPython/config/profile`. If | |
|
123 | you create profiles with the name of one of our shipped profiles, these config | |
|
124 | files will be copied over instead of starting with the automatically generated | |
|
125 | config files. | |
|
126 | ||
|
127 | 122 | IPython extends the config loader for Python files so that you can inherit |
|
128 | 123 | config from another profile. To do this, use a line like this in your Python |
|
129 | 124 | config file: |
@@ -9,15 +9,15 b' IPython Documentation' | |||
|
9 | 9 | :Release: |release| |
|
10 | 10 | :Date: |today| |
|
11 | 11 | |
|
12 | Welcome to the official IPython documentation | |
|
12 | Welcome to the official IPython documentation. | |
|
13 | 13 | |
|
14 | 14 | IPython provides a rich toolkit to help you make the most of using Python |
|
15 | 15 | interactively. Its main components are: |
|
16 | 16 | |
|
17 | * A powerful interactive Python shell | |
|
17 | * A powerful interactive Python shell. | |
|
18 | 18 | |
|
19 | 19 | |
|
20 | .. image:: /_images/ipython-6-screenshot.png | |
|
20 | .. image:: ./_images/ipython-6-screenshot.png | |
|
21 | 21 | :alt: Screenshot of IPython 6.0 |
|
22 | 22 | :align: center |
|
23 | 23 | |
@@ -59,7 +59,7 b' The Command line interface inherits the above functionality and adds' | |||
|
59 | 59 | |
|
60 | 60 | * real multi-line editing thanks to `prompt_toolkit <http://python-prompt-toolkit.readthedocs.io/en/stable/>`_. |
|
61 | 61 | |
|
62 | * syntax highlighting as you type | |
|
62 | * syntax highlighting as you type. | |
|
63 | 63 | |
|
64 | 64 | * integration with command line editor for a better workflow. |
|
65 | 65 | |
@@ -84,8 +84,6 b" The latest development version is always available from IPython's `GitHub" | |||
|
84 | 84 | repository <http://github.com/ipython/ipython>`_. |
|
85 | 85 | |
|
86 | 86 | |
|
87 | ||
|
88 | ||
|
89 | 87 | .. toctree:: |
|
90 | 88 | :maxdepth: 1 |
|
91 | 89 | :hidden: |
@@ -3,20 +3,20 b' Python vs IPython' | |||
|
3 | 3 | ================= |
|
4 | 4 | |
|
5 | 5 | This document is meant to highlight the main differences between the Python |
|
6 | language and what are the specific construct you can do only in IPython. | |
|
6 | language and what are the specific constructs you can do only in IPython. | |
|
7 | 7 | |
|
8 | Unless expressed otherwise all of the construct you will see here will raise a | |
|
8 | Unless expressed otherwise all of the constructs you will see here will raise a | |
|
9 | 9 | ``SyntaxError`` if run in a pure Python shell, or if executing in a Python |
|
10 | 10 | script. |
|
11 | 11 | |
|
12 |
Each of these features |
|
|
12 | Each of these features is described more in detail in the further parts of the documentation. | |
|
13 | 13 | |
|
14 | 14 | |
|
15 | 15 | Quick overview: |
|
16 | 16 | =============== |
|
17 | 17 | |
|
18 | 18 | |
|
19 | All the following construct are valid IPython syntax: | |
|
19 | All the following constructs are valid IPython syntax: | |
|
20 | 20 | |
|
21 | 21 | .. code-block:: ipython |
|
22 | 22 | |
@@ -58,8 +58,8 b' All the following construct are valid IPython syntax:' | |||
|
58 | 58 | ...: print $months[0]; |
|
59 | 59 | |
|
60 | 60 | |
|
61 | Each of these construct is compiled by IPython into valid python code and will | |
|
62 | do most of the time what you expect it will do. Let see each of these example | |
|
61 | Each of these constructs is compiled by IPython into valid python code and will | |
|
62 | do most of the time what you expect it will do. Let's see each of these examples | |
|
63 | 63 | in more detail. |
|
64 | 64 | |
|
65 | 65 | |
@@ -89,7 +89,7 b' shortcut to get help. A question mark alone will bring up the IPython help:' | |||
|
89 | 89 | ------------- |
|
90 | 90 | ... |
|
91 | 91 | |
|
92 |
A single question mark before |
|
|
92 | A single question mark before or after an object available in the current | |
|
93 | 93 | namespace will show help relative to this object: |
|
94 | 94 | |
|
95 | 95 | .. code-block:: ipython |
@@ -127,7 +127,7 b' and if possible display the python source code of this object.' | |||
|
127 | 127 | |
|
128 | 128 | |
|
129 | 129 | If you are looking for an object, the use of wildcards ``*`` in conjunction |
|
130 | with question mark will allow you to search current namespace for object with | |
|
130 | with a question mark will allow you to search the current namespace for objects with | |
|
131 | 131 | matching names: |
|
132 | 132 | |
|
133 | 133 | .. code-block:: ipython |
@@ -142,10 +142,10 b' Shell Assignment' | |||
|
142 | 142 | ================ |
|
143 | 143 | |
|
144 | 144 | |
|
145 |
When doing interactive computing it is common |
|
|
145 | When doing interactive computing it is a common need to access the underlying shell. | |
|
146 | 146 | This is doable through the use of the exclamation mark ``!`` (or bang). |
|
147 | 147 | |
|
148 | This allow to execute simple command when present in beginning of line: | |
|
148 | This allows to execute simple commands when present in beginning of the line: | |
|
149 | 149 | |
|
150 | 150 | .. code-block:: ipython |
|
151 | 151 | |
@@ -167,7 +167,7 b' Or edit file:' | |||
|
167 | 167 | |
|
168 | 168 | The line after the bang can call any program installed in the underlying |
|
169 | 169 | shell, and support variable expansion in the form of ``$variable`` or ``{variable}``. |
|
170 | The later form of expansion supports arbitrary python expression: | |
|
170 | The later form of expansion supports arbitrary python expressions: | |
|
171 | 171 | |
|
172 | 172 | .. code-block:: ipython |
|
173 | 173 | |
@@ -176,19 +176,19 b' The later form of expansion supports arbitrary python expression:' | |||
|
176 | 176 | In[2]: !mv $file {file.upper()} |
|
177 | 177 | |
|
178 | 178 | |
|
179 |
The bang can also be present |
|
|
180 |
after the equal sign, or separated from it by a white space. In |
|
|
181 |
standard output of the command after the bang |
|
|
182 | in a list-like object and assign to the left hand side. | |
|
179 | The bang (``!``) can also be present on the right hand side of an assignment, just | |
|
180 | after the equal sign, or separated from it by a white space. In this case the | |
|
181 | standard output of the command after the bang will be split out into lines | |
|
182 | in a list-like object and assigned to the left hand side. | |
|
183 | 183 | |
|
184 | This allow you for example to put the list of files of the current working directory in a variable: | |
|
184 | This allows you, for example, to put the list of files of the current working directory in a variable: | |
|
185 | 185 | |
|
186 | 186 | .. code-block:: ipython |
|
187 | 187 | |
|
188 | 188 | In[1]: my_files = !ls |
|
189 | 189 | |
|
190 | 190 | |
|
191 | You can combine the different possibilities in for loops, condition, functions...: | |
|
191 | You can combine the different possibilities in for loops, conditions, functions...: | |
|
192 | 192 | |
|
193 | 193 | .. code-block:: ipython |
|
194 | 194 | |
@@ -202,19 +202,19 b' You can combine the different possibilities in for loops, condition, functions..' | |||
|
202 | 202 | Magics |
|
203 | 203 | ------ |
|
204 | 204 | |
|
205 |
Magic |
|
|
206 |
|
|
|
205 | Magic functions (magics) are often present in the form of shell-like syntax, but they are | |
|
206 | python functions under the hood. The syntax and assignment possibilities are | |
|
207 | 207 | similar to the one with the bang (``!``) syntax, but with more flexibility and |
|
208 | power. Magic function start with a percent sign (``%``) or double percent (``%%``). | |
|
208 | power. Magic functions start with a percent sign (``%``) or double percent signs (``%%``). | |
|
209 | 209 | |
|
210 |
A magic call with a si |
|
|
210 | A magic call with a single percent sign will act only on one line: | |
|
211 | 211 | |
|
212 | 212 | .. code-block:: ipython |
|
213 | 213 | |
|
214 | 214 | In[1]: %xmode |
|
215 | 215 | Exception reporting mode: Verbose |
|
216 | 216 | |
|
217 |
|
|
|
217 | Magics support assignment: | |
|
218 | 218 | |
|
219 | 219 | .. code-block:: ipython |
|
220 | 220 | |
@@ -224,7 +224,7 b' And support assignment:' | |||
|
224 | 224 | In [2]: results |
|
225 | 225 | Out[2]: <TimeitResult : 1 loops, best of 1: 21.1 µs per loop> |
|
226 | 226 | |
|
227 |
Magic with |
|
|
227 | Magics with double percent signs (``%%``) can spread over multiple lines, but they do not support assignments: | |
|
228 | 228 | |
|
229 | 229 | .. code-block:: ipython |
|
230 | 230 |
@@ -22,6 +22,47 b' Need to be updated:' | |||
|
22 | 22 | |
|
23 | 23 | pr/* |
|
24 | 24 | |
|
25 | IPython 8.0 is bringing a number of new features and improvements to both the | |
|
26 | user of the terminal and of the kernel via Jupyter. The removal of compatibility | |
|
27 | with older version of Python is also the opportunity to do a couple of | |
|
28 | performance improvement in particular with respect to startup time. | |
|
29 | ||
|
30 | The main change in IPython 8.0 is the integration of the ``stack_data`` package; | |
|
31 | which provide smarter information in traceback; in particular it will highlight | |
|
32 | the AST node where an error occurs which can help to quickly narrow down errors. | |
|
33 | ||
|
34 | For example in the following snippet:: | |
|
35 | ||
|
36 | def foo(i): | |
|
37 | x = [[[0]]] | |
|
38 | return x[0][i][0] | |
|
39 | ||
|
40 | ||
|
41 | def bar(): | |
|
42 | return foo(0) + foo( | |
|
43 | 1 | |
|
44 | ) + foo(2) | |
|
45 | ||
|
46 | ||
|
47 | Calling ``bar()`` would raise an ``IndexError`` on the return line of ``foo``, | |
|
48 | IPython 8.0 is capable of telling you, where the index error occurs:: | |
|
49 | ||
|
50 | return x[0][i][0] | |
|
51 | ^ | |
|
52 | ||
|
53 | To prepare for Python 3.10 we have also started working on removing reliance and | |
|
54 | any dependency that is not Python 3.10 compatible; that include migrating our | |
|
55 | test suite to Pytest, and starting to remove nose. | |
|
56 | ||
|
57 | We are also removing support for Python 3.6 allowing internal code to use more | |
|
58 | efficient ``pathlib``, and make better use of type annotations. | |
|
59 | ||
|
60 | The completer has also seen significant updates and make use of newer Jedi API | |
|
61 | offering faster and more reliable tab completion. | |
|
62 | ||
|
63 | For the terminal users this also enable the auto-suggestion feature, described | |
|
64 | below, which show "ghost text" ahead of your cursor you can accept without | |
|
65 | having to press the tab key or ask the completer to suggest completions. | |
|
25 | 66 | |
|
26 | 67 | |
|
27 | 68 | Autosuggestion is a very useful feature available in `fish <https://fishshell.com/>`__, `zsh <https://en.wikipedia.org/wiki/Z_shell>`__, and `prompt-toolkit <https://python-prompt-toolkit.readthedocs.io/en/master/pages/asking_for_input.html#auto-suggestion>`__. |
@@ -93,6 +134,25 b' Currently, autosuggestions are only shown in the emacs or vi insert editing mode' | |||
|
93 | 134 | - The ctrl e, ctrl f, and alt f shortcuts work by default in emacs mode. |
|
94 | 135 | - To use these shortcuts in vi insert mode, you will have to create `custom keybindings in your config.py <https://github.com/mskar/setup/commit/2892fcee46f9f80ef7788f0749edc99daccc52f4/>`__. |
|
95 | 136 | |
|
137 | ||
|
138 | Show pinfo information in ipdb using "?" and "??" | |
|
139 | ------------------------------------------------- | |
|
140 | ||
|
141 | In IPDB, it is now possible to show the information about an object using "?" | |
|
142 | and "??", in much the same way it can be done when using the IPython prompt:: | |
|
143 | ||
|
144 | ipdb> partial? | |
|
145 | Init signature: partial(self, /, *args, **kwargs) | |
|
146 | Docstring: | |
|
147 | partial(func, *args, **keywords) - new function with partial application | |
|
148 | of the given arguments and keywords. | |
|
149 | File: ~/.pyenv/versions/3.8.6/lib/python3.8/functools.py | |
|
150 | Type: type | |
|
151 | Subclasses: | |
|
152 | ||
|
153 | Previously, "pinfo" or "pinfo2" command had to be used for this purpose. | |
|
154 | ||
|
155 | ||
|
96 | 156 | Autoreload 3 feature |
|
97 | 157 | ==================== |
|
98 | 158 | |
@@ -107,6 +167,7 b' Try ``%autoreload 3`` in an IPython session after running ``%load_ext autoreload' | |||
|
107 | 167 | |
|
108 | 168 | For more information please see unit test - |
|
109 | 169 | extensions/tests/test_autoreload.py : 'test_autoload_newly_added_objects' |
|
170 | ======= | |
|
110 | 171 | |
|
111 | 172 | .. DO NOT EDIT THIS LINE BEFORE RELEASE. FEATURE INSERTION POINT. |
|
112 | 173 |
@@ -2,6 +2,105 b'' | |||
|
2 | 2 | 7.x Series |
|
3 | 3 | ============ |
|
4 | 4 | |
|
5 | .. _version 7.22: | |
|
6 | ||
|
7 | IPython 7.22 | |
|
8 | ============ | |
|
9 | ||
|
10 | Second release of IPython for 2021, mostly containing bug fixes. Here is a quick | |
|
11 | rundown of the few changes. | |
|
12 | ||
|
13 | - Fix some ``sys.excepthook`` shenanigan when embedding with qt, recommended if | |
|
14 | you – for example – use `napari <https://napari.org>`__. :ghpull:`12842`. | |
|
15 | - Fix bug when using the new ipdb ``%context`` magic :ghpull:`12844` | |
|
16 | - Couples of deprecation cleanup :ghpull:`12868` | |
|
17 | - Update for new dpast.com api if you use the ``%pastbin`` magic. :ghpull:`12712` | |
|
18 | - Remove support for numpy before 1.16. :ghpull:`12836` | |
|
19 | ||
|
20 | ||
|
21 | Thanks | |
|
22 | ------ | |
|
23 | ||
|
24 | We have a new team member that you should see more often on the IPython | |
|
25 | repository, Błażej Michalik (@MrMino) have been doing regular contributions to | |
|
26 | IPython, and spent time replying to many issues and guiding new users to the | |
|
27 | codebase; they now have triage permissions to the IPython repository and we'll | |
|
28 | work toward giving them more permission in the future. | |
|
29 | ||
|
30 | Many thanks to all the contributors to this release you can find all individual | |
|
31 | contributions to this milestone `on github <https://github.com/ipython/ipython/milestone/84>`__. | |
|
32 | ||
|
33 | Thanks as well to organisations, QuantStack for working on debugger | |
|
34 | compatibility for Xeus_python, and the `D. E. Shaw group | |
|
35 | <https://deshaw.com/>`__ for sponsoring work on IPython and related libraries. | |
|
36 | ||
|
37 | .. _version 721: | |
|
38 | ||
|
39 | IPython 7.21 | |
|
40 | ============ | |
|
41 | ||
|
42 | IPython 7.21 is the first release we have back on schedule of one release every | |
|
43 | month; it contains a number of minor fixes and improvements, notably, the new | |
|
44 | context command for ipdb | |
|
45 | ||
|
46 | ||
|
47 | New "context" command in ipdb | |
|
48 | ----------------------------- | |
|
49 | ||
|
50 | It is now possible to change the number of lines shown in the backtrace | |
|
51 | information in ipdb using "context" command. :ghpull:`12826` | |
|
52 | ||
|
53 | (thanks @MrMino, there are other improvement from them on master). | |
|
54 | ||
|
55 | Other notable changes in IPython 7.21 | |
|
56 | ------------------------------------- | |
|
57 | ||
|
58 | - Fix some issues on new osx-arm64 :ghpull:`12804`, :ghpull:`12807`. | |
|
59 | - Compatibility with Xeus-Python for debugger protocol, :ghpull:`12809` | |
|
60 | - Misc docs fixes for compatibility and uniformity with Numpydoc. | |
|
61 | :ghpull:`12824` | |
|
62 | ||
|
63 | ||
|
64 | Thanks | |
|
65 | ------ | |
|
66 | ||
|
67 | Many thanks to all the contributors to this release you can find all individual | |
|
68 | contribution to this milestone `on github <https://github.com/ipython/ipython/milestone/83>`__. | |
|
69 | ||
|
70 | ||
|
71 | .. _version 720: | |
|
72 | ||
|
73 | IPython 7.20 | |
|
74 | ============ | |
|
75 | ||
|
76 | IPython 7.20 is the accumulation of 3 month of work on IPython, spacing between | |
|
77 | IPython release have been increased from the usual once a month for various | |
|
78 | reason. | |
|
79 | ||
|
80 | - Mainly as I'm too busy and the effectively sole maintainer, and | |
|
81 | - Second because not much changes happened before mid December. | |
|
82 | ||
|
83 | The main driver for this release was the new version of Jedi 0.18 breaking API; | |
|
84 | which was taken care of in the master branch early in 2020 but not in 7.x as I | |
|
85 | though that by now 8.0 would be out. | |
|
86 | ||
|
87 | The inclusion of a resolver in pip did not help and actually made things worse. | |
|
88 | If usually I would have simply pinned Jedi to ``<0.18``; this is not a solution | |
|
89 | anymore as now pip is free to install Jedi 0.18, and downgrade IPython. | |
|
90 | ||
|
91 | I'll do my best to keep the regular release, but as the 8.0-dev branch and 7.x | |
|
92 | are starting to diverge this is becoming difficult in particular with my limited | |
|
93 | time, so if you have any cycles to spare I'll appreciate your help to respond to | |
|
94 | issues and pushing 8.0 forward. | |
|
95 | ||
|
96 | Here are thus some of the changes for IPython 7.20. | |
|
97 | ||
|
98 | - Support for PyQt5 >= 5.11 :ghpull:`12715` | |
|
99 | - ``%reset`` remove imports more agressively :ghpull:`12718` | |
|
100 | - fix the ``%conda`` magic :ghpull:`12739` | |
|
101 | - compatibility with Jedi 0.18, and bump minimum Jedi version. :ghpull:`12793` | |
|
102 | ||
|
103 | ||
|
5 | 104 | .. _version 719: |
|
6 | 105 | |
|
7 | 106 | IPython 7.19 |
@@ -55,7 +154,7 b' IPython 7.17' | |||
|
55 | 154 | ============ |
|
56 | 155 | |
|
57 | 156 | IPython 7.17 brings a couple of new improvements to API and a couple of user |
|
58 |
facing changes to make the terminal experience more user friendly. |
|
|
157 | facing changes to make the terminal experience more user friendly. | |
|
59 | 158 | |
|
60 | 159 | :ghpull:`12407` introduces the ability to pass extra argument to the IPython |
|
61 | 160 | debugger class; this is to help a new project from ``kmaork`` |
@@ -171,15 +171,23 b' setuptools_extra_args = {}' | |||
|
171 | 171 | # setuptools requirements |
|
172 | 172 | |
|
173 | 173 | extras_require = dict( |
|
174 |
parallel |
|
|
175 |
qtconsole |
|
|
176 |
doc |
|
|
177 | test = ['nose>=0.10.1', 'requests', 'testpath', 'pygments', 'nbformat', 'ipykernel', 'numpy>=1.14'], | |
|
178 | terminal = [], | |
|
179 | kernel = ['ipykernel'], | |
|
180 | nbformat = ['nbformat'], | |
|
181 | notebook = ['notebook', 'ipywidgets'], | |
|
182 | nbconvert = ['nbconvert'], | |
|
174 | parallel=["ipyparallel"], | |
|
175 | qtconsole=["qtconsole"], | |
|
176 | doc=["Sphinx>=1.3"], | |
|
177 | test=[ | |
|
178 | "nose>=0.10.1", | |
|
179 | "requests", | |
|
180 | "testpath", | |
|
181 | "pygments", | |
|
182 | "nbformat", | |
|
183 | "ipykernel", | |
|
184 | "numpy>=1.16", | |
|
185 | ], | |
|
186 | terminal=[], | |
|
187 | kernel=["ipykernel"], | |
|
188 | nbformat=["nbformat"], | |
|
189 | notebook=["notebook", "ipywidgets"], | |
|
190 | nbconvert=["nbconvert"], | |
|
183 | 191 | ) |
|
184 | 192 | |
|
185 | 193 | install_requires = [ |
General Comments 0
You need to be logged in to leave comments.
Login now