diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml
index 2778805..aceca00 100644
--- a/.github/workflows/mypy.yml
+++ b/.github/workflows/mypy.yml
@@ -2,9 +2,9 @@ name: Run MyPy
on:
push:
- branches: [ master ]
+ branches: [ master, 7.x]
pull_request:
- branches: [ master ]
+ branches: [ master, 7.x]
jobs:
build:
diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml
index 80497bb..db57170 100644
--- a/.github/workflows/python-package.yml
+++ b/.github/workflows/python-package.yml
@@ -5,9 +5,9 @@ name: Python package
on:
push:
- branches: [ master ]
+ branches: [ master, 7.x ]
pull_request:
- branches: [ master ]
+ branches: [ master, 7.x ]
jobs:
build:
diff --git a/.travis.yml b/.travis.yml
index 3702df2..db02c50 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -37,7 +37,7 @@ install:
- pip install -e file://$PWD#egg=ipython[test] --upgrade
- pip install trio curio --upgrade --upgrade-strategy eager
- pip install 'pytest' 'matplotlib !=3.2.0'
- - pip install codecov check-manifest pytest-cov --upgrade anyio pytest-asyncio
+ - pip install codecov check-manifest pytest-cov --upgrade anyio pytest-trio
script:
diff --git a/IPython/core/compilerop.py b/IPython/core/compilerop.py
index c4771af..50672a1 100644
--- a/IPython/core/compilerop.py
+++ b/IPython/core/compilerop.py
@@ -99,7 +99,7 @@ class CachingCompiler(codeop.Compile):
Arguments are exactly the same as ast.parse (in the standard library),
and are passed to the built-in compile function."""
return compile(source, filename, symbol, self.flags | PyCF_ONLY_AST, 1)
-
+
def reset_compiler_flags(self):
"""Reset compiler flags to default state."""
# This value is copied from codeop.Compile.__init__, so if that ever
@@ -112,25 +112,53 @@ class CachingCompiler(codeop.Compile):
"""
return self.flags
- def cache(self, code, number=0):
+ def get_code_name(self, raw_code, transformed_code, number):
+ """Compute filename given the code, and the cell number.
+
+ Parameters
+ ----------
+ raw_code : str
+ The raw cell code.
+ transformed_code : str
+ The executable Python source code to cache and compile.
+ number : int
+ A number which forms part of the code's name. Used for the execution
+ counter.
+
+ Returns
+ -------
+ The computed filename.
+ """
+ return code_name(transformed_code, number)
+
+ def cache(self, transformed_code, number=0, raw_code=None):
"""Make a name for a block of code, and cache the code.
Parameters
----------
- code : str
- The Python source code to cache.
+ transformed_code : str
+ The executable Python source code to cache and compile.
number : int
A number which forms part of the code's name. Used for the execution
counter.
+ raw_code : str
+ The raw code before transformation, if None, set to `transformed_code`.
Returns
-------
The name of the cached code (as a string). Pass this as the filename
argument to compilation, so that tracebacks are correctly hooked up.
"""
- name = code_name(code, number)
- entry = (len(code), time.time(),
- [line+'\n' for line in code.splitlines()], name)
+ if raw_code is None:
+ raw_code = transformed_code
+
+ name = self.get_code_name(raw_code, transformed_code, number)
+ entry = (
+ len(transformed_code),
+ time.time(),
+ [line + "\n" for line in transformed_code.splitlines()],
+ name,
+ )
linecache.cache[name] = entry
linecache._ipython_cache[name] = entry
return name
@@ -146,7 +174,7 @@ class CachingCompiler(codeop.Compile):
yield
finally:
# turn off only the bits we turned on so that something like
- # __future__ that set flags stays.
+ # __future__ that set flags stays.
self.flags &= ~turn_on_bits
diff --git a/IPython/core/completer.py b/IPython/core/completer.py
index 0100bfc..78bc57e 100644
--- a/IPython/core/completer.py
+++ b/IPython/core/completer.py
@@ -201,7 +201,9 @@ def provisionalcompleter(action='ignore'):
>>> completer.do_experimental_things() # raises.
- .. note:: Unstable
+ .. note::
+
+ Unstable
By using this context manager you agree that the API in use may change
without warning, and that you won't complain if they do so.
@@ -356,7 +358,9 @@ class Completion:
"""
Completion object used and return by IPython completers.
- .. warning:: Unstable
+ .. warning::
+
+ Unstable
This function is unstable, API may change without warning.
It will also raise unless use in proper context manager.
@@ -419,7 +423,9 @@ def _deduplicate_completions(text: str, completions: _IC)-> _IC:
"""
Deduplicate a set of completions.
- .. warning:: Unstable
+ .. warning::
+
+ Unstable
This function is unstable, API may change without warning.
@@ -459,7 +465,9 @@ def rectify_completions(text: str, completions: _IC, *, _debug=False)->_IC:
"""
Rectify a set of completions to all have the same ``start`` and ``end``
- .. warning:: Unstable
+ .. warning::
+
+ Unstable
This function is unstable, API may change without warning.
It will also raise unless use in proper context manager.
@@ -1837,7 +1845,9 @@ class IPCompleter(Completer):
"""
Returns an iterator over the possible completions
- .. warning:: Unstable
+ .. warning::
+
+ Unstable
This function is unstable, API may change without warning.
It will also raise unless use in proper context manager.
diff --git a/IPython/core/crashhandler.py b/IPython/core/crashhandler.py
index 1e0b429..2cfe85c 100644
--- a/IPython/core/crashhandler.py
+++ b/IPython/core/crashhandler.py
@@ -23,6 +23,7 @@ import os
import sys
import traceback
from pprint import pformat
+from pathlib import Path
from IPython.core import ultratb
from IPython.core.release import author_email
@@ -151,10 +152,10 @@ class CrashHandler(object):
try:
rptdir = self.app.ipython_dir
except:
- rptdir = os.getcwd()
- if rptdir is None or not os.path.isdir(rptdir):
- rptdir = os.getcwd()
- report_name = os.path.join(rptdir,self.crash_report_fname)
+ rptdir = Path.cwd()
+ if rptdir is None or not Path.is_dir(rptdir):
+ rptdir = Path.cwd()
+ report_name = rptdir / self.crash_report_fname
# write the report filename into the instance dict so it can get
# properly expanded out in the user message template
self.crash_report_fname = report_name
diff --git a/IPython/core/debugger.py b/IPython/core/debugger.py
index dde8492..b0e62ca 100644
--- a/IPython/core/debugger.py
+++ b/IPython/core/debugger.py
@@ -43,13 +43,14 @@ from IPython.testing.skipdoctest import skip_doctest
prompt = 'ipdb> '
-#We have to check this directly from sys.argv, config struct not yet available
+# We have to check this directly from sys.argv, config struct not yet available
from pdb import Pdb as OldPdb
# Allow the set_trace code to operate outside of an ipython instance, even if
# it does so with some limitations. The rest of this support is implemented in
# the Tracer constructor.
+
def make_arrow(pad):
"""generate the leading arrow in front of traceback or debugger"""
if pad >= 2:
@@ -67,16 +68,16 @@ def BdbQuit_excepthook(et, ev, tb, excepthook=None):
"""
warnings.warn("`BdbQuit_excepthook` is deprecated since version 5.1",
DeprecationWarning, stacklevel=2)
- if et==bdb.BdbQuit:
+ if et == bdb.BdbQuit:
print('Exiting Debugger.')
elif excepthook is not None:
excepthook(et, ev, tb)
else:
# Backwards compatibility. Raise deprecation warning?
- BdbQuit_excepthook.excepthook_ori(et,ev,tb)
+ BdbQuit_excepthook.excepthook_ori(et, ev, tb)
-def BdbQuit_IPython_excepthook(self,et,ev,tb,tb_offset=None):
+def BdbQuit_IPython_excepthook(self, et, ev, tb, tb_offset=None):
warnings.warn(
"`BdbQuit_IPython_excepthook` is deprecated since version 5.1",
DeprecationWarning, stacklevel=2)
@@ -203,7 +204,7 @@ class Pdb(OldPdb):
def __init__(self, color_scheme=None, completekey=None,
stdin=None, stdout=None, context=5, **kwargs):
"""Create a new IPython debugger.
-
+
:param color_scheme: Deprecated, do not use.
:param completekey: Passed to pdb.Pdb.
:param stdin: Passed to pdb.Pdb.
@@ -237,7 +238,7 @@ class Pdb(OldPdb):
self.shell = TerminalInteractiveShell.instance()
# needed by any code which calls __import__("__main__") after
# the debugger was entered. See also #9941.
- sys.modules['__main__'] = save_main
+ sys.modules["__main__"] = save_main
if color_scheme is not None:
warnings.warn(
@@ -272,7 +273,6 @@ class Pdb(OldPdb):
cst['Neutral'].colors.breakpoint_enabled = C.LightRed
cst['Neutral'].colors.breakpoint_disabled = C.Red
-
# Add a python parser so we can syntax highlight source while
# debugging.
self.parser = PyColorize.Parser(style=color_scheme)
@@ -320,13 +320,25 @@ class Pdb(OldPdb):
except KeyboardInterrupt:
self.stdout.write("\n" + self.shell.get_exception_only())
+ def precmd(self, line):
+ """Perform useful escapes on the command before it is executed."""
+
+ if line.endswith("??"):
+ line = "pinfo2 " + line[:-2]
+ elif line.endswith("?"):
+ line = "pinfo " + line[:-1]
+
+ line = super().precmd(line)
+
+ return line
+
def new_do_frame(self, arg):
OldPdb.do_frame(self, arg)
def new_do_quit(self, arg):
if hasattr(self, 'old_all_completions'):
- self.shell.Completer.all_completions=self.old_all_completions
+ self.shell.Completer.all_completions = self.old_all_completions
return OldPdb.do_quit(self, arg)
@@ -344,7 +356,7 @@ class Pdb(OldPdb):
if context is None:
context = self.context
try:
- context=int(context)
+ context = int(context)
if context <= 0:
raise ValueError("Context must be a positive integer")
except (TypeError, ValueError) as e:
@@ -373,7 +385,7 @@ class Pdb(OldPdb):
if context is None:
context = self.context
try:
- context=int(context)
+ context = int(context)
if context <= 0:
raise ValueError("Context must be a positive integer")
except (TypeError, ValueError) as e:
@@ -390,7 +402,7 @@ class Pdb(OldPdb):
if context is None:
context = self.context
try:
- context=int(context)
+ context = int(context)
if context <= 0:
print("Context must be a positive integer", file=self.stdout)
except (TypeError, ValueError):
@@ -402,11 +414,10 @@ class Pdb(OldPdb):
Colors = self.color_scheme_table.active_colors
ColorsNormal = Colors.Normal
- tpl_link = u'%s%%s%s' % (Colors.filenameEm, ColorsNormal)
- tpl_call = u'%s%%s%s%%s%s' % (Colors.vName, Colors.valEm, ColorsNormal)
- tpl_line = u'%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
- tpl_line_em = u'%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line,
- ColorsNormal)
+ tpl_link = "%s%%s%s" % (Colors.filenameEm, ColorsNormal)
+ tpl_call = "%s%%s%s%%s%s" % (Colors.vName, Colors.valEm, ColorsNormal)
+ tpl_line = "%%s%s%%s %s%%s" % (Colors.lineno, ColorsNormal)
+ tpl_line_em = "%%s%s%%s %s%%s%s" % (Colors.linenoEm, Colors.line, ColorsNormal)
frame, lineno = frame_lineno
@@ -439,8 +450,8 @@ class Pdb(OldPdb):
if frame is self.curframe:
ret.append('> ')
else:
- ret.append(' ')
- ret.append(u'%s(%s)%s\n' % (link,lineno,call))
+ ret.append(" ")
+ ret.append("%s(%s)%s\n" % (link, lineno, call))
start = lineno - 1 - context//2
lines = linecache.getlines(filename)
@@ -448,17 +459,17 @@ class Pdb(OldPdb):
start = max(start, 0)
lines = lines[start : start + context]
- for i,line in enumerate(lines):
- show_arrow = (start + 1 + i == lineno)
- linetpl = (frame is self.curframe or show_arrow) \
- and tpl_line_em \
- or tpl_line
- ret.append(self.__format_line(linetpl, filename,
- start + 1 + i, line,
- arrow = show_arrow) )
- return ''.join(ret)
-
- def __format_line(self, tpl_line, filename, lineno, line, arrow = False):
+ for i, line in enumerate(lines):
+ show_arrow = start + 1 + i == lineno
+ linetpl = (frame is self.curframe or show_arrow) and tpl_line_em or tpl_line
+ ret.append(
+ self.__format_line(
+ linetpl, filename, start + 1 + i, line, arrow=show_arrow
+ )
+ )
+ return "".join(ret)
+
+ def __format_line(self, tpl_line, filename, lineno, line, arrow=False):
bp_mark = ""
bp_mark_color = ""
@@ -488,7 +499,6 @@ class Pdb(OldPdb):
return tpl_line % (bp_mark_color + bp_mark, num, line)
-
def print_list_lines(self, filename, first, last):
"""The printing (as opposed to the parsing part of a 'list'
command."""
@@ -507,9 +517,13 @@ class Pdb(OldPdb):
break
if lineno == self.curframe.f_lineno:
- line = self.__format_line(tpl_line_em, filename, lineno, line, arrow = True)
+ line = self.__format_line(
+ tpl_line_em, filename, lineno, line, arrow=True
+ )
else:
- line = self.__format_line(tpl_line, filename, lineno, line, arrow = False)
+ line = self.__format_line(
+ tpl_line, filename, lineno, line, arrow=False
+ )
src.append(line)
self.lineno = lineno
@@ -706,7 +720,7 @@ class Pdb(OldPdb):
Will skip hidden frames.
"""
- ## modified version of upstream that skips
+ # modified version of upstream that skips
# frames with __tracebackide__
if self.curindex == 0:
self.error("Oldest frame")
@@ -720,11 +734,9 @@ class Pdb(OldPdb):
if count < 0:
_newframe = 0
else:
- _newindex = self.curindex
counter = 0
hidden_frames = self.hidden_frames(self.stack)
for i in range(self.curindex - 1, -1, -1):
- frame = self.stack[i][0]
if hidden_frames[i] and self.skip_hidden:
skipped += 1
continue
@@ -765,12 +777,10 @@ class Pdb(OldPdb):
if count < 0:
_newframe = len(self.stack) - 1
else:
- _newindex = self.curindex
counter = 0
skipped = 0
hidden_frames = self.hidden_frames(self.stack)
for i in range(self.curindex + 1, len(self.stack)):
- frame = self.stack[i][0]
if hidden_frames[i] and self.skip_hidden:
skipped += 1
continue
@@ -796,6 +806,20 @@ class Pdb(OldPdb):
do_d = do_down
do_u = do_up
+ def do_context(self, context):
+ """context number_of_lines
+ Set the number of lines of source code to show when displaying
+ stacktrace information.
+ """
+ try:
+ new_context = int(context)
+ if new_context <= 0:
+ raise ValueError()
+ self.context = new_context
+ except ValueError:
+ self.error("The 'context' command requires a positive integer argument.")
+
+
class InterruptiblePdb(Pdb):
"""Version of debugger where KeyboardInterrupt exits the debugger altogether."""
diff --git a/IPython/core/display.py b/IPython/core/display.py
index 2920b84..bd098e7 100644
--- a/IPython/core/display.py
+++ b/IPython/core/display.py
@@ -567,7 +567,7 @@ class JSON(DisplayObject):
Path to a local file to load the data from.
expanded : boolean
Metadata to control whether a JSON display component is expanded.
- metadata: dict
+ metadata : dict
Specify extra metadata to attach to the json display object.
root : str
The name of the root element of the JSON tree
@@ -651,12 +651,11 @@ class GeoJSON(JSON):
A URL to download the data from.
filename : unicode
Path to a local file to load the data from.
- metadata: dict
+ metadata : dict
Specify extra metadata to attach to the json display object.
Examples
--------
-
The following will display an interactive map of Mars with a point of
interest on frontend that do support GeoJSON display.
@@ -723,7 +722,7 @@ class Javascript(TextDisplayObject):
running the source code. The full URLs of the libraries should
be given. A single Javascript library URL can also be given as a
string.
- css: : list or str
+ css : list or str
A sequence of css files to load before running the source code.
The full URLs of the css files should be given. A single css URL
can also be given as a string.
@@ -844,25 +843,33 @@ class Image(DisplayObject):
from image data.
For non-embedded images, you can just set the desired display width
and height directly.
- unconfined: bool
+ unconfined : bool
Set unconfined=True to disable max-width confinement of the image.
- metadata: dict
+ metadata : dict
Specify extra metadata to attach to the image.
Examples
--------
- # embedded image data, works in qtconsole and notebook
- # when passed positionally, the first arg can be any of raw image data,
- # a URL, or a filename from which to load image data.
- # The result is always embedding image data for inline images.
- Image('http://www.google.fr/images/srpr/logo3w.png')
- Image('/path/to/image.jpg')
- Image(b'RAW_PNG_DATA...')
-
- # Specifying Image(url=...) does not embed the image data,
- # it only generates `` tag with a link to the source.
- # This will not work in the qtconsole or offline.
- Image(url='http://www.google.fr/images/srpr/logo3w.png')
+ embedded image data, works in qtconsole and notebook
+ when passed positionally, the first arg can be any of raw image data,
+ a URL, or a filename from which to load image data.
+ The result is always embedding image data for inline images.
+
+ >>> Image('http://www.google.fr/images/srpr/logo3w.png')
+
+
+ >>> Image('/path/to/image.jpg')
+
+
+ >>> Image(b'RAW_PNG_DATA...')
+
+
+ Specifying Image(url=...) does not embed the image data,
+ it only generates ```` tag with a link to the source.
+ This will not work in the qtconsole or offline.
+
+ >>> Image(url='http://www.google.fr/images/srpr/logo3w.png')
+
"""
if isinstance(data, (Path, PurePath)):
@@ -1036,25 +1043,24 @@ class Video(DisplayObject):
----------
data : unicode, str or bytes
The raw video data or a URL or filename to load the data from.
- Raw data will require passing `embed=True`.
+ Raw data will require passing ``embed=True``.
url : unicode
- A URL for the video. If you specify `url=`,
+ A URL for the video. If you specify ``url=``,
the image data will not be embedded.
filename : unicode
Path to a local file containing the video.
- Will be interpreted as a local URL unless `embed=True`.
+ Will be interpreted as a local URL unless ``embed=True``.
embed : bool
Should the video be embedded using a data URI (True) or be
loaded using a