Skip to content

Commit b78775e

Browse files
committed
Intermediate changes
commit_hash:293c725da86af9df83cab900e86bf2b75cc6b4e8
1 parent 784038d commit b78775e

File tree

9 files changed

+365
-33
lines changed

9 files changed

+365
-33
lines changed

contrib/python/ipython/py3/.dist-info/METADATA

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
Metadata-Version: 2.1
1+
Metadata-Version: 2.2
22
Name: ipython
3-
Version: 8.31.0
3+
Version: 8.32.0
44
Summary: IPython: Productive Interactive Computing
55
Author: The IPython Development Team
66
Author-email: ipython-dev@python.org
@@ -85,6 +85,9 @@ Requires-Dist: matplotlib; extra == "matplotlib"
8585
Provides-Extra: all
8686
Requires-Dist: ipython[black,doc,kernel,matplotlib,nbconvert,nbformat,notebook,parallel,qtconsole]; extra == "all"
8787
Requires-Dist: ipython[test,test_extra]; extra == "all"
88+
Dynamic: author
89+
Dynamic: author-email
90+
Dynamic: license
8891

8992
IPython provides a rich toolkit to help you make the most out of using Python
9093
interactively. Its main components are:

contrib/python/ipython/py3/IPython/core/interactiveshell.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,7 @@ def init_virtualenv(self):
900900
return
901901

902902
p = Path(sys.executable)
903-
p_venv = Path(os.environ["VIRTUAL_ENV"])
903+
p_venv = Path(os.environ["VIRTUAL_ENV"]).resolve()
904904

905905
# fallback venv detection:
906906
# stdlib venv may symlink sys.executable, so we can't use realpath.
@@ -913,7 +913,7 @@ def init_virtualenv(self):
913913
drive_name = p_venv.parts[2]
914914
p_venv = (drive_name + ":/") / Path(*p_venv.parts[3:])
915915

916-
if any(p_venv == p.parents[1] for p in paths):
916+
if any(p_venv == p.parents[1].resolve() for p in paths):
917917
# Our exe is inside or has access to the virtualenv, don't need to do anything.
918918
return
919919

@@ -2093,6 +2093,8 @@ def _get_exc_info(self, exc_tuple=None):
20932093
sys.last_type = etype
20942094
sys.last_value = value
20952095
sys.last_traceback = tb
2096+
if sys.version_info >= (3, 12):
2097+
sys.last_exc = value
20962098

20972099
return etype, value, tb
20982100

contrib/python/ipython/py3/IPython/core/magics/execution.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,21 @@ def _run_with_debugger(
977977
break
978978
finally:
979979
sys.settrace(trace)
980-
980+
981+
# Perform proper cleanup of the session in case if
982+
# it exited with "continue" and not "quit" command
983+
if hasattr(deb, "rcLines"):
984+
# Run this code defensively in case if custom debugger
985+
# class does not implement rcLines, which although public
986+
# is an implementation detail of `pdb.Pdb` and not part of
987+
# the more generic basic debugger framework (`bdb.Bdb`).
988+
deb.set_quit()
989+
deb.rcLines.extend(["q"])
990+
try:
991+
deb.run("", code_ns, local_ns)
992+
except StopIteration:
993+
# Stop iteration is raised on quit command
994+
pass
981995

982996
except:
983997
etype, value, tb = sys.exc_info()

contrib/python/ipython/py3/IPython/core/magics/script.py

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ def script_args(f):
6767
return f
6868

6969

70+
class RaiseAfterInterrupt(Exception):
71+
pass
72+
73+
7074
@magics_class
7175
class ScriptMagics(Magics):
7276
"""Magics for talking to scripts
@@ -176,6 +180,10 @@ def shebang(self, line, cell):
176180
177181
The rest of the cell is run by that program.
178182
183+
.. versionchanged:: 9.0
184+
Interrupting the script executed without `--bg` will end in
185+
raising an exception (unless `--no-raise-error` is passed).
186+
179187
Examples
180188
--------
181189
::
@@ -212,7 +220,7 @@ def in_thread(coro):
212220

213221
async def _readchunk(stream):
214222
try:
215-
return await stream.readuntil(b"\n")
223+
return await stream.read(100)
216224
except asyncio.exceptions.IncompleteReadError as e:
217225
return e.partial
218226
except asyncio.exceptions.LimitOverrunError as e:
@@ -292,20 +300,33 @@ async def _stream_communicate(process, cell):
292300
p.send_signal(signal.SIGINT)
293301
in_thread(asyncio.wait_for(p.wait(), timeout=0.1))
294302
if p.returncode is not None:
295-
print("Process is interrupted.")
296-
return
303+
print("Process was interrupted.")
304+
if args.raise_error:
305+
raise RaiseAfterInterrupt()
306+
else:
307+
return
297308
p.terminate()
298309
in_thread(asyncio.wait_for(p.wait(), timeout=0.1))
299310
if p.returncode is not None:
300-
print("Process is terminated.")
301-
return
311+
print("Process was terminated.")
312+
if args.raise_error:
313+
raise RaiseAfterInterrupt()
314+
else:
315+
return
302316
p.kill()
303-
print("Process is killed.")
317+
print("Process was killed.")
318+
if args.raise_error:
319+
raise RaiseAfterInterrupt()
320+
except RaiseAfterInterrupt:
321+
pass
304322
except OSError:
305323
pass
306324
except Exception as e:
307325
print("Error while terminating subprocess (pid=%i): %s" % (p.pid, e))
308-
return
326+
if args.raise_error:
327+
raise CalledProcessError(p.returncode, cell) from None
328+
else:
329+
return
309330

310331
if args.raise_error and p.returncode != 0:
311332
# If we get here and p.returncode is still None, we must have

contrib/python/ipython/py3/IPython/core/release.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# release. 'dev' as a _version_extra string means this is a development
1717
# version
1818
_version_major = 8
19-
_version_minor = 31
19+
_version_minor = 32
2020
_version_patch = 0
2121
_version_extra = ".dev"
2222
# _version_extra = "rc1"

contrib/python/ipython/py3/IPython/terminal/interactiveshell.py

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@
2626
Any,
2727
validate,
2828
Float,
29+
DottedObjectName,
2930
)
31+
from traitlets.utils.importstring import import_item
32+
3033

3134
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
3235
from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode
@@ -214,7 +217,9 @@ class TerminalInteractiveShell(InteractiveShell):
214217

215218
pt_app: UnionType[PromptSession, None] = None
216219
auto_suggest: UnionType[
217-
AutoSuggestFromHistory, NavigableAutoSuggestFromHistory, None
220+
AutoSuggestFromHistory,
221+
NavigableAutoSuggestFromHistory,
222+
None,
218223
] = None
219224
debugger_history = None
220225

@@ -421,6 +426,37 @@ def _displayhook_class_default(self):
421426
allow_none=True,
422427
).tag(config=True)
423428

429+
llm_provider_class = DottedObjectName(
430+
None,
431+
allow_none=True,
432+
help="""\
433+
Provisional:
434+
This is a provisinal API in IPython 8.32, before stabilisation
435+
in 9.0, it may change without warnings.
436+
437+
class to use for the `NavigableAutoSuggestFromHistory` to request
438+
completions from a LLM, this should inherit from
439+
`jupyter_ai_magics:BaseProvider` and implement
440+
`stream_inline_completions`
441+
""",
442+
).tag(config=True)
443+
444+
@observe("llm_provider_class")
445+
def _llm_provider_class_changed(self, change):
446+
provider_class = change.new
447+
if provider_class is not None:
448+
warn(
449+
"TerminalInteractiveShell.llm_provider_class is a provisional"
450+
" API as of IPython 8.32, and may change without warnings."
451+
)
452+
if isinstance(self.auto_suggest, NavigableAutoSuggestFromHistory):
453+
self.auto_suggest._llm_provider = provider_class()
454+
else:
455+
self.log.warn(
456+
"llm_provider_class only has effects when using"
457+
"`NavigableAutoSuggestFromHistory` as auto_suggest."
458+
)
459+
424460
def _set_autosuggestions(self, provider):
425461
# disconnect old handler
426462
if self.auto_suggest and isinstance(
@@ -432,7 +468,15 @@ def _set_autosuggestions(self, provider):
432468
elif provider == "AutoSuggestFromHistory":
433469
self.auto_suggest = AutoSuggestFromHistory()
434470
elif provider == "NavigableAutoSuggestFromHistory":
471+
# LLM stuff are all Provisional in 8.32
472+
if self.llm_provider_class:
473+
llm_provider_constructor = import_item(self.llm_provider_class)
474+
llm_provider = llm_provider_constructor()
475+
else:
476+
llm_provider = None
435477
self.auto_suggest = NavigableAutoSuggestFromHistory()
478+
# Provisinal in 8.32
479+
self.auto_suggest._llm_provider = llm_provider
436480
else:
437481
raise ValueError("No valid provider.")
438482
if self.pt_app:
@@ -815,7 +859,8 @@ def get_message():
815859
& ~IsDone()
816860
& Condition(
817861
lambda: isinstance(
818-
self.auto_suggest, NavigableAutoSuggestFromHistory
862+
self.auto_suggest,
863+
NavigableAutoSuggestFromHistory,
819864
)
820865
),
821866
),

0 commit comments

Comments
 (0)