diff --git a/IPython/core/application.py b/IPython/core/application.py index e5570ef..841e867 100644 --- a/IPython/core/application.py +++ b/IPython/core/application.py @@ -260,7 +260,7 @@ class BaseIPythonApplication(Application): # ensure current working directory exists try: os.getcwd() - except Exception: + except: # exit if cwd doesn't exist self.log.error("Current working directory doesn't exist.") self.exit(1) @@ -342,7 +342,7 @@ class BaseIPythonApplication(Application): try: if suppress_errors is not None: old_value = Application.raise_config_file_errors - Application.raise_config_file_errors = not suppress_errors + Application.raise_config_file_errors = not suppress_errors; Application.load_config_file( self, base_config, diff --git a/IPython/core/builtin_trap.py b/IPython/core/builtin_trap.py index 4e9a0d0..a8ea4ab 100644 --- a/IPython/core/builtin_trap.py +++ b/IPython/core/builtin_trap.py @@ -10,13 +10,10 @@ from traitlets.config.configurable import Configurable from traitlets import Instance -class __BuiltinUndefined: - pass +class __BuiltinUndefined(object): pass BuiltinUndefined = __BuiltinUndefined() - -class __HideBuiltin: - pass +class __HideBuiltin(object): pass HideBuiltin = __HideBuiltin() diff --git a/IPython/core/compilerop.py b/IPython/core/compilerop.py index d916a98..7799a4f 100644 --- a/IPython/core/compilerop.py +++ b/IPython/core/compilerop.py @@ -34,6 +34,7 @@ import functools import hashlib import linecache import operator +import time from contextlib import contextmanager #----------------------------------------------------------------------------- diff --git a/IPython/core/completer.py b/IPython/core/completer.py index f80675c..c9ed55e 100644 --- a/IPython/core/completer.py +++ b/IPython/core/completer.py @@ -226,6 +226,7 @@ from IPython.testing.skipdoctest import skip_doctest from IPython.utils import generics from IPython.utils.decorators import sphinx_options from IPython.utils.dir2 import dir2, get_real_method +from IPython.utils.docs import GENERATING_DOCUMENTATION from IPython.utils.path import ensure_dir_exists from IPython.utils.process import arg_split from traitlets import ( diff --git a/IPython/core/debugger.py b/IPython/core/debugger.py index 7c56ead..76c42e0 100644 --- a/IPython/core/debugger.py +++ b/IPython/core/debugger.py @@ -133,7 +133,7 @@ from functools import lru_cache from IPython import get_ipython from IPython.core.excolors import exception_colors -from IPython.utils import PyColorize, py3compat +from IPython.utils import PyColorize, coloransi, py3compat from typing import TYPE_CHECKING @@ -281,6 +281,11 @@ class Pdb(OldPdb): # module and add a few attributes needed for debugging self.color_scheme_table = exception_colors() + # shorthands + C = coloransi.TermColors + cst = self.color_scheme_table + + # Add a python parser so we can syntax highlight source while # debugging. self.parser = PyColorize.Parser(style=color_scheme) diff --git a/IPython/core/displayhook.py b/IPython/core/displayhook.py index 19139b8..b411f11 100644 --- a/IPython/core/displayhook.py +++ b/IPython/core/displayhook.py @@ -214,7 +214,7 @@ class DisplayHook(Configurable): # by the user. update_unders = True for unders in ['_'*i for i in range(1,4)]: - if unders not in self.shell.user_ns: + if not unders in self.shell.user_ns: continue if getattr(self, unders) is not self.shell.user_ns.get(unders): update_unders = False diff --git a/IPython/core/displaypub.py b/IPython/core/displaypub.py index db01f88..ed6a708 100644 --- a/IPython/core/displaypub.py +++ b/IPython/core/displaypub.py @@ -21,6 +21,9 @@ import sys from traitlets.config.configurable import Configurable from traitlets import List +# This used to be defined here - it is imported for backwards compatibility +from .display_functions import publish_display_data + import typing as t # ----------------------------------------------------------------------------- diff --git a/IPython/core/extensions.py b/IPython/core/extensions.py index 9fcc2c7..27c6a41 100644 --- a/IPython/core/extensions.py +++ b/IPython/core/extensions.py @@ -4,10 +4,13 @@ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. +import os +import os.path import sys from importlib import import_module, reload from traitlets.config.configurable import Configurable +from IPython.utils.path import ensure_dir_exists from traitlets import Instance diff --git a/IPython/core/history.py b/IPython/core/history.py index ee4f8a9..966d26f 100644 --- a/IPython/core/history.py +++ b/IPython/core/history.py @@ -954,6 +954,7 @@ class HistoryManager(HistoryAccessor): """ if (not self.db_log_output) or (line_num not in self.output_hist_reprs): return + lnum: int = line_num output = self.output_hist_reprs[line_num] with self.db_output_cache_lock: diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index ac19ed6..bbea59e 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -33,7 +33,7 @@ from io import open as io_open from logging import error from pathlib import Path from typing import Callable -from typing import List as ListType, Any as AnyType +from typing import List as ListType, Dict as DictType, Any as AnyType from typing import Optional, Sequence, Tuple from warnings import warn @@ -118,7 +118,7 @@ from IPython.core.usage import default_banner from IPython.display import display from IPython.paths import get_ipython_dir from IPython.testing.skipdoctest import skip_doctest -from IPython.utils import PyColorize, openpy, py3compat +from IPython.utils import PyColorize, io, openpy, py3compat from IPython.utils.decorators import undoc from IPython.utils.io import ask_yes_no from IPython.utils.ipstruct import Struct @@ -129,18 +129,6 @@ from IPython.utils.syspathcontext import prepended_to_syspath from IPython.utils.text import DollarFormatter, LSString, SList, format_screen from IPython.core.oinspect import OInfo -from ast import Module - -# we still need to run things using the asyncio eventloop, but there is no -# async integration - -from .async_helpers import ( - _asyncio_runner, - _curio_runner, - _pseudo_sync_runner, - _should_be_async, - _trio_runner, -) sphinxify: Optional[Callable] @@ -168,11 +156,26 @@ class ProvisionalWarning(DeprecationWarning): """ pass +from ast import Module _assign_nodes = (ast.AugAssign, ast.AnnAssign, ast.Assign) _single_targets_nodes = (ast.AugAssign, ast.AnnAssign) #----------------------------------------------------------------------------- +# Await Helpers +#----------------------------------------------------------------------------- + +# we still need to run things using the asyncio eventloop, but there is no +# async integration +from .async_helpers import ( + _asyncio_runner, + _curio_runner, + _pseudo_sync_runner, + _should_be_async, + _trio_runner, +) + +#----------------------------------------------------------------------------- # Globals #----------------------------------------------------------------------------- @@ -217,8 +220,7 @@ def no_op(*a, **kw): pass -class SpaceInInput(Exception): - pass +class SpaceInInput(Exception): pass class SeparateUnicode(Unicode): @@ -228,9 +230,8 @@ class SeparateUnicode(Unicode): """ def validate(self, obj, value): - if value == "0": - value = "" - value = value.replace("\\n", "\n") + if value == '0': value = '' + value = value.replace('\\n','\n') return super(SeparateUnicode, self).validate(obj, value) @@ -1571,7 +1572,7 @@ class InteractiveShell(SingletonConfigurable): for name in vlist: try: vdict[name] = eval(name, cf.f_globals, cf.f_locals) - except Exception: + except: print('Could not get variable %s from %s' % (name,cf.f_code.co_name)) else: @@ -1730,7 +1731,7 @@ class InteractiveShell(SingletonConfigurable): obj = obj[int(part)] else: obj = getattr(obj, part) - except Exception: + except: # Blanket except b/c some badly implemented objects # allow __getattr__ to raise exceptions other than # AttributeError, which then crashes IPython. @@ -2021,7 +2022,7 @@ class InteractiveShell(SingletonConfigurable): try: stb = handler(self,etype,value,tb,tb_offset=tb_offset) return validate_stb(stb) - except Exception: + except: # clear custom handler immediately self.set_custom_exc((), None) print("Custom TB Handler failed, unregistering", file=sys.stderr) @@ -2214,7 +2215,7 @@ class InteractiveShell(SingletonConfigurable): if filename and issubclass(etype, SyntaxError): try: value.filename = filename - except Exception: + except: # Not the format we expect; leave it alone pass @@ -2860,7 +2861,7 @@ class InteractiveShell(SingletonConfigurable): for key, expr in expressions.items(): try: value = self._format_user_obj(eval(expr, global_ns, user_ns)) - except Exception: + except: value = self._user_obj_error() out[key] = value return out @@ -2914,7 +2915,7 @@ class InteractiveShell(SingletonConfigurable): try: with fname.open("rb"): pass - except Exception: + except: warn('Could not open file <%s> for safe execution.' % fname) return @@ -2944,7 +2945,7 @@ class InteractiveShell(SingletonConfigurable): raise if not exit_ignore: self.showtraceback(exception_only=True) - except Exception: + except: if raise_exceptions: raise # tb offset is 2 because we wrap execfile @@ -2972,7 +2973,7 @@ class InteractiveShell(SingletonConfigurable): try: with fname.open("rb"): pass - except Exception: + except: warn('Could not open file <%s> for safe execution.' % fname) return @@ -3002,7 +3003,7 @@ class InteractiveShell(SingletonConfigurable): result.raise_error() elif not result.success: break - except Exception: + except: if raise_exceptions: raise self.showtraceback() @@ -3032,7 +3033,7 @@ class InteractiveShell(SingletonConfigurable): except SystemExit as status: if status.code: raise - except Exception: + except: self.showtraceback() warn('Unknown failure executing module: <%s>' % mod_name) @@ -3518,7 +3519,7 @@ class InteractiveShell(SingletonConfigurable): if softspace(sys.stdout, 0): print() - except Exception: + except: # It's possible to have exceptions raised here, typically by # compilation of odd code (such as a naked 'return' outside a # function) that did parse but isn't valid. Typically the exception @@ -3590,7 +3591,7 @@ class InteractiveShell(SingletonConfigurable): if result is not None: result.error_in_exec = value self.CustomTB(etype, value, tb) - except Exception: + except: if result is not None: result.error_in_exec = sys.exc_info()[1] self.showtraceback(running_compiled_code=True) @@ -3656,12 +3657,12 @@ class InteractiveShell(SingletonConfigurable): if not _matplotlib_manages_backends() and gui in (None, "auto"): # Early import of backend_inline required for its side effect of # calling _enable_matplotlib_integration() - import matplotlib_inline.backend_inline # noqa : F401 + import matplotlib_inline.backend_inline from IPython.core import pylabtools as pt gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select) - if gui is not None: + if gui != None: # If we have our first gui selection, store it if self.pylab_gui_select is None: self.pylab_gui_select = gui diff --git a/IPython/core/magics/__init__.py b/IPython/core/magics/__init__.py index fa820b6..a6c5f47 100644 --- a/IPython/core/magics/__init__.py +++ b/IPython/core/magics/__init__.py @@ -1,39 +1,36 @@ """Implementation of all the magic functions built into IPython. """ - -# ----------------------------------------------------------------------------- +#----------------------------------------------------------------------------- # Copyright (c) 2012 The IPython Development Team. # # Distributed under the terms of the Modified BSD License. # # The full license is in the file COPYING.txt, distributed with this software. -# ----------------------------------------------------------------------------- +#----------------------------------------------------------------------------- -# ----------------------------------------------------------------------------- +#----------------------------------------------------------------------------- # Imports -# ----------------------------------------------------------------------------- - -from ..magic import Magics as Magics, magics_class as magics_class -from .auto import AutoMagics as AutoMagics -from .basic import BasicMagics as BasicMagics, AsyncMagics as AsyncMagics -from .code import CodeMagics as CodeMagics, MacroToEdit as MacroToEdit -from .config import ConfigMagics as ConfigMagics -from .display import DisplayMagics as DisplayMagics -from .execution import ExecutionMagics as ExecutionMagics -from .extension import ExtensionMagics as ExtensionMagics -from .history import HistoryMagics as HistoryMagics -from .logging import LoggingMagics as LoggingMagics -from .namespace import NamespaceMagics as NamespaceMagics -from .osm import OSMagics as OSMagics -from .packaging import PackagingMagics as PackagingMagics -from .pylab import PylabMagics as PylabMagics -from .script import ScriptMagics as ScriptMagics - - -# ----------------------------------------------------------------------------- +#----------------------------------------------------------------------------- + +from ..magic import Magics, magics_class +from .auto import AutoMagics +from .basic import BasicMagics, AsyncMagics +from .code import CodeMagics, MacroToEdit +from .config import ConfigMagics +from .display import DisplayMagics +from .execution import ExecutionMagics +from .extension import ExtensionMagics +from .history import HistoryMagics +from .logging import LoggingMagics +from .namespace import NamespaceMagics +from .osm import OSMagics +from .packaging import PackagingMagics +from .pylab import PylabMagics +from .script import ScriptMagics + +#----------------------------------------------------------------------------- # Magic implementation classes -# ----------------------------------------------------------------------------- - +#----------------------------------------------------------------------------- @magics_class class UserMagics(Magics): diff --git a/IPython/core/magics/auto.py b/IPython/core/magics/auto.py index 329e7ac..56aa4f7 100644 --- a/IPython/core/magics/auto.py +++ b/IPython/core/magics/auto.py @@ -118,14 +118,14 @@ class AutoMagics(Magics): return error if parameter_s: - if parameter_s not in map(str, valid_modes.keys()): + if not parameter_s in map(str, valid_modes.keys()): error(errorMessage()) return arg = int(parameter_s) else: arg = 'toggle' - if arg not in (*list(valid_modes.keys()), "toggle"): + if not arg in (*list(valid_modes.keys()), "toggle"): error(errorMessage()) return diff --git a/IPython/core/magics/execution.py b/IPython/core/magics/execution.py index bcaf36d..3aa0a27 100644 --- a/IPython/core/magics/execution.py +++ b/IPython/core/magics/execution.py @@ -8,6 +8,7 @@ import ast import bdb import builtins as builtin_mod +import copy import cProfile as profile import gc import itertools @@ -21,16 +22,25 @@ import time import timeit from typing import Dict, Any from ast import ( + Assign, + Call, + Expr, + Load, Module, + Name, + NodeTransformer, + Store, + parse, + unparse, ) from io import StringIO from logging import error from pathlib import Path from pdb import Restart -from textwrap import indent +from textwrap import dedent, indent from warnings import warn -from IPython.core import magic_arguments, page +from IPython.core import magic_arguments, oinspect, page from IPython.core.displayhook import DisplayHook from IPython.core.error import UsageError from IPython.core.macro import Macro @@ -1447,12 +1457,10 @@ class ExecutionMagics(Magics): return macro = Macro(lines) self.shell.define_macro(name, macro) - if "q" not in opts: - print( - "Macro `%s` created. To execute, type its name (without quotes)." % name - ) - print("=== Macro contents: ===") - print(macro, end=" ") + if not ( 'q' in opts) : + print('Macro `%s` created. To execute, type its name (without quotes).' % name) + print('=== Macro contents: ===') + print(macro, end=' ') @magic_arguments.magic_arguments() @magic_arguments.argument('output', type=str, default='', nargs='?', diff --git a/IPython/core/magics/osm.py b/IPython/core/magics/osm.py index 48cb6c9..f64f1bc 100644 --- a/IPython/core/magics/osm.py +++ b/IPython/core/magics/osm.py @@ -425,9 +425,9 @@ class OSMagics(Magics): if oldcwd != cwd: dhist.append(cwd) - self.shell.db["dhist"] = compress_dhist(dhist)[-100:] - if "q" not in opts and not self.cd_force_quiet and self.shell.user_ns["_dh"]: - print(self.shell.user_ns["_dh"][-1]) + self.shell.db['dhist'] = compress_dhist(dhist)[-100:] + if not 'q' in opts and not self.cd_force_quiet and self.shell.user_ns['_dh']: + print(self.shell.user_ns['_dh'][-1]) @line_magic def env(self, parameter_s=''): diff --git a/IPython/core/oinspect.py b/IPython/core/oinspect.py index 6fb6039..30e2bbc 100644 --- a/IPython/core/oinspect.py +++ b/IPython/core/oinspect.py @@ -255,6 +255,7 @@ def getsource(obj, oname='') -> Union[str,None]: for attrname in ['fget', 'fset', 'fdel']: fn = getattr(obj, attrname) if fn is not None: + encoding = get_encoding(fn) oname_prefix = ('%s.' % oname) if oname else '' sources.append(''.join(('# ', oname_prefix, attrname))) if inspect.isfunction(fn): diff --git a/IPython/core/page.py b/IPython/core/page.py index 5ebd351..2eb6c39 100644 --- a/IPython/core/page.py +++ b/IPython/core/page.py @@ -223,6 +223,7 @@ def pager_page(strng, start=0, screen_lines=0, pager_cmd=None) -> None: io.TextIOWrapper(proc.stdin, encoding="utf-8"), proc ) try: + pager_encoding = pager.encoding or sys.stdout.encoding pager.write(strng) finally: retval = pager.close() diff --git a/IPython/core/payloadpage.py b/IPython/core/payloadpage.py index f44bb2b..ba2bca2 100644 --- a/IPython/core/payloadpage.py +++ b/IPython/core/payloadpage.py @@ -3,6 +3,7 @@ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. +import warnings from IPython.core.getipython import get_ipython # see https://github.com/ipython/ipykernel/issues/1304 diff --git a/IPython/core/tests/refbug.py b/IPython/core/tests/refbug.py index bbf550f..92e2eea 100644 --- a/IPython/core/tests/refbug.py +++ b/IPython/core/tests/refbug.py @@ -30,8 +30,8 @@ if __name__ == '__main__': ip = get_ipython() - if "_refbug_cache" not in ip.user_ns: - ip.user_ns["_refbug_cache"] = [] + if not '_refbug_cache' in ip.user_ns: + ip.user_ns['_refbug_cache'] = [] aglobal = 'Hello' diff --git a/IPython/core/tests/test_exceptiongroup_tb.py b/IPython/core/tests/test_exceptiongroup_tb.py index d36e0e7..4efa3d3 100644 --- a/IPython/core/tests/test_exceptiongroup_tb.py +++ b/IPython/core/tests/test_exceptiongroup_tb.py @@ -1,5 +1,10 @@ +import unittest +import re from IPython.utils.capture import capture_output +import sys import pytest +from tempfile import TemporaryDirectory +from IPython.testing import tools as tt def _exceptiongroup_common( diff --git a/IPython/core/tests/test_formatters.py b/IPython/core/tests/test_formatters.py index 4e4d415..5f8eeda 100644 --- a/IPython/core/tests/test_formatters.py +++ b/IPython/core/tests/test_formatters.py @@ -12,6 +12,7 @@ from IPython import get_ipython from traitlets.config import Config from IPython.core.formatters import ( PlainTextFormatter, HTMLFormatter, PDFFormatter, _mod_name_key, + DisplayFormatter, JSONFormatter, ) from IPython.utils.io import capture_output diff --git a/IPython/core/tests/test_handlers.py b/IPython/core/tests/test_handlers.py index c8c89df..905d9ab 100644 --- a/IPython/core/tests/test_handlers.py +++ b/IPython/core/tests/test_handlers.py @@ -6,6 +6,7 @@ # our own packages from IPython.core import autocall +from IPython.testing import tools as tt import pytest from collections.abc import Callable diff --git a/IPython/core/tests/test_interactiveshell.py b/IPython/core/tests/test_interactiveshell.py index a272cc2..f87d96f 100644 --- a/IPython/core/tests/test_interactiveshell.py +++ b/IPython/core/tests/test_interactiveshell.py @@ -23,6 +23,7 @@ from unittest import mock from os.path import join from IPython.core.error import InputRejected +from IPython.core.inputtransformer import InputTransformer from IPython.core import interactiveshell from IPython.core.oinspect import OInfo from IPython.testing.decorators import ( diff --git a/IPython/core/tests/test_iplib.py b/IPython/core/tests/test_iplib.py index 373dc82..a5e51fb 100644 --- a/IPython/core/tests/test_iplib.py +++ b/IPython/core/tests/test_iplib.py @@ -2,6 +2,7 @@ """ import stack_data +import sys SV_VERSION = tuple([int(x) for x in stack_data.__version__.split(".")[0:2]]) diff --git a/IPython/core/tests/test_magic.py b/IPython/core/tests/test_magic.py index d86c278..036f250 100644 --- a/IPython/core/tests/test_magic.py +++ b/IPython/core/tests/test_magic.py @@ -35,16 +35,12 @@ from IPython.utils.process import find_cmd from IPython.utils.tempdir import TemporaryDirectory, TemporaryWorkingDirectory from IPython.utils.syspathcontext import prepended_to_syspath -# import needed by doctest -from .test_debugger import PdbTestInput # noqa: F401 - -_ip = get_ipython() +from .test_debugger import PdbTestInput +from tempfile import NamedTemporaryFile @magic.magics_class -class DummyMagics(magic.Magics): - pass - +class DummyMagics(magic.Magics): pass def test_extract_code_ranges(): instr = "1 3 5-6 7-9 10:15 17: :10 10- -13 :" @@ -63,24 +59,24 @@ def test_extract_code_ranges(): actual = list(code.extract_code_ranges(instr)) assert actual == expected - def test_extract_symbols(): source = """import foo\na = 10\ndef b():\n return 42\n\n\nclass A: pass\n\n\n""" symbols_args = ["a", "b", "A", "A,b", "A,a", "z"] - expected = [ - ([], ["a"]), - (["def b():\n return 42\n"], []), - (["class A: pass\n"], []), - (["class A: pass\n", "def b():\n return 42\n"], []), - (["class A: pass\n"], ["a"]), - ([], ["z"]), - ] + expected = [([], ['a']), + (["def b():\n return 42\n"], []), + (["class A: pass\n"], []), + (["class A: pass\n", "def b():\n return 42\n"], []), + (["class A: pass\n"], ['a']), + ([], ['z'])] for symbols, exp in zip(symbols_args, expected): assert code.extract_symbols(source, symbols) == exp def test_extract_symbols_raises_exception_with_non_python_code(): - source = "=begin A Ruby program :)=end\n" "def hello\n" "puts 'Hello world'\n" "end" + source = ("=begin A Ruby program :)=end\n" + "def hello\n" + "puts 'Hello world'\n" + "end") with pytest.raises(SyntaxError): code.extract_symbols(source, "hello") @@ -91,31 +87,30 @@ def test_magic_not_found(): _ip.run_line_magic("doesntexist", "") # ensure result isn't success when a magic isn't found - result = _ip.run_cell("%doesntexist") + result = _ip.run_cell('%doesntexist') assert isinstance(result.error_in_exec, UsageError) def test_cell_magic_not_found(): # magic not found raises UsageError with pytest.raises(UsageError): - _ip.run_cell_magic("doesntexist", "line", "cell") + _ip.run_cell_magic('doesntexist', 'line', 'cell') # ensure result isn't success when a magic isn't found - result = _ip.run_cell("%%doesntexist") + result = _ip.run_cell('%%doesntexist') assert isinstance(result.error_in_exec, UsageError) def test_magic_error_status(): def fail(shell): - 1 / 0 - + 1/0 _ip.register_magic_function(fail) - result = _ip.run_cell("%fail") + result = _ip.run_cell('%fail') assert isinstance(result.error_in_exec, ZeroDivisionError) def test_config(): - """test that config magic does not raise + """ test that config magic does not raise can happen if Configurable init is moved too early into Magics.__init__ as then a Config object will be registered as a magic. @@ -125,18 +120,17 @@ def test_config(): def test_config_available_configs(): - """test that config magic prints available configs in unique and - sorted order.""" + """ test that config magic prints available configs in unique and + sorted order. """ with capture_output() as captured: _ip.run_line_magic("config", "") stdout = captured.stdout - config_classes = stdout.strip().split("\n")[1:] + config_classes = stdout.strip().split('\n')[1:] assert config_classes == sorted(set(config_classes)) - def test_config_print_class(): - """test that config with a classname prints the class's options.""" + """ test that config with a classname prints the class's options. """ with capture_output() as captured: _ip.run_line_magic("config", "TerminalInteractiveShell") @@ -149,7 +143,7 @@ def test_config_print_class(): def test_rehashx(): # clear up everything _ip.alias_manager.clear_aliases() - del _ip.db["syscmdlist"] + del _ip.db['syscmdlist'] _ip.run_line_magic("rehashx", "") # Practically ALL ipython development systems will have more than 10 aliases @@ -160,19 +154,19 @@ def test_rehashx(): assert "." not in name # rehashx must fill up syscmdlist - scoms = _ip.db["syscmdlist"] + scoms = _ip.db['syscmdlist'] assert len(scoms) > 10 def test_magic_parse_options(): """Test that we don't mangle paths when parsing magic options.""" ip = get_ipython() - path = "c:\\x" + path = 'c:\\x' m = DummyMagics(ip) - opts = m.parse_options("-f %s" % path, "f:")[0] + opts = m.parse_options('-f %s' % path,'f:')[0] # argv splitting is os-dependent - if os.name == "posix": - expected = "c:x" + if os.name == 'posix': + expected = 'c:x' else: expected = path assert opts["f"] == expected @@ -267,21 +261,20 @@ def doctest_hist_op(): >>> """ - def test_hist_pof(): ip = get_ipython() ip.run_cell("1+2", store_history=True) - # raise Exception(ip.history_manager.session_number) - # raise Exception(list(ip.history_manager._get_range_session())) + #raise Exception(ip.history_manager.session_number) + #raise Exception(list(ip.history_manager._get_range_session())) with TemporaryDirectory() as td: - tf = os.path.join(td, "hist.py") - ip.run_line_magic("history", "-pof %s" % tf) + tf = os.path.join(td, 'hist.py') + ip.run_line_magic('history', '-pof %s' % tf) assert os.path.isfile(tf) def test_macro(): ip = get_ipython() - ip.history_manager.reset() # Clear any existing history. + ip.history_manager.reset() # Clear any existing history. cmds = ["a=1", "def b():\n return a**2", "print(a,b())"] for i, cmd in enumerate(cmds, start=1): ip.history_manager.store_inputs(i, cmd) @@ -368,12 +361,13 @@ def test_reset_in_length(): class TestResetErrors(TestCase): + def test_reset_redefine(self): + @magics_class class KernelMagics(Magics): - @line_magic - def less(self, shell): - pass + @line_magic + def less(self, shell): pass _ip.register_magics(KernelMagics) @@ -382,9 +376,8 @@ class TestResetErrors(TestCase): # logs get produce. # so log one things we ignore. import logging as log_mod - log = log_mod.getLogger() - log.info("Nothing") + log.info('Nothing') # end hack. _ip.run_cell("reset -f") @@ -392,7 +385,6 @@ class TestResetErrors(TestCase): for out in cm.output: assert "Invalid alias" not in out - def test_tb_syntaxerror(): """test %tb after a SyntaxError""" ip = get_ipython() @@ -417,7 +409,8 @@ def test_time(): with tt.AssertPrints("Wall time: "): ip.run_cell("%time None") - ip.run_cell("def f(kmjy):\n" " %time print (2*kmjy)") + ip.run_cell("def f(kmjy):\n" + " %time print (2*kmjy)") with tt.AssertPrints("Wall time: "): with tt.AssertPrints("hihi", suppress=False): @@ -483,11 +476,13 @@ def test_time_no_output_with_semicolon(): def test_time_last_not_expression(): - _ip.run_cell("%%time\n" "var_1 = 1\n" "var_2 = 2\n") - assert _ip.user_ns["var_1"] == 1 - del _ip.user_ns["var_1"] - assert _ip.user_ns["var_2"] == 2 - del _ip.user_ns["var_2"] + ip.run_cell("%%time\n" + "var_1 = 1\n" + "var_2 = 2\n") + assert ip.user_ns['var_1'] == 1 + del ip.user_ns['var_1'] + assert ip.user_ns['var_2'] == 2 + del ip.user_ns['var_2'] @dec.skip_win32 @@ -497,20 +492,20 @@ def test_time2(): with tt.AssertPrints("CPU times: user "): ip.run_cell("%time None") - def test_time3(): """Erroneous magic function calls, issue gh-3334""" ip = get_ipython() - ip.user_ns.pop("run", None) - - with tt.AssertNotPrints("not found", channel="stderr"): - ip.run_cell("%%time\n" "run = 0\n" "run += 1") + ip.user_ns.pop('run', None) + with tt.AssertNotPrints("not found", channel='stderr'): + ip.run_cell("%%time\n" + "run = 0\n" + "run += 1") def test_multiline_time(): """Make sure last statement from time return a value.""" ip = get_ipython() - ip.user_ns.pop("run", None) + ip.user_ns.pop('run', None) ip.run_cell( dedent( @@ -627,7 +622,7 @@ def test_cd_force_quiet(): with tt.AssertNotPrints(ipdir): osmagics.cd('"%s"' % ipdir) with tt.AssertNotPrints(startdir): - osmagics.cd("-") + osmagics.cd('-') finally: os.chdir(startdir) @@ -639,14 +634,11 @@ def test_xmode(): _ip.run_line_magic("xmode", "") assert _ip.InteractiveTB.mode == xmode - def test_reset_hard(): monitor = [] - class A(object): def __del__(self): monitor.append(1) - def __repr__(self): return "" @@ -657,17 +649,14 @@ def test_reset_hard(): _ip.run_line_magic("reset", "-f") assert monitor == [1] - class TestXdel(tt.TempFileMixin): def test_xdel(self): """Test that references from %run are cleared by xdel.""" - src = ( - "class A(object):\n" - " monitor = []\n" - " def __del__(self):\n" - " self.monitor.append(1)\n" - "a = A()\n" - ) + src = ("class A(object):\n" + " monitor = []\n" + " def __del__(self):\n" + " self.monitor.append(1)\n" + "a = A()\n") self.mktmp(src) # %run creates some hidden references... _ip.run_line_magic("run", "%s" % self.fname) @@ -683,7 +672,6 @@ class TestXdel(tt.TempFileMixin): gc.collect(0) assert monitor == [1] - def doctest_who(): """doctest for %who @@ -709,18 +697,14 @@ def doctest_who(): Out[7]: ['alpha', 'beta'] """ - def test_whos(): """Check that whos is protected against objects where repr() fails.""" - class A(object): def __repr__(self): raise Exception() - - _ip.user_ns["a"] = A() + _ip.user_ns['a'] = A() _ip.run_line_magic("whos", "") - def doctest_precision(): """doctest for %precision @@ -768,14 +752,12 @@ def test_debug_magic_locals(): In [2]: """ - def test_psearch(): with tt.AssertPrints("dict.fromkeys"): _ip.run_cell("dict.fr*?") with tt.AssertPrints("π.is_integer"): _ip.run_cell("π = 3.14;\nπ.is_integ*?") - def test_timeit_shlex(): """test shlex issues with timeit (#1109)""" _ip.ex("def f(*a,**kw): pass") @@ -789,11 +771,10 @@ def test_timeit_shlex(): def test_timeit_special_syntax(): "Test %%timeit with IPython special syntax" - @register_line_magic def lmagic(line): ip = get_ipython() - ip.user_ns["lmagic_out"] = line + ip.user_ns['lmagic_out'] = line # line mode test _ip.run_line_magic("timeit", "-n1 -r1 %lmagic my line") @@ -808,9 +789,8 @@ def test_timeit_return(): test whether timeit -o return object """ - res = _ip.run_line_magic("timeit", "-n10 -r10 -o 1") - assert res is not None - + res = _ip.run_line_magic('timeit','-n10 -r10 -o 1') + assert(res is not None) def test_timeit_quiet(): """ @@ -819,26 +799,22 @@ def test_timeit_quiet(): with tt.AssertNotPrints("loops"): _ip.run_cell("%timeit -n1 -r1 -q 1") - def test_timeit_return_quiet(): with tt.AssertNotPrints("loops"): - res = _ip.run_line_magic("timeit", "-n1 -r1 -q -o 1") - assert res is not None - + res = _ip.run_line_magic('timeit', '-n1 -r1 -q -o 1') + assert (res is not None) def test_timeit_invalid_return(): with pytest.raises(SyntaxError): - _ip.run_line_magic("timeit", "return") - + _ip.run_line_magic('timeit', 'return') @dec.skipif(execution.profile is None) def test_prun_special_syntax(): "Test %%prun with IPython special syntax" - @register_line_magic def lmagic(line): ip = get_ipython() - ip.user_ns["lmagic_out"] = line + ip.user_ns['lmagic_out'] = line # line mode test _ip.run_line_magic("prun", "-q %lmagic my line") @@ -857,21 +833,21 @@ def test_prun_quotes(): def test_extension(): # Debugging information for failures of this test - print("sys.path:") + print('sys.path:') for p in sys.path: - print(" ", p) - print("CWD", os.getcwd()) + print(' ', p) + print('CWD', os.getcwd()) pytest.raises(ImportError, _ip.run_line_magic, "load_ext", "daft_extension") daft_path = os.path.join(os.path.dirname(__file__), "daft_extension") sys.path.insert(0, daft_path) try: - _ip.user_ns.pop("arq", None) - invalidate_caches() # Clear import caches + _ip.user_ns.pop('arq', None) + invalidate_caches() # Clear import caches _ip.run_line_magic("load_ext", "daft_extension") assert _ip.user_ns["arq"] == 185 _ip.run_line_magic("unload_ext", "daft_extension") - assert "arq" not in _ip.user_ns + assert 'arq' not in _ip.user_ns finally: sys.path.remove(daft_path) @@ -879,7 +855,7 @@ def test_extension(): def test_notebook_export_json(): pytest.importorskip("nbformat") _ip = get_ipython() - _ip.history_manager.reset() # Clear any existing history. + _ip.history_manager.reset() # Clear any existing history. cmds = ["a=1", "def b():\n return a**2", "print('noël, été', b())"] for i, cmd in enumerate(cmds, start=1): _ip.history_manager.store_inputs(i, cmd) @@ -889,6 +865,7 @@ def test_notebook_export_json(): class TestEnv(TestCase): + def test_env(self): env = _ip.run_line_magic("env", "") self.assertTrue(isinstance(env, dict)) @@ -902,8 +879,8 @@ class TestEnv(TestCase): "API_KEY": "abc123", "SECRET_THING": "ssshhh", "JUPYTER_TOKEN": "", - "VAR": "abc", - }, + "VAR": "abc" + } ): env = _ip.run_line_magic("env", "") assert env["API_KEY"] == hidden @@ -918,16 +895,16 @@ class TestEnv(TestCase): self.assertEqual(_ip.run_line_magic("env", "var"), "val1") env = _ip.run_line_magic("env", "var=val2") self.assertEqual(env, None) - self.assertEqual(os.environ["var"], "val2") + self.assertEqual(os.environ['var'], 'val2') def test_env_get_set_complex(self): env = _ip.run_line_magic("env", "var 'val1 '' 'val2") self.assertEqual(env, None) - self.assertEqual(os.environ["var"], "'val1 '' 'val2") + self.assertEqual(os.environ['var'], "'val1 '' 'val2") self.assertEqual(_ip.run_line_magic("env", "var"), "'val1 '' 'val2") env = _ip.run_line_magic("env", 'var=val2 val3="val4') self.assertEqual(env, None) - self.assertEqual(os.environ["var"], 'val2 val3="val4') + self.assertEqual(os.environ['var'], 'val2 val3="val4') def test_env_set_bad_input(self): self.assertRaises(UsageError, lambda: _ip.run_line_magic("set_env", "var")) @@ -937,6 +914,7 @@ class TestEnv(TestCase): class CellMagicTestCase(TestCase): + def check_ident(self, magic): # Manually called, we get the result out = _ip.run_cell_magic(magic, "a", "b") @@ -947,49 +925,46 @@ class CellMagicTestCase(TestCase): def test_cell_magic_func_deco(self): "Cell magic using simple decorator" - @register_cell_magic def cellm(line, cell): return line, cell - self.check_ident("cellm") + self.check_ident('cellm') def test_cell_magic_reg(self): "Cell magic manually registered" - def cellm(line, cell): return line, cell - _ip.register_magic_function(cellm, "cell", "cellm2") - self.check_ident("cellm2") + _ip.register_magic_function(cellm, 'cell', 'cellm2') + self.check_ident('cellm2') def test_cell_magic_class(self): "Cell magics declared via a class" - @magics_class class MyMagics(Magics): + @cell_magic def cellm3(self, line, cell): return line, cell _ip.register_magics(MyMagics) - self.check_ident("cellm3") + self.check_ident('cellm3') def test_cell_magic_class2(self): "Cell magics declared via a class, #2" - @magics_class class MyMagics2(Magics): - @cell_magic("cellm4") + + @cell_magic('cellm4') def cellm33(self, line, cell): return line, cell _ip.register_magics(MyMagics2) - self.check_ident("cellm4") + self.check_ident('cellm4') # Check that nothing is registered as 'cellm33' - c33 = _ip.find_cell_magic("cellm33") - assert c33 is None - + c33 = _ip.find_cell_magic('cellm33') + assert c33 == None def test_file(): """Basic %%writefile""" @@ -1078,18 +1053,12 @@ def test_file_unicode(): """%%writefile with unicode cell""" ip = get_ipython() with TemporaryDirectory() as td: - fname = os.path.join(td, "file1") - ip.run_cell_magic( - "writefile", - fname, - "\n".join( - [ - "liné1", - "liné2", - ] - ), - ) - with io.open(fname, encoding="utf-8") as f: + fname = os.path.join(td, 'file1') + ip.run_cell_magic("writefile", fname, u'\n'.join([ + u'liné1', + u'liné2', + ])) + with io.open(fname, encoding='utf-8') as f: s = f.read() assert "liné1\n" in s assert "liné2" in s @@ -1128,7 +1097,7 @@ def test_file_amend(): def test_file_spaces(): """%%file with spaces in filename""" ip = get_ipython() - with TemporaryWorkingDirectory(): + with TemporaryWorkingDirectory() as td: fname = "file name" ip.run_cell_magic( "file", @@ -1147,7 +1116,7 @@ def test_file_spaces(): def test_script_config(): ip = get_ipython() - ip.config.ScriptMagics.script_magics = ["whoda"] + ip.config.ScriptMagics.script_magics = ['whoda'] sm = script.ScriptMagics(shell=ip) assert "whoda" in sm.magics["cell"] @@ -1247,7 +1216,7 @@ async def test_script_bg_proc(): def test_script_defaults(): ip = get_ipython() - for cmd in ["sh", "bash", "perl", "ruby"]: + for cmd in ['sh', 'bash', 'perl', 'ruby']: try: find_cmd(cmd) except Exception: @@ -1259,8 +1228,7 @@ def test_script_defaults(): @magics_class class FooFoo(Magics): """class with both %foo and %%foo magics""" - - @line_magic("foo") + @line_magic('foo') def line_foo(self, line): "I am line foo" pass @@ -1270,7 +1238,6 @@ class FooFoo(Magics): "I am cell foo, not line foo" pass - def test_line_cell_info(): """%%foo and %foo magics are distinguishable to inspect""" ip = get_ipython() @@ -1330,7 +1297,7 @@ def test_alias_magic(): def test_save(): """Test %save.""" ip = get_ipython() - ip.history_manager.reset() # Clear any existing history. + ip.history_manager.reset() # Clear any existing history. cmds = ["a=1", "def b():\n return a**2", "print(a, b())"] for i, cmd in enumerate(cmds, start=1): ip.history_manager.store_inputs(i, cmd) @@ -1372,7 +1339,7 @@ def test_save_with_no_args(): def test_store(): """Test %store.""" ip = get_ipython() - ip.run_line_magic("load_ext", "storemagic") + ip.run_line_magic('load_ext', 'storemagic') # make sure the storage is empty ip.run_line_magic("store", "-z") @@ -1388,19 +1355,20 @@ def test_store(): assert ip.user_ns["var"] == 39 -def _run_edit_test( - arg_s, exp_filename=None, exp_lineno=-1, exp_contents=None, exp_is_temp=None -): +def _run_edit_test(arg_s, exp_filename=None, + exp_lineno=-1, + exp_contents=None, + exp_is_temp=None): ip = get_ipython() M = code.CodeMagics(ip) - last_call = ["", ""] - opts, args = M.parse_options(arg_s, "prxn:") + last_call = ['',''] + opts,args = M.parse_options(arg_s,'prxn:') filename, lineno, is_temp = M._find_edit_target(ip, args, opts, last_call) if exp_filename is not None: assert exp_filename == filename if exp_contents is not None: - with io.open(filename, "r", encoding="utf-8") as f: + with io.open(filename, 'r', encoding='utf-8') as f: contents = f.read() assert exp_contents == contents if exp_lineno != -1: @@ -1427,26 +1395,23 @@ def test_edit_cell(): ip.run_cell("def foo(): return 1", store_history=True) # test - _run_edit_test("1", exp_contents=ip.user_ns["In"][1], exp_is_temp=True) - + _run_edit_test("1", exp_contents=ip.user_ns['In'][1], exp_is_temp=True) def test_edit_fname(): """%edit file""" # test _run_edit_test("test file.py", exp_filename="test file.py") - def test_bookmark(): ip = get_ipython() - ip.run_line_magic("bookmark", "bmname") - with tt.AssertPrints("bmname"): - ip.run_line_magic("bookmark", "-l") - ip.run_line_magic("bookmark", "-d bmname") - + ip.run_line_magic('bookmark', 'bmname') + with tt.AssertPrints('bmname'): + ip.run_line_magic('bookmark', '-l') + ip.run_line_magic('bookmark', '-d bmname') def test_ls_magic(): ip = get_ipython() - json_formatter = ip.display_formatter.formatters["application/json"] + json_formatter = ip.display_formatter.formatters['application/json'] json_formatter.enabled = True lsmagic = ip.run_line_magic("lsmagic", "") with warnings.catch_warnings(record=True) as w: @@ -1458,24 +1423,23 @@ def test_ls_magic(): def test_strip_initial_indent(): def sii(s): lines = s.splitlines() - return "\n".join(code.strip_initial_indent(lines)) + return '\n'.join(code.strip_initial_indent(lines)) assert sii(" a = 1\nb = 2") == "a = 1\nb = 2" assert sii(" a\n b\nc") == "a\n b\nc" assert sii("a\n b") == "a\n b" - def test_logging_magic_quiet_from_arg(): _ip.config.LoggingMagics.quiet = False lm = logging.LoggingMagics(shell=_ip) with TemporaryDirectory() as td: try: with tt.AssertNotPrints(re.compile("Activating.*")): - lm.logstart("-q {}".format(os.path.join(td, "quiet_from_arg.log"))) + lm.logstart('-q {}'.format( + os.path.join(td, "quiet_from_arg.log"))) finally: _ip.logger.logstop() - def test_logging_magic_quiet_from_config(): _ip.config.LoggingMagics.quiet = True lm = logging.LoggingMagics(shell=_ip) @@ -1538,16 +1502,18 @@ def load_ipython_extension(ipython): def test_lazy_magics(): with pytest.raises(UsageError): - _ip.run_line_magic("lazy_line", "") + ip.run_line_magic("lazy_line", "") + + startdir = os.getcwd() with TemporaryDirectory() as tmpdir: with prepended_to_syspath(tmpdir): ptempdir = Path(tmpdir) tf = ptempdir / "lazy_magic_module.py" tf.write_text(MINIMAL_LAZY_MAGIC) - _ip.magics_manager.register_lazy("lazy_line", Path(tf.name).name[:-3]) + ip.magics_manager.register_lazy("lazy_line", Path(tf.name).name[:-3]) with tt.AssertPrints("Lazy Line"): - _ip.run_line_magic("lazy_line", "") + ip.run_line_magic("lazy_line", "") TEST_MODULE = """ @@ -1556,7 +1522,6 @@ if __name__ == "__main__": print('I just ran a script') """ - def test_run_module_from_import_hook(): "Test that a module can be loaded via an import hook" with TemporaryDirectory() as tmpdir: diff --git a/IPython/core/tests/test_paths.py b/IPython/core/tests/test_paths.py index cc29a97..8e4a63f 100644 --- a/IPython/core/tests/test_paths.py +++ b/IPython/core/tests/test_paths.py @@ -100,7 +100,7 @@ def test_get_ipython_dir_4(): 'IPYTHONDIR': None, 'XDG_CONFIG_HOME': XDG_TEST_DIR, }), warnings.catch_warnings(record=True) as w: - _ipdir = paths.get_ipython_dir() + ipdir = paths.get_ipython_dir() assert len(w) == 1 assert "Ignoring" in str(w[0]) diff --git a/IPython/core/tests/test_prefilter.py b/IPython/core/tests/test_prefilter.py index 2cb164f..379a530 100644 --- a/IPython/core/tests/test_prefilter.py +++ b/IPython/core/tests/test_prefilter.py @@ -3,6 +3,7 @@ #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- +import pytest from IPython.core.prefilter import AutocallChecker diff --git a/IPython/core/tests/test_ultratb.py b/IPython/core/tests/test_ultratb.py index 2d26af2..c8f5271 100644 --- a/IPython/core/tests/test_ultratb.py +++ b/IPython/core/tests/test_ultratb.py @@ -257,6 +257,7 @@ bar() with tt.AssertPrints('QWERTY'): ip.showsyntaxerror() +import sys if platform.python_implementation() != "PyPy": """ diff --git a/IPython/core/ultratb.py b/IPython/core/ultratb.py index 2d10a02..a8a38f1 100644 --- a/IPython/core/ultratb.py +++ b/IPython/core/ultratb.py @@ -188,7 +188,7 @@ def _safe_string(value, what, func=str): # Copied from cpython/Lib/traceback.py try: return func(value) - except Exception: + except: return f"<{what} {func.__name__}() failed>" @@ -730,9 +730,9 @@ class ListTB(TBTools): def _some_str(self, value): # Lifted from traceback.py try: - return str(value) + return py3compat.cast_unicode(str(value)) except: - return "" % type(value).__name__ + return u'' % type(value).__name__ class FrameInfo: @@ -1048,7 +1048,7 @@ class VerboseTB(TBTools): colors.excName, etype_str, colorsnormal, - evalue_str, + py3compat.cast_unicode(evalue_str), ), *( "{}{}".format( @@ -1071,6 +1071,8 @@ class VerboseTB(TBTools): This may be called multiple times by Python 3 exception chaining (PEP 3134). """ + # some locals + orig_etype = etype try: etype = etype.__name__ # type: ignore except AttributeError: @@ -1213,7 +1215,7 @@ class VerboseTB(TBTools): chained_exceptions_tb_offset) exception = self.get_parts_of_chained_exception(evalue) - if exception and id(exception[1]) not in chained_exc_ids: + if exception and not id(exception[1]) in chained_exc_ids: chained_exc_ids.add(id(exception[1])) # trace exception to avoid infinite 'cause' loop formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__) etype, evalue, etb = exception @@ -1408,7 +1410,7 @@ class AutoFormattedTB(FormattedTB): AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux') try: ... - except Exception: + except: AutoTB() # or AutoTB(out=logfile) where logfile is an open file object """ @@ -1515,12 +1517,12 @@ def text_repr(value): return pydoc.text.repr(value) # type: ignore[call-arg] except KeyboardInterrupt: raise - except Exception: + except: try: return repr(value) except KeyboardInterrupt: raise - except Exception: + except: try: # all still in an except block so we catch # getattr raising @@ -1533,7 +1535,7 @@ def text_repr(value): return '%s instance' % text_repr(klass) except KeyboardInterrupt: raise - except Exception: + except: return 'UNRECOVERABLE REPR FAILURE' diff --git a/IPython/lib/demo.py b/IPython/lib/demo.py index 5067872..ebffd54 100644 --- a/IPython/lib/demo.py +++ b/IPython/lib/demo.py @@ -429,7 +429,7 @@ class Demo(object): def show_all(self): """Show entire demo on screen, block by block""" - self.title + fname = self.title title = self.title nblocks = self.nblocks silent = self._silent diff --git a/IPython/lib/tests/test_display.py b/IPython/lib/tests/test_display.py index 3127bf3..f5ed34c 100644 --- a/IPython/lib/tests/test_display.py +++ b/IPython/lib/tests/test_display.py @@ -56,21 +56,21 @@ def test_warning_on_non_existent_path_FileLink(): def test_existing_path_FileLink(): """FileLink: Calling _repr_html_ functions as expected on existing filepath """ - with NamedTemporaryFile() as tf: - fl = display.FileLink(tf.name) - actual = fl._repr_html_() - expected = "%s
" % (tf.name, tf.name) - assert actual == expected + tf = NamedTemporaryFile() + fl = display.FileLink(tf.name) + actual = fl._repr_html_() + expected = "%s
" % (tf.name, tf.name) + assert actual == expected def test_existing_path_FileLink_repr(): """FileLink: Calling repr() functions as expected on existing filepath """ - with NamedTemporaryFile() as tf: - fl = display.FileLink(tf.name) - actual = repr(fl) - expected = tf.name - assert actual == expected + tf = NamedTemporaryFile() + fl = display.FileLink(tf.name) + actual = repr(fl) + expected = tf.name + assert actual == expected def test_error_on_directory_to_FileLink(): @@ -98,104 +98,98 @@ def test_existing_path_FileLinks(): """FileLinks: Calling _repr_html_ functions as expected on existing dir """ td = mkdtemp() - with NamedTemporaryFile(dir=td) as tf1, NamedTemporaryFile(dir=td) as tf2: - fl = display.FileLinks(td) - actual = fl._repr_html_() - actual = actual.split("\n") - actual.sort() - # the links should always have forward slashes, even on windows, so replace - # backslashes with forward slashes here - expected = [ - "%s/
" % td, - "  %s
" - % (tf2.name.replace("\\", "/"), split(tf2.name)[1]), - "  %s
" - % (tf1.name.replace("\\", "/"), split(tf1.name)[1]), - ] - expected.sort() - # We compare the sorted list of links here as that's more reliable - assert actual == expected + tf1 = NamedTemporaryFile(dir=td) + tf2 = NamedTemporaryFile(dir=td) + fl = display.FileLinks(td) + actual = fl._repr_html_() + actual = actual.split('\n') + actual.sort() + # the links should always have forward slashes, even on windows, so replace + # backslashes with forward slashes here + expected = ["%s/
" % td, + "  %s
" %\ + (tf2.name.replace("\\","/"),split(tf2.name)[1]), + "  %s
" %\ + (tf1.name.replace("\\","/"),split(tf1.name)[1])] + expected.sort() + # We compare the sorted list of links here as that's more reliable + assert actual == expected def test_existing_path_FileLinks_alt_formatter(): """FileLinks: Calling _repr_html_ functions as expected w/ an alt formatter """ td = mkdtemp() - with NamedTemporaryFile(dir=td), NamedTemporaryFile(dir=td): - - def fake_formatter(dirname, fnames, included_suffixes): - return ["hello", "world"] - - fl = display.FileLinks(td, notebook_display_formatter=fake_formatter) - actual = fl._repr_html_() - actual = actual.split("\n") - actual.sort() - expected = ["hello", "world"] - expected.sort() - # We compare the sorted list of links here as that's more reliable - assert actual == expected + tf1 = NamedTemporaryFile(dir=td) + tf2 = NamedTemporaryFile(dir=td) + def fake_formatter(dirname,fnames,included_suffixes): + return ["hello","world"] + fl = display.FileLinks(td,notebook_display_formatter=fake_formatter) + actual = fl._repr_html_() + actual = actual.split('\n') + actual.sort() + expected = ["hello","world"] + expected.sort() + # We compare the sorted list of links here as that's more reliable + assert actual == expected def test_existing_path_FileLinks_repr(): """FileLinks: Calling repr() functions as expected on existing directory """ td = mkdtemp() - with NamedTemporaryFile(dir=td) as tf1, NamedTemporaryFile(dir=td) as tf2: - fl = display.FileLinks(td) - actual = repr(fl) - actual = actual.split("\n") - actual.sort() - expected = [ - "%s/" % td, - " %s" % split(tf1.name)[1], - " %s" % split(tf2.name)[1], - ] - expected.sort() - # We compare the sorted list of links here as that's more reliable - assert actual == expected + tf1 = NamedTemporaryFile(dir=td) + tf2 = NamedTemporaryFile(dir=td) + fl = display.FileLinks(td) + actual = repr(fl) + actual = actual.split('\n') + actual.sort() + expected = ['%s/' % td, ' %s' % split(tf1.name)[1],' %s' % split(tf2.name)[1]] + expected.sort() + # We compare the sorted list of links here as that's more reliable + assert actual == expected def test_existing_path_FileLinks_repr_alt_formatter(): """FileLinks: Calling repr() functions as expected w/ alt formatter """ td = mkdtemp() - with NamedTemporaryFile(dir=td), NamedTemporaryFile(dir=td): - - def fake_formatter(dirname, fnames, included_suffixes): - return ["hello", "world"] - - fl = display.FileLinks(td, terminal_display_formatter=fake_formatter) - actual = repr(fl) - actual = actual.split("\n") - actual.sort() - expected = ["hello", "world"] - expected.sort() - # We compare the sorted list of links here as that's more reliable - assert actual == expected + tf1 = NamedTemporaryFile(dir=td) + tf2 = NamedTemporaryFile(dir=td) + def fake_formatter(dirname,fnames,included_suffixes): + return ["hello","world"] + fl = display.FileLinks(td,terminal_display_formatter=fake_formatter) + actual = repr(fl) + actual = actual.split('\n') + actual.sort() + expected = ["hello","world"] + expected.sort() + # We compare the sorted list of links here as that's more reliable + assert actual == expected def test_error_on_file_to_FileLinks(): """FileLinks: Raises error when passed file """ td = mkdtemp() - with NamedTemporaryFile(dir=td) as tf: - pytest.raises(ValueError, display.FileLinks, tf.name) + tf1 = NamedTemporaryFile(dir=td) + pytest.raises(ValueError, display.FileLinks, tf1.name) def test_recursive_FileLinks(): """FileLinks: Does not recurse when recursive=False """ td = mkdtemp() - with NamedTemporaryFile(dir=td): - subtd = mkdtemp(dir=td) - with NamedTemporaryFile(dir=subtd): - fl = display.FileLinks(td) - actual = str(fl) - actual = actual.split("\n") - assert len(actual) == 4, actual - fl = display.FileLinks(td, recursive=False) - actual = str(fl) - actual = actual.split("\n") - assert len(actual) == 2, actual + tf = NamedTemporaryFile(dir=td) + subtd = mkdtemp(dir=td) + subtf = NamedTemporaryFile(dir=subtd) + fl = display.FileLinks(td) + actual = str(fl) + actual = actual.split('\n') + assert len(actual) == 4, actual + fl = display.FileLinks(td, recursive=False) + actual = str(fl) + actual = actual.split('\n') + assert len(actual) == 2, actual def test_audio_from_file(): path = pjoin(dirname(__file__), 'test.wav') diff --git a/IPython/terminal/ptutils.py b/IPython/terminal/ptutils.py index 4b6b79f..39bc2e1 100644 --- a/IPython/terminal/ptutils.py +++ b/IPython/terminal/ptutils.py @@ -120,7 +120,7 @@ class IPythonPTCompleter(Completer): offset = cursor_to_position(body, cursor_row, cursor_col) try: yield from self._get_completions(body, offset, cursor_position, self.ipy_completer) - except Exception: + except Exception as e: try: exc_type, exc_value, exc_tb = sys.exc_info() traceback.print_exception(exc_type, exc_value, exc_tb) @@ -132,6 +132,7 @@ class IPythonPTCompleter(Completer): """ Private equivalent of get_completions() use only for unit_testing. """ + debug = getattr(ipyc, 'debug', False) completions = _deduplicate_completions( body, ipyc.completions(body, offset)) for c in completions: diff --git a/IPython/terminal/shortcuts/__init__.py b/IPython/terminal/shortcuts/__init__.py index 73229c3..ba6d405 100644 --- a/IPython/terminal/shortcuts/__init__.py +++ b/IPython/terminal/shortcuts/__init__.py @@ -393,7 +393,7 @@ def reformat_text_before_cursor(buffer, document, shell): try: formatted_text = shell.reformat_handler(text) buffer.insert_text(formatted_text) - except Exception: + except Exception as e: buffer.insert_text(text) diff --git a/IPython/testing/decorators.py b/IPython/testing/decorators.py index bd53bae..97e6918 100644 --- a/IPython/testing/decorators.py +++ b/IPython/testing/decorators.py @@ -120,17 +120,19 @@ def onlyif(condition, msg): #----------------------------------------------------------------------------- # Utility functions for decorators -def module_available(module): +def module_not_available(module): """Can module be imported? Returns true if module does NOT import. This is used to make a decorator to skip tests that require module to be available, but delay the 'import numpy' to test execution time. """ try: - import_module(module) - return True + mod = import_module(module) + mod_not_avail = False except ImportError: - return False + mod_not_avail = True + + return mod_not_avail #----------------------------------------------------------------------------- @@ -162,9 +164,7 @@ skip_if_no_x11 = skipif(_x11_skip_cond, _x11_skip_msg) # Other skip decorators # generic skip without module -skip_without = lambda mod: skipif( - not module_available(mod), "This test requires %s" % mod -) +skip_without = lambda mod: skipif(module_not_available(mod), "This test requires %s" % mod) skipif_not_numpy = skip_without('numpy') diff --git a/IPython/tests/cve.py b/IPython/tests/cve.py index 0e73d78..fd1b807 100644 --- a/IPython/tests/cve.py +++ b/IPython/tests/cve.py @@ -30,7 +30,7 @@ def test_cve_2022_21699(): [random.choice(string.ascii_letters) for i in range(10)] ) - with TemporaryWorkingDirectory(): + with TemporaryWorkingDirectory() as t: dangerous_startup_dir.mkdir(parents=True) (dangerous_startup_dir / "foo.py").write_text( f'print("{dangerous_expected}")', encoding="utf-8" diff --git a/IPython/utils/_process_cli.py b/IPython/utils/_process_cli.py index d3b78c8..e303202 100644 --- a/IPython/utils/_process_cli.py +++ b/IPython/utils/_process_cli.py @@ -22,7 +22,7 @@ import os from ._process_common import arg_split -def system(cmd: str): +def system(cmd): """ system(cmd) should work in a cli environment on Mac OSX, Linux, and Windows @@ -33,10 +33,10 @@ def system(cmd: str): psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal psi.UseShellExecute = False # Start up process: - _reg = System.Diagnostics.Process.Start(psi) + reg = System.Diagnostics.Process.Start(psi) -def getoutput(cmd: str): +def getoutput(cmd): """ getoutput(cmd) should work in a cli environment on Mac OSX, Linux, and Windows @@ -51,11 +51,11 @@ def getoutput(cmd: str): myOutput = reg.StandardOutput output = myOutput.ReadToEnd() myError = reg.StandardError - _error = myError.ReadToEnd() + error = myError.ReadToEnd() return output -def check_pid(pid: int): +def check_pid(pid): """ Check if a process with the given PID (pid) exists """ diff --git a/IPython/utils/io.py b/IPython/utils/io.py index 24b1445..a29fed9 100644 --- a/IPython/utils/io.py +++ b/IPython/utils/io.py @@ -8,11 +8,15 @@ IO related utilities. +import atexit +import os import sys import tempfile from pathlib import Path +from warnings import warn -from .capture import capture_output as capture_output +from IPython.utils.decorators import undoc +from .capture import CapturedIO, capture_output class Tee(object): """A class to duplicate an output stream to stdout/err. diff --git a/IPython/utils/tests/test_io.py b/IPython/utils/tests/test_io.py index a1f5255..97a768e 100644 --- a/IPython/utils/tests/test_io.py +++ b/IPython/utils/tests/test_io.py @@ -36,7 +36,7 @@ class TeeTestCase(unittest.TestCase): tee = Tee(chan, channel=channel) print(text, end='', file=chan) - _trap_val = trap.getvalue() + trap_val = trap.getvalue() self.assertEqual(chan.getvalue(), text) tee.close() diff --git a/IPython/utils/tests/test_path.py b/IPython/utils/tests/test_path.py index c7f7817..92794b6 100644 --- a/IPython/utils/tests/test_path.py +++ b/IPython/utils/tests/test_path.py @@ -158,7 +158,7 @@ def test_get_home_dir_4(): if 'HOME' in env: del env['HOME'] # this should still succeed, but we don't care what the answer is - _home = path.get_home_dir(False) + home = path.get_home_dir(False) @skip_win32 @with_environment @@ -254,7 +254,7 @@ def test_filefind(): f = tempfile.NamedTemporaryFile() # print('fname:',f.name) alt_dirs = paths.get_ipython_dir() - _t = path.filefind(f.name, alt_dirs) + t = path.filefind(f.name, alt_dirs) # print('found:',t) diff --git a/IPython/utils/tests/test_tokenutil.py b/IPython/utils/tests/test_tokenutil.py index 1b5c7d2..c4539d1 100644 --- a/IPython/utils/tests/test_tokenutil.py +++ b/IPython/utils/tests/test_tokenutil.py @@ -31,6 +31,7 @@ def test_simple(): def test_function(): cell = "foo(a=5, b='10')" + expected = 'foo' # up to `foo(|a=` for i in range(cell.find('a=') + 1): expect_token("foo", cell, i) diff --git a/docs/sphinxext/github.py b/docs/sphinxext/github.py index 3e14ad5..f56181e 100644 --- a/docs/sphinxext/github.py +++ b/docs/sphinxext/github.py @@ -79,6 +79,7 @@ def ghissue_role(name, rawtext, text, lineno, inliner, options=None, content=Non '"%s" is invalid.' % text, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] + app = inliner.document.settings.env.app #info('issue %r' % text) if 'pull' in name.lower(): category = 'pull' @@ -90,7 +91,6 @@ def ghissue_role(name, rawtext, text, lineno, inliner, options=None, content=Non '"%s" is invalid.' % name, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] - app = inliner.document.settings.env.app node = make_link_node(rawtext, app, category, str(issue_num), options) return [node], [] @@ -112,6 +112,7 @@ def ghuser_role(name, rawtext, text, lineno, inliner, options=None, content=None if options is None: options = {} + app = inliner.document.settings.env.app #info('user link %r' % text) ref = 'https://www.github.com/' + text node = nodes.reference(rawtext, text, refuri=ref, **options) @@ -135,6 +136,7 @@ def ghcommit_role(name, rawtext, text, lineno, inliner, options=None, content=No if options is None: options = {} + app = inliner.document.settings.env.app #info('user link %r' % text) try: base = app.config.github_project_url diff --git a/pyproject.toml b/pyproject.toml index c94ca24..0837a0e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ requires = ["setuptools>=61.2"] # We need access to the 'setupbase' module at build time. # Hence we declare a custom build backend. -build-backend = "_build_meta" # just re-exports setuptools.build_meta definitions +build-backend = "_build_meta" # just re-exports setuptools.build_meta definitions backend-path = ["."] [project] @@ -56,7 +56,9 @@ Source = "https://github.com/ipython/ipython" Tracker = "https://github.com/ipython/ipython/issues" [project.optional-dependencies] -black = ["black"] +black = [ + "black", +] doc = [ "docrepr", "exceptiongroup", @@ -69,14 +71,33 @@ doc = [ "sphinx>=1.3", "sphinxcontrib-jquery", ] -kernel = ["ipykernel"] -nbconvert = ["nbconvert"] -nbformat = ["nbformat"] -notebook = ["ipywidgets", "notebook"] -parallel = ["ipyparallel"] -qtconsole = ["qtconsole"] +kernel = [ + "ipykernel", +] +nbconvert = [ + "nbconvert", +] +nbformat = [ + "nbformat", +] +notebook = [ + "ipywidgets", + "notebook", +] +parallel = [ + "ipyparallel", +] +qtconsole = [ + "qtconsole", +] terminal = [] -test = ["pytest", "pytest-asyncio<0.22", "testpath", "pickleshare", "packaging"] +test = [ + "pytest", + "pytest-asyncio<0.22", + "testpath", + "pickleshare", + "packaging", +] test_extra = [ "ipython[test]", "curio", @@ -86,7 +107,9 @@ test_extra = [ "pandas", "trio", ] -matplotlib = ["matplotlib"] +matplotlib = [ + "matplotlib" +] all = [ "ipython[black,doc,kernel,nbconvert,nbformat,notebook,parallel,qtconsole,matplotlib]", "ipython[test,test_extra]", @@ -97,18 +120,18 @@ python_version = "3.10" ignore_missing_imports = true follow_imports = 'silent' exclude = [ - 'test_\.+\.py', - 'IPython.utils.tests.test_wildcard', - 'testing', - 'tests', - 'PyColorize.py', - '_process_win32_controller.py', - 'IPython/core/application.py', - 'IPython/core/profileapp.py', - 'IPython/lib/deepreload.py', - 'IPython/sphinxext/ipython_directive.py', - 'IPython/terminal/ipapp.py', - 'IPython/utils/path.py', + 'test_\.+\.py', + 'IPython.utils.tests.test_wildcard', + 'testing', + 'tests', + 'PyColorize.py', + '_process_win32_controller.py', + 'IPython/core/application.py', + 'IPython/core/profileapp.py', + 'IPython/lib/deepreload.py', + 'IPython/sphinxext/ipython_directive.py', + 'IPython/terminal/ipapp.py', + 'IPython/utils/path.py', ] # check_untyped_defs = true # disallow_untyped_calls = true @@ -120,7 +143,9 @@ disallow_untyped_defs = true warn_redundant_casts = true [[tool.mypy.overrides]] -module = ["IPython.core.crashhandler"] +module = [ + "IPython.core.crashhandler", +] check_untyped_defs = true disallow_incomplete_defs = true disallow_untyped_calls = true @@ -130,13 +155,16 @@ ignore_errors = false ignore_missing_imports = false [[tool.mypy.overrides]] -module = ["IPython.utils.text"] +module = [ + "IPython.utils.text", +] disallow_untyped_defs = true check_untyped_defs = false disallow_untyped_decorators = true [[tool.mypy.overrides]] -module = [] +module = [ +] disallow_untyped_defs = false ignore_errors = true ignore_missing_imports = true @@ -283,46 +311,52 @@ disallow_untyped_decorators = false [tool.pytest.ini_options] addopts = [ - "--durations=10", - "-pIPython.testing.plugin.pytest_ipdoctest", - "--ipdoctest-modules", - "--ignore=docs", - "--ignore=examples", - "--ignore=htmlcov", - "--ignore=ipython_kernel", - "--ignore=ipython_parallel", - "--ignore=results", - "--ignore=tmp", - "--ignore=tools", - "--ignore=traitlets", - "--ignore=IPython/core/tests/daft_extension", - "--ignore=IPython/sphinxext", - "--ignore=IPython/terminal/pt_inputhooks", - "--ignore=IPython/__main__.py", - "--ignore=IPython/external/qt_for_kernel.py", - "--ignore=IPython/html/widgets/widget_link.py", - "--ignore=IPython/html/widgets/widget_output.py", - "--ignore=IPython/terminal/console.py", - "--ignore=IPython/utils/_process_cli.py", - "--ignore=IPython/utils/_process_posix.py", - "--ignore=IPython/utils/_process_win32_controller.py", - "--ignore=IPython/utils/daemonize.py", - "--ignore=IPython/utils/eventful.py", - "--ignore=IPython/kernel", - "--ignore=IPython/consoleapp.py", - "--ignore=IPython/lib/kernel.py", - "--ignore=IPython/utils/jsonutil.py", - "--ignore=IPython/utils/localinterfaces.py", - "--ignore=IPython/utils/log.py", - "--ignore=IPython/utils/signatures.py", - "--ignore=IPython/utils/version.py", + "--durations=10", + "-pIPython.testing.plugin.pytest_ipdoctest", + "--ipdoctest-modules", + "--ignore=docs", + "--ignore=examples", + "--ignore=htmlcov", + "--ignore=ipython_kernel", + "--ignore=ipython_parallel", + "--ignore=results", + "--ignore=tmp", + "--ignore=tools", + "--ignore=traitlets", + "--ignore=IPython/core/tests/daft_extension", + "--ignore=IPython/sphinxext", + "--ignore=IPython/terminal/pt_inputhooks", + "--ignore=IPython/__main__.py", + "--ignore=IPython/external/qt_for_kernel.py", + "--ignore=IPython/html/widgets/widget_link.py", + "--ignore=IPython/html/widgets/widget_output.py", + "--ignore=IPython/terminal/console.py", + "--ignore=IPython/utils/_process_cli.py", + "--ignore=IPython/utils/_process_posix.py", + "--ignore=IPython/utils/_process_win32_controller.py", + "--ignore=IPython/utils/daemonize.py", + "--ignore=IPython/utils/eventful.py", + "--ignore=IPython/kernel", + "--ignore=IPython/consoleapp.py", + "--ignore=IPython/lib/kernel.py", + "--ignore=IPython/utils/jsonutil.py", + "--ignore=IPython/utils/localinterfaces.py", + "--ignore=IPython/utils/log.py", + "--ignore=IPython/utils/signatures.py", + "--ignore=IPython/utils/version.py" +] +doctest_optionflags = [ + "NORMALIZE_WHITESPACE", + "ELLIPSIS" +] +ipdoctest_optionflags = [ + "NORMALIZE_WHITESPACE", + "ELLIPSIS" ] -doctest_optionflags = ["NORMALIZE_WHITESPACE", "ELLIPSIS"] -ipdoctest_optionflags = ["NORMALIZE_WHITESPACE", "ELLIPSIS"] asyncio_mode = "strict" [tool.pyright] -pythonPlatform = "All" +pythonPlatform="All" [tool.setuptools] zip-safe = false @@ -342,51 +376,10 @@ namespaces = false "IPython.testing.plugin" = ["*.txt"] [tool.setuptools.dynamic] -version = { attr = "IPython.core.release.__version__" } +version = {attr = "IPython.core.release.__version__"} [tool.coverage.run] omit = [ # omit everything in /tmp as we run tempfile "/tmp/*", -] - -[tool.ruff.lint] -extend-select = [ - # "B", # flake8-bugbear - # "I", # isort - # 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 - # "ARG", # flake8-unused-arguments - # "C4", # flake8-comprehensions - # "EM", # flake8-errmsg - # "ICN", # flake8-import-conventions - # "G", # flake8-logging-format - # "PGH", # pygrep-hooks - # "PIE", # flake8-pie - # "PL", # pylint - # "PTH", # flake8-use-pathlib - # "PT", # flake8-pytest-style - # "RET", # flake8-return - # "RUF", # Ruff-specific - # "SIM", # flake8-simplify - # "T20", # flake8-print - # "UP", # pyupgrade - # "YTT", # flake8-2020 - # "EXE", # flake8-executable - # "PYI", # flake8-pyi - # "S", # flake8-bandit -] -ignore = [ - # "E501", # E501 Line too long (158 > 100 characters) - # "SIM105", # SIM105 Use `contextlib.suppress(...)` - # "PLR", # Design related pylint codes - # "S101", # Use of `assert` detected -] -unfixable = [ - # Don't touch print statements - "T201", - # Don't touch noqa lines - "RUF100", -] - -[tool.ruff] -extend-exclude = ["tests"] + ]