##// END OF EJS Templates
Allow to dispatch getting documentation on objects...
Matthias Bussonnier -
Show More

The requested changes are too big and content was truncated. Show full diff

1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,1098 +1,1154 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tools for inspecting Python objects.
2 """Tools for inspecting Python objects.
3
3
4 Uses syntax highlighting for presenting the various information elements.
4 Uses syntax highlighting for presenting the various information elements.
5
5
6 Similar in spirit to the inspect module, but all calls take a name argument to
6 Similar in spirit to the inspect module, but all calls take a name argument to
7 reference the name under which an object is being read.
7 reference the name under which an object is being read.
8 """
8 """
9
9
10 # Copyright (c) IPython Development Team.
10 # Copyright (c) IPython Development Team.
11 # Distributed under the terms of the Modified BSD License.
11 # Distributed under the terms of the Modified BSD License.
12
12
13 __all__ = ['Inspector','InspectColors']
13 __all__ = ['Inspector','InspectColors']
14
14
15 # stdlib modules
15 # stdlib modules
16 import ast
16 from dataclasses import dataclass
17 import inspect
18 from inspect import signature
17 from inspect import signature
18 from textwrap import dedent
19 import ast
19 import html
20 import html
21 import inspect
22 import io as stdlib_io
20 import linecache
23 import linecache
21 import warnings
22 import os
24 import os
23 from textwrap import dedent
25 import sys
24 import types
26 import types
25 import io as stdlib_io
27 import warnings
26
28
27 from typing import Union
29 from typing import Any, Optional, Dict, Union, List, Tuple
30
31 if sys.version_info <= (3, 10):
32 from typing_extensions import TypeAlias
33 else:
34 from typing import TypeAlias
28
35
29 # IPython's own
36 # IPython's own
30 from IPython.core import page
37 from IPython.core import page
31 from IPython.lib.pretty import pretty
38 from IPython.lib.pretty import pretty
32 from IPython.testing.skipdoctest import skip_doctest
39 from IPython.testing.skipdoctest import skip_doctest
33 from IPython.utils import PyColorize
40 from IPython.utils import PyColorize
34 from IPython.utils import openpy
41 from IPython.utils import openpy
35 from IPython.utils.dir2 import safe_hasattr
42 from IPython.utils.dir2 import safe_hasattr
36 from IPython.utils.path import compress_user
43 from IPython.utils.path import compress_user
37 from IPython.utils.text import indent
44 from IPython.utils.text import indent
38 from IPython.utils.wildcard import list_namespace
45 from IPython.utils.wildcard import list_namespace
39 from IPython.utils.wildcard import typestr2type
46 from IPython.utils.wildcard import typestr2type
40 from IPython.utils.coloransi import TermColors, ColorScheme, ColorSchemeTable
47 from IPython.utils.coloransi import TermColors, ColorScheme, ColorSchemeTable
41 from IPython.utils.py3compat import cast_unicode
48 from IPython.utils.py3compat import cast_unicode
42 from IPython.utils.colorable import Colorable
49 from IPython.utils.colorable import Colorable
43 from IPython.utils.decorators import undoc
50 from IPython.utils.decorators import undoc
44
51
45 from pygments import highlight
52 from pygments import highlight
46 from pygments.lexers import PythonLexer
53 from pygments.lexers import PythonLexer
47 from pygments.formatters import HtmlFormatter
54 from pygments.formatters import HtmlFormatter
48
55
49 from typing import Any, Optional
56 HOOK_NAME = "__custom_documentations__"
50 from dataclasses import dataclass
57
58
59 UnformattedBundle: TypeAlias = Dict[str, List[Tuple[str, str]]] # List of (title, body)
60 Bundle: TypeAlias = Dict[str, str]
51
61
52
62
53 @dataclass
63 @dataclass
54 class OInfo:
64 class OInfo:
55 ismagic: bool
65 ismagic: bool
56 isalias: bool
66 isalias: bool
57 found: bool
67 found: bool
58 namespace: Optional[str]
68 namespace: Optional[str]
59 parent: Any
69 parent: Any
60 obj: Any
70 obj: Any
61
71
62 def pylight(code):
72 def pylight(code):
63 return highlight(code, PythonLexer(), HtmlFormatter(noclasses=True))
73 return highlight(code, PythonLexer(), HtmlFormatter(noclasses=True))
64
74
65 # builtin docstrings to ignore
75 # builtin docstrings to ignore
66 _func_call_docstring = types.FunctionType.__call__.__doc__
76 _func_call_docstring = types.FunctionType.__call__.__doc__
67 _object_init_docstring = object.__init__.__doc__
77 _object_init_docstring = object.__init__.__doc__
68 _builtin_type_docstrings = {
78 _builtin_type_docstrings = {
69 inspect.getdoc(t) for t in (types.ModuleType, types.MethodType,
79 inspect.getdoc(t) for t in (types.ModuleType, types.MethodType,
70 types.FunctionType, property)
80 types.FunctionType, property)
71 }
81 }
72
82
73 _builtin_func_type = type(all)
83 _builtin_func_type = type(all)
74 _builtin_meth_type = type(str.upper) # Bound methods have the same type as builtin functions
84 _builtin_meth_type = type(str.upper) # Bound methods have the same type as builtin functions
75 #****************************************************************************
85 #****************************************************************************
76 # Builtin color schemes
86 # Builtin color schemes
77
87
78 Colors = TermColors # just a shorthand
88 Colors = TermColors # just a shorthand
79
89
80 InspectColors = PyColorize.ANSICodeColors
90 InspectColors = PyColorize.ANSICodeColors
81
91
82 #****************************************************************************
92 #****************************************************************************
83 # Auxiliary functions and objects
93 # Auxiliary functions and objects
84
94
85 # See the messaging spec for the definition of all these fields. This list
95 # See the messaging spec for the definition of all these fields. This list
86 # effectively defines the order of display
96 # effectively defines the order of display
87 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
97 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
88 'length', 'file', 'definition', 'docstring', 'source',
98 'length', 'file', 'definition', 'docstring', 'source',
89 'init_definition', 'class_docstring', 'init_docstring',
99 'init_definition', 'class_docstring', 'init_docstring',
90 'call_def', 'call_docstring',
100 'call_def', 'call_docstring',
91 # These won't be printed but will be used to determine how to
101 # These won't be printed but will be used to determine how to
92 # format the object
102 # format the object
93 'ismagic', 'isalias', 'isclass', 'found', 'name'
103 'ismagic', 'isalias', 'isclass', 'found', 'name'
94 ]
104 ]
95
105
96
106
97 def object_info(**kw):
107 def object_info(**kw):
98 """Make an object info dict with all fields present."""
108 """Make an object info dict with all fields present."""
99 infodict = {k:None for k in info_fields}
109 infodict = {k:None for k in info_fields}
100 infodict.update(kw)
110 infodict.update(kw)
101 return infodict
111 return infodict
102
112
103
113
104 def get_encoding(obj):
114 def get_encoding(obj):
105 """Get encoding for python source file defining obj
115 """Get encoding for python source file defining obj
106
116
107 Returns None if obj is not defined in a sourcefile.
117 Returns None if obj is not defined in a sourcefile.
108 """
118 """
109 ofile = find_file(obj)
119 ofile = find_file(obj)
110 # run contents of file through pager starting at line where the object
120 # run contents of file through pager starting at line where the object
111 # is defined, as long as the file isn't binary and is actually on the
121 # is defined, as long as the file isn't binary and is actually on the
112 # filesystem.
122 # filesystem.
113 if ofile is None:
123 if ofile is None:
114 return None
124 return None
115 elif ofile.endswith(('.so', '.dll', '.pyd')):
125 elif ofile.endswith(('.so', '.dll', '.pyd')):
116 return None
126 return None
117 elif not os.path.isfile(ofile):
127 elif not os.path.isfile(ofile):
118 return None
128 return None
119 else:
129 else:
120 # Print only text files, not extension binaries. Note that
130 # Print only text files, not extension binaries. Note that
121 # getsourcelines returns lineno with 1-offset and page() uses
131 # getsourcelines returns lineno with 1-offset and page() uses
122 # 0-offset, so we must adjust.
132 # 0-offset, so we must adjust.
123 with stdlib_io.open(ofile, 'rb') as buffer: # Tweaked to use io.open for Python 2
133 with stdlib_io.open(ofile, 'rb') as buffer: # Tweaked to use io.open for Python 2
124 encoding, lines = openpy.detect_encoding(buffer.readline)
134 encoding, lines = openpy.detect_encoding(buffer.readline)
125 return encoding
135 return encoding
126
136
127 def getdoc(obj) -> Union[str,None]:
137 def getdoc(obj) -> Union[str,None]:
128 """Stable wrapper around inspect.getdoc.
138 """Stable wrapper around inspect.getdoc.
129
139
130 This can't crash because of attribute problems.
140 This can't crash because of attribute problems.
131
141
132 It also attempts to call a getdoc() method on the given object. This
142 It also attempts to call a getdoc() method on the given object. This
133 allows objects which provide their docstrings via non-standard mechanisms
143 allows objects which provide their docstrings via non-standard mechanisms
134 (like Pyro proxies) to still be inspected by ipython's ? system.
144 (like Pyro proxies) to still be inspected by ipython's ? system.
135 """
145 """
136 # Allow objects to offer customized documentation via a getdoc method:
146 # Allow objects to offer customized documentation via a getdoc method:
137 try:
147 try:
138 ds = obj.getdoc()
148 ds = obj.getdoc()
139 except Exception:
149 except Exception:
140 pass
150 pass
141 else:
151 else:
142 if isinstance(ds, str):
152 if isinstance(ds, str):
143 return inspect.cleandoc(ds)
153 return inspect.cleandoc(ds)
144 docstr = inspect.getdoc(obj)
154 docstr = inspect.getdoc(obj)
145 return docstr
155 return docstr
146
156
147
157
148 def getsource(obj, oname='') -> Union[str,None]:
158 def getsource(obj, oname='') -> Union[str,None]:
149 """Wrapper around inspect.getsource.
159 """Wrapper around inspect.getsource.
150
160
151 This can be modified by other projects to provide customized source
161 This can be modified by other projects to provide customized source
152 extraction.
162 extraction.
153
163
154 Parameters
164 Parameters
155 ----------
165 ----------
156 obj : object
166 obj : object
157 an object whose source code we will attempt to extract
167 an object whose source code we will attempt to extract
158 oname : str
168 oname : str
159 (optional) a name under which the object is known
169 (optional) a name under which the object is known
160
170
161 Returns
171 Returns
162 -------
172 -------
163 src : unicode or None
173 src : unicode or None
164
174
165 """
175 """
166
176
167 if isinstance(obj, property):
177 if isinstance(obj, property):
168 sources = []
178 sources = []
169 for attrname in ['fget', 'fset', 'fdel']:
179 for attrname in ['fget', 'fset', 'fdel']:
170 fn = getattr(obj, attrname)
180 fn = getattr(obj, attrname)
171 if fn is not None:
181 if fn is not None:
172 encoding = get_encoding(fn)
182 encoding = get_encoding(fn)
173 oname_prefix = ('%s.' % oname) if oname else ''
183 oname_prefix = ('%s.' % oname) if oname else ''
174 sources.append(''.join(('# ', oname_prefix, attrname)))
184 sources.append(''.join(('# ', oname_prefix, attrname)))
175 if inspect.isfunction(fn):
185 if inspect.isfunction(fn):
176 _src = getsource(fn)
186 _src = getsource(fn)
177 if _src:
187 if _src:
178 # assert _src is not None, "please mypy"
188 # assert _src is not None, "please mypy"
179 sources.append(dedent(_src))
189 sources.append(dedent(_src))
180 else:
190 else:
181 # Default str/repr only prints function name,
191 # Default str/repr only prints function name,
182 # pretty.pretty prints module name too.
192 # pretty.pretty prints module name too.
183 sources.append(
193 sources.append(
184 '%s%s = %s\n' % (oname_prefix, attrname, pretty(fn))
194 '%s%s = %s\n' % (oname_prefix, attrname, pretty(fn))
185 )
195 )
186 if sources:
196 if sources:
187 return '\n'.join(sources)
197 return '\n'.join(sources)
188 else:
198 else:
189 return None
199 return None
190
200
191 else:
201 else:
192 # Get source for non-property objects.
202 # Get source for non-property objects.
193
203
194 obj = _get_wrapped(obj)
204 obj = _get_wrapped(obj)
195
205
196 try:
206 try:
197 src = inspect.getsource(obj)
207 src = inspect.getsource(obj)
198 except TypeError:
208 except TypeError:
199 # The object itself provided no meaningful source, try looking for
209 # The object itself provided no meaningful source, try looking for
200 # its class definition instead.
210 # its class definition instead.
201 try:
211 try:
202 src = inspect.getsource(obj.__class__)
212 src = inspect.getsource(obj.__class__)
203 except (OSError, TypeError):
213 except (OSError, TypeError):
204 return None
214 return None
205 except OSError:
215 except OSError:
206 return None
216 return None
207
217
208 return src
218 return src
209
219
210
220
211 def is_simple_callable(obj):
221 def is_simple_callable(obj):
212 """True if obj is a function ()"""
222 """True if obj is a function ()"""
213 return (inspect.isfunction(obj) or inspect.ismethod(obj) or \
223 return (inspect.isfunction(obj) or inspect.ismethod(obj) or \
214 isinstance(obj, _builtin_func_type) or isinstance(obj, _builtin_meth_type))
224 isinstance(obj, _builtin_func_type) or isinstance(obj, _builtin_meth_type))
215
225
216 @undoc
226 @undoc
217 def getargspec(obj):
227 def getargspec(obj):
218 """Wrapper around :func:`inspect.getfullargspec`
228 """Wrapper around :func:`inspect.getfullargspec`
219
229
220 In addition to functions and methods, this can also handle objects with a
230 In addition to functions and methods, this can also handle objects with a
221 ``__call__`` attribute.
231 ``__call__`` attribute.
222
232
223 DEPRECATED: Deprecated since 7.10. Do not use, will be removed.
233 DEPRECATED: Deprecated since 7.10. Do not use, will be removed.
224 """
234 """
225
235
226 warnings.warn('`getargspec` function is deprecated as of IPython 7.10'
236 warnings.warn('`getargspec` function is deprecated as of IPython 7.10'
227 'and will be removed in future versions.', DeprecationWarning, stacklevel=2)
237 'and will be removed in future versions.', DeprecationWarning, stacklevel=2)
228
238
229 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
239 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
230 obj = obj.__call__
240 obj = obj.__call__
231
241
232 return inspect.getfullargspec(obj)
242 return inspect.getfullargspec(obj)
233
243
234 @undoc
244 @undoc
235 def format_argspec(argspec):
245 def format_argspec(argspec):
236 """Format argspect, convenience wrapper around inspect's.
246 """Format argspect, convenience wrapper around inspect's.
237
247
238 This takes a dict instead of ordered arguments and calls
248 This takes a dict instead of ordered arguments and calls
239 inspect.format_argspec with the arguments in the necessary order.
249 inspect.format_argspec with the arguments in the necessary order.
240
250
241 DEPRECATED (since 7.10): Do not use; will be removed in future versions.
251 DEPRECATED (since 7.10): Do not use; will be removed in future versions.
242 """
252 """
243
253
244 warnings.warn('`format_argspec` function is deprecated as of IPython 7.10'
254 warnings.warn('`format_argspec` function is deprecated as of IPython 7.10'
245 'and will be removed in future versions.', DeprecationWarning, stacklevel=2)
255 'and will be removed in future versions.', DeprecationWarning, stacklevel=2)
246
256
247
257
248 return inspect.formatargspec(argspec['args'], argspec['varargs'],
258 return inspect.formatargspec(argspec['args'], argspec['varargs'],
249 argspec['varkw'], argspec['defaults'])
259 argspec['varkw'], argspec['defaults'])
250
260
251 @undoc
261 @undoc
252 def call_tip(oinfo, format_call=True):
262 def call_tip(oinfo, format_call=True):
253 """DEPRECATED since 6.0. Extract call tip data from an oinfo dict."""
263 """DEPRECATED since 6.0. Extract call tip data from an oinfo dict."""
254 warnings.warn(
264 warnings.warn(
255 "`call_tip` function is deprecated as of IPython 6.0"
265 "`call_tip` function is deprecated as of IPython 6.0"
256 "and will be removed in future versions.",
266 "and will be removed in future versions.",
257 DeprecationWarning,
267 DeprecationWarning,
258 stacklevel=2,
268 stacklevel=2,
259 )
269 )
260 # Get call definition
270 # Get call definition
261 argspec = oinfo.get('argspec')
271 argspec = oinfo.get('argspec')
262 if argspec is None:
272 if argspec is None:
263 call_line = None
273 call_line = None
264 else:
274 else:
265 # Callable objects will have 'self' as their first argument, prune
275 # Callable objects will have 'self' as their first argument, prune
266 # it out if it's there for clarity (since users do *not* pass an
276 # it out if it's there for clarity (since users do *not* pass an
267 # extra first argument explicitly).
277 # extra first argument explicitly).
268 try:
278 try:
269 has_self = argspec['args'][0] == 'self'
279 has_self = argspec['args'][0] == 'self'
270 except (KeyError, IndexError):
280 except (KeyError, IndexError):
271 pass
281 pass
272 else:
282 else:
273 if has_self:
283 if has_self:
274 argspec['args'] = argspec['args'][1:]
284 argspec['args'] = argspec['args'][1:]
275
285
276 call_line = oinfo['name']+format_argspec(argspec)
286 call_line = oinfo['name']+format_argspec(argspec)
277
287
278 # Now get docstring.
288 # Now get docstring.
279 # The priority is: call docstring, constructor docstring, main one.
289 # The priority is: call docstring, constructor docstring, main one.
280 doc = oinfo.get('call_docstring')
290 doc = oinfo.get('call_docstring')
281 if doc is None:
291 if doc is None:
282 doc = oinfo.get('init_docstring')
292 doc = oinfo.get('init_docstring')
283 if doc is None:
293 if doc is None:
284 doc = oinfo.get('docstring','')
294 doc = oinfo.get('docstring','')
285
295
286 return call_line, doc
296 return call_line, doc
287
297
288
298
289 def _get_wrapped(obj):
299 def _get_wrapped(obj):
290 """Get the original object if wrapped in one or more @decorators
300 """Get the original object if wrapped in one or more @decorators
291
301
292 Some objects automatically construct similar objects on any unrecognised
302 Some objects automatically construct similar objects on any unrecognised
293 attribute access (e.g. unittest.mock.call). To protect against infinite loops,
303 attribute access (e.g. unittest.mock.call). To protect against infinite loops,
294 this will arbitrarily cut off after 100 levels of obj.__wrapped__
304 this will arbitrarily cut off after 100 levels of obj.__wrapped__
295 attribute access. --TK, Jan 2016
305 attribute access. --TK, Jan 2016
296 """
306 """
297 orig_obj = obj
307 orig_obj = obj
298 i = 0
308 i = 0
299 while safe_hasattr(obj, '__wrapped__'):
309 while safe_hasattr(obj, '__wrapped__'):
300 obj = obj.__wrapped__
310 obj = obj.__wrapped__
301 i += 1
311 i += 1
302 if i > 100:
312 if i > 100:
303 # __wrapped__ is probably a lie, so return the thing we started with
313 # __wrapped__ is probably a lie, so return the thing we started with
304 return orig_obj
314 return orig_obj
305 return obj
315 return obj
306
316
307 def find_file(obj) -> str:
317 def find_file(obj) -> str:
308 """Find the absolute path to the file where an object was defined.
318 """Find the absolute path to the file where an object was defined.
309
319
310 This is essentially a robust wrapper around `inspect.getabsfile`.
320 This is essentially a robust wrapper around `inspect.getabsfile`.
311
321
312 Returns None if no file can be found.
322 Returns None if no file can be found.
313
323
314 Parameters
324 Parameters
315 ----------
325 ----------
316 obj : any Python object
326 obj : any Python object
317
327
318 Returns
328 Returns
319 -------
329 -------
320 fname : str
330 fname : str
321 The absolute path to the file where the object was defined.
331 The absolute path to the file where the object was defined.
322 """
332 """
323 obj = _get_wrapped(obj)
333 obj = _get_wrapped(obj)
324
334
325 fname = None
335 fname = None
326 try:
336 try:
327 fname = inspect.getabsfile(obj)
337 fname = inspect.getabsfile(obj)
328 except TypeError:
338 except TypeError:
329 # For an instance, the file that matters is where its class was
339 # For an instance, the file that matters is where its class was
330 # declared.
340 # declared.
331 try:
341 try:
332 fname = inspect.getabsfile(obj.__class__)
342 fname = inspect.getabsfile(obj.__class__)
333 except (OSError, TypeError):
343 except (OSError, TypeError):
334 # Can happen for builtins
344 # Can happen for builtins
335 pass
345 pass
336 except OSError:
346 except OSError:
337 pass
347 pass
338
348
339 return cast_unicode(fname)
349 return cast_unicode(fname)
340
350
341
351
342 def find_source_lines(obj):
352 def find_source_lines(obj):
343 """Find the line number in a file where an object was defined.
353 """Find the line number in a file where an object was defined.
344
354
345 This is essentially a robust wrapper around `inspect.getsourcelines`.
355 This is essentially a robust wrapper around `inspect.getsourcelines`.
346
356
347 Returns None if no file can be found.
357 Returns None if no file can be found.
348
358
349 Parameters
359 Parameters
350 ----------
360 ----------
351 obj : any Python object
361 obj : any Python object
352
362
353 Returns
363 Returns
354 -------
364 -------
355 lineno : int
365 lineno : int
356 The line number where the object definition starts.
366 The line number where the object definition starts.
357 """
367 """
358 obj = _get_wrapped(obj)
368 obj = _get_wrapped(obj)
359
369
360 try:
370 try:
361 lineno = inspect.getsourcelines(obj)[1]
371 lineno = inspect.getsourcelines(obj)[1]
362 except TypeError:
372 except TypeError:
363 # For instances, try the class object like getsource() does
373 # For instances, try the class object like getsource() does
364 try:
374 try:
365 lineno = inspect.getsourcelines(obj.__class__)[1]
375 lineno = inspect.getsourcelines(obj.__class__)[1]
366 except (OSError, TypeError):
376 except (OSError, TypeError):
367 return None
377 return None
368 except OSError:
378 except OSError:
369 return None
379 return None
370
380
371 return lineno
381 return lineno
372
382
373 class Inspector(Colorable):
383 class Inspector(Colorable):
374
384
375 def __init__(self, color_table=InspectColors,
385 def __init__(self, color_table=InspectColors,
376 code_color_table=PyColorize.ANSICodeColors,
386 code_color_table=PyColorize.ANSICodeColors,
377 scheme=None,
387 scheme=None,
378 str_detail_level=0,
388 str_detail_level=0,
379 parent=None, config=None):
389 parent=None, config=None):
380 super(Inspector, self).__init__(parent=parent, config=config)
390 super(Inspector, self).__init__(parent=parent, config=config)
381 self.color_table = color_table
391 self.color_table = color_table
382 self.parser = PyColorize.Parser(out='str', parent=self, style=scheme)
392 self.parser = PyColorize.Parser(out='str', parent=self, style=scheme)
383 self.format = self.parser.format
393 self.format = self.parser.format
384 self.str_detail_level = str_detail_level
394 self.str_detail_level = str_detail_level
385 self.set_active_scheme(scheme)
395 self.set_active_scheme(scheme)
386
396
387 def _getdef(self,obj,oname='') -> Union[str,None]:
397 def _getdef(self,obj,oname='') -> Union[str,None]:
388 """Return the call signature for any callable object.
398 """Return the call signature for any callable object.
389
399
390 If any exception is generated, None is returned instead and the
400 If any exception is generated, None is returned instead and the
391 exception is suppressed."""
401 exception is suppressed."""
392 try:
402 try:
393 return _render_signature(signature(obj), oname)
403 return _render_signature(signature(obj), oname)
394 except:
404 except:
395 return None
405 return None
396
406
397 def __head(self,h) -> str:
407 def __head(self,h) -> str:
398 """Return a header string with proper colors."""
408 """Return a header string with proper colors."""
399 return '%s%s%s' % (self.color_table.active_colors.header,h,
409 return '%s%s%s' % (self.color_table.active_colors.header,h,
400 self.color_table.active_colors.normal)
410 self.color_table.active_colors.normal)
401
411
402 def set_active_scheme(self, scheme):
412 def set_active_scheme(self, scheme):
403 if scheme is not None:
413 if scheme is not None:
404 self.color_table.set_active_scheme(scheme)
414 self.color_table.set_active_scheme(scheme)
405 self.parser.color_table.set_active_scheme(scheme)
415 self.parser.color_table.set_active_scheme(scheme)
406
416
407 def noinfo(self, msg, oname):
417 def noinfo(self, msg, oname):
408 """Generic message when no information is found."""
418 """Generic message when no information is found."""
409 print('No %s found' % msg, end=' ')
419 print('No %s found' % msg, end=' ')
410 if oname:
420 if oname:
411 print('for %s' % oname)
421 print('for %s' % oname)
412 else:
422 else:
413 print()
423 print()
414
424
415 def pdef(self, obj, oname=''):
425 def pdef(self, obj, oname=''):
416 """Print the call signature for any callable object.
426 """Print the call signature for any callable object.
417
427
418 If the object is a class, print the constructor information."""
428 If the object is a class, print the constructor information."""
419
429
420 if not callable(obj):
430 if not callable(obj):
421 print('Object is not callable.')
431 print('Object is not callable.')
422 return
432 return
423
433
424 header = ''
434 header = ''
425
435
426 if inspect.isclass(obj):
436 if inspect.isclass(obj):
427 header = self.__head('Class constructor information:\n')
437 header = self.__head('Class constructor information:\n')
428
438
429
439
430 output = self._getdef(obj,oname)
440 output = self._getdef(obj,oname)
431 if output is None:
441 if output is None:
432 self.noinfo('definition header',oname)
442 self.noinfo('definition header',oname)
433 else:
443 else:
434 print(header,self.format(output), end=' ')
444 print(header,self.format(output), end=' ')
435
445
436 # In Python 3, all classes are new-style, so they all have __init__.
446 # In Python 3, all classes are new-style, so they all have __init__.
437 @skip_doctest
447 @skip_doctest
438 def pdoc(self, obj, oname='', formatter=None):
448 def pdoc(self, obj, oname='', formatter=None):
439 """Print the docstring for any object.
449 """Print the docstring for any object.
440
450
441 Optional:
451 Optional:
442 -formatter: a function to run the docstring through for specially
452 -formatter: a function to run the docstring through for specially
443 formatted docstrings.
453 formatted docstrings.
444
454
445 Examples
455 Examples
446 --------
456 --------
447 In [1]: class NoInit:
457 In [1]: class NoInit:
448 ...: pass
458 ...: pass
449
459
450 In [2]: class NoDoc:
460 In [2]: class NoDoc:
451 ...: def __init__(self):
461 ...: def __init__(self):
452 ...: pass
462 ...: pass
453
463
454 In [3]: %pdoc NoDoc
464 In [3]: %pdoc NoDoc
455 No documentation found for NoDoc
465 No documentation found for NoDoc
456
466
457 In [4]: %pdoc NoInit
467 In [4]: %pdoc NoInit
458 No documentation found for NoInit
468 No documentation found for NoInit
459
469
460 In [5]: obj = NoInit()
470 In [5]: obj = NoInit()
461
471
462 In [6]: %pdoc obj
472 In [6]: %pdoc obj
463 No documentation found for obj
473 No documentation found for obj
464
474
465 In [5]: obj2 = NoDoc()
475 In [5]: obj2 = NoDoc()
466
476
467 In [6]: %pdoc obj2
477 In [6]: %pdoc obj2
468 No documentation found for obj2
478 No documentation found for obj2
469 """
479 """
470
480
471 head = self.__head # For convenience
481 head = self.__head # For convenience
472 lines = []
482 lines = []
473 ds = getdoc(obj)
483 ds = getdoc(obj)
474 if formatter:
484 if formatter:
475 ds = formatter(ds).get('plain/text', ds)
485 ds = formatter(ds).get('plain/text', ds)
476 if ds:
486 if ds:
477 lines.append(head("Class docstring:"))
487 lines.append(head("Class docstring:"))
478 lines.append(indent(ds))
488 lines.append(indent(ds))
479 if inspect.isclass(obj) and hasattr(obj, '__init__'):
489 if inspect.isclass(obj) and hasattr(obj, '__init__'):
480 init_ds = getdoc(obj.__init__)
490 init_ds = getdoc(obj.__init__)
481 if init_ds is not None:
491 if init_ds is not None:
482 lines.append(head("Init docstring:"))
492 lines.append(head("Init docstring:"))
483 lines.append(indent(init_ds))
493 lines.append(indent(init_ds))
484 elif hasattr(obj,'__call__'):
494 elif hasattr(obj,'__call__'):
485 call_ds = getdoc(obj.__call__)
495 call_ds = getdoc(obj.__call__)
486 if call_ds:
496 if call_ds:
487 lines.append(head("Call docstring:"))
497 lines.append(head("Call docstring:"))
488 lines.append(indent(call_ds))
498 lines.append(indent(call_ds))
489
499
490 if not lines:
500 if not lines:
491 self.noinfo('documentation',oname)
501 self.noinfo('documentation',oname)
492 else:
502 else:
493 page.page('\n'.join(lines))
503 page.page('\n'.join(lines))
494
504
495 def psource(self, obj, oname=''):
505 def psource(self, obj, oname=''):
496 """Print the source code for an object."""
506 """Print the source code for an object."""
497
507
498 # Flush the source cache because inspect can return out-of-date source
508 # Flush the source cache because inspect can return out-of-date source
499 linecache.checkcache()
509 linecache.checkcache()
500 try:
510 try:
501 src = getsource(obj, oname=oname)
511 src = getsource(obj, oname=oname)
502 except Exception:
512 except Exception:
503 src = None
513 src = None
504
514
505 if src is None:
515 if src is None:
506 self.noinfo('source', oname)
516 self.noinfo('source', oname)
507 else:
517 else:
508 page.page(self.format(src))
518 page.page(self.format(src))
509
519
510 def pfile(self, obj, oname=''):
520 def pfile(self, obj, oname=''):
511 """Show the whole file where an object was defined."""
521 """Show the whole file where an object was defined."""
512
522
513 lineno = find_source_lines(obj)
523 lineno = find_source_lines(obj)
514 if lineno is None:
524 if lineno is None:
515 self.noinfo('file', oname)
525 self.noinfo('file', oname)
516 return
526 return
517
527
518 ofile = find_file(obj)
528 ofile = find_file(obj)
519 # run contents of file through pager starting at line where the object
529 # run contents of file through pager starting at line where the object
520 # is defined, as long as the file isn't binary and is actually on the
530 # is defined, as long as the file isn't binary and is actually on the
521 # filesystem.
531 # filesystem.
522 if ofile.endswith(('.so', '.dll', '.pyd')):
532 if ofile.endswith(('.so', '.dll', '.pyd')):
523 print('File %r is binary, not printing.' % ofile)
533 print('File %r is binary, not printing.' % ofile)
524 elif not os.path.isfile(ofile):
534 elif not os.path.isfile(ofile):
525 print('File %r does not exist, not printing.' % ofile)
535 print('File %r does not exist, not printing.' % ofile)
526 else:
536 else:
527 # Print only text files, not extension binaries. Note that
537 # Print only text files, not extension binaries. Note that
528 # getsourcelines returns lineno with 1-offset and page() uses
538 # getsourcelines returns lineno with 1-offset and page() uses
529 # 0-offset, so we must adjust.
539 # 0-offset, so we must adjust.
530 page.page(self.format(openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1)
540 page.page(self.format(openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1)
531
541
532
542
533 def _mime_format(self, text:str, formatter=None) -> dict:
543 def _mime_format(self, text:str, formatter=None) -> dict:
534 """Return a mime bundle representation of the input text.
544 """Return a mime bundle representation of the input text.
535
545
536 - if `formatter` is None, the returned mime bundle has
546 - if `formatter` is None, the returned mime bundle has
537 a ``text/plain`` field, with the input text.
547 a ``text/plain`` field, with the input text.
538 a ``text/html`` field with a ``<pre>`` tag containing the input text.
548 a ``text/html`` field with a ``<pre>`` tag containing the input text.
539
549
540 - if ``formatter`` is not None, it must be a callable transforming the
550 - if ``formatter`` is not None, it must be a callable transforming the
541 input text into a mime bundle. Default values for ``text/plain`` and
551 input text into a mime bundle. Default values for ``text/plain`` and
542 ``text/html`` representations are the ones described above.
552 ``text/html`` representations are the ones described above.
543
553
544 Note:
554 Note:
545
555
546 Formatters returning strings are supported but this behavior is deprecated.
556 Formatters returning strings are supported but this behavior is deprecated.
547
557
548 """
558 """
549 defaults = {
559 defaults = {
550 "text/plain": text,
560 "text/plain": text,
551 "text/html": f"<pre>{html.escape(text)}</pre>",
561 "text/html": f"<pre>{html.escape(text)}</pre>",
552 }
562 }
553
563
554 if formatter is None:
564 if formatter is None:
555 return defaults
565 return defaults
556 else:
566 else:
557 formatted = formatter(text)
567 formatted = formatter(text)
558
568
559 if not isinstance(formatted, dict):
569 if not isinstance(formatted, dict):
560 # Handle the deprecated behavior of a formatter returning
570 # Handle the deprecated behavior of a formatter returning
561 # a string instead of a mime bundle.
571 # a string instead of a mime bundle.
562 return {"text/plain": formatted, "text/html": f"<pre>{formatted}</pre>"}
572 return {"text/plain": formatted, "text/html": f"<pre>{formatted}</pre>"}
563
573
564 else:
574 else:
565 return dict(defaults, **formatted)
575 return dict(defaults, **formatted)
566
576
567
577 def format_mime(self, bundle: UnformattedBundle) -> Bundle:
568 def format_mime(self, bundle):
569 """Format a mimebundle being created by _make_info_unformatted into a real mimebundle"""
578 """Format a mimebundle being created by _make_info_unformatted into a real mimebundle"""
570 # Format text/plain mimetype
579 # Format text/plain mimetype
571 if isinstance(bundle["text/plain"], (list, tuple)):
580 assert isinstance(bundle["text/plain"], list)
572 # bundle['text/plain'] is a list of (head, formatted body) pairs
581 for item in bundle["text/plain"]:
573 lines = []
582 assert isinstance(item, tuple)
574 _len = max(len(h) for h, _ in bundle["text/plain"])
575
576 for head, body in bundle["text/plain"]:
577 body = body.strip("\n")
578 delim = "\n" if "\n" in body else " "
579 lines.append(
580 f"{self.__head(head+':')}{(_len - len(head))*' '}{delim}{body}"
581 )
582
583
583 bundle["text/plain"] = "\n".join(lines)
584 new_b: Bundle = {}
585 lines = []
586 _len = max(len(h) for h, _ in bundle["text/plain"])
584
587
585 # Format the text/html mimetype
588 for head, body in bundle["text/plain"]:
586 if isinstance(bundle["text/html"], (list, tuple)):
589 body = body.strip("\n")
587 # bundle['text/html'] is a list of (head, formatted body) pairs
590 delim = "\n" if "\n" in body else " "
588 bundle["text/html"] = "\n".join(
591 lines.append(
589 (f"<h1>{head}</h1>\n{body}" for (head, body) in bundle["text/html"])
592 f"{self.__head(head+':')}{(_len - len(head))*' '}{delim}{body}"
590 )
593 )
591 return bundle
594
595 new_b["text/plain"] = "\n".join(lines)
596
597 if "text/html" in bundle:
598 assert isinstance(bundle["text/html"], list)
599 for item in bundle["text/html"]:
600 assert isinstance(item, tuple)
601 # Format the text/html mimetype
602 if isinstance(bundle["text/html"], (list, tuple)):
603 # bundle['text/html'] is a list of (head, formatted body) pairs
604 new_b["text/html"] = "\n".join(
605 (f"<h1>{head}</h1>\n{body}" for (head, body) in bundle["text/html"])
606 )
607
608 for k in bundle.keys():
609 if k in ("text/html", "text/plain"):
610 continue
611 else:
612 new_b = bundle[k] # type:ignore
613 return new_b
592
614
593 def _append_info_field(
615 def _append_info_field(
594 self, bundle, title: str, key: str, info, omit_sections, formatter
616 self,
617 bundle: UnformattedBundle,
618 title: str,
619 key: str,
620 info,
621 omit_sections,
622 formatter,
595 ):
623 ):
596 """Append an info value to the unformatted mimebundle being constructed by _make_info_unformatted"""
624 """Append an info value to the unformatted mimebundle being constructed by _make_info_unformatted"""
597 if title in omit_sections or key in omit_sections:
625 if title in omit_sections or key in omit_sections:
598 return
626 return
599 field = info[key]
627 field = info[key]
600 if field is not None:
628 if field is not None:
601 formatted_field = self._mime_format(field, formatter)
629 formatted_field = self._mime_format(field, formatter)
602 bundle["text/plain"].append((title, formatted_field["text/plain"]))
630 bundle["text/plain"].append((title, formatted_field["text/plain"]))
603 bundle["text/html"].append((title, formatted_field["text/html"]))
631 bundle["text/html"].append((title, formatted_field["text/html"]))
604
632
605 def _make_info_unformatted(self, obj, info, formatter, detail_level, omit_sections):
633 def _make_info_unformatted(
634 self, obj, info, formatter, detail_level, omit_sections
635 ) -> UnformattedBundle:
606 """Assemble the mimebundle as unformatted lists of information"""
636 """Assemble the mimebundle as unformatted lists of information"""
607 bundle = {
637 bundle: UnformattedBundle = {
608 "text/plain": [],
638 "text/plain": [],
609 "text/html": [],
639 "text/html": [],
610 }
640 }
611
641
612 # A convenience function to simplify calls below
642 # A convenience function to simplify calls below
613 def append_field(bundle, title: str, key: str, formatter=None):
643 def append_field(
644 bundle: UnformattedBundle, title: str, key: str, formatter=None
645 ):
614 self._append_info_field(
646 self._append_info_field(
615 bundle,
647 bundle,
616 title=title,
648 title=title,
617 key=key,
649 key=key,
618 info=info,
650 info=info,
619 omit_sections=omit_sections,
651 omit_sections=omit_sections,
620 formatter=formatter,
652 formatter=formatter,
621 )
653 )
622
654
623 def code_formatter(text):
655 def code_formatter(text) -> Bundle:
624 return {
656 return {
625 'text/plain': self.format(text),
657 'text/plain': self.format(text),
626 'text/html': pylight(text)
658 'text/html': pylight(text)
627 }
659 }
628
660
629 if info["isalias"]:
661 if info["isalias"]:
630 append_field(bundle, "Repr", "string_form")
662 append_field(bundle, "Repr", "string_form")
631
663
632 elif info['ismagic']:
664 elif info['ismagic']:
633 if detail_level > 0:
665 if detail_level > 0:
634 append_field(bundle, "Source", "source", code_formatter)
666 append_field(bundle, "Source", "source", code_formatter)
635 else:
667 else:
636 append_field(bundle, "Docstring", "docstring", formatter)
668 append_field(bundle, "Docstring", "docstring", formatter)
637 append_field(bundle, "File", "file")
669 append_field(bundle, "File", "file")
638
670
639 elif info['isclass'] or is_simple_callable(obj):
671 elif info['isclass'] or is_simple_callable(obj):
640 # Functions, methods, classes
672 # Functions, methods, classes
641 append_field(bundle, "Signature", "definition", code_formatter)
673 append_field(bundle, "Signature", "definition", code_formatter)
642 append_field(bundle, "Init signature", "init_definition", code_formatter)
674 append_field(bundle, "Init signature", "init_definition", code_formatter)
643 append_field(bundle, "Docstring", "docstring", formatter)
675 append_field(bundle, "Docstring", "docstring", formatter)
644 if detail_level > 0 and info["source"]:
676 if detail_level > 0 and info["source"]:
645 append_field(bundle, "Source", "source", code_formatter)
677 append_field(bundle, "Source", "source", code_formatter)
646 else:
678 else:
647 append_field(bundle, "Init docstring", "init_docstring", formatter)
679 append_field(bundle, "Init docstring", "init_docstring", formatter)
648
680
649 append_field(bundle, "File", "file")
681 append_field(bundle, "File", "file")
650 append_field(bundle, "Type", "type_name")
682 append_field(bundle, "Type", "type_name")
651 append_field(bundle, "Subclasses", "subclasses")
683 append_field(bundle, "Subclasses", "subclasses")
652
684
653 else:
685 else:
654 # General Python objects
686 # General Python objects
655 append_field(bundle, "Signature", "definition", code_formatter)
687 append_field(bundle, "Signature", "definition", code_formatter)
656 append_field(bundle, "Call signature", "call_def", code_formatter)
688 append_field(bundle, "Call signature", "call_def", code_formatter)
657 append_field(bundle, "Type", "type_name")
689 append_field(bundle, "Type", "type_name")
658 append_field(bundle, "String form", "string_form")
690 append_field(bundle, "String form", "string_form")
659
691
660 # Namespace
692 # Namespace
661 if info["namespace"] != "Interactive":
693 if info["namespace"] != "Interactive":
662 append_field(bundle, "Namespace", "namespace")
694 append_field(bundle, "Namespace", "namespace")
663
695
664 append_field(bundle, "Length", "length")
696 append_field(bundle, "Length", "length")
665 append_field(bundle, "File", "file")
697 append_field(bundle, "File", "file")
666
698
667 # Source or docstring, depending on detail level and whether
699 # Source or docstring, depending on detail level and whether
668 # source found.
700 # source found.
669 if detail_level > 0 and info["source"]:
701 if detail_level > 0 and info["source"]:
670 append_field(bundle, "Source", "source", code_formatter)
702 append_field(bundle, "Source", "source", code_formatter)
671 else:
703 else:
672 append_field(bundle, "Docstring", "docstring", formatter)
704 append_field(bundle, "Docstring", "docstring", formatter)
673
705
674 append_field(bundle, "Class docstring", "class_docstring", formatter)
706 append_field(bundle, "Class docstring", "class_docstring", formatter)
675 append_field(bundle, "Init docstring", "init_docstring", formatter)
707 append_field(bundle, "Init docstring", "init_docstring", formatter)
676 append_field(bundle, "Call docstring", "call_docstring", formatter)
708 append_field(bundle, "Call docstring", "call_docstring", formatter)
677 return bundle
709 return bundle
678
710
679
711
680 def _get_info(
712 def _get_info(
681 self, obj, oname="", formatter=None, info=None, detail_level=0, omit_sections=()
713 self,
682 ):
714 obj: Any,
715 oname: str = "",
716 formatter=None,
717 info: Optional[OInfo] = None,
718 detail_level=0,
719 omit_sections=(),
720 ) -> Bundle:
683 """Retrieve an info dict and format it.
721 """Retrieve an info dict and format it.
684
722
685 Parameters
723 Parameters
686 ----------
724 ----------
687 obj : any
725 obj : any
688 Object to inspect and return info from
726 Object to inspect and return info from
689 oname : str (default: ''):
727 oname : str (default: ''):
690 Name of the variable pointing to `obj`.
728 Name of the variable pointing to `obj`.
691 formatter : callable
729 formatter : callable
692 info
730 info
693 already computed information
731 already computed information
694 detail_level : integer
732 detail_level : integer
695 Granularity of detail level, if set to 1, give more information.
733 Granularity of detail level, if set to 1, give more information.
696 omit_sections : container[str]
734 omit_sections : container[str]
697 Titles or keys to omit from output (can be set, tuple, etc., anything supporting `in`)
735 Titles or keys to omit from output (can be set, tuple, etc., anything supporting `in`)
698 """
736 """
699
737
700 info = self.info(obj, oname=oname, info=info, detail_level=detail_level)
738 info_dict = self.info(obj, oname=oname, info=info, detail_level=detail_level)
701 bundle = self._make_info_unformatted(
739 bundle = self._make_info_unformatted(
702 obj, info, formatter, detail_level=detail_level, omit_sections=omit_sections
740 obj,
741 info_dict,
742 formatter,
743 detail_level=detail_level,
744 omit_sections=omit_sections,
703 )
745 )
704 return self.format_mime(bundle)
746 return self.format_mime(bundle)
705
747
706 def pinfo(
748 def pinfo(
707 self,
749 self,
708 obj,
750 obj,
709 oname="",
751 oname="",
710 formatter=None,
752 formatter=None,
711 info=None,
753 info: Optional[OInfo] = None,
712 detail_level=0,
754 detail_level=0,
713 enable_html_pager=True,
755 enable_html_pager=True,
714 omit_sections=(),
756 omit_sections=(),
715 ):
757 ):
716 """Show detailed information about an object.
758 """Show detailed information about an object.
717
759
718 Optional arguments:
760 Optional arguments:
719
761
720 - oname: name of the variable pointing to the object.
762 - oname: name of the variable pointing to the object.
721
763
722 - formatter: callable (optional)
764 - formatter: callable (optional)
723 A special formatter for docstrings.
765 A special formatter for docstrings.
724
766
725 The formatter is a callable that takes a string as an input
767 The formatter is a callable that takes a string as an input
726 and returns either a formatted string or a mime type bundle
768 and returns either a formatted string or a mime type bundle
727 in the form of a dictionary.
769 in the form of a dictionary.
728
770
729 Although the support of custom formatter returning a string
771 Although the support of custom formatter returning a string
730 instead of a mime type bundle is deprecated.
772 instead of a mime type bundle is deprecated.
731
773
732 - info: a structure with some information fields which may have been
774 - info: a structure with some information fields which may have been
733 precomputed already.
775 precomputed already.
734
776
735 - detail_level: if set to 1, more information is given.
777 - detail_level: if set to 1, more information is given.
736
778
737 - omit_sections: set of section keys and titles to omit
779 - omit_sections: set of section keys and titles to omit
738 """
780 """
739 info = self._get_info(
781 assert info is not None
782 info_b: Bundle = self._get_info(
740 obj, oname, formatter, info, detail_level, omit_sections=omit_sections
783 obj, oname, formatter, info, detail_level, omit_sections=omit_sections
741 )
784 )
742 if not enable_html_pager:
785 if not enable_html_pager:
743 del info['text/html']
786 del info_b["text/html"]
744 page.page(info)
787 page.page(info_b)
745
788
746 def _info(self, obj, oname="", info=None, detail_level=0):
789 def _info(self, obj, oname="", info=None, detail_level=0):
747 """
790 """
748 Inspector.info() was likely improperly marked as deprecated
791 Inspector.info() was likely improperly marked as deprecated
749 while only a parameter was deprecated. We "un-deprecate" it.
792 while only a parameter was deprecated. We "un-deprecate" it.
750 """
793 """
751
794
752 warnings.warn(
795 warnings.warn(
753 "The `Inspector.info()` method has been un-deprecated as of 8.0 "
796 "The `Inspector.info()` method has been un-deprecated as of 8.0 "
754 "and the `formatter=` keyword removed. `Inspector._info` is now "
797 "and the `formatter=` keyword removed. `Inspector._info` is now "
755 "an alias, and you can just call `.info()` directly.",
798 "an alias, and you can just call `.info()` directly.",
756 DeprecationWarning,
799 DeprecationWarning,
757 stacklevel=2,
800 stacklevel=2,
758 )
801 )
759 return self.info(obj, oname=oname, info=info, detail_level=detail_level)
802 return self.info(obj, oname=oname, info=info, detail_level=detail_level)
760
803
761 def info(self, obj, oname="", info=None, detail_level=0) -> dict:
804 def info(self, obj, oname="", info=None, detail_level=0) -> Dict[str, Any]:
762 """Compute a dict with detailed information about an object.
805 """Compute a dict with detailed information about an object.
763
806
764 Parameters
807 Parameters
765 ----------
808 ----------
766 obj : any
809 obj : any
767 An object to find information about
810 An object to find information about
768 oname : str (default: '')
811 oname : str (default: '')
769 Name of the variable pointing to `obj`.
812 Name of the variable pointing to `obj`.
770 info : (default: None)
813 info : (default: None)
771 A struct (dict like with attr access) with some information fields
814 A struct (dict like with attr access) with some information fields
772 which may have been precomputed already.
815 which may have been precomputed already.
773 detail_level : int (default:0)
816 detail_level : int (default:0)
774 If set to 1, more information is given.
817 If set to 1, more information is given.
775
818
776 Returns
819 Returns
777 -------
820 -------
778 An object info dict with known fields from `info_fields`. Keys are
821 An object info dict with known fields from `info_fields`. Keys are
779 strings, values are string or None.
822 strings, values are string or None.
780 """
823 """
781
824
782 if info is None:
825 if info is None:
783 ismagic = False
826 ismagic = False
784 isalias = False
827 isalias = False
785 ospace = ''
828 ospace = ''
786 else:
829 else:
787 ismagic = info.ismagic
830 ismagic = info.ismagic
788 isalias = info.isalias
831 isalias = info.isalias
789 ospace = info.namespace
832 ospace = info.namespace
790
833
791 # Get docstring, special-casing aliases:
834 # Get docstring, special-casing aliases:
792 if isalias:
835 att_name = oname.split(".")[-1]
836 parents_docs = None
837 prelude = ""
838 if info and info.parent and hasattr(info.parent, HOOK_NAME):
839 parents_docs_dict = getattr(info.parent, HOOK_NAME)
840 parents_docs = parents_docs_dict.get(att_name, None)
841 out = dict(
842 name=oname, found=True, isalias=isalias, ismagic=ismagic, subclasses=None
843 )
844
845 if parents_docs:
846 ds = parents_docs
847 elif isalias:
793 if not callable(obj):
848 if not callable(obj):
794 try:
849 try:
795 ds = "Alias to the system command:\n %s" % obj[1]
850 ds = "Alias to the system command:\n %s" % obj[1]
796 except:
851 except:
797 ds = "Alias: " + str(obj)
852 ds = "Alias: " + str(obj)
798 else:
853 else:
799 ds = "Alias to " + str(obj)
854 ds = "Alias to " + str(obj)
800 if obj.__doc__:
855 if obj.__doc__:
801 ds += "\nDocstring:\n" + obj.__doc__
856 ds += "\nDocstring:\n" + obj.__doc__
802 else:
857 else:
803 ds_or_None = getdoc(obj)
858 ds_or_None = getdoc(obj)
804 if ds_or_None is None:
859 if ds_or_None is None:
805 ds = '<no docstring>'
860 ds = '<no docstring>'
806 else:
861 else:
807 ds = ds_or_None
862 ds = ds_or_None
808
863
864 ds = prelude + ds
865
809 # store output in a dict, we initialize it here and fill it as we go
866 # store output in a dict, we initialize it here and fill it as we go
810 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic, subclasses=None)
811
867
812 string_max = 200 # max size of strings to show (snipped if longer)
868 string_max = 200 # max size of strings to show (snipped if longer)
813 shalf = int((string_max - 5) / 2)
869 shalf = int((string_max - 5) / 2)
814
870
815 if ismagic:
871 if ismagic:
816 out['type_name'] = 'Magic function'
872 out['type_name'] = 'Magic function'
817 elif isalias:
873 elif isalias:
818 out['type_name'] = 'System alias'
874 out['type_name'] = 'System alias'
819 else:
875 else:
820 out['type_name'] = type(obj).__name__
876 out['type_name'] = type(obj).__name__
821
877
822 try:
878 try:
823 bclass = obj.__class__
879 bclass = obj.__class__
824 out['base_class'] = str(bclass)
880 out['base_class'] = str(bclass)
825 except:
881 except:
826 pass
882 pass
827
883
828 # String form, but snip if too long in ? form (full in ??)
884 # String form, but snip if too long in ? form (full in ??)
829 if detail_level >= self.str_detail_level:
885 if detail_level >= self.str_detail_level:
830 try:
886 try:
831 ostr = str(obj)
887 ostr = str(obj)
832 str_head = 'string_form'
888 str_head = 'string_form'
833 if not detail_level and len(ostr)>string_max:
889 if not detail_level and len(ostr)>string_max:
834 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
890 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
835 ostr = ("\n" + " " * len(str_head.expandtabs())).\
891 ostr = ("\n" + " " * len(str_head.expandtabs())).\
836 join(q.strip() for q in ostr.split("\n"))
892 join(q.strip() for q in ostr.split("\n"))
837 out[str_head] = ostr
893 out[str_head] = ostr
838 except:
894 except:
839 pass
895 pass
840
896
841 if ospace:
897 if ospace:
842 out['namespace'] = ospace
898 out['namespace'] = ospace
843
899
844 # Length (for strings and lists)
900 # Length (for strings and lists)
845 try:
901 try:
846 out['length'] = str(len(obj))
902 out['length'] = str(len(obj))
847 except Exception:
903 except Exception:
848 pass
904 pass
849
905
850 # Filename where object was defined
906 # Filename where object was defined
851 binary_file = False
907 binary_file = False
852 fname = find_file(obj)
908 fname = find_file(obj)
853 if fname is None:
909 if fname is None:
854 # if anything goes wrong, we don't want to show source, so it's as
910 # if anything goes wrong, we don't want to show source, so it's as
855 # if the file was binary
911 # if the file was binary
856 binary_file = True
912 binary_file = True
857 else:
913 else:
858 if fname.endswith(('.so', '.dll', '.pyd')):
914 if fname.endswith(('.so', '.dll', '.pyd')):
859 binary_file = True
915 binary_file = True
860 elif fname.endswith('<string>'):
916 elif fname.endswith('<string>'):
861 fname = 'Dynamically generated function. No source code available.'
917 fname = 'Dynamically generated function. No source code available.'
862 out['file'] = compress_user(fname)
918 out['file'] = compress_user(fname)
863
919
864 # Original source code for a callable, class or property.
920 # Original source code for a callable, class or property.
865 if detail_level:
921 if detail_level:
866 # Flush the source cache because inspect can return out-of-date
922 # Flush the source cache because inspect can return out-of-date
867 # source
923 # source
868 linecache.checkcache()
924 linecache.checkcache()
869 try:
925 try:
870 if isinstance(obj, property) or not binary_file:
926 if isinstance(obj, property) or not binary_file:
871 src = getsource(obj, oname)
927 src = getsource(obj, oname)
872 if src is not None:
928 if src is not None:
873 src = src.rstrip()
929 src = src.rstrip()
874 out['source'] = src
930 out['source'] = src
875
931
876 except Exception:
932 except Exception:
877 pass
933 pass
878
934
879 # Add docstring only if no source is to be shown (avoid repetitions).
935 # Add docstring only if no source is to be shown (avoid repetitions).
880 if ds and not self._source_contains_docstring(out.get('source'), ds):
936 if ds and not self._source_contains_docstring(out.get('source'), ds):
881 out['docstring'] = ds
937 out['docstring'] = ds
882
938
883 # Constructor docstring for classes
939 # Constructor docstring for classes
884 if inspect.isclass(obj):
940 if inspect.isclass(obj):
885 out['isclass'] = True
941 out['isclass'] = True
886
942
887 # get the init signature:
943 # get the init signature:
888 try:
944 try:
889 init_def = self._getdef(obj, oname)
945 init_def = self._getdef(obj, oname)
890 except AttributeError:
946 except AttributeError:
891 init_def = None
947 init_def = None
892
948
893 # get the __init__ docstring
949 # get the __init__ docstring
894 try:
950 try:
895 obj_init = obj.__init__
951 obj_init = obj.__init__
896 except AttributeError:
952 except AttributeError:
897 init_ds = None
953 init_ds = None
898 else:
954 else:
899 if init_def is None:
955 if init_def is None:
900 # Get signature from init if top-level sig failed.
956 # Get signature from init if top-level sig failed.
901 # Can happen for built-in types (list, etc.).
957 # Can happen for built-in types (list, etc.).
902 try:
958 try:
903 init_def = self._getdef(obj_init, oname)
959 init_def = self._getdef(obj_init, oname)
904 except AttributeError:
960 except AttributeError:
905 pass
961 pass
906 init_ds = getdoc(obj_init)
962 init_ds = getdoc(obj_init)
907 # Skip Python's auto-generated docstrings
963 # Skip Python's auto-generated docstrings
908 if init_ds == _object_init_docstring:
964 if init_ds == _object_init_docstring:
909 init_ds = None
965 init_ds = None
910
966
911 if init_def:
967 if init_def:
912 out['init_definition'] = init_def
968 out['init_definition'] = init_def
913
969
914 if init_ds:
970 if init_ds:
915 out['init_docstring'] = init_ds
971 out['init_docstring'] = init_ds
916
972
917 names = [sub.__name__ for sub in type.__subclasses__(obj)]
973 names = [sub.__name__ for sub in type.__subclasses__(obj)]
918 if len(names) < 10:
974 if len(names) < 10:
919 all_names = ', '.join(names)
975 all_names = ', '.join(names)
920 else:
976 else:
921 all_names = ', '.join(names[:10]+['...'])
977 all_names = ', '.join(names[:10]+['...'])
922 out['subclasses'] = all_names
978 out['subclasses'] = all_names
923 # and class docstring for instances:
979 # and class docstring for instances:
924 else:
980 else:
925 # reconstruct the function definition and print it:
981 # reconstruct the function definition and print it:
926 defln = self._getdef(obj, oname)
982 defln = self._getdef(obj, oname)
927 if defln:
983 if defln:
928 out['definition'] = defln
984 out['definition'] = defln
929
985
930 # First, check whether the instance docstring is identical to the
986 # First, check whether the instance docstring is identical to the
931 # class one, and print it separately if they don't coincide. In
987 # class one, and print it separately if they don't coincide. In
932 # most cases they will, but it's nice to print all the info for
988 # most cases they will, but it's nice to print all the info for
933 # objects which use instance-customized docstrings.
989 # objects which use instance-customized docstrings.
934 if ds:
990 if ds:
935 try:
991 try:
936 cls = getattr(obj,'__class__')
992 cls = getattr(obj,'__class__')
937 except:
993 except:
938 class_ds = None
994 class_ds = None
939 else:
995 else:
940 class_ds = getdoc(cls)
996 class_ds = getdoc(cls)
941 # Skip Python's auto-generated docstrings
997 # Skip Python's auto-generated docstrings
942 if class_ds in _builtin_type_docstrings:
998 if class_ds in _builtin_type_docstrings:
943 class_ds = None
999 class_ds = None
944 if class_ds and ds != class_ds:
1000 if class_ds and ds != class_ds:
945 out['class_docstring'] = class_ds
1001 out['class_docstring'] = class_ds
946
1002
947 # Next, try to show constructor docstrings
1003 # Next, try to show constructor docstrings
948 try:
1004 try:
949 init_ds = getdoc(obj.__init__)
1005 init_ds = getdoc(obj.__init__)
950 # Skip Python's auto-generated docstrings
1006 # Skip Python's auto-generated docstrings
951 if init_ds == _object_init_docstring:
1007 if init_ds == _object_init_docstring:
952 init_ds = None
1008 init_ds = None
953 except AttributeError:
1009 except AttributeError:
954 init_ds = None
1010 init_ds = None
955 if init_ds:
1011 if init_ds:
956 out['init_docstring'] = init_ds
1012 out['init_docstring'] = init_ds
957
1013
958 # Call form docstring for callable instances
1014 # Call form docstring for callable instances
959 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
1015 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
960 call_def = self._getdef(obj.__call__, oname)
1016 call_def = self._getdef(obj.__call__, oname)
961 if call_def and (call_def != out.get('definition')):
1017 if call_def and (call_def != out.get('definition')):
962 # it may never be the case that call def and definition differ,
1018 # it may never be the case that call def and definition differ,
963 # but don't include the same signature twice
1019 # but don't include the same signature twice
964 out['call_def'] = call_def
1020 out['call_def'] = call_def
965 call_ds = getdoc(obj.__call__)
1021 call_ds = getdoc(obj.__call__)
966 # Skip Python's auto-generated docstrings
1022 # Skip Python's auto-generated docstrings
967 if call_ds == _func_call_docstring:
1023 if call_ds == _func_call_docstring:
968 call_ds = None
1024 call_ds = None
969 if call_ds:
1025 if call_ds:
970 out['call_docstring'] = call_ds
1026 out['call_docstring'] = call_ds
971
1027
972 return object_info(**out)
1028 return object_info(**out)
973
1029
974 @staticmethod
1030 @staticmethod
975 def _source_contains_docstring(src, doc):
1031 def _source_contains_docstring(src, doc):
976 """
1032 """
977 Check whether the source *src* contains the docstring *doc*.
1033 Check whether the source *src* contains the docstring *doc*.
978
1034
979 This is is helper function to skip displaying the docstring if the
1035 This is is helper function to skip displaying the docstring if the
980 source already contains it, avoiding repetition of information.
1036 source already contains it, avoiding repetition of information.
981 """
1037 """
982 try:
1038 try:
983 def_node, = ast.parse(dedent(src)).body
1039 (def_node,) = ast.parse(dedent(src)).body
984 return ast.get_docstring(def_node) == doc
1040 return ast.get_docstring(def_node) == doc # type: ignore[arg-type]
985 except Exception:
1041 except Exception:
986 # The source can become invalid or even non-existent (because it
1042 # The source can become invalid or even non-existent (because it
987 # is re-fetched from the source file) so the above code fail in
1043 # is re-fetched from the source file) so the above code fail in
988 # arbitrary ways.
1044 # arbitrary ways.
989 return False
1045 return False
990
1046
991 def psearch(self,pattern,ns_table,ns_search=[],
1047 def psearch(self,pattern,ns_table,ns_search=[],
992 ignore_case=False,show_all=False, *, list_types=False):
1048 ignore_case=False,show_all=False, *, list_types=False):
993 """Search namespaces with wildcards for objects.
1049 """Search namespaces with wildcards for objects.
994
1050
995 Arguments:
1051 Arguments:
996
1052
997 - pattern: string containing shell-like wildcards to use in namespace
1053 - pattern: string containing shell-like wildcards to use in namespace
998 searches and optionally a type specification to narrow the search to
1054 searches and optionally a type specification to narrow the search to
999 objects of that type.
1055 objects of that type.
1000
1056
1001 - ns_table: dict of name->namespaces for search.
1057 - ns_table: dict of name->namespaces for search.
1002
1058
1003 Optional arguments:
1059 Optional arguments:
1004
1060
1005 - ns_search: list of namespace names to include in search.
1061 - ns_search: list of namespace names to include in search.
1006
1062
1007 - ignore_case(False): make the search case-insensitive.
1063 - ignore_case(False): make the search case-insensitive.
1008
1064
1009 - show_all(False): show all names, including those starting with
1065 - show_all(False): show all names, including those starting with
1010 underscores.
1066 underscores.
1011
1067
1012 - list_types(False): list all available object types for object matching.
1068 - list_types(False): list all available object types for object matching.
1013 """
1069 """
1014 #print 'ps pattern:<%r>' % pattern # dbg
1070 #print 'ps pattern:<%r>' % pattern # dbg
1015
1071
1016 # defaults
1072 # defaults
1017 type_pattern = 'all'
1073 type_pattern = 'all'
1018 filter = ''
1074 filter = ''
1019
1075
1020 # list all object types
1076 # list all object types
1021 if list_types:
1077 if list_types:
1022 page.page('\n'.join(sorted(typestr2type)))
1078 page.page('\n'.join(sorted(typestr2type)))
1023 return
1079 return
1024
1080
1025 cmds = pattern.split()
1081 cmds = pattern.split()
1026 len_cmds = len(cmds)
1082 len_cmds = len(cmds)
1027 if len_cmds == 1:
1083 if len_cmds == 1:
1028 # Only filter pattern given
1084 # Only filter pattern given
1029 filter = cmds[0]
1085 filter = cmds[0]
1030 elif len_cmds == 2:
1086 elif len_cmds == 2:
1031 # Both filter and type specified
1087 # Both filter and type specified
1032 filter,type_pattern = cmds
1088 filter,type_pattern = cmds
1033 else:
1089 else:
1034 raise ValueError('invalid argument string for psearch: <%s>' %
1090 raise ValueError('invalid argument string for psearch: <%s>' %
1035 pattern)
1091 pattern)
1036
1092
1037 # filter search namespaces
1093 # filter search namespaces
1038 for name in ns_search:
1094 for name in ns_search:
1039 if name not in ns_table:
1095 if name not in ns_table:
1040 raise ValueError('invalid namespace <%s>. Valid names: %s' %
1096 raise ValueError('invalid namespace <%s>. Valid names: %s' %
1041 (name,ns_table.keys()))
1097 (name,ns_table.keys()))
1042
1098
1043 #print 'type_pattern:',type_pattern # dbg
1099 #print 'type_pattern:',type_pattern # dbg
1044 search_result, namespaces_seen = set(), set()
1100 search_result, namespaces_seen = set(), set()
1045 for ns_name in ns_search:
1101 for ns_name in ns_search:
1046 ns = ns_table[ns_name]
1102 ns = ns_table[ns_name]
1047 # Normally, locals and globals are the same, so we just check one.
1103 # Normally, locals and globals are the same, so we just check one.
1048 if id(ns) in namespaces_seen:
1104 if id(ns) in namespaces_seen:
1049 continue
1105 continue
1050 namespaces_seen.add(id(ns))
1106 namespaces_seen.add(id(ns))
1051 tmp_res = list_namespace(ns, type_pattern, filter,
1107 tmp_res = list_namespace(ns, type_pattern, filter,
1052 ignore_case=ignore_case, show_all=show_all)
1108 ignore_case=ignore_case, show_all=show_all)
1053 search_result.update(tmp_res)
1109 search_result.update(tmp_res)
1054
1110
1055 page.page('\n'.join(sorted(search_result)))
1111 page.page('\n'.join(sorted(search_result)))
1056
1112
1057
1113
1058 def _render_signature(obj_signature, obj_name) -> str:
1114 def _render_signature(obj_signature, obj_name) -> str:
1059 """
1115 """
1060 This was mostly taken from inspect.Signature.__str__.
1116 This was mostly taken from inspect.Signature.__str__.
1061 Look there for the comments.
1117 Look there for the comments.
1062 The only change is to add linebreaks when this gets too long.
1118 The only change is to add linebreaks when this gets too long.
1063 """
1119 """
1064 result = []
1120 result = []
1065 pos_only = False
1121 pos_only = False
1066 kw_only = True
1122 kw_only = True
1067 for param in obj_signature.parameters.values():
1123 for param in obj_signature.parameters.values():
1068 if param.kind == inspect.Parameter.POSITIONAL_ONLY:
1124 if param.kind == inspect.Parameter.POSITIONAL_ONLY:
1069 pos_only = True
1125 pos_only = True
1070 elif pos_only:
1126 elif pos_only:
1071 result.append('/')
1127 result.append('/')
1072 pos_only = False
1128 pos_only = False
1073
1129
1074 if param.kind == inspect.Parameter.VAR_POSITIONAL:
1130 if param.kind == inspect.Parameter.VAR_POSITIONAL:
1075 kw_only = False
1131 kw_only = False
1076 elif param.kind == inspect.Parameter.KEYWORD_ONLY and kw_only:
1132 elif param.kind == inspect.Parameter.KEYWORD_ONLY and kw_only:
1077 result.append('*')
1133 result.append('*')
1078 kw_only = False
1134 kw_only = False
1079
1135
1080 result.append(str(param))
1136 result.append(str(param))
1081
1137
1082 if pos_only:
1138 if pos_only:
1083 result.append('/')
1139 result.append('/')
1084
1140
1085 # add up name, parameters, braces (2), and commas
1141 # add up name, parameters, braces (2), and commas
1086 if len(obj_name) + sum(len(r) + 2 for r in result) > 75:
1142 if len(obj_name) + sum(len(r) + 2 for r in result) > 75:
1087 # This doesn’t fit behind “Signature: ” in an inspect window.
1143 # This doesn’t fit behind “Signature: ” in an inspect window.
1088 rendered = '{}(\n{})'.format(obj_name, ''.join(
1144 rendered = '{}(\n{})'.format(obj_name, ''.join(
1089 ' {},\n'.format(r) for r in result)
1145 ' {},\n'.format(r) for r in result)
1090 )
1146 )
1091 else:
1147 else:
1092 rendered = '{}({})'.format(obj_name, ', '.join(result))
1148 rendered = '{}({})'.format(obj_name, ', '.join(result))
1093
1149
1094 if obj_signature.return_annotation is not inspect._empty:
1150 if obj_signature.return_annotation is not inspect._empty:
1095 anno = inspect.formatannotation(obj_signature.return_annotation)
1151 anno = inspect.formatannotation(obj_signature.return_annotation)
1096 rendered += ' -> {}'.format(anno)
1152 rendered += ' -> {}'.format(anno)
1097
1153
1098 return rendered
1154 return rendered
@@ -1,541 +1,578 b''
1 """Tests for the object inspection functionality.
1 """Tests for the object inspection functionality.
2 """
2 """
3
3
4 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7
7
8 from contextlib import contextmanager
8 from contextlib import contextmanager
9 from inspect import signature, Signature, Parameter
9 from inspect import signature, Signature, Parameter
10 import inspect
10 import inspect
11 import os
11 import os
12 import pytest
12 import pytest
13 import re
13 import re
14 import sys
14 import sys
15
15
16 from .. import oinspect
16 from .. import oinspect
17
17
18 from decorator import decorator
18 from decorator import decorator
19
19
20 from IPython.testing.tools import AssertPrints, AssertNotPrints
20 from IPython.testing.tools import AssertPrints, AssertNotPrints
21 from IPython.utils.path import compress_user
21 from IPython.utils.path import compress_user
22
22
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Globals and constants
25 # Globals and constants
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 inspector = None
28 inspector = None
29
29
30 def setup_module():
30 def setup_module():
31 global inspector
31 global inspector
32 inspector = oinspect.Inspector()
32 inspector = oinspect.Inspector()
33
33
34
34
35 class SourceModuleMainTest:
35 class SourceModuleMainTest:
36 __module__ = "__main__"
36 __module__ = "__main__"
37
37
38
38
39 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
40 # Local utilities
40 # Local utilities
41 #-----------------------------------------------------------------------------
41 #-----------------------------------------------------------------------------
42
42
43 # WARNING: since this test checks the line number where a function is
43 # WARNING: since this test checks the line number where a function is
44 # defined, if any code is inserted above, the following line will need to be
44 # defined, if any code is inserted above, the following line will need to be
45 # updated. Do NOT insert any whitespace between the next line and the function
45 # updated. Do NOT insert any whitespace between the next line and the function
46 # definition below.
46 # definition below.
47 THIS_LINE_NUMBER = 47 # Put here the actual number of this line
47 THIS_LINE_NUMBER = 47 # Put here the actual number of this line
48
48
49
49
50 def test_find_source_lines():
50 def test_find_source_lines():
51 assert oinspect.find_source_lines(test_find_source_lines) == THIS_LINE_NUMBER + 3
51 assert oinspect.find_source_lines(test_find_source_lines) == THIS_LINE_NUMBER + 3
52 assert oinspect.find_source_lines(type) is None
52 assert oinspect.find_source_lines(type) is None
53 assert oinspect.find_source_lines(SourceModuleMainTest) is None
53 assert oinspect.find_source_lines(SourceModuleMainTest) is None
54 assert oinspect.find_source_lines(SourceModuleMainTest()) is None
54 assert oinspect.find_source_lines(SourceModuleMainTest()) is None
55
55
56
56
57 def test_getsource():
57 def test_getsource():
58 assert oinspect.getsource(type) is None
58 assert oinspect.getsource(type) is None
59 assert oinspect.getsource(SourceModuleMainTest) is None
59 assert oinspect.getsource(SourceModuleMainTest) is None
60 assert oinspect.getsource(SourceModuleMainTest()) is None
60 assert oinspect.getsource(SourceModuleMainTest()) is None
61
61
62
62
63 def test_inspect_getfile_raises_exception():
63 def test_inspect_getfile_raises_exception():
64 """Check oinspect.find_file/getsource/find_source_lines expectations"""
64 """Check oinspect.find_file/getsource/find_source_lines expectations"""
65 with pytest.raises(TypeError):
65 with pytest.raises(TypeError):
66 inspect.getfile(type)
66 inspect.getfile(type)
67 with pytest.raises(OSError if sys.version_info >= (3, 10) else TypeError):
67 with pytest.raises(OSError if sys.version_info >= (3, 10) else TypeError):
68 inspect.getfile(SourceModuleMainTest)
68 inspect.getfile(SourceModuleMainTest)
69
69
70
70
71 # A couple of utilities to ensure these tests work the same from a source or a
71 # A couple of utilities to ensure these tests work the same from a source or a
72 # binary install
72 # binary install
73 def pyfile(fname):
73 def pyfile(fname):
74 return os.path.normcase(re.sub('.py[co]$', '.py', fname))
74 return os.path.normcase(re.sub('.py[co]$', '.py', fname))
75
75
76
76
77 def match_pyfiles(f1, f2):
77 def match_pyfiles(f1, f2):
78 assert pyfile(f1) == pyfile(f2)
78 assert pyfile(f1) == pyfile(f2)
79
79
80
80
81 def test_find_file():
81 def test_find_file():
82 match_pyfiles(oinspect.find_file(test_find_file), os.path.abspath(__file__))
82 match_pyfiles(oinspect.find_file(test_find_file), os.path.abspath(__file__))
83 assert oinspect.find_file(type) is None
83 assert oinspect.find_file(type) is None
84 assert oinspect.find_file(SourceModuleMainTest) is None
84 assert oinspect.find_file(SourceModuleMainTest) is None
85 assert oinspect.find_file(SourceModuleMainTest()) is None
85 assert oinspect.find_file(SourceModuleMainTest()) is None
86
86
87
87
88 def test_find_file_decorated1():
88 def test_find_file_decorated1():
89
89
90 @decorator
90 @decorator
91 def noop1(f):
91 def noop1(f):
92 def wrapper(*a, **kw):
92 def wrapper(*a, **kw):
93 return f(*a, **kw)
93 return f(*a, **kw)
94 return wrapper
94 return wrapper
95
95
96 @noop1
96 @noop1
97 def f(x):
97 def f(x):
98 "My docstring"
98 "My docstring"
99
99
100 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
100 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
101 assert f.__doc__ == "My docstring"
101 assert f.__doc__ == "My docstring"
102
102
103
103
104 def test_find_file_decorated2():
104 def test_find_file_decorated2():
105
105
106 @decorator
106 @decorator
107 def noop2(f, *a, **kw):
107 def noop2(f, *a, **kw):
108 return f(*a, **kw)
108 return f(*a, **kw)
109
109
110 @noop2
110 @noop2
111 @noop2
111 @noop2
112 @noop2
112 @noop2
113 def f(x):
113 def f(x):
114 "My docstring 2"
114 "My docstring 2"
115
115
116 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
116 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
117 assert f.__doc__ == "My docstring 2"
117 assert f.__doc__ == "My docstring 2"
118
118
119
119
120 def test_find_file_magic():
120 def test_find_file_magic():
121 run = ip.find_line_magic('run')
121 run = ip.find_line_magic('run')
122 assert oinspect.find_file(run) is not None
122 assert oinspect.find_file(run) is not None
123
123
124
124
125 # A few generic objects we can then inspect in the tests below
125 # A few generic objects we can then inspect in the tests below
126
126
127 class Call(object):
127 class Call(object):
128 """This is the class docstring."""
128 """This is the class docstring."""
129
129
130 def __init__(self, x, y=1):
130 def __init__(self, x, y=1):
131 """This is the constructor docstring."""
131 """This is the constructor docstring."""
132
132
133 def __call__(self, *a, **kw):
133 def __call__(self, *a, **kw):
134 """This is the call docstring."""
134 """This is the call docstring."""
135
135
136 def method(self, x, z=2):
136 def method(self, x, z=2):
137 """Some method's docstring"""
137 """Some method's docstring"""
138
138
139 class HasSignature(object):
139 class HasSignature(object):
140 """This is the class docstring."""
140 """This is the class docstring."""
141 __signature__ = Signature([Parameter('test', Parameter.POSITIONAL_OR_KEYWORD)])
141 __signature__ = Signature([Parameter('test', Parameter.POSITIONAL_OR_KEYWORD)])
142
142
143 def __init__(self, *args):
143 def __init__(self, *args):
144 """This is the init docstring"""
144 """This is the init docstring"""
145
145
146
146
147 class SimpleClass(object):
147 class SimpleClass(object):
148 def method(self, x, z=2):
148 def method(self, x, z=2):
149 """Some method's docstring"""
149 """Some method's docstring"""
150
150
151
151
152 class Awkward(object):
152 class Awkward(object):
153 def __getattr__(self, name):
153 def __getattr__(self, name):
154 raise Exception(name)
154 raise Exception(name)
155
155
156 class NoBoolCall:
156 class NoBoolCall:
157 """
157 """
158 callable with `__bool__` raising should still be inspect-able.
158 callable with `__bool__` raising should still be inspect-able.
159 """
159 """
160
160
161 def __call__(self):
161 def __call__(self):
162 """does nothing"""
162 """does nothing"""
163 pass
163 pass
164
164
165 def __bool__(self):
165 def __bool__(self):
166 """just raise NotImplemented"""
166 """just raise NotImplemented"""
167 raise NotImplementedError('Must be implemented')
167 raise NotImplementedError('Must be implemented')
168
168
169
169
170 class SerialLiar(object):
170 class SerialLiar(object):
171 """Attribute accesses always get another copy of the same class.
171 """Attribute accesses always get another copy of the same class.
172
172
173 unittest.mock.call does something similar, but it's not ideal for testing
173 unittest.mock.call does something similar, but it's not ideal for testing
174 as the failure mode is to eat all your RAM. This gives up after 10k levels.
174 as the failure mode is to eat all your RAM. This gives up after 10k levels.
175 """
175 """
176 def __init__(self, max_fibbing_twig, lies_told=0):
176 def __init__(self, max_fibbing_twig, lies_told=0):
177 if lies_told > 10000:
177 if lies_told > 10000:
178 raise RuntimeError('Nose too long, honesty is the best policy')
178 raise RuntimeError('Nose too long, honesty is the best policy')
179 self.max_fibbing_twig = max_fibbing_twig
179 self.max_fibbing_twig = max_fibbing_twig
180 self.lies_told = lies_told
180 self.lies_told = lies_told
181 max_fibbing_twig[0] = max(max_fibbing_twig[0], lies_told)
181 max_fibbing_twig[0] = max(max_fibbing_twig[0], lies_told)
182
182
183 def __getattr__(self, item):
183 def __getattr__(self, item):
184 return SerialLiar(self.max_fibbing_twig, self.lies_told + 1)
184 return SerialLiar(self.max_fibbing_twig, self.lies_told + 1)
185
185
186 #-----------------------------------------------------------------------------
186 #-----------------------------------------------------------------------------
187 # Tests
187 # Tests
188 #-----------------------------------------------------------------------------
188 #-----------------------------------------------------------------------------
189
189
190 def test_info():
190 def test_info():
191 "Check that Inspector.info fills out various fields as expected."
191 "Check that Inspector.info fills out various fields as expected."
192 i = inspector.info(Call, oname="Call")
192 i = inspector.info(Call, oname="Call")
193 assert i["type_name"] == "type"
193 assert i["type_name"] == "type"
194 expected_class = str(type(type)) # <class 'type'> (Python 3) or <type 'type'>
194 expected_class = str(type(type)) # <class 'type'> (Python 3) or <type 'type'>
195 assert i["base_class"] == expected_class
195 assert i["base_class"] == expected_class
196 assert re.search(
196 assert re.search(
197 "<class 'IPython.core.tests.test_oinspect.Call'( at 0x[0-9a-f]{1,9})?>",
197 "<class 'IPython.core.tests.test_oinspect.Call'( at 0x[0-9a-f]{1,9})?>",
198 i["string_form"],
198 i["string_form"],
199 )
199 )
200 fname = __file__
200 fname = __file__
201 if fname.endswith(".pyc"):
201 if fname.endswith(".pyc"):
202 fname = fname[:-1]
202 fname = fname[:-1]
203 # case-insensitive comparison needed on some filesystems
203 # case-insensitive comparison needed on some filesystems
204 # e.g. Windows:
204 # e.g. Windows:
205 assert i["file"].lower() == compress_user(fname).lower()
205 assert i["file"].lower() == compress_user(fname).lower()
206 assert i["definition"] == None
206 assert i["definition"] == None
207 assert i["docstring"] == Call.__doc__
207 assert i["docstring"] == Call.__doc__
208 assert i["source"] == None
208 assert i["source"] == None
209 assert i["isclass"] is True
209 assert i["isclass"] is True
210 assert i["init_definition"] == "Call(x, y=1)"
210 assert i["init_definition"] == "Call(x, y=1)"
211 assert i["init_docstring"] == Call.__init__.__doc__
211 assert i["init_docstring"] == Call.__init__.__doc__
212
212
213 i = inspector.info(Call, detail_level=1)
213 i = inspector.info(Call, detail_level=1)
214 assert i["source"] is not None
214 assert i["source"] is not None
215 assert i["docstring"] == None
215 assert i["docstring"] == None
216
216
217 c = Call(1)
217 c = Call(1)
218 c.__doc__ = "Modified instance docstring"
218 c.__doc__ = "Modified instance docstring"
219 i = inspector.info(c)
219 i = inspector.info(c)
220 assert i["type_name"] == "Call"
220 assert i["type_name"] == "Call"
221 assert i["docstring"] == "Modified instance docstring"
221 assert i["docstring"] == "Modified instance docstring"
222 assert i["class_docstring"] == Call.__doc__
222 assert i["class_docstring"] == Call.__doc__
223 assert i["init_docstring"] == Call.__init__.__doc__
223 assert i["init_docstring"] == Call.__init__.__doc__
224 assert i["call_docstring"] == Call.__call__.__doc__
224 assert i["call_docstring"] == Call.__call__.__doc__
225
225
226
226
227 def test_class_signature():
227 def test_class_signature():
228 info = inspector.info(HasSignature, "HasSignature")
228 info = inspector.info(HasSignature, "HasSignature")
229 assert info["init_definition"] == "HasSignature(test)"
229 assert info["init_definition"] == "HasSignature(test)"
230 assert info["init_docstring"] == HasSignature.__init__.__doc__
230 assert info["init_docstring"] == HasSignature.__init__.__doc__
231
231
232
232
233 def test_info_awkward():
233 def test_info_awkward():
234 # Just test that this doesn't throw an error.
234 # Just test that this doesn't throw an error.
235 inspector.info(Awkward())
235 inspector.info(Awkward())
236
236
237 def test_bool_raise():
237 def test_bool_raise():
238 inspector.info(NoBoolCall())
238 inspector.info(NoBoolCall())
239
239
240 def test_info_serialliar():
240 def test_info_serialliar():
241 fib_tracker = [0]
241 fib_tracker = [0]
242 inspector.info(SerialLiar(fib_tracker))
242 inspector.info(SerialLiar(fib_tracker))
243
243
244 # Nested attribute access should be cut off at 100 levels deep to avoid
244 # Nested attribute access should be cut off at 100 levels deep to avoid
245 # infinite loops: https://github.com/ipython/ipython/issues/9122
245 # infinite loops: https://github.com/ipython/ipython/issues/9122
246 assert fib_tracker[0] < 9000
246 assert fib_tracker[0] < 9000
247
247
248 def support_function_one(x, y=2, *a, **kw):
248 def support_function_one(x, y=2, *a, **kw):
249 """A simple function."""
249 """A simple function."""
250
250
251 def test_calldef_none():
251 def test_calldef_none():
252 # We should ignore __call__ for all of these.
252 # We should ignore __call__ for all of these.
253 for obj in [support_function_one, SimpleClass().method, any, str.upper]:
253 for obj in [support_function_one, SimpleClass().method, any, str.upper]:
254 i = inspector.info(obj)
254 i = inspector.info(obj)
255 assert i["call_def"] is None
255 assert i["call_def"] is None
256
256
257
257
258 def f_kwarg(pos, *, kwonly):
258 def f_kwarg(pos, *, kwonly):
259 pass
259 pass
260
260
261 def test_definition_kwonlyargs():
261 def test_definition_kwonlyargs():
262 i = inspector.info(f_kwarg, oname="f_kwarg") # analysis:ignore
262 i = inspector.info(f_kwarg, oname="f_kwarg") # analysis:ignore
263 assert i["definition"] == "f_kwarg(pos, *, kwonly)"
263 assert i["definition"] == "f_kwarg(pos, *, kwonly)"
264
264
265
265
266 def test_getdoc():
266 def test_getdoc():
267 class A(object):
267 class A(object):
268 """standard docstring"""
268 """standard docstring"""
269 pass
269 pass
270
270
271 class B(object):
271 class B(object):
272 """standard docstring"""
272 """standard docstring"""
273 def getdoc(self):
273 def getdoc(self):
274 return "custom docstring"
274 return "custom docstring"
275
275
276 class C(object):
276 class C(object):
277 """standard docstring"""
277 """standard docstring"""
278 def getdoc(self):
278 def getdoc(self):
279 return None
279 return None
280
280
281 a = A()
281 a = A()
282 b = B()
282 b = B()
283 c = C()
283 c = C()
284
284
285 assert oinspect.getdoc(a) == "standard docstring"
285 assert oinspect.getdoc(a) == "standard docstring"
286 assert oinspect.getdoc(b) == "custom docstring"
286 assert oinspect.getdoc(b) == "custom docstring"
287 assert oinspect.getdoc(c) == "standard docstring"
287 assert oinspect.getdoc(c) == "standard docstring"
288
288
289
289
290 def test_empty_property_has_no_source():
290 def test_empty_property_has_no_source():
291 i = inspector.info(property(), detail_level=1)
291 i = inspector.info(property(), detail_level=1)
292 assert i["source"] is None
292 assert i["source"] is None
293
293
294
294
295 def test_property_sources():
295 def test_property_sources():
296 # A simple adder whose source and signature stays
296 # A simple adder whose source and signature stays
297 # the same across Python distributions
297 # the same across Python distributions
298 def simple_add(a, b):
298 def simple_add(a, b):
299 "Adds two numbers"
299 "Adds two numbers"
300 return a + b
300 return a + b
301
301
302 class A(object):
302 class A(object):
303 @property
303 @property
304 def foo(self):
304 def foo(self):
305 return 'bar'
305 return 'bar'
306
306
307 foo = foo.setter(lambda self, v: setattr(self, 'bar', v))
307 foo = foo.setter(lambda self, v: setattr(self, 'bar', v))
308
308
309 dname = property(oinspect.getdoc)
309 dname = property(oinspect.getdoc)
310 adder = property(simple_add)
310 adder = property(simple_add)
311
311
312 i = inspector.info(A.foo, detail_level=1)
312 i = inspector.info(A.foo, detail_level=1)
313 assert "def foo(self):" in i["source"]
313 assert "def foo(self):" in i["source"]
314 assert "lambda self, v:" in i["source"]
314 assert "lambda self, v:" in i["source"]
315
315
316 i = inspector.info(A.dname, detail_level=1)
316 i = inspector.info(A.dname, detail_level=1)
317 assert "def getdoc(obj)" in i["source"]
317 assert "def getdoc(obj)" in i["source"]
318
318
319 i = inspector.info(A.adder, detail_level=1)
319 i = inspector.info(A.adder, detail_level=1)
320 assert "def simple_add(a, b)" in i["source"]
320 assert "def simple_add(a, b)" in i["source"]
321
321
322
322
323 def test_property_docstring_is_in_info_for_detail_level_0():
323 def test_property_docstring_is_in_info_for_detail_level_0():
324 class A(object):
324 class A(object):
325 @property
325 @property
326 def foobar(self):
326 def foobar(self):
327 """This is `foobar` property."""
327 """This is `foobar` property."""
328 pass
328 pass
329
329
330 ip.user_ns["a_obj"] = A()
330 ip.user_ns["a_obj"] = A()
331 assert (
331 assert (
332 "This is `foobar` property."
332 "This is `foobar` property."
333 == ip.object_inspect("a_obj.foobar", detail_level=0)["docstring"]
333 == ip.object_inspect("a_obj.foobar", detail_level=0)["docstring"]
334 )
334 )
335
335
336 ip.user_ns["a_cls"] = A
336 ip.user_ns["a_cls"] = A
337 assert (
337 assert (
338 "This is `foobar` property."
338 "This is `foobar` property."
339 == ip.object_inspect("a_cls.foobar", detail_level=0)["docstring"]
339 == ip.object_inspect("a_cls.foobar", detail_level=0)["docstring"]
340 )
340 )
341
341
342
342
343 def test_pdef():
343 def test_pdef():
344 # See gh-1914
344 # See gh-1914
345 def foo(): pass
345 def foo(): pass
346 inspector.pdef(foo, 'foo')
346 inspector.pdef(foo, 'foo')
347
347
348
348
349 @contextmanager
349 @contextmanager
350 def cleanup_user_ns(**kwargs):
350 def cleanup_user_ns(**kwargs):
351 """
351 """
352 On exit delete all the keys that were not in user_ns before entering.
352 On exit delete all the keys that were not in user_ns before entering.
353
353
354 It does not restore old values !
354 It does not restore old values !
355
355
356 Parameters
356 Parameters
357 ----------
357 ----------
358
358
359 **kwargs
359 **kwargs
360 used to update ip.user_ns
360 used to update ip.user_ns
361
361
362 """
362 """
363 try:
363 try:
364 known = set(ip.user_ns.keys())
364 known = set(ip.user_ns.keys())
365 ip.user_ns.update(kwargs)
365 ip.user_ns.update(kwargs)
366 yield
366 yield
367 finally:
367 finally:
368 added = set(ip.user_ns.keys()) - known
368 added = set(ip.user_ns.keys()) - known
369 for k in added:
369 for k in added:
370 del ip.user_ns[k]
370 del ip.user_ns[k]
371
371
372
372
373 def test_pinfo_getindex():
373 def test_pinfo_getindex():
374 def dummy():
374 def dummy():
375 """
375 """
376 MARKER
376 MARKER
377 """
377 """
378
378
379 container = [dummy]
379 container = [dummy]
380 with cleanup_user_ns(container=container):
380 with cleanup_user_ns(container=container):
381 with AssertPrints("MARKER"):
381 with AssertPrints("MARKER"):
382 ip._inspect("pinfo", "container[0]", detail_level=0)
382 ip._inspect("pinfo", "container[0]", detail_level=0)
383 assert "container" not in ip.user_ns.keys()
383 assert "container" not in ip.user_ns.keys()
384
384
385
385
386 def test_qmark_getindex():
386 def test_qmark_getindex():
387 def dummy():
387 def dummy():
388 """
388 """
389 MARKER 2
389 MARKER 2
390 """
390 """
391
391
392 container = [dummy]
392 container = [dummy]
393 with cleanup_user_ns(container=container):
393 with cleanup_user_ns(container=container):
394 with AssertPrints("MARKER 2"):
394 with AssertPrints("MARKER 2"):
395 ip.run_cell("container[0]?")
395 ip.run_cell("container[0]?")
396 assert "container" not in ip.user_ns.keys()
396 assert "container" not in ip.user_ns.keys()
397
397
398
398
399 def test_qmark_getindex_negatif():
399 def test_qmark_getindex_negatif():
400 def dummy():
400 def dummy():
401 """
401 """
402 MARKER 3
402 MARKER 3
403 """
403 """
404
404
405 container = [dummy]
405 container = [dummy]
406 with cleanup_user_ns(container=container):
406 with cleanup_user_ns(container=container):
407 with AssertPrints("MARKER 3"):
407 with AssertPrints("MARKER 3"):
408 ip.run_cell("container[-1]?")
408 ip.run_cell("container[-1]?")
409 assert "container" not in ip.user_ns.keys()
409 assert "container" not in ip.user_ns.keys()
410
410
411
411
412
412
413 def test_pinfo_nonascii():
413 def test_pinfo_nonascii():
414 # See gh-1177
414 # See gh-1177
415 from . import nonascii2
415 from . import nonascii2
416 ip.user_ns['nonascii2'] = nonascii2
416 ip.user_ns['nonascii2'] = nonascii2
417 ip._inspect('pinfo', 'nonascii2', detail_level=1)
417 ip._inspect('pinfo', 'nonascii2', detail_level=1)
418
418
419 def test_pinfo_type():
419 def test_pinfo_type():
420 """
420 """
421 type can fail in various edge case, for example `type.__subclass__()`
421 type can fail in various edge case, for example `type.__subclass__()`
422 """
422 """
423 ip._inspect('pinfo', 'type')
423 ip._inspect('pinfo', 'type')
424
424
425
425
426 def test_pinfo_docstring_no_source():
426 def test_pinfo_docstring_no_source():
427 """Docstring should be included with detail_level=1 if there is no source"""
427 """Docstring should be included with detail_level=1 if there is no source"""
428 with AssertPrints('Docstring:'):
428 with AssertPrints('Docstring:'):
429 ip._inspect('pinfo', 'str.format', detail_level=0)
429 ip._inspect('pinfo', 'str.format', detail_level=0)
430 with AssertPrints('Docstring:'):
430 with AssertPrints('Docstring:'):
431 ip._inspect('pinfo', 'str.format', detail_level=1)
431 ip._inspect('pinfo', 'str.format', detail_level=1)
432
432
433
433
434 def test_pinfo_no_docstring_if_source():
434 def test_pinfo_no_docstring_if_source():
435 """Docstring should not be included with detail_level=1 if source is found"""
435 """Docstring should not be included with detail_level=1 if source is found"""
436 def foo():
436 def foo():
437 """foo has a docstring"""
437 """foo has a docstring"""
438
438
439 ip.user_ns['foo'] = foo
439 ip.user_ns['foo'] = foo
440
440
441 with AssertPrints('Docstring:'):
441 with AssertPrints('Docstring:'):
442 ip._inspect('pinfo', 'foo', detail_level=0)
442 ip._inspect('pinfo', 'foo', detail_level=0)
443 with AssertPrints('Source:'):
443 with AssertPrints('Source:'):
444 ip._inspect('pinfo', 'foo', detail_level=1)
444 ip._inspect('pinfo', 'foo', detail_level=1)
445 with AssertNotPrints('Docstring:'):
445 with AssertNotPrints('Docstring:'):
446 ip._inspect('pinfo', 'foo', detail_level=1)
446 ip._inspect('pinfo', 'foo', detail_level=1)
447
447
448
448
449 def test_pinfo_docstring_if_detail_and_no_source():
449 def test_pinfo_docstring_if_detail_and_no_source():
450 """ Docstring should be displayed if source info not available """
450 """ Docstring should be displayed if source info not available """
451 obj_def = '''class Foo(object):
451 obj_def = '''class Foo(object):
452 """ This is a docstring for Foo """
452 """ This is a docstring for Foo """
453 def bar(self):
453 def bar(self):
454 """ This is a docstring for Foo.bar """
454 """ This is a docstring for Foo.bar """
455 pass
455 pass
456 '''
456 '''
457
457
458 ip.run_cell(obj_def)
458 ip.run_cell(obj_def)
459 ip.run_cell('foo = Foo()')
459 ip.run_cell('foo = Foo()')
460
460
461 with AssertNotPrints("Source:"):
461 with AssertNotPrints("Source:"):
462 with AssertPrints('Docstring:'):
462 with AssertPrints('Docstring:'):
463 ip._inspect('pinfo', 'foo', detail_level=0)
463 ip._inspect('pinfo', 'foo', detail_level=0)
464 with AssertPrints('Docstring:'):
464 with AssertPrints('Docstring:'):
465 ip._inspect('pinfo', 'foo', detail_level=1)
465 ip._inspect('pinfo', 'foo', detail_level=1)
466 with AssertPrints('Docstring:'):
466 with AssertPrints('Docstring:'):
467 ip._inspect('pinfo', 'foo.bar', detail_level=0)
467 ip._inspect('pinfo', 'foo.bar', detail_level=0)
468
468
469 with AssertNotPrints('Docstring:'):
469 with AssertNotPrints('Docstring:'):
470 with AssertPrints('Source:'):
470 with AssertPrints('Source:'):
471 ip._inspect('pinfo', 'foo.bar', detail_level=1)
471 ip._inspect('pinfo', 'foo.bar', detail_level=1)
472
472
473
473
474 def test_pinfo_docstring_dynamic():
475 obj_def = """class Bar:
476 __custom_documentations__ = {
477 "prop" : "cdoc for prop",
478 "non_exist" : "cdoc for non_exist",
479 }
480 @property
481 def prop(self):
482 '''
483 Docstring for prop
484 '''
485 return self._prop
486
487 @prop.setter
488 def prop(self, v):
489 self._prop = v
490 """
491 ip.run_cell(obj_def)
492
493 ip.run_cell("b = Bar()")
494
495 with AssertPrints("Docstring: cdoc for prop"):
496 ip.run_line_magic("pinfo", "b.prop")
497
498 with AssertPrints("Docstring: cdoc for non_exist"):
499 ip.run_line_magic("pinfo", "b.non_exist")
500
501 with AssertPrints("Docstring: cdoc for prop"):
502 ip.run_cell("b.prop?")
503
504 with AssertPrints("Docstring: cdoc for non_exist"):
505 ip.run_cell("b.non_exist?")
506
507 with AssertPrints("Docstring: <no docstring>"):
508 ip.run_cell("b.undefined?")
509
510
474 def test_pinfo_magic():
511 def test_pinfo_magic():
475 with AssertPrints('Docstring:'):
512 with AssertPrints("Docstring:"):
476 ip._inspect('pinfo', 'lsmagic', detail_level=0)
513 ip._inspect("pinfo", "lsmagic", detail_level=0)
477
514
478 with AssertPrints('Source:'):
515 with AssertPrints("Source:"):
479 ip._inspect('pinfo', 'lsmagic', detail_level=1)
516 ip._inspect("pinfo", "lsmagic", detail_level=1)
480
517
481
518
482 def test_init_colors():
519 def test_init_colors():
483 # ensure colors are not present in signature info
520 # ensure colors are not present in signature info
484 info = inspector.info(HasSignature)
521 info = inspector.info(HasSignature)
485 init_def = info["init_definition"]
522 init_def = info["init_definition"]
486 assert "[0m" not in init_def
523 assert "[0m" not in init_def
487
524
488
525
489 def test_builtin_init():
526 def test_builtin_init():
490 info = inspector.info(list)
527 info = inspector.info(list)
491 init_def = info['init_definition']
528 init_def = info['init_definition']
492 assert init_def is not None
529 assert init_def is not None
493
530
494
531
495 def test_render_signature_short():
532 def test_render_signature_short():
496 def short_fun(a=1): pass
533 def short_fun(a=1): pass
497 sig = oinspect._render_signature(
534 sig = oinspect._render_signature(
498 signature(short_fun),
535 signature(short_fun),
499 short_fun.__name__,
536 short_fun.__name__,
500 )
537 )
501 assert sig == "short_fun(a=1)"
538 assert sig == "short_fun(a=1)"
502
539
503
540
504 def test_render_signature_long():
541 def test_render_signature_long():
505 from typing import Optional
542 from typing import Optional
506
543
507 def long_function(
544 def long_function(
508 a_really_long_parameter: int,
545 a_really_long_parameter: int,
509 and_another_long_one: bool = False,
546 and_another_long_one: bool = False,
510 let_us_make_sure_this_is_looong: Optional[str] = None,
547 let_us_make_sure_this_is_looong: Optional[str] = None,
511 ) -> bool: pass
548 ) -> bool: pass
512
549
513 sig = oinspect._render_signature(
550 sig = oinspect._render_signature(
514 signature(long_function),
551 signature(long_function),
515 long_function.__name__,
552 long_function.__name__,
516 )
553 )
517 assert sig in [
554 assert sig in [
518 # Python >=3.9
555 # Python >=3.9
519 '''\
556 '''\
520 long_function(
557 long_function(
521 a_really_long_parameter: int,
558 a_really_long_parameter: int,
522 and_another_long_one: bool = False,
559 and_another_long_one: bool = False,
523 let_us_make_sure_this_is_looong: Optional[str] = None,
560 let_us_make_sure_this_is_looong: Optional[str] = None,
524 ) -> bool\
561 ) -> bool\
525 ''',
562 ''',
526 # Python >=3.7
563 # Python >=3.7
527 '''\
564 '''\
528 long_function(
565 long_function(
529 a_really_long_parameter: int,
566 a_really_long_parameter: int,
530 and_another_long_one: bool = False,
567 and_another_long_one: bool = False,
531 let_us_make_sure_this_is_looong: Union[str, NoneType] = None,
568 let_us_make_sure_this_is_looong: Union[str, NoneType] = None,
532 ) -> bool\
569 ) -> bool\
533 ''', # Python <=3.6
570 ''', # Python <=3.6
534 '''\
571 '''\
535 long_function(
572 long_function(
536 a_really_long_parameter:int,
573 a_really_long_parameter:int,
537 and_another_long_one:bool=False,
574 and_another_long_one:bool=False,
538 let_us_make_sure_this_is_looong:Union[str, NoneType]=None,
575 let_us_make_sure_this_is_looong:Union[str, NoneType]=None,
539 ) -> bool\
576 ) -> bool\
540 ''',
577 ''',
541 ]
578 ]
@@ -1,1499 +1,1574 b''
1 ============
1 ============
2 8.x Series
2 8.x Series
3 ============
3 ============
4
4
5 .. _version 8.12.0:
6
7
8 Dynamic documentation dispatch
9 ------------------------------
10
11
12 We are experimenting with dynamic documentation dispatch for object attribute.
13 See :ghissue:`13860`. The goal is to allow object to define documentation for
14 their attributes, properties, even when those are dynamically defined with
15 `__getattr__`.
16
17 In particular when those objects are base types it can be useful to show the
18 documentation
19
20
21 .. code::
22
23 In [1]: class User:
24 ...:
25 ...: __custom_documentations__ = {
26 ...: "first": "The first name of the user.",
27 ...: "last": "The last name of the user.",
28 ...: }
29 ...:
30 ...: first:str
31 ...: last:str
32 ...:
33 ...: def __init__(self, first, last):
34 ...: self.first = first
35 ...: self.last = last
36 ...:
37 ...: @property
38 ...: def full(self):
39 ...: """`self.first` and `self.last` joined by a space."""
40 ...: return self.first + " " + self.last
41 ...:
42 ...:
43 ...: user = Person('Jane', 'Doe')
44
45 In [2]: user.first?
46 Type: str
47 String form: Jane
48 Length: 4
49 Docstring: the first name of a the person object, a str
50 Class docstring:
51 ....
52
53 In [3]: user.last?
54 Type: str
55 String form: Doe
56 Length: 3
57 Docstring: the last name, also a str
58 ...
59
60
61 We can see here the symmetry with IPython looking for the docstring on the
62 properties::
63
64
65 In [4]: user.full?
66 HERE
67 Type: property
68 String form: <property object at 0x102bb15d0>
69 Docstring: first and last join by a space
70
71
72 Note that while in the above example we use a static dictionary, libraries may
73 decide to use a custom object that define ``__getitem__``, we caution against
74 using objects that would trigger computation to show documentation, but it is
75 sometime preferable for highly dynamic code that for example export ans API as
76 object.
77
78
79
5 .. _version 8.11.0:
80 .. _version 8.11.0:
6
81
7 IPython 8.11
82 IPython 8.11
8 ------------
83 ------------
9
84
10 Back on almost regular monthly schedule for IPython with end-of-month
85 Back on almost regular monthly schedule for IPython with end-of-month
11 really-late-Friday release to make sure some bugs are properly fixed.
86 really-late-Friday release to make sure some bugs are properly fixed.
12 Small addition of with a few new features, bugfix and UX improvements.
87 Small addition of with a few new features, bugfix and UX improvements.
13
88
14 This is a non-exhaustive list, but among other you will find:
89 This is a non-exhaustive list, but among other you will find:
15
90
16 Faster Traceback Highlighting
91 Faster Traceback Highlighting
17 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
92 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
18
93
19 Resurrection of pre-IPython-8 traceback highlighting code.
94 Resurrection of pre-IPython-8 traceback highlighting code.
20
95
21 Really long and complicated files were slow to highlight in traceback with
96 Really long and complicated files were slow to highlight in traceback with
22 IPython 8 despite upstream improvement that make many case better. Therefore
97 IPython 8 despite upstream improvement that make many case better. Therefore
23 starting with IPython 8.11 when one of the highlighted file is more than 10 000
98 starting with IPython 8.11 when one of the highlighted file is more than 10 000
24 line long by default, we'll fallback to a faster path that does not have all the
99 line long by default, we'll fallback to a faster path that does not have all the
25 features of highlighting failing AST nodes.
100 features of highlighting failing AST nodes.
26
101
27 This can be configures by setting the value of
102 This can be configures by setting the value of
28 ``IPython.code.ultratb.FAST_THRESHOLD`` to an arbitrary low or large value.
103 ``IPython.code.ultratb.FAST_THRESHOLD`` to an arbitrary low or large value.
29
104
30
105
31 Autoreload verbosity
106 Autoreload verbosity
32 ~~~~~~~~~~~~~~~~~~~~
107 ~~~~~~~~~~~~~~~~~~~~
33
108
34 We introduce more descriptive names for the ``%autoreload`` parameter:
109 We introduce more descriptive names for the ``%autoreload`` parameter:
35
110
36 - ``%autoreload now`` (also ``%autoreload``) - perform autoreload immediately.
111 - ``%autoreload now`` (also ``%autoreload``) - perform autoreload immediately.
37 - ``%autoreload off`` (also ``%autoreload 0``) - turn off autoreload.
112 - ``%autoreload off`` (also ``%autoreload 0``) - turn off autoreload.
38 - ``%autoreload explicit`` (also ``%autoreload 1``) - turn on autoreload only for modules
113 - ``%autoreload explicit`` (also ``%autoreload 1``) - turn on autoreload only for modules
39 whitelisted by ``%aimport`` statements.
114 whitelisted by ``%aimport`` statements.
40 - ``%autoreload all`` (also ``%autoreload 2``) - turn on autoreload for all modules except those
115 - ``%autoreload all`` (also ``%autoreload 2``) - turn on autoreload for all modules except those
41 blacklisted by ``%aimport`` statements.
116 blacklisted by ``%aimport`` statements.
42 - ``%autoreload complete`` (also ``%autoreload 3``) - all the fatures of ``all`` but also adding new
117 - ``%autoreload complete`` (also ``%autoreload 3``) - all the fatures of ``all`` but also adding new
43 objects from the imported modules (see
118 objects from the imported modules (see
44 IPython/extensions/tests/test_autoreload.py::test_autoload_newly_added_objects).
119 IPython/extensions/tests/test_autoreload.py::test_autoload_newly_added_objects).
45
120
46 The original designations (e.g. "2") still work, and these new ones are case-insensitive.
121 The original designations (e.g. "2") still work, and these new ones are case-insensitive.
47
122
48 Additionally, the option ``--print`` or ``-p`` can be added to the line to print the names of
123 Additionally, the option ``--print`` or ``-p`` can be added to the line to print the names of
49 modules being reloaded. Similarly, ``--log`` or ``-l`` will output the names to the logger at INFO
124 modules being reloaded. Similarly, ``--log`` or ``-l`` will output the names to the logger at INFO
50 level. Both can be used simultaneously.
125 level. Both can be used simultaneously.
51
126
52 The parsing logic for ``%aimport`` is now improved such that modules can be whitelisted and
127 The parsing logic for ``%aimport`` is now improved such that modules can be whitelisted and
53 blacklisted in the same line, e.g. it's now possible to call ``%aimport os, -math`` to include
128 blacklisted in the same line, e.g. it's now possible to call ``%aimport os, -math`` to include
54 ``os`` for ``%autoreload explicit`` and exclude ``math`` for modes ``all`` and ``complete``.
129 ``os`` for ``%autoreload explicit`` and exclude ``math`` for modes ``all`` and ``complete``.
55
130
56 Terminal shortcuts customization
131 Terminal shortcuts customization
57 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
132 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
58
133
59 Previously modifying shortcuts was only possible by hooking into startup files
134 Previously modifying shortcuts was only possible by hooking into startup files
60 and practically limited to adding new shortcuts or removing all shortcuts bound
135 and practically limited to adding new shortcuts or removing all shortcuts bound
61 to a specific key. This release enables users to override existing terminal
136 to a specific key. This release enables users to override existing terminal
62 shortcuts, disable them or add new keybindings.
137 shortcuts, disable them or add new keybindings.
63
138
64 For example, to set the :kbd:`right` to accept a single character of auto-suggestion
139 For example, to set the :kbd:`right` to accept a single character of auto-suggestion
65 you could use::
140 you could use::
66
141
67 my_shortcuts = [
142 my_shortcuts = [
68 {
143 {
69 "command": "IPython:auto_suggest.accept_character",
144 "command": "IPython:auto_suggest.accept_character",
70 "new_keys": ["right"]
145 "new_keys": ["right"]
71 }
146 }
72 ]
147 ]
73 %config TerminalInteractiveShell.shortcuts = my_shortcuts
148 %config TerminalInteractiveShell.shortcuts = my_shortcuts
74
149
75 You can learn more in :std:configtrait:`TerminalInteractiveShell.shortcuts`
150 You can learn more in :std:configtrait:`TerminalInteractiveShell.shortcuts`
76 configuration reference.
151 configuration reference.
77
152
78 Miscellaneous
153 Miscellaneous
79 ~~~~~~~~~~~~~
154 ~~~~~~~~~~~~~
80
155
81 - ``%gui`` should now support PySide6. :ghpull:`13864`
156 - ``%gui`` should now support PySide6. :ghpull:`13864`
82 - Cli shortcuts can now be configured :ghpull:`13928`, see above.
157 - Cli shortcuts can now be configured :ghpull:`13928`, see above.
83 (note that there might be an issue with prompt_toolkit 3.0.37 and shortcut configuration).
158 (note that there might be an issue with prompt_toolkit 3.0.37 and shortcut configuration).
84
159
85 - Capture output should now respect ``;`` semicolon to suppress output.
160 - Capture output should now respect ``;`` semicolon to suppress output.
86 :ghpull:`13940`
161 :ghpull:`13940`
87 - Base64 encoded images (in jupyter frontend), will not have trailing newlines.
162 - Base64 encoded images (in jupyter frontend), will not have trailing newlines.
88 :ghpull:`13941`
163 :ghpull:`13941`
89
164
90 As usual you can find the full list of PRs on GitHub under `the 8.11 milestone
165 As usual you can find the full list of PRs on GitHub under `the 8.11 milestone
91 <https://github.com/ipython/ipython/milestone/113?closed=1>`__.
166 <https://github.com/ipython/ipython/milestone/113?closed=1>`__.
92
167
93 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
168 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
94 work on IPython and related libraries.
169 work on IPython and related libraries.
95
170
96 .. _version 8.10.0:
171 .. _version 8.10.0:
97
172
98 IPython 8.10
173 IPython 8.10
99 ------------
174 ------------
100
175
101 Out of schedule release of IPython with minor fixes to patch a potential CVE-2023-24816.
176 Out of schedule release of IPython with minor fixes to patch a potential CVE-2023-24816.
102 This is a really low severity CVE that you most likely are not affected by unless:
177 This is a really low severity CVE that you most likely are not affected by unless:
103
178
104 - You are on windows.
179 - You are on windows.
105 - You have a custom build of Python without ``_ctypes``
180 - You have a custom build of Python without ``_ctypes``
106 - You cd or start IPython or Jupyter in untrusted directory which names may be
181 - You cd or start IPython or Jupyter in untrusted directory which names may be
107 valid shell commands.
182 valid shell commands.
108
183
109 You can read more on `the advisory
184 You can read more on `the advisory
110 <https://github.com/ipython/ipython/security/advisories/GHSA-29gw-9793-fvw7>`__.
185 <https://github.com/ipython/ipython/security/advisories/GHSA-29gw-9793-fvw7>`__.
111
186
112 In addition to fixing this CVE we also fix a couple of outstanding bugs and issues.
187 In addition to fixing this CVE we also fix a couple of outstanding bugs and issues.
113
188
114 As usual you can find the full list of PRs on GitHub under `the 8.10 milestone
189 As usual you can find the full list of PRs on GitHub under `the 8.10 milestone
115 <https://github.com/ipython/ipython/milestone/112?closed=1>`__.
190 <https://github.com/ipython/ipython/milestone/112?closed=1>`__.
116
191
117 In Particular:
192 In Particular:
118
193
119 - bump minimum numpy to `>=1.21` version following NEP29. :ghpull:`13930`
194 - bump minimum numpy to `>=1.21` version following NEP29. :ghpull:`13930`
120 - fix for compatibility with MyPy 1.0. :ghpull:`13933`
195 - fix for compatibility with MyPy 1.0. :ghpull:`13933`
121 - fix nbgrader stalling when IPython's ``showtraceback`` function is
196 - fix nbgrader stalling when IPython's ``showtraceback`` function is
122 monkeypatched. :ghpull:`13934`
197 monkeypatched. :ghpull:`13934`
123
198
124
199
125
200
126 As this release also contains those minimal changes in addition to fixing the
201 As this release also contains those minimal changes in addition to fixing the
127 CVE I decided to bump the minor version anyway.
202 CVE I decided to bump the minor version anyway.
128
203
129 This will not affect the normal release schedule, so IPython 8.11 is due in
204 This will not affect the normal release schedule, so IPython 8.11 is due in
130 about 2 weeks.
205 about 2 weeks.
131
206
132 .. _version 8.9.0:
207 .. _version 8.9.0:
133
208
134 IPython 8.9.0
209 IPython 8.9.0
135 -------------
210 -------------
136
211
137 Second release of IPython in 2023, last Friday of the month, we are back on
212 Second release of IPython in 2023, last Friday of the month, we are back on
138 track. This is a small release with a few bug-fixes, and improvements, mostly
213 track. This is a small release with a few bug-fixes, and improvements, mostly
139 with respect to terminal shortcuts.
214 with respect to terminal shortcuts.
140
215
141
216
142 The biggest improvement for 8.9 is a drastic amelioration of the
217 The biggest improvement for 8.9 is a drastic amelioration of the
143 auto-suggestions sponsored by D.E. Shaw and implemented by the more and more
218 auto-suggestions sponsored by D.E. Shaw and implemented by the more and more
144 active contributor `@krassowski <https://github.com/krassowski>`.
219 active contributor `@krassowski <https://github.com/krassowski>`.
145
220
146 - ``right`` accepts a single character from suggestion
221 - ``right`` accepts a single character from suggestion
147 - ``ctrl+right`` accepts a semantic token (macos default shortcuts take
222 - ``ctrl+right`` accepts a semantic token (macos default shortcuts take
148 precedence and need to be disabled to make this work)
223 precedence and need to be disabled to make this work)
149 - ``backspace`` deletes a character and resumes hinting autosuggestions
224 - ``backspace`` deletes a character and resumes hinting autosuggestions
150 - ``ctrl-left`` accepts suggestion and moves cursor left one character.
225 - ``ctrl-left`` accepts suggestion and moves cursor left one character.
151 - ``backspace`` deletes a character and resumes hinting autosuggestions
226 - ``backspace`` deletes a character and resumes hinting autosuggestions
152 - ``down`` moves to suggestion to later in history when no lines are present below the cursors.
227 - ``down`` moves to suggestion to later in history when no lines are present below the cursors.
153 - ``up`` moves to suggestion from earlier in history when no lines are present above the cursor.
228 - ``up`` moves to suggestion from earlier in history when no lines are present above the cursor.
154
229
155 This is best described by the Gif posted by `@krassowski
230 This is best described by the Gif posted by `@krassowski
156 <https://github.com/krassowski>`, and in the PR itself :ghpull:`13888`.
231 <https://github.com/krassowski>`, and in the PR itself :ghpull:`13888`.
157
232
158 .. image:: ../_images/autosuggest.gif
233 .. image:: ../_images/autosuggest.gif
159
234
160 Please report any feedback in order for us to improve the user experience.
235 Please report any feedback in order for us to improve the user experience.
161 In particular we are also working on making the shortcuts configurable.
236 In particular we are also working on making the shortcuts configurable.
162
237
163 If you are interested in better terminal shortcuts, I also invite you to
238 If you are interested in better terminal shortcuts, I also invite you to
164 participate in issue `13879
239 participate in issue `13879
165 <https://github.com/ipython/ipython/issues/13879>`__.
240 <https://github.com/ipython/ipython/issues/13879>`__.
166
241
167
242
168 As we follow `NEP29
243 As we follow `NEP29
169 <https://numpy.org/neps/nep-0029-deprecation_policy.html>`__, next version of
244 <https://numpy.org/neps/nep-0029-deprecation_policy.html>`__, next version of
170 IPython will officially stop supporting numpy 1.20, and will stop supporting
245 IPython will officially stop supporting numpy 1.20, and will stop supporting
171 Python 3.8 after April release.
246 Python 3.8 after April release.
172
247
173 As usual you can find the full list of PRs on GitHub under `the 8.9 milestone
248 As usual you can find the full list of PRs on GitHub under `the 8.9 milestone
174 <https://github.com/ipython/ipython/milestone/111?closed=1>`__.
249 <https://github.com/ipython/ipython/milestone/111?closed=1>`__.
175
250
176
251
177 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
252 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
178 work on IPython and related libraries.
253 work on IPython and related libraries.
179
254
180 .. _version 8.8.0:
255 .. _version 8.8.0:
181
256
182 IPython 8.8.0
257 IPython 8.8.0
183 -------------
258 -------------
184
259
185 First release of IPython in 2023 as there was no release at the end of
260 First release of IPython in 2023 as there was no release at the end of
186 December.
261 December.
187
262
188 This is an unusually big release (relatively speaking) with more than 15 Pull
263 This is an unusually big release (relatively speaking) with more than 15 Pull
189 Requests merged.
264 Requests merged.
190
265
191 Of particular interest are:
266 Of particular interest are:
192
267
193 - :ghpull:`13852` that replaces the greedy completer and improves
268 - :ghpull:`13852` that replaces the greedy completer and improves
194 completion, in particular for dictionary keys.
269 completion, in particular for dictionary keys.
195 - :ghpull:`13858` that adds ``py.typed`` to ``setup.cfg`` to make sure it is
270 - :ghpull:`13858` that adds ``py.typed`` to ``setup.cfg`` to make sure it is
196 bundled in wheels.
271 bundled in wheels.
197 - :ghpull:`13869` that implements tab completions for IPython options in the
272 - :ghpull:`13869` that implements tab completions for IPython options in the
198 shell when using `argcomplete <https://github.com/kislyuk/argcomplete>`. I
273 shell when using `argcomplete <https://github.com/kislyuk/argcomplete>`. I
199 believe this also needs a recent version of Traitlets.
274 believe this also needs a recent version of Traitlets.
200 - :ghpull:`13865` makes the ``inspector`` class of `InteractiveShell`
275 - :ghpull:`13865` makes the ``inspector`` class of `InteractiveShell`
201 configurable.
276 configurable.
202 - :ghpull:`13880` that removes minor-version entrypoints as the minor version
277 - :ghpull:`13880` that removes minor-version entrypoints as the minor version
203 entry points that would be included in the wheel would be the one of the
278 entry points that would be included in the wheel would be the one of the
204 Python version that was used to build the ``whl`` file.
279 Python version that was used to build the ``whl`` file.
205
280
206 In no particular order, the rest of the changes update the test suite to be
281 In no particular order, the rest of the changes update the test suite to be
207 compatible with Pygments 2.14, various docfixes, testing on more recent python
282 compatible with Pygments 2.14, various docfixes, testing on more recent python
208 versions and various updates.
283 versions and various updates.
209
284
210 As usual you can find the full list of PRs on GitHub under `the 8.8 milestone
285 As usual you can find the full list of PRs on GitHub under `the 8.8 milestone
211 <https://github.com/ipython/ipython/milestone/110>`__.
286 <https://github.com/ipython/ipython/milestone/110>`__.
212
287
213 Many thanks to @krassowski for the many PRs and @jasongrout for reviewing and
288 Many thanks to @krassowski for the many PRs and @jasongrout for reviewing and
214 merging contributions.
289 merging contributions.
215
290
216 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
291 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
217 work on IPython and related libraries.
292 work on IPython and related libraries.
218
293
219 .. _version 8.7.0:
294 .. _version 8.7.0:
220
295
221 IPython 8.7.0
296 IPython 8.7.0
222 -------------
297 -------------
223
298
224
299
225 Small release of IPython with a couple of bug fixes and new features for this
300 Small release of IPython with a couple of bug fixes and new features for this
226 month. Next month is the end of year, it is unclear if there will be a release
301 month. Next month is the end of year, it is unclear if there will be a release
227 close to the new year's eve, or if the next release will be at the end of January.
302 close to the new year's eve, or if the next release will be at the end of January.
228
303
229 Here are a few of the relevant fixes,
304 Here are a few of the relevant fixes,
230 as usual you can find the full list of PRs on GitHub under `the 8.7 milestone
305 as usual you can find the full list of PRs on GitHub under `the 8.7 milestone
231 <https://github.com/ipython/ipython/pulls?q=milestone%3A8.7>`__.
306 <https://github.com/ipython/ipython/pulls?q=milestone%3A8.7>`__.
232
307
233
308
234 - :ghpull:`13834` bump the minimum prompt toolkit to 3.0.11.
309 - :ghpull:`13834` bump the minimum prompt toolkit to 3.0.11.
235 - IPython shipped with the ``py.typed`` marker now, and we are progressively
310 - IPython shipped with the ``py.typed`` marker now, and we are progressively
236 adding more types. :ghpull:`13831`
311 adding more types. :ghpull:`13831`
237 - :ghpull:`13817` add configuration of code blacks formatting.
312 - :ghpull:`13817` add configuration of code blacks formatting.
238
313
239
314
240 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
315 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
241 work on IPython and related libraries.
316 work on IPython and related libraries.
242
317
243
318
244 .. _version 8.6.0:
319 .. _version 8.6.0:
245
320
246 IPython 8.6.0
321 IPython 8.6.0
247 -------------
322 -------------
248
323
249 Back to a more regular release schedule (at least I try), as Friday is
324 Back to a more regular release schedule (at least I try), as Friday is
250 already over by more than 24h hours. This is a slightly bigger release with a
325 already over by more than 24h hours. This is a slightly bigger release with a
251 few new features that contain no less than 25 PRs.
326 few new features that contain no less than 25 PRs.
252
327
253 We'll notably found a couple of non negligible changes:
328 We'll notably found a couple of non negligible changes:
254
329
255 The ``install_ext`` and related functions have been removed after being
330 The ``install_ext`` and related functions have been removed after being
256 deprecated for years. You can use pip to install extensions. ``pip`` did not
331 deprecated for years. You can use pip to install extensions. ``pip`` did not
257 exist when ``install_ext`` was introduced. You can still load local extensions
332 exist when ``install_ext`` was introduced. You can still load local extensions
258 without installing them. Just set your ``sys.path`` for example. :ghpull:`13744`
333 without installing them. Just set your ``sys.path`` for example. :ghpull:`13744`
259
334
260 IPython now has extra entry points that use the major *and minor* version of
335 IPython now has extra entry points that use the major *and minor* version of
261 python. For some of you this means that you can do a quick ``ipython3.10`` to
336 python. For some of you this means that you can do a quick ``ipython3.10`` to
262 launch IPython from the Python 3.10 interpreter, while still using Python 3.11
337 launch IPython from the Python 3.10 interpreter, while still using Python 3.11
263 as your main Python. :ghpull:`13743`
338 as your main Python. :ghpull:`13743`
264
339
265 The completer matcher API has been improved. See :ghpull:`13745`. This should
340 The completer matcher API has been improved. See :ghpull:`13745`. This should
266 improve the type inference and improve dict keys completions in many use case.
341 improve the type inference and improve dict keys completions in many use case.
267 Thanks ``@krassowski`` for all the work, and the D.E. Shaw group for sponsoring
342 Thanks ``@krassowski`` for all the work, and the D.E. Shaw group for sponsoring
268 it.
343 it.
269
344
270 The color of error nodes in tracebacks can now be customized. See
345 The color of error nodes in tracebacks can now be customized. See
271 :ghpull:`13756`. This is a private attribute until someone finds the time to
346 :ghpull:`13756`. This is a private attribute until someone finds the time to
272 properly add a configuration option. Note that with Python 3.11 that also shows
347 properly add a configuration option. Note that with Python 3.11 that also shows
273 the relevant nodes in traceback, it would be good to leverage this information
348 the relevant nodes in traceback, it would be good to leverage this information
274 (plus the "did you mean" info added on attribute errors). But that's likely work
349 (plus the "did you mean" info added on attribute errors). But that's likely work
275 I won't have time to do before long, so contributions welcome.
350 I won't have time to do before long, so contributions welcome.
276
351
277 As we follow NEP 29, we removed support for numpy 1.19 :ghpull:`13760`.
352 As we follow NEP 29, we removed support for numpy 1.19 :ghpull:`13760`.
278
353
279
354
280 The ``open()`` function present in the user namespace by default will now refuse
355 The ``open()`` function present in the user namespace by default will now refuse
281 to open the file descriptors 0,1,2 (stdin, out, err), to avoid crashing IPython.
356 to open the file descriptors 0,1,2 (stdin, out, err), to avoid crashing IPython.
282 This mostly occurs in teaching context when incorrect values get passed around.
357 This mostly occurs in teaching context when incorrect values get passed around.
283
358
284
359
285 The ``?``, ``??``, and corresponding ``pinfo``, ``pinfo2`` magics can now find
360 The ``?``, ``??``, and corresponding ``pinfo``, ``pinfo2`` magics can now find
286 objects inside arrays. That is to say, the following now works::
361 objects inside arrays. That is to say, the following now works::
287
362
288
363
289 >>> def my_func(*arg, **kwargs):pass
364 >>> def my_func(*arg, **kwargs):pass
290 >>> container = [my_func]
365 >>> container = [my_func]
291 >>> container[0]?
366 >>> container[0]?
292
367
293
368
294 If ``container`` define a custom ``getitem``, this __will__ trigger the custom
369 If ``container`` define a custom ``getitem``, this __will__ trigger the custom
295 method. So don't put side effects in your ``getitems``. Thanks to the D.E. Shaw
370 method. So don't put side effects in your ``getitems``. Thanks to the D.E. Shaw
296 group for the request and sponsoring the work.
371 group for the request and sponsoring the work.
297
372
298
373
299 As usual you can find the full list of PRs on GitHub under `the 8.6 milestone
374 As usual you can find the full list of PRs on GitHub under `the 8.6 milestone
300 <https://github.com/ipython/ipython/pulls?q=milestone%3A8.6>`__.
375 <https://github.com/ipython/ipython/pulls?q=milestone%3A8.6>`__.
301
376
302 Thanks to all hacktoberfest contributors, please contribute to
377 Thanks to all hacktoberfest contributors, please contribute to
303 `closember.org <https://closember.org/>`__.
378 `closember.org <https://closember.org/>`__.
304
379
305 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
380 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
306 work on IPython and related libraries.
381 work on IPython and related libraries.
307
382
308 .. _version 8.5.0:
383 .. _version 8.5.0:
309
384
310 IPython 8.5.0
385 IPython 8.5.0
311 -------------
386 -------------
312
387
313 First release since a couple of month due to various reasons and timing preventing
388 First release since a couple of month due to various reasons and timing preventing
314 me for sticking to the usual monthly release the last Friday of each month. This
389 me for sticking to the usual monthly release the last Friday of each month. This
315 is of non negligible size as it has more than two dozen PRs with various fixes
390 is of non negligible size as it has more than two dozen PRs with various fixes
316 an bug fixes.
391 an bug fixes.
317
392
318 Many thanks to everybody who contributed PRs for your patience in review and
393 Many thanks to everybody who contributed PRs for your patience in review and
319 merges.
394 merges.
320
395
321 Here is a non-exhaustive list of changes that have been implemented for IPython
396 Here is a non-exhaustive list of changes that have been implemented for IPython
322 8.5.0. As usual you can find the full list of issues and PRs tagged with `the
397 8.5.0. As usual you can find the full list of issues and PRs tagged with `the
323 8.5 milestone
398 8.5 milestone
324 <https://github.com/ipython/ipython/pulls?q=is%3Aclosed+milestone%3A8.5+>`__.
399 <https://github.com/ipython/ipython/pulls?q=is%3Aclosed+milestone%3A8.5+>`__.
325
400
326 - Added a shortcut for accepting auto suggestion. The End key shortcut for
401 - Added a shortcut for accepting auto suggestion. The End key shortcut for
327 accepting auto-suggestion This binding works in Vi mode too, provided
402 accepting auto-suggestion This binding works in Vi mode too, provided
328 ``TerminalInteractiveShell.emacs_bindings_in_vi_insert_mode`` is set to be
403 ``TerminalInteractiveShell.emacs_bindings_in_vi_insert_mode`` is set to be
329 ``True`` :ghpull:`13566`.
404 ``True`` :ghpull:`13566`.
330
405
331 - No popup in window for latex generation when generating latex (e.g. via
406 - No popup in window for latex generation when generating latex (e.g. via
332 `_latex_repr_`) no popup window is shows under Windows. :ghpull:`13679`
407 `_latex_repr_`) no popup window is shows under Windows. :ghpull:`13679`
333
408
334 - Fixed error raised when attempting to tab-complete an input string with
409 - Fixed error raised when attempting to tab-complete an input string with
335 consecutive periods or forward slashes (such as "file:///var/log/...").
410 consecutive periods or forward slashes (such as "file:///var/log/...").
336 :ghpull:`13675`
411 :ghpull:`13675`
337
412
338 - Relative filenames in Latex rendering :
413 - Relative filenames in Latex rendering :
339 The `latex_to_png_dvipng` command internally generates input and output file
414 The `latex_to_png_dvipng` command internally generates input and output file
340 arguments to `latex` and `dvipis`. These arguments are now generated as
415 arguments to `latex` and `dvipis`. These arguments are now generated as
341 relative files to the current working directory instead of absolute file
416 relative files to the current working directory instead of absolute file
342 paths. This solves a problem where the current working directory contains
417 paths. This solves a problem where the current working directory contains
343 characters that are not handled properly by `latex` and `dvips`. There are
418 characters that are not handled properly by `latex` and `dvips`. There are
344 no changes to the user API. :ghpull:`13680`
419 no changes to the user API. :ghpull:`13680`
345
420
346 - Stripping decorators bug: Fixed bug which meant that ipython code blocks in
421 - Stripping decorators bug: Fixed bug which meant that ipython code blocks in
347 restructured text documents executed with the ipython-sphinx extension
422 restructured text documents executed with the ipython-sphinx extension
348 skipped any lines of code containing python decorators. :ghpull:`13612`
423 skipped any lines of code containing python decorators. :ghpull:`13612`
349
424
350 - Allow some modules with frozen dataclasses to be reloaded. :ghpull:`13732`
425 - Allow some modules with frozen dataclasses to be reloaded. :ghpull:`13732`
351 - Fix paste magic on wayland. :ghpull:`13671`
426 - Fix paste magic on wayland. :ghpull:`13671`
352 - show maxlen in deque's repr. :ghpull:`13648`
427 - show maxlen in deque's repr. :ghpull:`13648`
353
428
354 Restore line numbers for Input
429 Restore line numbers for Input
355 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
430 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
356
431
357 Line number information in tracebacks from input are restored.
432 Line number information in tracebacks from input are restored.
358 Line numbers from input were removed during the transition to v8 enhanced traceback reporting.
433 Line numbers from input were removed during the transition to v8 enhanced traceback reporting.
359
434
360 So, instead of::
435 So, instead of::
361
436
362 ---------------------------------------------------------------------------
437 ---------------------------------------------------------------------------
363 ZeroDivisionError Traceback (most recent call last)
438 ZeroDivisionError Traceback (most recent call last)
364 Input In [3], in <cell line: 1>()
439 Input In [3], in <cell line: 1>()
365 ----> 1 myfunc(2)
440 ----> 1 myfunc(2)
366
441
367 Input In [2], in myfunc(z)
442 Input In [2], in myfunc(z)
368 1 def myfunc(z):
443 1 def myfunc(z):
369 ----> 2 foo.boo(z-1)
444 ----> 2 foo.boo(z-1)
370
445
371 File ~/code/python/ipython/foo.py:3, in boo(x)
446 File ~/code/python/ipython/foo.py:3, in boo(x)
372 2 def boo(x):
447 2 def boo(x):
373 ----> 3 return 1/(1-x)
448 ----> 3 return 1/(1-x)
374
449
375 ZeroDivisionError: division by zero
450 ZeroDivisionError: division by zero
376
451
377 The error traceback now looks like::
452 The error traceback now looks like::
378
453
379 ---------------------------------------------------------------------------
454 ---------------------------------------------------------------------------
380 ZeroDivisionError Traceback (most recent call last)
455 ZeroDivisionError Traceback (most recent call last)
381 Cell In [3], line 1
456 Cell In [3], line 1
382 ----> 1 myfunc(2)
457 ----> 1 myfunc(2)
383
458
384 Cell In [2], line 2, in myfunc(z)
459 Cell In [2], line 2, in myfunc(z)
385 1 def myfunc(z):
460 1 def myfunc(z):
386 ----> 2 foo.boo(z-1)
461 ----> 2 foo.boo(z-1)
387
462
388 File ~/code/python/ipython/foo.py:3, in boo(x)
463 File ~/code/python/ipython/foo.py:3, in boo(x)
389 2 def boo(x):
464 2 def boo(x):
390 ----> 3 return 1/(1-x)
465 ----> 3 return 1/(1-x)
391
466
392 ZeroDivisionError: division by zero
467 ZeroDivisionError: division by zero
393
468
394 or, with xmode=Plain::
469 or, with xmode=Plain::
395
470
396 Traceback (most recent call last):
471 Traceback (most recent call last):
397 Cell In [12], line 1
472 Cell In [12], line 1
398 myfunc(2)
473 myfunc(2)
399 Cell In [6], line 2 in myfunc
474 Cell In [6], line 2 in myfunc
400 foo.boo(z-1)
475 foo.boo(z-1)
401 File ~/code/python/ipython/foo.py:3 in boo
476 File ~/code/python/ipython/foo.py:3 in boo
402 return 1/(1-x)
477 return 1/(1-x)
403 ZeroDivisionError: division by zero
478 ZeroDivisionError: division by zero
404
479
405 :ghpull:`13560`
480 :ghpull:`13560`
406
481
407 New setting to silence warning if working inside a virtual environment
482 New setting to silence warning if working inside a virtual environment
408 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
483 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
409
484
410 Previously, when starting IPython in a virtual environment without IPython installed (so IPython from the global environment is used), the following warning was printed:
485 Previously, when starting IPython in a virtual environment without IPython installed (so IPython from the global environment is used), the following warning was printed:
411
486
412 Attempting to work in a virtualenv. If you encounter problems, please install IPython inside the virtualenv.
487 Attempting to work in a virtualenv. If you encounter problems, please install IPython inside the virtualenv.
413
488
414 This warning can be permanently silenced by setting ``c.InteractiveShell.warn_venv`` to ``False`` (the default is ``True``).
489 This warning can be permanently silenced by setting ``c.InteractiveShell.warn_venv`` to ``False`` (the default is ``True``).
415
490
416 :ghpull:`13706`
491 :ghpull:`13706`
417
492
418 -------
493 -------
419
494
420 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
495 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
421 work on IPython and related libraries.
496 work on IPython and related libraries.
422
497
423
498
424 .. _version 8.4.0:
499 .. _version 8.4.0:
425
500
426 IPython 8.4.0
501 IPython 8.4.0
427 -------------
502 -------------
428
503
429 As for 7.34, this version contains a single fix: fix uncaught BdbQuit exceptions on ipdb
504 As for 7.34, this version contains a single fix: fix uncaught BdbQuit exceptions on ipdb
430 exit :ghpull:`13668`, and a single typo fix in documentation: :ghpull:`13682`
505 exit :ghpull:`13668`, and a single typo fix in documentation: :ghpull:`13682`
431
506
432 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
507 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
433 work on IPython and related libraries.
508 work on IPython and related libraries.
434
509
435
510
436 .. _version 8.3.0:
511 .. _version 8.3.0:
437
512
438 IPython 8.3.0
513 IPython 8.3.0
439 -------------
514 -------------
440
515
441 - :ghpull:`13625`, using ``?``, ``??``, ``*?`` will not call
516 - :ghpull:`13625`, using ``?``, ``??``, ``*?`` will not call
442 ``set_next_input`` as most frontend allow proper multiline editing and it was
517 ``set_next_input`` as most frontend allow proper multiline editing and it was
443 causing issues for many users of multi-cell frontends. This has been backported to 7.33
518 causing issues for many users of multi-cell frontends. This has been backported to 7.33
444
519
445
520
446 - :ghpull:`13600`, ``pre_run_*``-hooks will now have a ``cell_id`` attribute on
521 - :ghpull:`13600`, ``pre_run_*``-hooks will now have a ``cell_id`` attribute on
447 the info object when frontend provides it. This has been backported to 7.33
522 the info object when frontend provides it. This has been backported to 7.33
448
523
449 - :ghpull:`13624`, fixed :kbd:`End` key being broken after accepting an
524 - :ghpull:`13624`, fixed :kbd:`End` key being broken after accepting an
450 auto-suggestion.
525 auto-suggestion.
451
526
452 - :ghpull:`13657` fixed an issue where history from different sessions would be mixed.
527 - :ghpull:`13657` fixed an issue where history from different sessions would be mixed.
453
528
454 .. _version 8.2.0:
529 .. _version 8.2.0:
455
530
456 IPython 8.2.0
531 IPython 8.2.0
457 -------------
532 -------------
458
533
459 IPython 8.2 mostly bring bugfixes to IPython.
534 IPython 8.2 mostly bring bugfixes to IPython.
460
535
461 - Auto-suggestion can now be elected with the ``end`` key. :ghpull:`13566`
536 - Auto-suggestion can now be elected with the ``end`` key. :ghpull:`13566`
462 - Some traceback issues with ``assert etb is not None`` have been fixed. :ghpull:`13588`
537 - Some traceback issues with ``assert etb is not None`` have been fixed. :ghpull:`13588`
463 - History is now pulled from the sqitel database and not from in-memory.
538 - History is now pulled from the sqitel database and not from in-memory.
464 In particular when using the ``%paste`` magic, the content of the pasted text will
539 In particular when using the ``%paste`` magic, the content of the pasted text will
465 be part of the history and not the verbatim text ``%paste`` anymore. :ghpull:`13592`
540 be part of the history and not the verbatim text ``%paste`` anymore. :ghpull:`13592`
466 - Fix ``Ctrl-\\`` exit cleanup :ghpull:`13603`
541 - Fix ``Ctrl-\\`` exit cleanup :ghpull:`13603`
467 - Fixes to ``ultratb`` ipdb support when used outside of IPython. :ghpull:`13498`
542 - Fixes to ``ultratb`` ipdb support when used outside of IPython. :ghpull:`13498`
468
543
469
544
470 I am still trying to fix and investigate :ghissue:`13598`, which seems to be
545 I am still trying to fix and investigate :ghissue:`13598`, which seems to be
471 random, and would appreciate help if you find a reproducible minimal case. I've
546 random, and would appreciate help if you find a reproducible minimal case. I've
472 tried to make various changes to the codebase to mitigate it, but a proper fix
547 tried to make various changes to the codebase to mitigate it, but a proper fix
473 will be difficult without understanding the cause.
548 will be difficult without understanding the cause.
474
549
475
550
476 All the issues on pull-requests for this release can be found in the `8.2
551 All the issues on pull-requests for this release can be found in the `8.2
477 milestone. <https://github.com/ipython/ipython/milestone/100>`__ . And some
552 milestone. <https://github.com/ipython/ipython/milestone/100>`__ . And some
478 documentation only PR can be found as part of the `7.33 milestone
553 documentation only PR can be found as part of the `7.33 milestone
479 <https://github.com/ipython/ipython/milestone/101>`__ (currently not released).
554 <https://github.com/ipython/ipython/milestone/101>`__ (currently not released).
480
555
481 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
556 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
482 work on IPython and related libraries.
557 work on IPython and related libraries.
483
558
484 .. _version 8.1.1:
559 .. _version 8.1.1:
485
560
486 IPython 8.1.1
561 IPython 8.1.1
487 -------------
562 -------------
488
563
489 Fix an issue with virtualenv and Python 3.8 introduced in 8.1
564 Fix an issue with virtualenv and Python 3.8 introduced in 8.1
490
565
491 Revert :ghpull:`13537` (fix an issue with symlinks in virtualenv) that raises an
566 Revert :ghpull:`13537` (fix an issue with symlinks in virtualenv) that raises an
492 error in Python 3.8, and fixed in a different way in :ghpull:`13559`.
567 error in Python 3.8, and fixed in a different way in :ghpull:`13559`.
493
568
494 .. _version 8.1:
569 .. _version 8.1:
495
570
496 IPython 8.1.0
571 IPython 8.1.0
497 -------------
572 -------------
498
573
499 IPython 8.1 is the first minor release after 8.0 and fixes a number of bugs and
574 IPython 8.1 is the first minor release after 8.0 and fixes a number of bugs and
500 updates a few behaviors that were problematic with the 8.0 as with many new major
575 updates a few behaviors that were problematic with the 8.0 as with many new major
501 release.
576 release.
502
577
503 Note that beyond the changes listed here, IPython 8.1.0 also contains all the
578 Note that beyond the changes listed here, IPython 8.1.0 also contains all the
504 features listed in :ref:`version 7.32`.
579 features listed in :ref:`version 7.32`.
505
580
506 - Misc and multiple fixes around quotation auto-closing. It is now disabled by
581 - Misc and multiple fixes around quotation auto-closing. It is now disabled by
507 default. Run with ``TerminalInteractiveShell.auto_match=True`` to re-enabled
582 default. Run with ``TerminalInteractiveShell.auto_match=True`` to re-enabled
508 - Require pygments>=2.4.0 :ghpull:`13459`, this was implicit in the code, but
583 - Require pygments>=2.4.0 :ghpull:`13459`, this was implicit in the code, but
509 is now explicit in ``setup.cfg``/``setup.py``
584 is now explicit in ``setup.cfg``/``setup.py``
510 - Docs improvement of ``core.magic_arguments`` examples. :ghpull:`13433`
585 - Docs improvement of ``core.magic_arguments`` examples. :ghpull:`13433`
511 - Multi-line edit executes too early with await. :ghpull:`13424`
586 - Multi-line edit executes too early with await. :ghpull:`13424`
512
587
513 - ``black`` is back as an optional dependency, and autoformatting disabled by
588 - ``black`` is back as an optional dependency, and autoformatting disabled by
514 default until some fixes are implemented (black improperly reformat magics).
589 default until some fixes are implemented (black improperly reformat magics).
515 :ghpull:`13471` Additionally the ability to use ``yapf`` as a code
590 :ghpull:`13471` Additionally the ability to use ``yapf`` as a code
516 reformatter has been added :ghpull:`13528` . You can use
591 reformatter has been added :ghpull:`13528` . You can use
517 ``TerminalInteractiveShell.autoformatter="black"``,
592 ``TerminalInteractiveShell.autoformatter="black"``,
518 ``TerminalInteractiveShell.autoformatter="yapf"`` to re-enable auto formating
593 ``TerminalInteractiveShell.autoformatter="yapf"`` to re-enable auto formating
519 with black, or switch to yapf.
594 with black, or switch to yapf.
520
595
521 - Fix and issue where ``display`` was not defined.
596 - Fix and issue where ``display`` was not defined.
522
597
523 - Auto suggestions are now configurable. Currently only
598 - Auto suggestions are now configurable. Currently only
524 ``AutoSuggestFromHistory`` (default) and ``None``. new provider contribution
599 ``AutoSuggestFromHistory`` (default) and ``None``. new provider contribution
525 welcomed. :ghpull:`13475`
600 welcomed. :ghpull:`13475`
526
601
527 - multiple packaging/testing improvement to simplify downstream packaging
602 - multiple packaging/testing improvement to simplify downstream packaging
528 (xfail with reasons, try to not access network...).
603 (xfail with reasons, try to not access network...).
529
604
530 - Update deprecation. ``InteractiveShell.magic`` internal method has been
605 - Update deprecation. ``InteractiveShell.magic`` internal method has been
531 deprecated for many years but did not emit a warning until now.
606 deprecated for many years but did not emit a warning until now.
532
607
533 - internal ``appended_to_syspath`` context manager has been deprecated.
608 - internal ``appended_to_syspath`` context manager has been deprecated.
534
609
535 - fix an issue with symlinks in virtualenv :ghpull:`13537` (Reverted in 8.1.1)
610 - fix an issue with symlinks in virtualenv :ghpull:`13537` (Reverted in 8.1.1)
536
611
537 - Fix an issue with vim mode, where cursor would not be reset on exit :ghpull:`13472`
612 - Fix an issue with vim mode, where cursor would not be reset on exit :ghpull:`13472`
538
613
539 - ipython directive now remove only known pseudo-decorators :ghpull:`13532`
614 - ipython directive now remove only known pseudo-decorators :ghpull:`13532`
540
615
541 - ``IPython/lib/security`` which used to be used for jupyter notebook has been
616 - ``IPython/lib/security`` which used to be used for jupyter notebook has been
542 removed.
617 removed.
543
618
544 - Fix an issue where ``async with`` would execute on new lines. :ghpull:`13436`
619 - Fix an issue where ``async with`` would execute on new lines. :ghpull:`13436`
545
620
546
621
547 We want to remind users that IPython is part of the Jupyter organisations, and
622 We want to remind users that IPython is part of the Jupyter organisations, and
548 thus governed by a Code of Conduct. Some of the behavior we have seen on GitHub is not acceptable.
623 thus governed by a Code of Conduct. Some of the behavior we have seen on GitHub is not acceptable.
549 Abuse and non-respectful comments on discussion will not be tolerated.
624 Abuse and non-respectful comments on discussion will not be tolerated.
550
625
551 Many thanks to all the contributors to this release, many of the above fixed issues and
626 Many thanks to all the contributors to this release, many of the above fixed issues and
552 new features were done by first time contributors, showing there is still
627 new features were done by first time contributors, showing there is still
553 plenty of easy contribution possible in IPython
628 plenty of easy contribution possible in IPython
554 . You can find all individual contributions
629 . You can find all individual contributions
555 to this milestone `on github <https://github.com/ipython/ipython/milestone/91>`__.
630 to this milestone `on github <https://github.com/ipython/ipython/milestone/91>`__.
556
631
557 Thanks as well to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
632 Thanks as well to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
558 work on IPython and related libraries. In particular the Lazy autoloading of
633 work on IPython and related libraries. In particular the Lazy autoloading of
559 magics that you will find described in the 7.32 release notes.
634 magics that you will find described in the 7.32 release notes.
560
635
561
636
562 .. _version 8.0.1:
637 .. _version 8.0.1:
563
638
564 IPython 8.0.1 (CVE-2022-21699)
639 IPython 8.0.1 (CVE-2022-21699)
565 ------------------------------
640 ------------------------------
566
641
567 IPython 8.0.1, 7.31.1 and 5.11 are security releases that change some default
642 IPython 8.0.1, 7.31.1 and 5.11 are security releases that change some default
568 values in order to prevent potential Execution with Unnecessary Privileges.
643 values in order to prevent potential Execution with Unnecessary Privileges.
569
644
570 Almost all version of IPython looks for configuration and profiles in current
645 Almost all version of IPython looks for configuration and profiles in current
571 working directory. Since IPython was developed before pip and environments
646 working directory. Since IPython was developed before pip and environments
572 existed it was used a convenient way to load code/packages in a project
647 existed it was used a convenient way to load code/packages in a project
573 dependant way.
648 dependant way.
574
649
575 In 2022, it is not necessary anymore, and can lead to confusing behavior where
650 In 2022, it is not necessary anymore, and can lead to confusing behavior where
576 for example cloning a repository and starting IPython or loading a notebook from
651 for example cloning a repository and starting IPython or loading a notebook from
577 any Jupyter-Compatible interface that has ipython set as a kernel can lead to
652 any Jupyter-Compatible interface that has ipython set as a kernel can lead to
578 code execution.
653 code execution.
579
654
580
655
581 I did not find any standard way for packaged to advertise CVEs they fix, I'm
656 I did not find any standard way for packaged to advertise CVEs they fix, I'm
582 thus trying to add a ``__patched_cves__`` attribute to the IPython module that
657 thus trying to add a ``__patched_cves__`` attribute to the IPython module that
583 list the CVEs that should have been fixed. This attribute is informational only
658 list the CVEs that should have been fixed. This attribute is informational only
584 as if a executable has a flaw, this value can always be changed by an attacker.
659 as if a executable has a flaw, this value can always be changed by an attacker.
585
660
586 .. code::
661 .. code::
587
662
588 In [1]: import IPython
663 In [1]: import IPython
589
664
590 In [2]: IPython.__patched_cves__
665 In [2]: IPython.__patched_cves__
591 Out[2]: {'CVE-2022-21699'}
666 Out[2]: {'CVE-2022-21699'}
592
667
593 In [3]: 'CVE-2022-21699' in IPython.__patched_cves__
668 In [3]: 'CVE-2022-21699' in IPython.__patched_cves__
594 Out[3]: True
669 Out[3]: True
595
670
596 Thus starting with this version:
671 Thus starting with this version:
597
672
598 - The current working directory is not searched anymore for profiles or
673 - The current working directory is not searched anymore for profiles or
599 configurations files.
674 configurations files.
600 - Added a ``__patched_cves__`` attribute (set of strings) to IPython module that contain
675 - Added a ``__patched_cves__`` attribute (set of strings) to IPython module that contain
601 the list of fixed CVE. This is informational only.
676 the list of fixed CVE. This is informational only.
602
677
603 Further details can be read on the `GitHub Advisory <https://github.com/ipython/ipython/security/advisories/GHSA-pq7m-3gw7-gq5x>`__
678 Further details can be read on the `GitHub Advisory <https://github.com/ipython/ipython/security/advisories/GHSA-pq7m-3gw7-gq5x>`__
604
679
605
680
606 .. _version 8.0:
681 .. _version 8.0:
607
682
608 IPython 8.0
683 IPython 8.0
609 -----------
684 -----------
610
685
611 IPython 8.0 is bringing a large number of new features and improvements to both the
686 IPython 8.0 is bringing a large number of new features and improvements to both the
612 user of the terminal and of the kernel via Jupyter. The removal of compatibility
687 user of the terminal and of the kernel via Jupyter. The removal of compatibility
613 with an older version of Python is also the opportunity to do a couple of
688 with an older version of Python is also the opportunity to do a couple of
614 performance improvements in particular with respect to startup time.
689 performance improvements in particular with respect to startup time.
615 The 8.x branch started diverging from its predecessor around IPython 7.12
690 The 8.x branch started diverging from its predecessor around IPython 7.12
616 (January 2020).
691 (January 2020).
617
692
618 This release contains 250+ pull requests, in addition to many of the features
693 This release contains 250+ pull requests, in addition to many of the features
619 and backports that have made it to the 7.x branch. Please see the
694 and backports that have made it to the 7.x branch. Please see the
620 `8.0 milestone <https://github.com/ipython/ipython/milestone/73?closed=1>`__ for the full list of pull requests.
695 `8.0 milestone <https://github.com/ipython/ipython/milestone/73?closed=1>`__ for the full list of pull requests.
621
696
622 Please feel free to send pull requests to update those notes after release,
697 Please feel free to send pull requests to update those notes after release,
623 I have likely forgotten a few things reviewing 250+ PRs.
698 I have likely forgotten a few things reviewing 250+ PRs.
624
699
625 Dependencies changes/downstream packaging
700 Dependencies changes/downstream packaging
626 -----------------------------------------
701 -----------------------------------------
627
702
628 Most of our building steps have been changed to be (mostly) declarative
703 Most of our building steps have been changed to be (mostly) declarative
629 and follow PEP 517. We are trying to completely remove ``setup.py`` (:ghpull:`13238`) and are
704 and follow PEP 517. We are trying to completely remove ``setup.py`` (:ghpull:`13238`) and are
630 looking for help to do so.
705 looking for help to do so.
631
706
632 - minimum supported ``traitlets`` version is now 5+
707 - minimum supported ``traitlets`` version is now 5+
633 - we now require ``stack_data``
708 - we now require ``stack_data``
634 - minimal Python is now 3.8
709 - minimal Python is now 3.8
635 - ``nose`` is not a testing requirement anymore
710 - ``nose`` is not a testing requirement anymore
636 - ``pytest`` replaces nose.
711 - ``pytest`` replaces nose.
637 - ``iptest``/``iptest3`` cli entrypoints do not exist anymore.
712 - ``iptest``/``iptest3`` cli entrypoints do not exist anymore.
638 - the minimum officially ​supported ``numpy`` version has been bumped, but this should
713 - the minimum officially ​supported ``numpy`` version has been bumped, but this should
639 not have much effect on packaging.
714 not have much effect on packaging.
640
715
641
716
642 Deprecation and removal
717 Deprecation and removal
643 -----------------------
718 -----------------------
644
719
645 We removed almost all features, arguments, functions, and modules that were
720 We removed almost all features, arguments, functions, and modules that were
646 marked as deprecated between IPython 1.0 and 5.0. As a reminder, 5.0 was released
721 marked as deprecated between IPython 1.0 and 5.0. As a reminder, 5.0 was released
647 in 2016, and 1.0 in 2013. Last release of the 5 branch was 5.10.0, in May 2020.
722 in 2016, and 1.0 in 2013. Last release of the 5 branch was 5.10.0, in May 2020.
648 The few remaining deprecated features we left have better deprecation warnings
723 The few remaining deprecated features we left have better deprecation warnings
649 or have been turned into explicit errors for better error messages.
724 or have been turned into explicit errors for better error messages.
650
725
651 I will use this occasion to add the following requests to anyone emitting a
726 I will use this occasion to add the following requests to anyone emitting a
652 deprecation warning:
727 deprecation warning:
653
728
654 - Please add at least ``stacklevel=2`` so that the warning is emitted into the
729 - Please add at least ``stacklevel=2`` so that the warning is emitted into the
655 caller context, and not the callee one.
730 caller context, and not the callee one.
656 - Please add **since which version** something is deprecated.
731 - Please add **since which version** something is deprecated.
657
732
658 As a side note, it is much easier to conditionally compare version
733 As a side note, it is much easier to conditionally compare version
659 numbers rather than using ``try/except`` when functionality changes with a version.
734 numbers rather than using ``try/except`` when functionality changes with a version.
660
735
661 I won't list all the removed features here, but modules like ``IPython.kernel``,
736 I won't list all the removed features here, but modules like ``IPython.kernel``,
662 which was just a shim module around ``ipykernel`` for the past 8 years, have been
737 which was just a shim module around ``ipykernel`` for the past 8 years, have been
663 removed, and so many other similar things that pre-date the name **Jupyter**
738 removed, and so many other similar things that pre-date the name **Jupyter**
664 itself.
739 itself.
665
740
666 We no longer need to add ``IPython.extensions`` to the PYTHONPATH because that is being
741 We no longer need to add ``IPython.extensions`` to the PYTHONPATH because that is being
667 handled by ``load_extension``.
742 handled by ``load_extension``.
668
743
669 We are also removing ``Cythonmagic``, ``sympyprinting`` and ``rmagic`` as they are now in
744 We are also removing ``Cythonmagic``, ``sympyprinting`` and ``rmagic`` as they are now in
670 other packages and no longer need to be inside IPython.
745 other packages and no longer need to be inside IPython.
671
746
672
747
673 Documentation
748 Documentation
674 -------------
749 -------------
675
750
676 The majority of our docstrings have now been reformatted and automatically fixed by
751 The majority of our docstrings have now been reformatted and automatically fixed by
677 the experimental `Vélin <https://pypi.org/project/velin/>`_ project to conform
752 the experimental `Vélin <https://pypi.org/project/velin/>`_ project to conform
678 to numpydoc.
753 to numpydoc.
679
754
680 Type annotations
755 Type annotations
681 ----------------
756 ----------------
682
757
683 While IPython itself is highly dynamic and can't be completely typed, many of
758 While IPython itself is highly dynamic and can't be completely typed, many of
684 the functions now have type annotations, and part of the codebase is now checked
759 the functions now have type annotations, and part of the codebase is now checked
685 by mypy.
760 by mypy.
686
761
687
762
688 Featured changes
763 Featured changes
689 ----------------
764 ----------------
690
765
691 Here is a features list of changes in IPython 8.0. This is of course non-exhaustive.
766 Here is a features list of changes in IPython 8.0. This is of course non-exhaustive.
692 Please note as well that many features have been added in the 7.x branch as well
767 Please note as well that many features have been added in the 7.x branch as well
693 (and hence why you want to read the 7.x what's new notes), in particular
768 (and hence why you want to read the 7.x what's new notes), in particular
694 features contributed by QuantStack (with respect to debugger protocol and Xeus
769 features contributed by QuantStack (with respect to debugger protocol and Xeus
695 Python), as well as many debugger features that I was pleased to implement as
770 Python), as well as many debugger features that I was pleased to implement as
696 part of my work at QuanSight and sponsored by DE Shaw.
771 part of my work at QuanSight and sponsored by DE Shaw.
697
772
698 Traceback improvements
773 Traceback improvements
699 ~~~~~~~~~~~~~~~~~~~~~~
774 ~~~~~~~~~~~~~~~~~~~~~~
700
775
701 Previously, error tracebacks for errors happening in code cells were showing a
776 Previously, error tracebacks for errors happening in code cells were showing a
702 hash, the one used for compiling the Python AST::
777 hash, the one used for compiling the Python AST::
703
778
704 In [1]: def foo():
779 In [1]: def foo():
705 ...: return 3 / 0
780 ...: return 3 / 0
706 ...:
781 ...:
707
782
708 In [2]: foo()
783 In [2]: foo()
709 ---------------------------------------------------------------------------
784 ---------------------------------------------------------------------------
710 ZeroDivisionError Traceback (most recent call last)
785 ZeroDivisionError Traceback (most recent call last)
711 <ipython-input-2-c19b6d9633cf> in <module>
786 <ipython-input-2-c19b6d9633cf> in <module>
712 ----> 1 foo()
787 ----> 1 foo()
713
788
714 <ipython-input-1-1595a74c32d5> in foo()
789 <ipython-input-1-1595a74c32d5> in foo()
715 1 def foo():
790 1 def foo():
716 ----> 2 return 3 / 0
791 ----> 2 return 3 / 0
717 3
792 3
718
793
719 ZeroDivisionError: division by zero
794 ZeroDivisionError: division by zero
720
795
721 The error traceback is now correctly formatted, showing the cell number in which the error happened::
796 The error traceback is now correctly formatted, showing the cell number in which the error happened::
722
797
723 In [1]: def foo():
798 In [1]: def foo():
724 ...: return 3 / 0
799 ...: return 3 / 0
725 ...:
800 ...:
726
801
727 Input In [2]: foo()
802 Input In [2]: foo()
728 ---------------------------------------------------------------------------
803 ---------------------------------------------------------------------------
729 ZeroDivisionError Traceback (most recent call last)
804 ZeroDivisionError Traceback (most recent call last)
730 input In [2], in <module>
805 input In [2], in <module>
731 ----> 1 foo()
806 ----> 1 foo()
732
807
733 Input In [1], in foo()
808 Input In [1], in foo()
734 1 def foo():
809 1 def foo():
735 ----> 2 return 3 / 0
810 ----> 2 return 3 / 0
736
811
737 ZeroDivisionError: division by zero
812 ZeroDivisionError: division by zero
738
813
739 The ``stack_data`` package has been integrated, which provides smarter information in the traceback;
814 The ``stack_data`` package has been integrated, which provides smarter information in the traceback;
740 in particular it will highlight the AST node where an error occurs which can help to quickly narrow down errors.
815 in particular it will highlight the AST node where an error occurs which can help to quickly narrow down errors.
741
816
742 For example in the following snippet::
817 For example in the following snippet::
743
818
744 def foo(i):
819 def foo(i):
745 x = [[[0]]]
820 x = [[[0]]]
746 return x[0][i][0]
821 return x[0][i][0]
747
822
748
823
749 def bar():
824 def bar():
750 return foo(0) + foo(
825 return foo(0) + foo(
751 1
826 1
752 ) + foo(2)
827 ) + foo(2)
753
828
754
829
755 calling ``bar()`` would raise an ``IndexError`` on the return line of ``foo``,
830 calling ``bar()`` would raise an ``IndexError`` on the return line of ``foo``,
756 and IPython 8.0 is capable of telling you where the index error occurs::
831 and IPython 8.0 is capable of telling you where the index error occurs::
757
832
758
833
759 IndexError
834 IndexError
760 Input In [2], in <module>
835 Input In [2], in <module>
761 ----> 1 bar()
836 ----> 1 bar()
762 ^^^^^
837 ^^^^^
763
838
764 Input In [1], in bar()
839 Input In [1], in bar()
765 6 def bar():
840 6 def bar():
766 ----> 7 return foo(0) + foo(
841 ----> 7 return foo(0) + foo(
767 ^^^^
842 ^^^^
768 8 1
843 8 1
769 ^^^^^^^^
844 ^^^^^^^^
770 9 ) + foo(2)
845 9 ) + foo(2)
771 ^^^^
846 ^^^^
772
847
773 Input In [1], in foo(i)
848 Input In [1], in foo(i)
774 1 def foo(i):
849 1 def foo(i):
775 2 x = [[[0]]]
850 2 x = [[[0]]]
776 ----> 3 return x[0][i][0]
851 ----> 3 return x[0][i][0]
777 ^^^^^^^
852 ^^^^^^^
778
853
779 The corresponding locations marked here with ``^`` will show up highlighted in
854 The corresponding locations marked here with ``^`` will show up highlighted in
780 the terminal and notebooks.
855 the terminal and notebooks.
781
856
782 Finally, a colon ``::`` and line number is appended after a filename in
857 Finally, a colon ``::`` and line number is appended after a filename in
783 traceback::
858 traceback::
784
859
785
860
786 ZeroDivisionError Traceback (most recent call last)
861 ZeroDivisionError Traceback (most recent call last)
787 File ~/error.py:4, in <module>
862 File ~/error.py:4, in <module>
788 1 def f():
863 1 def f():
789 2 1/0
864 2 1/0
790 ----> 4 f()
865 ----> 4 f()
791
866
792 File ~/error.py:2, in f()
867 File ~/error.py:2, in f()
793 1 def f():
868 1 def f():
794 ----> 2 1/0
869 ----> 2 1/0
795
870
796 Many terminals and editors have integrations enabling you to directly jump to the
871 Many terminals and editors have integrations enabling you to directly jump to the
797 relevant file/line when this syntax is used, so this small addition may have a high
872 relevant file/line when this syntax is used, so this small addition may have a high
798 impact on productivity.
873 impact on productivity.
799
874
800
875
801 Autosuggestions
876 Autosuggestions
802 ~~~~~~~~~~~~~~~
877 ~~~~~~~~~~~~~~~
803
878
804 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>`__.
879 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>`__.
805
880
806 `Ptpython <https://github.com/prompt-toolkit/ptpython#ptpython>`__ allows users to enable this feature in
881 `Ptpython <https://github.com/prompt-toolkit/ptpython#ptpython>`__ allows users to enable this feature in
807 `ptpython/config.py <https://github.com/prompt-toolkit/ptpython/blob/master/examples/ptpython_config/config.py#L90>`__.
882 `ptpython/config.py <https://github.com/prompt-toolkit/ptpython/blob/master/examples/ptpython_config/config.py#L90>`__.
808
883
809 This feature allows users to accept autosuggestions with ctrl e, ctrl f,
884 This feature allows users to accept autosuggestions with ctrl e, ctrl f,
810 or right arrow as described below.
885 or right arrow as described below.
811
886
812 1. Start ipython
887 1. Start ipython
813
888
814 .. image:: ../_images/8.0/auto_suggest_1_prompt_no_text.png
889 .. image:: ../_images/8.0/auto_suggest_1_prompt_no_text.png
815
890
816 2. Run ``print("hello")``
891 2. Run ``print("hello")``
817
892
818 .. image:: ../_images/8.0/auto_suggest_2_print_hello_suggest.png
893 .. image:: ../_images/8.0/auto_suggest_2_print_hello_suggest.png
819
894
820 3. start typing ``print`` again to see the autosuggestion
895 3. start typing ``print`` again to see the autosuggestion
821
896
822 .. image:: ../_images/8.0/auto_suggest_3_print_hello_suggest.png
897 .. image:: ../_images/8.0/auto_suggest_3_print_hello_suggest.png
823
898
824 4. Press ``ctrl-f``, or ``ctrl-e``, or ``right-arrow`` to accept the suggestion
899 4. Press ``ctrl-f``, or ``ctrl-e``, or ``right-arrow`` to accept the suggestion
825
900
826 .. image:: ../_images/8.0/auto_suggest_4_print_hello.png
901 .. image:: ../_images/8.0/auto_suggest_4_print_hello.png
827
902
828 You can also complete word by word:
903 You can also complete word by word:
829
904
830 1. Run ``def say_hello(): print("hello")``
905 1. Run ``def say_hello(): print("hello")``
831
906
832 .. image:: ../_images/8.0/auto_suggest_second_prompt.png
907 .. image:: ../_images/8.0/auto_suggest_second_prompt.png
833
908
834 2. Start typing the first letter if ``def`` to see the autosuggestion
909 2. Start typing the first letter if ``def`` to see the autosuggestion
835
910
836 .. image:: ../_images/8.0/auto_suggest_d_phantom.png
911 .. image:: ../_images/8.0/auto_suggest_d_phantom.png
837
912
838 3. Press ``alt-f`` (or ``escape`` followed by ``f``), to accept the first word of the suggestion
913 3. Press ``alt-f`` (or ``escape`` followed by ``f``), to accept the first word of the suggestion
839
914
840 .. image:: ../_images/8.0/auto_suggest_def_phantom.png
915 .. image:: ../_images/8.0/auto_suggest_def_phantom.png
841
916
842 Importantly, this feature does not interfere with tab completion:
917 Importantly, this feature does not interfere with tab completion:
843
918
844 1. After running ``def say_hello(): print("hello")``, press d
919 1. After running ``def say_hello(): print("hello")``, press d
845
920
846 .. image:: ../_images/8.0/auto_suggest_d_phantom.png
921 .. image:: ../_images/8.0/auto_suggest_d_phantom.png
847
922
848 2. Press Tab to start tab completion
923 2. Press Tab to start tab completion
849
924
850 .. image:: ../_images/8.0/auto_suggest_d_completions.png
925 .. image:: ../_images/8.0/auto_suggest_d_completions.png
851
926
852 3A. Press Tab again to select the first option
927 3A. Press Tab again to select the first option
853
928
854 .. image:: ../_images/8.0/auto_suggest_def_completions.png
929 .. image:: ../_images/8.0/auto_suggest_def_completions.png
855
930
856 3B. Press ``alt f`` (``escape``, ``f``) to accept to accept the first word of the suggestion
931 3B. Press ``alt f`` (``escape``, ``f``) to accept to accept the first word of the suggestion
857
932
858 .. image:: ../_images/8.0/auto_suggest_def_phantom.png
933 .. image:: ../_images/8.0/auto_suggest_def_phantom.png
859
934
860 3C. Press ``ctrl-f`` or ``ctrl-e`` to accept the entire suggestion
935 3C. Press ``ctrl-f`` or ``ctrl-e`` to accept the entire suggestion
861
936
862 .. image:: ../_images/8.0/auto_suggest_match_parens.png
937 .. image:: ../_images/8.0/auto_suggest_match_parens.png
863
938
864
939
865 Currently, autosuggestions are only shown in the emacs or vi insert editing modes:
940 Currently, autosuggestions are only shown in the emacs or vi insert editing modes:
866
941
867 - The ctrl e, ctrl f, and alt f shortcuts work by default in emacs mode.
942 - The ctrl e, ctrl f, and alt f shortcuts work by default in emacs mode.
868 - 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/>`__.
943 - 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/>`__.
869
944
870
945
871 Show pinfo information in ipdb using "?" and "??"
946 Show pinfo information in ipdb using "?" and "??"
872 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
947 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
873
948
874 In IPDB, it is now possible to show the information about an object using "?"
949 In IPDB, it is now possible to show the information about an object using "?"
875 and "??", in much the same way that it can be done when using the IPython prompt::
950 and "??", in much the same way that it can be done when using the IPython prompt::
876
951
877 ipdb> partial?
952 ipdb> partial?
878 Init signature: partial(self, /, *args, **kwargs)
953 Init signature: partial(self, /, *args, **kwargs)
879 Docstring:
954 Docstring:
880 partial(func, *args, **keywords) - new function with partial application
955 partial(func, *args, **keywords) - new function with partial application
881 of the given arguments and keywords.
956 of the given arguments and keywords.
882 File: ~/.pyenv/versions/3.8.6/lib/python3.8/functools.py
957 File: ~/.pyenv/versions/3.8.6/lib/python3.8/functools.py
883 Type: type
958 Type: type
884 Subclasses:
959 Subclasses:
885
960
886 Previously, ``pinfo`` or ``pinfo2`` command had to be used for this purpose.
961 Previously, ``pinfo`` or ``pinfo2`` command had to be used for this purpose.
887
962
888
963
889 Autoreload 3 feature
964 Autoreload 3 feature
890 ~~~~~~~~~~~~~~~~~~~~
965 ~~~~~~~~~~~~~~~~~~~~
891
966
892 Example: When an IPython session is run with the 'autoreload' extension loaded,
967 Example: When an IPython session is run with the 'autoreload' extension loaded,
893 you will now have the option '3' to select, which means the following:
968 you will now have the option '3' to select, which means the following:
894
969
895 1. replicate all functionality from option 2
970 1. replicate all functionality from option 2
896 2. autoload all new funcs/classes/enums/globals from the module when they are added
971 2. autoload all new funcs/classes/enums/globals from the module when they are added
897 3. autoload all newly imported funcs/classes/enums/globals from external modules
972 3. autoload all newly imported funcs/classes/enums/globals from external modules
898
973
899 Try ``%autoreload 3`` in an IPython session after running ``%load_ext autoreload``.
974 Try ``%autoreload 3`` in an IPython session after running ``%load_ext autoreload``.
900
975
901 For more information please see the following unit test : ``extensions/tests/test_autoreload.py:test_autoload_newly_added_objects``
976 For more information please see the following unit test : ``extensions/tests/test_autoreload.py:test_autoload_newly_added_objects``
902
977
903 Auto formatting with black in the CLI
978 Auto formatting with black in the CLI
904 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
979 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
905
980
906 This feature was present in 7.x, but disabled by default.
981 This feature was present in 7.x, but disabled by default.
907
982
908 In 8.0, input was automatically reformatted with Black when black was installed.
983 In 8.0, input was automatically reformatted with Black when black was installed.
909 This feature has been reverted for the time being.
984 This feature has been reverted for the time being.
910 You can re-enable it by setting ``TerminalInteractiveShell.autoformatter`` to ``"black"``
985 You can re-enable it by setting ``TerminalInteractiveShell.autoformatter`` to ``"black"``
911
986
912 History Range Glob feature
987 History Range Glob feature
913 ~~~~~~~~~~~~~~~~~~~~~~~~~~
988 ~~~~~~~~~~~~~~~~~~~~~~~~~~
914
989
915 Previously, when using ``%history``, users could specify either
990 Previously, when using ``%history``, users could specify either
916 a range of sessions and lines, for example:
991 a range of sessions and lines, for example:
917
992
918 .. code-block:: python
993 .. code-block:: python
919
994
920 ~8/1-~6/5 # see history from the first line of 8 sessions ago,
995 ~8/1-~6/5 # see history from the first line of 8 sessions ago,
921 # to the fifth line of 6 sessions ago.``
996 # to the fifth line of 6 sessions ago.``
922
997
923 Or users could specify a glob pattern:
998 Or users could specify a glob pattern:
924
999
925 .. code-block:: python
1000 .. code-block:: python
926
1001
927 -g <pattern> # glob ALL history for the specified pattern.
1002 -g <pattern> # glob ALL history for the specified pattern.
928
1003
929 However users could *not* specify both.
1004 However users could *not* specify both.
930
1005
931 If a user *did* specify both a range and a glob pattern,
1006 If a user *did* specify both a range and a glob pattern,
932 then the glob pattern would be used (globbing *all* history) *and the range would be ignored*.
1007 then the glob pattern would be used (globbing *all* history) *and the range would be ignored*.
933
1008
934 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.
1009 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.
935
1010
936 Don't start a multi-line cell with sunken parenthesis
1011 Don't start a multi-line cell with sunken parenthesis
937 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1012 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
938
1013
939 From now on, IPython will not ask for the next line of input when given a single
1014 From now on, IPython will not ask for the next line of input when given a single
940 line with more closing than opening brackets. For example, this means that if
1015 line with more closing than opening brackets. For example, this means that if
941 you (mis)type ``]]`` instead of ``[]``, a ``SyntaxError`` will show up, instead of
1016 you (mis)type ``]]`` instead of ``[]``, a ``SyntaxError`` will show up, instead of
942 the ``...:`` prompt continuation.
1017 the ``...:`` prompt continuation.
943
1018
944 IPython shell for ipdb interact
1019 IPython shell for ipdb interact
945 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1020 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
946
1021
947 The ipdb ``interact`` starts an IPython shell instead of Python's built-in ``code.interact()``.
1022 The ipdb ``interact`` starts an IPython shell instead of Python's built-in ``code.interact()``.
948
1023
949 Automatic Vi prompt stripping
1024 Automatic Vi prompt stripping
950 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1025 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
951
1026
952 When pasting code into IPython, it will strip the leading prompt characters if
1027 When pasting code into IPython, it will strip the leading prompt characters if
953 there are any. For example, you can paste the following code into the console -
1028 there are any. For example, you can paste the following code into the console -
954 it will still work, even though each line is prefixed with prompts (``In``,
1029 it will still work, even though each line is prefixed with prompts (``In``,
955 ``Out``)::
1030 ``Out``)::
956
1031
957 In [1]: 2 * 2 == 4
1032 In [1]: 2 * 2 == 4
958 Out[1]: True
1033 Out[1]: True
959
1034
960 In [2]: print("This still works as pasted")
1035 In [2]: print("This still works as pasted")
961
1036
962
1037
963 Previously, this was not the case for the Vi-mode prompts::
1038 Previously, this was not the case for the Vi-mode prompts::
964
1039
965 In [1]: [ins] In [13]: 2 * 2 == 4
1040 In [1]: [ins] In [13]: 2 * 2 == 4
966 ...: Out[13]: True
1041 ...: Out[13]: True
967 ...:
1042 ...:
968 File "<ipython-input-1-727bb88eaf33>", line 1
1043 File "<ipython-input-1-727bb88eaf33>", line 1
969 [ins] In [13]: 2 * 2 == 4
1044 [ins] In [13]: 2 * 2 == 4
970 ^
1045 ^
971 SyntaxError: invalid syntax
1046 SyntaxError: invalid syntax
972
1047
973 This is now fixed, and Vi prompt prefixes - ``[ins]`` and ``[nav]`` - are
1048 This is now fixed, and Vi prompt prefixes - ``[ins]`` and ``[nav]`` - are
974 skipped just as the normal ``In`` would be.
1049 skipped just as the normal ``In`` would be.
975
1050
976 IPython shell can be started in the Vi mode using ``ipython --TerminalInteractiveShell.editing_mode=vi``,
1051 IPython shell can be started in the Vi mode using ``ipython --TerminalInteractiveShell.editing_mode=vi``,
977 You should be able to change mode dynamically with ``%config TerminalInteractiveShell.editing_mode='vi'``
1052 You should be able to change mode dynamically with ``%config TerminalInteractiveShell.editing_mode='vi'``
978
1053
979 Empty History Ranges
1054 Empty History Ranges
980 ~~~~~~~~~~~~~~~~~~~~
1055 ~~~~~~~~~~~~~~~~~~~~
981
1056
982 A number of magics that take history ranges can now be used with an empty
1057 A number of magics that take history ranges can now be used with an empty
983 range. These magics are:
1058 range. These magics are:
984
1059
985 * ``%save``
1060 * ``%save``
986 * ``%load``
1061 * ``%load``
987 * ``%pastebin``
1062 * ``%pastebin``
988 * ``%pycat``
1063 * ``%pycat``
989
1064
990 Using them this way will make them take the history of the current session up
1065 Using them this way will make them take the history of the current session up
991 to the point of the magic call (such that the magic itself will not be
1066 to the point of the magic call (such that the magic itself will not be
992 included).
1067 included).
993
1068
994 Therefore it is now possible to save the whole history to a file using
1069 Therefore it is now possible to save the whole history to a file using
995 ``%save <filename>``, load and edit it using ``%load`` (makes for a nice usage
1070 ``%save <filename>``, load and edit it using ``%load`` (makes for a nice usage
996 when followed with :kbd:`F2`), send it to `dpaste.org <http://dpast.org>`_ using
1071 when followed with :kbd:`F2`), send it to `dpaste.org <http://dpast.org>`_ using
997 ``%pastebin``, or view the whole thing syntax-highlighted with a single
1072 ``%pastebin``, or view the whole thing syntax-highlighted with a single
998 ``%pycat``.
1073 ``%pycat``.
999
1074
1000
1075
1001 Windows timing implementation: Switch to process_time
1076 Windows timing implementation: Switch to process_time
1002 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1077 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1003 Timing on Windows, for example with ``%%time``, was changed from being based on ``time.perf_counter``
1078 Timing on Windows, for example with ``%%time``, was changed from being based on ``time.perf_counter``
1004 (which counted time even when the process was sleeping) to being based on ``time.process_time`` instead
1079 (which counted time even when the process was sleeping) to being based on ``time.process_time`` instead
1005 (which only counts CPU time). This brings it closer to the behavior on Linux. See :ghpull:`12984`.
1080 (which only counts CPU time). This brings it closer to the behavior on Linux. See :ghpull:`12984`.
1006
1081
1007 Miscellaneous
1082 Miscellaneous
1008 ~~~~~~~~~~~~~
1083 ~~~~~~~~~~~~~
1009 - Non-text formatters are not disabled in the terminal, which should simplify
1084 - Non-text formatters are not disabled in the terminal, which should simplify
1010 writing extensions displaying images or other mimetypes in supporting terminals.
1085 writing extensions displaying images or other mimetypes in supporting terminals.
1011 :ghpull:`12315`
1086 :ghpull:`12315`
1012 - It is now possible to automatically insert matching brackets in Terminal IPython using the
1087 - It is now possible to automatically insert matching brackets in Terminal IPython using the
1013 ``TerminalInteractiveShell.auto_match=True`` option. :ghpull:`12586`
1088 ``TerminalInteractiveShell.auto_match=True`` option. :ghpull:`12586`
1014 - We are thinking of deprecating the current ``%%javascript`` magic in favor of a better replacement. See :ghpull:`13376`.
1089 - We are thinking of deprecating the current ``%%javascript`` magic in favor of a better replacement. See :ghpull:`13376`.
1015 - ``~`` is now expanded when part of a path in most magics :ghpull:`13385`
1090 - ``~`` is now expanded when part of a path in most magics :ghpull:`13385`
1016 - ``%/%%timeit`` magic now adds a comma every thousands to make reading a long number easier :ghpull:`13379`
1091 - ``%/%%timeit`` magic now adds a comma every thousands to make reading a long number easier :ghpull:`13379`
1017 - ``"info"`` messages can now be customised to hide some fields :ghpull:`13343`
1092 - ``"info"`` messages can now be customised to hide some fields :ghpull:`13343`
1018 - ``collections.UserList`` now pretty-prints :ghpull:`13320`
1093 - ``collections.UserList`` now pretty-prints :ghpull:`13320`
1019 - The debugger now has a persistent history, which should make it less
1094 - The debugger now has a persistent history, which should make it less
1020 annoying to retype commands :ghpull:`13246`
1095 annoying to retype commands :ghpull:`13246`
1021 - ``!pip`` ``!conda`` ``!cd`` or ``!ls`` are likely doing the wrong thing. We
1096 - ``!pip`` ``!conda`` ``!cd`` or ``!ls`` are likely doing the wrong thing. We
1022 now warn users if they use one of those commands. :ghpull:`12954`
1097 now warn users if they use one of those commands. :ghpull:`12954`
1023 - Make ``%precision`` work for ``numpy.float64`` type :ghpull:`12902`
1098 - Make ``%precision`` work for ``numpy.float64`` type :ghpull:`12902`
1024
1099
1025 Re-added support for XDG config directories
1100 Re-added support for XDG config directories
1026 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1101 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1027
1102
1028 XDG support through the years comes and goes. There is a tension between having
1103 XDG support through the years comes and goes. There is a tension between having
1029 an identical location for configuration in all platforms versus having simple instructions.
1104 an identical location for configuration in all platforms versus having simple instructions.
1030 After initial failures a couple of years ago, IPython was modified to automatically migrate XDG
1105 After initial failures a couple of years ago, IPython was modified to automatically migrate XDG
1031 config files back into ``~/.ipython``. That migration code has now been removed.
1106 config files back into ``~/.ipython``. That migration code has now been removed.
1032 IPython now checks the XDG locations, so if you _manually_ move your config
1107 IPython now checks the XDG locations, so if you _manually_ move your config
1033 files to your preferred location, IPython will not move them back.
1108 files to your preferred location, IPython will not move them back.
1034
1109
1035
1110
1036 Preparing for Python 3.10
1111 Preparing for Python 3.10
1037 -------------------------
1112 -------------------------
1038
1113
1039 To prepare for Python 3.10, we have started working on removing reliance and
1114 To prepare for Python 3.10, we have started working on removing reliance and
1040 any dependency that is not compatible with Python 3.10. This includes migrating our
1115 any dependency that is not compatible with Python 3.10. This includes migrating our
1041 test suite to pytest and starting to remove nose. This also means that the
1116 test suite to pytest and starting to remove nose. This also means that the
1042 ``iptest`` command is now gone and all testing is via pytest.
1117 ``iptest`` command is now gone and all testing is via pytest.
1043
1118
1044 This was in large part thanks to the NumFOCUS Small Developer grant, which enabled us to
1119 This was in large part thanks to the NumFOCUS Small Developer grant, which enabled us to
1045 allocate \$4000 to hire `Nikita Kniazev (@Kojoley) <https://github.com/Kojoley>`_,
1120 allocate \$4000 to hire `Nikita Kniazev (@Kojoley) <https://github.com/Kojoley>`_,
1046 who did a fantastic job at updating our code base, migrating to pytest, pushing
1121 who did a fantastic job at updating our code base, migrating to pytest, pushing
1047 our coverage, and fixing a large number of bugs. I highly recommend contacting
1122 our coverage, and fixing a large number of bugs. I highly recommend contacting
1048 them if you need help with C++ and Python projects.
1123 them if you need help with C++ and Python projects.
1049
1124
1050 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+>`__
1125 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+>`__
1051
1126
1052 Removing support for older Python versions
1127 Removing support for older Python versions
1053 ------------------------------------------
1128 ------------------------------------------
1054
1129
1055
1130
1056 We are removing support for Python up through 3.7, allowing internal code to use the more
1131 We are removing support for Python up through 3.7, allowing internal code to use the more
1057 efficient ``pathlib`` and to make better use of type annotations.
1132 efficient ``pathlib`` and to make better use of type annotations.
1058
1133
1059 .. image:: ../_images/8.0/pathlib_pathlib_everywhere.jpg
1134 .. image:: ../_images/8.0/pathlib_pathlib_everywhere.jpg
1060 :alt: "Meme image of Toy Story with Woody and Buzz, with the text 'pathlib, pathlib everywhere'"
1135 :alt: "Meme image of Toy Story with Woody and Buzz, with the text 'pathlib, pathlib everywhere'"
1061
1136
1062
1137
1063 We had about 34 PRs only to update some logic to update some functions from managing strings to
1138 We had about 34 PRs only to update some logic to update some functions from managing strings to
1064 using Pathlib.
1139 using Pathlib.
1065
1140
1066 The completer has also seen significant updates and now makes use of newer Jedi APIs,
1141 The completer has also seen significant updates and now makes use of newer Jedi APIs,
1067 offering faster and more reliable tab completion.
1142 offering faster and more reliable tab completion.
1068
1143
1069 Misc Statistics
1144 Misc Statistics
1070 ---------------
1145 ---------------
1071
1146
1072 Here are some numbers::
1147 Here are some numbers::
1073
1148
1074 7.x: 296 files, 12561 blank lines, 20282 comments, 35142 line of code.
1149 7.x: 296 files, 12561 blank lines, 20282 comments, 35142 line of code.
1075 8.0: 252 files, 12053 blank lines, 19232 comments, 34505 line of code.
1150 8.0: 252 files, 12053 blank lines, 19232 comments, 34505 line of code.
1076
1151
1077 $ git diff --stat 7.x...master | tail -1
1152 $ git diff --stat 7.x...master | tail -1
1078 340 files changed, 13399 insertions(+), 12421 deletions(-)
1153 340 files changed, 13399 insertions(+), 12421 deletions(-)
1079
1154
1080 We have commits from 162 authors, who contributed 1916 commits in 23 month, excluding merges (to not bias toward
1155 We have commits from 162 authors, who contributed 1916 commits in 23 month, excluding merges (to not bias toward
1081 maintainers pushing buttons).::
1156 maintainers pushing buttons).::
1082
1157
1083 $ git shortlog -s --no-merges 7.x...master | sort -nr
1158 $ git shortlog -s --no-merges 7.x...master | sort -nr
1084 535 Matthias Bussonnier
1159 535 Matthias Bussonnier
1085 86 Nikita Kniazev
1160 86 Nikita Kniazev
1086 69 Blazej Michalik
1161 69 Blazej Michalik
1087 49 Samuel Gaist
1162 49 Samuel Gaist
1088 27 Itamar Turner-Trauring
1163 27 Itamar Turner-Trauring
1089 18 Spas Kalaydzhisyki
1164 18 Spas Kalaydzhisyki
1090 17 Thomas Kluyver
1165 17 Thomas Kluyver
1091 17 Quentin Peter
1166 17 Quentin Peter
1092 17 James Morris
1167 17 James Morris
1093 17 Artur Svistunov
1168 17 Artur Svistunov
1094 15 Bart Skowron
1169 15 Bart Skowron
1095 14 Alex Hall
1170 14 Alex Hall
1096 13 rushabh-v
1171 13 rushabh-v
1097 13 Terry Davis
1172 13 Terry Davis
1098 13 Benjamin Ragan-Kelley
1173 13 Benjamin Ragan-Kelley
1099 8 martinRenou
1174 8 martinRenou
1100 8 farisachugthai
1175 8 farisachugthai
1101 7 dswij
1176 7 dswij
1102 7 Gal B
1177 7 Gal B
1103 7 Corentin Cadiou
1178 7 Corentin Cadiou
1104 6 yuji96
1179 6 yuji96
1105 6 Martin Skarzynski
1180 6 Martin Skarzynski
1106 6 Justin Palmer
1181 6 Justin Palmer
1107 6 Daniel Goldfarb
1182 6 Daniel Goldfarb
1108 6 Ben Greiner
1183 6 Ben Greiner
1109 5 Sammy Al Hashemi
1184 5 Sammy Al Hashemi
1110 5 Paul Ivanov
1185 5 Paul Ivanov
1111 5 Inception95
1186 5 Inception95
1112 5 Eyenpi
1187 5 Eyenpi
1113 5 Douglas Blank
1188 5 Douglas Blank
1114 5 Coco Mishra
1189 5 Coco Mishra
1115 5 Bibo Hao
1190 5 Bibo Hao
1116 5 André A. Gomes
1191 5 André A. Gomes
1117 5 Ahmed Fasih
1192 5 Ahmed Fasih
1118 4 takuya fujiwara
1193 4 takuya fujiwara
1119 4 palewire
1194 4 palewire
1120 4 Thomas A Caswell
1195 4 Thomas A Caswell
1121 4 Talley Lambert
1196 4 Talley Lambert
1122 4 Scott Sanderson
1197 4 Scott Sanderson
1123 4 Ram Rachum
1198 4 Ram Rachum
1124 4 Nick Muoh
1199 4 Nick Muoh
1125 4 Nathan Goldbaum
1200 4 Nathan Goldbaum
1126 4 Mithil Poojary
1201 4 Mithil Poojary
1127 4 Michael T
1202 4 Michael T
1128 4 Jakub Klus
1203 4 Jakub Klus
1129 4 Ian Castleden
1204 4 Ian Castleden
1130 4 Eli Rykoff
1205 4 Eli Rykoff
1131 4 Ashwin Vishnu
1206 4 Ashwin Vishnu
1132 3 谭九鼎
1207 3 谭九鼎
1133 3 sleeping
1208 3 sleeping
1134 3 Sylvain Corlay
1209 3 Sylvain Corlay
1135 3 Peter Corke
1210 3 Peter Corke
1136 3 Paul Bissex
1211 3 Paul Bissex
1137 3 Matthew Feickert
1212 3 Matthew Feickert
1138 3 Fernando Perez
1213 3 Fernando Perez
1139 3 Eric Wieser
1214 3 Eric Wieser
1140 3 Daniel Mietchen
1215 3 Daniel Mietchen
1141 3 Aditya Sathe
1216 3 Aditya Sathe
1142 3 007vedant
1217 3 007vedant
1143 2 rchiodo
1218 2 rchiodo
1144 2 nicolaslazo
1219 2 nicolaslazo
1145 2 luttik
1220 2 luttik
1146 2 gorogoroumaru
1221 2 gorogoroumaru
1147 2 foobarbyte
1222 2 foobarbyte
1148 2 bar-hen
1223 2 bar-hen
1149 2 Theo Ouzhinski
1224 2 Theo Ouzhinski
1150 2 Strawkage
1225 2 Strawkage
1151 2 Samreen Zarroug
1226 2 Samreen Zarroug
1152 2 Pete Blois
1227 2 Pete Blois
1153 2 Meysam Azad
1228 2 Meysam Azad
1154 2 Matthieu Ancellin
1229 2 Matthieu Ancellin
1155 2 Mark Schmitz
1230 2 Mark Schmitz
1156 2 Maor Kleinberger
1231 2 Maor Kleinberger
1157 2 MRCWirtz
1232 2 MRCWirtz
1158 2 Lumir Balhar
1233 2 Lumir Balhar
1159 2 Julien Rabinow
1234 2 Julien Rabinow
1160 2 Juan Luis Cano Rodríguez
1235 2 Juan Luis Cano Rodríguez
1161 2 Joyce Er
1236 2 Joyce Er
1162 2 Jakub
1237 2 Jakub
1163 2 Faris A Chugthai
1238 2 Faris A Chugthai
1164 2 Ethan Madden
1239 2 Ethan Madden
1165 2 Dimitri Papadopoulos
1240 2 Dimitri Papadopoulos
1166 2 Diego Fernandez
1241 2 Diego Fernandez
1167 2 Daniel Shimon
1242 2 Daniel Shimon
1168 2 Coco Bennett
1243 2 Coco Bennett
1169 2 Carlos Cordoba
1244 2 Carlos Cordoba
1170 2 Boyuan Liu
1245 2 Boyuan Liu
1171 2 BaoGiang HoangVu
1246 2 BaoGiang HoangVu
1172 2 Augusto
1247 2 Augusto
1173 2 Arthur Svistunov
1248 2 Arthur Svistunov
1174 2 Arthur Moreira
1249 2 Arthur Moreira
1175 2 Ali Nabipour
1250 2 Ali Nabipour
1176 2 Adam Hackbarth
1251 2 Adam Hackbarth
1177 1 richard
1252 1 richard
1178 1 linar-jether
1253 1 linar-jether
1179 1 lbennett
1254 1 lbennett
1180 1 juacrumar
1255 1 juacrumar
1181 1 gpotter2
1256 1 gpotter2
1182 1 digitalvirtuoso
1257 1 digitalvirtuoso
1183 1 dalthviz
1258 1 dalthviz
1184 1 Yonatan Goldschmidt
1259 1 Yonatan Goldschmidt
1185 1 Tomasz Kłoczko
1260 1 Tomasz Kłoczko
1186 1 Tobias Bengfort
1261 1 Tobias Bengfort
1187 1 Timur Kushukov
1262 1 Timur Kushukov
1188 1 Thomas
1263 1 Thomas
1189 1 Snir Broshi
1264 1 Snir Broshi
1190 1 Shao Yang Hong
1265 1 Shao Yang Hong
1191 1 Sanjana-03
1266 1 Sanjana-03
1192 1 Romulo Filho
1267 1 Romulo Filho
1193 1 Rodolfo Carvalho
1268 1 Rodolfo Carvalho
1194 1 Richard Shadrach
1269 1 Richard Shadrach
1195 1 Reilly Tucker Siemens
1270 1 Reilly Tucker Siemens
1196 1 Rakessh Roshan
1271 1 Rakessh Roshan
1197 1 Piers Titus van der Torren
1272 1 Piers Titus van der Torren
1198 1 PhanatosZou
1273 1 PhanatosZou
1199 1 Pavel Safronov
1274 1 Pavel Safronov
1200 1 Paulo S. Costa
1275 1 Paulo S. Costa
1201 1 Paul McCarthy
1276 1 Paul McCarthy
1202 1 NotWearingPants
1277 1 NotWearingPants
1203 1 Naelson Douglas
1278 1 Naelson Douglas
1204 1 Michael Tiemann
1279 1 Michael Tiemann
1205 1 Matt Wozniski
1280 1 Matt Wozniski
1206 1 Markus Wageringel
1281 1 Markus Wageringel
1207 1 Marcus Wirtz
1282 1 Marcus Wirtz
1208 1 Marcio Mazza
1283 1 Marcio Mazza
1209 1 Lumír 'Frenzy' Balhar
1284 1 Lumír 'Frenzy' Balhar
1210 1 Lightyagami1
1285 1 Lightyagami1
1211 1 Leon Anavi
1286 1 Leon Anavi
1212 1 LeafyLi
1287 1 LeafyLi
1213 1 L0uisJ0shua
1288 1 L0uisJ0shua
1214 1 Kyle Cutler
1289 1 Kyle Cutler
1215 1 Krzysztof Cybulski
1290 1 Krzysztof Cybulski
1216 1 Kevin Kirsche
1291 1 Kevin Kirsche
1217 1 KIU Shueng Chuan
1292 1 KIU Shueng Chuan
1218 1 Jonathan Slenders
1293 1 Jonathan Slenders
1219 1 Jay Qi
1294 1 Jay Qi
1220 1 Jake VanderPlas
1295 1 Jake VanderPlas
1221 1 Iwan Briquemont
1296 1 Iwan Briquemont
1222 1 Hussaina Begum Nandyala
1297 1 Hussaina Begum Nandyala
1223 1 Gordon Ball
1298 1 Gordon Ball
1224 1 Gabriel Simonetto
1299 1 Gabriel Simonetto
1225 1 Frank Tobia
1300 1 Frank Tobia
1226 1 Erik
1301 1 Erik
1227 1 Elliott Sales de Andrade
1302 1 Elliott Sales de Andrade
1228 1 Daniel Hahler
1303 1 Daniel Hahler
1229 1 Dan Green-Leipciger
1304 1 Dan Green-Leipciger
1230 1 Dan Green
1305 1 Dan Green
1231 1 Damian Yurzola
1306 1 Damian Yurzola
1232 1 Coon, Ethan T
1307 1 Coon, Ethan T
1233 1 Carol Willing
1308 1 Carol Willing
1234 1 Brian Lee
1309 1 Brian Lee
1235 1 Brendan Gerrity
1310 1 Brendan Gerrity
1236 1 Blake Griffin
1311 1 Blake Griffin
1237 1 Bastian Ebeling
1312 1 Bastian Ebeling
1238 1 Bartosz Telenczuk
1313 1 Bartosz Telenczuk
1239 1 Ankitsingh6299
1314 1 Ankitsingh6299
1240 1 Andrew Port
1315 1 Andrew Port
1241 1 Andrew J. Hesford
1316 1 Andrew J. Hesford
1242 1 Albert Zhang
1317 1 Albert Zhang
1243 1 Adam Johnson
1318 1 Adam Johnson
1244
1319
1245 This does not, of course, represent non-code contributions, for which we are also grateful.
1320 This does not, of course, represent non-code contributions, for which we are also grateful.
1246
1321
1247
1322
1248 API Changes using Frappuccino
1323 API Changes using Frappuccino
1249 -----------------------------
1324 -----------------------------
1250
1325
1251 This is an experimental exhaustive API difference using `Frappuccino <https://pypi.org/project/frappuccino/>`_
1326 This is an experimental exhaustive API difference using `Frappuccino <https://pypi.org/project/frappuccino/>`_
1252
1327
1253
1328
1254 The following items are new in IPython 8.0 ::
1329 The following items are new in IPython 8.0 ::
1255
1330
1256 + IPython.core.async_helpers.get_asyncio_loop()
1331 + IPython.core.async_helpers.get_asyncio_loop()
1257 + IPython.core.completer.Dict
1332 + IPython.core.completer.Dict
1258 + IPython.core.completer.Pattern
1333 + IPython.core.completer.Pattern
1259 + IPython.core.completer.Sequence
1334 + IPython.core.completer.Sequence
1260 + IPython.core.completer.__skip_doctest__
1335 + IPython.core.completer.__skip_doctest__
1261 + IPython.core.debugger.Pdb.precmd(self, line)
1336 + IPython.core.debugger.Pdb.precmd(self, line)
1262 + IPython.core.debugger.__skip_doctest__
1337 + IPython.core.debugger.__skip_doctest__
1263 + IPython.core.display.__getattr__(name)
1338 + IPython.core.display.__getattr__(name)
1264 + IPython.core.display.warn
1339 + IPython.core.display.warn
1265 + IPython.core.display_functions
1340 + IPython.core.display_functions
1266 + IPython.core.display_functions.DisplayHandle
1341 + IPython.core.display_functions.DisplayHandle
1267 + IPython.core.display_functions.DisplayHandle.display(self, obj, **kwargs)
1342 + IPython.core.display_functions.DisplayHandle.display(self, obj, **kwargs)
1268 + IPython.core.display_functions.DisplayHandle.update(self, obj, **kwargs)
1343 + IPython.core.display_functions.DisplayHandle.update(self, obj, **kwargs)
1269 + IPython.core.display_functions.__all__
1344 + IPython.core.display_functions.__all__
1270 + IPython.core.display_functions.__builtins__
1345 + IPython.core.display_functions.__builtins__
1271 + IPython.core.display_functions.__cached__
1346 + IPython.core.display_functions.__cached__
1272 + IPython.core.display_functions.__doc__
1347 + IPython.core.display_functions.__doc__
1273 + IPython.core.display_functions.__file__
1348 + IPython.core.display_functions.__file__
1274 + IPython.core.display_functions.__loader__
1349 + IPython.core.display_functions.__loader__
1275 + IPython.core.display_functions.__name__
1350 + IPython.core.display_functions.__name__
1276 + IPython.core.display_functions.__package__
1351 + IPython.core.display_functions.__package__
1277 + IPython.core.display_functions.__spec__
1352 + IPython.core.display_functions.__spec__
1278 + IPython.core.display_functions.b2a_hex
1353 + IPython.core.display_functions.b2a_hex
1279 + IPython.core.display_functions.clear_output(wait=False)
1354 + IPython.core.display_functions.clear_output(wait=False)
1280 + IPython.core.display_functions.display(*objs, include='None', exclude='None', metadata='None', transient='None', display_id='None', raw=False, clear=False, **kwargs)
1355 + IPython.core.display_functions.display(*objs, include='None', exclude='None', metadata='None', transient='None', display_id='None', raw=False, clear=False, **kwargs)
1281 + IPython.core.display_functions.publish_display_data(data, metadata='None', source='<deprecated>', *, transient='None', **kwargs)
1356 + IPython.core.display_functions.publish_display_data(data, metadata='None', source='<deprecated>', *, transient='None', **kwargs)
1282 + IPython.core.display_functions.update_display(obj, *, display_id, **kwargs)
1357 + IPython.core.display_functions.update_display(obj, *, display_id, **kwargs)
1283 + IPython.core.extensions.BUILTINS_EXTS
1358 + IPython.core.extensions.BUILTINS_EXTS
1284 + IPython.core.inputtransformer2.has_sunken_brackets(tokens)
1359 + IPython.core.inputtransformer2.has_sunken_brackets(tokens)
1285 + IPython.core.interactiveshell.Callable
1360 + IPython.core.interactiveshell.Callable
1286 + IPython.core.interactiveshell.__annotations__
1361 + IPython.core.interactiveshell.__annotations__
1287 + IPython.core.ultratb.List
1362 + IPython.core.ultratb.List
1288 + IPython.core.ultratb.Tuple
1363 + IPython.core.ultratb.Tuple
1289 + IPython.lib.pretty.CallExpression
1364 + IPython.lib.pretty.CallExpression
1290 + IPython.lib.pretty.CallExpression.factory(name)
1365 + IPython.lib.pretty.CallExpression.factory(name)
1291 + IPython.lib.pretty.RawStringLiteral
1366 + IPython.lib.pretty.RawStringLiteral
1292 + IPython.lib.pretty.RawText
1367 + IPython.lib.pretty.RawText
1293 + IPython.terminal.debugger.TerminalPdb.do_interact(self, arg)
1368 + IPython.terminal.debugger.TerminalPdb.do_interact(self, arg)
1294 + IPython.terminal.embed.Set
1369 + IPython.terminal.embed.Set
1295
1370
1296 The following items have been removed (or moved to superclass)::
1371 The following items have been removed (or moved to superclass)::
1297
1372
1298 - IPython.core.application.BaseIPythonApplication.initialize_subcommand
1373 - IPython.core.application.BaseIPythonApplication.initialize_subcommand
1299 - IPython.core.completer.Sentinel
1374 - IPython.core.completer.Sentinel
1300 - IPython.core.completer.skip_doctest
1375 - IPython.core.completer.skip_doctest
1301 - IPython.core.debugger.Tracer
1376 - IPython.core.debugger.Tracer
1302 - IPython.core.display.DisplayHandle
1377 - IPython.core.display.DisplayHandle
1303 - IPython.core.display.DisplayHandle.display
1378 - IPython.core.display.DisplayHandle.display
1304 - IPython.core.display.DisplayHandle.update
1379 - IPython.core.display.DisplayHandle.update
1305 - IPython.core.display.b2a_hex
1380 - IPython.core.display.b2a_hex
1306 - IPython.core.display.clear_output
1381 - IPython.core.display.clear_output
1307 - IPython.core.display.display
1382 - IPython.core.display.display
1308 - IPython.core.display.publish_display_data
1383 - IPython.core.display.publish_display_data
1309 - IPython.core.display.update_display
1384 - IPython.core.display.update_display
1310 - IPython.core.excolors.Deprec
1385 - IPython.core.excolors.Deprec
1311 - IPython.core.excolors.ExceptionColors
1386 - IPython.core.excolors.ExceptionColors
1312 - IPython.core.history.warn
1387 - IPython.core.history.warn
1313 - IPython.core.hooks.late_startup_hook
1388 - IPython.core.hooks.late_startup_hook
1314 - IPython.core.hooks.pre_run_code_hook
1389 - IPython.core.hooks.pre_run_code_hook
1315 - IPython.core.hooks.shutdown_hook
1390 - IPython.core.hooks.shutdown_hook
1316 - IPython.core.interactiveshell.InteractiveShell.init_deprecation_warnings
1391 - IPython.core.interactiveshell.InteractiveShell.init_deprecation_warnings
1317 - IPython.core.interactiveshell.InteractiveShell.init_readline
1392 - IPython.core.interactiveshell.InteractiveShell.init_readline
1318 - IPython.core.interactiveshell.InteractiveShell.write
1393 - IPython.core.interactiveshell.InteractiveShell.write
1319 - IPython.core.interactiveshell.InteractiveShell.write_err
1394 - IPython.core.interactiveshell.InteractiveShell.write_err
1320 - IPython.core.interactiveshell.get_default_colors
1395 - IPython.core.interactiveshell.get_default_colors
1321 - IPython.core.interactiveshell.removed_co_newlocals
1396 - IPython.core.interactiveshell.removed_co_newlocals
1322 - IPython.core.magics.execution.ExecutionMagics.profile_missing_notice
1397 - IPython.core.magics.execution.ExecutionMagics.profile_missing_notice
1323 - IPython.core.magics.script.PIPE
1398 - IPython.core.magics.script.PIPE
1324 - IPython.core.prefilter.PrefilterManager.init_transformers
1399 - IPython.core.prefilter.PrefilterManager.init_transformers
1325 - IPython.core.release.classifiers
1400 - IPython.core.release.classifiers
1326 - IPython.core.release.description
1401 - IPython.core.release.description
1327 - IPython.core.release.keywords
1402 - IPython.core.release.keywords
1328 - IPython.core.release.long_description
1403 - IPython.core.release.long_description
1329 - IPython.core.release.name
1404 - IPython.core.release.name
1330 - IPython.core.release.platforms
1405 - IPython.core.release.platforms
1331 - IPython.core.release.url
1406 - IPython.core.release.url
1332 - IPython.core.ultratb.VerboseTB.format_records
1407 - IPython.core.ultratb.VerboseTB.format_records
1333 - IPython.core.ultratb.find_recursion
1408 - IPython.core.ultratb.find_recursion
1334 - IPython.core.ultratb.findsource
1409 - IPython.core.ultratb.findsource
1335 - IPython.core.ultratb.fix_frame_records_filenames
1410 - IPython.core.ultratb.fix_frame_records_filenames
1336 - IPython.core.ultratb.inspect_error
1411 - IPython.core.ultratb.inspect_error
1337 - IPython.core.ultratb.is_recursion_error
1412 - IPython.core.ultratb.is_recursion_error
1338 - IPython.core.ultratb.with_patch_inspect
1413 - IPython.core.ultratb.with_patch_inspect
1339 - IPython.external.__all__
1414 - IPython.external.__all__
1340 - IPython.external.__builtins__
1415 - IPython.external.__builtins__
1341 - IPython.external.__cached__
1416 - IPython.external.__cached__
1342 - IPython.external.__doc__
1417 - IPython.external.__doc__
1343 - IPython.external.__file__
1418 - IPython.external.__file__
1344 - IPython.external.__loader__
1419 - IPython.external.__loader__
1345 - IPython.external.__name__
1420 - IPython.external.__name__
1346 - IPython.external.__package__
1421 - IPython.external.__package__
1347 - IPython.external.__path__
1422 - IPython.external.__path__
1348 - IPython.external.__spec__
1423 - IPython.external.__spec__
1349 - IPython.kernel.KernelConnectionInfo
1424 - IPython.kernel.KernelConnectionInfo
1350 - IPython.kernel.__builtins__
1425 - IPython.kernel.__builtins__
1351 - IPython.kernel.__cached__
1426 - IPython.kernel.__cached__
1352 - IPython.kernel.__warningregistry__
1427 - IPython.kernel.__warningregistry__
1353 - IPython.kernel.pkg
1428 - IPython.kernel.pkg
1354 - IPython.kernel.protocol_version
1429 - IPython.kernel.protocol_version
1355 - IPython.kernel.protocol_version_info
1430 - IPython.kernel.protocol_version_info
1356 - IPython.kernel.src
1431 - IPython.kernel.src
1357 - IPython.kernel.version_info
1432 - IPython.kernel.version_info
1358 - IPython.kernel.warn
1433 - IPython.kernel.warn
1359 - IPython.lib.backgroundjobs
1434 - IPython.lib.backgroundjobs
1360 - IPython.lib.backgroundjobs.BackgroundJobBase
1435 - IPython.lib.backgroundjobs.BackgroundJobBase
1361 - IPython.lib.backgroundjobs.BackgroundJobBase.run
1436 - IPython.lib.backgroundjobs.BackgroundJobBase.run
1362 - IPython.lib.backgroundjobs.BackgroundJobBase.traceback
1437 - IPython.lib.backgroundjobs.BackgroundJobBase.traceback
1363 - IPython.lib.backgroundjobs.BackgroundJobExpr
1438 - IPython.lib.backgroundjobs.BackgroundJobExpr
1364 - IPython.lib.backgroundjobs.BackgroundJobExpr.call
1439 - IPython.lib.backgroundjobs.BackgroundJobExpr.call
1365 - IPython.lib.backgroundjobs.BackgroundJobFunc
1440 - IPython.lib.backgroundjobs.BackgroundJobFunc
1366 - IPython.lib.backgroundjobs.BackgroundJobFunc.call
1441 - IPython.lib.backgroundjobs.BackgroundJobFunc.call
1367 - IPython.lib.backgroundjobs.BackgroundJobManager
1442 - IPython.lib.backgroundjobs.BackgroundJobManager
1368 - IPython.lib.backgroundjobs.BackgroundJobManager.flush
1443 - IPython.lib.backgroundjobs.BackgroundJobManager.flush
1369 - IPython.lib.backgroundjobs.BackgroundJobManager.new
1444 - IPython.lib.backgroundjobs.BackgroundJobManager.new
1370 - IPython.lib.backgroundjobs.BackgroundJobManager.remove
1445 - IPython.lib.backgroundjobs.BackgroundJobManager.remove
1371 - IPython.lib.backgroundjobs.BackgroundJobManager.result
1446 - IPython.lib.backgroundjobs.BackgroundJobManager.result
1372 - IPython.lib.backgroundjobs.BackgroundJobManager.status
1447 - IPython.lib.backgroundjobs.BackgroundJobManager.status
1373 - IPython.lib.backgroundjobs.BackgroundJobManager.traceback
1448 - IPython.lib.backgroundjobs.BackgroundJobManager.traceback
1374 - IPython.lib.backgroundjobs.__builtins__
1449 - IPython.lib.backgroundjobs.__builtins__
1375 - IPython.lib.backgroundjobs.__cached__
1450 - IPython.lib.backgroundjobs.__cached__
1376 - IPython.lib.backgroundjobs.__doc__
1451 - IPython.lib.backgroundjobs.__doc__
1377 - IPython.lib.backgroundjobs.__file__
1452 - IPython.lib.backgroundjobs.__file__
1378 - IPython.lib.backgroundjobs.__loader__
1453 - IPython.lib.backgroundjobs.__loader__
1379 - IPython.lib.backgroundjobs.__name__
1454 - IPython.lib.backgroundjobs.__name__
1380 - IPython.lib.backgroundjobs.__package__
1455 - IPython.lib.backgroundjobs.__package__
1381 - IPython.lib.backgroundjobs.__spec__
1456 - IPython.lib.backgroundjobs.__spec__
1382 - IPython.lib.kernel.__builtins__
1457 - IPython.lib.kernel.__builtins__
1383 - IPython.lib.kernel.__cached__
1458 - IPython.lib.kernel.__cached__
1384 - IPython.lib.kernel.__doc__
1459 - IPython.lib.kernel.__doc__
1385 - IPython.lib.kernel.__file__
1460 - IPython.lib.kernel.__file__
1386 - IPython.lib.kernel.__loader__
1461 - IPython.lib.kernel.__loader__
1387 - IPython.lib.kernel.__name__
1462 - IPython.lib.kernel.__name__
1388 - IPython.lib.kernel.__package__
1463 - IPython.lib.kernel.__package__
1389 - IPython.lib.kernel.__spec__
1464 - IPython.lib.kernel.__spec__
1390 - IPython.lib.kernel.__warningregistry__
1465 - IPython.lib.kernel.__warningregistry__
1391 - IPython.paths.fs_encoding
1466 - IPython.paths.fs_encoding
1392 - IPython.terminal.debugger.DEFAULT_BUFFER
1467 - IPython.terminal.debugger.DEFAULT_BUFFER
1393 - IPython.terminal.debugger.cursor_in_leading_ws
1468 - IPython.terminal.debugger.cursor_in_leading_ws
1394 - IPython.terminal.debugger.emacs_insert_mode
1469 - IPython.terminal.debugger.emacs_insert_mode
1395 - IPython.terminal.debugger.has_selection
1470 - IPython.terminal.debugger.has_selection
1396 - IPython.terminal.debugger.vi_insert_mode
1471 - IPython.terminal.debugger.vi_insert_mode
1397 - IPython.terminal.interactiveshell.DISPLAY_BANNER_DEPRECATED
1472 - IPython.terminal.interactiveshell.DISPLAY_BANNER_DEPRECATED
1398 - IPython.terminal.ipapp.TerminalIPythonApp.parse_command_line
1473 - IPython.terminal.ipapp.TerminalIPythonApp.parse_command_line
1399 - IPython.testing.test
1474 - IPython.testing.test
1400 - IPython.utils.contexts.NoOpContext
1475 - IPython.utils.contexts.NoOpContext
1401 - IPython.utils.io.IOStream
1476 - IPython.utils.io.IOStream
1402 - IPython.utils.io.IOStream.close
1477 - IPython.utils.io.IOStream.close
1403 - IPython.utils.io.IOStream.write
1478 - IPython.utils.io.IOStream.write
1404 - IPython.utils.io.IOStream.writelines
1479 - IPython.utils.io.IOStream.writelines
1405 - IPython.utils.io.__warningregistry__
1480 - IPython.utils.io.__warningregistry__
1406 - IPython.utils.io.atomic_writing
1481 - IPython.utils.io.atomic_writing
1407 - IPython.utils.io.stderr
1482 - IPython.utils.io.stderr
1408 - IPython.utils.io.stdin
1483 - IPython.utils.io.stdin
1409 - IPython.utils.io.stdout
1484 - IPython.utils.io.stdout
1410 - IPython.utils.io.unicode_std_stream
1485 - IPython.utils.io.unicode_std_stream
1411 - IPython.utils.path.get_ipython_cache_dir
1486 - IPython.utils.path.get_ipython_cache_dir
1412 - IPython.utils.path.get_ipython_dir
1487 - IPython.utils.path.get_ipython_dir
1413 - IPython.utils.path.get_ipython_module_path
1488 - IPython.utils.path.get_ipython_module_path
1414 - IPython.utils.path.get_ipython_package_dir
1489 - IPython.utils.path.get_ipython_package_dir
1415 - IPython.utils.path.locate_profile
1490 - IPython.utils.path.locate_profile
1416 - IPython.utils.path.unquote_filename
1491 - IPython.utils.path.unquote_filename
1417 - IPython.utils.py3compat.PY2
1492 - IPython.utils.py3compat.PY2
1418 - IPython.utils.py3compat.PY3
1493 - IPython.utils.py3compat.PY3
1419 - IPython.utils.py3compat.buffer_to_bytes
1494 - IPython.utils.py3compat.buffer_to_bytes
1420 - IPython.utils.py3compat.builtin_mod_name
1495 - IPython.utils.py3compat.builtin_mod_name
1421 - IPython.utils.py3compat.cast_bytes
1496 - IPython.utils.py3compat.cast_bytes
1422 - IPython.utils.py3compat.getcwd
1497 - IPython.utils.py3compat.getcwd
1423 - IPython.utils.py3compat.isidentifier
1498 - IPython.utils.py3compat.isidentifier
1424 - IPython.utils.py3compat.u_format
1499 - IPython.utils.py3compat.u_format
1425
1500
1426 The following signatures differ between 7.x and 8.0::
1501 The following signatures differ between 7.x and 8.0::
1427
1502
1428 - IPython.core.completer.IPCompleter.unicode_name_matches(self, text)
1503 - IPython.core.completer.IPCompleter.unicode_name_matches(self, text)
1429 + IPython.core.completer.IPCompleter.unicode_name_matches(text)
1504 + IPython.core.completer.IPCompleter.unicode_name_matches(text)
1430
1505
1431 - IPython.core.completer.match_dict_keys(keys, prefix, delims)
1506 - IPython.core.completer.match_dict_keys(keys, prefix, delims)
1432 + IPython.core.completer.match_dict_keys(keys, prefix, delims, extra_prefix='None')
1507 + IPython.core.completer.match_dict_keys(keys, prefix, delims, extra_prefix='None')
1433
1508
1434 - IPython.core.interactiveshell.InteractiveShell.object_inspect_mime(self, oname, detail_level=0)
1509 - IPython.core.interactiveshell.InteractiveShell.object_inspect_mime(self, oname, detail_level=0)
1435 + IPython.core.interactiveshell.InteractiveShell.object_inspect_mime(self, oname, detail_level=0, omit_sections='()')
1510 + IPython.core.interactiveshell.InteractiveShell.object_inspect_mime(self, oname, detail_level=0, omit_sections='()')
1436
1511
1437 - IPython.core.interactiveshell.InteractiveShell.set_hook(self, name, hook, priority=50, str_key='None', re_key='None', _warn_deprecated=True)
1512 - IPython.core.interactiveshell.InteractiveShell.set_hook(self, name, hook, priority=50, str_key='None', re_key='None', _warn_deprecated=True)
1438 + IPython.core.interactiveshell.InteractiveShell.set_hook(self, name, hook, priority=50, str_key='None', re_key='None')
1513 + IPython.core.interactiveshell.InteractiveShell.set_hook(self, name, hook, priority=50, str_key='None', re_key='None')
1439
1514
1440 - IPython.core.oinspect.Inspector.info(self, obj, oname='', formatter='None', info='None', detail_level=0)
1515 - IPython.core.oinspect.Inspector.info(self, obj, oname='', formatter='None', info='None', detail_level=0)
1441 + IPython.core.oinspect.Inspector.info(self, obj, oname='', info='None', detail_level=0)
1516 + IPython.core.oinspect.Inspector.info(self, obj, oname='', info='None', detail_level=0)
1442
1517
1443 - IPython.core.oinspect.Inspector.pinfo(self, obj, oname='', formatter='None', info='None', detail_level=0, enable_html_pager=True)
1518 - IPython.core.oinspect.Inspector.pinfo(self, obj, oname='', formatter='None', info='None', detail_level=0, enable_html_pager=True)
1444 + IPython.core.oinspect.Inspector.pinfo(self, obj, oname='', formatter='None', info='None', detail_level=0, enable_html_pager=True, omit_sections='()')
1519 + IPython.core.oinspect.Inspector.pinfo(self, obj, oname='', formatter='None', info='None', detail_level=0, enable_html_pager=True, omit_sections='()')
1445
1520
1446 - IPython.core.profiledir.ProfileDir.copy_config_file(self, config_file, path='None', overwrite=False)
1521 - IPython.core.profiledir.ProfileDir.copy_config_file(self, config_file, path='None', overwrite=False)
1447 + IPython.core.profiledir.ProfileDir.copy_config_file(self, config_file, path, overwrite=False)
1522 + IPython.core.profiledir.ProfileDir.copy_config_file(self, config_file, path, overwrite=False)
1448
1523
1449 - IPython.core.ultratb.VerboseTB.format_record(self, frame, file, lnum, func, lines, index)
1524 - IPython.core.ultratb.VerboseTB.format_record(self, frame, file, lnum, func, lines, index)
1450 + IPython.core.ultratb.VerboseTB.format_record(self, frame_info)
1525 + IPython.core.ultratb.VerboseTB.format_record(self, frame_info)
1451
1526
1452 - IPython.terminal.embed.InteractiveShellEmbed.mainloop(self, local_ns='None', module='None', stack_depth=0, display_banner='None', global_ns='None', compile_flags='None')
1527 - IPython.terminal.embed.InteractiveShellEmbed.mainloop(self, local_ns='None', module='None', stack_depth=0, display_banner='None', global_ns='None', compile_flags='None')
1453 + IPython.terminal.embed.InteractiveShellEmbed.mainloop(self, local_ns='None', module='None', stack_depth=0, compile_flags='None')
1528 + IPython.terminal.embed.InteractiveShellEmbed.mainloop(self, local_ns='None', module='None', stack_depth=0, compile_flags='None')
1454
1529
1455 - IPython.terminal.embed.embed(**kwargs)
1530 - IPython.terminal.embed.embed(**kwargs)
1456 + IPython.terminal.embed.embed(*, header='', compile_flags='None', **kwargs)
1531 + IPython.terminal.embed.embed(*, header='', compile_flags='None', **kwargs)
1457
1532
1458 - IPython.terminal.interactiveshell.TerminalInteractiveShell.interact(self, display_banner='<object object at 0xffffff>')
1533 - IPython.terminal.interactiveshell.TerminalInteractiveShell.interact(self, display_banner='<object object at 0xffffff>')
1459 + IPython.terminal.interactiveshell.TerminalInteractiveShell.interact(self)
1534 + IPython.terminal.interactiveshell.TerminalInteractiveShell.interact(self)
1460
1535
1461 - IPython.terminal.interactiveshell.TerminalInteractiveShell.mainloop(self, display_banner='<object object at 0xffffff>')
1536 - IPython.terminal.interactiveshell.TerminalInteractiveShell.mainloop(self, display_banner='<object object at 0xffffff>')
1462 + IPython.terminal.interactiveshell.TerminalInteractiveShell.mainloop(self)
1537 + IPython.terminal.interactiveshell.TerminalInteractiveShell.mainloop(self)
1463
1538
1464 - IPython.utils.path.get_py_filename(name, force_win32='None')
1539 - IPython.utils.path.get_py_filename(name, force_win32='None')
1465 + IPython.utils.path.get_py_filename(name)
1540 + IPython.utils.path.get_py_filename(name)
1466
1541
1467 The following are new attributes (that might be inherited)::
1542 The following are new attributes (that might be inherited)::
1468
1543
1469 + IPython.core.completer.IPCompleter.unicode_names
1544 + IPython.core.completer.IPCompleter.unicode_names
1470 + IPython.core.debugger.InterruptiblePdb.precmd
1545 + IPython.core.debugger.InterruptiblePdb.precmd
1471 + IPython.core.debugger.Pdb.precmd
1546 + IPython.core.debugger.Pdb.precmd
1472 + IPython.core.ultratb.AutoFormattedTB.has_colors
1547 + IPython.core.ultratb.AutoFormattedTB.has_colors
1473 + IPython.core.ultratb.ColorTB.has_colors
1548 + IPython.core.ultratb.ColorTB.has_colors
1474 + IPython.core.ultratb.FormattedTB.has_colors
1549 + IPython.core.ultratb.FormattedTB.has_colors
1475 + IPython.core.ultratb.ListTB.has_colors
1550 + IPython.core.ultratb.ListTB.has_colors
1476 + IPython.core.ultratb.SyntaxTB.has_colors
1551 + IPython.core.ultratb.SyntaxTB.has_colors
1477 + IPython.core.ultratb.TBTools.has_colors
1552 + IPython.core.ultratb.TBTools.has_colors
1478 + IPython.core.ultratb.VerboseTB.has_colors
1553 + IPython.core.ultratb.VerboseTB.has_colors
1479 + IPython.terminal.debugger.TerminalPdb.do_interact
1554 + IPython.terminal.debugger.TerminalPdb.do_interact
1480 + IPython.terminal.debugger.TerminalPdb.precmd
1555 + IPython.terminal.debugger.TerminalPdb.precmd
1481
1556
1482 The following attribute/methods have been removed::
1557 The following attribute/methods have been removed::
1483
1558
1484 - IPython.core.application.BaseIPythonApplication.deprecated_subcommands
1559 - IPython.core.application.BaseIPythonApplication.deprecated_subcommands
1485 - IPython.core.ultratb.AutoFormattedTB.format_records
1560 - IPython.core.ultratb.AutoFormattedTB.format_records
1486 - IPython.core.ultratb.ColorTB.format_records
1561 - IPython.core.ultratb.ColorTB.format_records
1487 - IPython.core.ultratb.FormattedTB.format_records
1562 - IPython.core.ultratb.FormattedTB.format_records
1488 - IPython.terminal.embed.InteractiveShellEmbed.init_deprecation_warnings
1563 - IPython.terminal.embed.InteractiveShellEmbed.init_deprecation_warnings
1489 - IPython.terminal.embed.InteractiveShellEmbed.init_readline
1564 - IPython.terminal.embed.InteractiveShellEmbed.init_readline
1490 - IPython.terminal.embed.InteractiveShellEmbed.write
1565 - IPython.terminal.embed.InteractiveShellEmbed.write
1491 - IPython.terminal.embed.InteractiveShellEmbed.write_err
1566 - IPython.terminal.embed.InteractiveShellEmbed.write_err
1492 - IPython.terminal.interactiveshell.TerminalInteractiveShell.init_deprecation_warnings
1567 - IPython.terminal.interactiveshell.TerminalInteractiveShell.init_deprecation_warnings
1493 - IPython.terminal.interactiveshell.TerminalInteractiveShell.init_readline
1568 - IPython.terminal.interactiveshell.TerminalInteractiveShell.init_readline
1494 - IPython.terminal.interactiveshell.TerminalInteractiveShell.write
1569 - IPython.terminal.interactiveshell.TerminalInteractiveShell.write
1495 - IPython.terminal.interactiveshell.TerminalInteractiveShell.write_err
1570 - IPython.terminal.interactiveshell.TerminalInteractiveShell.write_err
1496 - IPython.terminal.ipapp.LocateIPythonApp.deprecated_subcommands
1571 - IPython.terminal.ipapp.LocateIPythonApp.deprecated_subcommands
1497 - IPython.terminal.ipapp.LocateIPythonApp.initialize_subcommand
1572 - IPython.terminal.ipapp.LocateIPythonApp.initialize_subcommand
1498 - IPython.terminal.ipapp.TerminalIPythonApp.deprecated_subcommands
1573 - IPython.terminal.ipapp.TerminalIPythonApp.deprecated_subcommands
1499 - IPython.terminal.ipapp.TerminalIPythonApp.initialize_subcommand
1574 - IPython.terminal.ipapp.TerminalIPythonApp.initialize_subcommand
@@ -1,115 +1,116 b''
1 [metadata]
1 [metadata]
2 name = ipython
2 name = ipython
3 version = attr: IPython.core.release.__version__
3 version = attr: IPython.core.release.__version__
4 url = https://ipython.org
4 url = https://ipython.org
5 description = IPython: Productive Interactive Computing
5 description = IPython: Productive Interactive Computing
6 long_description_content_type = text/x-rst
6 long_description_content_type = text/x-rst
7 long_description = file: long_description.rst
7 long_description = file: long_description.rst
8 license_file = LICENSE
8 license_file = LICENSE
9 project_urls =
9 project_urls =
10 Documentation = https://ipython.readthedocs.io/
10 Documentation = https://ipython.readthedocs.io/
11 Funding = https://numfocus.org/
11 Funding = https://numfocus.org/
12 Source = https://github.com/ipython/ipython
12 Source = https://github.com/ipython/ipython
13 Tracker = https://github.com/ipython/ipython/issues
13 Tracker = https://github.com/ipython/ipython/issues
14 keywords = Interactive, Interpreter, Shell, Embedding
14 keywords = Interactive, Interpreter, Shell, Embedding
15 platforms = Linux, Mac OSX, Windows
15 platforms = Linux, Mac OSX, Windows
16 classifiers =
16 classifiers =
17 Framework :: IPython
17 Framework :: IPython
18 Framework :: Jupyter
18 Framework :: Jupyter
19 Intended Audience :: Developers
19 Intended Audience :: Developers
20 Intended Audience :: Science/Research
20 Intended Audience :: Science/Research
21 License :: OSI Approved :: BSD License
21 License :: OSI Approved :: BSD License
22 Programming Language :: Python
22 Programming Language :: Python
23 Programming Language :: Python :: 3
23 Programming Language :: Python :: 3
24 Programming Language :: Python :: 3 :: Only
24 Programming Language :: Python :: 3 :: Only
25 Topic :: System :: Shells
25 Topic :: System :: Shells
26
26
27 [options]
27 [options]
28 packages = find:
28 packages = find:
29 python_requires = >=3.8
29 python_requires = >=3.8
30 zip_safe = False
30 zip_safe = False
31 install_requires =
31 install_requires =
32 appnope; sys_platform == "darwin"
32 appnope; sys_platform == "darwin"
33 backcall
33 backcall
34 colorama; sys_platform == "win32"
34 colorama; sys_platform == "win32"
35 decorator
35 decorator
36 jedi>=0.16
36 jedi>=0.16
37 matplotlib-inline
37 matplotlib-inline
38 pexpect>4.3; sys_platform != "win32"
38 pexpect>4.3; sys_platform != "win32"
39 pickleshare
39 pickleshare
40 prompt_toolkit>=3.0.30,<3.1.0,!=3.0.37
40 prompt_toolkit>=3.0.30,<3.1.0,!=3.0.37
41 pygments>=2.4.0
41 pygments>=2.4.0
42 stack_data
42 stack_data
43 traitlets>=5
43 traitlets>=5
44 typing_extensions ; python_version<'3.10'
44
45
45 [options.extras_require]
46 [options.extras_require]
46 black =
47 black =
47 black
48 black
48 doc =
49 doc =
49 ipykernel
50 ipykernel
50 setuptools>=18.5
51 setuptools>=18.5
51 sphinx>=1.3
52 sphinx>=1.3
52 sphinx-rtd-theme
53 sphinx-rtd-theme
53 docrepr
54 docrepr
54 matplotlib
55 matplotlib
55 stack_data
56 stack_data
56 pytest<7
57 pytest<7
57 typing_extensions
58 typing_extensions
58 %(test)s
59 %(test)s
59 kernel =
60 kernel =
60 ipykernel
61 ipykernel
61 nbconvert =
62 nbconvert =
62 nbconvert
63 nbconvert
63 nbformat =
64 nbformat =
64 nbformat
65 nbformat
65 notebook =
66 notebook =
66 ipywidgets
67 ipywidgets
67 notebook
68 notebook
68 parallel =
69 parallel =
69 ipyparallel
70 ipyparallel
70 qtconsole =
71 qtconsole =
71 qtconsole
72 qtconsole
72 terminal =
73 terminal =
73 test =
74 test =
74 pytest<7.1
75 pytest<7.1
75 pytest-asyncio
76 pytest-asyncio
76 testpath
77 testpath
77 test_extra =
78 test_extra =
78 %(test)s
79 %(test)s
79 curio
80 curio
80 matplotlib!=3.2.0
81 matplotlib!=3.2.0
81 nbformat
82 nbformat
82 numpy>=1.21
83 numpy>=1.21
83 pandas
84 pandas
84 trio
85 trio
85 all =
86 all =
86 %(black)s
87 %(black)s
87 %(doc)s
88 %(doc)s
88 %(kernel)s
89 %(kernel)s
89 %(nbconvert)s
90 %(nbconvert)s
90 %(nbformat)s
91 %(nbformat)s
91 %(notebook)s
92 %(notebook)s
92 %(parallel)s
93 %(parallel)s
93 %(qtconsole)s
94 %(qtconsole)s
94 %(terminal)s
95 %(terminal)s
95 %(test_extra)s
96 %(test_extra)s
96 %(test)s
97 %(test)s
97
98
98 [options.packages.find]
99 [options.packages.find]
99 exclude =
100 exclude =
100 setupext
101 setupext
101
102
102 [options.package_data]
103 [options.package_data]
103 IPython = py.typed
104 IPython = py.typed
104 IPython.core = profile/README*
105 IPython.core = profile/README*
105 IPython.core.tests = *.png, *.jpg, daft_extension/*.py
106 IPython.core.tests = *.png, *.jpg, daft_extension/*.py
106 IPython.lib.tests = *.wav
107 IPython.lib.tests = *.wav
107 IPython.testing.plugin = *.txt
108 IPython.testing.plugin = *.txt
108
109
109 [velin]
110 [velin]
110 ignore_patterns =
111 ignore_patterns =
111 IPython/core/tests
112 IPython/core/tests
112 IPython/testing
113 IPython/testing
113
114
114 [tool.black]
115 [tool.black]
115 exclude = 'timing\.py'
116 exclude = 'timing\.py'
General Comments 0
You need to be logged in to leave comments. Login now