##// END OF EJS Templates
Merge branch 'main' into greedy-completions
Michał Krassowski -
r27919:5c16bcd7 merge
parent child Browse files
Show More
@@ -1,199 +1,214 b''
1 1 """Compiler tools with improved interactive support.
2 2
3 3 Provides compilation machinery similar to codeop, but with caching support so
4 4 we can provide interactive tracebacks.
5 5
6 6 Authors
7 7 -------
8 8 * Robert Kern
9 9 * Fernando Perez
10 10 * Thomas Kluyver
11 11 """
12 12
13 13 # Note: though it might be more natural to name this module 'compiler', that
14 14 # name is in the stdlib and name collisions with the stdlib tend to produce
15 15 # weird problems (often with third-party tools).
16 16
17 17 #-----------------------------------------------------------------------------
18 18 # Copyright (C) 2010-2011 The IPython Development Team.
19 19 #
20 20 # Distributed under the terms of the BSD License.
21 21 #
22 22 # The full license is in the file COPYING.txt, distributed with this software.
23 23 #-----------------------------------------------------------------------------
24 24
25 25 #-----------------------------------------------------------------------------
26 26 # Imports
27 27 #-----------------------------------------------------------------------------
28 28
29 29 # Stdlib imports
30 30 import __future__
31 31 from ast import PyCF_ONLY_AST
32 32 import codeop
33 33 import functools
34 34 import hashlib
35 35 import linecache
36 36 import operator
37 37 import time
38 38 from contextlib import contextmanager
39 39
40 40 #-----------------------------------------------------------------------------
41 41 # Constants
42 42 #-----------------------------------------------------------------------------
43 43
44 44 # Roughly equal to PyCF_MASK | PyCF_MASK_OBSOLETE as defined in pythonrun.h,
45 45 # this is used as a bitmask to extract future-related code flags.
46 46 PyCF_MASK = functools.reduce(operator.or_,
47 47 (getattr(__future__, fname).compiler_flag
48 48 for fname in __future__.all_feature_names))
49 49
50 50 #-----------------------------------------------------------------------------
51 51 # Local utilities
52 52 #-----------------------------------------------------------------------------
53 53
54 54 def code_name(code, number=0):
55 55 """ Compute a (probably) unique name for code for caching.
56 56
57 57 This now expects code to be unicode.
58 58 """
59 59 hash_digest = hashlib.sha1(code.encode("utf-8")).hexdigest()
60 60 # Include the number and 12 characters of the hash in the name. It's
61 61 # pretty much impossible that in a single session we'll have collisions
62 62 # even with truncated hashes, and the full one makes tracebacks too long
63 63 return '<ipython-input-{0}-{1}>'.format(number, hash_digest[:12])
64 64
65 65 #-----------------------------------------------------------------------------
66 66 # Classes and functions
67 67 #-----------------------------------------------------------------------------
68 68
69 69 class CachingCompiler(codeop.Compile):
70 70 """A compiler that caches code compiled from interactive statements.
71 71 """
72 72
73 73 def __init__(self):
74 74 codeop.Compile.__init__(self)
75 75
76 76 # Caching a dictionary { filename: execution_count } for nicely
77 77 # rendered tracebacks. The filename corresponds to the filename
78 78 # argument used for the builtins.compile function.
79 79 self._filename_map = {}
80 80
81 81 def ast_parse(self, source, filename='<unknown>', symbol='exec'):
82 82 """Parse code to an AST with the current compiler flags active.
83 83
84 84 Arguments are exactly the same as ast.parse (in the standard library),
85 85 and are passed to the built-in compile function."""
86 86 return compile(source, filename, symbol, self.flags | PyCF_ONLY_AST, 1)
87 87
88 88 def reset_compiler_flags(self):
89 89 """Reset compiler flags to default state."""
90 90 # This value is copied from codeop.Compile.__init__, so if that ever
91 91 # changes, it will need to be updated.
92 92 self.flags = codeop.PyCF_DONT_IMPLY_DEDENT
93 93
94 94 @property
95 95 def compiler_flags(self):
96 96 """Flags currently active in the compilation process.
97 97 """
98 98 return self.flags
99 99
100 100 def get_code_name(self, raw_code, transformed_code, number):
101 101 """Compute filename given the code, and the cell number.
102 102
103 103 Parameters
104 104 ----------
105 105 raw_code : str
106 106 The raw cell code.
107 107 transformed_code : str
108 108 The executable Python source code to cache and compile.
109 109 number : int
110 110 A number which forms part of the code's name. Used for the execution
111 111 counter.
112 112
113 113 Returns
114 114 -------
115 115 The computed filename.
116 116 """
117 117 return code_name(transformed_code, number)
118 118
119 def format_code_name(self, name):
120 """Return a user-friendly label and name for a code block.
121
122 Parameters
123 ----------
124 name : str
125 The name for the code block returned from get_code_name
126
127 Returns
128 -------
129 A (label, name) pair that can be used in tracebacks, or None if the default formatting should be used.
130 """
131 if name in self._filename_map:
132 return "Cell", "In[%s]" % self._filename_map[name]
133
119 134 def cache(self, transformed_code, number=0, raw_code=None):
120 135 """Make a name for a block of code, and cache the code.
121 136
122 137 Parameters
123 138 ----------
124 139 transformed_code : str
125 140 The executable Python source code to cache and compile.
126 141 number : int
127 142 A number which forms part of the code's name. Used for the execution
128 143 counter.
129 144 raw_code : str
130 145 The raw code before transformation, if None, set to `transformed_code`.
131 146
132 147 Returns
133 148 -------
134 149 The name of the cached code (as a string). Pass this as the filename
135 150 argument to compilation, so that tracebacks are correctly hooked up.
136 151 """
137 152 if raw_code is None:
138 153 raw_code = transformed_code
139 154
140 155 name = self.get_code_name(raw_code, transformed_code, number)
141 156
142 157 # Save the execution count
143 158 self._filename_map[name] = number
144 159
145 160 # Since Python 2.5, setting mtime to `None` means the lines will
146 161 # never be removed by `linecache.checkcache`. This means all the
147 162 # monkeypatching has *never* been necessary, since this code was
148 163 # only added in 2010, at which point IPython had already stopped
149 164 # supporting Python 2.4.
150 165 #
151 166 # Note that `linecache.clearcache` and `linecache.updatecache` may
152 167 # still remove our code from the cache, but those show explicit
153 168 # intent, and we should not try to interfere. Normally the former
154 169 # is never called except when out of memory, and the latter is only
155 170 # called for lines *not* in the cache.
156 171 entry = (
157 172 len(transformed_code),
158 173 None,
159 174 [line + "\n" for line in transformed_code.splitlines()],
160 175 name,
161 176 )
162 177 linecache.cache[name] = entry
163 178 return name
164 179
165 180 @contextmanager
166 181 def extra_flags(self, flags):
167 182 ## bits that we'll set to 1
168 183 turn_on_bits = ~self.flags & flags
169 184
170 185
171 186 self.flags = self.flags | flags
172 187 try:
173 188 yield
174 189 finally:
175 190 # turn off only the bits we turned on so that something like
176 191 # __future__ that set flags stays.
177 192 self.flags &= ~turn_on_bits
178 193
179 194
180 195 def check_linecache_ipython(*args):
181 196 """Deprecated since IPython 8.6. Call linecache.checkcache() directly.
182 197
183 198 It was already not necessary to call this function directly. If no
184 199 CachingCompiler had been created, this function would fail badly. If
185 200 an instance had been created, this function would've been monkeypatched
186 201 into place.
187 202
188 203 As of IPython 8.6, the monkeypatching has gone away entirely. But there
189 204 were still internal callers of this function, so maybe external callers
190 205 also existed?
191 206 """
192 207 import warnings
193 208
194 209 warnings.warn(
195 210 "Deprecated Since IPython 8.6, Just call linecache.checkcache() directly.",
196 211 DeprecationWarning,
197 212 stacklevel=2,
198 213 )
199 214 linecache.checkcache()
@@ -1,54 +1,54 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Release data for the IPython project."""
3 3
4 4 #-----------------------------------------------------------------------------
5 5 # Copyright (c) 2008, IPython Development Team.
6 6 # Copyright (c) 2001, Fernando Perez <fernando.perez@colorado.edu>
7 7 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
8 8 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
9 9 #
10 10 # Distributed under the terms of the Modified BSD License.
11 11 #
12 12 # The full license is in the file COPYING.txt, distributed with this software.
13 13 #-----------------------------------------------------------------------------
14 14
15 15 # IPython version information. An empty _version_extra corresponds to a full
16 16 # release. 'dev' as a _version_extra string means this is a development
17 17 # version
18 18 _version_major = 8
19 _version_minor = 7
19 _version_minor = 8
20 20 _version_patch = 0
21 21 _version_extra = ".dev"
22 22 # _version_extra = "rc1"
23 23 # _version_extra = "" # Uncomment this for full releases
24 24
25 25 # Construct full version string from these.
26 26 _ver = [_version_major, _version_minor, _version_patch]
27 27
28 28 __version__ = '.'.join(map(str, _ver))
29 29 if _version_extra:
30 30 __version__ = __version__ + _version_extra
31 31
32 32 version = __version__ # backwards compatibility name
33 33 version_info = (_version_major, _version_minor, _version_patch, _version_extra)
34 34
35 35 # Change this when incrementing the kernel protocol version
36 36 kernel_protocol_version_info = (5, 0)
37 37 kernel_protocol_version = "%i.%i" % kernel_protocol_version_info
38 38
39 39 license = "BSD-3-Clause"
40 40
41 41 authors = {'Fernando' : ('Fernando Perez','fperez.net@gmail.com'),
42 42 'Janko' : ('Janko Hauser','jhauser@zscout.de'),
43 43 'Nathan' : ('Nathaniel Gray','n8gray@caltech.edu'),
44 44 'Ville' : ('Ville Vainio','vivainio@gmail.com'),
45 45 'Brian' : ('Brian E Granger', 'ellisonbg@gmail.com'),
46 46 'Min' : ('Min Ragan-Kelley', 'benjaminrk@gmail.com'),
47 47 'Thomas' : ('Thomas A. Kluyver', 'takowl@gmail.com'),
48 48 'Jorgen' : ('Jorgen Stenarson', 'jorgen.stenarson@bostream.nu'),
49 49 'Matthias' : ('Matthias Bussonnier', 'bussonniermatthias@gmail.com'),
50 50 }
51 51
52 52 author = 'The IPython Development Team'
53 53
54 54 author_email = 'ipython-dev@python.org'
@@ -1,1201 +1,1207 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Verbose and colourful traceback formatting.
4 4
5 5 **ColorTB**
6 6
7 7 I've always found it a bit hard to visually parse tracebacks in Python. The
8 8 ColorTB class is a solution to that problem. It colors the different parts of a
9 9 traceback in a manner similar to what you would expect from a syntax-highlighting
10 10 text editor.
11 11
12 12 Installation instructions for ColorTB::
13 13
14 14 import sys,ultratb
15 15 sys.excepthook = ultratb.ColorTB()
16 16
17 17 **VerboseTB**
18 18
19 19 I've also included a port of Ka-Ping Yee's "cgitb.py" that produces all kinds
20 20 of useful info when a traceback occurs. Ping originally had it spit out HTML
21 21 and intended it for CGI programmers, but why should they have all the fun? I
22 22 altered it to spit out colored text to the terminal. It's a bit overwhelming,
23 23 but kind of neat, and maybe useful for long-running programs that you believe
24 24 are bug-free. If a crash *does* occur in that type of program you want details.
25 25 Give it a shot--you'll love it or you'll hate it.
26 26
27 27 .. note::
28 28
29 29 The Verbose mode prints the variables currently visible where the exception
30 30 happened (shortening their strings if too long). This can potentially be
31 31 very slow, if you happen to have a huge data structure whose string
32 32 representation is complex to compute. Your computer may appear to freeze for
33 33 a while with cpu usage at 100%. If this occurs, you can cancel the traceback
34 34 with Ctrl-C (maybe hitting it more than once).
35 35
36 36 If you encounter this kind of situation often, you may want to use the
37 37 Verbose_novars mode instead of the regular Verbose, which avoids formatting
38 38 variables (but otherwise includes the information and context given by
39 39 Verbose).
40 40
41 41 .. note::
42 42
43 43 The verbose mode print all variables in the stack, which means it can
44 44 potentially leak sensitive information like access keys, or unencrypted
45 45 password.
46 46
47 47 Installation instructions for VerboseTB::
48 48
49 49 import sys,ultratb
50 50 sys.excepthook = ultratb.VerboseTB()
51 51
52 52 Note: Much of the code in this module was lifted verbatim from the standard
53 53 library module 'traceback.py' and Ka-Ping Yee's 'cgitb.py'.
54 54
55 55 Color schemes
56 56 -------------
57 57
58 58 The colors are defined in the class TBTools through the use of the
59 59 ColorSchemeTable class. Currently the following exist:
60 60
61 61 - NoColor: allows all of this module to be used in any terminal (the color
62 62 escapes are just dummy blank strings).
63 63
64 64 - Linux: is meant to look good in a terminal like the Linux console (black
65 65 or very dark background).
66 66
67 67 - LightBG: similar to Linux but swaps dark/light colors to be more readable
68 68 in light background terminals.
69 69
70 70 - Neutral: a neutral color scheme that should be readable on both light and
71 71 dark background
72 72
73 73 You can implement other color schemes easily, the syntax is fairly
74 74 self-explanatory. Please send back new schemes you develop to the author for
75 75 possible inclusion in future releases.
76 76
77 77 Inheritance diagram:
78 78
79 79 .. inheritance-diagram:: IPython.core.ultratb
80 80 :parts: 3
81 81 """
82 82
83 83 #*****************************************************************************
84 84 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
85 85 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
86 86 #
87 87 # Distributed under the terms of the BSD License. The full license is in
88 88 # the file COPYING, distributed as part of this software.
89 89 #*****************************************************************************
90 90
91 91
92 92 import inspect
93 93 import linecache
94 94 import pydoc
95 95 import sys
96 96 import time
97 97 import traceback
98 98 from types import TracebackType
99 99 from typing import Tuple, List, Any, Optional
100 100
101 101 import stack_data
102 102 from pygments.formatters.terminal256 import Terminal256Formatter
103 103 from pygments.styles import get_style_by_name
104 104
105 105 # IPython's own modules
106 106 from IPython import get_ipython
107 107 from IPython.core import debugger
108 108 from IPython.core.display_trap import DisplayTrap
109 109 from IPython.core.excolors import exception_colors
110 110 from IPython.utils import path as util_path
111 111 from IPython.utils import py3compat
112 112 from IPython.utils.terminal import get_terminal_size
113 113
114 114 import IPython.utils.colorable as colorable
115 115
116 116 # Globals
117 117 # amount of space to put line numbers before verbose tracebacks
118 118 INDENT_SIZE = 8
119 119
120 120 # Default color scheme. This is used, for example, by the traceback
121 121 # formatter. When running in an actual IPython instance, the user's rc.colors
122 122 # value is used, but having a module global makes this functionality available
123 123 # to users of ultratb who are NOT running inside ipython.
124 124 DEFAULT_SCHEME = 'NoColor'
125 125
126 126 # ---------------------------------------------------------------------------
127 127 # Code begins
128 128
129 129 # Helper function -- largely belongs to VerboseTB, but we need the same
130 130 # functionality to produce a pseudo verbose TB for SyntaxErrors, so that they
131 131 # can be recognized properly by ipython.el's py-traceback-line-re
132 132 # (SyntaxErrors have to be treated specially because they have no traceback)
133 133
134 134
135 135 def _format_traceback_lines(lines, Colors, has_colors: bool, lvals):
136 136 """
137 137 Format tracebacks lines with pointing arrow, leading numbers...
138 138
139 139 Parameters
140 140 ----------
141 141 lines : list[Line]
142 142 Colors
143 143 ColorScheme used.
144 144 lvals : str
145 145 Values of local variables, already colored, to inject just after the error line.
146 146 """
147 147 numbers_width = INDENT_SIZE - 1
148 148 res = []
149 149
150 150 for stack_line in lines:
151 151 if stack_line is stack_data.LINE_GAP:
152 152 res.append('%s (...)%s\n' % (Colors.linenoEm, Colors.Normal))
153 153 continue
154 154
155 155 line = stack_line.render(pygmented=has_colors).rstrip('\n') + '\n'
156 156 lineno = stack_line.lineno
157 157 if stack_line.is_current:
158 158 # This is the line with the error
159 159 pad = numbers_width - len(str(lineno))
160 160 num = '%s%s' % (debugger.make_arrow(pad), str(lineno))
161 161 start_color = Colors.linenoEm
162 162 else:
163 163 num = '%*s' % (numbers_width, lineno)
164 164 start_color = Colors.lineno
165 165
166 166 line = '%s%s%s %s' % (start_color, num, Colors.Normal, line)
167 167
168 168 res.append(line)
169 169 if lvals and stack_line.is_current:
170 170 res.append(lvals + '\n')
171 171 return res
172 172
173 173
174 174 def _format_filename(file, ColorFilename, ColorNormal, *, lineno=None):
175 175 """
176 Format filename lines with `In [n]` if it's the nth code cell or `File *.py` if it's a module.
176 Format filename lines with custom formatting from caching compiler or `File *.py` by default
177 177
178 178 Parameters
179 179 ----------
180 180 file : str
181 181 ColorFilename
182 182 ColorScheme's filename coloring to be used.
183 183 ColorNormal
184 184 ColorScheme's normal coloring to be used.
185 185 """
186 186 ipinst = get_ipython()
187
188 if ipinst is not None and file in ipinst.compile._filename_map:
189 file = "[%s]" % ipinst.compile._filename_map[file]
187 if (
188 ipinst is not None
189 and (data := ipinst.compile.format_code_name(file)) is not None
190 ):
191 label, name = data
190 192 if lineno is None:
191 tpl_link = f"Cell {ColorFilename}In {{file}}{ColorNormal}"
193 tpl_link = f"{{label}} {ColorFilename}{{name}}{ColorNormal}"
192 194 else:
193 tpl_link = f"Cell {ColorFilename}In {{file}}, line {{lineno}}{ColorNormal}"
195 tpl_link = (
196 f"{{label}} {ColorFilename}{{name}}, line {{lineno}}{ColorNormal}"
197 )
194 198 else:
195 file = util_path.compress_user(
199 label = "File"
200 name = util_path.compress_user(
196 201 py3compat.cast_unicode(file, util_path.fs_encoding)
197 202 )
198 203 if lineno is None:
199 tpl_link = f"File {ColorFilename}{{file}}{ColorNormal}"
204 tpl_link = f"{{label}} {ColorFilename}{{name}}{ColorNormal}"
200 205 else:
201 tpl_link = f"File {ColorFilename}{{file}}:{{lineno}}{ColorNormal}"
206 # can we make this the more friendly ", line {{lineno}}", or do we need to preserve the formatting with the colon?
207 tpl_link = f"{{label}} {ColorFilename}{{name}}:{{lineno}}{ColorNormal}"
202 208
203 return tpl_link.format(file=file, lineno=lineno)
209 return tpl_link.format(label=label, name=name, lineno=lineno)
204 210
205 211 #---------------------------------------------------------------------------
206 212 # Module classes
207 213 class TBTools(colorable.Colorable):
208 214 """Basic tools used by all traceback printer classes."""
209 215
210 216 # Number of frames to skip when reporting tracebacks
211 217 tb_offset = 0
212 218
213 219 def __init__(
214 220 self,
215 221 color_scheme="NoColor",
216 222 call_pdb=False,
217 223 ostream=None,
218 224 parent=None,
219 225 config=None,
220 226 *,
221 227 debugger_cls=None,
222 228 ):
223 229 # Whether to call the interactive pdb debugger after printing
224 230 # tracebacks or not
225 231 super(TBTools, self).__init__(parent=parent, config=config)
226 232 self.call_pdb = call_pdb
227 233
228 234 # Output stream to write to. Note that we store the original value in
229 235 # a private attribute and then make the public ostream a property, so
230 236 # that we can delay accessing sys.stdout until runtime. The way
231 237 # things are written now, the sys.stdout object is dynamically managed
232 238 # so a reference to it should NEVER be stored statically. This
233 239 # property approach confines this detail to a single location, and all
234 240 # subclasses can simply access self.ostream for writing.
235 241 self._ostream = ostream
236 242
237 243 # Create color table
238 244 self.color_scheme_table = exception_colors()
239 245
240 246 self.set_colors(color_scheme)
241 247 self.old_scheme = color_scheme # save initial value for toggles
242 248 self.debugger_cls = debugger_cls or debugger.Pdb
243 249
244 250 if call_pdb:
245 251 self.pdb = self.debugger_cls()
246 252 else:
247 253 self.pdb = None
248 254
249 255 def _get_ostream(self):
250 256 """Output stream that exceptions are written to.
251 257
252 258 Valid values are:
253 259
254 260 - None: the default, which means that IPython will dynamically resolve
255 261 to sys.stdout. This ensures compatibility with most tools, including
256 262 Windows (where plain stdout doesn't recognize ANSI escapes).
257 263
258 264 - Any object with 'write' and 'flush' attributes.
259 265 """
260 266 return sys.stdout if self._ostream is None else self._ostream
261 267
262 268 def _set_ostream(self, val):
263 269 assert val is None or (hasattr(val, 'write') and hasattr(val, 'flush'))
264 270 self._ostream = val
265 271
266 272 ostream = property(_get_ostream, _set_ostream)
267 273
268 274 @staticmethod
269 275 def _get_chained_exception(exception_value):
270 276 cause = getattr(exception_value, "__cause__", None)
271 277 if cause:
272 278 return cause
273 279 if getattr(exception_value, "__suppress_context__", False):
274 280 return None
275 281 return getattr(exception_value, "__context__", None)
276 282
277 283 def get_parts_of_chained_exception(
278 284 self, evalue
279 285 ) -> Optional[Tuple[type, BaseException, TracebackType]]:
280 286
281 287 chained_evalue = self._get_chained_exception(evalue)
282 288
283 289 if chained_evalue:
284 290 return chained_evalue.__class__, chained_evalue, chained_evalue.__traceback__
285 291 return None
286 292
287 293 def prepare_chained_exception_message(self, cause) -> List[Any]:
288 294 direct_cause = "\nThe above exception was the direct cause of the following exception:\n"
289 295 exception_during_handling = "\nDuring handling of the above exception, another exception occurred:\n"
290 296
291 297 if cause:
292 298 message = [[direct_cause]]
293 299 else:
294 300 message = [[exception_during_handling]]
295 301 return message
296 302
297 303 @property
298 304 def has_colors(self) -> bool:
299 305 return self.color_scheme_table.active_scheme_name.lower() != "nocolor"
300 306
301 307 def set_colors(self, *args, **kw):
302 308 """Shorthand access to the color table scheme selector method."""
303 309
304 310 # Set own color table
305 311 self.color_scheme_table.set_active_scheme(*args, **kw)
306 312 # for convenience, set Colors to the active scheme
307 313 self.Colors = self.color_scheme_table.active_colors
308 314 # Also set colors of debugger
309 315 if hasattr(self, 'pdb') and self.pdb is not None:
310 316 self.pdb.set_colors(*args, **kw)
311 317
312 318 def color_toggle(self):
313 319 """Toggle between the currently active color scheme and NoColor."""
314 320
315 321 if self.color_scheme_table.active_scheme_name == 'NoColor':
316 322 self.color_scheme_table.set_active_scheme(self.old_scheme)
317 323 self.Colors = self.color_scheme_table.active_colors
318 324 else:
319 325 self.old_scheme = self.color_scheme_table.active_scheme_name
320 326 self.color_scheme_table.set_active_scheme('NoColor')
321 327 self.Colors = self.color_scheme_table.active_colors
322 328
323 329 def stb2text(self, stb):
324 330 """Convert a structured traceback (a list) to a string."""
325 331 return '\n'.join(stb)
326 332
327 333 def text(self, etype, value, tb, tb_offset: Optional[int] = None, context=5):
328 334 """Return formatted traceback.
329 335
330 336 Subclasses may override this if they add extra arguments.
331 337 """
332 338 tb_list = self.structured_traceback(etype, value, tb,
333 339 tb_offset, context)
334 340 return self.stb2text(tb_list)
335 341
336 342 def structured_traceback(
337 343 self, etype, evalue, tb, tb_offset: Optional[int] = None, context=5, mode=None
338 344 ):
339 345 """Return a list of traceback frames.
340 346
341 347 Must be implemented by each class.
342 348 """
343 349 raise NotImplementedError()
344 350
345 351
346 352 #---------------------------------------------------------------------------
347 353 class ListTB(TBTools):
348 354 """Print traceback information from a traceback list, with optional color.
349 355
350 356 Calling requires 3 arguments: (etype, evalue, elist)
351 357 as would be obtained by::
352 358
353 359 etype, evalue, tb = sys.exc_info()
354 360 if tb:
355 361 elist = traceback.extract_tb(tb)
356 362 else:
357 363 elist = None
358 364
359 365 It can thus be used by programs which need to process the traceback before
360 366 printing (such as console replacements based on the code module from the
361 367 standard library).
362 368
363 369 Because they are meant to be called without a full traceback (only a
364 370 list), instances of this class can't call the interactive pdb debugger."""
365 371
366 372
367 373 def __call__(self, etype, value, elist):
368 374 self.ostream.flush()
369 375 self.ostream.write(self.text(etype, value, elist))
370 376 self.ostream.write('\n')
371 377
372 378 def _extract_tb(self, tb):
373 379 if tb:
374 380 return traceback.extract_tb(tb)
375 381 else:
376 382 return None
377 383
378 384 def structured_traceback(
379 385 self,
380 386 etype: type,
381 387 evalue: BaseException,
382 388 etb: Optional[TracebackType] = None,
383 389 tb_offset: Optional[int] = None,
384 390 context=5,
385 391 ):
386 392 """Return a color formatted string with the traceback info.
387 393
388 394 Parameters
389 395 ----------
390 396 etype : exception type
391 397 Type of the exception raised.
392 398 evalue : object
393 399 Data stored in the exception
394 400 etb : list | TracebackType | None
395 401 If list: List of frames, see class docstring for details.
396 402 If Traceback: Traceback of the exception.
397 403 tb_offset : int, optional
398 404 Number of frames in the traceback to skip. If not given, the
399 405 instance evalue is used (set in constructor).
400 406 context : int, optional
401 407 Number of lines of context information to print.
402 408
403 409 Returns
404 410 -------
405 411 String with formatted exception.
406 412 """
407 413 # This is a workaround to get chained_exc_ids in recursive calls
408 414 # etb should not be a tuple if structured_traceback is not recursive
409 415 if isinstance(etb, tuple):
410 416 etb, chained_exc_ids = etb
411 417 else:
412 418 chained_exc_ids = set()
413 419
414 420 if isinstance(etb, list):
415 421 elist = etb
416 422 elif etb is not None:
417 423 elist = self._extract_tb(etb)
418 424 else:
419 425 elist = []
420 426 tb_offset = self.tb_offset if tb_offset is None else tb_offset
421 427 assert isinstance(tb_offset, int)
422 428 Colors = self.Colors
423 429 out_list = []
424 430 if elist:
425 431
426 432 if tb_offset and len(elist) > tb_offset:
427 433 elist = elist[tb_offset:]
428 434
429 435 out_list.append('Traceback %s(most recent call last)%s:' %
430 436 (Colors.normalEm, Colors.Normal) + '\n')
431 437 out_list.extend(self._format_list(elist))
432 438 # The exception info should be a single entry in the list.
433 439 lines = ''.join(self._format_exception_only(etype, evalue))
434 440 out_list.append(lines)
435 441
436 442 exception = self.get_parts_of_chained_exception(evalue)
437 443
438 444 if exception and not id(exception[1]) in chained_exc_ids:
439 445 chained_exception_message = self.prepare_chained_exception_message(
440 446 evalue.__cause__)[0]
441 447 etype, evalue, etb = exception
442 448 # Trace exception to avoid infinite 'cause' loop
443 449 chained_exc_ids.add(id(exception[1]))
444 450 chained_exceptions_tb_offset = 0
445 451 out_list = (
446 452 self.structured_traceback(
447 453 etype, evalue, (etb, chained_exc_ids),
448 454 chained_exceptions_tb_offset, context)
449 455 + chained_exception_message
450 456 + out_list)
451 457
452 458 return out_list
453 459
454 460 def _format_list(self, extracted_list):
455 461 """Format a list of traceback entry tuples for printing.
456 462
457 463 Given a list of tuples as returned by extract_tb() or
458 464 extract_stack(), return a list of strings ready for printing.
459 465 Each string in the resulting list corresponds to the item with the
460 466 same index in the argument list. Each string ends in a newline;
461 467 the strings may contain internal newlines as well, for those items
462 468 whose source text line is not None.
463 469
464 470 Lifted almost verbatim from traceback.py
465 471 """
466 472
467 473 Colors = self.Colors
468 474 list = []
469 475 for ind, (filename, lineno, name, line) in enumerate(extracted_list):
470 476 normalCol, nameCol, fileCol, lineCol = (
471 477 # Emphasize the last entry
472 478 (Colors.normalEm, Colors.nameEm, Colors.filenameEm, Colors.line)
473 479 if ind == len(extracted_list) - 1
474 480 else (Colors.Normal, Colors.name, Colors.filename, "")
475 481 )
476 482
477 483 fns = _format_filename(filename, fileCol, normalCol, lineno=lineno)
478 484 item = f"{normalCol} {fns}"
479 485
480 486 if name != "<module>":
481 487 item += f" in {nameCol}{name}{normalCol}\n"
482 488 else:
483 489 item += "\n"
484 490 if line:
485 491 item += f"{lineCol} {line.strip()}{normalCol}\n"
486 492 list.append(item)
487 493
488 494 return list
489 495
490 496 def _format_exception_only(self, etype, value):
491 497 """Format the exception part of a traceback.
492 498
493 499 The arguments are the exception type and value such as given by
494 500 sys.exc_info()[:2]. The return value is a list of strings, each ending
495 501 in a newline. Normally, the list contains a single string; however,
496 502 for SyntaxError exceptions, it contains several lines that (when
497 503 printed) display detailed information about where the syntax error
498 504 occurred. The message indicating which exception occurred is the
499 505 always last string in the list.
500 506
501 507 Also lifted nearly verbatim from traceback.py
502 508 """
503 509 have_filedata = False
504 510 Colors = self.Colors
505 511 list = []
506 512 stype = py3compat.cast_unicode(Colors.excName + etype.__name__ + Colors.Normal)
507 513 if value is None:
508 514 # Not sure if this can still happen in Python 2.6 and above
509 515 list.append(stype + '\n')
510 516 else:
511 517 if issubclass(etype, SyntaxError):
512 518 have_filedata = True
513 519 if not value.filename: value.filename = "<string>"
514 520 if value.lineno:
515 521 lineno = value.lineno
516 522 textline = linecache.getline(value.filename, value.lineno)
517 523 else:
518 524 lineno = "unknown"
519 525 textline = ""
520 526 list.append(
521 527 "%s %s%s\n"
522 528 % (
523 529 Colors.normalEm,
524 530 _format_filename(
525 531 value.filename,
526 532 Colors.filenameEm,
527 533 Colors.normalEm,
528 534 lineno=(None if lineno == "unknown" else lineno),
529 535 ),
530 536 Colors.Normal,
531 537 )
532 538 )
533 539 if textline == "":
534 540 textline = py3compat.cast_unicode(value.text, "utf-8")
535 541
536 542 if textline is not None:
537 543 i = 0
538 544 while i < len(textline) and textline[i].isspace():
539 545 i += 1
540 546 list.append('%s %s%s\n' % (Colors.line,
541 547 textline.strip(),
542 548 Colors.Normal))
543 549 if value.offset is not None:
544 550 s = ' '
545 551 for c in textline[i:value.offset - 1]:
546 552 if c.isspace():
547 553 s += c
548 554 else:
549 555 s += ' '
550 556 list.append('%s%s^%s\n' % (Colors.caret, s,
551 557 Colors.Normal))
552 558
553 559 try:
554 560 s = value.msg
555 561 except Exception:
556 562 s = self._some_str(value)
557 563 if s:
558 564 list.append('%s%s:%s %s\n' % (stype, Colors.excName,
559 565 Colors.Normal, s))
560 566 else:
561 567 list.append('%s\n' % stype)
562 568
563 569 # sync with user hooks
564 570 if have_filedata:
565 571 ipinst = get_ipython()
566 572 if ipinst is not None:
567 573 ipinst.hooks.synchronize_with_editor(value.filename, value.lineno, 0)
568 574
569 575 return list
570 576
571 577 def get_exception_only(self, etype, value):
572 578 """Only print the exception type and message, without a traceback.
573 579
574 580 Parameters
575 581 ----------
576 582 etype : exception type
577 583 value : exception value
578 584 """
579 585 return ListTB.structured_traceback(self, etype, value)
580 586
581 587 def show_exception_only(self, etype, evalue):
582 588 """Only print the exception type and message, without a traceback.
583 589
584 590 Parameters
585 591 ----------
586 592 etype : exception type
587 593 evalue : exception value
588 594 """
589 595 # This method needs to use __call__ from *this* class, not the one from
590 596 # a subclass whose signature or behavior may be different
591 597 ostream = self.ostream
592 598 ostream.flush()
593 599 ostream.write('\n'.join(self.get_exception_only(etype, evalue)))
594 600 ostream.flush()
595 601
596 602 def _some_str(self, value):
597 603 # Lifted from traceback.py
598 604 try:
599 605 return py3compat.cast_unicode(str(value))
600 606 except:
601 607 return u'<unprintable %s object>' % type(value).__name__
602 608
603 609
604 610 #----------------------------------------------------------------------------
605 611 class VerboseTB(TBTools):
606 612 """A port of Ka-Ping Yee's cgitb.py module that outputs color text instead
607 613 of HTML. Requires inspect and pydoc. Crazy, man.
608 614
609 615 Modified version which optionally strips the topmost entries from the
610 616 traceback, to be used with alternate interpreters (because their own code
611 617 would appear in the traceback)."""
612 618
613 619 _tb_highlight = "bg:ansiyellow"
614 620
615 621 def __init__(
616 622 self,
617 623 color_scheme: str = "Linux",
618 624 call_pdb: bool = False,
619 625 ostream=None,
620 626 tb_offset: int = 0,
621 627 long_header: bool = False,
622 628 include_vars: bool = True,
623 629 check_cache=None,
624 630 debugger_cls=None,
625 631 parent=None,
626 632 config=None,
627 633 ):
628 634 """Specify traceback offset, headers and color scheme.
629 635
630 636 Define how many frames to drop from the tracebacks. Calling it with
631 637 tb_offset=1 allows use of this handler in interpreters which will have
632 638 their own code at the top of the traceback (VerboseTB will first
633 639 remove that frame before printing the traceback info)."""
634 640 TBTools.__init__(
635 641 self,
636 642 color_scheme=color_scheme,
637 643 call_pdb=call_pdb,
638 644 ostream=ostream,
639 645 parent=parent,
640 646 config=config,
641 647 debugger_cls=debugger_cls,
642 648 )
643 649 self.tb_offset = tb_offset
644 650 self.long_header = long_header
645 651 self.include_vars = include_vars
646 652 # By default we use linecache.checkcache, but the user can provide a
647 653 # different check_cache implementation. This was formerly used by the
648 654 # IPython kernel for interactive code, but is no longer necessary.
649 655 if check_cache is None:
650 656 check_cache = linecache.checkcache
651 657 self.check_cache = check_cache
652 658
653 659 self.skip_hidden = True
654 660
655 661 def format_record(self, frame_info):
656 662 """Format a single stack frame"""
657 663 Colors = self.Colors # just a shorthand + quicker name lookup
658 664 ColorsNormal = Colors.Normal # used a lot
659 665
660 666 if isinstance(frame_info, stack_data.RepeatedFrames):
661 667 return ' %s[... skipping similar frames: %s]%s\n' % (
662 668 Colors.excName, frame_info.description, ColorsNormal)
663 669
664 670 indent = " " * INDENT_SIZE
665 671 em_normal = "%s\n%s%s" % (Colors.valEm, indent, ColorsNormal)
666 672 tpl_call = f"in {Colors.vName}{{file}}{Colors.valEm}{{scope}}{ColorsNormal}"
667 673 tpl_call_fail = "in %s%%s%s(***failed resolving arguments***)%s" % (
668 674 Colors.vName,
669 675 Colors.valEm,
670 676 ColorsNormal,
671 677 )
672 678 tpl_name_val = "%%s %s= %%s%s" % (Colors.valEm, ColorsNormal)
673 679
674 680 link = _format_filename(
675 681 frame_info.filename,
676 682 Colors.filenameEm,
677 683 ColorsNormal,
678 684 lineno=frame_info.lineno,
679 685 )
680 686 args, varargs, varkw, locals_ = inspect.getargvalues(frame_info.frame)
681 687
682 688 func = frame_info.executing.code_qualname()
683 689 if func == "<module>":
684 690 call = ""
685 691 else:
686 692 # Decide whether to include variable details or not
687 693 var_repr = eqrepr if self.include_vars else nullrepr
688 694 try:
689 695 scope = inspect.formatargvalues(
690 696 args, varargs, varkw, locals_, formatvalue=var_repr
691 697 )
692 698 call = tpl_call.format(file=func, scope=scope)
693 699 except KeyError:
694 700 # This happens in situations like errors inside generator
695 701 # expressions, where local variables are listed in the
696 702 # line, but can't be extracted from the frame. I'm not
697 703 # 100% sure this isn't actually a bug in inspect itself,
698 704 # but since there's no info for us to compute with, the
699 705 # best we can do is report the failure and move on. Here
700 706 # we must *not* call any traceback construction again,
701 707 # because that would mess up use of %debug later on. So we
702 708 # simply report the failure and move on. The only
703 709 # limitation will be that this frame won't have locals
704 710 # listed in the call signature. Quite subtle problem...
705 711 # I can't think of a good way to validate this in a unit
706 712 # test, but running a script consisting of:
707 713 # dict( (k,v.strip()) for (k,v) in range(10) )
708 714 # will illustrate the error, if this exception catch is
709 715 # disabled.
710 716 call = tpl_call_fail % func
711 717
712 718 lvals = ''
713 719 lvals_list = []
714 720 if self.include_vars:
715 721 try:
716 722 # we likely want to fix stackdata at some point, but
717 723 # still need a workaround.
718 724 fibp = frame_info.variables_in_executing_piece
719 725 for var in fibp:
720 726 lvals_list.append(tpl_name_val % (var.name, repr(var.value)))
721 727 except Exception:
722 728 lvals_list.append(
723 729 "Exception trying to inspect frame. No more locals available."
724 730 )
725 731 if lvals_list:
726 732 lvals = '%s%s' % (indent, em_normal.join(lvals_list))
727 733
728 734 result = f'{link}{", " if call else ""}{call}\n'
729 735
730 736 result += ''.join(_format_traceback_lines(frame_info.lines, Colors, self.has_colors, lvals))
731 737 return result
732 738
733 739 def prepare_header(self, etype, long_version=False):
734 740 colors = self.Colors # just a shorthand + quicker name lookup
735 741 colorsnormal = colors.Normal # used a lot
736 742 exc = '%s%s%s' % (colors.excName, etype, colorsnormal)
737 743 width = min(75, get_terminal_size()[0])
738 744 if long_version:
739 745 # Header with the exception type, python version, and date
740 746 pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
741 747 date = time.ctime(time.time())
742 748
743 749 head = '%s%s%s\n%s%s%s\n%s' % (colors.topline, '-' * width, colorsnormal,
744 750 exc, ' ' * (width - len(str(etype)) - len(pyver)),
745 751 pyver, date.rjust(width) )
746 752 head += "\nA problem occurred executing Python code. Here is the sequence of function" \
747 753 "\ncalls leading up to the error, with the most recent (innermost) call last."
748 754 else:
749 755 # Simplified header
750 756 head = '%s%s' % (exc, 'Traceback (most recent call last)'. \
751 757 rjust(width - len(str(etype))) )
752 758
753 759 return head
754 760
755 761 def format_exception(self, etype, evalue):
756 762 colors = self.Colors # just a shorthand + quicker name lookup
757 763 colorsnormal = colors.Normal # used a lot
758 764 # Get (safely) a string form of the exception info
759 765 try:
760 766 etype_str, evalue_str = map(str, (etype, evalue))
761 767 except:
762 768 # User exception is improperly defined.
763 769 etype, evalue = str, sys.exc_info()[:2]
764 770 etype_str, evalue_str = map(str, (etype, evalue))
765 771 # ... and format it
766 772 return ['%s%s%s: %s' % (colors.excName, etype_str,
767 773 colorsnormal, py3compat.cast_unicode(evalue_str))]
768 774
769 775 def format_exception_as_a_whole(
770 776 self,
771 777 etype: type,
772 778 evalue: BaseException,
773 779 etb: Optional[TracebackType],
774 780 number_of_lines_of_context,
775 781 tb_offset: Optional[int],
776 782 ):
777 783 """Formats the header, traceback and exception message for a single exception.
778 784
779 785 This may be called multiple times by Python 3 exception chaining
780 786 (PEP 3134).
781 787 """
782 788 # some locals
783 789 orig_etype = etype
784 790 try:
785 791 etype = etype.__name__
786 792 except AttributeError:
787 793 pass
788 794
789 795 tb_offset = self.tb_offset if tb_offset is None else tb_offset
790 796 assert isinstance(tb_offset, int)
791 797 head = self.prepare_header(etype, self.long_header)
792 798 records = (
793 799 self.get_records(etb, number_of_lines_of_context, tb_offset) if etb else []
794 800 )
795 801
796 802 frames = []
797 803 skipped = 0
798 804 lastrecord = len(records) - 1
799 805 for i, r in enumerate(records):
800 806 if not isinstance(r, stack_data.RepeatedFrames) and self.skip_hidden:
801 807 if r.frame.f_locals.get("__tracebackhide__", 0) and i != lastrecord:
802 808 skipped += 1
803 809 continue
804 810 if skipped:
805 811 Colors = self.Colors # just a shorthand + quicker name lookup
806 812 ColorsNormal = Colors.Normal # used a lot
807 813 frames.append(
808 814 " %s[... skipping hidden %s frame]%s\n"
809 815 % (Colors.excName, skipped, ColorsNormal)
810 816 )
811 817 skipped = 0
812 818 frames.append(self.format_record(r))
813 819 if skipped:
814 820 Colors = self.Colors # just a shorthand + quicker name lookup
815 821 ColorsNormal = Colors.Normal # used a lot
816 822 frames.append(
817 823 " %s[... skipping hidden %s frame]%s\n"
818 824 % (Colors.excName, skipped, ColorsNormal)
819 825 )
820 826
821 827 formatted_exception = self.format_exception(etype, evalue)
822 828 if records:
823 829 frame_info = records[-1]
824 830 ipinst = get_ipython()
825 831 if ipinst is not None:
826 832 ipinst.hooks.synchronize_with_editor(frame_info.filename, frame_info.lineno, 0)
827 833
828 834 return [[head] + frames + [''.join(formatted_exception[0])]]
829 835
830 836 def get_records(
831 837 self, etb: TracebackType, number_of_lines_of_context: int, tb_offset: int
832 838 ):
833 839 assert etb is not None
834 840 context = number_of_lines_of_context - 1
835 841 after = context // 2
836 842 before = context - after
837 843 if self.has_colors:
838 844 style = get_style_by_name("default")
839 845 style = stack_data.style_with_executing_node(style, self._tb_highlight)
840 846 formatter = Terminal256Formatter(style=style)
841 847 else:
842 848 formatter = None
843 849 options = stack_data.Options(
844 850 before=before,
845 851 after=after,
846 852 pygments_formatter=formatter,
847 853 )
848 854 return list(stack_data.FrameInfo.stack_data(etb, options=options))[tb_offset:]
849 855
850 856 def structured_traceback(
851 857 self,
852 858 etype: type,
853 859 evalue: Optional[BaseException],
854 860 etb: Optional[TracebackType],
855 861 tb_offset: Optional[int] = None,
856 862 number_of_lines_of_context: int = 5,
857 863 ):
858 864 """Return a nice text document describing the traceback."""
859 865 formatted_exception = self.format_exception_as_a_whole(etype, evalue, etb, number_of_lines_of_context,
860 866 tb_offset)
861 867
862 868 colors = self.Colors # just a shorthand + quicker name lookup
863 869 colorsnormal = colors.Normal # used a lot
864 870 head = '%s%s%s' % (colors.topline, '-' * min(75, get_terminal_size()[0]), colorsnormal)
865 871 structured_traceback_parts = [head]
866 872 chained_exceptions_tb_offset = 0
867 873 lines_of_context = 3
868 874 formatted_exceptions = formatted_exception
869 875 exception = self.get_parts_of_chained_exception(evalue)
870 876 if exception:
871 877 assert evalue is not None
872 878 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
873 879 etype, evalue, etb = exception
874 880 else:
875 881 evalue = None
876 882 chained_exc_ids = set()
877 883 while evalue:
878 884 formatted_exceptions += self.format_exception_as_a_whole(etype, evalue, etb, lines_of_context,
879 885 chained_exceptions_tb_offset)
880 886 exception = self.get_parts_of_chained_exception(evalue)
881 887
882 888 if exception and not id(exception[1]) in chained_exc_ids:
883 889 chained_exc_ids.add(id(exception[1])) # trace exception to avoid infinite 'cause' loop
884 890 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
885 891 etype, evalue, etb = exception
886 892 else:
887 893 evalue = None
888 894
889 895 # we want to see exceptions in a reversed order:
890 896 # the first exception should be on top
891 897 for formatted_exception in reversed(formatted_exceptions):
892 898 structured_traceback_parts += formatted_exception
893 899
894 900 return structured_traceback_parts
895 901
896 902 def debugger(self, force: bool = False):
897 903 """Call up the pdb debugger if desired, always clean up the tb
898 904 reference.
899 905
900 906 Keywords:
901 907
902 908 - force(False): by default, this routine checks the instance call_pdb
903 909 flag and does not actually invoke the debugger if the flag is false.
904 910 The 'force' option forces the debugger to activate even if the flag
905 911 is false.
906 912
907 913 If the call_pdb flag is set, the pdb interactive debugger is
908 914 invoked. In all cases, the self.tb reference to the current traceback
909 915 is deleted to prevent lingering references which hamper memory
910 916 management.
911 917
912 918 Note that each call to pdb() does an 'import readline', so if your app
913 919 requires a special setup for the readline completers, you'll have to
914 920 fix that by hand after invoking the exception handler."""
915 921
916 922 if force or self.call_pdb:
917 923 if self.pdb is None:
918 924 self.pdb = self.debugger_cls()
919 925 # the system displayhook may have changed, restore the original
920 926 # for pdb
921 927 display_trap = DisplayTrap(hook=sys.__displayhook__)
922 928 with display_trap:
923 929 self.pdb.reset()
924 930 # Find the right frame so we don't pop up inside ipython itself
925 931 if hasattr(self, 'tb') and self.tb is not None:
926 932 etb = self.tb
927 933 else:
928 934 etb = self.tb = sys.last_traceback
929 935 while self.tb is not None and self.tb.tb_next is not None:
930 936 assert self.tb.tb_next is not None
931 937 self.tb = self.tb.tb_next
932 938 if etb and etb.tb_next:
933 939 etb = etb.tb_next
934 940 self.pdb.botframe = etb.tb_frame
935 941 self.pdb.interaction(None, etb)
936 942
937 943 if hasattr(self, 'tb'):
938 944 del self.tb
939 945
940 946 def handler(self, info=None):
941 947 (etype, evalue, etb) = info or sys.exc_info()
942 948 self.tb = etb
943 949 ostream = self.ostream
944 950 ostream.flush()
945 951 ostream.write(self.text(etype, evalue, etb))
946 952 ostream.write('\n')
947 953 ostream.flush()
948 954
949 955 # Changed so an instance can just be called as VerboseTB_inst() and print
950 956 # out the right info on its own.
951 957 def __call__(self, etype=None, evalue=None, etb=None):
952 958 """This hook can replace sys.excepthook (for Python 2.1 or higher)."""
953 959 if etb is None:
954 960 self.handler()
955 961 else:
956 962 self.handler((etype, evalue, etb))
957 963 try:
958 964 self.debugger()
959 965 except KeyboardInterrupt:
960 966 print("\nKeyboardInterrupt")
961 967
962 968
963 969 #----------------------------------------------------------------------------
964 970 class FormattedTB(VerboseTB, ListTB):
965 971 """Subclass ListTB but allow calling with a traceback.
966 972
967 973 It can thus be used as a sys.excepthook for Python > 2.1.
968 974
969 975 Also adds 'Context' and 'Verbose' modes, not available in ListTB.
970 976
971 977 Allows a tb_offset to be specified. This is useful for situations where
972 978 one needs to remove a number of topmost frames from the traceback (such as
973 979 occurs with python programs that themselves execute other python code,
974 980 like Python shells). """
975 981
976 982 mode: str
977 983
978 984 def __init__(self, mode='Plain', color_scheme='Linux', call_pdb=False,
979 985 ostream=None,
980 986 tb_offset=0, long_header=False, include_vars=False,
981 987 check_cache=None, debugger_cls=None,
982 988 parent=None, config=None):
983 989
984 990 # NEVER change the order of this list. Put new modes at the end:
985 991 self.valid_modes = ['Plain', 'Context', 'Verbose', 'Minimal']
986 992 self.verbose_modes = self.valid_modes[1:3]
987 993
988 994 VerboseTB.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
989 995 ostream=ostream, tb_offset=tb_offset,
990 996 long_header=long_header, include_vars=include_vars,
991 997 check_cache=check_cache, debugger_cls=debugger_cls,
992 998 parent=parent, config=config)
993 999
994 1000 # Different types of tracebacks are joined with different separators to
995 1001 # form a single string. They are taken from this dict
996 1002 self._join_chars = dict(Plain='', Context='\n', Verbose='\n',
997 1003 Minimal='')
998 1004 # set_mode also sets the tb_join_char attribute
999 1005 self.set_mode(mode)
1000 1006
1001 1007 def structured_traceback(self, etype, value, tb, tb_offset=None, number_of_lines_of_context=5):
1002 1008 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1003 1009 mode = self.mode
1004 1010 if mode in self.verbose_modes:
1005 1011 # Verbose modes need a full traceback
1006 1012 return VerboseTB.structured_traceback(
1007 1013 self, etype, value, tb, tb_offset, number_of_lines_of_context
1008 1014 )
1009 1015 elif mode == 'Minimal':
1010 1016 return ListTB.get_exception_only(self, etype, value)
1011 1017 else:
1012 1018 # We must check the source cache because otherwise we can print
1013 1019 # out-of-date source code.
1014 1020 self.check_cache()
1015 1021 # Now we can extract and format the exception
1016 1022 return ListTB.structured_traceback(
1017 1023 self, etype, value, tb, tb_offset, number_of_lines_of_context
1018 1024 )
1019 1025
1020 1026 def stb2text(self, stb):
1021 1027 """Convert a structured traceback (a list) to a string."""
1022 1028 return self.tb_join_char.join(stb)
1023 1029
1024 1030 def set_mode(self, mode: Optional[str] = None):
1025 1031 """Switch to the desired mode.
1026 1032
1027 1033 If mode is not specified, cycles through the available modes."""
1028 1034
1029 1035 if not mode:
1030 1036 new_idx = (self.valid_modes.index(self.mode) + 1 ) % \
1031 1037 len(self.valid_modes)
1032 1038 self.mode = self.valid_modes[new_idx]
1033 1039 elif mode not in self.valid_modes:
1034 1040 raise ValueError(
1035 1041 "Unrecognized mode in FormattedTB: <" + mode + ">\n"
1036 1042 "Valid modes: " + str(self.valid_modes)
1037 1043 )
1038 1044 else:
1039 1045 assert isinstance(mode, str)
1040 1046 self.mode = mode
1041 1047 # include variable details only in 'Verbose' mode
1042 1048 self.include_vars = (self.mode == self.valid_modes[2])
1043 1049 # Set the join character for generating text tracebacks
1044 1050 self.tb_join_char = self._join_chars[self.mode]
1045 1051
1046 1052 # some convenient shortcuts
1047 1053 def plain(self):
1048 1054 self.set_mode(self.valid_modes[0])
1049 1055
1050 1056 def context(self):
1051 1057 self.set_mode(self.valid_modes[1])
1052 1058
1053 1059 def verbose(self):
1054 1060 self.set_mode(self.valid_modes[2])
1055 1061
1056 1062 def minimal(self):
1057 1063 self.set_mode(self.valid_modes[3])
1058 1064
1059 1065
1060 1066 #----------------------------------------------------------------------------
1061 1067 class AutoFormattedTB(FormattedTB):
1062 1068 """A traceback printer which can be called on the fly.
1063 1069
1064 1070 It will find out about exceptions by itself.
1065 1071
1066 1072 A brief example::
1067 1073
1068 1074 AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
1069 1075 try:
1070 1076 ...
1071 1077 except:
1072 1078 AutoTB() # or AutoTB(out=logfile) where logfile is an open file object
1073 1079 """
1074 1080
1075 1081 def __call__(self, etype=None, evalue=None, etb=None,
1076 1082 out=None, tb_offset=None):
1077 1083 """Print out a formatted exception traceback.
1078 1084
1079 1085 Optional arguments:
1080 1086 - out: an open file-like object to direct output to.
1081 1087
1082 1088 - tb_offset: the number of frames to skip over in the stack, on a
1083 1089 per-call basis (this overrides temporarily the instance's tb_offset
1084 1090 given at initialization time."""
1085 1091
1086 1092 if out is None:
1087 1093 out = self.ostream
1088 1094 out.flush()
1089 1095 out.write(self.text(etype, evalue, etb, tb_offset))
1090 1096 out.write('\n')
1091 1097 out.flush()
1092 1098 # FIXME: we should remove the auto pdb behavior from here and leave
1093 1099 # that to the clients.
1094 1100 try:
1095 1101 self.debugger()
1096 1102 except KeyboardInterrupt:
1097 1103 print("\nKeyboardInterrupt")
1098 1104
1099 1105 def structured_traceback(self, etype=None, value=None, tb=None,
1100 1106 tb_offset=None, number_of_lines_of_context=5):
1101 1107
1102 1108 etype: type
1103 1109 value: BaseException
1104 1110 # tb: TracebackType or tupleof tb types ?
1105 1111 if etype is None:
1106 1112 etype, value, tb = sys.exc_info()
1107 1113 if isinstance(tb, tuple):
1108 1114 # tb is a tuple if this is a chained exception.
1109 1115 self.tb = tb[0]
1110 1116 else:
1111 1117 self.tb = tb
1112 1118 return FormattedTB.structured_traceback(
1113 1119 self, etype, value, tb, tb_offset, number_of_lines_of_context)
1114 1120
1115 1121
1116 1122 #---------------------------------------------------------------------------
1117 1123
1118 1124 # A simple class to preserve Nathan's original functionality.
1119 1125 class ColorTB(FormattedTB):
1120 1126 """Shorthand to initialize a FormattedTB in Linux colors mode."""
1121 1127
1122 1128 def __init__(self, color_scheme='Linux', call_pdb=0, **kwargs):
1123 1129 FormattedTB.__init__(self, color_scheme=color_scheme,
1124 1130 call_pdb=call_pdb, **kwargs)
1125 1131
1126 1132
1127 1133 class SyntaxTB(ListTB):
1128 1134 """Extension which holds some state: the last exception value"""
1129 1135
1130 1136 def __init__(self, color_scheme='NoColor', parent=None, config=None):
1131 1137 ListTB.__init__(self, color_scheme, parent=parent, config=config)
1132 1138 self.last_syntax_error = None
1133 1139
1134 1140 def __call__(self, etype, value, elist):
1135 1141 self.last_syntax_error = value
1136 1142
1137 1143 ListTB.__call__(self, etype, value, elist)
1138 1144
1139 1145 def structured_traceback(self, etype, value, elist, tb_offset=None,
1140 1146 context=5):
1141 1147 # If the source file has been edited, the line in the syntax error can
1142 1148 # be wrong (retrieved from an outdated cache). This replaces it with
1143 1149 # the current value.
1144 1150 if isinstance(value, SyntaxError) \
1145 1151 and isinstance(value.filename, str) \
1146 1152 and isinstance(value.lineno, int):
1147 1153 linecache.checkcache(value.filename)
1148 1154 newtext = linecache.getline(value.filename, value.lineno)
1149 1155 if newtext:
1150 1156 value.text = newtext
1151 1157 self.last_syntax_error = value
1152 1158 return super(SyntaxTB, self).structured_traceback(etype, value, elist,
1153 1159 tb_offset=tb_offset, context=context)
1154 1160
1155 1161 def clear_err_state(self):
1156 1162 """Return the current error state and clear it"""
1157 1163 e = self.last_syntax_error
1158 1164 self.last_syntax_error = None
1159 1165 return e
1160 1166
1161 1167 def stb2text(self, stb):
1162 1168 """Convert a structured traceback (a list) to a string."""
1163 1169 return ''.join(stb)
1164 1170
1165 1171
1166 1172 # some internal-use functions
1167 1173 def text_repr(value):
1168 1174 """Hopefully pretty robust repr equivalent."""
1169 1175 # this is pretty horrible but should always return *something*
1170 1176 try:
1171 1177 return pydoc.text.repr(value)
1172 1178 except KeyboardInterrupt:
1173 1179 raise
1174 1180 except:
1175 1181 try:
1176 1182 return repr(value)
1177 1183 except KeyboardInterrupt:
1178 1184 raise
1179 1185 except:
1180 1186 try:
1181 1187 # all still in an except block so we catch
1182 1188 # getattr raising
1183 1189 name = getattr(value, '__name__', None)
1184 1190 if name:
1185 1191 # ick, recursion
1186 1192 return text_repr(name)
1187 1193 klass = getattr(value, '__class__', None)
1188 1194 if klass:
1189 1195 return '%s instance' % text_repr(klass)
1190 1196 except KeyboardInterrupt:
1191 1197 raise
1192 1198 except:
1193 1199 return 'UNRECOVERABLE REPR FAILURE'
1194 1200
1195 1201
1196 1202 def eqrepr(value, repr=text_repr):
1197 1203 return '=%s' % repr(value)
1198 1204
1199 1205
1200 1206 def nullrepr(value, repr=text_repr):
1201 1207 return ''
@@ -1,1260 +1,1286 b''
1 1 ============
2 2 8.x Series
3 3 ============
4 4
5
6 .. _version 8.7.0:
7
8 IPython 8.7.0
9 -------------
10
11
12 Small release of IPython with a couple of bug fixes and new features for this
13 month. Next month is end of year, it is unclear if there will be a release close
14 the new year's eve, or if the next release will be at end of January.
15
16 Here are a few of the relevant fixes,
17 as usual you can find the full list of PRs on GitHub under `the 8.7 milestone
18 <https://github.com/ipython/ipython/pulls?q=milestone%3A8.7>`__.
19
20
21 - :ghpull:`13834` bump the minimum prompt toolkit to 3.0.11.
22 - IPython shipped with the ``py.typed`` marker now, and we are progressively
23 adding more types. :ghpull:`13831`
24 - :ghpull:`13817` add configuration of code blacks formatting.
25
26
27 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
28 work on IPython and related libraries.
29
30
5 31 .. _version 8.6.0:
6 32
7 33 IPython 8.6.0
8 34 -------------
9 35
10 36 Back to a more regular release schedule (at least I try), as Friday is
11 37 already over by more than 24h hours. This is a slightly bigger release with a
12 38 few new features that contain no less then 25 PRs.
13 39
14 40 We'll notably found a couple of non negligible changes:
15 41
16 42 The ``install_ext`` and related functions have been removed after being
17 43 deprecated for years. You can use pip to install extensions. ``pip`` did not
18 44 exists when ``install_ext`` was introduced. You can still load local extensions
19 45 without installing them. Just set your ``sys.path`` for example. :ghpull:`13744`
20 46
21 47 IPython now have extra entry points that that the major *and minor* version of
22 48 python. For some of you this mean that you can do a quick ``ipython3.10`` to
23 49 launch IPython from the Python 3.10 interpreter, while still using Python 3.11
24 50 as your main Python. :ghpull:`13743`
25 51
26 52 The completer matcher API have been improved. See :ghpull:`13745`. This should
27 53 improve the type inference and improve dict keys completions in many use case.
28 54 Tanks ``@krassowski`` for all the works, and the D.E. Shaw group for sponsoring
29 55 it.
30 56
31 57 The color of error nodes in tracebacks can now be customized. See
32 58 :ghpull:`13756`. This is a private attribute until someone find the time to
33 59 properly add a configuration option. Note that with Python 3.11 that also show
34 60 the relevant nodes in traceback, it would be good to leverage this informations
35 61 (plus the "did you mean" info added on attribute errors). But that's likely work
36 62 I won't have time to do before long, so contributions welcome.
37 63
38 64 As we follow NEP 29, we removed support for numpy 1.19 :ghpull:`13760`.
39 65
40 66
41 67 The ``open()`` function present in the user namespace by default will now refuse
42 68 to open the file descriptors 0,1,2 (stdin, out, err), to avoid crashing IPython.
43 This mostly occurs in teaching context when incorrect values get passed around.
69 This mostly occurs in teaching context when incorrect values get passed around.
44 70
45 71
46 72 The ``?``, ``??``, and corresponding ``pinfo``, ``pinfo2`` magics can now find
47 73 objects insides arrays. That is to say, the following now works::
48 74
49 75
50 76 >>> def my_func(*arg, **kwargs):pass
51 77 >>> container = [my_func]
52 78 >>> container[0]?
53 79
54 80
55 81 If ``container`` define a custom ``getitem``, this __will__ trigger the custom
56 82 method. So don't put side effects in your ``getitems``. Thanks the D.E. Shaw
57 83 group for the request and sponsoring the work.
58 84
59 85
60 86 As usual you can find the full list of PRs on GitHub under `the 8.6 milestone
61 87 <https://github.com/ipython/ipython/pulls?q=milestone%3A8.6>`__.
62 88
63 89 Thanks to all hacktoberfest contributors, please contribute to
64 90 `closember.org <https://closember.org/>`__.
65 91
66 92 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
67 93 work on IPython and related libraries.
68 94
69 95 .. _version 8.5.0:
70 96
71 97 IPython 8.5.0
72 98 -------------
73 99
74 100 First release since a couple of month due to various reasons and timing preventing
75 101 me for sticking to the usual monthly release the last Friday of each month. This
76 102 is of non negligible size as it has more than two dozen PRs with various fixes
77 103 an bug fixes.
78 104
79 105 Many thanks to everybody who contributed PRs for your patience in review and
80 106 merges.
81 107
82 108 Here is a non exhaustive list of changes that have been implemented for IPython
83 109 8.5.0. As usual you can find the full list of issues and PRs tagged with `the
84 110 8.5 milestone
85 111 <https://github.com/ipython/ipython/pulls?q=is%3Aclosed+milestone%3A8.5+>`__.
86 112
87 113 - Added shortcut for accepting auto suggestion. The End key shortcut for
88 114 accepting auto-suggestion This binding works in Vi mode too, provided
89 115 ``TerminalInteractiveShell.emacs_bindings_in_vi_insert_mode`` is set to be
90 116 ``True`` :ghpull:`13566`.
91 117
92 118 - No popup in window for latex generation w hen generating latex (e.g. via
93 119 `_latex_repr_`) no popup window is shows under Windows. :ghpull:`13679`
94 120
95 121 - Fixed error raised when attempting to tab-complete an input string with
96 122 consecutive periods or forward slashes (such as "file:///var/log/...").
97 123 :ghpull:`13675`
98 124
99 125 - Relative filenames in Latex rendering :
100 126 The `latex_to_png_dvipng` command internally generates input and output file
101 127 arguments to `latex` and `dvipis`. These arguments are now generated as
102 128 relative files to the current working directory instead of absolute file
103 129 paths. This solves a problem where the current working directory contains
104 130 characters that are not handled properly by `latex` and `dvips`. There are
105 131 no changes to the user API. :ghpull:`13680`
106 132
107 133 - Stripping decorators bug: Fixed bug which meant that ipython code blocks in
108 134 restructured text documents executed with the ipython-sphinx extension
109 135 skipped any lines of code containing python decorators. :ghpull:`13612`
110 136
111 137 - Allow some modules with frozen dataclasses to be reloaded. :ghpull:`13732`
112 138 - Fix paste magic on wayland. :ghpull:`13671`
113 139 - show maxlen in deque's repr. :ghpull:`13648`
114 140
115 141 Restore line numbers for Input
116 142 ------------------------------
117 143
118 144 Line number information in tracebacks from input are restored.
119 145 Line numbers from input were removed during the transition to v8 enhanced traceback reporting.
120 146
121 147 So, instead of::
122 148
123 149 ---------------------------------------------------------------------------
124 150 ZeroDivisionError Traceback (most recent call last)
125 151 Input In [3], in <cell line: 1>()
126 152 ----> 1 myfunc(2)
127 153
128 154 Input In [2], in myfunc(z)
129 155 1 def myfunc(z):
130 156 ----> 2 foo.boo(z-1)
131 157
132 158 File ~/code/python/ipython/foo.py:3, in boo(x)
133 159 2 def boo(x):
134 160 ----> 3 return 1/(1-x)
135 161
136 162 ZeroDivisionError: division by zero
137 163
138 164 The error traceback now looks like::
139 165
140 166 ---------------------------------------------------------------------------
141 167 ZeroDivisionError Traceback (most recent call last)
142 168 Cell In [3], line 1
143 169 ----> 1 myfunc(2)
144 170
145 171 Cell In [2], line 2, in myfunc(z)
146 172 1 def myfunc(z):
147 173 ----> 2 foo.boo(z-1)
148 174
149 175 File ~/code/python/ipython/foo.py:3, in boo(x)
150 176 2 def boo(x):
151 177 ----> 3 return 1/(1-x)
152 178
153 179 ZeroDivisionError: division by zero
154 180
155 181 or, with xmode=Plain::
156 182
157 183 Traceback (most recent call last):
158 184 Cell In [12], line 1
159 185 myfunc(2)
160 186 Cell In [6], line 2 in myfunc
161 187 foo.boo(z-1)
162 188 File ~/code/python/ipython/foo.py:3 in boo
163 189 return 1/(1-x)
164 190 ZeroDivisionError: division by zero
165 191
166 192 :ghpull:`13560`
167 193
168 194 New setting to silence warning if working inside a virtual environment
169 195 ----------------------------------------------------------------------
170 196
171 197 Previously, when starting IPython in a virtual environment without IPython installed (so IPython from the global environment is used), the following warning was printed:
172 198
173 199 Attempting to work in a virtualenv. If you encounter problems, please install IPython inside the virtualenv.
174 200
175 201 This warning can be permanently silenced by setting ``c.InteractiveShell.warn_venv`` to ``False`` (the default is ``True``).
176 202
177 203 :ghpull:`13706`
178 204
179 205 -------
180 206
181 207 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
182 208 work on IPython and related libraries.
183 209
184 210
185 211 .. _version 8.4.0:
186 212
187 213 IPython 8.4.0
188 214 -------------
189 215
190 216 As for 7.34, this version contains a single fix: fix uncaught BdbQuit exceptions on ipdb
191 217 exit :ghpull:`13668`, and a single typo fix in documentation: :ghpull:`13682`
192 218
193 219 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
194 220 work on IPython and related libraries.
195 221
196 222
197 223 .. _version 8.3.0:
198 224
199 225 IPython 8.3.0
200 226 -------------
201 227
202 228 - :ghpull:`13625`, using ``?``, ``??``, ``*?`` will not call
203 229 ``set_next_input`` as most frontend allow proper multiline editing and it was
204 230 causing issues for many users of multi-cell frontends. This has been backported to 7.33
205 231
206 232
207 233 - :ghpull:`13600`, ``pre_run_*``-hooks will now have a ``cell_id`` attribute on
208 234 the info object when frontend provide it. This has been backported to 7.33
209 235
210 236 - :ghpull:`13624`, fixed :kbd:`End` key being broken after accepting an
211 237 auto-suggestion.
212 238
213 239 - :ghpull:`13657` fix issue where history from different sessions would be mixed.
214 240
215 241 .. _version 8.2.0:
216 242
217 243 IPython 8.2.0
218 244 -------------
219 245
220 246 IPython 8.2 mostly bring bugfixes to IPython.
221 247
222 248 - Auto-suggestion can now be elected with the ``end`` key. :ghpull:`13566`
223 249 - Some traceback issues with ``assert etb is not None`` have been fixed. :ghpull:`13588`
224 250 - History is now pulled from the sqitel database and not from in-memory.
225 251 In particular when using the ``%paste`` magic, the content of the pasted text will
226 252 be part of the history and not the verbatim text ``%paste`` anymore. :ghpull:`13592`
227 253 - Fix ``Ctrl-\\`` exit cleanup :ghpull:`13603`
228 254 - Fixes to ``ultratb`` ipdb support when used outside of IPython. :ghpull:`13498`
229 255
230 256
231 257 I am still trying to fix and investigate :ghissue:`13598`, which seem to be
232 258 random, and would appreciate help if you find reproducible minimal case. I've
233 259 tried to make various changes to the codebase to mitigate it, but a proper fix
234 260 will be difficult without understanding the cause.
235 261
236 262
237 263 All the issues on pull-requests for this release can be found in the `8.2
238 264 milestone. <https://github.com/ipython/ipython/milestone/100>`__ . And some
239 265 documentation only PR can be found as part of the `7.33 milestone
240 266 <https://github.com/ipython/ipython/milestone/101>`__ (currently not released).
241 267
242 268 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
243 269 work on IPython and related libraries.
244 270
245 271 .. _version 8.1.1:
246 272
247 273 IPython 8.1.1
248 274 -------------
249 275
250 276 Fix an issue with virtualenv and Python 3.8 introduced in 8.1
251 277
252 278 Revert :ghpull:`13537` (fix an issue with symlinks in virtualenv) that raises an
253 279 error in Python 3.8, and fixed in a different way in :ghpull:`13559`.
254 280
255 281 .. _version 8.1:
256 282
257 283 IPython 8.1.0
258 284 -------------
259 285
260 286 IPython 8.1 is the first minor release after 8.0 and fixes a number of bugs and
261 287 Update a few behavior that were problematic with the 8.0 as with many new major
262 288 release.
263 289
264 290 Note that beyond the changes listed here, IPython 8.1.0 also contains all the
265 291 features listed in :ref:`version 7.32`.
266 292
267 293 - Misc and multiple fixes around quotation auto-closing. It is now disabled by
268 294 default. Run with ``TerminalInteractiveShell.auto_match=True`` to re-enabled
269 295 - Require pygments>=2.4.0 :ghpull:`13459`, this was implicit in the code, but
270 296 is now explicit in ``setup.cfg``/``setup.py``
271 297 - Docs improvement of ``core.magic_arguments`` examples. :ghpull:`13433`
272 298 - Multi-line edit executes too early with await. :ghpull:`13424`
273 299
274 300 - ``black`` is back as an optional dependency, and autoformatting disabled by
275 301 default until some fixes are implemented (black improperly reformat magics).
276 302 :ghpull:`13471` Additionally the ability to use ``yapf`` as a code
277 303 reformatter has been added :ghpull:`13528` . You can use
278 304 ``TerminalInteractiveShell.autoformatter="black"``,
279 305 ``TerminalInteractiveShell.autoformatter="yapf"`` to re-enable auto formating
280 306 with black, or switch to yapf.
281 307
282 308 - Fix and issue where ``display`` was not defined.
283 309
284 310 - Auto suggestions are now configurable. Currently only
285 311 ``AutoSuggestFromHistory`` (default) and ``None``. new provider contribution
286 312 welcomed. :ghpull:`13475`
287 313
288 314 - multiple packaging/testing improvement to simplify downstream packaging
289 315 (xfail with reasons, try to not access network...).
290 316
291 317 - Update deprecation. ``InteractiveShell.magic`` internal method has been
292 318 deprecated for many years but did not emit a warning until now.
293 319
294 320 - internal ``appended_to_syspath`` context manager has been deprecated.
295 321
296 322 - fix an issue with symlinks in virtualenv :ghpull:`13537` (Reverted in 8.1.1)
297 323
298 324 - Fix an issue with vim mode, where cursor would not be reset on exit :ghpull:`13472`
299 325
300 326 - ipython directive now remove only known pseudo-decorators :ghpull:`13532`
301 327
302 328 - ``IPython/lib/security`` which used to be used for jupyter notebook has been
303 329 removed.
304 330
305 331 - Fix an issue where ``async with`` would execute on new lines. :ghpull:`13436`
306 332
307 333
308 334 We want to remind users that IPython is part of the Jupyter organisations, and
309 335 thus governed by a Code of Conduct. Some of the behavior we have seen on GitHub is not acceptable.
310 336 Abuse and non-respectful comments on discussion will not be tolerated.
311 337
312 338 Many thanks to all the contributors to this release, many of the above fixed issue and
313 339 new features where done by first time contributors, showing there is still
314 340 plenty of easy contribution possible in IPython
315 341 . You can find all individual contributions
316 342 to this milestone `on github <https://github.com/ipython/ipython/milestone/91>`__.
317 343
318 344 Thanks as well to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
319 345 work on IPython and related libraries. In particular the Lazy autoloading of
320 346 magics that you will find described in the 7.32 release notes.
321 347
322 348
323 349 .. _version 8.0.1:
324 350
325 351 IPython 8.0.1 (CVE-2022-21699)
326 352 ------------------------------
327 353
328 354 IPython 8.0.1, 7.31.1 and 5.11 are security releases that change some default
329 355 values in order to prevent potential Execution with Unnecessary Privileges.
330 356
331 357 Almost all version of IPython looks for configuration and profiles in current
332 358 working directory. Since IPython was developed before pip and environments
333 359 existed it was used a convenient way to load code/packages in a project
334 360 dependant way.
335 361
336 362 In 2022, it is not necessary anymore, and can lead to confusing behavior where
337 363 for example cloning a repository and starting IPython or loading a notebook from
338 364 any Jupyter-Compatible interface that has ipython set as a kernel can lead to
339 365 code execution.
340 366
341 367
342 368 I did not find any standard way for packaged to advertise CVEs they fix, I'm
343 369 thus trying to add a ``__patched_cves__`` attribute to the IPython module that
344 370 list the CVEs that should have been fixed. This attribute is informational only
345 371 as if a executable has a flaw, this value can always be changed by an attacker.
346 372
347 373 .. code::
348 374
349 375 In [1]: import IPython
350 376
351 377 In [2]: IPython.__patched_cves__
352 378 Out[2]: {'CVE-2022-21699'}
353 379
354 380 In [3]: 'CVE-2022-21699' in IPython.__patched_cves__
355 381 Out[3]: True
356 382
357 383 Thus starting with this version:
358 384
359 385 - The current working directory is not searched anymore for profiles or
360 386 configurations files.
361 387 - Added a ``__patched_cves__`` attribute (set of strings) to IPython module that contain
362 388 the list of fixed CVE. This is informational only.
363 389
364 390 Further details can be read on the `GitHub Advisory <https://github.com/ipython/ipython/security/advisories/GHSA-pq7m-3gw7-gq5x>`__
365 391
366 392
367 393 .. _version 8.0:
368 394
369 395 IPython 8.0
370 396 -----------
371 397
372 398 IPython 8.0 is bringing a large number of new features and improvements to both the
373 399 user of the terminal and of the kernel via Jupyter. The removal of compatibility
374 400 with older version of Python is also the opportunity to do a couple of
375 401 performance improvements in particular with respect to startup time.
376 402 The 8.x branch started diverging from its predecessor around IPython 7.12
377 403 (January 2020).
378 404
379 405 This release contains 250+ pull requests, in addition to many of the features
380 406 and backports that have made it to the 7.x branch. Please see the
381 407 `8.0 milestone <https://github.com/ipython/ipython/milestone/73?closed=1>`__ for the full list of pull requests.
382 408
383 409 Please feel free to send pull requests to updates those notes after release,
384 410 I have likely forgotten a few things reviewing 250+ PRs.
385 411
386 412 Dependencies changes/downstream packaging
387 413 -----------------------------------------
388 414
389 415 Most of our building steps have been changed to be (mostly) declarative
390 416 and follow PEP 517. We are trying to completely remove ``setup.py`` (:ghpull:`13238`) and are
391 417 looking for help to do so.
392 418
393 419 - minimum supported ``traitlets`` version is now 5+
394 420 - we now require ``stack_data``
395 421 - minimal Python is now 3.8
396 422 - ``nose`` is not a testing requirement anymore
397 423 - ``pytest`` replaces nose.
398 424 - ``iptest``/``iptest3`` cli entrypoints do not exists anymore.
399 425 - minimum officially support ``numpy`` version has been bumped, but this should
400 426 not have much effect on packaging.
401 427
402 428
403 429 Deprecation and removal
404 430 -----------------------
405 431
406 432 We removed almost all features, arguments, functions, and modules that were
407 433 marked as deprecated between IPython 1.0 and 5.0. As a reminder, 5.0 was released
408 434 in 2016, and 1.0 in 2013. Last release of the 5 branch was 5.10.0, in May 2020.
409 435 The few remaining deprecated features we left have better deprecation warnings
410 436 or have been turned into explicit errors for better error messages.
411 437
412 438 I will use this occasion to add the following requests to anyone emitting a
413 439 deprecation warning:
414 440
415 441 - Please add at least ``stacklevel=2`` so that the warning is emitted into the
416 442 caller context, and not the callee one.
417 443 - Please add **since which version** something is deprecated.
418 444
419 445 As a side note, it is much easier to conditionally compare version
420 446 numbers rather than using ``try/except`` when functionality changes with a version.
421 447
422 448 I won't list all the removed features here, but modules like ``IPython.kernel``,
423 449 which was just a shim module around ``ipykernel`` for the past 8 years, have been
424 450 removed, and so many other similar things that pre-date the name **Jupyter**
425 451 itself.
426 452
427 453 We no longer need to add ``IPython.extensions`` to the PYTHONPATH because that is being
428 454 handled by ``load_extension``.
429 455
430 456 We are also removing ``Cythonmagic``, ``sympyprinting`` and ``rmagic`` as they are now in
431 457 other packages and no longer need to be inside IPython.
432 458
433 459
434 460 Documentation
435 461 -------------
436 462
437 463 The majority of our docstrings have now been reformatted and automatically fixed by
438 464 the experimental `Vélin <https://pypi.org/project/velin/>`_ project to conform
439 465 to numpydoc.
440 466
441 467 Type annotations
442 468 ----------------
443 469
444 470 While IPython itself is highly dynamic and can't be completely typed, many of
445 471 the functions now have type annotations, and part of the codebase is now checked
446 472 by mypy.
447 473
448 474
449 475 Featured changes
450 476 ----------------
451 477
452 478 Here is a features list of changes in IPython 8.0. This is of course non-exhaustive.
453 479 Please note as well that many features have been added in the 7.x branch as well
454 480 (and hence why you want to read the 7.x what's new notes), in particular
455 481 features contributed by QuantStack (with respect to debugger protocol and Xeus
456 482 Python), as well as many debugger features that I was pleased to implement as
457 483 part of my work at QuanSight and sponsored by DE Shaw.
458 484
459 485 Traceback improvements
460 486 ~~~~~~~~~~~~~~~~~~~~~~
461 487
462 488 Previously, error tracebacks for errors happening in code cells were showing a
463 489 hash, the one used for compiling the Python AST::
464 490
465 491 In [1]: def foo():
466 492 ...: return 3 / 0
467 493 ...:
468 494
469 495 In [2]: foo()
470 496 ---------------------------------------------------------------------------
471 497 ZeroDivisionError Traceback (most recent call last)
472 498 <ipython-input-2-c19b6d9633cf> in <module>
473 499 ----> 1 foo()
474 500
475 501 <ipython-input-1-1595a74c32d5> in foo()
476 502 1 def foo():
477 503 ----> 2 return 3 / 0
478 504 3
479 505
480 506 ZeroDivisionError: division by zero
481 507
482 508 The error traceback is now correctly formatted, showing the cell number in which the error happened::
483 509
484 510 In [1]: def foo():
485 511 ...: return 3 / 0
486 512 ...:
487 513
488 514 Input In [2]: foo()
489 515 ---------------------------------------------------------------------------
490 516 ZeroDivisionError Traceback (most recent call last)
491 517 input In [2], in <module>
492 518 ----> 1 foo()
493 519
494 520 Input In [1], in foo()
495 521 1 def foo():
496 522 ----> 2 return 3 / 0
497 523
498 524 ZeroDivisionError: division by zero
499 525
500 526 The ``stack_data`` package has been integrated, which provides smarter information in the traceback;
501 527 in particular it will highlight the AST node where an error occurs which can help to quickly narrow down errors.
502 528
503 529 For example in the following snippet::
504 530
505 531 def foo(i):
506 532 x = [[[0]]]
507 533 return x[0][i][0]
508 534
509 535
510 536 def bar():
511 537 return foo(0) + foo(
512 538 1
513 539 ) + foo(2)
514 540
515 541
516 542 calling ``bar()`` would raise an ``IndexError`` on the return line of ``foo``,
517 543 and IPython 8.0 is capable of telling you where the index error occurs::
518 544
519 545
520 546 IndexError
521 547 Input In [2], in <module>
522 548 ----> 1 bar()
523 549 ^^^^^
524 550
525 551 Input In [1], in bar()
526 552 6 def bar():
527 553 ----> 7 return foo(0) + foo(
528 554 ^^^^
529 555 8 1
530 556 ^^^^^^^^
531 557 9 ) + foo(2)
532 558 ^^^^
533 559
534 560 Input In [1], in foo(i)
535 561 1 def foo(i):
536 562 2 x = [[[0]]]
537 563 ----> 3 return x[0][i][0]
538 564 ^^^^^^^
539 565
540 566 The corresponding locations marked here with ``^`` will show up highlighted in
541 567 the terminal and notebooks.
542 568
543 569 Finally, a colon ``::`` and line number is appended after a filename in
544 570 traceback::
545 571
546 572
547 573 ZeroDivisionError Traceback (most recent call last)
548 574 File ~/error.py:4, in <module>
549 575 1 def f():
550 576 2 1/0
551 577 ----> 4 f()
552 578
553 579 File ~/error.py:2, in f()
554 580 1 def f():
555 581 ----> 2 1/0
556 582
557 583 Many terminals and editors have integrations enabling you to directly jump to the
558 584 relevant file/line when this syntax is used, so this small addition may have a high
559 585 impact on productivity.
560 586
561 587
562 588 Autosuggestions
563 589 ~~~~~~~~~~~~~~~
564 590
565 591 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>`__.
566 592
567 593 `Ptpython <https://github.com/prompt-toolkit/ptpython#ptpython>`__ allows users to enable this feature in
568 594 `ptpython/config.py <https://github.com/prompt-toolkit/ptpython/blob/master/examples/ptpython_config/config.py#L90>`__.
569 595
570 596 This feature allows users to accept autosuggestions with ctrl e, ctrl f,
571 597 or right arrow as described below.
572 598
573 599 1. Start ipython
574 600
575 601 .. image:: ../_images/8.0/auto_suggest_1_prompt_no_text.png
576 602
577 603 2. Run ``print("hello")``
578 604
579 605 .. image:: ../_images/8.0/auto_suggest_2_print_hello_suggest.png
580 606
581 607 3. start typing ``print`` again to see the autosuggestion
582 608
583 609 .. image:: ../_images/8.0/auto_suggest_3_print_hello_suggest.png
584 610
585 611 4. Press ``ctrl-f``, or ``ctrl-e``, or ``right-arrow`` to accept the suggestion
586 612
587 613 .. image:: ../_images/8.0/auto_suggest_4_print_hello.png
588 614
589 615 You can also complete word by word:
590 616
591 617 1. Run ``def say_hello(): print("hello")``
592 618
593 619 .. image:: ../_images/8.0/auto_suggest_second_prompt.png
594 620
595 621 2. Start typing the first letter if ``def`` to see the autosuggestion
596 622
597 623 .. image:: ../_images/8.0/auto_suggest_d_phantom.png
598 624
599 625 3. Press ``alt-f`` (or ``escape`` followed by ``f``), to accept the first word of the suggestion
600 626
601 627 .. image:: ../_images/8.0/auto_suggest_def_phantom.png
602 628
603 629 Importantly, this feature does not interfere with tab completion:
604 630
605 631 1. After running ``def say_hello(): print("hello")``, press d
606 632
607 633 .. image:: ../_images/8.0/auto_suggest_d_phantom.png
608 634
609 635 2. Press Tab to start tab completion
610 636
611 637 .. image:: ../_images/8.0/auto_suggest_d_completions.png
612 638
613 639 3A. Press Tab again to select the first option
614 640
615 641 .. image:: ../_images/8.0/auto_suggest_def_completions.png
616 642
617 643 3B. Press ``alt f`` (``escape``, ``f``) to accept to accept the first word of the suggestion
618 644
619 645 .. image:: ../_images/8.0/auto_suggest_def_phantom.png
620 646
621 647 3C. Press ``ctrl-f`` or ``ctrl-e`` to accept the entire suggestion
622 648
623 649 .. image:: ../_images/8.0/auto_suggest_match_parens.png
624 650
625 651
626 652 Currently, autosuggestions are only shown in the emacs or vi insert editing modes:
627 653
628 654 - The ctrl e, ctrl f, and alt f shortcuts work by default in emacs mode.
629 655 - 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/>`__.
630 656
631 657
632 658 Show pinfo information in ipdb using "?" and "??"
633 659 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
634 660
635 661 In IPDB, it is now possible to show the information about an object using "?"
636 662 and "??", in much the same way that it can be done when using the IPython prompt::
637 663
638 664 ipdb> partial?
639 665 Init signature: partial(self, /, *args, **kwargs)
640 666 Docstring:
641 667 partial(func, *args, **keywords) - new function with partial application
642 668 of the given arguments and keywords.
643 669 File: ~/.pyenv/versions/3.8.6/lib/python3.8/functools.py
644 670 Type: type
645 671 Subclasses:
646 672
647 673 Previously, ``pinfo`` or ``pinfo2`` command had to be used for this purpose.
648 674
649 675
650 676 Autoreload 3 feature
651 677 ~~~~~~~~~~~~~~~~~~~~
652 678
653 679 Example: When an IPython session is run with the 'autoreload' extension loaded,
654 680 you will now have the option '3' to select, which means the following:
655 681
656 682 1. replicate all functionality from option 2
657 683 2. autoload all new funcs/classes/enums/globals from the module when they are added
658 684 3. autoload all newly imported funcs/classes/enums/globals from external modules
659 685
660 686 Try ``%autoreload 3`` in an IPython session after running ``%load_ext autoreload``.
661 687
662 688 For more information please see the following unit test : ``extensions/tests/test_autoreload.py:test_autoload_newly_added_objects``
663 689
664 690 Auto formatting with black in the CLI
665 691 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
666 692
667 693 This feature was present in 7.x, but disabled by default.
668 694
669 695 In 8.0, input was automatically reformatted with Black when black was installed.
670 696 This feature has been reverted for the time being.
671 697 You can re-enable it by setting ``TerminalInteractiveShell.autoformatter`` to ``"black"``
672 698
673 699 History Range Glob feature
674 700 ~~~~~~~~~~~~~~~~~~~~~~~~~~
675 701
676 702 Previously, when using ``%history``, users could specify either
677 703 a range of sessions and lines, for example:
678 704
679 705 .. code-block:: python
680 706
681 707 ~8/1-~6/5 # see history from the first line of 8 sessions ago,
682 708 # to the fifth line of 6 sessions ago.``
683 709
684 710 Or users could specify a glob pattern:
685 711
686 712 .. code-block:: python
687 713
688 714 -g <pattern> # glob ALL history for the specified pattern.
689 715
690 716 However users could *not* specify both.
691 717
692 718 If a user *did* specify both a range and a glob pattern,
693 719 then the glob pattern would be used (globbing *all* history) *and the range would be ignored*.
694 720
695 721 With this enhancement, if a user specifies both a range and a glob pattern, then the glob pattern will be applied to the specified range of history.
696 722
697 723 Don't start a multi-line cell with sunken parenthesis
698 724 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
699 725
700 726 From now on, IPython will not ask for the next line of input when given a single
701 727 line with more closing than opening brackets. For example, this means that if
702 728 you (mis)type ``]]`` instead of ``[]``, a ``SyntaxError`` will show up, instead of
703 729 the ``...:`` prompt continuation.
704 730
705 731 IPython shell for ipdb interact
706 732 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
707 733
708 734 The ipdb ``interact`` starts an IPython shell instead of Python's built-in ``code.interact()``.
709 735
710 736 Automatic Vi prompt stripping
711 737 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
712 738
713 739 When pasting code into IPython, it will strip the leading prompt characters if
714 740 there are any. For example, you can paste the following code into the console -
715 741 it will still work, even though each line is prefixed with prompts (``In``,
716 742 ``Out``)::
717 743
718 744 In [1]: 2 * 2 == 4
719 745 Out[1]: True
720 746
721 747 In [2]: print("This still works as pasted")
722 748
723 749
724 750 Previously, this was not the case for the Vi-mode prompts::
725 751
726 752 In [1]: [ins] In [13]: 2 * 2 == 4
727 753 ...: Out[13]: True
728 754 ...:
729 755 File "<ipython-input-1-727bb88eaf33>", line 1
730 756 [ins] In [13]: 2 * 2 == 4
731 757 ^
732 758 SyntaxError: invalid syntax
733 759
734 760 This is now fixed, and Vi prompt prefixes - ``[ins]`` and ``[nav]`` - are
735 761 skipped just as the normal ``In`` would be.
736 762
737 763 IPython shell can be started in the Vi mode using ``ipython --TerminalInteractiveShell.editing_mode=vi``,
738 764 You should be able to change mode dynamically with ``%config TerminalInteractiveShell.editing_mode='vi'``
739 765
740 766 Empty History Ranges
741 767 ~~~~~~~~~~~~~~~~~~~~
742 768
743 769 A number of magics that take history ranges can now be used with an empty
744 770 range. These magics are:
745 771
746 772 * ``%save``
747 773 * ``%load``
748 774 * ``%pastebin``
749 775 * ``%pycat``
750 776
751 777 Using them this way will make them take the history of the current session up
752 778 to the point of the magic call (such that the magic itself will not be
753 779 included).
754 780
755 781 Therefore it is now possible to save the whole history to a file using
756 782 ``%save <filename>``, load and edit it using ``%load`` (makes for a nice usage
757 783 when followed with :kbd:`F2`), send it to `dpaste.org <http://dpast.org>`_ using
758 784 ``%pastebin``, or view the whole thing syntax-highlighted with a single
759 785 ``%pycat``.
760 786
761 787
762 788 Windows timing implementation: Switch to process_time
763 789 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
764 790 Timing on Windows, for example with ``%%time``, was changed from being based on ``time.perf_counter``
765 791 (which counted time even when the process was sleeping) to being based on ``time.process_time`` instead
766 792 (which only counts CPU time). This brings it closer to the behavior on Linux. See :ghpull:`12984`.
767 793
768 794 Miscellaneous
769 795 ~~~~~~~~~~~~~
770 796 - Non-text formatters are not disabled in the terminal, which should simplify
771 797 writing extensions displaying images or other mimetypes in supporting terminals.
772 798 :ghpull:`12315`
773 799 - It is now possible to automatically insert matching brackets in Terminal IPython using the
774 800 ``TerminalInteractiveShell.auto_match=True`` option. :ghpull:`12586`
775 801 - We are thinking of deprecating the current ``%%javascript`` magic in favor of a better replacement. See :ghpull:`13376`.
776 802 - ``~`` is now expanded when part of a path in most magics :ghpull:`13385`
777 803 - ``%/%%timeit`` magic now adds a comma every thousands to make reading a long number easier :ghpull:`13379`
778 804 - ``"info"`` messages can now be customised to hide some fields :ghpull:`13343`
779 805 - ``collections.UserList`` now pretty-prints :ghpull:`13320`
780 806 - The debugger now has a persistent history, which should make it less
781 807 annoying to retype commands :ghpull:`13246`
782 808 - ``!pip`` ``!conda`` ``!cd`` or ``!ls`` are likely doing the wrong thing. We
783 809 now warn users if they use one of those commands. :ghpull:`12954`
784 810 - Make ``%precision`` work for ``numpy.float64`` type :ghpull:`12902`
785 811
786 812 Re-added support for XDG config directories
787 813 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
788 814
789 815 XDG support through the years comes and goes. There is a tension between having
790 816 an identical location for configuration in all platforms versus having simple instructions.
791 817 After initial failures a couple of years ago, IPython was modified to automatically migrate XDG
792 818 config files back into ``~/.ipython``. That migration code has now been removed.
793 819 IPython now checks the XDG locations, so if you _manually_ move your config
794 820 files to your preferred location, IPython will not move them back.
795 821
796 822
797 823 Preparing for Python 3.10
798 824 -------------------------
799 825
800 826 To prepare for Python 3.10, we have started working on removing reliance and
801 827 any dependency that is not compatible with Python 3.10. This includes migrating our
802 828 test suite to pytest and starting to remove nose. This also means that the
803 829 ``iptest`` command is now gone and all testing is via pytest.
804 830
805 831 This was in large part thanks to the NumFOCUS Small Developer grant, which enabled us to
806 832 allocate \$4000 to hire `Nikita Kniazev (@Kojoley) <https://github.com/Kojoley>`_,
807 833 who did a fantastic job at updating our code base, migrating to pytest, pushing
808 834 our coverage, and fixing a large number of bugs. I highly recommend contacting
809 835 them if you need help with C++ and Python projects.
810 836
811 837 You can find all relevant issues and PRs with `the SDG 2021 tag <https://github.com/ipython/ipython/issues?q=label%3A%22Numfocus+SDG+2021%22+>`__
812 838
813 839 Removing support for older Python versions
814 840 ------------------------------------------
815 841
816 842
817 843 We are removing support for Python up through 3.7, allowing internal code to use the more
818 844 efficient ``pathlib`` and to make better use of type annotations.
819 845
820 846 .. image:: ../_images/8.0/pathlib_pathlib_everywhere.jpg
821 847 :alt: "Meme image of Toy Story with Woody and Buzz, with the text 'pathlib, pathlib everywhere'"
822 848
823 849
824 850 We had about 34 PRs only to update some logic to update some functions from managing strings to
825 851 using Pathlib.
826 852
827 853 The completer has also seen significant updates and now makes use of newer Jedi APIs,
828 854 offering faster and more reliable tab completion.
829 855
830 856 Misc Statistics
831 857 ---------------
832 858
833 859 Here are some numbers::
834 860
835 861 7.x: 296 files, 12561 blank lines, 20282 comments, 35142 line of code.
836 862 8.0: 252 files, 12053 blank lines, 19232 comments, 34505 line of code.
837 863
838 864 $ git diff --stat 7.x...master | tail -1
839 865 340 files changed, 13399 insertions(+), 12421 deletions(-)
840 866
841 867 We have commits from 162 authors, who contributed 1916 commits in 23 month, excluding merges (to not bias toward
842 868 maintainers pushing buttons).::
843 869
844 870 $ git shortlog -s --no-merges 7.x...master | sort -nr
845 871 535 Matthias Bussonnier
846 872 86 Nikita Kniazev
847 873 69 Blazej Michalik
848 874 49 Samuel Gaist
849 875 27 Itamar Turner-Trauring
850 876 18 Spas Kalaydzhisyki
851 877 17 Thomas Kluyver
852 878 17 Quentin Peter
853 879 17 James Morris
854 880 17 Artur Svistunov
855 881 15 Bart Skowron
856 882 14 Alex Hall
857 883 13 rushabh-v
858 884 13 Terry Davis
859 885 13 Benjamin Ragan-Kelley
860 886 8 martinRenou
861 887 8 farisachugthai
862 888 7 dswij
863 889 7 Gal B
864 890 7 Corentin Cadiou
865 891 6 yuji96
866 892 6 Martin Skarzynski
867 893 6 Justin Palmer
868 894 6 Daniel Goldfarb
869 895 6 Ben Greiner
870 896 5 Sammy Al Hashemi
871 897 5 Paul Ivanov
872 898 5 Inception95
873 899 5 Eyenpi
874 900 5 Douglas Blank
875 901 5 Coco Mishra
876 902 5 Bibo Hao
877 903 5 André A. Gomes
878 904 5 Ahmed Fasih
879 905 4 takuya fujiwara
880 906 4 palewire
881 907 4 Thomas A Caswell
882 908 4 Talley Lambert
883 909 4 Scott Sanderson
884 910 4 Ram Rachum
885 911 4 Nick Muoh
886 912 4 Nathan Goldbaum
887 913 4 Mithil Poojary
888 914 4 Michael T
889 915 4 Jakub Klus
890 916 4 Ian Castleden
891 917 4 Eli Rykoff
892 918 4 Ashwin Vishnu
893 919 3 谭九鼎
894 920 3 sleeping
895 921 3 Sylvain Corlay
896 922 3 Peter Corke
897 923 3 Paul Bissex
898 924 3 Matthew Feickert
899 925 3 Fernando Perez
900 926 3 Eric Wieser
901 927 3 Daniel Mietchen
902 928 3 Aditya Sathe
903 929 3 007vedant
904 930 2 rchiodo
905 931 2 nicolaslazo
906 932 2 luttik
907 933 2 gorogoroumaru
908 934 2 foobarbyte
909 935 2 bar-hen
910 936 2 Theo Ouzhinski
911 937 2 Strawkage
912 938 2 Samreen Zarroug
913 939 2 Pete Blois
914 940 2 Meysam Azad
915 941 2 Matthieu Ancellin
916 942 2 Mark Schmitz
917 943 2 Maor Kleinberger
918 944 2 MRCWirtz
919 945 2 Lumir Balhar
920 946 2 Julien Rabinow
921 947 2 Juan Luis Cano Rodríguez
922 948 2 Joyce Er
923 949 2 Jakub
924 950 2 Faris A Chugthai
925 951 2 Ethan Madden
926 952 2 Dimitri Papadopoulos
927 953 2 Diego Fernandez
928 954 2 Daniel Shimon
929 955 2 Coco Bennett
930 956 2 Carlos Cordoba
931 957 2 Boyuan Liu
932 958 2 BaoGiang HoangVu
933 959 2 Augusto
934 960 2 Arthur Svistunov
935 961 2 Arthur Moreira
936 962 2 Ali Nabipour
937 963 2 Adam Hackbarth
938 964 1 richard
939 965 1 linar-jether
940 966 1 lbennett
941 967 1 juacrumar
942 968 1 gpotter2
943 969 1 digitalvirtuoso
944 970 1 dalthviz
945 971 1 Yonatan Goldschmidt
946 972 1 Tomasz Kłoczko
947 973 1 Tobias Bengfort
948 974 1 Timur Kushukov
949 975 1 Thomas
950 976 1 Snir Broshi
951 977 1 Shao Yang Hong
952 978 1 Sanjana-03
953 979 1 Romulo Filho
954 980 1 Rodolfo Carvalho
955 981 1 Richard Shadrach
956 982 1 Reilly Tucker Siemens
957 983 1 Rakessh Roshan
958 984 1 Piers Titus van der Torren
959 985 1 PhanatosZou
960 986 1 Pavel Safronov
961 987 1 Paulo S. Costa
962 988 1 Paul McCarthy
963 989 1 NotWearingPants
964 990 1 Naelson Douglas
965 991 1 Michael Tiemann
966 992 1 Matt Wozniski
967 993 1 Markus Wageringel
968 994 1 Marcus Wirtz
969 995 1 Marcio Mazza
970 996 1 Lumír 'Frenzy' Balhar
971 997 1 Lightyagami1
972 998 1 Leon Anavi
973 999 1 LeafyLi
974 1000 1 L0uisJ0shua
975 1001 1 Kyle Cutler
976 1002 1 Krzysztof Cybulski
977 1003 1 Kevin Kirsche
978 1004 1 KIU Shueng Chuan
979 1005 1 Jonathan Slenders
980 1006 1 Jay Qi
981 1007 1 Jake VanderPlas
982 1008 1 Iwan Briquemont
983 1009 1 Hussaina Begum Nandyala
984 1010 1 Gordon Ball
985 1011 1 Gabriel Simonetto
986 1012 1 Frank Tobia
987 1013 1 Erik
988 1014 1 Elliott Sales de Andrade
989 1015 1 Daniel Hahler
990 1016 1 Dan Green-Leipciger
991 1017 1 Dan Green
992 1018 1 Damian Yurzola
993 1019 1 Coon, Ethan T
994 1020 1 Carol Willing
995 1021 1 Brian Lee
996 1022 1 Brendan Gerrity
997 1023 1 Blake Griffin
998 1024 1 Bastian Ebeling
999 1025 1 Bartosz Telenczuk
1000 1026 1 Ankitsingh6299
1001 1027 1 Andrew Port
1002 1028 1 Andrew J. Hesford
1003 1029 1 Albert Zhang
1004 1030 1 Adam Johnson
1005 1031
1006 1032 This does not, of course, represent non-code contributions, for which we are also grateful.
1007 1033
1008 1034
1009 1035 API Changes using Frappuccino
1010 1036 -----------------------------
1011 1037
1012 1038 This is an experimental exhaustive API difference using `Frappuccino <https://pypi.org/project/frappuccino/>`_
1013 1039
1014 1040
1015 1041 The following items are new in IPython 8.0 ::
1016 1042
1017 1043 + IPython.core.async_helpers.get_asyncio_loop()
1018 1044 + IPython.core.completer.Dict
1019 1045 + IPython.core.completer.Pattern
1020 1046 + IPython.core.completer.Sequence
1021 1047 + IPython.core.completer.__skip_doctest__
1022 1048 + IPython.core.debugger.Pdb.precmd(self, line)
1023 1049 + IPython.core.debugger.__skip_doctest__
1024 1050 + IPython.core.display.__getattr__(name)
1025 1051 + IPython.core.display.warn
1026 1052 + IPython.core.display_functions
1027 1053 + IPython.core.display_functions.DisplayHandle
1028 1054 + IPython.core.display_functions.DisplayHandle.display(self, obj, **kwargs)
1029 1055 + IPython.core.display_functions.DisplayHandle.update(self, obj, **kwargs)
1030 1056 + IPython.core.display_functions.__all__
1031 1057 + IPython.core.display_functions.__builtins__
1032 1058 + IPython.core.display_functions.__cached__
1033 1059 + IPython.core.display_functions.__doc__
1034 1060 + IPython.core.display_functions.__file__
1035 1061 + IPython.core.display_functions.__loader__
1036 1062 + IPython.core.display_functions.__name__
1037 1063 + IPython.core.display_functions.__package__
1038 1064 + IPython.core.display_functions.__spec__
1039 1065 + IPython.core.display_functions.b2a_hex
1040 1066 + IPython.core.display_functions.clear_output(wait=False)
1041 1067 + IPython.core.display_functions.display(*objs, include='None', exclude='None', metadata='None', transient='None', display_id='None', raw=False, clear=False, **kwargs)
1042 1068 + IPython.core.display_functions.publish_display_data(data, metadata='None', source='<deprecated>', *, transient='None', **kwargs)
1043 1069 + IPython.core.display_functions.update_display(obj, *, display_id, **kwargs)
1044 1070 + IPython.core.extensions.BUILTINS_EXTS
1045 1071 + IPython.core.inputtransformer2.has_sunken_brackets(tokens)
1046 1072 + IPython.core.interactiveshell.Callable
1047 1073 + IPython.core.interactiveshell.__annotations__
1048 1074 + IPython.core.ultratb.List
1049 1075 + IPython.core.ultratb.Tuple
1050 1076 + IPython.lib.pretty.CallExpression
1051 1077 + IPython.lib.pretty.CallExpression.factory(name)
1052 1078 + IPython.lib.pretty.RawStringLiteral
1053 1079 + IPython.lib.pretty.RawText
1054 1080 + IPython.terminal.debugger.TerminalPdb.do_interact(self, arg)
1055 1081 + IPython.terminal.embed.Set
1056 1082
1057 1083 The following items have been removed (or moved to superclass)::
1058 1084
1059 1085 - IPython.core.application.BaseIPythonApplication.initialize_subcommand
1060 1086 - IPython.core.completer.Sentinel
1061 1087 - IPython.core.completer.skip_doctest
1062 1088 - IPython.core.debugger.Tracer
1063 1089 - IPython.core.display.DisplayHandle
1064 1090 - IPython.core.display.DisplayHandle.display
1065 1091 - IPython.core.display.DisplayHandle.update
1066 1092 - IPython.core.display.b2a_hex
1067 1093 - IPython.core.display.clear_output
1068 1094 - IPython.core.display.display
1069 1095 - IPython.core.display.publish_display_data
1070 1096 - IPython.core.display.update_display
1071 1097 - IPython.core.excolors.Deprec
1072 1098 - IPython.core.excolors.ExceptionColors
1073 1099 - IPython.core.history.warn
1074 1100 - IPython.core.hooks.late_startup_hook
1075 1101 - IPython.core.hooks.pre_run_code_hook
1076 1102 - IPython.core.hooks.shutdown_hook
1077 1103 - IPython.core.interactiveshell.InteractiveShell.init_deprecation_warnings
1078 1104 - IPython.core.interactiveshell.InteractiveShell.init_readline
1079 1105 - IPython.core.interactiveshell.InteractiveShell.write
1080 1106 - IPython.core.interactiveshell.InteractiveShell.write_err
1081 1107 - IPython.core.interactiveshell.get_default_colors
1082 1108 - IPython.core.interactiveshell.removed_co_newlocals
1083 1109 - IPython.core.magics.execution.ExecutionMagics.profile_missing_notice
1084 1110 - IPython.core.magics.script.PIPE
1085 1111 - IPython.core.prefilter.PrefilterManager.init_transformers
1086 1112 - IPython.core.release.classifiers
1087 1113 - IPython.core.release.description
1088 1114 - IPython.core.release.keywords
1089 1115 - IPython.core.release.long_description
1090 1116 - IPython.core.release.name
1091 1117 - IPython.core.release.platforms
1092 1118 - IPython.core.release.url
1093 1119 - IPython.core.ultratb.VerboseTB.format_records
1094 1120 - IPython.core.ultratb.find_recursion
1095 1121 - IPython.core.ultratb.findsource
1096 1122 - IPython.core.ultratb.fix_frame_records_filenames
1097 1123 - IPython.core.ultratb.inspect_error
1098 1124 - IPython.core.ultratb.is_recursion_error
1099 1125 - IPython.core.ultratb.with_patch_inspect
1100 1126 - IPython.external.__all__
1101 1127 - IPython.external.__builtins__
1102 1128 - IPython.external.__cached__
1103 1129 - IPython.external.__doc__
1104 1130 - IPython.external.__file__
1105 1131 - IPython.external.__loader__
1106 1132 - IPython.external.__name__
1107 1133 - IPython.external.__package__
1108 1134 - IPython.external.__path__
1109 1135 - IPython.external.__spec__
1110 1136 - IPython.kernel.KernelConnectionInfo
1111 1137 - IPython.kernel.__builtins__
1112 1138 - IPython.kernel.__cached__
1113 1139 - IPython.kernel.__warningregistry__
1114 1140 - IPython.kernel.pkg
1115 1141 - IPython.kernel.protocol_version
1116 1142 - IPython.kernel.protocol_version_info
1117 1143 - IPython.kernel.src
1118 1144 - IPython.kernel.version_info
1119 1145 - IPython.kernel.warn
1120 1146 - IPython.lib.backgroundjobs
1121 1147 - IPython.lib.backgroundjobs.BackgroundJobBase
1122 1148 - IPython.lib.backgroundjobs.BackgroundJobBase.run
1123 1149 - IPython.lib.backgroundjobs.BackgroundJobBase.traceback
1124 1150 - IPython.lib.backgroundjobs.BackgroundJobExpr
1125 1151 - IPython.lib.backgroundjobs.BackgroundJobExpr.call
1126 1152 - IPython.lib.backgroundjobs.BackgroundJobFunc
1127 1153 - IPython.lib.backgroundjobs.BackgroundJobFunc.call
1128 1154 - IPython.lib.backgroundjobs.BackgroundJobManager
1129 1155 - IPython.lib.backgroundjobs.BackgroundJobManager.flush
1130 1156 - IPython.lib.backgroundjobs.BackgroundJobManager.new
1131 1157 - IPython.lib.backgroundjobs.BackgroundJobManager.remove
1132 1158 - IPython.lib.backgroundjobs.BackgroundJobManager.result
1133 1159 - IPython.lib.backgroundjobs.BackgroundJobManager.status
1134 1160 - IPython.lib.backgroundjobs.BackgroundJobManager.traceback
1135 1161 - IPython.lib.backgroundjobs.__builtins__
1136 1162 - IPython.lib.backgroundjobs.__cached__
1137 1163 - IPython.lib.backgroundjobs.__doc__
1138 1164 - IPython.lib.backgroundjobs.__file__
1139 1165 - IPython.lib.backgroundjobs.__loader__
1140 1166 - IPython.lib.backgroundjobs.__name__
1141 1167 - IPython.lib.backgroundjobs.__package__
1142 1168 - IPython.lib.backgroundjobs.__spec__
1143 1169 - IPython.lib.kernel.__builtins__
1144 1170 - IPython.lib.kernel.__cached__
1145 1171 - IPython.lib.kernel.__doc__
1146 1172 - IPython.lib.kernel.__file__
1147 1173 - IPython.lib.kernel.__loader__
1148 1174 - IPython.lib.kernel.__name__
1149 1175 - IPython.lib.kernel.__package__
1150 1176 - IPython.lib.kernel.__spec__
1151 1177 - IPython.lib.kernel.__warningregistry__
1152 1178 - IPython.paths.fs_encoding
1153 1179 - IPython.terminal.debugger.DEFAULT_BUFFER
1154 1180 - IPython.terminal.debugger.cursor_in_leading_ws
1155 1181 - IPython.terminal.debugger.emacs_insert_mode
1156 1182 - IPython.terminal.debugger.has_selection
1157 1183 - IPython.terminal.debugger.vi_insert_mode
1158 1184 - IPython.terminal.interactiveshell.DISPLAY_BANNER_DEPRECATED
1159 1185 - IPython.terminal.ipapp.TerminalIPythonApp.parse_command_line
1160 1186 - IPython.testing.test
1161 1187 - IPython.utils.contexts.NoOpContext
1162 1188 - IPython.utils.io.IOStream
1163 1189 - IPython.utils.io.IOStream.close
1164 1190 - IPython.utils.io.IOStream.write
1165 1191 - IPython.utils.io.IOStream.writelines
1166 1192 - IPython.utils.io.__warningregistry__
1167 1193 - IPython.utils.io.atomic_writing
1168 1194 - IPython.utils.io.stderr
1169 1195 - IPython.utils.io.stdin
1170 1196 - IPython.utils.io.stdout
1171 1197 - IPython.utils.io.unicode_std_stream
1172 1198 - IPython.utils.path.get_ipython_cache_dir
1173 1199 - IPython.utils.path.get_ipython_dir
1174 1200 - IPython.utils.path.get_ipython_module_path
1175 1201 - IPython.utils.path.get_ipython_package_dir
1176 1202 - IPython.utils.path.locate_profile
1177 1203 - IPython.utils.path.unquote_filename
1178 1204 - IPython.utils.py3compat.PY2
1179 1205 - IPython.utils.py3compat.PY3
1180 1206 - IPython.utils.py3compat.buffer_to_bytes
1181 1207 - IPython.utils.py3compat.builtin_mod_name
1182 1208 - IPython.utils.py3compat.cast_bytes
1183 1209 - IPython.utils.py3compat.getcwd
1184 1210 - IPython.utils.py3compat.isidentifier
1185 1211 - IPython.utils.py3compat.u_format
1186 1212
1187 1213 The following signatures differ between 7.x and 8.0::
1188 1214
1189 1215 - IPython.core.completer.IPCompleter.unicode_name_matches(self, text)
1190 1216 + IPython.core.completer.IPCompleter.unicode_name_matches(text)
1191 1217
1192 1218 - IPython.core.completer.match_dict_keys(keys, prefix, delims)
1193 1219 + IPython.core.completer.match_dict_keys(keys, prefix, delims, extra_prefix='None')
1194 1220
1195 1221 - IPython.core.interactiveshell.InteractiveShell.object_inspect_mime(self, oname, detail_level=0)
1196 1222 + IPython.core.interactiveshell.InteractiveShell.object_inspect_mime(self, oname, detail_level=0, omit_sections='()')
1197 1223
1198 1224 - IPython.core.interactiveshell.InteractiveShell.set_hook(self, name, hook, priority=50, str_key='None', re_key='None', _warn_deprecated=True)
1199 1225 + IPython.core.interactiveshell.InteractiveShell.set_hook(self, name, hook, priority=50, str_key='None', re_key='None')
1200 1226
1201 1227 - IPython.core.oinspect.Inspector.info(self, obj, oname='', formatter='None', info='None', detail_level=0)
1202 1228 + IPython.core.oinspect.Inspector.info(self, obj, oname='', info='None', detail_level=0)
1203 1229
1204 1230 - IPython.core.oinspect.Inspector.pinfo(self, obj, oname='', formatter='None', info='None', detail_level=0, enable_html_pager=True)
1205 1231 + IPython.core.oinspect.Inspector.pinfo(self, obj, oname='', formatter='None', info='None', detail_level=0, enable_html_pager=True, omit_sections='()')
1206 1232
1207 1233 - IPython.core.profiledir.ProfileDir.copy_config_file(self, config_file, path='None', overwrite=False)
1208 1234 + IPython.core.profiledir.ProfileDir.copy_config_file(self, config_file, path, overwrite=False)
1209 1235
1210 1236 - IPython.core.ultratb.VerboseTB.format_record(self, frame, file, lnum, func, lines, index)
1211 1237 + IPython.core.ultratb.VerboseTB.format_record(self, frame_info)
1212 1238
1213 1239 - IPython.terminal.embed.InteractiveShellEmbed.mainloop(self, local_ns='None', module='None', stack_depth=0, display_banner='None', global_ns='None', compile_flags='None')
1214 1240 + IPython.terminal.embed.InteractiveShellEmbed.mainloop(self, local_ns='None', module='None', stack_depth=0, compile_flags='None')
1215 1241
1216 1242 - IPython.terminal.embed.embed(**kwargs)
1217 1243 + IPython.terminal.embed.embed(*, header='', compile_flags='None', **kwargs)
1218 1244
1219 1245 - IPython.terminal.interactiveshell.TerminalInteractiveShell.interact(self, display_banner='<object object at 0xffffff>')
1220 1246 + IPython.terminal.interactiveshell.TerminalInteractiveShell.interact(self)
1221 1247
1222 1248 - IPython.terminal.interactiveshell.TerminalInteractiveShell.mainloop(self, display_banner='<object object at 0xffffff>')
1223 1249 + IPython.terminal.interactiveshell.TerminalInteractiveShell.mainloop(self)
1224 1250
1225 1251 - IPython.utils.path.get_py_filename(name, force_win32='None')
1226 1252 + IPython.utils.path.get_py_filename(name)
1227 1253
1228 1254 The following are new attributes (that might be inherited)::
1229 1255
1230 1256 + IPython.core.completer.IPCompleter.unicode_names
1231 1257 + IPython.core.debugger.InterruptiblePdb.precmd
1232 1258 + IPython.core.debugger.Pdb.precmd
1233 1259 + IPython.core.ultratb.AutoFormattedTB.has_colors
1234 1260 + IPython.core.ultratb.ColorTB.has_colors
1235 1261 + IPython.core.ultratb.FormattedTB.has_colors
1236 1262 + IPython.core.ultratb.ListTB.has_colors
1237 1263 + IPython.core.ultratb.SyntaxTB.has_colors
1238 1264 + IPython.core.ultratb.TBTools.has_colors
1239 1265 + IPython.core.ultratb.VerboseTB.has_colors
1240 1266 + IPython.terminal.debugger.TerminalPdb.do_interact
1241 1267 + IPython.terminal.debugger.TerminalPdb.precmd
1242 1268
1243 1269 The following attribute/methods have been removed::
1244 1270
1245 1271 - IPython.core.application.BaseIPythonApplication.deprecated_subcommands
1246 1272 - IPython.core.ultratb.AutoFormattedTB.format_records
1247 1273 - IPython.core.ultratb.ColorTB.format_records
1248 1274 - IPython.core.ultratb.FormattedTB.format_records
1249 1275 - IPython.terminal.embed.InteractiveShellEmbed.init_deprecation_warnings
1250 1276 - IPython.terminal.embed.InteractiveShellEmbed.init_readline
1251 1277 - IPython.terminal.embed.InteractiveShellEmbed.write
1252 1278 - IPython.terminal.embed.InteractiveShellEmbed.write_err
1253 1279 - IPython.terminal.interactiveshell.TerminalInteractiveShell.init_deprecation_warnings
1254 1280 - IPython.terminal.interactiveshell.TerminalInteractiveShell.init_readline
1255 1281 - IPython.terminal.interactiveshell.TerminalInteractiveShell.write
1256 1282 - IPython.terminal.interactiveshell.TerminalInteractiveShell.write_err
1257 1283 - IPython.terminal.ipapp.LocateIPythonApp.deprecated_subcommands
1258 1284 - IPython.terminal.ipapp.LocateIPythonApp.initialize_subcommand
1259 1285 - IPython.terminal.ipapp.TerminalIPythonApp.deprecated_subcommands
1260 1286 - IPython.terminal.ipapp.TerminalIPythonApp.initialize_subcommand
@@ -1,123 +1,120 b''
1 1 [metadata]
2 2 name = ipython
3 3 version = attr: IPython.core.release.__version__
4 4 url = https://ipython.org
5 5 description = IPython: Productive Interactive Computing
6 6 long_description_content_type = text/x-rst
7 7 long_description = file: long_description.rst
8 8 license_file = LICENSE
9 9 project_urls =
10 10 Documentation = https://ipython.readthedocs.io/
11 11 Funding = https://numfocus.org/
12 12 Source = https://github.com/ipython/ipython
13 13 Tracker = https://github.com/ipython/ipython/issues
14 14 keywords = Interactive, Interpreter, Shell, Embedding
15 15 platforms = Linux, Mac OSX, Windows
16 16 classifiers =
17 17 Framework :: IPython
18 18 Framework :: Jupyter
19 19 Intended Audience :: Developers
20 20 Intended Audience :: Science/Research
21 21 License :: OSI Approved :: BSD License
22 22 Programming Language :: Python
23 23 Programming Language :: Python :: 3
24 24 Programming Language :: Python :: 3 :: Only
25 25 Topic :: System :: Shells
26 26
27 27 [options]
28 28 packages = find:
29 29 python_requires = >=3.8
30 30 zip_safe = False
31 31 install_requires =
32 32 appnope; sys_platform == "darwin"
33 33 backcall
34 34 colorama; sys_platform == "win32"
35 35 decorator
36 36 jedi>=0.16
37 37 matplotlib-inline
38 38 pexpect>4.3; sys_platform != "win32"
39 39 pickleshare
40 prompt_toolkit>3.0.1,<3.1.0
40 prompt_toolkit>=3.0.11,<3.1.0
41 41 pygments>=2.4.0
42 42 stack_data
43 43 traitlets>=5
44 44
45 45 [options.extras_require]
46 46 black =
47 47 black
48 48 doc =
49 49 ipykernel
50 50 setuptools>=18.5
51 51 sphinx>=1.3
52 52 sphinx-rtd-theme
53 53 docrepr
54 54 matplotlib
55 55 stack_data
56 56 pytest<7
57 57 typing_extensions
58 58 %(test)s
59 59 kernel =
60 60 ipykernel
61 61 nbconvert =
62 62 nbconvert
63 63 nbformat =
64 64 nbformat
65 65 notebook =
66 66 ipywidgets
67 67 notebook
68 68 parallel =
69 69 ipyparallel
70 70 qtconsole =
71 71 qtconsole
72 72 terminal =
73 73 test =
74 74 pytest<7.1
75 75 pytest-asyncio
76 76 testpath
77 77 test_extra =
78 78 %(test)s
79 79 curio
80 80 matplotlib!=3.2.0
81 81 nbformat
82 82 numpy>=1.20
83 83 pandas
84 84 trio
85 85 all =
86 86 %(black)s
87 87 %(doc)s
88 88 %(kernel)s
89 89 %(nbconvert)s
90 90 %(nbformat)s
91 91 %(notebook)s
92 92 %(parallel)s
93 93 %(qtconsole)s
94 94 %(terminal)s
95 95 %(test_extra)s
96 96 %(test)s
97 97
98 98 [options.packages.find]
99 99 exclude =
100 100 setupext
101 101
102 102 [options.package_data]
103 103 IPython.core = profile/README*
104 104 IPython.core.tests = *.png, *.jpg, daft_extension/*.py
105 105 IPython.lib.tests = *.wav
106 106 IPython.testing.plugin = *.txt
107 107
108 108 [options.entry_points]
109 console_scripts =
110 ipython = IPython:start_ipython
111 ipython3 = IPython:start_ipython
112 109 pygments.lexers =
113 110 ipythonconsole = IPython.lib.lexers:IPythonConsoleLexer
114 111 ipython = IPython.lib.lexers:IPythonLexer
115 112 ipython3 = IPython.lib.lexers:IPython3Lexer
116 113
117 114 [velin]
118 115 ignore_patterns =
119 116 IPython/core/tests
120 117 IPython/testing
121 118
122 119 [tool.black]
123 120 exclude = 'timing\.py'
@@ -1,148 +1,149 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Setup script for IPython.
3 3
4 4 Under Posix environments it works like a typical setup.py script.
5 5 Under Windows, the command sdist is not supported, since IPython
6 6 requires utilities which are not available under Windows."""
7 7
8 8 #-----------------------------------------------------------------------------
9 9 # Copyright (c) 2008-2011, IPython Development Team.
10 10 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
11 11 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
12 12 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
13 13 #
14 14 # Distributed under the terms of the Modified BSD License.
15 15 #
16 16 # The full license is in the file COPYING.rst, distributed with this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 import os
20 20 import sys
21 21
22 22 # **Python version check**
23 23 #
24 24 # This check is also made in IPython/__init__, don't forget to update both when
25 25 # changing Python version requirements.
26 26 if sys.version_info < (3, 8):
27 27 pip_message = 'This may be due to an out of date pip. Make sure you have pip >= 9.0.1.'
28 28 try:
29 29 import pip
30 30 pip_version = tuple([int(x) for x in pip.__version__.split('.')[:3]])
31 31 if pip_version < (9, 0, 1) :
32 32 pip_message = 'Your pip version is out of date, please install pip >= 9.0.1. '\
33 33 'pip {} detected.'.format(pip.__version__)
34 34 else:
35 35 # pip is new enough - it must be something else
36 36 pip_message = ''
37 37 except Exception:
38 38 pass
39 39
40 40
41 41 error = """
42 42 IPython 8+ supports Python 3.8 and above, following NEP 29.
43 43 When using Python 2.7, please install IPython 5.x LTS Long Term Support version.
44 44 Python 3.3 and 3.4 were supported up to IPython 6.x.
45 45 Python 3.5 was supported with IPython 7.0 to 7.9.
46 46 Python 3.6 was supported with IPython up to 7.16.
47 47 Python 3.7 was still supported with the 7.x branch.
48 48
49 49 See IPython `README.rst` file for more information:
50 50
51 51 https://github.com/ipython/ipython/blob/main/README.rst
52 52
53 53 Python {py} detected.
54 54 {pip}
55 55 """.format(
56 56 py=sys.version_info, pip=pip_message
57 57 )
58 58
59 59 print(error, file=sys.stderr)
60 60 sys.exit(1)
61 61
62 62 # At least we're on the python version we need, move on.
63 63
64 64 from setuptools import setup
65 65
66 66 # Our own imports
67 67 sys.path.insert(0, ".")
68 68
69 from setupbase import target_update
69 from setupbase import target_update, find_entry_points
70 70
71 71 from setupbase import (
72 72 setup_args,
73 73 check_package_data_first,
74 74 find_data_files,
75 75 git_prebuild,
76 76 install_symlinked,
77 77 install_lib_symlink,
78 78 install_scripts_for_symlink,
79 79 unsymlink,
80 80 )
81 81
82 82 #-------------------------------------------------------------------------------
83 83 # Handle OS specific things
84 84 #-------------------------------------------------------------------------------
85 85
86 86 if os.name in ('nt','dos'):
87 87 os_name = 'windows'
88 88 else:
89 89 os_name = os.name
90 90
91 91 # Under Windows, 'sdist' has not been supported. Now that the docs build with
92 92 # Sphinx it might work, but let's not turn it on until someone confirms that it
93 93 # actually works.
94 94 if os_name == 'windows' and 'sdist' in sys.argv:
95 95 print('The sdist command is not available under Windows. Exiting.')
96 96 sys.exit(1)
97 97
98 98
99 99 #-------------------------------------------------------------------------------
100 100 # Things related to the IPython documentation
101 101 #-------------------------------------------------------------------------------
102 102
103 103 # update the manuals when building a source dist
104 104 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
105 105
106 106 # List of things to be updated. Each entry is a triplet of args for
107 107 # target_update()
108 108 to_update = [
109 109 (
110 110 "docs/man/ipython.1.gz",
111 111 ["docs/man/ipython.1"],
112 112 "cd docs/man && python -m gzip --best ipython.1",
113 113 ),
114 114 ]
115 115
116 116
117 117 [ target_update(*t) for t in to_update ]
118 118
119 119 #---------------------------------------------------------------------------
120 120 # Find all the packages, package data, and data_files
121 121 #---------------------------------------------------------------------------
122 122
123 123 data_files = find_data_files()
124 124
125 125 setup_args['data_files'] = data_files
126 126
127 127 #---------------------------------------------------------------------------
128 128 # custom distutils commands
129 129 #---------------------------------------------------------------------------
130 130 # imports here, so they are after setuptools import if there was one
131 131 from setuptools.command.sdist import sdist
132 132
133 133 setup_args['cmdclass'] = {
134 134 'build_py': \
135 135 check_package_data_first(git_prebuild('IPython')),
136 136 'sdist' : git_prebuild('IPython', sdist),
137 137 'symlink': install_symlinked,
138 138 'install_lib_symlink': install_lib_symlink,
139 139 'install_scripts_sym': install_scripts_for_symlink,
140 140 'unsymlink': unsymlink,
141 141 }
142 setup_args["entry_points"] = {"console_scripts": find_entry_points()}
142 143
143 144 #---------------------------------------------------------------------------
144 145 # Do the actual setup now
145 146 #---------------------------------------------------------------------------
146 147
147 148 if __name__ == "__main__":
148 149 setup(**setup_args)
General Comments 0
You need to be logged in to leave comments. Login now