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 |
|
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 |
|
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 == |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
15 | from ..magic import Magics, magics_class | |
17 |
from .auto import AutoMagics |
|
16 | from .auto import AutoMagics | |
18 |
from .basic import BasicMagics |
|
17 | from .basic import BasicMagics, AsyncMagics | |
19 |
from .code import CodeMagics |
|
18 | from .code import CodeMagics, MacroToEdit | |
20 |
from .config import ConfigMagics |
|
19 | from .config import ConfigMagics | |
21 |
from .display import DisplayMagics |
|
20 | from .display import DisplayMagics | |
22 |
from .execution import ExecutionMagics |
|
21 | from .execution import ExecutionMagics | |
23 |
from .extension import ExtensionMagics |
|
22 | from .extension import ExtensionMagics | |
24 |
from .history import HistoryMagics |
|
23 | from .history import HistoryMagics | |
25 |
from .logging import LoggingMagics |
|
24 | from .logging import LoggingMagics | |
26 |
from .namespace import NamespaceMagics |
|
25 | from .namespace import NamespaceMagics | |
27 |
from .osm import OSMagics |
|
26 | from .osm import OSMagics | |
28 |
from .packaging import PackagingMagics |
|
27 | from .packaging import PackagingMagics | |
29 |
from .pylab import PylabMagics |
|
28 | from .pylab import PylabMagics | |
30 |
from .script import 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 |
|
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 |
|
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 |
|
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[ |
|
428 | self.shell.db['dhist'] = compress_dhist(dhist)[-100:] | |
429 |
if |
|
429 | if not 'q' in opts and not self.cd_force_quiet and self.shell.user_ns['_dh']: | |
430 |
print(self.shell.user_ns[ |
|
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 |
|
33 | if not '_refbug_cache' in ip.user_ns: | |
34 |
ip.user_ns[ |
|
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" |
|
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" |
|
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( |
|
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( |
|
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( |
|
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 |
|
106 | 1/0 | |
111 |
|
||||
112 | _ip.register_magic_function(fail) |
|
107 | _ip.register_magic_function(fail) | |
113 |
result = _ip.run_cell( |
|
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( |
|
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[ |
|
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[ |
|
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 = |
|
164 | path = 'c:\\x' | |
171 | m = DummyMagics(ip) |
|
165 | m = DummyMagics(ip) | |
172 |
opts = m.parse_options( |
|
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 == |
|
168 | if os.name == 'posix': | |
175 |
expected = |
|
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 |
# |
|
267 | #raise Exception(ip.history_manager.session_number) | |
275 |
# |
|
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, |
|
270 | tf = os.path.join(td, 'hist.py') | |
278 |
ip.run_line_magic( |
|
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( |
|
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" |
|
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 |
|
|
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 |
|
482 | assert ip.user_ns['var_1'] == 1 | |
490 |
del |
|
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( |
|
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( |
|
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[ |
|
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( |
|
792 | res = _ip.run_line_magic('timeit','-n10 -r10 -o 1') | |
812 |
assert |
|
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( |
|
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( |
|
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[ |
|
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( |
|
836 | print('sys.path:') | |
861 | for p in sys.path: |
|
837 | for p in sys.path: | |
862 |
print( |
|
838 | print(' ', p) | |
863 |
print( |
|
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( |
|
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 |
|
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[ |
|
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[ |
|
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[ |
|
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( |
|
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, |
|
939 | _ip.register_magic_function(cellm, 'cell', 'cellm2') | |
964 |
self.check_ident( |
|
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( |
|
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( |
|
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( |
|
966 | c33 = _ip.find_cell_magic('cellm33') | |
991 |
assert c33 |
|
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, |
|
1056 | fname = os.path.join(td, 'file1') | |
1082 | ip.run_cell_magic( |
|
1057 | ip.run_cell_magic("writefile", fname, u'\n'.join([ | |
1083 |
|
|
1058 | u'liné1', | |
1084 |
|
|
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 = [ |
|
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 [ |
|
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( |
|
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, |
|
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, |
|
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[ |
|
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( |
|
1407 | ip.run_line_magic('bookmark', 'bmname') | |
1442 |
with tt.AssertPrints( |
|
1408 | with tt.AssertPrints('bmname'): | |
1443 |
ip.run_line_magic( |
|
1409 | ip.run_line_magic('bookmark', '-l') | |
1444 |
ip.run_line_magic( |
|
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[ |
|
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 |
|
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( |
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
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 |
|
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]) |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
|
59 | tf = NamedTemporaryFile() | |
60 |
|
|
60 | fl = display.FileLink(tf.name) | |
61 |
|
|
61 | actual = fl._repr_html_() | |
62 |
|
|
62 | expected = "<a href='%s' target='_blank'>%s</a><br>" % (tf.name, tf.name) | |
63 |
|
|
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 |
|
|
69 | tf = NamedTemporaryFile() | |
70 |
|
|
70 | fl = display.FileLink(tf.name) | |
71 |
|
|
71 | actual = repr(fl) | |
72 |
|
|
72 | expected = tf.name | |
73 |
|
|
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 |
|
|
109 | expected = ["%s/<br>" % td, | |
110 | " <a href='%s' target='_blank'>%s</a><br>" |
|
110 | " <a href='%s' target='_blank'>%s</a><br>" %\ | |
111 |
|
|
111 | (tf2.name.replace("\\","/"),split(tf2.name)[1]), | |
112 | " <a href='%s' target='_blank'>%s</a><br>" |
|
112 | " <a href='%s' target='_blank'>%s</a><br>" %\ | |
113 |
|
|
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 |
|
|
123 | tf1 = NamedTemporaryFile(dir=td) | |
125 |
|
124 | tf2 = NamedTemporaryFile(dir=td) | ||
126 |
|
|
125 | def fake_formatter(dirname,fnames,included_suffixes): | |
127 |
|
|
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 |
|
|
156 | tf1 = NamedTemporaryFile(dir=td) | |
162 |
|
157 | tf2 = NamedTemporaryFile(dir=td) | ||
163 |
|
|
158 | def fake_formatter(dirname,fnames,included_suffixes): | |
164 |
|
|
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 |
|
|
174 | tf1 = NamedTemporaryFile(dir=td) | |
181 |
|
|
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 |
|
|
182 | tf = NamedTemporaryFile(dir=td) | |
189 |
|
|
183 | subtd = mkdtemp(dir=td) | |
190 |
|
|
184 | subtf = NamedTemporaryFile(dir=subtd) | |
191 |
|
|
185 | fl = display.FileLinks(td) | |
192 |
|
|
186 | actual = str(fl) | |
193 |
|
|
187 | actual = actual.split('\n') | |
194 |
|
|
188 | assert len(actual) == 4, actual | |
195 |
|
|
189 | fl = display.FileLinks(td, recursive=False) | |
196 |
|
|
190 | actual = str(fl) | |
197 |
|
|
191 | actual = actual.split('\n') | |
198 |
|
|
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 |
|
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 |
|
|
36 | reg = System.Diagnostics.Process.Start(psi) | |
37 |
|
37 | |||
38 |
|
38 | |||
39 |
def getoutput(cmd |
|
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 |
|
|
54 | error = myError.ReadToEnd() | |
55 | return output |
|
55 | return output | |
56 |
|
56 | |||
57 |
|
57 | |||
58 |
def check_pid(pid |
|
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 |
|
|
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 |
|
|
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 |
|
|
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 = [ |
|
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 = [ |
|
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 = [ |
|
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 |
|
|
123 | 'test_\.+\.py', | |
101 |
|
|
124 | 'IPython.utils.tests.test_wildcard', | |
102 |
|
|
125 | 'testing', | |
103 |
|
|
126 | 'tests', | |
104 |
|
|
127 | 'PyColorize.py', | |
105 |
|
|
128 | '_process_win32_controller.py', | |
106 |
|
|
129 | 'IPython/core/application.py', | |
107 |
|
|
130 | 'IPython/core/profileapp.py', | |
108 |
|
|
131 | 'IPython/lib/deepreload.py', | |
109 |
|
|
132 | 'IPython/sphinxext/ipython_directive.py', | |
110 |
|
|
133 | 'IPython/terminal/ipapp.py', | |
111 |
|
|
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 |
|
|
314 | "--durations=10", | |
287 |
|
|
315 | "-pIPython.testing.plugin.pytest_ipdoctest", | |
288 |
|
|
316 | "--ipdoctest-modules", | |
289 |
|
|
317 | "--ignore=docs", | |
290 |
|
|
318 | "--ignore=examples", | |
291 |
|
|
319 | "--ignore=htmlcov", | |
292 |
|
|
320 | "--ignore=ipython_kernel", | |
293 |
|
|
321 | "--ignore=ipython_parallel", | |
294 |
|
|
322 | "--ignore=results", | |
295 |
|
|
323 | "--ignore=tmp", | |
296 |
|
|
324 | "--ignore=tools", | |
297 |
|
|
325 | "--ignore=traitlets", | |
298 |
|
|
326 | "--ignore=IPython/core/tests/daft_extension", | |
299 |
|
|
327 | "--ignore=IPython/sphinxext", | |
300 |
|
|
328 | "--ignore=IPython/terminal/pt_inputhooks", | |
301 |
|
|
329 | "--ignore=IPython/__main__.py", | |
302 |
|
|
330 | "--ignore=IPython/external/qt_for_kernel.py", | |
303 |
|
|
331 | "--ignore=IPython/html/widgets/widget_link.py", | |
304 |
|
|
332 | "--ignore=IPython/html/widgets/widget_output.py", | |
305 |
|
|
333 | "--ignore=IPython/terminal/console.py", | |
306 |
|
|
334 | "--ignore=IPython/utils/_process_cli.py", | |
307 |
|
|
335 | "--ignore=IPython/utils/_process_posix.py", | |
308 |
|
|
336 | "--ignore=IPython/utils/_process_win32_controller.py", | |
309 |
|
|
337 | "--ignore=IPython/utils/daemonize.py", | |
310 |
|
|
338 | "--ignore=IPython/utils/eventful.py", | |
311 |
|
|
339 | "--ignore=IPython/kernel", | |
312 |
|
|
340 | "--ignore=IPython/consoleapp.py", | |
313 |
|
|
341 | "--ignore=IPython/lib/kernel.py", | |
314 |
|
|
342 | "--ignore=IPython/utils/jsonutil.py", | |
315 |
|
|
343 | "--ignore=IPython/utils/localinterfaces.py", | |
316 |
|
|
344 | "--ignore=IPython/utils/log.py", | |
317 |
|
|
345 | "--ignore=IPython/utils/signatures.py", | |
318 |
|
|
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 |
|
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 = { |
|
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