ipython 8.31.0__tar.gz → 8.32.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (498) hide show
  1. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/interactiveshell.py +4 -2
  2. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/magics/execution.py +15 -1
  3. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/magics/script.py +28 -7
  4. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/release.py +1 -1
  5. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_magic.py +67 -0
  6. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/interactiveshell.py +47 -2
  7. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/shortcuts/auto_suggest.py +263 -16
  8. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/_sysinfo.py +1 -1
  9. {ipython-8.31.0/ipython.egg-info → ipython-8.32.0}/PKG-INFO +5 -2
  10. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/version8.rst +51 -1
  11. ipython-8.32.0/examples/auto_suggest_llm.py +130 -0
  12. {ipython-8.31.0 → ipython-8.32.0/ipython.egg-info}/PKG-INFO +5 -2
  13. {ipython-8.31.0 → ipython-8.32.0}/ipython.egg-info/SOURCES.txt +1 -0
  14. {ipython-8.31.0 → ipython-8.32.0}/.flake8 +0 -0
  15. {ipython-8.31.0 → ipython-8.32.0}/.mailmap +0 -0
  16. {ipython-8.31.0 → ipython-8.32.0}/.pre-commit-config.yaml +0 -0
  17. {ipython-8.31.0 → ipython-8.32.0}/COPYING.rst +0 -0
  18. {ipython-8.31.0 → ipython-8.32.0}/IPython/__init__.py +0 -0
  19. {ipython-8.31.0 → ipython-8.32.0}/IPython/__main__.py +0 -0
  20. {ipython-8.31.0 → ipython-8.32.0}/IPython/conftest.py +0 -0
  21. {ipython-8.31.0 → ipython-8.32.0}/IPython/consoleapp.py +0 -0
  22. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/__init__.py +0 -0
  23. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/alias.py +0 -0
  24. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/application.py +0 -0
  25. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/async_helpers.py +0 -0
  26. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/autocall.py +0 -0
  27. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/builtin_trap.py +0 -0
  28. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/compilerop.py +0 -0
  29. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/completer.py +0 -0
  30. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/completerlib.py +0 -0
  31. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/crashhandler.py +0 -0
  32. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/debugger.py +0 -0
  33. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/display.py +0 -0
  34. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/display_functions.py +0 -0
  35. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/display_trap.py +0 -0
  36. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/displayhook.py +0 -0
  37. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/displaypub.py +0 -0
  38. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/error.py +0 -0
  39. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/events.py +0 -0
  40. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/excolors.py +0 -0
  41. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/extensions.py +0 -0
  42. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/formatters.py +0 -0
  43. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/getipython.py +0 -0
  44. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/guarded_eval.py +0 -0
  45. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/history.py +0 -0
  46. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/historyapp.py +0 -0
  47. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/hooks.py +0 -0
  48. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/inputsplitter.py +0 -0
  49. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/inputtransformer.py +0 -0
  50. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/inputtransformer2.py +0 -0
  51. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/latex_symbols.py +0 -0
  52. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/logger.py +0 -0
  53. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/macro.py +0 -0
  54. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/magic.py +0 -0
  55. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/magic_arguments.py +0 -0
  56. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/magics/__init__.py +0 -0
  57. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/magics/ast_mod.py +0 -0
  58. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/magics/auto.py +0 -0
  59. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/magics/basic.py +0 -0
  60. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/magics/code.py +0 -0
  61. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/magics/config.py +0 -0
  62. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/magics/display.py +0 -0
  63. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/magics/extension.py +0 -0
  64. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/magics/history.py +0 -0
  65. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/magics/logging.py +0 -0
  66. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/magics/namespace.py +0 -0
  67. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/magics/osm.py +0 -0
  68. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/magics/packaging.py +0 -0
  69. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/magics/pylab.py +0 -0
  70. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/oinspect.py +0 -0
  71. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/page.py +0 -0
  72. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/payload.py +0 -0
  73. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/payloadpage.py +0 -0
  74. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/prefilter.py +0 -0
  75. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/profile/README_STARTUP +0 -0
  76. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/profileapp.py +0 -0
  77. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/profiledir.py +0 -0
  78. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/prompts.py +0 -0
  79. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/pylabtools.py +0 -0
  80. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/shellapp.py +0 -0
  81. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/splitinput.py +0 -0
  82. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/2x2.jpg +0 -0
  83. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/2x2.png +0 -0
  84. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/__init__.py +0 -0
  85. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/bad_all.py +0 -0
  86. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/daft_extension/daft_extension.py +0 -0
  87. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/nonascii.py +0 -0
  88. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/nonascii2.py +0 -0
  89. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/print_argv.py +0 -0
  90. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/refbug.py +0 -0
  91. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/simpleerr.py +0 -0
  92. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/tclass.py +0 -0
  93. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_alias.py +0 -0
  94. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_application.py +0 -0
  95. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_async_helpers.py +0 -0
  96. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_autocall.py +0 -0
  97. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_compilerop.py +0 -0
  98. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_completer.py +0 -0
  99. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_completerlib.py +0 -0
  100. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_debugger.py +0 -0
  101. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_display.py +0 -0
  102. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_displayhook.py +0 -0
  103. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_events.py +0 -0
  104. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_exceptiongroup_tb.py +0 -0
  105. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_extension.py +0 -0
  106. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_formatters.py +0 -0
  107. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_guarded_eval.py +0 -0
  108. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_handlers.py +0 -0
  109. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_history.py +0 -0
  110. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_hooks.py +0 -0
  111. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_imports.py +0 -0
  112. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_inputsplitter.py +0 -0
  113. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_inputtransformer.py +0 -0
  114. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_inputtransformer2.py +0 -0
  115. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_inputtransformer2_line.py +0 -0
  116. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_interactiveshell.py +0 -0
  117. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_iplib.py +0 -0
  118. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_logger.py +0 -0
  119. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_magic_arguments.py +0 -0
  120. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_magic_terminal.py +0 -0
  121. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_oinspect.py +0 -0
  122. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_page.py +0 -0
  123. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_paths.py +0 -0
  124. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_prefilter.py +0 -0
  125. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_profile.py +0 -0
  126. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_prompts.py +0 -0
  127. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_pylabtools.py +0 -0
  128. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_run.py +0 -0
  129. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_shellapp.py +0 -0
  130. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_splitinput.py +0 -0
  131. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/tests/test_ultratb.py +0 -0
  132. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/ultratb.py +0 -0
  133. {ipython-8.31.0 → ipython-8.32.0}/IPython/core/usage.py +0 -0
  134. {ipython-8.31.0 → ipython-8.32.0}/IPython/display.py +0 -0
  135. {ipython-8.31.0 → ipython-8.32.0}/IPython/extensions/__init__.py +0 -0
  136. {ipython-8.31.0 → ipython-8.32.0}/IPython/extensions/autoreload.py +0 -0
  137. {ipython-8.31.0 → ipython-8.32.0}/IPython/extensions/storemagic.py +0 -0
  138. {ipython-8.31.0 → ipython-8.32.0}/IPython/extensions/tests/__init__.py +0 -0
  139. {ipython-8.31.0 → ipython-8.32.0}/IPython/extensions/tests/test_autoreload.py +0 -0
  140. {ipython-8.31.0 → ipython-8.32.0}/IPython/extensions/tests/test_storemagic.py +0 -0
  141. {ipython-8.31.0 → ipython-8.32.0}/IPython/external/__init__.py +0 -0
  142. {ipython-8.31.0 → ipython-8.32.0}/IPython/external/qt_for_kernel.py +0 -0
  143. {ipython-8.31.0 → ipython-8.32.0}/IPython/external/qt_loaders.py +0 -0
  144. {ipython-8.31.0 → ipython-8.32.0}/IPython/external/tests/__init__.py +0 -0
  145. {ipython-8.31.0 → ipython-8.32.0}/IPython/external/tests/test_qt_loaders.py +0 -0
  146. {ipython-8.31.0 → ipython-8.32.0}/IPython/lib/__init__.py +0 -0
  147. {ipython-8.31.0 → ipython-8.32.0}/IPython/lib/backgroundjobs.py +0 -0
  148. {ipython-8.31.0 → ipython-8.32.0}/IPython/lib/clipboard.py +0 -0
  149. {ipython-8.31.0 → ipython-8.32.0}/IPython/lib/deepreload.py +0 -0
  150. {ipython-8.31.0 → ipython-8.32.0}/IPython/lib/demo.py +0 -0
  151. {ipython-8.31.0 → ipython-8.32.0}/IPython/lib/display.py +0 -0
  152. {ipython-8.31.0 → ipython-8.32.0}/IPython/lib/editorhooks.py +0 -0
  153. {ipython-8.31.0 → ipython-8.32.0}/IPython/lib/guisupport.py +0 -0
  154. {ipython-8.31.0 → ipython-8.32.0}/IPython/lib/latextools.py +0 -0
  155. {ipython-8.31.0 → ipython-8.32.0}/IPython/lib/lexers.py +0 -0
  156. {ipython-8.31.0 → ipython-8.32.0}/IPython/lib/pretty.py +0 -0
  157. {ipython-8.31.0 → ipython-8.32.0}/IPython/lib/tests/__init__.py +0 -0
  158. {ipython-8.31.0 → ipython-8.32.0}/IPython/lib/tests/test.wav +0 -0
  159. {ipython-8.31.0 → ipython-8.32.0}/IPython/lib/tests/test_backgroundjobs.py +0 -0
  160. {ipython-8.31.0 → ipython-8.32.0}/IPython/lib/tests/test_clipboard.py +0 -0
  161. {ipython-8.31.0 → ipython-8.32.0}/IPython/lib/tests/test_deepreload.py +0 -0
  162. {ipython-8.31.0 → ipython-8.32.0}/IPython/lib/tests/test_display.py +0 -0
  163. {ipython-8.31.0 → ipython-8.32.0}/IPython/lib/tests/test_editorhooks.py +0 -0
  164. {ipython-8.31.0 → ipython-8.32.0}/IPython/lib/tests/test_imports.py +0 -0
  165. {ipython-8.31.0 → ipython-8.32.0}/IPython/lib/tests/test_latextools.py +0 -0
  166. {ipython-8.31.0 → ipython-8.32.0}/IPython/lib/tests/test_lexers.py +0 -0
  167. {ipython-8.31.0 → ipython-8.32.0}/IPython/lib/tests/test_pretty.py +0 -0
  168. {ipython-8.31.0 → ipython-8.32.0}/IPython/lib/tests/test_pygments.py +0 -0
  169. {ipython-8.31.0 → ipython-8.32.0}/IPython/paths.py +0 -0
  170. {ipython-8.31.0 → ipython-8.32.0}/IPython/py.typed +0 -0
  171. {ipython-8.31.0 → ipython-8.32.0}/IPython/sphinxext/__init__.py +0 -0
  172. {ipython-8.31.0 → ipython-8.32.0}/IPython/sphinxext/custom_doctests.py +0 -0
  173. {ipython-8.31.0 → ipython-8.32.0}/IPython/sphinxext/ipython_console_highlighting.py +0 -0
  174. {ipython-8.31.0 → ipython-8.32.0}/IPython/sphinxext/ipython_directive.py +0 -0
  175. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/__init__.py +0 -0
  176. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/console.py +0 -0
  177. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/debugger.py +0 -0
  178. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/embed.py +0 -0
  179. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/ipapp.py +0 -0
  180. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/magics.py +0 -0
  181. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/prompts.py +0 -0
  182. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/pt_inputhooks/__init__.py +0 -0
  183. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/pt_inputhooks/asyncio.py +0 -0
  184. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/pt_inputhooks/glut.py +0 -0
  185. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/pt_inputhooks/gtk.py +0 -0
  186. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/pt_inputhooks/gtk3.py +0 -0
  187. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/pt_inputhooks/gtk4.py +0 -0
  188. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/pt_inputhooks/osx.py +0 -0
  189. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/pt_inputhooks/pyglet.py +0 -0
  190. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/pt_inputhooks/qt.py +0 -0
  191. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/pt_inputhooks/tk.py +0 -0
  192. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/pt_inputhooks/wx.py +0 -0
  193. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/ptutils.py +0 -0
  194. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/shortcuts/__init__.py +0 -0
  195. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/shortcuts/auto_match.py +0 -0
  196. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/shortcuts/filters.py +0 -0
  197. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/tests/__init__.py +0 -0
  198. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/tests/test_debug_magic.py +0 -0
  199. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/tests/test_embed.py +0 -0
  200. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/tests/test_help.py +0 -0
  201. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/tests/test_interactivshell.py +0 -0
  202. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/tests/test_pt_inputhooks.py +0 -0
  203. {ipython-8.31.0 → ipython-8.32.0}/IPython/terminal/tests/test_shortcuts.py +0 -0
  204. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/__init__.py +0 -0
  205. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/decorators.py +0 -0
  206. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/globalipapp.py +0 -0
  207. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/ipunittest.py +0 -0
  208. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/plugin/Makefile +0 -0
  209. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/plugin/README.txt +0 -0
  210. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/plugin/__init__.py +0 -0
  211. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/plugin/dtexample.py +0 -0
  212. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/plugin/ipdoctest.py +0 -0
  213. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/plugin/pytest_ipdoctest.py +0 -0
  214. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/plugin/setup.py +0 -0
  215. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/plugin/simple.py +0 -0
  216. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/plugin/simplevars.py +0 -0
  217. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/plugin/test_combo.txt +0 -0
  218. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/plugin/test_example.txt +0 -0
  219. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/plugin/test_exampleip.txt +0 -0
  220. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/plugin/test_ipdoctest.py +0 -0
  221. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/plugin/test_refs.py +0 -0
  222. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/skipdoctest.py +0 -0
  223. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/tests/__init__.py +0 -0
  224. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/tests/test_decorators.py +0 -0
  225. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/tests/test_ipunittest.py +0 -0
  226. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/tests/test_tools.py +0 -0
  227. {ipython-8.31.0 → ipython-8.32.0}/IPython/testing/tools.py +0 -0
  228. {ipython-8.31.0 → ipython-8.32.0}/IPython/tests/cve.py +0 -0
  229. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/PyColorize.py +0 -0
  230. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/__init__.py +0 -0
  231. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/_process_cli.py +0 -0
  232. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/_process_common.py +0 -0
  233. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/_process_emscripten.py +0 -0
  234. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/_process_posix.py +0 -0
  235. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/_process_win32.py +0 -0
  236. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/_process_win32_controller.py +0 -0
  237. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/capture.py +0 -0
  238. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/colorable.py +0 -0
  239. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/coloransi.py +0 -0
  240. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/contexts.py +0 -0
  241. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/daemonize.py +0 -0
  242. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/data.py +0 -0
  243. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/decorators.py +0 -0
  244. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/dir2.py +0 -0
  245. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/docs.py +0 -0
  246. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/encoding.py +0 -0
  247. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/eventful.py +0 -0
  248. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/frame.py +0 -0
  249. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/generics.py +0 -0
  250. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/importstring.py +0 -0
  251. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/io.py +0 -0
  252. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/ipstruct.py +0 -0
  253. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/jsonutil.py +0 -0
  254. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/localinterfaces.py +0 -0
  255. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/log.py +0 -0
  256. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/module_paths.py +0 -0
  257. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/openpy.py +0 -0
  258. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/path.py +0 -0
  259. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/process.py +0 -0
  260. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/py3compat.py +0 -0
  261. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/sentinel.py +0 -0
  262. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/shimmodule.py +0 -0
  263. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/signatures.py +0 -0
  264. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/strdispatch.py +0 -0
  265. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/sysinfo.py +0 -0
  266. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/syspathcontext.py +0 -0
  267. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/tempdir.py +0 -0
  268. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/terminal.py +0 -0
  269. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/tests/__init__.py +0 -0
  270. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/tests/test_capture.py +0 -0
  271. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/tests/test_decorators.py +0 -0
  272. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/tests/test_deprecated.py +0 -0
  273. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/tests/test_dir2.py +0 -0
  274. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/tests/test_imports.py +0 -0
  275. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/tests/test_importstring.py +0 -0
  276. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/tests/test_io.py +0 -0
  277. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/tests/test_module_paths.py +0 -0
  278. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/tests/test_openpy.py +0 -0
  279. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/tests/test_path.py +0 -0
  280. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/tests/test_process.py +0 -0
  281. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/tests/test_pycolorize.py +0 -0
  282. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/tests/test_shimmodule.py +0 -0
  283. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/tests/test_sysinfo.py +0 -0
  284. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/tests/test_tempdir.py +0 -0
  285. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/tests/test_text.py +0 -0
  286. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/tests/test_tokenutil.py +0 -0
  287. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/tests/test_wildcard.py +0 -0
  288. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/text.py +0 -0
  289. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/timing.py +0 -0
  290. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/tokenutil.py +0 -0
  291. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/traitlets.py +0 -0
  292. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/tz.py +0 -0
  293. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/ulinecache.py +0 -0
  294. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/version.py +0 -0
  295. {ipython-8.31.0 → ipython-8.32.0}/IPython/utils/wildcard.py +0 -0
  296. {ipython-8.31.0 → ipython-8.32.0}/LICENSE +0 -0
  297. {ipython-8.31.0 → ipython-8.32.0}/MANIFEST.in +0 -0
  298. {ipython-8.31.0 → ipython-8.32.0}/README.rst +0 -0
  299. {ipython-8.31.0 → ipython-8.32.0}/_build_meta.py +0 -0
  300. {ipython-8.31.0 → ipython-8.32.0}/docs/Makefile +0 -0
  301. {ipython-8.31.0 → ipython-8.32.0}/docs/README.rst +0 -0
  302. {ipython-8.31.0 → ipython-8.32.0}/docs/autogen_api.py +0 -0
  303. {ipython-8.31.0 → ipython-8.32.0}/docs/autogen_config.py +0 -0
  304. {ipython-8.31.0 → ipython-8.32.0}/docs/autogen_magics.py +0 -0
  305. {ipython-8.31.0 → ipython-8.32.0}/docs/autogen_shortcuts.py +0 -0
  306. {ipython-8.31.0 → ipython-8.32.0}/docs/make.cmd +0 -0
  307. {ipython-8.31.0 → ipython-8.32.0}/docs/man/ipython.1 +0 -0
  308. {ipython-8.31.0 → ipython-8.32.0}/docs/requirements.txt +0 -0
  309. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/2.0/running-crop.png +0 -0
  310. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/2.0/running.png +0 -0
  311. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/2.0/treeview.png +0 -0
  312. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/2.0/user-interface.png +0 -0
  313. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/2.0/widgets.png +0 -0
  314. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/8.0/auto_suggest_1_prompt_no_text.png +0 -0
  315. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/8.0/auto_suggest_2_print_hello_suggest.png +0 -0
  316. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/8.0/auto_suggest_3_print_hello_suggest.png +0 -0
  317. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/8.0/auto_suggest_4_print_hello.png +0 -0
  318. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/8.0/auto_suggest_d_completions.png +0 -0
  319. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/8.0/auto_suggest_d_phantom.png +0 -0
  320. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/8.0/auto_suggest_def_completions.png +0 -0
  321. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/8.0/auto_suggest_def_phantom.png +0 -0
  322. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/8.0/auto_suggest_match_parens.png +0 -0
  323. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/8.0/auto_suggest_second_prompt.png +0 -0
  324. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/8.0/pathlib_pathlib_everywhere.jpg +0 -0
  325. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/autosuggest.gif +0 -0
  326. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/ipy_013_dashboard.png +0 -0
  327. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/ipy_013_dashboard_cluster.png +0 -0
  328. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/ipy_013_notebook_cythonmagic.png +0 -0
  329. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/ipy_013_notebook_long_out.png +0 -0
  330. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/ipy_013_notebook_octavemagic.png +0 -0
  331. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/ipy_013_notebook_rmagic.png +0 -0
  332. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/ipy_013_notebook_script_cells.png +0 -0
  333. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/ipy_013_notebook_spectrogram.png +0 -0
  334. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/ipy_013_notebook_tooltip.png +0 -0
  335. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/ipy_013_par_tb.png +0 -0
  336. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/ipy_013_qtconsole_baboon.png +0 -0
  337. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/ipy_013_qtconsole_completer.png +0 -0
  338. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/ipython-6-screenshot.png +0 -0
  339. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/jedi_type_inference_60.png +0 -0
  340. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/kernel_selector_screenshot.png +0 -0
  341. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/ms_visual_studio.png +0 -0
  342. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/notebook_specgram.png +0 -0
  343. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/ptshell_features.png +0 -0
  344. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/qtconsole.png +0 -0
  345. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/qtconsole_tabbed.png +0 -0
  346. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_images/unicode_completion.png +0 -0
  347. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_static/favicon.ico +0 -0
  348. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_static/logo.png +0 -0
  349. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_static/theme_overrides.css +0 -0
  350. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_templates/breadcrumbs.html +0 -0
  351. {ipython-8.31.0 → ipython-8.32.0}/docs/source/_templates/notebook_redirect.html +0 -0
  352. {ipython-8.31.0 → ipython-8.32.0}/docs/source/about/history.rst +0 -0
  353. {ipython-8.31.0 → ipython-8.32.0}/docs/source/about/index.rst +0 -0
  354. {ipython-8.31.0 → ipython-8.32.0}/docs/source/about/license_and_copyright.rst +0 -0
  355. {ipython-8.31.0 → ipython-8.32.0}/docs/source/api/index.rst +0 -0
  356. {ipython-8.31.0 → ipython-8.32.0}/docs/source/conf.py +0 -0
  357. {ipython-8.31.0 → ipython-8.32.0}/docs/source/config/callbacks.rst +0 -0
  358. {ipython-8.31.0 → ipython-8.32.0}/docs/source/config/custommagics.rst +0 -0
  359. {ipython-8.31.0 → ipython-8.32.0}/docs/source/config/details.rst +0 -0
  360. {ipython-8.31.0 → ipython-8.32.0}/docs/source/config/eventloops.rst +0 -0
  361. {ipython-8.31.0 → ipython-8.32.0}/docs/source/config/extensions/autoreload.rst +0 -0
  362. {ipython-8.31.0 → ipython-8.32.0}/docs/source/config/extensions/index.rst +0 -0
  363. {ipython-8.31.0 → ipython-8.32.0}/docs/source/config/extensions/storemagic.rst +0 -0
  364. {ipython-8.31.0 → ipython-8.32.0}/docs/source/config/index.rst +0 -0
  365. {ipython-8.31.0 → ipython-8.32.0}/docs/source/config/inputtransforms.rst +0 -0
  366. {ipython-8.31.0 → ipython-8.32.0}/docs/source/config/integrating.rst +0 -0
  367. {ipython-8.31.0 → ipython-8.32.0}/docs/source/config/intro.rst +0 -0
  368. {ipython-8.31.0 → ipython-8.32.0}/docs/source/config/options/index.rst +0 -0
  369. {ipython-8.31.0 → ipython-8.32.0}/docs/source/config/shell_mimerenderer.rst +0 -0
  370. {ipython-8.31.0 → ipython-8.32.0}/docs/source/config/shortcuts/index.rst +0 -0
  371. {ipython-8.31.0 → ipython-8.32.0}/docs/source/coredev/index.rst +0 -0
  372. {ipython-8.31.0 → ipython-8.32.0}/docs/source/development/config.rst +0 -0
  373. {ipython-8.31.0 → ipython-8.32.0}/docs/source/development/execution.rst +0 -0
  374. {ipython-8.31.0 → ipython-8.32.0}/docs/source/development/figs/ipy_kernel_and_terminal.png +0 -0
  375. {ipython-8.31.0 → ipython-8.32.0}/docs/source/development/figs/ipy_kernel_and_terminal.svg +0 -0
  376. {ipython-8.31.0 → ipython-8.32.0}/docs/source/development/figs/other_kernels.png +0 -0
  377. {ipython-8.31.0 → ipython-8.32.0}/docs/source/development/figs/other_kernels.svg +0 -0
  378. {ipython-8.31.0 → ipython-8.32.0}/docs/source/development/how_ipython_works.rst +0 -0
  379. {ipython-8.31.0 → ipython-8.32.0}/docs/source/development/index.rst +0 -0
  380. {ipython-8.31.0 → ipython-8.32.0}/docs/source/development/inputhook_app.rst +0 -0
  381. {ipython-8.31.0 → ipython-8.32.0}/docs/source/development/kernels.rst +0 -0
  382. {ipython-8.31.0 → ipython-8.32.0}/docs/source/development/lexer.rst +0 -0
  383. {ipython-8.31.0 → ipython-8.32.0}/docs/source/development/messaging.rst +0 -0
  384. {ipython-8.31.0 → ipython-8.32.0}/docs/source/development/pycompat.rst +0 -0
  385. {ipython-8.31.0 → ipython-8.32.0}/docs/source/development/wrapperkernels.rst +0 -0
  386. {ipython-8.31.0 → ipython-8.32.0}/docs/source/index.rst +0 -0
  387. {ipython-8.31.0 → ipython-8.32.0}/docs/source/install/index.rst +0 -0
  388. {ipython-8.31.0 → ipython-8.32.0}/docs/source/install/install.rst +0 -0
  389. {ipython-8.31.0 → ipython-8.32.0}/docs/source/install/kernel_install.rst +0 -0
  390. {ipython-8.31.0 → ipython-8.32.0}/docs/source/interactive/autoawait.rst +0 -0
  391. {ipython-8.31.0 → ipython-8.32.0}/docs/source/interactive/figs/besselj.png +0 -0
  392. {ipython-8.31.0 → ipython-8.32.0}/docs/source/interactive/figs/colors_dark.png +0 -0
  393. {ipython-8.31.0 → ipython-8.32.0}/docs/source/interactive/figs/jn.html +0 -0
  394. {ipython-8.31.0 → ipython-8.32.0}/docs/source/interactive/figs/jn.xhtml +0 -0
  395. {ipython-8.31.0 → ipython-8.32.0}/docs/source/interactive/index.rst +0 -0
  396. {ipython-8.31.0 → ipython-8.32.0}/docs/source/interactive/magics.rst +0 -0
  397. {ipython-8.31.0 → ipython-8.32.0}/docs/source/interactive/plotting.rst +0 -0
  398. {ipython-8.31.0 → ipython-8.32.0}/docs/source/interactive/python-ipython-diff.rst +0 -0
  399. {ipython-8.31.0 → ipython-8.32.0}/docs/source/interactive/reference.rst +0 -0
  400. {ipython-8.31.0 → ipython-8.32.0}/docs/source/interactive/shell.rst +0 -0
  401. {ipython-8.31.0 → ipython-8.32.0}/docs/source/interactive/tips.rst +0 -0
  402. {ipython-8.31.0 → ipython-8.32.0}/docs/source/interactive/tutorial.rst +0 -0
  403. {ipython-8.31.0 → ipython-8.32.0}/docs/source/links.txt +0 -0
  404. {ipython-8.31.0 → ipython-8.32.0}/docs/source/overview.rst +0 -0
  405. {ipython-8.31.0 → ipython-8.32.0}/docs/source/parallel/index.rst +0 -0
  406. {ipython-8.31.0 → ipython-8.32.0}/docs/source/sphinx.toml +0 -0
  407. {ipython-8.31.0 → ipython-8.32.0}/docs/source/sphinxext.rst +0 -0
  408. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/development.rst +0 -0
  409. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/github-stats-0.11.rst +0 -0
  410. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/github-stats-0.12.rst +0 -0
  411. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/github-stats-0.13.rst +0 -0
  412. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/github-stats-1.0.rst +0 -0
  413. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/github-stats-2.0.rst +0 -0
  414. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/github-stats-3.rst +0 -0
  415. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/github-stats-4.rst +0 -0
  416. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/github-stats-5.rst +0 -0
  417. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/github-stats-6.rst +0 -0
  418. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/github-stats-7.rst +0 -0
  419. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/github-stats-8.rst +0 -0
  420. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/index.rst +0 -0
  421. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/pr/README.md +0 -0
  422. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/pr/antigravity-feature.rst +0 -0
  423. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/pr/incompat-switching-to-perl.rst +0 -0
  424. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/version0.10.rst +0 -0
  425. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/version0.11.rst +0 -0
  426. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/version0.12.rst +0 -0
  427. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/version0.13.rst +0 -0
  428. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/version0.8.rst +0 -0
  429. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/version0.9.rst +0 -0
  430. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/version1.0.rst +0 -0
  431. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/version2.0.rst +0 -0
  432. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/version3.rst +0 -0
  433. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/version3_widget_migration.rst +0 -0
  434. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/version4.rst +0 -0
  435. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/version5.rst +0 -0
  436. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/version6.rst +0 -0
  437. {ipython-8.31.0 → ipython-8.32.0}/docs/source/whatsnew/version7.rst +0 -0
  438. {ipython-8.31.0 → ipython-8.32.0}/docs/sphinxext/apigen.py +0 -0
  439. {ipython-8.31.0 → ipython-8.32.0}/docs/sphinxext/configtraits.py +0 -0
  440. {ipython-8.31.0 → ipython-8.32.0}/docs/sphinxext/github.py +0 -0
  441. {ipython-8.31.0 → ipython-8.32.0}/docs/sphinxext/magics.py +0 -0
  442. {ipython-8.31.0 → ipython-8.32.0}/examples/Embedding/Index.ipynb +0 -0
  443. {ipython-8.31.0 → ipython-8.32.0}/examples/Embedding/embed_class_long.py +0 -0
  444. {ipython-8.31.0 → ipython-8.32.0}/examples/Embedding/embed_class_short.py +0 -0
  445. {ipython-8.31.0 → ipython-8.32.0}/examples/Embedding/embed_function.py +0 -0
  446. {ipython-8.31.0 → ipython-8.32.0}/examples/Embedding/start_ipython_config.py +0 -0
  447. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/Animations Using clear_output.ipynb +0 -0
  448. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/Background Jobs.ipynb +0 -0
  449. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/Beyond Plain Python.ipynb +0 -0
  450. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/Capturing Output.ipynb +0 -0
  451. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/Cell Magics.ipynb +0 -0
  452. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/Custom Display Logic.ipynb +0 -0
  453. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/Importing Notebooks.ipynb +0 -0
  454. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/Index.ipynb +0 -0
  455. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/Plotting in the Notebook.ipynb +0 -0
  456. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/Raw Input in the Notebook.ipynb +0 -0
  457. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/Rich Output.ipynb +0 -0
  458. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/Script Magics.ipynb +0 -0
  459. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/SymPy.ipynb +0 -0
  460. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/Terminal Usage.ipynb +0 -0
  461. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/Third Party Rich Output.ipynb +0 -0
  462. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/Trapezoid Rule.ipynb +0 -0
  463. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/Updating Displays.ipynb +0 -0
  464. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/Working With External Code.ipynb +0 -0
  465. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/data/flare.json +0 -0
  466. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/example-demo.py +0 -0
  467. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/gui/gui-glut.py +0 -0
  468. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/gui/gui-gtk4.py +0 -0
  469. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/gui/gui-qt.py +0 -0
  470. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/ipython-completion.bash +0 -0
  471. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/ipython-get-history.py +0 -0
  472. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/ipython.desktop +0 -0
  473. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/nbpackage/__init__.py +0 -0
  474. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/nbpackage/mynotebook.ipynb +0 -0
  475. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/nbpackage/nbs/__init__.py +0 -0
  476. {ipython-8.31.0 → ipython-8.32.0}/examples/IPython Kernel/nbpackage/nbs/other.ipynb +0 -0
  477. {ipython-8.31.0 → ipython-8.32.0}/examples/Index.ipynb +0 -0
  478. {ipython-8.31.0 → ipython-8.32.0}/examples/images/FrontendKernel.graffle/data.plist +0 -0
  479. {ipython-8.31.0 → ipython-8.32.0}/examples/images/FrontendKernel.graffle/image1.png +0 -0
  480. {ipython-8.31.0 → ipython-8.32.0}/examples/images/FrontendKernel.png +0 -0
  481. {ipython-8.31.0 → ipython-8.32.0}/examples/images/animation.m4v +0 -0
  482. {ipython-8.31.0 → ipython-8.32.0}/examples/images/ipython_logo.png +0 -0
  483. {ipython-8.31.0 → ipython-8.32.0}/examples/images/python_logo.svg +0 -0
  484. {ipython-8.31.0 → ipython-8.32.0}/examples/utils/cwd_prompt.py +0 -0
  485. {ipython-8.31.0 → ipython-8.32.0}/examples/utils/list_pyfiles.ipy +0 -0
  486. {ipython-8.31.0 → ipython-8.32.0}/examples/utils/list_subdirs.ipy +0 -0
  487. {ipython-8.31.0 → ipython-8.32.0}/ipython.egg-info/dependency_links.txt +0 -0
  488. {ipython-8.31.0 → ipython-8.32.0}/ipython.egg-info/entry_points.txt +0 -0
  489. {ipython-8.31.0 → ipython-8.32.0}/ipython.egg-info/not-zip-safe +0 -0
  490. {ipython-8.31.0 → ipython-8.32.0}/ipython.egg-info/requires.txt +0 -0
  491. {ipython-8.31.0 → ipython-8.32.0}/ipython.egg-info/top_level.txt +0 -0
  492. {ipython-8.31.0 → ipython-8.32.0}/long_description.rst +0 -0
  493. {ipython-8.31.0 → ipython-8.32.0}/pyproject.toml +0 -0
  494. {ipython-8.31.0 → ipython-8.32.0}/scripts/ipython.ico +0 -0
  495. {ipython-8.31.0 → ipython-8.32.0}/scripts/ipython_nb.ico +0 -0
  496. {ipython-8.31.0 → ipython-8.32.0}/setup.cfg +0 -0
  497. {ipython-8.31.0 → ipython-8.32.0}/setup.py +0 -0
  498. {ipython-8.31.0 → ipython-8.32.0}/setupbase.py +0 -0
@@ -900,7 +900,7 @@ class InteractiveShell(SingletonConfigurable):
900
900
  return
901
901
 
902
902
  p = Path(sys.executable)
903
- p_venv = Path(os.environ["VIRTUAL_ENV"])
903
+ p_venv = Path(os.environ["VIRTUAL_ENV"]).resolve()
904
904
 
905
905
  # fallback venv detection:
906
906
  # stdlib venv may symlink sys.executable, so we can't use realpath.
@@ -913,7 +913,7 @@ class InteractiveShell(SingletonConfigurable):
913
913
  drive_name = p_venv.parts[2]
914
914
  p_venv = (drive_name + ":/") / Path(*p_venv.parts[3:])
915
915
 
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):
917
917
  # Our exe is inside or has access to the virtualenv, don't need to do anything.
918
918
  return
919
919
 
@@ -2093,6 +2093,8 @@ class InteractiveShell(SingletonConfigurable):
2093
2093
  sys.last_type = etype
2094
2094
  sys.last_value = value
2095
2095
  sys.last_traceback = tb
2096
+ if sys.version_info >= (3, 12):
2097
+ sys.last_exc = value
2096
2098
 
2097
2099
  return etype, value, tb
2098
2100
 
@@ -977,7 +977,21 @@ class ExecutionMagics(Magics):
977
977
  break
978
978
  finally:
979
979
  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
981
995
 
982
996
  except:
983
997
  etype, value, tb = sys.exc_info()
@@ -67,6 +67,10 @@ def script_args(f):
67
67
  return f
68
68
 
69
69
 
70
+ class RaiseAfterInterrupt(Exception):
71
+ pass
72
+
73
+
70
74
  @magics_class
71
75
  class ScriptMagics(Magics):
72
76
  """Magics for talking to scripts
@@ -176,6 +180,10 @@ class ScriptMagics(Magics):
176
180
 
177
181
  The rest of the cell is run by that program.
178
182
 
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
+
179
187
  Examples
180
188
  --------
181
189
  ::
@@ -212,7 +220,7 @@ class ScriptMagics(Magics):
212
220
 
213
221
  async def _readchunk(stream):
214
222
  try:
215
- return await stream.readuntil(b"\n")
223
+ return await stream.read(100)
216
224
  except asyncio.exceptions.IncompleteReadError as e:
217
225
  return e.partial
218
226
  except asyncio.exceptions.LimitOverrunError as e:
@@ -292,20 +300,33 @@ class ScriptMagics(Magics):
292
300
  p.send_signal(signal.SIGINT)
293
301
  in_thread(asyncio.wait_for(p.wait(), timeout=0.1))
294
302
  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
297
308
  p.terminate()
298
309
  in_thread(asyncio.wait_for(p.wait(), timeout=0.1))
299
310
  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
302
316
  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
304
322
  except OSError:
305
323
  pass
306
324
  except Exception as e:
307
325
  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
309
330
 
310
331
  if args.raise_error and p.returncode != 0:
311
332
  # If we get here and p.returncode is still None, we must have
@@ -16,7 +16,7 @@
16
16
  # release. 'dev' as a _version_extra string means this is a development
17
17
  # version
18
18
  _version_major = 8
19
- _version_minor = 31
19
+ _version_minor = 32
20
20
  _version_patch = 0
21
21
  _version_extra = ".dev"
22
22
  # _version_extra = "rc1"
@@ -6,12 +6,18 @@ import io
6
6
  import os
7
7
  import re
8
8
  import shlex
9
+ import signal
9
10
  import sys
10
11
  import warnings
11
12
  from importlib import invalidate_caches
12
13
  from io import StringIO
13
14
  from pathlib import Path
15
+ from time import sleep
16
+ from threading import Thread
17
+ from subprocess import CalledProcessError
14
18
  from textwrap import dedent
19
+ from time import sleep
20
+ from threading import Thread
15
21
  from unittest import TestCase, mock
16
22
 
17
23
  import pytest
@@ -1121,6 +1127,36 @@ def test_script_config():
1121
1127
  assert "whoda" in sm.magics["cell"]
1122
1128
 
1123
1129
 
1130
+ def _interrupt_after_1s():
1131
+ sleep(1)
1132
+ signal.raise_signal(signal.SIGINT)
1133
+
1134
+
1135
+ def test_script_raise_on_interrupt():
1136
+ ip = get_ipython()
1137
+
1138
+ with pytest.raises(CalledProcessError):
1139
+ thread = Thread(target=_interrupt_after_1s)
1140
+ thread.start()
1141
+ ip.run_cell_magic(
1142
+ "script", f"{sys.executable}", "from time import sleep; sleep(2)"
1143
+ )
1144
+ thread.join()
1145
+
1146
+
1147
+ def test_script_do_not_raise_on_interrupt():
1148
+ ip = get_ipython()
1149
+
1150
+ thread = Thread(target=_interrupt_after_1s)
1151
+ thread.start()
1152
+ ip.run_cell_magic(
1153
+ "script",
1154
+ f"--no-raise-error {sys.executable}",
1155
+ "from time import sleep; sleep(2)",
1156
+ )
1157
+ thread.join()
1158
+
1159
+
1124
1160
  def test_script_out():
1125
1161
  ip = get_ipython()
1126
1162
  ip.run_cell_magic("script", f"--out output {sys.executable}", "print('hi')")
@@ -1225,6 +1261,37 @@ def test_script_defaults():
1225
1261
  assert cmd in ip.magics_manager.magics["cell"]
1226
1262
 
1227
1263
 
1264
+ async def test_script_streams_continiously(capsys):
1265
+ ip = get_ipython()
1266
+ # Windows is slow to start up a thread on CI
1267
+ is_windows = os.name == "nt"
1268
+ step = 3 if is_windows else 1
1269
+ code = dedent(
1270
+ f"""\
1271
+ import time
1272
+ for _ in range(3):
1273
+ time.sleep({step})
1274
+ print(".", flush=True, end="")
1275
+ """
1276
+ )
1277
+
1278
+ def print_numbers():
1279
+ for i in range(3):
1280
+ sleep(step)
1281
+ print(i, flush=True, end="")
1282
+
1283
+ thread = Thread(target=print_numbers)
1284
+ thread.start()
1285
+ sleep(step / 2)
1286
+ ip.run_cell_magic("script", f"{sys.executable}", code)
1287
+ thread.join()
1288
+
1289
+ captured = capsys.readouterr()
1290
+ # If the streaming was line-wise or broken
1291
+ # we would get `012...`
1292
+ assert captured.out == "0.1.2."
1293
+
1294
+
1228
1295
  @magics_class
1229
1296
  class FooFoo(Magics):
1230
1297
  """class with both %foo and %%foo magics"""
@@ -26,7 +26,10 @@ from traitlets import (
26
26
  Any,
27
27
  validate,
28
28
  Float,
29
+ DottedObjectName,
29
30
  )
31
+ from traitlets.utils.importstring import import_item
32
+
30
33
 
31
34
  from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
32
35
  from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode
@@ -214,7 +217,9 @@ class TerminalInteractiveShell(InteractiveShell):
214
217
 
215
218
  pt_app: UnionType[PromptSession, None] = None
216
219
  auto_suggest: UnionType[
217
- AutoSuggestFromHistory, NavigableAutoSuggestFromHistory, None
220
+ AutoSuggestFromHistory,
221
+ NavigableAutoSuggestFromHistory,
222
+ None,
218
223
  ] = None
219
224
  debugger_history = None
220
225
 
@@ -421,6 +426,37 @@ class TerminalInteractiveShell(InteractiveShell):
421
426
  allow_none=True,
422
427
  ).tag(config=True)
423
428
 
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
+
424
460
  def _set_autosuggestions(self, provider):
425
461
  # disconnect old handler
426
462
  if self.auto_suggest and isinstance(
@@ -432,7 +468,15 @@ class TerminalInteractiveShell(InteractiveShell):
432
468
  elif provider == "AutoSuggestFromHistory":
433
469
  self.auto_suggest = AutoSuggestFromHistory()
434
470
  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
435
477
  self.auto_suggest = NavigableAutoSuggestFromHistory()
478
+ # Provisinal in 8.32
479
+ self.auto_suggest._llm_provider = llm_provider
436
480
  else:
437
481
  raise ValueError("No valid provider.")
438
482
  if self.pt_app:
@@ -815,7 +859,8 @@ class TerminalInteractiveShell(InteractiveShell):
815
859
  & ~IsDone()
816
860
  & Condition(
817
861
  lambda: isinstance(
818
- self.auto_suggest, NavigableAutoSuggestFromHistory
862
+ self.auto_suggest,
863
+ NavigableAutoSuggestFromHistory,
819
864
  )
820
865
  ),
821
866
  ),
@@ -1,13 +1,15 @@
1
1
  import re
2
+ import asyncio
2
3
  import tokenize
3
4
  from io import StringIO
4
- from typing import Callable, List, Optional, Union, Generator, Tuple
5
+ from typing import Callable, List, Optional, Union, Generator, Tuple, ClassVar, Any
5
6
  import warnings
6
7
 
8
+ import prompt_toolkit
7
9
  from prompt_toolkit.buffer import Buffer
8
10
  from prompt_toolkit.key_binding import KeyPressEvent
9
11
  from prompt_toolkit.key_binding.bindings import named_commands as nc
10
- from prompt_toolkit.auto_suggest import AutoSuggestFromHistory, Suggestion
12
+ from prompt_toolkit.auto_suggest import AutoSuggestFromHistory, Suggestion, AutoSuggest
11
13
  from prompt_toolkit.document import Document
12
14
  from prompt_toolkit.history import History
13
15
  from prompt_toolkit.shortcuts import PromptSession
@@ -22,6 +24,12 @@ from IPython.utils.tokenutil import generate_tokens
22
24
 
23
25
  from .filters import pass_through
24
26
 
27
+ try:
28
+ import jupyter_ai_magics
29
+ import jupyter_ai.completions.models as jai_models
30
+ except ModuleNotFoundError:
31
+ jai_models = None
32
+
25
33
 
26
34
  def _get_query(document: Document):
27
35
  return document.lines[document.cursor_position_row]
@@ -31,26 +39,124 @@ class AppendAutoSuggestionInAnyLine(Processor):
31
39
  """
32
40
  Append the auto suggestion to lines other than the last (appending to the
33
41
  last line is natively supported by the prompt toolkit).
42
+
43
+ This has a private `_debug` attribute that can be set to True to display
44
+ debug information as virtual suggestion on the end of any line. You can do
45
+ so with:
46
+
47
+ >>> from IPython.terminal.shortcuts.auto_suggest import AppendAutoSuggestionInAnyLine
48
+ >>> AppendAutoSuggestionInAnyLine._debug = True
49
+
34
50
  """
35
51
 
52
+ _debug: ClassVar[bool] = False
53
+
36
54
  def __init__(self, style: str = "class:auto-suggestion") -> None:
37
55
  self.style = style
38
56
 
39
57
  def apply_transformation(self, ti: TransformationInput) -> Transformation:
40
- is_last_line = ti.lineno == ti.document.line_count - 1
41
- is_active_line = ti.lineno == ti.document.cursor_position_row
58
+ """
59
+ Apply transformation to the line that is currently being edited.
42
60
 
43
- if not is_last_line and is_active_line:
44
- buffer = ti.buffer_control.buffer
61
+ This is a variation of the original implementation in prompt toolkit
62
+ that allows to not only append suggestions to any line, but also to show
63
+ multi-line suggestions.
45
64
 
46
- if buffer.suggestion and ti.document.is_cursor_at_the_end_of_line:
47
- suggestion = buffer.suggestion.text
48
- else:
49
- suggestion = ""
65
+ As transformation are applied on a line-by-line basis; we need to trick
66
+ a bit, and elide any line that is after the line we are currently
67
+ editing, until we run out of completions. We cannot shift the existing
68
+ lines
69
+
70
+ There are multiple cases to handle:
71
+
72
+ The completions ends before the end of the buffer:
73
+ We can resume showing the normal line, and say that some code may
74
+ be hidden.
75
+
76
+ The completions ends at the end of the buffer
77
+ We can just say that some code may be hidden.
78
+
79
+ And separately:
80
+
81
+ The completions ends beyond the end of the buffer
82
+ We need to both say that some code may be hidden, and that some
83
+ lines are not shown.
84
+
85
+ """
86
+ last_line_number = ti.document.line_count - 1
87
+ is_last_line = ti.lineno == last_line_number
88
+
89
+ noop = lambda text: Transformation(
90
+ fragments=ti.fragments + [(self.style, " " + text if self._debug else "")]
91
+ )
92
+ if ti.document.line_count == 1:
93
+ return noop("noop:oneline")
94
+ if ti.document.cursor_position_row == last_line_number and is_last_line:
95
+ # prompt toolkit already appends something; just leave it be
96
+ return noop("noop:last line and cursor")
97
+
98
+ # first everything before the current line is unchanged.
99
+ if ti.lineno < ti.document.cursor_position_row:
100
+ return noop("noop:before cursor")
101
+
102
+ buffer = ti.buffer_control.buffer
103
+ if not buffer.suggestion or not ti.document.is_cursor_at_the_end_of_line:
104
+ return noop("noop:not eol")
105
+
106
+ delta = ti.lineno - ti.document.cursor_position_row
107
+ suggestions = buffer.suggestion.text.splitlines()
50
108
 
109
+ if len(suggestions) == 0:
110
+ return noop("noop: no suggestions")
111
+
112
+ suggestions_longer_than_buffer: bool = (
113
+ len(suggestions) + ti.document.cursor_position_row > ti.document.line_count
114
+ )
115
+
116
+ if len(suggestions) >= 1 and prompt_toolkit.VERSION < (3, 0, 49):
117
+ if ti.lineno == ti.document.cursor_position_row:
118
+ return Transformation(
119
+ fragments=ti.fragments
120
+ + [
121
+ (
122
+ "red",
123
+ "(Cannot show multiline suggestion; requires prompt_toolkit > 3.0.49)",
124
+ )
125
+ ]
126
+ )
127
+ else:
128
+ return Transformation(fragments=ti.fragments)
129
+ if delta == 0:
130
+ suggestion = suggestions[0]
51
131
  return Transformation(fragments=ti.fragments + [(self.style, suggestion)])
132
+ if is_last_line:
133
+ if delta < len(suggestions):
134
+ extra = f"; {len(suggestions) - delta} line(s) hidden"
135
+ suggestion = f"… rest of suggestion ({len(suggestions) - delta} lines) and code hidden"
136
+ return Transformation([(self.style, suggestion)])
137
+
138
+ n_elided = len(suggestions)
139
+ for i in range(len(suggestions)):
140
+ ll = ti.get_line(last_line_number - i)
141
+ el = "".join(l[1] for l in ll).strip()
142
+ if el:
143
+ break
144
+ else:
145
+ n_elided -= 1
146
+ if n_elided:
147
+ return Transformation([(self.style, f"… {n_elided} line(s) hidden")])
148
+ else:
149
+ return Transformation(
150
+ ti.get_line(last_line_number - len(suggestions) + 1)
151
+ + ([(self.style, "shift-last-line")] if self._debug else [])
152
+ )
153
+
154
+ elif delta < len(suggestions):
155
+ suggestion = suggestions[delta]
156
+ return Transformation([(self.style, suggestion)])
52
157
  else:
53
- return Transformation(fragments=ti.fragments)
158
+ shift = ti.lineno - len(suggestions) + 1
159
+ return Transformation(ti.get_line(shift))
54
160
 
55
161
 
56
162
  class NavigableAutoSuggestFromHistory(AutoSuggestFromHistory):
@@ -60,16 +166,29 @@ class NavigableAutoSuggestFromHistory(AutoSuggestFromHistory):
60
166
  state need to carefully be cleared on the right events.
61
167
  """
62
168
 
63
- def __init__(
64
- self,
65
- ):
169
+ skip_lines: int
170
+ _connected_apps: list[PromptSession]
171
+
172
+ # handle to the currently running llm task that appends suggestions to the
173
+ # current buffer; we keep a handle to it in order to cancell it when there is a cursor movement, or
174
+ # another request.
175
+ _llm_task: asyncio.Task | None = None
176
+
177
+ # This is the instance of the LLM provider from jupyter-ai to which we forward the request
178
+ # to generate inline completions.
179
+ _llm_provider: Any | None
180
+
181
+ def __init__(self):
182
+ super().__init__()
66
183
  self.skip_lines = 0
67
184
  self._connected_apps = []
185
+ self._llm_provider = None
68
186
 
69
187
  def reset_history_position(self, _: Buffer):
70
188
  self.skip_lines = 0
71
189
 
72
- def disconnect(self):
190
+ def disconnect(self) -> None:
191
+ self._cancel_running_llm_task()
73
192
  for pt_app in self._connected_apps:
74
193
  text_insert_event = pt_app.default_buffer.on_text_insert
75
194
  text_insert_event.remove_handler(self.reset_history_position)
@@ -94,7 +213,8 @@ class NavigableAutoSuggestFromHistory(AutoSuggestFromHistory):
94
213
 
95
214
  return None
96
215
 
97
- def _dismiss(self, buffer, *args, **kwargs):
216
+ def _dismiss(self, buffer, *args, **kwargs) -> None:
217
+ self._cancel_running_llm_task()
98
218
  buffer.suggestion = None
99
219
 
100
220
  def _find_match(
@@ -149,6 +269,7 @@ class NavigableAutoSuggestFromHistory(AutoSuggestFromHistory):
149
269
  )
150
270
 
151
271
  def up(self, query: str, other_than: str, history: History) -> None:
272
+ self._cancel_running_llm_task()
152
273
  for suggestion, line_number in self._find_next_match(
153
274
  query, self.skip_lines, history
154
275
  ):
@@ -165,6 +286,7 @@ class NavigableAutoSuggestFromHistory(AutoSuggestFromHistory):
165
286
  self.skip_lines = 0
166
287
 
167
288
  def down(self, query: str, other_than: str, history: History) -> None:
289
+ self._cancel_running_llm_task()
168
290
  for suggestion, line_number in self._find_previous_match(
169
291
  query, self.skip_lines, history
170
292
  ):
@@ -180,6 +302,131 @@ class NavigableAutoSuggestFromHistory(AutoSuggestFromHistory):
180
302
  self.skip_lines = line_number
181
303
  break
182
304
 
305
+ def _cancel_running_llm_task(self) -> None:
306
+ """
307
+ Try to cancell the currently running llm_task if exists, and set it to None.
308
+ """
309
+ if self._llm_task is not None:
310
+ if self._llm_task.done():
311
+ self._llm_task = None
312
+ return
313
+ cancelled = self._llm_task.cancel()
314
+ if cancelled:
315
+ self._llm_task = None
316
+ if not cancelled:
317
+ warnings.warn(
318
+ "LLM task not cancelled, does your provider support cancellation?"
319
+ )
320
+
321
+ async def _trigger_llm(self, buffer) -> None:
322
+ """
323
+ This will ask the current llm provider a suggestion for the current buffer.
324
+
325
+ If there is a currently running llm task, it will cancel it.
326
+ """
327
+ # we likely want to store the current cursor position, and cancel if the cursor has moved.
328
+ if not self._llm_provider:
329
+ warnings.warn("No LLM provider found, cannot trigger LLM completions")
330
+ return
331
+ if jai_models is None:
332
+ warnings.warn(
333
+ "LLM Completion requires `jupyter_ai_magics` and `jupyter_ai` to be installed"
334
+ )
335
+
336
+ self._cancel_running_llm_task()
337
+
338
+ async def error_catcher(buffer):
339
+ """
340
+ This catches and log any errors, as otherwise this is just
341
+ lost in the void of the future running task.
342
+ """
343
+ try:
344
+ await self._trigger_llm_core(buffer)
345
+ except Exception as e:
346
+ get_ipython().log.error("error")
347
+ raise
348
+
349
+ # here we need a cancellable task so we can't just await the error catched
350
+ self._llm_task = asyncio.create_task(error_catcher(buffer))
351
+ await self._llm_task
352
+
353
+ async def _trigger_llm_core(self, buffer: Buffer):
354
+ """
355
+ This is the core of the current llm request.
356
+
357
+ Here we build a compatible `InlineCompletionRequest` and ask the llm
358
+ provider to stream it's response back to us iteratively setting it as
359
+ the suggestion on the current buffer.
360
+
361
+ Unlike with JupyterAi, as we do not have multiple cell, the cell number
362
+ is always set to `0`, note that we _could_ set it to a new number each
363
+ time and ignore threply from past numbers.
364
+
365
+ We set the prefix to the current cell content, but could also inset the
366
+ rest of the history or even just the non-fail history.
367
+
368
+ In the same way, we do not have cell id.
369
+
370
+ LLM provider may return multiple suggestion stream, but for the time
371
+ being we only support one.
372
+
373
+ Here we make the assumption that the provider will have
374
+ stream_inline_completions, I'm not sure it is the case for all
375
+ providers.
376
+ """
377
+
378
+ request = jai_models.InlineCompletionRequest(
379
+ number=0,
380
+ prefix=buffer.document.text,
381
+ suffix="",
382
+ mime="text/x-python",
383
+ stream=True,
384
+ path=None,
385
+ language="python",
386
+ cell_id=None,
387
+ )
388
+
389
+ async for reply_and_chunks in self._llm_provider.stream_inline_completions(
390
+ request
391
+ ):
392
+ if isinstance(reply_and_chunks, jai_models.InlineCompletionReply):
393
+ if len(reply_and_chunks.list.items) > 1:
394
+ raise ValueError(
395
+ "Terminal IPython cannot deal with multiple LLM suggestions at once"
396
+ )
397
+ buffer.suggestion = Suggestion(
398
+ reply_and_chunks.list.items[0].insertText
399
+ )
400
+ buffer.on_suggestion_set.fire()
401
+ elif isinstance(reply_and_chunks, jai_models.InlineCompletionStreamChunk):
402
+ buffer.suggestion = Suggestion(reply_and_chunks.response.insertText)
403
+ buffer.on_suggestion_set.fire()
404
+ return
405
+
406
+
407
+ _MIN_LINES = 5
408
+
409
+
410
+ async def llm_autosuggestion(event: KeyPressEvent):
411
+ """
412
+ Ask the AutoSuggester from history to delegate to ask an LLM for completion
413
+
414
+ This will first make sure that the current buffer have _MIN_LINES (7)
415
+ available lines to insert the LLM completion
416
+
417
+ Provisional as of 8.32, may change without warnigns
418
+
419
+ """
420
+ provider = get_ipython().auto_suggest
421
+ if not isinstance(provider, NavigableAutoSuggestFromHistory):
422
+ return
423
+ doc = event.current_buffer.document
424
+ lines_to_insert = max(0, _MIN_LINES - doc.line_count + doc.cursor_position_row)
425
+ for _ in range(lines_to_insert):
426
+ event.current_buffer.insert_text("\n", move_cursor=False)
427
+
428
+ await provider._trigger_llm(event.current_buffer)
429
+
183
430
 
184
431
  def accept_or_jump_to_end(event: KeyPressEvent):
185
432
  """Apply autosuggestion or jump to end of line."""
@@ -1,2 +1,2 @@
1
1
  # GENERATED BY setup.py
2
- commit = "22d6a1c16"
2
+ commit = "56a70e42d"
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: ipython
3
- Version: 8.31.0
3
+ Version: 8.32.0
4
4
  Summary: IPython: Productive Interactive Computing
5
5
  Author: The IPython Development Team
6
6
  Author-email: ipython-dev@python.org
@@ -85,6 +85,9 @@ Requires-Dist: matplotlib; extra == "matplotlib"
85
85
  Provides-Extra: all
86
86
  Requires-Dist: ipython[black,doc,kernel,matplotlib,nbconvert,nbformat,notebook,parallel,qtconsole]; extra == "all"
87
87
  Requires-Dist: ipython[test,test_extra]; extra == "all"
88
+ Dynamic: author
89
+ Dynamic: author-email
90
+ Dynamic: license
88
91
 
89
92
  IPython provides a rich toolkit to help you make the most out of using Python
90
93
  interactively. Its main components are: