##// END OF EJS Templates
Revert "Ruffisation"
M Bussonnier -
Show More
@@ -260,7 +260,7 class BaseIPythonApplication(Application):
260 # ensure current working directory exists
260 # ensure current working directory exists
261 try:
261 try:
262 os.getcwd()
262 os.getcwd()
263 except Exception:
263 except:
264 # exit if cwd doesn't exist
264 # exit if cwd doesn't exist
265 self.log.error("Current working directory doesn't exist.")
265 self.log.error("Current working directory doesn't exist.")
266 self.exit(1)
266 self.exit(1)
@@ -342,7 +342,7 class BaseIPythonApplication(Application):
342 try:
342 try:
343 if suppress_errors is not None:
343 if suppress_errors is not None:
344 old_value = Application.raise_config_file_errors
344 old_value = Application.raise_config_file_errors
345 Application.raise_config_file_errors = not suppress_errors
345 Application.raise_config_file_errors = not suppress_errors;
346 Application.load_config_file(
346 Application.load_config_file(
347 self,
347 self,
348 base_config,
348 base_config,
@@ -10,13 +10,10 from traitlets.config.configurable import Configurable
10 from traitlets import Instance
10 from traitlets import Instance
11
11
12
12
13 class __BuiltinUndefined:
13 class __BuiltinUndefined(object): pass
14 pass
15 BuiltinUndefined = __BuiltinUndefined()
14 BuiltinUndefined = __BuiltinUndefined()
16
15
17
16 class __HideBuiltin(object): pass
18 class __HideBuiltin:
19 pass
20 HideBuiltin = __HideBuiltin()
17 HideBuiltin = __HideBuiltin()
21
18
22
19
@@ -34,6 +34,7 import functools
34 import hashlib
34 import hashlib
35 import linecache
35 import linecache
36 import operator
36 import operator
37 import time
37 from contextlib import contextmanager
38 from contextlib import contextmanager
38
39
39 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
@@ -226,6 +226,7 from IPython.testing.skipdoctest import skip_doctest
226 from IPython.utils import generics
226 from IPython.utils import generics
227 from IPython.utils.decorators import sphinx_options
227 from IPython.utils.decorators import sphinx_options
228 from IPython.utils.dir2 import dir2, get_real_method
228 from IPython.utils.dir2 import dir2, get_real_method
229 from IPython.utils.docs import GENERATING_DOCUMENTATION
229 from IPython.utils.path import ensure_dir_exists
230 from IPython.utils.path import ensure_dir_exists
230 from IPython.utils.process import arg_split
231 from IPython.utils.process import arg_split
231 from traitlets import (
232 from traitlets import (
@@ -133,7 +133,7 from functools import lru_cache
133
133
134 from IPython import get_ipython
134 from IPython import get_ipython
135 from IPython.core.excolors import exception_colors
135 from IPython.core.excolors import exception_colors
136 from IPython.utils import PyColorize, py3compat
136 from IPython.utils import PyColorize, coloransi, py3compat
137
137
138 from typing import TYPE_CHECKING
138 from typing import TYPE_CHECKING
139
139
@@ -281,6 +281,11 class Pdb(OldPdb):
281 # module and add a few attributes needed for debugging
281 # module and add a few attributes needed for debugging
282 self.color_scheme_table = exception_colors()
282 self.color_scheme_table = exception_colors()
283
283
284 # shorthands
285 C = coloransi.TermColors
286 cst = self.color_scheme_table
287
288
284 # Add a python parser so we can syntax highlight source while
289 # Add a python parser so we can syntax highlight source while
285 # debugging.
290 # debugging.
286 self.parser = PyColorize.Parser(style=color_scheme)
291 self.parser = PyColorize.Parser(style=color_scheme)
@@ -214,7 +214,7 class DisplayHook(Configurable):
214 # by the user.
214 # by the user.
215 update_unders = True
215 update_unders = True
216 for unders in ['_'*i for i in range(1,4)]:
216 for unders in ['_'*i for i in range(1,4)]:
217 if unders not in self.shell.user_ns:
217 if not unders in self.shell.user_ns:
218 continue
218 continue
219 if getattr(self, unders) is not self.shell.user_ns.get(unders):
219 if getattr(self, unders) is not self.shell.user_ns.get(unders):
220 update_unders = False
220 update_unders = False
@@ -21,6 +21,9 import sys
21 from traitlets.config.configurable import Configurable
21 from traitlets.config.configurable import Configurable
22 from traitlets import List
22 from traitlets import List
23
23
24 # This used to be defined here - it is imported for backwards compatibility
25 from .display_functions import publish_display_data
26
24 import typing as t
27 import typing as t
25
28
26 # -----------------------------------------------------------------------------
29 # -----------------------------------------------------------------------------
@@ -4,10 +4,13
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 import os
8 import os.path
7 import sys
9 import sys
8 from importlib import import_module, reload
10 from importlib import import_module, reload
9
11
10 from traitlets.config.configurable import Configurable
12 from traitlets.config.configurable import Configurable
13 from IPython.utils.path import ensure_dir_exists
11 from traitlets import Instance
14 from traitlets import Instance
12
15
13
16
@@ -954,6 +954,7 class HistoryManager(HistoryAccessor):
954 """
954 """
955 if (not self.db_log_output) or (line_num not in self.output_hist_reprs):
955 if (not self.db_log_output) or (line_num not in self.output_hist_reprs):
956 return
956 return
957 lnum: int = line_num
957 output = self.output_hist_reprs[line_num]
958 output = self.output_hist_reprs[line_num]
958
959
959 with self.db_output_cache_lock:
960 with self.db_output_cache_lock:
@@ -33,7 +33,7 from io import open as io_open
33 from logging import error
33 from logging import error
34 from pathlib import Path
34 from pathlib import Path
35 from typing import Callable
35 from typing import Callable
36 from typing import List as ListType, Any as AnyType
36 from typing import List as ListType, Dict as DictType, Any as AnyType
37 from typing import Optional, Sequence, Tuple
37 from typing import Optional, Sequence, Tuple
38 from warnings import warn
38 from warnings import warn
39
39
@@ -118,7 +118,7 from IPython.core.usage import default_banner
118 from IPython.display import display
118 from IPython.display import display
119 from IPython.paths import get_ipython_dir
119 from IPython.paths import get_ipython_dir
120 from IPython.testing.skipdoctest import skip_doctest
120 from IPython.testing.skipdoctest import skip_doctest
121 from IPython.utils import PyColorize, openpy, py3compat
121 from IPython.utils import PyColorize, io, openpy, py3compat
122 from IPython.utils.decorators import undoc
122 from IPython.utils.decorators import undoc
123 from IPython.utils.io import ask_yes_no
123 from IPython.utils.io import ask_yes_no
124 from IPython.utils.ipstruct import Struct
124 from IPython.utils.ipstruct import Struct
@@ -129,18 +129,6 from IPython.utils.syspathcontext import prepended_to_syspath
129 from IPython.utils.text import DollarFormatter, LSString, SList, format_screen
129 from IPython.utils.text import DollarFormatter, LSString, SList, format_screen
130 from IPython.core.oinspect import OInfo
130 from IPython.core.oinspect import OInfo
131
131
132 from ast import Module
133
134 # we still need to run things using the asyncio eventloop, but there is no
135 # async integration
136
137 from .async_helpers import (
138 _asyncio_runner,
139 _curio_runner,
140 _pseudo_sync_runner,
141 _should_be_async,
142 _trio_runner,
143 )
144
132
145 sphinxify: Optional[Callable]
133 sphinxify: Optional[Callable]
146
134
@@ -168,11 +156,26 class ProvisionalWarning(DeprecationWarning):
168 """
156 """
169 pass
157 pass
170
158
159 from ast import Module
171
160
172 _assign_nodes = (ast.AugAssign, ast.AnnAssign, ast.Assign)
161 _assign_nodes = (ast.AugAssign, ast.AnnAssign, ast.Assign)
173 _single_targets_nodes = (ast.AugAssign, ast.AnnAssign)
162 _single_targets_nodes = (ast.AugAssign, ast.AnnAssign)
174
163
175 #-----------------------------------------------------------------------------
164 #-----------------------------------------------------------------------------
165 # Await Helpers
166 #-----------------------------------------------------------------------------
167
168 # we still need to run things using the asyncio eventloop, but there is no
169 # async integration
170 from .async_helpers import (
171 _asyncio_runner,
172 _curio_runner,
173 _pseudo_sync_runner,
174 _should_be_async,
175 _trio_runner,
176 )
177
178 #-----------------------------------------------------------------------------
176 # Globals
179 # Globals
177 #-----------------------------------------------------------------------------
180 #-----------------------------------------------------------------------------
178
181
@@ -217,8 +220,7 def no_op(*a, **kw):
217 pass
220 pass
218
221
219
222
220 class SpaceInInput(Exception):
223 class SpaceInInput(Exception): pass
221 pass
222
224
223
225
224 class SeparateUnicode(Unicode):
226 class SeparateUnicode(Unicode):
@@ -228,9 +230,8 class SeparateUnicode(Unicode):
228 """
230 """
229
231
230 def validate(self, obj, value):
232 def validate(self, obj, value):
231 if value == "0":
233 if value == '0': value = ''
232 value = ""
234 value = value.replace('\\n','\n')
233 value = value.replace("\\n", "\n")
234 return super(SeparateUnicode, self).validate(obj, value)
235 return super(SeparateUnicode, self).validate(obj, value)
235
236
236
237
@@ -1571,7 +1572,7 class InteractiveShell(SingletonConfigurable):
1571 for name in vlist:
1572 for name in vlist:
1572 try:
1573 try:
1573 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1574 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1574 except Exception:
1575 except:
1575 print('Could not get variable %s from %s' %
1576 print('Could not get variable %s from %s' %
1576 (name,cf.f_code.co_name))
1577 (name,cf.f_code.co_name))
1577 else:
1578 else:
@@ -1730,7 +1731,7 class InteractiveShell(SingletonConfigurable):
1730 obj = obj[int(part)]
1731 obj = obj[int(part)]
1731 else:
1732 else:
1732 obj = getattr(obj, part)
1733 obj = getattr(obj, part)
1733 except Exception:
1734 except:
1734 # Blanket except b/c some badly implemented objects
1735 # Blanket except b/c some badly implemented objects
1735 # allow __getattr__ to raise exceptions other than
1736 # allow __getattr__ to raise exceptions other than
1736 # AttributeError, which then crashes IPython.
1737 # AttributeError, which then crashes IPython.
@@ -2021,7 +2022,7 class InteractiveShell(SingletonConfigurable):
2021 try:
2022 try:
2022 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
2023 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
2023 return validate_stb(stb)
2024 return validate_stb(stb)
2024 except Exception:
2025 except:
2025 # clear custom handler immediately
2026 # clear custom handler immediately
2026 self.set_custom_exc((), None)
2027 self.set_custom_exc((), None)
2027 print("Custom TB Handler failed, unregistering", file=sys.stderr)
2028 print("Custom TB Handler failed, unregistering", file=sys.stderr)
@@ -2214,7 +2215,7 class InteractiveShell(SingletonConfigurable):
2214 if filename and issubclass(etype, SyntaxError):
2215 if filename and issubclass(etype, SyntaxError):
2215 try:
2216 try:
2216 value.filename = filename
2217 value.filename = filename
2217 except Exception:
2218 except:
2218 # Not the format we expect; leave it alone
2219 # Not the format we expect; leave it alone
2219 pass
2220 pass
2220
2221
@@ -2860,7 +2861,7 class InteractiveShell(SingletonConfigurable):
2860 for key, expr in expressions.items():
2861 for key, expr in expressions.items():
2861 try:
2862 try:
2862 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2863 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2863 except Exception:
2864 except:
2864 value = self._user_obj_error()
2865 value = self._user_obj_error()
2865 out[key] = value
2866 out[key] = value
2866 return out
2867 return out
@@ -2914,7 +2915,7 class InteractiveShell(SingletonConfigurable):
2914 try:
2915 try:
2915 with fname.open("rb"):
2916 with fname.open("rb"):
2916 pass
2917 pass
2917 except Exception:
2918 except:
2918 warn('Could not open file <%s> for safe execution.' % fname)
2919 warn('Could not open file <%s> for safe execution.' % fname)
2919 return
2920 return
2920
2921
@@ -2944,7 +2945,7 class InteractiveShell(SingletonConfigurable):
2944 raise
2945 raise
2945 if not exit_ignore:
2946 if not exit_ignore:
2946 self.showtraceback(exception_only=True)
2947 self.showtraceback(exception_only=True)
2947 except Exception:
2948 except:
2948 if raise_exceptions:
2949 if raise_exceptions:
2949 raise
2950 raise
2950 # tb offset is 2 because we wrap execfile
2951 # tb offset is 2 because we wrap execfile
@@ -2972,7 +2973,7 class InteractiveShell(SingletonConfigurable):
2972 try:
2973 try:
2973 with fname.open("rb"):
2974 with fname.open("rb"):
2974 pass
2975 pass
2975 except Exception:
2976 except:
2976 warn('Could not open file <%s> for safe execution.' % fname)
2977 warn('Could not open file <%s> for safe execution.' % fname)
2977 return
2978 return
2978
2979
@@ -3002,7 +3003,7 class InteractiveShell(SingletonConfigurable):
3002 result.raise_error()
3003 result.raise_error()
3003 elif not result.success:
3004 elif not result.success:
3004 break
3005 break
3005 except Exception:
3006 except:
3006 if raise_exceptions:
3007 if raise_exceptions:
3007 raise
3008 raise
3008 self.showtraceback()
3009 self.showtraceback()
@@ -3032,7 +3033,7 class InteractiveShell(SingletonConfigurable):
3032 except SystemExit as status:
3033 except SystemExit as status:
3033 if status.code:
3034 if status.code:
3034 raise
3035 raise
3035 except Exception:
3036 except:
3036 self.showtraceback()
3037 self.showtraceback()
3037 warn('Unknown failure executing module: <%s>' % mod_name)
3038 warn('Unknown failure executing module: <%s>' % mod_name)
3038
3039
@@ -3518,7 +3519,7 class InteractiveShell(SingletonConfigurable):
3518 if softspace(sys.stdout, 0):
3519 if softspace(sys.stdout, 0):
3519 print()
3520 print()
3520
3521
3521 except Exception:
3522 except:
3522 # It's possible to have exceptions raised here, typically by
3523 # It's possible to have exceptions raised here, typically by
3523 # compilation of odd code (such as a naked 'return' outside a
3524 # compilation of odd code (such as a naked 'return' outside a
3524 # function) that did parse but isn't valid. Typically the exception
3525 # function) that did parse but isn't valid. Typically the exception
@@ -3590,7 +3591,7 class InteractiveShell(SingletonConfigurable):
3590 if result is not None:
3591 if result is not None:
3591 result.error_in_exec = value
3592 result.error_in_exec = value
3592 self.CustomTB(etype, value, tb)
3593 self.CustomTB(etype, value, tb)
3593 except Exception:
3594 except:
3594 if result is not None:
3595 if result is not None:
3595 result.error_in_exec = sys.exc_info()[1]
3596 result.error_in_exec = sys.exc_info()[1]
3596 self.showtraceback(running_compiled_code=True)
3597 self.showtraceback(running_compiled_code=True)
@@ -3656,12 +3657,12 class InteractiveShell(SingletonConfigurable):
3656 if not _matplotlib_manages_backends() and gui in (None, "auto"):
3657 if not _matplotlib_manages_backends() and gui in (None, "auto"):
3657 # Early import of backend_inline required for its side effect of
3658 # Early import of backend_inline required for its side effect of
3658 # calling _enable_matplotlib_integration()
3659 # calling _enable_matplotlib_integration()
3659 import matplotlib_inline.backend_inline # noqa : F401
3660 import matplotlib_inline.backend_inline
3660
3661
3661 from IPython.core import pylabtools as pt
3662 from IPython.core import pylabtools as pt
3662 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
3663 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
3663
3664
3664 if gui is not None:
3665 if gui != None:
3665 # If we have our first gui selection, store it
3666 # If we have our first gui selection, store it
3666 if self.pylab_gui_select is None:
3667 if self.pylab_gui_select is None:
3667 self.pylab_gui_select = gui
3668 self.pylab_gui_select = gui
@@ -1,39 +1,36
1 """Implementation of all the magic functions built into IPython.
1 """Implementation of all the magic functions built into IPython.
2 """
2 """
3
3 #-----------------------------------------------------------------------------
4 # -----------------------------------------------------------------------------
5 # Copyright (c) 2012 The IPython Development Team.
4 # Copyright (c) 2012 The IPython Development Team.
6 #
5 #
7 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
8 #
7 #
9 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
10 # -----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
11
10
12 # -----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
13 # Imports
12 # Imports
14 # -----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
15
14
16 from ..magic import Magics as Magics, magics_class as magics_class
15 from ..magic import Magics, magics_class
17 from .auto import AutoMagics as AutoMagics
16 from .auto import AutoMagics
18 from .basic import BasicMagics as BasicMagics, AsyncMagics as AsyncMagics
17 from .basic import BasicMagics, AsyncMagics
19 from .code import CodeMagics as CodeMagics, MacroToEdit as MacroToEdit
18 from .code import CodeMagics, MacroToEdit
20 from .config import ConfigMagics as ConfigMagics
19 from .config import ConfigMagics
21 from .display import DisplayMagics as DisplayMagics
20 from .display import DisplayMagics
22 from .execution import ExecutionMagics as ExecutionMagics
21 from .execution import ExecutionMagics
23 from .extension import ExtensionMagics as ExtensionMagics
22 from .extension import ExtensionMagics
24 from .history import HistoryMagics as HistoryMagics
23 from .history import HistoryMagics
25 from .logging import LoggingMagics as LoggingMagics
24 from .logging import LoggingMagics
26 from .namespace import NamespaceMagics as NamespaceMagics
25 from .namespace import NamespaceMagics
27 from .osm import OSMagics as OSMagics
26 from .osm import OSMagics
28 from .packaging import PackagingMagics as PackagingMagics
27 from .packaging import PackagingMagics
29 from .pylab import PylabMagics as PylabMagics
28 from .pylab import PylabMagics
30 from .script import ScriptMagics as ScriptMagics
29 from .script import ScriptMagics
31
30
32
31 #-----------------------------------------------------------------------------
33 # -----------------------------------------------------------------------------
34 # Magic implementation classes
32 # Magic implementation classes
35 # -----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
36
37
34
38 @magics_class
35 @magics_class
39 class UserMagics(Magics):
36 class UserMagics(Magics):
@@ -118,14 +118,14 class AutoMagics(Magics):
118 return error
118 return error
119
119
120 if parameter_s:
120 if parameter_s:
121 if parameter_s not in map(str, valid_modes.keys()):
121 if not parameter_s in map(str, valid_modes.keys()):
122 error(errorMessage())
122 error(errorMessage())
123 return
123 return
124 arg = int(parameter_s)
124 arg = int(parameter_s)
125 else:
125 else:
126 arg = 'toggle'
126 arg = 'toggle'
127
127
128 if arg not in (*list(valid_modes.keys()), "toggle"):
128 if not arg in (*list(valid_modes.keys()), "toggle"):
129 error(errorMessage())
129 error(errorMessage())
130 return
130 return
131
131
@@ -8,6 +8,7
8 import ast
8 import ast
9 import bdb
9 import bdb
10 import builtins as builtin_mod
10 import builtins as builtin_mod
11 import copy
11 import cProfile as profile
12 import cProfile as profile
12 import gc
13 import gc
13 import itertools
14 import itertools
@@ -21,16 +22,25 import time
21 import timeit
22 import timeit
22 from typing import Dict, Any
23 from typing import Dict, Any
23 from ast import (
24 from ast import (
25 Assign,
26 Call,
27 Expr,
28 Load,
24 Module,
29 Module,
30 Name,
31 NodeTransformer,
32 Store,
33 parse,
34 unparse,
25 )
35 )
26 from io import StringIO
36 from io import StringIO
27 from logging import error
37 from logging import error
28 from pathlib import Path
38 from pathlib import Path
29 from pdb import Restart
39 from pdb import Restart
30 from textwrap import indent
40 from textwrap import dedent, indent
31 from warnings import warn
41 from warnings import warn
32
42
33 from IPython.core import magic_arguments, page
43 from IPython.core import magic_arguments, oinspect, page
34 from IPython.core.displayhook import DisplayHook
44 from IPython.core.displayhook import DisplayHook
35 from IPython.core.error import UsageError
45 from IPython.core.error import UsageError
36 from IPython.core.macro import Macro
46 from IPython.core.macro import Macro
@@ -1447,12 +1457,10 class ExecutionMagics(Magics):
1447 return
1457 return
1448 macro = Macro(lines)
1458 macro = Macro(lines)
1449 self.shell.define_macro(name, macro)
1459 self.shell.define_macro(name, macro)
1450 if "q" not in opts:
1460 if not ( 'q' in opts) :
1451 print(
1461 print('Macro `%s` created. To execute, type its name (without quotes).' % name)
1452 "Macro `%s` created. To execute, type its name (without quotes)." % name
1462 print('=== Macro contents: ===')
1453 )
1463 print(macro, end=' ')
1454 print("=== Macro contents: ===")
1455 print(macro, end=" ")
1456
1464
1457 @magic_arguments.magic_arguments()
1465 @magic_arguments.magic_arguments()
1458 @magic_arguments.argument('output', type=str, default='', nargs='?',
1466 @magic_arguments.argument('output', type=str, default='', nargs='?',
@@ -425,9 +425,9 class OSMagics(Magics):
425
425
426 if oldcwd != cwd:
426 if oldcwd != cwd:
427 dhist.append(cwd)
427 dhist.append(cwd)
428 self.shell.db["dhist"] = compress_dhist(dhist)[-100:]
428 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
429 if "q" not in opts and not self.cd_force_quiet and self.shell.user_ns["_dh"]:
429 if not 'q' in opts and not self.cd_force_quiet and self.shell.user_ns['_dh']:
430 print(self.shell.user_ns["_dh"][-1])
430 print(self.shell.user_ns['_dh'][-1])
431
431
432 @line_magic
432 @line_magic
433 def env(self, parameter_s=''):
433 def env(self, parameter_s=''):
@@ -255,6 +255,7 def getsource(obj, oname='') -> Union[str,None]:
255 for attrname in ['fget', 'fset', 'fdel']:
255 for attrname in ['fget', 'fset', 'fdel']:
256 fn = getattr(obj, attrname)
256 fn = getattr(obj, attrname)
257 if fn is not None:
257 if fn is not None:
258 encoding = get_encoding(fn)
258 oname_prefix = ('%s.' % oname) if oname else ''
259 oname_prefix = ('%s.' % oname) if oname else ''
259 sources.append(''.join(('# ', oname_prefix, attrname)))
260 sources.append(''.join(('# ', oname_prefix, attrname)))
260 if inspect.isfunction(fn):
261 if inspect.isfunction(fn):
@@ -223,6 +223,7 def pager_page(strng, start=0, screen_lines=0, pager_cmd=None) -> None:
223 io.TextIOWrapper(proc.stdin, encoding="utf-8"), proc
223 io.TextIOWrapper(proc.stdin, encoding="utf-8"), proc
224 )
224 )
225 try:
225 try:
226 pager_encoding = pager.encoding or sys.stdout.encoding
226 pager.write(strng)
227 pager.write(strng)
227 finally:
228 finally:
228 retval = pager.close()
229 retval = pager.close()
@@ -3,6 +3,7
3 # Copyright (c) IPython Development Team.
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6 import warnings
6 from IPython.core.getipython import get_ipython
7 from IPython.core.getipython import get_ipython
7
8
8 # see https://github.com/ipython/ipykernel/issues/1304
9 # see https://github.com/ipython/ipykernel/issues/1304
@@ -30,8 +30,8 if __name__ == '__main__':
30
30
31 ip = get_ipython()
31 ip = get_ipython()
32
32
33 if "_refbug_cache" not in ip.user_ns:
33 if not '_refbug_cache' in ip.user_ns:
34 ip.user_ns["_refbug_cache"] = []
34 ip.user_ns['_refbug_cache'] = []
35
35
36
36
37 aglobal = 'Hello'
37 aglobal = 'Hello'
@@ -1,5 +1,10
1 import unittest
2 import re
1 from IPython.utils.capture import capture_output
3 from IPython.utils.capture import capture_output
4 import sys
2 import pytest
5 import pytest
6 from tempfile import TemporaryDirectory
7 from IPython.testing import tools as tt
3
8
4
9
5 def _exceptiongroup_common(
10 def _exceptiongroup_common(
@@ -12,6 +12,7 from IPython import get_ipython
12 from traitlets.config import Config
12 from traitlets.config import Config
13 from IPython.core.formatters import (
13 from IPython.core.formatters import (
14 PlainTextFormatter, HTMLFormatter, PDFFormatter, _mod_name_key,
14 PlainTextFormatter, HTMLFormatter, PDFFormatter, _mod_name_key,
15 DisplayFormatter, JSONFormatter,
15 )
16 )
16 from IPython.utils.io import capture_output
17 from IPython.utils.io import capture_output
17
18
@@ -6,6 +6,7
6
6
7 # our own packages
7 # our own packages
8 from IPython.core import autocall
8 from IPython.core import autocall
9 from IPython.testing import tools as tt
9 import pytest
10 import pytest
10 from collections.abc import Callable
11 from collections.abc import Callable
11
12
@@ -23,6 +23,7 from unittest import mock
23 from os.path import join
23 from os.path import join
24
24
25 from IPython.core.error import InputRejected
25 from IPython.core.error import InputRejected
26 from IPython.core.inputtransformer import InputTransformer
26 from IPython.core import interactiveshell
27 from IPython.core import interactiveshell
27 from IPython.core.oinspect import OInfo
28 from IPython.core.oinspect import OInfo
28 from IPython.testing.decorators import (
29 from IPython.testing.decorators import (
@@ -2,6 +2,7
2 """
2 """
3
3
4 import stack_data
4 import stack_data
5 import sys
5
6
6 SV_VERSION = tuple([int(x) for x in stack_data.__version__.split(".")[0:2]])
7 SV_VERSION = tuple([int(x) for x in stack_data.__version__.split(".")[0:2]])
7
8
@@ -35,16 +35,12 from IPython.utils.process import find_cmd
35 from IPython.utils.tempdir import TemporaryDirectory, TemporaryWorkingDirectory
35 from IPython.utils.tempdir import TemporaryDirectory, TemporaryWorkingDirectory
36 from IPython.utils.syspathcontext import prepended_to_syspath
36 from IPython.utils.syspathcontext import prepended_to_syspath
37
37
38 # import needed by doctest
38 from .test_debugger import PdbTestInput
39 from .test_debugger import PdbTestInput # noqa: F401
40
41 _ip = get_ipython()
42
39
40 from tempfile import NamedTemporaryFile
43
41
44 @magic.magics_class
42 @magic.magics_class
45 class DummyMagics(magic.Magics):
43 class DummyMagics(magic.Magics): pass
46 pass
47
48
44
49 def test_extract_code_ranges():
45 def test_extract_code_ranges():
50 instr = "1 3 5-6 7-9 10:15 17: :10 10- -13 :"
46 instr = "1 3 5-6 7-9 10:15 17: :10 10- -13 :"
@@ -63,24 +59,24 def test_extract_code_ranges():
63 actual = list(code.extract_code_ranges(instr))
59 actual = list(code.extract_code_ranges(instr))
64 assert actual == expected
60 assert actual == expected
65
61
66
67 def test_extract_symbols():
62 def test_extract_symbols():
68 source = """import foo\na = 10\ndef b():\n return 42\n\n\nclass A: pass\n\n\n"""
63 source = """import foo\na = 10\ndef b():\n return 42\n\n\nclass A: pass\n\n\n"""
69 symbols_args = ["a", "b", "A", "A,b", "A,a", "z"]
64 symbols_args = ["a", "b", "A", "A,b", "A,a", "z"]
70 expected = [
65 expected = [([], ['a']),
71 ([], ["a"]),
66 (["def b():\n return 42\n"], []),
72 (["def b():\n return 42\n"], []),
67 (["class A: pass\n"], []),
73 (["class A: pass\n"], []),
68 (["class A: pass\n", "def b():\n return 42\n"], []),
74 (["class A: pass\n", "def b():\n return 42\n"], []),
69 (["class A: pass\n"], ['a']),
75 (["class A: pass\n"], ["a"]),
70 ([], ['z'])]
76 ([], ["z"]),
77 ]
78 for symbols, exp in zip(symbols_args, expected):
71 for symbols, exp in zip(symbols_args, expected):
79 assert code.extract_symbols(source, symbols) == exp
72 assert code.extract_symbols(source, symbols) == exp
80
73
81
74
82 def test_extract_symbols_raises_exception_with_non_python_code():
75 def test_extract_symbols_raises_exception_with_non_python_code():
83 source = "=begin A Ruby program :)=end\n" "def hello\n" "puts 'Hello world'\n" "end"
76 source = ("=begin A Ruby program :)=end\n"
77 "def hello\n"
78 "puts 'Hello world'\n"
79 "end")
84 with pytest.raises(SyntaxError):
80 with pytest.raises(SyntaxError):
85 code.extract_symbols(source, "hello")
81 code.extract_symbols(source, "hello")
86
82
@@ -91,31 +87,30 def test_magic_not_found():
91 _ip.run_line_magic("doesntexist", "")
87 _ip.run_line_magic("doesntexist", "")
92
88
93 # ensure result isn't success when a magic isn't found
89 # ensure result isn't success when a magic isn't found
94 result = _ip.run_cell("%doesntexist")
90 result = _ip.run_cell('%doesntexist')
95 assert isinstance(result.error_in_exec, UsageError)
91 assert isinstance(result.error_in_exec, UsageError)
96
92
97
93
98 def test_cell_magic_not_found():
94 def test_cell_magic_not_found():
99 # magic not found raises UsageError
95 # magic not found raises UsageError
100 with pytest.raises(UsageError):
96 with pytest.raises(UsageError):
101 _ip.run_cell_magic("doesntexist", "line", "cell")
97 _ip.run_cell_magic('doesntexist', 'line', 'cell')
102
98
103 # ensure result isn't success when a magic isn't found
99 # ensure result isn't success when a magic isn't found
104 result = _ip.run_cell("%%doesntexist")
100 result = _ip.run_cell('%%doesntexist')
105 assert isinstance(result.error_in_exec, UsageError)
101 assert isinstance(result.error_in_exec, UsageError)
106
102
107
103
108 def test_magic_error_status():
104 def test_magic_error_status():
109 def fail(shell):
105 def fail(shell):
110 1 / 0
106 1/0
111
112 _ip.register_magic_function(fail)
107 _ip.register_magic_function(fail)
113 result = _ip.run_cell("%fail")
108 result = _ip.run_cell('%fail')
114 assert isinstance(result.error_in_exec, ZeroDivisionError)
109 assert isinstance(result.error_in_exec, ZeroDivisionError)
115
110
116
111
117 def test_config():
112 def test_config():
118 """test that config magic does not raise
113 """ test that config magic does not raise
119 can happen if Configurable init is moved too early into
114 can happen if Configurable init is moved too early into
120 Magics.__init__ as then a Config object will be registered as a
115 Magics.__init__ as then a Config object will be registered as a
121 magic.
116 magic.
@@ -125,18 +120,17 def test_config():
125
120
126
121
127 def test_config_available_configs():
122 def test_config_available_configs():
128 """test that config magic prints available configs in unique and
123 """ test that config magic prints available configs in unique and
129 sorted order."""
124 sorted order. """
130 with capture_output() as captured:
125 with capture_output() as captured:
131 _ip.run_line_magic("config", "")
126 _ip.run_line_magic("config", "")
132
127
133 stdout = captured.stdout
128 stdout = captured.stdout
134 config_classes = stdout.strip().split("\n")[1:]
129 config_classes = stdout.strip().split('\n')[1:]
135 assert config_classes == sorted(set(config_classes))
130 assert config_classes == sorted(set(config_classes))
136
131
137
138 def test_config_print_class():
132 def test_config_print_class():
139 """test that config with a classname prints the class's options."""
133 """ test that config with a classname prints the class's options. """
140 with capture_output() as captured:
134 with capture_output() as captured:
141 _ip.run_line_magic("config", "TerminalInteractiveShell")
135 _ip.run_line_magic("config", "TerminalInteractiveShell")
142
136
@@ -149,7 +143,7 def test_config_print_class():
149 def test_rehashx():
143 def test_rehashx():
150 # clear up everything
144 # clear up everything
151 _ip.alias_manager.clear_aliases()
145 _ip.alias_manager.clear_aliases()
152 del _ip.db["syscmdlist"]
146 del _ip.db['syscmdlist']
153
147
154 _ip.run_line_magic("rehashx", "")
148 _ip.run_line_magic("rehashx", "")
155 # Practically ALL ipython development systems will have more than 10 aliases
149 # Practically ALL ipython development systems will have more than 10 aliases
@@ -160,19 +154,19 def test_rehashx():
160 assert "." not in name
154 assert "." not in name
161
155
162 # rehashx must fill up syscmdlist
156 # rehashx must fill up syscmdlist
163 scoms = _ip.db["syscmdlist"]
157 scoms = _ip.db['syscmdlist']
164 assert len(scoms) > 10
158 assert len(scoms) > 10
165
159
166
160
167 def test_magic_parse_options():
161 def test_magic_parse_options():
168 """Test that we don't mangle paths when parsing magic options."""
162 """Test that we don't mangle paths when parsing magic options."""
169 ip = get_ipython()
163 ip = get_ipython()
170 path = "c:\\x"
164 path = 'c:\\x'
171 m = DummyMagics(ip)
165 m = DummyMagics(ip)
172 opts = m.parse_options("-f %s" % path, "f:")[0]
166 opts = m.parse_options('-f %s' % path,'f:')[0]
173 # argv splitting is os-dependent
167 # argv splitting is os-dependent
174 if os.name == "posix":
168 if os.name == 'posix':
175 expected = "c:x"
169 expected = 'c:x'
176 else:
170 else:
177 expected = path
171 expected = path
178 assert opts["f"] == expected
172 assert opts["f"] == expected
@@ -267,21 +261,20 def doctest_hist_op():
267 >>>
261 >>>
268 """
262 """
269
263
270
271 def test_hist_pof():
264 def test_hist_pof():
272 ip = get_ipython()
265 ip = get_ipython()
273 ip.run_cell("1+2", store_history=True)
266 ip.run_cell("1+2", store_history=True)
274 # raise Exception(ip.history_manager.session_number)
267 #raise Exception(ip.history_manager.session_number)
275 # raise Exception(list(ip.history_manager._get_range_session()))
268 #raise Exception(list(ip.history_manager._get_range_session()))
276 with TemporaryDirectory() as td:
269 with TemporaryDirectory() as td:
277 tf = os.path.join(td, "hist.py")
270 tf = os.path.join(td, 'hist.py')
278 ip.run_line_magic("history", "-pof %s" % tf)
271 ip.run_line_magic('history', '-pof %s' % tf)
279 assert os.path.isfile(tf)
272 assert os.path.isfile(tf)
280
273
281
274
282 def test_macro():
275 def test_macro():
283 ip = get_ipython()
276 ip = get_ipython()
284 ip.history_manager.reset() # Clear any existing history.
277 ip.history_manager.reset() # Clear any existing history.
285 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
278 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
286 for i, cmd in enumerate(cmds, start=1):
279 for i, cmd in enumerate(cmds, start=1):
287 ip.history_manager.store_inputs(i, cmd)
280 ip.history_manager.store_inputs(i, cmd)
@@ -368,12 +361,13 def test_reset_in_length():
368
361
369
362
370 class TestResetErrors(TestCase):
363 class TestResetErrors(TestCase):
364
371 def test_reset_redefine(self):
365 def test_reset_redefine(self):
366
372 @magics_class
367 @magics_class
373 class KernelMagics(Magics):
368 class KernelMagics(Magics):
374 @line_magic
369 @line_magic
375 def less(self, shell):
370 def less(self, shell): pass
376 pass
377
371
378 _ip.register_magics(KernelMagics)
372 _ip.register_magics(KernelMagics)
379
373
@@ -382,9 +376,8 class TestResetErrors(TestCase):
382 # logs get produce.
376 # logs get produce.
383 # so log one things we ignore.
377 # so log one things we ignore.
384 import logging as log_mod
378 import logging as log_mod
385
386 log = log_mod.getLogger()
379 log = log_mod.getLogger()
387 log.info("Nothing")
380 log.info('Nothing')
388 # end hack.
381 # end hack.
389 _ip.run_cell("reset -f")
382 _ip.run_cell("reset -f")
390
383
@@ -392,7 +385,6 class TestResetErrors(TestCase):
392 for out in cm.output:
385 for out in cm.output:
393 assert "Invalid alias" not in out
386 assert "Invalid alias" not in out
394
387
395
396 def test_tb_syntaxerror():
388 def test_tb_syntaxerror():
397 """test %tb after a SyntaxError"""
389 """test %tb after a SyntaxError"""
398 ip = get_ipython()
390 ip = get_ipython()
@@ -417,7 +409,8 def test_time():
417 with tt.AssertPrints("Wall time: "):
409 with tt.AssertPrints("Wall time: "):
418 ip.run_cell("%time None")
410 ip.run_cell("%time None")
419
411
420 ip.run_cell("def f(kmjy):\n" " %time print (2*kmjy)")
412 ip.run_cell("def f(kmjy):\n"
413 " %time print (2*kmjy)")
421
414
422 with tt.AssertPrints("Wall time: "):
415 with tt.AssertPrints("Wall time: "):
423 with tt.AssertPrints("hihi", suppress=False):
416 with tt.AssertPrints("hihi", suppress=False):
@@ -483,11 +476,13 def test_time_no_output_with_semicolon():
483
476
484
477
485 def test_time_last_not_expression():
478 def test_time_last_not_expression():
486 _ip.run_cell("%%time\n" "var_1 = 1\n" "var_2 = 2\n")
479 ip.run_cell("%%time\n"
487 assert _ip.user_ns["var_1"] == 1
480 "var_1 = 1\n"
488 del _ip.user_ns["var_1"]
481 "var_2 = 2\n")
489 assert _ip.user_ns["var_2"] == 2
482 assert ip.user_ns['var_1'] == 1
490 del _ip.user_ns["var_2"]
483 del ip.user_ns['var_1']
484 assert ip.user_ns['var_2'] == 2
485 del ip.user_ns['var_2']
491
486
492
487
493 @dec.skip_win32
488 @dec.skip_win32
@@ -497,20 +492,20 def test_time2():
497 with tt.AssertPrints("CPU times: user "):
492 with tt.AssertPrints("CPU times: user "):
498 ip.run_cell("%time None")
493 ip.run_cell("%time None")
499
494
500
501 def test_time3():
495 def test_time3():
502 """Erroneous magic function calls, issue gh-3334"""
496 """Erroneous magic function calls, issue gh-3334"""
503 ip = get_ipython()
497 ip = get_ipython()
504 ip.user_ns.pop("run", None)
498 ip.user_ns.pop('run', None)
505
506 with tt.AssertNotPrints("not found", channel="stderr"):
507 ip.run_cell("%%time\n" "run = 0\n" "run += 1")
508
499
500 with tt.AssertNotPrints("not found", channel='stderr'):
501 ip.run_cell("%%time\n"
502 "run = 0\n"
503 "run += 1")
509
504
510 def test_multiline_time():
505 def test_multiline_time():
511 """Make sure last statement from time return a value."""
506 """Make sure last statement from time return a value."""
512 ip = get_ipython()
507 ip = get_ipython()
513 ip.user_ns.pop("run", None)
508 ip.user_ns.pop('run', None)
514
509
515 ip.run_cell(
510 ip.run_cell(
516 dedent(
511 dedent(
@@ -627,7 +622,7 def test_cd_force_quiet():
627 with tt.AssertNotPrints(ipdir):
622 with tt.AssertNotPrints(ipdir):
628 osmagics.cd('"%s"' % ipdir)
623 osmagics.cd('"%s"' % ipdir)
629 with tt.AssertNotPrints(startdir):
624 with tt.AssertNotPrints(startdir):
630 osmagics.cd("-")
625 osmagics.cd('-')
631 finally:
626 finally:
632 os.chdir(startdir)
627 os.chdir(startdir)
633
628
@@ -639,14 +634,11 def test_xmode():
639 _ip.run_line_magic("xmode", "")
634 _ip.run_line_magic("xmode", "")
640 assert _ip.InteractiveTB.mode == xmode
635 assert _ip.InteractiveTB.mode == xmode
641
636
642
643 def test_reset_hard():
637 def test_reset_hard():
644 monitor = []
638 monitor = []
645
646 class A(object):
639 class A(object):
647 def __del__(self):
640 def __del__(self):
648 monitor.append(1)
641 monitor.append(1)
649
650 def __repr__(self):
642 def __repr__(self):
651 return "<A instance>"
643 return "<A instance>"
652
644
@@ -657,17 +649,14 def test_reset_hard():
657 _ip.run_line_magic("reset", "-f")
649 _ip.run_line_magic("reset", "-f")
658 assert monitor == [1]
650 assert monitor == [1]
659
651
660
661 class TestXdel(tt.TempFileMixin):
652 class TestXdel(tt.TempFileMixin):
662 def test_xdel(self):
653 def test_xdel(self):
663 """Test that references from %run are cleared by xdel."""
654 """Test that references from %run are cleared by xdel."""
664 src = (
655 src = ("class A(object):\n"
665 "class A(object):\n"
656 " monitor = []\n"
666 " monitor = []\n"
657 " def __del__(self):\n"
667 " def __del__(self):\n"
658 " self.monitor.append(1)\n"
668 " self.monitor.append(1)\n"
659 "a = A()\n")
669 "a = A()\n"
670 )
671 self.mktmp(src)
660 self.mktmp(src)
672 # %run creates some hidden references...
661 # %run creates some hidden references...
673 _ip.run_line_magic("run", "%s" % self.fname)
662 _ip.run_line_magic("run", "%s" % self.fname)
@@ -683,7 +672,6 class TestXdel(tt.TempFileMixin):
683 gc.collect(0)
672 gc.collect(0)
684 assert monitor == [1]
673 assert monitor == [1]
685
674
686
687 def doctest_who():
675 def doctest_who():
688 """doctest for %who
676 """doctest for %who
689
677
@@ -709,18 +697,14 def doctest_who():
709 Out[7]: ['alpha', 'beta']
697 Out[7]: ['alpha', 'beta']
710 """
698 """
711
699
712
713 def test_whos():
700 def test_whos():
714 """Check that whos is protected against objects where repr() fails."""
701 """Check that whos is protected against objects where repr() fails."""
715
716 class A(object):
702 class A(object):
717 def __repr__(self):
703 def __repr__(self):
718 raise Exception()
704 raise Exception()
719
705 _ip.user_ns['a'] = A()
720 _ip.user_ns["a"] = A()
721 _ip.run_line_magic("whos", "")
706 _ip.run_line_magic("whos", "")
722
707
723
724 def doctest_precision():
708 def doctest_precision():
725 """doctest for %precision
709 """doctest for %precision
726
710
@@ -768,14 +752,12 def test_debug_magic_locals():
768 In [2]:
752 In [2]:
769 """
753 """
770
754
771
772 def test_psearch():
755 def test_psearch():
773 with tt.AssertPrints("dict.fromkeys"):
756 with tt.AssertPrints("dict.fromkeys"):
774 _ip.run_cell("dict.fr*?")
757 _ip.run_cell("dict.fr*?")
775 with tt.AssertPrints("Ï€.is_integer"):
758 with tt.AssertPrints("Ï€.is_integer"):
776 _ip.run_cell("π = 3.14;\nπ.is_integ*?")
759 _ip.run_cell("π = 3.14;\nπ.is_integ*?")
777
760
778
779 def test_timeit_shlex():
761 def test_timeit_shlex():
780 """test shlex issues with timeit (#1109)"""
762 """test shlex issues with timeit (#1109)"""
781 _ip.ex("def f(*a,**kw): pass")
763 _ip.ex("def f(*a,**kw): pass")
@@ -789,11 +771,10 def test_timeit_shlex():
789
771
790 def test_timeit_special_syntax():
772 def test_timeit_special_syntax():
791 "Test %%timeit with IPython special syntax"
773 "Test %%timeit with IPython special syntax"
792
793 @register_line_magic
774 @register_line_magic
794 def lmagic(line):
775 def lmagic(line):
795 ip = get_ipython()
776 ip = get_ipython()
796 ip.user_ns["lmagic_out"] = line
777 ip.user_ns['lmagic_out'] = line
797
778
798 # line mode test
779 # line mode test
799 _ip.run_line_magic("timeit", "-n1 -r1 %lmagic my line")
780 _ip.run_line_magic("timeit", "-n1 -r1 %lmagic my line")
@@ -808,9 +789,8 def test_timeit_return():
808 test whether timeit -o return object
789 test whether timeit -o return object
809 """
790 """
810
791
811 res = _ip.run_line_magic("timeit", "-n10 -r10 -o 1")
792 res = _ip.run_line_magic('timeit','-n10 -r10 -o 1')
812 assert res is not None
793 assert(res is not None)
813
814
794
815 def test_timeit_quiet():
795 def test_timeit_quiet():
816 """
796 """
@@ -819,26 +799,22 def test_timeit_quiet():
819 with tt.AssertNotPrints("loops"):
799 with tt.AssertNotPrints("loops"):
820 _ip.run_cell("%timeit -n1 -r1 -q 1")
800 _ip.run_cell("%timeit -n1 -r1 -q 1")
821
801
822
823 def test_timeit_return_quiet():
802 def test_timeit_return_quiet():
824 with tt.AssertNotPrints("loops"):
803 with tt.AssertNotPrints("loops"):
825 res = _ip.run_line_magic("timeit", "-n1 -r1 -q -o 1")
804 res = _ip.run_line_magic('timeit', '-n1 -r1 -q -o 1')
826 assert res is not None
805 assert (res is not None)
827
828
806
829 def test_timeit_invalid_return():
807 def test_timeit_invalid_return():
830 with pytest.raises(SyntaxError):
808 with pytest.raises(SyntaxError):
831 _ip.run_line_magic("timeit", "return")
809 _ip.run_line_magic('timeit', 'return')
832
833
810
834 @dec.skipif(execution.profile is None)
811 @dec.skipif(execution.profile is None)
835 def test_prun_special_syntax():
812 def test_prun_special_syntax():
836 "Test %%prun with IPython special syntax"
813 "Test %%prun with IPython special syntax"
837
838 @register_line_magic
814 @register_line_magic
839 def lmagic(line):
815 def lmagic(line):
840 ip = get_ipython()
816 ip = get_ipython()
841 ip.user_ns["lmagic_out"] = line
817 ip.user_ns['lmagic_out'] = line
842
818
843 # line mode test
819 # line mode test
844 _ip.run_line_magic("prun", "-q %lmagic my line")
820 _ip.run_line_magic("prun", "-q %lmagic my line")
@@ -857,21 +833,21 def test_prun_quotes():
857
833
858 def test_extension():
834 def test_extension():
859 # Debugging information for failures of this test
835 # Debugging information for failures of this test
860 print("sys.path:")
836 print('sys.path:')
861 for p in sys.path:
837 for p in sys.path:
862 print(" ", p)
838 print(' ', p)
863 print("CWD", os.getcwd())
839 print('CWD', os.getcwd())
864
840
865 pytest.raises(ImportError, _ip.run_line_magic, "load_ext", "daft_extension")
841 pytest.raises(ImportError, _ip.run_line_magic, "load_ext", "daft_extension")
866 daft_path = os.path.join(os.path.dirname(__file__), "daft_extension")
842 daft_path = os.path.join(os.path.dirname(__file__), "daft_extension")
867 sys.path.insert(0, daft_path)
843 sys.path.insert(0, daft_path)
868 try:
844 try:
869 _ip.user_ns.pop("arq", None)
845 _ip.user_ns.pop('arq', None)
870 invalidate_caches() # Clear import caches
846 invalidate_caches() # Clear import caches
871 _ip.run_line_magic("load_ext", "daft_extension")
847 _ip.run_line_magic("load_ext", "daft_extension")
872 assert _ip.user_ns["arq"] == 185
848 assert _ip.user_ns["arq"] == 185
873 _ip.run_line_magic("unload_ext", "daft_extension")
849 _ip.run_line_magic("unload_ext", "daft_extension")
874 assert "arq" not in _ip.user_ns
850 assert 'arq' not in _ip.user_ns
875 finally:
851 finally:
876 sys.path.remove(daft_path)
852 sys.path.remove(daft_path)
877
853
@@ -879,7 +855,7 def test_extension():
879 def test_notebook_export_json():
855 def test_notebook_export_json():
880 pytest.importorskip("nbformat")
856 pytest.importorskip("nbformat")
881 _ip = get_ipython()
857 _ip = get_ipython()
882 _ip.history_manager.reset() # Clear any existing history.
858 _ip.history_manager.reset() # Clear any existing history.
883 cmds = ["a=1", "def b():\n return a**2", "print('noël, été', b())"]
859 cmds = ["a=1", "def b():\n return a**2", "print('noël, été', b())"]
884 for i, cmd in enumerate(cmds, start=1):
860 for i, cmd in enumerate(cmds, start=1):
885 _ip.history_manager.store_inputs(i, cmd)
861 _ip.history_manager.store_inputs(i, cmd)
@@ -889,6 +865,7 def test_notebook_export_json():
889
865
890
866
891 class TestEnv(TestCase):
867 class TestEnv(TestCase):
868
892 def test_env(self):
869 def test_env(self):
893 env = _ip.run_line_magic("env", "")
870 env = _ip.run_line_magic("env", "")
894 self.assertTrue(isinstance(env, dict))
871 self.assertTrue(isinstance(env, dict))
@@ -902,8 +879,8 class TestEnv(TestCase):
902 "API_KEY": "abc123",
879 "API_KEY": "abc123",
903 "SECRET_THING": "ssshhh",
880 "SECRET_THING": "ssshhh",
904 "JUPYTER_TOKEN": "",
881 "JUPYTER_TOKEN": "",
905 "VAR": "abc",
882 "VAR": "abc"
906 },
883 }
907 ):
884 ):
908 env = _ip.run_line_magic("env", "")
885 env = _ip.run_line_magic("env", "")
909 assert env["API_KEY"] == hidden
886 assert env["API_KEY"] == hidden
@@ -918,16 +895,16 class TestEnv(TestCase):
918 self.assertEqual(_ip.run_line_magic("env", "var"), "val1")
895 self.assertEqual(_ip.run_line_magic("env", "var"), "val1")
919 env = _ip.run_line_magic("env", "var=val2")
896 env = _ip.run_line_magic("env", "var=val2")
920 self.assertEqual(env, None)
897 self.assertEqual(env, None)
921 self.assertEqual(os.environ["var"], "val2")
898 self.assertEqual(os.environ['var'], 'val2')
922
899
923 def test_env_get_set_complex(self):
900 def test_env_get_set_complex(self):
924 env = _ip.run_line_magic("env", "var 'val1 '' 'val2")
901 env = _ip.run_line_magic("env", "var 'val1 '' 'val2")
925 self.assertEqual(env, None)
902 self.assertEqual(env, None)
926 self.assertEqual(os.environ["var"], "'val1 '' 'val2")
903 self.assertEqual(os.environ['var'], "'val1 '' 'val2")
927 self.assertEqual(_ip.run_line_magic("env", "var"), "'val1 '' 'val2")
904 self.assertEqual(_ip.run_line_magic("env", "var"), "'val1 '' 'val2")
928 env = _ip.run_line_magic("env", 'var=val2 val3="val4')
905 env = _ip.run_line_magic("env", 'var=val2 val3="val4')
929 self.assertEqual(env, None)
906 self.assertEqual(env, None)
930 self.assertEqual(os.environ["var"], 'val2 val3="val4')
907 self.assertEqual(os.environ['var'], 'val2 val3="val4')
931
908
932 def test_env_set_bad_input(self):
909 def test_env_set_bad_input(self):
933 self.assertRaises(UsageError, lambda: _ip.run_line_magic("set_env", "var"))
910 self.assertRaises(UsageError, lambda: _ip.run_line_magic("set_env", "var"))
@@ -937,6 +914,7 class TestEnv(TestCase):
937
914
938
915
939 class CellMagicTestCase(TestCase):
916 class CellMagicTestCase(TestCase):
917
940 def check_ident(self, magic):
918 def check_ident(self, magic):
941 # Manually called, we get the result
919 # Manually called, we get the result
942 out = _ip.run_cell_magic(magic, "a", "b")
920 out = _ip.run_cell_magic(magic, "a", "b")
@@ -947,49 +925,46 class CellMagicTestCase(TestCase):
947
925
948 def test_cell_magic_func_deco(self):
926 def test_cell_magic_func_deco(self):
949 "Cell magic using simple decorator"
927 "Cell magic using simple decorator"
950
951 @register_cell_magic
928 @register_cell_magic
952 def cellm(line, cell):
929 def cellm(line, cell):
953 return line, cell
930 return line, cell
954
931
955 self.check_ident("cellm")
932 self.check_ident('cellm')
956
933
957 def test_cell_magic_reg(self):
934 def test_cell_magic_reg(self):
958 "Cell magic manually registered"
935 "Cell magic manually registered"
959
960 def cellm(line, cell):
936 def cellm(line, cell):
961 return line, cell
937 return line, cell
962
938
963 _ip.register_magic_function(cellm, "cell", "cellm2")
939 _ip.register_magic_function(cellm, 'cell', 'cellm2')
964 self.check_ident("cellm2")
940 self.check_ident('cellm2')
965
941
966 def test_cell_magic_class(self):
942 def test_cell_magic_class(self):
967 "Cell magics declared via a class"
943 "Cell magics declared via a class"
968
969 @magics_class
944 @magics_class
970 class MyMagics(Magics):
945 class MyMagics(Magics):
946
971 @cell_magic
947 @cell_magic
972 def cellm3(self, line, cell):
948 def cellm3(self, line, cell):
973 return line, cell
949 return line, cell
974
950
975 _ip.register_magics(MyMagics)
951 _ip.register_magics(MyMagics)
976 self.check_ident("cellm3")
952 self.check_ident('cellm3')
977
953
978 def test_cell_magic_class2(self):
954 def test_cell_magic_class2(self):
979 "Cell magics declared via a class, #2"
955 "Cell magics declared via a class, #2"
980
981 @magics_class
956 @magics_class
982 class MyMagics2(Magics):
957 class MyMagics2(Magics):
983 @cell_magic("cellm4")
958
959 @cell_magic('cellm4')
984 def cellm33(self, line, cell):
960 def cellm33(self, line, cell):
985 return line, cell
961 return line, cell
986
962
987 _ip.register_magics(MyMagics2)
963 _ip.register_magics(MyMagics2)
988 self.check_ident("cellm4")
964 self.check_ident('cellm4')
989 # Check that nothing is registered as 'cellm33'
965 # Check that nothing is registered as 'cellm33'
990 c33 = _ip.find_cell_magic("cellm33")
966 c33 = _ip.find_cell_magic('cellm33')
991 assert c33 is None
967 assert c33 == None
992
993
968
994 def test_file():
969 def test_file():
995 """Basic %%writefile"""
970 """Basic %%writefile"""
@@ -1078,18 +1053,12 def test_file_unicode():
1078 """%%writefile with unicode cell"""
1053 """%%writefile with unicode cell"""
1079 ip = get_ipython()
1054 ip = get_ipython()
1080 with TemporaryDirectory() as td:
1055 with TemporaryDirectory() as td:
1081 fname = os.path.join(td, "file1")
1056 fname = os.path.join(td, 'file1')
1082 ip.run_cell_magic(
1057 ip.run_cell_magic("writefile", fname, u'\n'.join([
1083 "writefile",
1058 u'liné1',
1084 fname,
1059 u'liné2',
1085 "\n".join(
1060 ]))
1086 [
1061 with io.open(fname, encoding='utf-8') as f:
1087 "liné1",
1088 "liné2",
1089 ]
1090 ),
1091 )
1092 with io.open(fname, encoding="utf-8") as f:
1093 s = f.read()
1062 s = f.read()
1094 assert "liné1\n" in s
1063 assert "liné1\n" in s
1095 assert "liné2" in s
1064 assert "liné2" in s
@@ -1128,7 +1097,7 def test_file_amend():
1128 def test_file_spaces():
1097 def test_file_spaces():
1129 """%%file with spaces in filename"""
1098 """%%file with spaces in filename"""
1130 ip = get_ipython()
1099 ip = get_ipython()
1131 with TemporaryWorkingDirectory():
1100 with TemporaryWorkingDirectory() as td:
1132 fname = "file name"
1101 fname = "file name"
1133 ip.run_cell_magic(
1102 ip.run_cell_magic(
1134 "file",
1103 "file",
@@ -1147,7 +1116,7 def test_file_spaces():
1147
1116
1148 def test_script_config():
1117 def test_script_config():
1149 ip = get_ipython()
1118 ip = get_ipython()
1150 ip.config.ScriptMagics.script_magics = ["whoda"]
1119 ip.config.ScriptMagics.script_magics = ['whoda']
1151 sm = script.ScriptMagics(shell=ip)
1120 sm = script.ScriptMagics(shell=ip)
1152 assert "whoda" in sm.magics["cell"]
1121 assert "whoda" in sm.magics["cell"]
1153
1122
@@ -1247,7 +1216,7 async def test_script_bg_proc():
1247
1216
1248 def test_script_defaults():
1217 def test_script_defaults():
1249 ip = get_ipython()
1218 ip = get_ipython()
1250 for cmd in ["sh", "bash", "perl", "ruby"]:
1219 for cmd in ['sh', 'bash', 'perl', 'ruby']:
1251 try:
1220 try:
1252 find_cmd(cmd)
1221 find_cmd(cmd)
1253 except Exception:
1222 except Exception:
@@ -1259,8 +1228,7 def test_script_defaults():
1259 @magics_class
1228 @magics_class
1260 class FooFoo(Magics):
1229 class FooFoo(Magics):
1261 """class with both %foo and %%foo magics"""
1230 """class with both %foo and %%foo magics"""
1262
1231 @line_magic('foo')
1263 @line_magic("foo")
1264 def line_foo(self, line):
1232 def line_foo(self, line):
1265 "I am line foo"
1233 "I am line foo"
1266 pass
1234 pass
@@ -1270,7 +1238,6 class FooFoo(Magics):
1270 "I am cell foo, not line foo"
1238 "I am cell foo, not line foo"
1271 pass
1239 pass
1272
1240
1273
1274 def test_line_cell_info():
1241 def test_line_cell_info():
1275 """%%foo and %foo magics are distinguishable to inspect"""
1242 """%%foo and %foo magics are distinguishable to inspect"""
1276 ip = get_ipython()
1243 ip = get_ipython()
@@ -1330,7 +1297,7 def test_alias_magic():
1330 def test_save():
1297 def test_save():
1331 """Test %save."""
1298 """Test %save."""
1332 ip = get_ipython()
1299 ip = get_ipython()
1333 ip.history_manager.reset() # Clear any existing history.
1300 ip.history_manager.reset() # Clear any existing history.
1334 cmds = ["a=1", "def b():\n return a**2", "print(a, b())"]
1301 cmds = ["a=1", "def b():\n return a**2", "print(a, b())"]
1335 for i, cmd in enumerate(cmds, start=1):
1302 for i, cmd in enumerate(cmds, start=1):
1336 ip.history_manager.store_inputs(i, cmd)
1303 ip.history_manager.store_inputs(i, cmd)
@@ -1372,7 +1339,7 def test_save_with_no_args():
1372 def test_store():
1339 def test_store():
1373 """Test %store."""
1340 """Test %store."""
1374 ip = get_ipython()
1341 ip = get_ipython()
1375 ip.run_line_magic("load_ext", "storemagic")
1342 ip.run_line_magic('load_ext', 'storemagic')
1376
1343
1377 # make sure the storage is empty
1344 # make sure the storage is empty
1378 ip.run_line_magic("store", "-z")
1345 ip.run_line_magic("store", "-z")
@@ -1388,19 +1355,20 def test_store():
1388 assert ip.user_ns["var"] == 39
1355 assert ip.user_ns["var"] == 39
1389
1356
1390
1357
1391 def _run_edit_test(
1358 def _run_edit_test(arg_s, exp_filename=None,
1392 arg_s, exp_filename=None, exp_lineno=-1, exp_contents=None, exp_is_temp=None
1359 exp_lineno=-1,
1393 ):
1360 exp_contents=None,
1361 exp_is_temp=None):
1394 ip = get_ipython()
1362 ip = get_ipython()
1395 M = code.CodeMagics(ip)
1363 M = code.CodeMagics(ip)
1396 last_call = ["", ""]
1364 last_call = ['','']
1397 opts, args = M.parse_options(arg_s, "prxn:")
1365 opts,args = M.parse_options(arg_s,'prxn:')
1398 filename, lineno, is_temp = M._find_edit_target(ip, args, opts, last_call)
1366 filename, lineno, is_temp = M._find_edit_target(ip, args, opts, last_call)
1399
1367
1400 if exp_filename is not None:
1368 if exp_filename is not None:
1401 assert exp_filename == filename
1369 assert exp_filename == filename
1402 if exp_contents is not None:
1370 if exp_contents is not None:
1403 with io.open(filename, "r", encoding="utf-8") as f:
1371 with io.open(filename, 'r', encoding='utf-8') as f:
1404 contents = f.read()
1372 contents = f.read()
1405 assert exp_contents == contents
1373 assert exp_contents == contents
1406 if exp_lineno != -1:
1374 if exp_lineno != -1:
@@ -1427,26 +1395,23 def test_edit_cell():
1427 ip.run_cell("def foo(): return 1", store_history=True)
1395 ip.run_cell("def foo(): return 1", store_history=True)
1428
1396
1429 # test
1397 # test
1430 _run_edit_test("1", exp_contents=ip.user_ns["In"][1], exp_is_temp=True)
1398 _run_edit_test("1", exp_contents=ip.user_ns['In'][1], exp_is_temp=True)
1431
1432
1399
1433 def test_edit_fname():
1400 def test_edit_fname():
1434 """%edit file"""
1401 """%edit file"""
1435 # test
1402 # test
1436 _run_edit_test("test file.py", exp_filename="test file.py")
1403 _run_edit_test("test file.py", exp_filename="test file.py")
1437
1404
1438
1439 def test_bookmark():
1405 def test_bookmark():
1440 ip = get_ipython()
1406 ip = get_ipython()
1441 ip.run_line_magic("bookmark", "bmname")
1407 ip.run_line_magic('bookmark', 'bmname')
1442 with tt.AssertPrints("bmname"):
1408 with tt.AssertPrints('bmname'):
1443 ip.run_line_magic("bookmark", "-l")
1409 ip.run_line_magic('bookmark', '-l')
1444 ip.run_line_magic("bookmark", "-d bmname")
1410 ip.run_line_magic('bookmark', '-d bmname')
1445
1446
1411
1447 def test_ls_magic():
1412 def test_ls_magic():
1448 ip = get_ipython()
1413 ip = get_ipython()
1449 json_formatter = ip.display_formatter.formatters["application/json"]
1414 json_formatter = ip.display_formatter.formatters['application/json']
1450 json_formatter.enabled = True
1415 json_formatter.enabled = True
1451 lsmagic = ip.run_line_magic("lsmagic", "")
1416 lsmagic = ip.run_line_magic("lsmagic", "")
1452 with warnings.catch_warnings(record=True) as w:
1417 with warnings.catch_warnings(record=True) as w:
@@ -1458,24 +1423,23 def test_ls_magic():
1458 def test_strip_initial_indent():
1423 def test_strip_initial_indent():
1459 def sii(s):
1424 def sii(s):
1460 lines = s.splitlines()
1425 lines = s.splitlines()
1461 return "\n".join(code.strip_initial_indent(lines))
1426 return '\n'.join(code.strip_initial_indent(lines))
1462
1427
1463 assert sii(" a = 1\nb = 2") == "a = 1\nb = 2"
1428 assert sii(" a = 1\nb = 2") == "a = 1\nb = 2"
1464 assert sii(" a\n b\nc") == "a\n b\nc"
1429 assert sii(" a\n b\nc") == "a\n b\nc"
1465 assert sii("a\n b") == "a\n b"
1430 assert sii("a\n b") == "a\n b"
1466
1431
1467
1468 def test_logging_magic_quiet_from_arg():
1432 def test_logging_magic_quiet_from_arg():
1469 _ip.config.LoggingMagics.quiet = False
1433 _ip.config.LoggingMagics.quiet = False
1470 lm = logging.LoggingMagics(shell=_ip)
1434 lm = logging.LoggingMagics(shell=_ip)
1471 with TemporaryDirectory() as td:
1435 with TemporaryDirectory() as td:
1472 try:
1436 try:
1473 with tt.AssertNotPrints(re.compile("Activating.*")):
1437 with tt.AssertNotPrints(re.compile("Activating.*")):
1474 lm.logstart("-q {}".format(os.path.join(td, "quiet_from_arg.log")))
1438 lm.logstart('-q {}'.format(
1439 os.path.join(td, "quiet_from_arg.log")))
1475 finally:
1440 finally:
1476 _ip.logger.logstop()
1441 _ip.logger.logstop()
1477
1442
1478
1479 def test_logging_magic_quiet_from_config():
1443 def test_logging_magic_quiet_from_config():
1480 _ip.config.LoggingMagics.quiet = True
1444 _ip.config.LoggingMagics.quiet = True
1481 lm = logging.LoggingMagics(shell=_ip)
1445 lm = logging.LoggingMagics(shell=_ip)
@@ -1538,16 +1502,18 def load_ipython_extension(ipython):
1538
1502
1539 def test_lazy_magics():
1503 def test_lazy_magics():
1540 with pytest.raises(UsageError):
1504 with pytest.raises(UsageError):
1541 _ip.run_line_magic("lazy_line", "")
1505 ip.run_line_magic("lazy_line", "")
1506
1507 startdir = os.getcwd()
1542
1508
1543 with TemporaryDirectory() as tmpdir:
1509 with TemporaryDirectory() as tmpdir:
1544 with prepended_to_syspath(tmpdir):
1510 with prepended_to_syspath(tmpdir):
1545 ptempdir = Path(tmpdir)
1511 ptempdir = Path(tmpdir)
1546 tf = ptempdir / "lazy_magic_module.py"
1512 tf = ptempdir / "lazy_magic_module.py"
1547 tf.write_text(MINIMAL_LAZY_MAGIC)
1513 tf.write_text(MINIMAL_LAZY_MAGIC)
1548 _ip.magics_manager.register_lazy("lazy_line", Path(tf.name).name[:-3])
1514 ip.magics_manager.register_lazy("lazy_line", Path(tf.name).name[:-3])
1549 with tt.AssertPrints("Lazy Line"):
1515 with tt.AssertPrints("Lazy Line"):
1550 _ip.run_line_magic("lazy_line", "")
1516 ip.run_line_magic("lazy_line", "")
1551
1517
1552
1518
1553 TEST_MODULE = """
1519 TEST_MODULE = """
@@ -1556,7 +1522,6 if __name__ == "__main__":
1556 print('I just ran a script')
1522 print('I just ran a script')
1557 """
1523 """
1558
1524
1559
1560 def test_run_module_from_import_hook():
1525 def test_run_module_from_import_hook():
1561 "Test that a module can be loaded via an import hook"
1526 "Test that a module can be loaded via an import hook"
1562 with TemporaryDirectory() as tmpdir:
1527 with TemporaryDirectory() as tmpdir:
@@ -100,7 +100,7 def test_get_ipython_dir_4():
100 'IPYTHONDIR': None,
100 'IPYTHONDIR': None,
101 'XDG_CONFIG_HOME': XDG_TEST_DIR,
101 'XDG_CONFIG_HOME': XDG_TEST_DIR,
102 }), warnings.catch_warnings(record=True) as w:
102 }), warnings.catch_warnings(record=True) as w:
103 _ipdir = paths.get_ipython_dir()
103 ipdir = paths.get_ipython_dir()
104
104
105 assert len(w) == 1
105 assert len(w) == 1
106 assert "Ignoring" in str(w[0])
106 assert "Ignoring" in str(w[0])
@@ -3,6 +3,7
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Imports
4 # Imports
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 import pytest
6
7
7 from IPython.core.prefilter import AutocallChecker
8 from IPython.core.prefilter import AutocallChecker
8
9
@@ -257,6 +257,7 bar()
257 with tt.AssertPrints('QWERTY'):
257 with tt.AssertPrints('QWERTY'):
258 ip.showsyntaxerror()
258 ip.showsyntaxerror()
259
259
260 import sys
260
261
261 if platform.python_implementation() != "PyPy":
262 if platform.python_implementation() != "PyPy":
262 """
263 """
@@ -188,7 +188,7 def _safe_string(value, what, func=str):
188 # Copied from cpython/Lib/traceback.py
188 # Copied from cpython/Lib/traceback.py
189 try:
189 try:
190 return func(value)
190 return func(value)
191 except Exception:
191 except:
192 return f"<{what} {func.__name__}() failed>"
192 return f"<{what} {func.__name__}() failed>"
193
193
194
194
@@ -730,9 +730,9 class ListTB(TBTools):
730 def _some_str(self, value):
730 def _some_str(self, value):
731 # Lifted from traceback.py
731 # Lifted from traceback.py
732 try:
732 try:
733 return str(value)
733 return py3compat.cast_unicode(str(value))
734 except:
734 except:
735 return "<unprintable %s object>" % type(value).__name__
735 return u'<unprintable %s object>' % type(value).__name__
736
736
737
737
738 class FrameInfo:
738 class FrameInfo:
@@ -1048,7 +1048,7 class VerboseTB(TBTools):
1048 colors.excName,
1048 colors.excName,
1049 etype_str,
1049 etype_str,
1050 colorsnormal,
1050 colorsnormal,
1051 evalue_str,
1051 py3compat.cast_unicode(evalue_str),
1052 ),
1052 ),
1053 *(
1053 *(
1054 "{}{}".format(
1054 "{}{}".format(
@@ -1071,6 +1071,8 class VerboseTB(TBTools):
1071 This may be called multiple times by Python 3 exception chaining
1071 This may be called multiple times by Python 3 exception chaining
1072 (PEP 3134).
1072 (PEP 3134).
1073 """
1073 """
1074 # some locals
1075 orig_etype = etype
1074 try:
1076 try:
1075 etype = etype.__name__ # type: ignore
1077 etype = etype.__name__ # type: ignore
1076 except AttributeError:
1078 except AttributeError:
@@ -1213,7 +1215,7 class VerboseTB(TBTools):
1213 chained_exceptions_tb_offset)
1215 chained_exceptions_tb_offset)
1214 exception = self.get_parts_of_chained_exception(evalue)
1216 exception = self.get_parts_of_chained_exception(evalue)
1215
1217
1216 if exception and id(exception[1]) not in chained_exc_ids:
1218 if exception and not id(exception[1]) in chained_exc_ids:
1217 chained_exc_ids.add(id(exception[1])) # trace exception to avoid infinite 'cause' loop
1219 chained_exc_ids.add(id(exception[1])) # trace exception to avoid infinite 'cause' loop
1218 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
1220 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
1219 etype, evalue, etb = exception
1221 etype, evalue, etb = exception
@@ -1408,7 +1410,7 class AutoFormattedTB(FormattedTB):
1408 AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
1410 AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
1409 try:
1411 try:
1410 ...
1412 ...
1411 except Exception:
1413 except:
1412 AutoTB() # or AutoTB(out=logfile) where logfile is an open file object
1414 AutoTB() # or AutoTB(out=logfile) where logfile is an open file object
1413 """
1415 """
1414
1416
@@ -1515,12 +1517,12 def text_repr(value):
1515 return pydoc.text.repr(value) # type: ignore[call-arg]
1517 return pydoc.text.repr(value) # type: ignore[call-arg]
1516 except KeyboardInterrupt:
1518 except KeyboardInterrupt:
1517 raise
1519 raise
1518 except Exception:
1520 except:
1519 try:
1521 try:
1520 return repr(value)
1522 return repr(value)
1521 except KeyboardInterrupt:
1523 except KeyboardInterrupt:
1522 raise
1524 raise
1523 except Exception:
1525 except:
1524 try:
1526 try:
1525 # all still in an except block so we catch
1527 # all still in an except block so we catch
1526 # getattr raising
1528 # getattr raising
@@ -1533,7 +1535,7 def text_repr(value):
1533 return '%s instance' % text_repr(klass)
1535 return '%s instance' % text_repr(klass)
1534 except KeyboardInterrupt:
1536 except KeyboardInterrupt:
1535 raise
1537 raise
1536 except Exception:
1538 except:
1537 return 'UNRECOVERABLE REPR FAILURE'
1539 return 'UNRECOVERABLE REPR FAILURE'
1538
1540
1539
1541
@@ -429,7 +429,7 class Demo(object):
429 def show_all(self):
429 def show_all(self):
430 """Show entire demo on screen, block by block"""
430 """Show entire demo on screen, block by block"""
431
431
432 self.title
432 fname = self.title
433 title = self.title
433 title = self.title
434 nblocks = self.nblocks
434 nblocks = self.nblocks
435 silent = self._silent
435 silent = self._silent
@@ -56,21 +56,21 def test_warning_on_non_existent_path_FileLink():
56 def test_existing_path_FileLink():
56 def test_existing_path_FileLink():
57 """FileLink: Calling _repr_html_ functions as expected on existing filepath
57 """FileLink: Calling _repr_html_ functions as expected on existing filepath
58 """
58 """
59 with NamedTemporaryFile() as tf:
59 tf = NamedTemporaryFile()
60 fl = display.FileLink(tf.name)
60 fl = display.FileLink(tf.name)
61 actual = fl._repr_html_()
61 actual = fl._repr_html_()
62 expected = "<a href='%s' target='_blank'>%s</a><br>" % (tf.name, tf.name)
62 expected = "<a href='%s' target='_blank'>%s</a><br>" % (tf.name, tf.name)
63 assert actual == expected
63 assert actual == expected
64
64
65
65
66 def test_existing_path_FileLink_repr():
66 def test_existing_path_FileLink_repr():
67 """FileLink: Calling repr() functions as expected on existing filepath
67 """FileLink: Calling repr() functions as expected on existing filepath
68 """
68 """
69 with NamedTemporaryFile() as tf:
69 tf = NamedTemporaryFile()
70 fl = display.FileLink(tf.name)
70 fl = display.FileLink(tf.name)
71 actual = repr(fl)
71 actual = repr(fl)
72 expected = tf.name
72 expected = tf.name
73 assert actual == expected
73 assert actual == expected
74
74
75
75
76 def test_error_on_directory_to_FileLink():
76 def test_error_on_directory_to_FileLink():
@@ -98,104 +98,98 def test_existing_path_FileLinks():
98 """FileLinks: Calling _repr_html_ functions as expected on existing dir
98 """FileLinks: Calling _repr_html_ functions as expected on existing dir
99 """
99 """
100 td = mkdtemp()
100 td = mkdtemp()
101 with NamedTemporaryFile(dir=td) as tf1, NamedTemporaryFile(dir=td) as tf2:
101 tf1 = NamedTemporaryFile(dir=td)
102 fl = display.FileLinks(td)
102 tf2 = NamedTemporaryFile(dir=td)
103 actual = fl._repr_html_()
103 fl = display.FileLinks(td)
104 actual = actual.split("\n")
104 actual = fl._repr_html_()
105 actual.sort()
105 actual = actual.split('\n')
106 # the links should always have forward slashes, even on windows, so replace
106 actual.sort()
107 # backslashes with forward slashes here
107 # the links should always have forward slashes, even on windows, so replace
108 expected = [
108 # backslashes with forward slashes here
109 "%s/<br>" % td,
109 expected = ["%s/<br>" % td,
110 "&nbsp;&nbsp;<a href='%s' target='_blank'>%s</a><br>"
110 "&nbsp;&nbsp;<a href='%s' target='_blank'>%s</a><br>" %\
111 % (tf2.name.replace("\\", "/"), split(tf2.name)[1]),
111 (tf2.name.replace("\\","/"),split(tf2.name)[1]),
112 "&nbsp;&nbsp;<a href='%s' target='_blank'>%s</a><br>"
112 "&nbsp;&nbsp;<a href='%s' target='_blank'>%s</a><br>" %\
113 % (tf1.name.replace("\\", "/"), split(tf1.name)[1]),
113 (tf1.name.replace("\\","/"),split(tf1.name)[1])]
114 ]
114 expected.sort()
115 expected.sort()
115 # We compare the sorted list of links here as that's more reliable
116 # We compare the sorted list of links here as that's more reliable
116 assert actual == expected
117 assert actual == expected
118
117
119
118
120 def test_existing_path_FileLinks_alt_formatter():
119 def test_existing_path_FileLinks_alt_formatter():
121 """FileLinks: Calling _repr_html_ functions as expected w/ an alt formatter
120 """FileLinks: Calling _repr_html_ functions as expected w/ an alt formatter
122 """
121 """
123 td = mkdtemp()
122 td = mkdtemp()
124 with NamedTemporaryFile(dir=td), NamedTemporaryFile(dir=td):
123 tf1 = NamedTemporaryFile(dir=td)
125
124 tf2 = NamedTemporaryFile(dir=td)
126 def fake_formatter(dirname, fnames, included_suffixes):
125 def fake_formatter(dirname,fnames,included_suffixes):
127 return ["hello", "world"]
126 return ["hello","world"]
128
127 fl = display.FileLinks(td,notebook_display_formatter=fake_formatter)
129 fl = display.FileLinks(td, notebook_display_formatter=fake_formatter)
128 actual = fl._repr_html_()
130 actual = fl._repr_html_()
129 actual = actual.split('\n')
131 actual = actual.split("\n")
130 actual.sort()
132 actual.sort()
131 expected = ["hello","world"]
133 expected = ["hello", "world"]
132 expected.sort()
134 expected.sort()
133 # We compare the sorted list of links here as that's more reliable
135 # We compare the sorted list of links here as that's more reliable
134 assert actual == expected
136 assert actual == expected
137
135
138
136
139 def test_existing_path_FileLinks_repr():
137 def test_existing_path_FileLinks_repr():
140 """FileLinks: Calling repr() functions as expected on existing directory """
138 """FileLinks: Calling repr() functions as expected on existing directory """
141 td = mkdtemp()
139 td = mkdtemp()
142 with NamedTemporaryFile(dir=td) as tf1, NamedTemporaryFile(dir=td) as tf2:
140 tf1 = NamedTemporaryFile(dir=td)
143 fl = display.FileLinks(td)
141 tf2 = NamedTemporaryFile(dir=td)
144 actual = repr(fl)
142 fl = display.FileLinks(td)
145 actual = actual.split("\n")
143 actual = repr(fl)
146 actual.sort()
144 actual = actual.split('\n')
147 expected = [
145 actual.sort()
148 "%s/" % td,
146 expected = ['%s/' % td, ' %s' % split(tf1.name)[1],' %s' % split(tf2.name)[1]]
149 " %s" % split(tf1.name)[1],
147 expected.sort()
150 " %s" % split(tf2.name)[1],
148 # We compare the sorted list of links here as that's more reliable
151 ]
149 assert actual == expected
152 expected.sort()
153 # We compare the sorted list of links here as that's more reliable
154 assert actual == expected
155
150
156
151
157 def test_existing_path_FileLinks_repr_alt_formatter():
152 def test_existing_path_FileLinks_repr_alt_formatter():
158 """FileLinks: Calling repr() functions as expected w/ alt formatter
153 """FileLinks: Calling repr() functions as expected w/ alt formatter
159 """
154 """
160 td = mkdtemp()
155 td = mkdtemp()
161 with NamedTemporaryFile(dir=td), NamedTemporaryFile(dir=td):
156 tf1 = NamedTemporaryFile(dir=td)
162
157 tf2 = NamedTemporaryFile(dir=td)
163 def fake_formatter(dirname, fnames, included_suffixes):
158 def fake_formatter(dirname,fnames,included_suffixes):
164 return ["hello", "world"]
159 return ["hello","world"]
165
160 fl = display.FileLinks(td,terminal_display_formatter=fake_formatter)
166 fl = display.FileLinks(td, terminal_display_formatter=fake_formatter)
161 actual = repr(fl)
167 actual = repr(fl)
162 actual = actual.split('\n')
168 actual = actual.split("\n")
163 actual.sort()
169 actual.sort()
164 expected = ["hello","world"]
170 expected = ["hello", "world"]
165 expected.sort()
171 expected.sort()
166 # We compare the sorted list of links here as that's more reliable
172 # We compare the sorted list of links here as that's more reliable
167 assert actual == expected
173 assert actual == expected
174
168
175
169
176 def test_error_on_file_to_FileLinks():
170 def test_error_on_file_to_FileLinks():
177 """FileLinks: Raises error when passed file
171 """FileLinks: Raises error when passed file
178 """
172 """
179 td = mkdtemp()
173 td = mkdtemp()
180 with NamedTemporaryFile(dir=td) as tf:
174 tf1 = NamedTemporaryFile(dir=td)
181 pytest.raises(ValueError, display.FileLinks, tf.name)
175 pytest.raises(ValueError, display.FileLinks, tf1.name)
182
176
183
177
184 def test_recursive_FileLinks():
178 def test_recursive_FileLinks():
185 """FileLinks: Does not recurse when recursive=False
179 """FileLinks: Does not recurse when recursive=False
186 """
180 """
187 td = mkdtemp()
181 td = mkdtemp()
188 with NamedTemporaryFile(dir=td):
182 tf = NamedTemporaryFile(dir=td)
189 subtd = mkdtemp(dir=td)
183 subtd = mkdtemp(dir=td)
190 with NamedTemporaryFile(dir=subtd):
184 subtf = NamedTemporaryFile(dir=subtd)
191 fl = display.FileLinks(td)
185 fl = display.FileLinks(td)
192 actual = str(fl)
186 actual = str(fl)
193 actual = actual.split("\n")
187 actual = actual.split('\n')
194 assert len(actual) == 4, actual
188 assert len(actual) == 4, actual
195 fl = display.FileLinks(td, recursive=False)
189 fl = display.FileLinks(td, recursive=False)
196 actual = str(fl)
190 actual = str(fl)
197 actual = actual.split("\n")
191 actual = actual.split('\n')
198 assert len(actual) == 2, actual
192 assert len(actual) == 2, actual
199
193
200 def test_audio_from_file():
194 def test_audio_from_file():
201 path = pjoin(dirname(__file__), 'test.wav')
195 path = pjoin(dirname(__file__), 'test.wav')
@@ -120,7 +120,7 class IPythonPTCompleter(Completer):
120 offset = cursor_to_position(body, cursor_row, cursor_col)
120 offset = cursor_to_position(body, cursor_row, cursor_col)
121 try:
121 try:
122 yield from self._get_completions(body, offset, cursor_position, self.ipy_completer)
122 yield from self._get_completions(body, offset, cursor_position, self.ipy_completer)
123 except Exception:
123 except Exception as e:
124 try:
124 try:
125 exc_type, exc_value, exc_tb = sys.exc_info()
125 exc_type, exc_value, exc_tb = sys.exc_info()
126 traceback.print_exception(exc_type, exc_value, exc_tb)
126 traceback.print_exception(exc_type, exc_value, exc_tb)
@@ -132,6 +132,7 class IPythonPTCompleter(Completer):
132 """
132 """
133 Private equivalent of get_completions() use only for unit_testing.
133 Private equivalent of get_completions() use only for unit_testing.
134 """
134 """
135 debug = getattr(ipyc, 'debug', False)
135 completions = _deduplicate_completions(
136 completions = _deduplicate_completions(
136 body, ipyc.completions(body, offset))
137 body, ipyc.completions(body, offset))
137 for c in completions:
138 for c in completions:
@@ -393,7 +393,7 def reformat_text_before_cursor(buffer, document, shell):
393 try:
393 try:
394 formatted_text = shell.reformat_handler(text)
394 formatted_text = shell.reformat_handler(text)
395 buffer.insert_text(formatted_text)
395 buffer.insert_text(formatted_text)
396 except Exception:
396 except Exception as e:
397 buffer.insert_text(text)
397 buffer.insert_text(text)
398
398
399
399
@@ -120,17 +120,19 def onlyif(condition, msg):
120
120
121 #-----------------------------------------------------------------------------
121 #-----------------------------------------------------------------------------
122 # Utility functions for decorators
122 # Utility functions for decorators
123 def module_available(module):
123 def module_not_available(module):
124 """Can module be imported? Returns true if module does NOT import.
124 """Can module be imported? Returns true if module does NOT import.
125
125
126 This is used to make a decorator to skip tests that require module to be
126 This is used to make a decorator to skip tests that require module to be
127 available, but delay the 'import numpy' to test execution time.
127 available, but delay the 'import numpy' to test execution time.
128 """
128 """
129 try:
129 try:
130 import_module(module)
130 mod = import_module(module)
131 return True
131 mod_not_avail = False
132 except ImportError:
132 except ImportError:
133 return False
133 mod_not_avail = True
134
135 return mod_not_avail
134
136
135
137
136 #-----------------------------------------------------------------------------
138 #-----------------------------------------------------------------------------
@@ -162,9 +164,7 skip_if_no_x11 = skipif(_x11_skip_cond, _x11_skip_msg)
162 # Other skip decorators
164 # Other skip decorators
163
165
164 # generic skip without module
166 # generic skip without module
165 skip_without = lambda mod: skipif(
167 skip_without = lambda mod: skipif(module_not_available(mod), "This test requires %s" % mod)
166 not module_available(mod), "This test requires %s" % mod
167 )
168
168
169 skipif_not_numpy = skip_without('numpy')
169 skipif_not_numpy = skip_without('numpy')
170
170
@@ -30,7 +30,7 def test_cve_2022_21699():
30 [random.choice(string.ascii_letters) for i in range(10)]
30 [random.choice(string.ascii_letters) for i in range(10)]
31 )
31 )
32
32
33 with TemporaryWorkingDirectory():
33 with TemporaryWorkingDirectory() as t:
34 dangerous_startup_dir.mkdir(parents=True)
34 dangerous_startup_dir.mkdir(parents=True)
35 (dangerous_startup_dir / "foo.py").write_text(
35 (dangerous_startup_dir / "foo.py").write_text(
36 f'print("{dangerous_expected}")', encoding="utf-8"
36 f'print("{dangerous_expected}")', encoding="utf-8"
@@ -22,7 +22,7 import os
22 from ._process_common import arg_split
22 from ._process_common import arg_split
23
23
24
24
25 def system(cmd: str):
25 def system(cmd):
26 """
26 """
27 system(cmd) should work in a cli environment on Mac OSX, Linux,
27 system(cmd) should work in a cli environment on Mac OSX, Linux,
28 and Windows
28 and Windows
@@ -33,10 +33,10 def system(cmd: str):
33 psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal
33 psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal
34 psi.UseShellExecute = False
34 psi.UseShellExecute = False
35 # Start up process:
35 # Start up process:
36 _reg = System.Diagnostics.Process.Start(psi)
36 reg = System.Diagnostics.Process.Start(psi)
37
37
38
38
39 def getoutput(cmd: str):
39 def getoutput(cmd):
40 """
40 """
41 getoutput(cmd) should work in a cli environment on Mac OSX, Linux,
41 getoutput(cmd) should work in a cli environment on Mac OSX, Linux,
42 and Windows
42 and Windows
@@ -51,11 +51,11 def getoutput(cmd: str):
51 myOutput = reg.StandardOutput
51 myOutput = reg.StandardOutput
52 output = myOutput.ReadToEnd()
52 output = myOutput.ReadToEnd()
53 myError = reg.StandardError
53 myError = reg.StandardError
54 _error = myError.ReadToEnd()
54 error = myError.ReadToEnd()
55 return output
55 return output
56
56
57
57
58 def check_pid(pid: int):
58 def check_pid(pid):
59 """
59 """
60 Check if a process with the given PID (pid) exists
60 Check if a process with the given PID (pid) exists
61 """
61 """
@@ -8,11 +8,15 IO related utilities.
8
8
9
9
10
10
11 import atexit
12 import os
11 import sys
13 import sys
12 import tempfile
14 import tempfile
13 from pathlib import Path
15 from pathlib import Path
16 from warnings import warn
14
17
15 from .capture import capture_output as capture_output
18 from IPython.utils.decorators import undoc
19 from .capture import CapturedIO, capture_output
16
20
17 class Tee(object):
21 class Tee(object):
18 """A class to duplicate an output stream to stdout/err.
22 """A class to duplicate an output stream to stdout/err.
@@ -36,7 +36,7 class TeeTestCase(unittest.TestCase):
36 tee = Tee(chan, channel=channel)
36 tee = Tee(chan, channel=channel)
37
37
38 print(text, end='', file=chan)
38 print(text, end='', file=chan)
39 _trap_val = trap.getvalue()
39 trap_val = trap.getvalue()
40 self.assertEqual(chan.getvalue(), text)
40 self.assertEqual(chan.getvalue(), text)
41
41
42 tee.close()
42 tee.close()
@@ -158,7 +158,7 def test_get_home_dir_4():
158
158
159 if 'HOME' in env: del env['HOME']
159 if 'HOME' in env: del env['HOME']
160 # this should still succeed, but we don't care what the answer is
160 # this should still succeed, but we don't care what the answer is
161 _home = path.get_home_dir(False)
161 home = path.get_home_dir(False)
162
162
163 @skip_win32
163 @skip_win32
164 @with_environment
164 @with_environment
@@ -254,7 +254,7 def test_filefind():
254 f = tempfile.NamedTemporaryFile()
254 f = tempfile.NamedTemporaryFile()
255 # print('fname:',f.name)
255 # print('fname:',f.name)
256 alt_dirs = paths.get_ipython_dir()
256 alt_dirs = paths.get_ipython_dir()
257 _t = path.filefind(f.name, alt_dirs)
257 t = path.filefind(f.name, alt_dirs)
258 # print('found:',t)
258 # print('found:',t)
259
259
260
260
@@ -31,6 +31,7 def test_simple():
31
31
32 def test_function():
32 def test_function():
33 cell = "foo(a=5, b='10')"
33 cell = "foo(a=5, b='10')"
34 expected = 'foo'
34 # up to `foo(|a=`
35 # up to `foo(|a=`
35 for i in range(cell.find('a=') + 1):
36 for i in range(cell.find('a=') + 1):
36 expect_token("foo", cell, i)
37 expect_token("foo", cell, i)
@@ -79,6 +79,7 def ghissue_role(name, rawtext, text, lineno, inliner, options=None, content=Non
79 '"%s" is invalid.' % text, line=lineno)
79 '"%s" is invalid.' % text, line=lineno)
80 prb = inliner.problematic(rawtext, rawtext, msg)
80 prb = inliner.problematic(rawtext, rawtext, msg)
81 return [prb], [msg]
81 return [prb], [msg]
82 app = inliner.document.settings.env.app
82 #info('issue %r' % text)
83 #info('issue %r' % text)
83 if 'pull' in name.lower():
84 if 'pull' in name.lower():
84 category = 'pull'
85 category = 'pull'
@@ -90,7 +91,6 def ghissue_role(name, rawtext, text, lineno, inliner, options=None, content=Non
90 '"%s" is invalid.' % name, line=lineno)
91 '"%s" is invalid.' % name, line=lineno)
91 prb = inliner.problematic(rawtext, rawtext, msg)
92 prb = inliner.problematic(rawtext, rawtext, msg)
92 return [prb], [msg]
93 return [prb], [msg]
93 app = inliner.document.settings.env.app
94 node = make_link_node(rawtext, app, category, str(issue_num), options)
94 node = make_link_node(rawtext, app, category, str(issue_num), options)
95 return [node], []
95 return [node], []
96
96
@@ -112,6 +112,7 def ghuser_role(name, rawtext, text, lineno, inliner, options=None, content=None
112 if options is None:
112 if options is None:
113 options = {}
113 options = {}
114
114
115 app = inliner.document.settings.env.app
115 #info('user link %r' % text)
116 #info('user link %r' % text)
116 ref = 'https://www.github.com/' + text
117 ref = 'https://www.github.com/' + text
117 node = nodes.reference(rawtext, text, refuri=ref, **options)
118 node = nodes.reference(rawtext, text, refuri=ref, **options)
@@ -135,6 +136,7 def ghcommit_role(name, rawtext, text, lineno, inliner, options=None, content=No
135 if options is None:
136 if options is None:
136 options = {}
137 options = {}
137
138
139 app = inliner.document.settings.env.app
138 #info('user link %r' % text)
140 #info('user link %r' % text)
139 try:
141 try:
140 base = app.config.github_project_url
142 base = app.config.github_project_url
@@ -2,7 +2,7
2 requires = ["setuptools>=61.2"]
2 requires = ["setuptools>=61.2"]
3 # We need access to the 'setupbase' module at build time.
3 # We need access to the 'setupbase' module at build time.
4 # Hence we declare a custom build backend.
4 # Hence we declare a custom build backend.
5 build-backend = "_build_meta" # just re-exports setuptools.build_meta definitions
5 build-backend = "_build_meta" # just re-exports setuptools.build_meta definitions
6 backend-path = ["."]
6 backend-path = ["."]
7
7
8 [project]
8 [project]
@@ -56,7 +56,9 Source = "https://github.com/ipython/ipython"
56 Tracker = "https://github.com/ipython/ipython/issues"
56 Tracker = "https://github.com/ipython/ipython/issues"
57
57
58 [project.optional-dependencies]
58 [project.optional-dependencies]
59 black = ["black"]
59 black = [
60 "black",
61 ]
60 doc = [
62 doc = [
61 "docrepr",
63 "docrepr",
62 "exceptiongroup",
64 "exceptiongroup",
@@ -69,14 +71,33 doc = [
69 "sphinx>=1.3",
71 "sphinx>=1.3",
70 "sphinxcontrib-jquery",
72 "sphinxcontrib-jquery",
71 ]
73 ]
72 kernel = ["ipykernel"]
74 kernel = [
73 nbconvert = ["nbconvert"]
75 "ipykernel",
74 nbformat = ["nbformat"]
76 ]
75 notebook = ["ipywidgets", "notebook"]
77 nbconvert = [
76 parallel = ["ipyparallel"]
78 "nbconvert",
77 qtconsole = ["qtconsole"]
79 ]
80 nbformat = [
81 "nbformat",
82 ]
83 notebook = [
84 "ipywidgets",
85 "notebook",
86 ]
87 parallel = [
88 "ipyparallel",
89 ]
90 qtconsole = [
91 "qtconsole",
92 ]
78 terminal = []
93 terminal = []
79 test = ["pytest", "pytest-asyncio<0.22", "testpath", "pickleshare", "packaging"]
94 test = [
95 "pytest",
96 "pytest-asyncio<0.22",
97 "testpath",
98 "pickleshare",
99 "packaging",
100 ]
80 test_extra = [
101 test_extra = [
81 "ipython[test]",
102 "ipython[test]",
82 "curio",
103 "curio",
@@ -86,7 +107,9 test_extra = [
86 "pandas",
107 "pandas",
87 "trio",
108 "trio",
88 ]
109 ]
89 matplotlib = ["matplotlib"]
110 matplotlib = [
111 "matplotlib"
112 ]
90 all = [
113 all = [
91 "ipython[black,doc,kernel,nbconvert,nbformat,notebook,parallel,qtconsole,matplotlib]",
114 "ipython[black,doc,kernel,nbconvert,nbformat,notebook,parallel,qtconsole,matplotlib]",
92 "ipython[test,test_extra]",
115 "ipython[test,test_extra]",
@@ -97,18 +120,18 python_version = "3.10"
97 ignore_missing_imports = true
120 ignore_missing_imports = true
98 follow_imports = 'silent'
121 follow_imports = 'silent'
99 exclude = [
122 exclude = [
100 'test_\.+\.py',
123 'test_\.+\.py',
101 'IPython.utils.tests.test_wildcard',
124 'IPython.utils.tests.test_wildcard',
102 'testing',
125 'testing',
103 'tests',
126 'tests',
104 'PyColorize.py',
127 'PyColorize.py',
105 '_process_win32_controller.py',
128 '_process_win32_controller.py',
106 'IPython/core/application.py',
129 'IPython/core/application.py',
107 'IPython/core/profileapp.py',
130 'IPython/core/profileapp.py',
108 'IPython/lib/deepreload.py',
131 'IPython/lib/deepreload.py',
109 'IPython/sphinxext/ipython_directive.py',
132 'IPython/sphinxext/ipython_directive.py',
110 'IPython/terminal/ipapp.py',
133 'IPython/terminal/ipapp.py',
111 'IPython/utils/path.py',
134 'IPython/utils/path.py',
112 ]
135 ]
113 # check_untyped_defs = true
136 # check_untyped_defs = true
114 # disallow_untyped_calls = true
137 # disallow_untyped_calls = true
@@ -120,7 +143,9 disallow_untyped_defs = true
120 warn_redundant_casts = true
143 warn_redundant_casts = true
121
144
122 [[tool.mypy.overrides]]
145 [[tool.mypy.overrides]]
123 module = ["IPython.core.crashhandler"]
146 module = [
147 "IPython.core.crashhandler",
148 ]
124 check_untyped_defs = true
149 check_untyped_defs = true
125 disallow_incomplete_defs = true
150 disallow_incomplete_defs = true
126 disallow_untyped_calls = true
151 disallow_untyped_calls = true
@@ -130,13 +155,16 ignore_errors = false
130 ignore_missing_imports = false
155 ignore_missing_imports = false
131
156
132 [[tool.mypy.overrides]]
157 [[tool.mypy.overrides]]
133 module = ["IPython.utils.text"]
158 module = [
159 "IPython.utils.text",
160 ]
134 disallow_untyped_defs = true
161 disallow_untyped_defs = true
135 check_untyped_defs = false
162 check_untyped_defs = false
136 disallow_untyped_decorators = true
163 disallow_untyped_decorators = true
137
164
138 [[tool.mypy.overrides]]
165 [[tool.mypy.overrides]]
139 module = []
166 module = [
167 ]
140 disallow_untyped_defs = false
168 disallow_untyped_defs = false
141 ignore_errors = true
169 ignore_errors = true
142 ignore_missing_imports = true
170 ignore_missing_imports = true
@@ -283,46 +311,52 disallow_untyped_decorators = false
283
311
284 [tool.pytest.ini_options]
312 [tool.pytest.ini_options]
285 addopts = [
313 addopts = [
286 "--durations=10",
314 "--durations=10",
287 "-pIPython.testing.plugin.pytest_ipdoctest",
315 "-pIPython.testing.plugin.pytest_ipdoctest",
288 "--ipdoctest-modules",
316 "--ipdoctest-modules",
289 "--ignore=docs",
317 "--ignore=docs",
290 "--ignore=examples",
318 "--ignore=examples",
291 "--ignore=htmlcov",
319 "--ignore=htmlcov",
292 "--ignore=ipython_kernel",
320 "--ignore=ipython_kernel",
293 "--ignore=ipython_parallel",
321 "--ignore=ipython_parallel",
294 "--ignore=results",
322 "--ignore=results",
295 "--ignore=tmp",
323 "--ignore=tmp",
296 "--ignore=tools",
324 "--ignore=tools",
297 "--ignore=traitlets",
325 "--ignore=traitlets",
298 "--ignore=IPython/core/tests/daft_extension",
326 "--ignore=IPython/core/tests/daft_extension",
299 "--ignore=IPython/sphinxext",
327 "--ignore=IPython/sphinxext",
300 "--ignore=IPython/terminal/pt_inputhooks",
328 "--ignore=IPython/terminal/pt_inputhooks",
301 "--ignore=IPython/__main__.py",
329 "--ignore=IPython/__main__.py",
302 "--ignore=IPython/external/qt_for_kernel.py",
330 "--ignore=IPython/external/qt_for_kernel.py",
303 "--ignore=IPython/html/widgets/widget_link.py",
331 "--ignore=IPython/html/widgets/widget_link.py",
304 "--ignore=IPython/html/widgets/widget_output.py",
332 "--ignore=IPython/html/widgets/widget_output.py",
305 "--ignore=IPython/terminal/console.py",
333 "--ignore=IPython/terminal/console.py",
306 "--ignore=IPython/utils/_process_cli.py",
334 "--ignore=IPython/utils/_process_cli.py",
307 "--ignore=IPython/utils/_process_posix.py",
335 "--ignore=IPython/utils/_process_posix.py",
308 "--ignore=IPython/utils/_process_win32_controller.py",
336 "--ignore=IPython/utils/_process_win32_controller.py",
309 "--ignore=IPython/utils/daemonize.py",
337 "--ignore=IPython/utils/daemonize.py",
310 "--ignore=IPython/utils/eventful.py",
338 "--ignore=IPython/utils/eventful.py",
311 "--ignore=IPython/kernel",
339 "--ignore=IPython/kernel",
312 "--ignore=IPython/consoleapp.py",
340 "--ignore=IPython/consoleapp.py",
313 "--ignore=IPython/lib/kernel.py",
341 "--ignore=IPython/lib/kernel.py",
314 "--ignore=IPython/utils/jsonutil.py",
342 "--ignore=IPython/utils/jsonutil.py",
315 "--ignore=IPython/utils/localinterfaces.py",
343 "--ignore=IPython/utils/localinterfaces.py",
316 "--ignore=IPython/utils/log.py",
344 "--ignore=IPython/utils/log.py",
317 "--ignore=IPython/utils/signatures.py",
345 "--ignore=IPython/utils/signatures.py",
318 "--ignore=IPython/utils/version.py",
346 "--ignore=IPython/utils/version.py"
347 ]
348 doctest_optionflags = [
349 "NORMALIZE_WHITESPACE",
350 "ELLIPSIS"
351 ]
352 ipdoctest_optionflags = [
353 "NORMALIZE_WHITESPACE",
354 "ELLIPSIS"
319 ]
355 ]
320 doctest_optionflags = ["NORMALIZE_WHITESPACE", "ELLIPSIS"]
321 ipdoctest_optionflags = ["NORMALIZE_WHITESPACE", "ELLIPSIS"]
322 asyncio_mode = "strict"
356 asyncio_mode = "strict"
323
357
324 [tool.pyright]
358 [tool.pyright]
325 pythonPlatform = "All"
359 pythonPlatform="All"
326
360
327 [tool.setuptools]
361 [tool.setuptools]
328 zip-safe = false
362 zip-safe = false
@@ -342,51 +376,10 namespaces = false
342 "IPython.testing.plugin" = ["*.txt"]
376 "IPython.testing.plugin" = ["*.txt"]
343
377
344 [tool.setuptools.dynamic]
378 [tool.setuptools.dynamic]
345 version = { attr = "IPython.core.release.__version__" }
379 version = {attr = "IPython.core.release.__version__"}
346
380
347 [tool.coverage.run]
381 [tool.coverage.run]
348 omit = [
382 omit = [
349 # omit everything in /tmp as we run tempfile
383 # omit everything in /tmp as we run tempfile
350 "/tmp/*",
384 "/tmp/*",
351 ]
385 ]
352
353 [tool.ruff.lint]
354 extend-select = [
355 # "B", # flake8-bugbear
356 # "I", # isort
357 # that will be a problem for pytest fixture unless you swap with the usefixture decorator https://docs.pytest.org/en/7.1.x/how-to/fixtures.html#use-fixtures-in-classes-and-modules-with-usefixtures
358 # "ARG", # flake8-unused-arguments
359 # "C4", # flake8-comprehensions
360 # "EM", # flake8-errmsg
361 # "ICN", # flake8-import-conventions
362 # "G", # flake8-logging-format
363 # "PGH", # pygrep-hooks
364 # "PIE", # flake8-pie
365 # "PL", # pylint
366 # "PTH", # flake8-use-pathlib
367 # "PT", # flake8-pytest-style
368 # "RET", # flake8-return
369 # "RUF", # Ruff-specific
370 # "SIM", # flake8-simplify
371 # "T20", # flake8-print
372 # "UP", # pyupgrade
373 # "YTT", # flake8-2020
374 # "EXE", # flake8-executable
375 # "PYI", # flake8-pyi
376 # "S", # flake8-bandit
377 ]
378 ignore = [
379 # "E501", # E501 Line too long (158 > 100 characters)
380 # "SIM105", # SIM105 Use `contextlib.suppress(...)`
381 # "PLR", # Design related pylint codes
382 # "S101", # Use of `assert` detected
383 ]
384 unfixable = [
385 # Don't touch print statements
386 "T201",
387 # Don't touch noqa lines
388 "RUF100",
389 ]
390
391 [tool.ruff]
392 extend-exclude = ["tests"]
General Comments 0
You need to be logged in to leave comments. Login now