ipython 9.6.0__tar.gz → 9.7.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 (444) hide show
  1. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/completer.py +5 -2
  2. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/guarded_eval.py +406 -22
  3. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/magic.py +143 -117
  4. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/magic_arguments.py +1 -1
  5. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/magics/history.py +24 -7
  6. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/release.py +1 -1
  7. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/shellapp.py +5 -1
  8. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/ultratb.py +5 -2
  9. {ipython-9.6.0 → ipython-9.7.0}/IPython/external/pickleshare.py +8 -66
  10. {ipython-9.6.0 → ipython-9.7.0}/IPython/terminal/interactiveshell.py +1 -1
  11. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/PyColorize.py +35 -0
  12. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/_sysinfo.py +1 -1
  13. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/py3compat.py +0 -10
  14. {ipython-9.6.0 → ipython-9.7.0}/MANIFEST.in +0 -2
  15. {ipython-9.6.0/ipython.egg-info → ipython-9.7.0}/PKG-INFO +23 -23
  16. {ipython-9.6.0 → ipython-9.7.0}/docs/source/config/details.rst +1 -1
  17. ipython-9.7.0/docs/source/whatsnew/development.rst +52 -0
  18. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/version9.rst +59 -0
  19. {ipython-9.6.0 → ipython-9.7.0/ipython.egg-info}/PKG-INFO +23 -23
  20. {ipython-9.6.0 → ipython-9.7.0}/ipython.egg-info/requires.txt +20 -19
  21. {ipython-9.6.0 → ipython-9.7.0}/pyproject.toml +36 -25
  22. {ipython-9.6.0 → ipython-9.7.0}/tests/test_completer.py +495 -5
  23. {ipython-9.6.0 → ipython-9.7.0}/tests/test_guarded_eval.py +19 -0
  24. {ipython-9.6.0 → ipython-9.7.0}/tests/test_interactiveshell.py +12 -9
  25. {ipython-9.6.0 → ipython-9.7.0}/tests/test_magic.py +10 -4
  26. {ipython-9.6.0 → ipython-9.7.0}/tests/test_run.py +5 -0
  27. {ipython-9.6.0 → ipython-9.7.0}/tests/test_ultratb.py +7 -0
  28. ipython-9.6.0/docs/source/whatsnew/development.rst +0 -34
  29. {ipython-9.6.0 → ipython-9.7.0}/.flake8 +0 -0
  30. {ipython-9.6.0 → ipython-9.7.0}/.mailmap +0 -0
  31. {ipython-9.6.0 → ipython-9.7.0}/.pre-commit-config.yaml +0 -0
  32. {ipython-9.6.0 → ipython-9.7.0}/COPYING.rst +0 -0
  33. {ipython-9.6.0 → ipython-9.7.0}/IPython/__init__.py +0 -0
  34. {ipython-9.6.0 → ipython-9.7.0}/IPython/__main__.py +0 -0
  35. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/__init__.py +0 -0
  36. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/alias.py +0 -0
  37. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/application.py +0 -0
  38. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/async_helpers.py +0 -0
  39. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/autocall.py +0 -0
  40. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/builtin_trap.py +0 -0
  41. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/compilerop.py +0 -0
  42. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/completerlib.py +0 -0
  43. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/crashhandler.py +0 -0
  44. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/debugger.py +0 -0
  45. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/debugger_backport.py +0 -0
  46. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/display.py +0 -0
  47. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/display_functions.py +0 -0
  48. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/display_trap.py +0 -0
  49. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/displayhook.py +0 -0
  50. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/displaypub.py +0 -0
  51. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/doctb.py +0 -0
  52. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/error.py +0 -0
  53. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/events.py +0 -0
  54. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/extensions.py +0 -0
  55. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/formatters.py +0 -0
  56. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/getipython.py +0 -0
  57. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/history.py +0 -0
  58. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/historyapp.py +0 -0
  59. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/hooks.py +0 -0
  60. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/inputtransformer2.py +0 -0
  61. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/interactiveshell.py +0 -0
  62. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/latex_symbols.py +0 -0
  63. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/logger.py +0 -0
  64. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/macro.py +0 -0
  65. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/magics/__init__.py +0 -0
  66. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/magics/ast_mod.py +0 -0
  67. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/magics/auto.py +0 -0
  68. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/magics/basic.py +0 -0
  69. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/magics/code.py +0 -0
  70. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/magics/config.py +0 -0
  71. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/magics/display.py +0 -0
  72. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/magics/execution.py +0 -0
  73. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/magics/extension.py +0 -0
  74. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/magics/logging.py +0 -0
  75. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/magics/namespace.py +0 -0
  76. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/magics/osm.py +0 -0
  77. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/magics/packaging.py +0 -0
  78. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/magics/pylab.py +0 -0
  79. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/magics/script.py +0 -0
  80. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/oinspect.py +0 -0
  81. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/page.py +0 -0
  82. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/payload.py +0 -0
  83. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/payloadpage.py +0 -0
  84. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/prefilter.py +0 -0
  85. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/profile/README_STARTUP +0 -0
  86. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/profileapp.py +0 -0
  87. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/profiledir.py +0 -0
  88. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/pylabtools.py +0 -0
  89. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/splitinput.py +0 -0
  90. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/tbtools.py +0 -0
  91. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/tips.py +0 -0
  92. {ipython-9.6.0 → ipython-9.7.0}/IPython/core/usage.py +0 -0
  93. {ipython-9.6.0 → ipython-9.7.0}/IPython/display.py +0 -0
  94. {ipython-9.6.0 → ipython-9.7.0}/IPython/extensions/__init__.py +0 -0
  95. {ipython-9.6.0 → ipython-9.7.0}/IPython/extensions/autoreload.py +0 -0
  96. {ipython-9.6.0 → ipython-9.7.0}/IPython/extensions/deduperreload/__init__.py +0 -0
  97. {ipython-9.6.0 → ipython-9.7.0}/IPython/extensions/deduperreload/deduperreload.py +0 -0
  98. {ipython-9.6.0 → ipython-9.7.0}/IPython/extensions/deduperreload/deduperreload_patching.py +0 -0
  99. {ipython-9.6.0 → ipython-9.7.0}/IPython/extensions/storemagic.py +0 -0
  100. {ipython-9.6.0 → ipython-9.7.0}/IPython/extensions/tests/test_deduperreload.py +0 -0
  101. {ipython-9.6.0 → ipython-9.7.0}/IPython/external/__init__.py +0 -0
  102. {ipython-9.6.0 → ipython-9.7.0}/IPython/external/qt_for_kernel.py +0 -0
  103. {ipython-9.6.0 → ipython-9.7.0}/IPython/external/qt_loaders.py +0 -0
  104. {ipython-9.6.0 → ipython-9.7.0}/IPython/lib/__init__.py +0 -0
  105. {ipython-9.6.0 → ipython-9.7.0}/IPython/lib/backgroundjobs.py +0 -0
  106. {ipython-9.6.0 → ipython-9.7.0}/IPython/lib/clipboard.py +0 -0
  107. {ipython-9.6.0 → ipython-9.7.0}/IPython/lib/deepreload.py +0 -0
  108. {ipython-9.6.0 → ipython-9.7.0}/IPython/lib/demo.py +0 -0
  109. {ipython-9.6.0 → ipython-9.7.0}/IPython/lib/display.py +0 -0
  110. {ipython-9.6.0 → ipython-9.7.0}/IPython/lib/editorhooks.py +0 -0
  111. {ipython-9.6.0 → ipython-9.7.0}/IPython/lib/guisupport.py +0 -0
  112. {ipython-9.6.0 → ipython-9.7.0}/IPython/lib/latextools.py +0 -0
  113. {ipython-9.6.0 → ipython-9.7.0}/IPython/lib/lexers.py +0 -0
  114. {ipython-9.6.0 → ipython-9.7.0}/IPython/lib/pretty.py +0 -0
  115. {ipython-9.6.0 → ipython-9.7.0}/IPython/paths.py +0 -0
  116. {ipython-9.6.0 → ipython-9.7.0}/IPython/py.typed +0 -0
  117. {ipython-9.6.0 → ipython-9.7.0}/IPython/sphinxext/__init__.py +0 -0
  118. {ipython-9.6.0 → ipython-9.7.0}/IPython/sphinxext/custom_doctests.py +0 -0
  119. {ipython-9.6.0 → ipython-9.7.0}/IPython/sphinxext/ipython_console_highlighting.py +0 -0
  120. {ipython-9.6.0 → ipython-9.7.0}/IPython/sphinxext/ipython_directive.py +0 -0
  121. {ipython-9.6.0 → ipython-9.7.0}/IPython/terminal/__init__.py +0 -0
  122. {ipython-9.6.0 → ipython-9.7.0}/IPython/terminal/debugger.py +0 -0
  123. {ipython-9.6.0 → ipython-9.7.0}/IPython/terminal/embed.py +0 -0
  124. {ipython-9.6.0 → ipython-9.7.0}/IPython/terminal/ipapp.py +0 -0
  125. {ipython-9.6.0 → ipython-9.7.0}/IPython/terminal/magics.py +0 -0
  126. {ipython-9.6.0 → ipython-9.7.0}/IPython/terminal/prompts.py +0 -0
  127. {ipython-9.6.0 → ipython-9.7.0}/IPython/terminal/pt_inputhooks/__init__.py +0 -0
  128. {ipython-9.6.0 → ipython-9.7.0}/IPython/terminal/pt_inputhooks/asyncio.py +0 -0
  129. {ipython-9.6.0 → ipython-9.7.0}/IPython/terminal/pt_inputhooks/glut.py +0 -0
  130. {ipython-9.6.0 → ipython-9.7.0}/IPython/terminal/pt_inputhooks/gtk.py +0 -0
  131. {ipython-9.6.0 → ipython-9.7.0}/IPython/terminal/pt_inputhooks/gtk3.py +0 -0
  132. {ipython-9.6.0 → ipython-9.7.0}/IPython/terminal/pt_inputhooks/gtk4.py +0 -0
  133. {ipython-9.6.0 → ipython-9.7.0}/IPython/terminal/pt_inputhooks/osx.py +0 -0
  134. {ipython-9.6.0 → ipython-9.7.0}/IPython/terminal/pt_inputhooks/pyglet.py +0 -0
  135. {ipython-9.6.0 → ipython-9.7.0}/IPython/terminal/pt_inputhooks/qt.py +0 -0
  136. {ipython-9.6.0 → ipython-9.7.0}/IPython/terminal/pt_inputhooks/tk.py +0 -0
  137. {ipython-9.6.0 → ipython-9.7.0}/IPython/terminal/pt_inputhooks/wx.py +0 -0
  138. {ipython-9.6.0 → ipython-9.7.0}/IPython/terminal/ptutils.py +0 -0
  139. {ipython-9.6.0 → ipython-9.7.0}/IPython/terminal/shortcuts/__init__.py +0 -0
  140. {ipython-9.6.0 → ipython-9.7.0}/IPython/terminal/shortcuts/auto_match.py +0 -0
  141. {ipython-9.6.0 → ipython-9.7.0}/IPython/terminal/shortcuts/auto_suggest.py +0 -0
  142. {ipython-9.6.0 → ipython-9.7.0}/IPython/terminal/shortcuts/filters.py +0 -0
  143. {ipython-9.6.0 → ipython-9.7.0}/IPython/testing/__init__.py +0 -0
  144. {ipython-9.6.0 → ipython-9.7.0}/IPython/testing/decorators.py +0 -0
  145. {ipython-9.6.0 → ipython-9.7.0}/IPython/testing/globalipapp.py +0 -0
  146. {ipython-9.6.0 → ipython-9.7.0}/IPython/testing/ipunittest.py +0 -0
  147. {ipython-9.6.0 → ipython-9.7.0}/IPython/testing/plugin/Makefile +0 -0
  148. {ipython-9.6.0 → ipython-9.7.0}/IPython/testing/plugin/__init__.py +0 -0
  149. {ipython-9.6.0 → ipython-9.7.0}/IPython/testing/plugin/dtexample.py +0 -0
  150. {ipython-9.6.0 → ipython-9.7.0}/IPython/testing/plugin/ipdoctest.py +0 -0
  151. {ipython-9.6.0 → ipython-9.7.0}/IPython/testing/plugin/pytest_ipdoctest.py +0 -0
  152. {ipython-9.6.0 → ipython-9.7.0}/IPython/testing/plugin/setup.py +0 -0
  153. {ipython-9.6.0 → ipython-9.7.0}/IPython/testing/plugin/simple.py +0 -0
  154. {ipython-9.6.0 → ipython-9.7.0}/IPython/testing/plugin/simplevars.py +0 -0
  155. {ipython-9.6.0 → ipython-9.7.0}/IPython/testing/plugin/test_combo.txt +0 -0
  156. {ipython-9.6.0 → ipython-9.7.0}/IPython/testing/plugin/test_example.txt +0 -0
  157. {ipython-9.6.0 → ipython-9.7.0}/IPython/testing/plugin/test_exampleip.txt +0 -0
  158. {ipython-9.6.0 → ipython-9.7.0}/IPython/testing/plugin/test_ipdoctest.py +0 -0
  159. {ipython-9.6.0 → ipython-9.7.0}/IPython/testing/plugin/test_refs.py +0 -0
  160. {ipython-9.6.0 → ipython-9.7.0}/IPython/testing/skipdoctest.py +0 -0
  161. {ipython-9.6.0 → ipython-9.7.0}/IPython/testing/tools.py +0 -0
  162. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/__init__.py +0 -0
  163. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/_process_cli.py +0 -0
  164. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/_process_common.py +0 -0
  165. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/_process_emscripten.py +0 -0
  166. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/_process_posix.py +0 -0
  167. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/_process_win32.py +0 -0
  168. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/_process_win32_controller.py +0 -0
  169. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/capture.py +0 -0
  170. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/coloransi.py +0 -0
  171. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/contexts.py +0 -0
  172. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/data.py +0 -0
  173. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/decorators.py +0 -0
  174. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/dir2.py +0 -0
  175. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/docs.py +0 -0
  176. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/encoding.py +0 -0
  177. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/eventful.py +0 -0
  178. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/frame.py +0 -0
  179. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/generics.py +0 -0
  180. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/importstring.py +0 -0
  181. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/io.py +0 -0
  182. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/ipstruct.py +0 -0
  183. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/jsonutil.py +0 -0
  184. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/log.py +0 -0
  185. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/module_paths.py +0 -0
  186. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/openpy.py +0 -0
  187. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/path.py +0 -0
  188. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/process.py +0 -0
  189. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/sentinel.py +0 -0
  190. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/strdispatch.py +0 -0
  191. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/sysinfo.py +0 -0
  192. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/syspathcontext.py +0 -0
  193. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/tempdir.py +0 -0
  194. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/terminal.py +0 -0
  195. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/text.py +0 -0
  196. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/timing.py +0 -0
  197. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/tokenutil.py +0 -0
  198. {ipython-9.6.0 → ipython-9.7.0}/IPython/utils/wildcard.py +0 -0
  199. {ipython-9.6.0 → ipython-9.7.0}/LICENSE +0 -0
  200. {ipython-9.6.0 → ipython-9.7.0}/README.rst +0 -0
  201. {ipython-9.6.0 → ipython-9.7.0}/_build_meta.py +0 -0
  202. {ipython-9.6.0 → ipython-9.7.0}/docs/Makefile +0 -0
  203. {ipython-9.6.0 → ipython-9.7.0}/docs/README.rst +0 -0
  204. {ipython-9.6.0 → ipython-9.7.0}/docs/autogen_api.py +0 -0
  205. {ipython-9.6.0 → ipython-9.7.0}/docs/autogen_config.py +0 -0
  206. {ipython-9.6.0 → ipython-9.7.0}/docs/autogen_magics.py +0 -0
  207. {ipython-9.6.0 → ipython-9.7.0}/docs/autogen_shortcuts.py +0 -0
  208. {ipython-9.6.0 → ipython-9.7.0}/docs/make.cmd +0 -0
  209. {ipython-9.6.0 → ipython-9.7.0}/docs/man/ipython.1 +0 -0
  210. {ipython-9.6.0 → ipython-9.7.0}/docs/requirements.txt +0 -0
  211. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/2.0/running-crop.png +0 -0
  212. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/2.0/running.png +0 -0
  213. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/2.0/treeview.png +0 -0
  214. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/2.0/user-interface.png +0 -0
  215. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/2.0/widgets.png +0 -0
  216. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/8.0/auto_suggest_1_prompt_no_text.png +0 -0
  217. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/8.0/auto_suggest_2_print_hello_suggest.png +0 -0
  218. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/8.0/auto_suggest_3_print_hello_suggest.png +0 -0
  219. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/8.0/auto_suggest_4_print_hello.png +0 -0
  220. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/8.0/auto_suggest_d_completions.png +0 -0
  221. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/8.0/auto_suggest_d_phantom.png +0 -0
  222. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/8.0/auto_suggest_def_completions.png +0 -0
  223. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/8.0/auto_suggest_def_phantom.png +0 -0
  224. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/8.0/auto_suggest_match_parens.png +0 -0
  225. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/8.0/auto_suggest_second_prompt.png +0 -0
  226. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/8.0/pathlib_pathlib_everywhere.jpg +0 -0
  227. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/autosuggest.gif +0 -0
  228. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/ipy_013_dashboard.png +0 -0
  229. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/ipy_013_dashboard_cluster.png +0 -0
  230. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/ipy_013_notebook_cythonmagic.png +0 -0
  231. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/ipy_013_notebook_long_out.png +0 -0
  232. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/ipy_013_notebook_octavemagic.png +0 -0
  233. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/ipy_013_notebook_rmagic.png +0 -0
  234. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/ipy_013_notebook_script_cells.png +0 -0
  235. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/ipy_013_notebook_spectrogram.png +0 -0
  236. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/ipy_013_notebook_tooltip.png +0 -0
  237. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/ipy_013_par_tb.png +0 -0
  238. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/ipy_013_qtconsole_baboon.png +0 -0
  239. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/ipy_013_qtconsole_completer.png +0 -0
  240. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/ipython-6-screenshot.png +0 -0
  241. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/jedi_type_inference_60.png +0 -0
  242. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/kernel_selector_screenshot.png +0 -0
  243. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/ms_visual_studio.png +0 -0
  244. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/notebook_specgram.png +0 -0
  245. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/ptshell_features.png +0 -0
  246. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/qtconsole.png +0 -0
  247. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/qtconsole_tabbed.png +0 -0
  248. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_images/unicode_completion.png +0 -0
  249. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_static/favicon.ico +0 -0
  250. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_static/logo.png +0 -0
  251. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_static/theme_overrides.css +0 -0
  252. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_templates/breadcrumbs.html +0 -0
  253. {ipython-9.6.0 → ipython-9.7.0}/docs/source/_templates/notebook_redirect.html +0 -0
  254. {ipython-9.6.0 → ipython-9.7.0}/docs/source/about/history.rst +0 -0
  255. {ipython-9.6.0 → ipython-9.7.0}/docs/source/about/index.rst +0 -0
  256. {ipython-9.6.0 → ipython-9.7.0}/docs/source/about/license_and_copyright.rst +0 -0
  257. {ipython-9.6.0 → ipython-9.7.0}/docs/source/api/index.rst +0 -0
  258. {ipython-9.6.0 → ipython-9.7.0}/docs/source/conf.py +0 -0
  259. {ipython-9.6.0 → ipython-9.7.0}/docs/source/config/callbacks.rst +0 -0
  260. {ipython-9.6.0 → ipython-9.7.0}/docs/source/config/custommagics.rst +0 -0
  261. {ipython-9.6.0 → ipython-9.7.0}/docs/source/config/eventloops.rst +0 -0
  262. {ipython-9.6.0 → ipython-9.7.0}/docs/source/config/extensions/autoreload.rst +0 -0
  263. {ipython-9.6.0 → ipython-9.7.0}/docs/source/config/extensions/index.rst +0 -0
  264. {ipython-9.6.0 → ipython-9.7.0}/docs/source/config/extensions/storemagic.rst +0 -0
  265. {ipython-9.6.0 → ipython-9.7.0}/docs/source/config/index.rst +0 -0
  266. {ipython-9.6.0 → ipython-9.7.0}/docs/source/config/inputtransforms.rst +0 -0
  267. {ipython-9.6.0 → ipython-9.7.0}/docs/source/config/integrating.rst +0 -0
  268. {ipython-9.6.0 → ipython-9.7.0}/docs/source/config/intro.rst +0 -0
  269. {ipython-9.6.0 → ipython-9.7.0}/docs/source/config/options/index.rst +0 -0
  270. {ipython-9.6.0 → ipython-9.7.0}/docs/source/config/shell_mimerenderer.rst +0 -0
  271. {ipython-9.6.0 → ipython-9.7.0}/docs/source/config/shortcuts/index.rst +0 -0
  272. {ipython-9.6.0 → ipython-9.7.0}/docs/source/coredev/index.rst +0 -0
  273. {ipython-9.6.0 → ipython-9.7.0}/docs/source/development/config.rst +0 -0
  274. {ipython-9.6.0 → ipython-9.7.0}/docs/source/development/execution.rst +0 -0
  275. {ipython-9.6.0 → ipython-9.7.0}/docs/source/development/figs/ipy_kernel_and_terminal.png +0 -0
  276. {ipython-9.6.0 → ipython-9.7.0}/docs/source/development/figs/ipy_kernel_and_terminal.svg +0 -0
  277. {ipython-9.6.0 → ipython-9.7.0}/docs/source/development/figs/other_kernels.png +0 -0
  278. {ipython-9.6.0 → ipython-9.7.0}/docs/source/development/figs/other_kernels.svg +0 -0
  279. {ipython-9.6.0 → ipython-9.7.0}/docs/source/development/how_ipython_works.rst +0 -0
  280. {ipython-9.6.0 → ipython-9.7.0}/docs/source/development/index.rst +0 -0
  281. {ipython-9.6.0 → ipython-9.7.0}/docs/source/development/inputhook_app.rst +0 -0
  282. {ipython-9.6.0 → ipython-9.7.0}/docs/source/development/kernels.rst +0 -0
  283. {ipython-9.6.0 → ipython-9.7.0}/docs/source/development/messaging.rst +0 -0
  284. {ipython-9.6.0 → ipython-9.7.0}/docs/source/development/pycompat.rst +0 -0
  285. {ipython-9.6.0 → ipython-9.7.0}/docs/source/development/wrapperkernels.rst +0 -0
  286. {ipython-9.6.0 → ipython-9.7.0}/docs/source/index.rst +0 -0
  287. {ipython-9.6.0 → ipython-9.7.0}/docs/source/install/index.rst +0 -0
  288. {ipython-9.6.0 → ipython-9.7.0}/docs/source/install/install.rst +0 -0
  289. {ipython-9.6.0 → ipython-9.7.0}/docs/source/install/kernel_install.rst +0 -0
  290. {ipython-9.6.0 → ipython-9.7.0}/docs/source/interactive/autoawait.rst +0 -0
  291. {ipython-9.6.0 → ipython-9.7.0}/docs/source/interactive/index.rst +0 -0
  292. {ipython-9.6.0 → ipython-9.7.0}/docs/source/interactive/magics.rst +0 -0
  293. {ipython-9.6.0 → ipython-9.7.0}/docs/source/interactive/plotting.rst +0 -0
  294. {ipython-9.6.0 → ipython-9.7.0}/docs/source/interactive/python-ipython-diff.rst +0 -0
  295. {ipython-9.6.0 → ipython-9.7.0}/docs/source/interactive/reference.rst +0 -0
  296. {ipython-9.6.0 → ipython-9.7.0}/docs/source/interactive/shell.rst +0 -0
  297. {ipython-9.6.0 → ipython-9.7.0}/docs/source/interactive/tips.rst +0 -0
  298. {ipython-9.6.0 → ipython-9.7.0}/docs/source/interactive/tutorial.rst +0 -0
  299. {ipython-9.6.0 → ipython-9.7.0}/docs/source/links.txt +0 -0
  300. {ipython-9.6.0 → ipython-9.7.0}/docs/source/overview.rst +0 -0
  301. {ipython-9.6.0 → ipython-9.7.0}/docs/source/parallel/index.rst +0 -0
  302. {ipython-9.6.0 → ipython-9.7.0}/docs/source/sphinx.toml +0 -0
  303. {ipython-9.6.0 → ipython-9.7.0}/docs/source/sphinxext.rst +0 -0
  304. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/github-stats-0.11.rst +0 -0
  305. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/github-stats-0.12.rst +0 -0
  306. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/github-stats-0.13.rst +0 -0
  307. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/github-stats-1.0.rst +0 -0
  308. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/github-stats-2.0.rst +0 -0
  309. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/github-stats-3.rst +0 -0
  310. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/github-stats-4.rst +0 -0
  311. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/github-stats-5.rst +0 -0
  312. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/github-stats-6.rst +0 -0
  313. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/github-stats-7.rst +0 -0
  314. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/github-stats-8.rst +0 -0
  315. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/index.rst +0 -0
  316. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/pr/README.md +0 -0
  317. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/pr/antigravity-feature.rst +0 -0
  318. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/pr/incompat-switching-to-perl.rst +0 -0
  319. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/version0.10.rst +0 -0
  320. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/version0.11.rst +0 -0
  321. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/version0.12.rst +0 -0
  322. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/version0.13.rst +0 -0
  323. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/version0.8.rst +0 -0
  324. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/version0.9.rst +0 -0
  325. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/version1.0.rst +0 -0
  326. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/version2.0.rst +0 -0
  327. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/version3.rst +0 -0
  328. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/version3_widget_migration.rst +0 -0
  329. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/version4.rst +0 -0
  330. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/version5.rst +0 -0
  331. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/version6.rst +0 -0
  332. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/version7.rst +0 -0
  333. {ipython-9.6.0 → ipython-9.7.0}/docs/source/whatsnew/version8.rst +0 -0
  334. {ipython-9.6.0 → ipython-9.7.0}/docs/sphinxext/apigen.py +0 -0
  335. {ipython-9.6.0 → ipython-9.7.0}/docs/sphinxext/configtraits.py +0 -0
  336. {ipython-9.6.0 → ipython-9.7.0}/docs/sphinxext/github.py +0 -0
  337. {ipython-9.6.0 → ipython-9.7.0}/docs/sphinxext/magics.py +0 -0
  338. {ipython-9.6.0 → ipython-9.7.0}/examples/Embedding/embed_class_long.py +0 -0
  339. {ipython-9.6.0 → ipython-9.7.0}/examples/Embedding/embed_class_short.py +0 -0
  340. {ipython-9.6.0 → ipython-9.7.0}/examples/Embedding/embed_function.py +0 -0
  341. {ipython-9.6.0 → ipython-9.7.0}/examples/Embedding/start_ipython_config.py +0 -0
  342. {ipython-9.6.0 → ipython-9.7.0}/examples/IPython Kernel/example-demo.py +0 -0
  343. {ipython-9.6.0 → ipython-9.7.0}/examples/IPython Kernel/gui/gui-glut.py +0 -0
  344. {ipython-9.6.0 → ipython-9.7.0}/examples/IPython Kernel/gui/gui-gtk4.py +0 -0
  345. {ipython-9.6.0 → ipython-9.7.0}/examples/IPython Kernel/gui/gui-qt.py +0 -0
  346. {ipython-9.6.0 → ipython-9.7.0}/examples/IPython Kernel/ipython-completion.bash +0 -0
  347. {ipython-9.6.0 → ipython-9.7.0}/examples/IPython Kernel/ipython-get-history.py +0 -0
  348. {ipython-9.6.0 → ipython-9.7.0}/examples/IPython Kernel/ipython.desktop +0 -0
  349. {ipython-9.6.0 → ipython-9.7.0}/examples/auto_suggest_llm.py +0 -0
  350. {ipython-9.6.0 → ipython-9.7.0}/examples/utils/cwd_prompt.py +0 -0
  351. {ipython-9.6.0 → ipython-9.7.0}/examples/utils/list_pyfiles.ipy +0 -0
  352. {ipython-9.6.0 → ipython-9.7.0}/examples/utils/list_subdirs.ipy +0 -0
  353. {ipython-9.6.0 → ipython-9.7.0}/ipython.egg-info/SOURCES.txt +0 -0
  354. {ipython-9.6.0 → ipython-9.7.0}/ipython.egg-info/dependency_links.txt +0 -0
  355. {ipython-9.6.0 → ipython-9.7.0}/ipython.egg-info/entry_points.txt +0 -0
  356. {ipython-9.6.0 → ipython-9.7.0}/ipython.egg-info/not-zip-safe +0 -0
  357. {ipython-9.6.0 → ipython-9.7.0}/ipython.egg-info/top_level.txt +0 -0
  358. {ipython-9.6.0 → ipython-9.7.0}/long_description.rst +0 -0
  359. {ipython-9.6.0 → ipython-9.7.0}/scripts/ipython.ico +0 -0
  360. {ipython-9.6.0 → ipython-9.7.0}/scripts/ipython_nb.ico +0 -0
  361. {ipython-9.6.0 → ipython-9.7.0}/setup.cfg +0 -0
  362. {ipython-9.6.0 → ipython-9.7.0}/setup.py +0 -0
  363. {ipython-9.6.0 → ipython-9.7.0}/setupbase.py +0 -0
  364. {ipython-9.6.0 → ipython-9.7.0}/tests/2x2.jpg +0 -0
  365. {ipython-9.6.0 → ipython-9.7.0}/tests/2x2.png +0 -0
  366. {ipython-9.6.0 → ipython-9.7.0}/tests/__init__.py +0 -0
  367. {ipython-9.6.0 → ipython-9.7.0}/tests/bad_all.py +0 -0
  368. {ipython-9.6.0 → ipython-9.7.0}/tests/conftest.py +0 -0
  369. {ipython-9.6.0 → ipython-9.7.0}/tests/cve.py +0 -0
  370. {ipython-9.6.0 → ipython-9.7.0}/tests/fake_ext_dir/daft_extension.py +0 -0
  371. {ipython-9.6.0 → ipython-9.7.0}/tests/fake_llm.py +0 -0
  372. {ipython-9.6.0 → ipython-9.7.0}/tests/nonascii.py +0 -0
  373. {ipython-9.6.0 → ipython-9.7.0}/tests/nonascii2.py +0 -0
  374. {ipython-9.6.0 → ipython-9.7.0}/tests/print_argv.py +0 -0
  375. {ipython-9.6.0 → ipython-9.7.0}/tests/refbug.py +0 -0
  376. {ipython-9.6.0 → ipython-9.7.0}/tests/simpleerr.py +0 -0
  377. {ipython-9.6.0 → ipython-9.7.0}/tests/tclass.py +0 -0
  378. {ipython-9.6.0 → ipython-9.7.0}/tests/test.wav +0 -0
  379. {ipython-9.6.0 → ipython-9.7.0}/tests/test_alias.py +0 -0
  380. {ipython-9.6.0 → ipython-9.7.0}/tests/test_application.py +0 -0
  381. {ipython-9.6.0 → ipython-9.7.0}/tests/test_async_helpers.py +0 -0
  382. {ipython-9.6.0 → ipython-9.7.0}/tests/test_autocall.py +0 -0
  383. {ipython-9.6.0 → ipython-9.7.0}/tests/test_backgroundjobs.py +0 -0
  384. {ipython-9.6.0 → ipython-9.7.0}/tests/test_capture.py +0 -0
  385. {ipython-9.6.0 → ipython-9.7.0}/tests/test_clipboard.py +0 -0
  386. {ipython-9.6.0 → ipython-9.7.0}/tests/test_compilerop.py +0 -0
  387. {ipython-9.6.0 → ipython-9.7.0}/tests/test_completerlib.py +0 -0
  388. {ipython-9.6.0 → ipython-9.7.0}/tests/test_debug_magic.py +0 -0
  389. {ipython-9.6.0 → ipython-9.7.0}/tests/test_debugger.py +0 -0
  390. {ipython-9.6.0 → ipython-9.7.0}/tests/test_decorators.py +0 -0
  391. {ipython-9.6.0 → ipython-9.7.0}/tests/test_decorators_2.py +0 -0
  392. {ipython-9.6.0 → ipython-9.7.0}/tests/test_deepreload.py +0 -0
  393. {ipython-9.6.0 → ipython-9.7.0}/tests/test_dir2.py +0 -0
  394. {ipython-9.6.0 → ipython-9.7.0}/tests/test_display.py +0 -0
  395. {ipython-9.6.0 → ipython-9.7.0}/tests/test_display_2.py +0 -0
  396. {ipython-9.6.0 → ipython-9.7.0}/tests/test_displayhook.py +0 -0
  397. {ipython-9.6.0 → ipython-9.7.0}/tests/test_editorhooks.py +0 -0
  398. {ipython-9.6.0 → ipython-9.7.0}/tests/test_embed.py +0 -0
  399. {ipython-9.6.0 → ipython-9.7.0}/tests/test_events.py +0 -0
  400. {ipython-9.6.0 → ipython-9.7.0}/tests/test_exceptiongroup_tb.py +0 -0
  401. {ipython-9.6.0 → ipython-9.7.0}/tests/test_extension.py +0 -0
  402. {ipython-9.6.0 → ipython-9.7.0}/tests/test_formatters.py +0 -0
  403. {ipython-9.6.0 → ipython-9.7.0}/tests/test_handlers.py +0 -0
  404. {ipython-9.6.0 → ipython-9.7.0}/tests/test_help.py +0 -0
  405. {ipython-9.6.0 → ipython-9.7.0}/tests/test_history.py +0 -0
  406. {ipython-9.6.0 → ipython-9.7.0}/tests/test_hooks.py +0 -0
  407. {ipython-9.6.0 → ipython-9.7.0}/tests/test_imports.py +0 -0
  408. {ipython-9.6.0 → ipython-9.7.0}/tests/test_importstring.py +0 -0
  409. {ipython-9.6.0 → ipython-9.7.0}/tests/test_inputtransformer2.py +0 -0
  410. {ipython-9.6.0 → ipython-9.7.0}/tests/test_inputtransformer2_line.py +0 -0
  411. {ipython-9.6.0 → ipython-9.7.0}/tests/test_interactivshell.py +0 -0
  412. {ipython-9.6.0 → ipython-9.7.0}/tests/test_io.py +0 -0
  413. {ipython-9.6.0 → ipython-9.7.0}/tests/test_iplib.py +0 -0
  414. {ipython-9.6.0 → ipython-9.7.0}/tests/test_ipunittest.py +0 -0
  415. {ipython-9.6.0 → ipython-9.7.0}/tests/test_latextools.py +0 -0
  416. {ipython-9.6.0 → ipython-9.7.0}/tests/test_logger.py +0 -0
  417. {ipython-9.6.0 → ipython-9.7.0}/tests/test_magic_arguments.py +0 -0
  418. {ipython-9.6.0 → ipython-9.7.0}/tests/test_magic_terminal.py +0 -0
  419. {ipython-9.6.0 → ipython-9.7.0}/tests/test_module_paths.py +0 -0
  420. {ipython-9.6.0 → ipython-9.7.0}/tests/test_oinspect.py +0 -0
  421. {ipython-9.6.0 → ipython-9.7.0}/tests/test_openpy.py +0 -0
  422. {ipython-9.6.0 → ipython-9.7.0}/tests/test_page.py +0 -0
  423. {ipython-9.6.0 → ipython-9.7.0}/tests/test_path.py +0 -0
  424. {ipython-9.6.0 → ipython-9.7.0}/tests/test_paths.py +0 -0
  425. {ipython-9.6.0 → ipython-9.7.0}/tests/test_prefilter.py +0 -0
  426. {ipython-9.6.0 → ipython-9.7.0}/tests/test_pretty.py +0 -0
  427. {ipython-9.6.0 → ipython-9.7.0}/tests/test_process.py +0 -0
  428. {ipython-9.6.0 → ipython-9.7.0}/tests/test_profile.py +0 -0
  429. {ipython-9.6.0 → ipython-9.7.0}/tests/test_pt_inputhooks.py +0 -0
  430. {ipython-9.6.0 → ipython-9.7.0}/tests/test_pycolorize.py +0 -0
  431. {ipython-9.6.0 → ipython-9.7.0}/tests/test_pylabtools.py +0 -0
  432. {ipython-9.6.0 → ipython-9.7.0}/tests/test_qt_loaders.py +0 -0
  433. {ipython-9.6.0 → ipython-9.7.0}/tests/test_shellapp.py +0 -0
  434. {ipython-9.6.0 → ipython-9.7.0}/tests/test_shortcuts.py +0 -0
  435. {ipython-9.6.0 → ipython-9.7.0}/tests/test_splitinput.py +0 -0
  436. {ipython-9.6.0 → ipython-9.7.0}/tests/test_storemagic.py +0 -0
  437. {ipython-9.6.0 → ipython-9.7.0}/tests/test_sysinfo.py +0 -0
  438. {ipython-9.6.0 → ipython-9.7.0}/tests/test_tempdir.py +0 -0
  439. {ipython-9.6.0 → ipython-9.7.0}/tests/test_text.py +0 -0
  440. {ipython-9.6.0 → ipython-9.7.0}/tests/test_tips.py +0 -0
  441. {ipython-9.6.0 → ipython-9.7.0}/tests/test_tokenutil.py +0 -0
  442. {ipython-9.6.0 → ipython-9.7.0}/tests/test_tools.py +0 -0
  443. {ipython-9.6.0 → ipython-9.7.0}/tests/test_wildcard.py +0 -0
  444. {ipython-9.6.0 → ipython-9.7.0}/tests/test_zzz_autoreload.py +0 -0
@@ -2481,7 +2481,7 @@ class IPCompleter(Completer):
2481
2481
  return {
2482
2482
  "completions": matches,
2483
2483
  # static analysis should not suppress other matchers
2484
- "suppress": False,
2484
+ "suppress": {_get_matcher_id(self.file_matcher)} if matches else False,
2485
2485
  }
2486
2486
 
2487
2487
  def _jedi_matches(
@@ -2741,9 +2741,12 @@ class IPCompleter(Completer):
2741
2741
  is None
2742
2742
  )
2743
2743
  matches = filter(no__name, matches)
2744
- return _convert_matcher_v1_result_to_v2(
2744
+ matches = _convert_matcher_v1_result_to_v2(
2745
2745
  matches, type="attribute", fragment=fragment
2746
2746
  )
2747
+ if matches["completions"]:
2748
+ matches["suppress"] = {_get_matcher_id(self.file_matcher)}
2749
+ return matches
2747
2750
  except NameError:
2748
2751
  # catches <undefined attributes>.<tab>
2749
2752
  return SimpleMatcherResult(completions=[], suppress=False)
@@ -165,7 +165,10 @@ def _has_original_dunder_external(
165
165
  value_module = getmodule(value_type)
166
166
  if not value_module or not value_module.__name__:
167
167
  return False
168
- if value_module.__name__.startswith(member_type.__name__):
168
+ if (
169
+ value_module.__name__ == member_type.__name__
170
+ or value_module.__name__.startswith(member_type.__name__ + ".")
171
+ ):
169
172
  return True
170
173
  if method_name == "__getattribute__":
171
174
  # we have to short-circuit here due to an unresolved issue in
@@ -176,6 +179,18 @@ def _has_original_dunder_external(
176
179
  member_method = getattr(member_type, method_name, None)
177
180
  if member_method == method:
178
181
  return True
182
+ if isinstance(member_type, ModuleType):
183
+ method = getattr(value_type, method_name, None)
184
+ for base_class in value_type.__mro__[1:]:
185
+ base_module = getmodule(base_class)
186
+ if base_module and (
187
+ base_module.__name__ == member_type.__name__
188
+ or base_module.__name__.startswith(member_type.__name__ + ".")
189
+ ):
190
+ # Check if the method comes from this trusted base class
191
+ base_method = getattr(base_class, method_name, None)
192
+ if base_method is not None and base_method == method:
193
+ return True
179
194
  except (AttributeError, KeyError):
180
195
  return False
181
196
 
@@ -381,6 +396,10 @@ class EvaluationContext:
381
396
  policy_overrides: dict = field(default_factory=dict)
382
397
  #: Transient local namespace used to store mocks
383
398
  transient_locals: dict = field(default_factory=dict)
399
+ #: Transients of class level
400
+ class_transients: dict | None = None
401
+ #: Instance variable name used in the method definition
402
+ instance_arg_name: str | None = None
384
403
 
385
404
  def replace(self, /, **changes):
386
405
  """Return a new copy of the context, with specified changes"""
@@ -545,6 +564,8 @@ def _validate_policy_overrides(
545
564
  def _handle_assign(node: ast.Assign, context: EvaluationContext):
546
565
  value = eval_node(node.value, context)
547
566
  transient_locals = context.transient_locals
567
+ policy = get_policy(context)
568
+ class_transients = context.class_transients
548
569
  for target in node.targets:
549
570
  if isinstance(target, (ast.Tuple, ast.List)):
550
571
  # Handle unpacking assignment
@@ -557,20 +578,81 @@ def _handle_assign(node: ast.Assign, context: EvaluationContext):
557
578
 
558
579
  # Before starred
559
580
  for i in range(star_or_last_idx):
560
- transient_locals[targets[i].id] = values[i]
581
+ # Check for self.x assignment
582
+ if _is_instance_attribute_assignment(targets[i], context):
583
+ class_transients[targets[i].attr] = values[i]
584
+ else:
585
+ transient_locals[targets[i].id] = values[i]
561
586
 
562
587
  # Starred if exists
563
588
  if starred:
564
589
  end = len(values) - (len(targets) - star_or_last_idx - 1)
565
- transient_locals[targets[star_or_last_idx].value.id] = values[
566
- star_or_last_idx:end
567
- ]
590
+ if _is_instance_attribute_assignment(
591
+ targets[star_or_last_idx], context
592
+ ):
593
+ class_transients[targets[star_or_last_idx].attr] = values[
594
+ star_or_last_idx:end
595
+ ]
596
+ else:
597
+ transient_locals[targets[star_or_last_idx].value.id] = values[
598
+ star_or_last_idx:end
599
+ ]
568
600
 
569
601
  # After starred
570
602
  for i in range(star_or_last_idx + 1, len(targets)):
571
- transient_locals[targets[i].id] = values[
572
- len(values) - (len(targets) - i)
573
- ]
603
+ if _is_instance_attribute_assignment(targets[i], context):
604
+ class_transients[targets[i].attr] = values[
605
+ len(values) - (len(targets) - i)
606
+ ]
607
+ else:
608
+ transient_locals[targets[i].id] = values[
609
+ len(values) - (len(targets) - i)
610
+ ]
611
+ elif isinstance(target, ast.Subscript):
612
+ if isinstance(target.value, ast.Name):
613
+ name = target.value.id
614
+ container = transient_locals.get(name)
615
+ if container is None:
616
+ container = context.locals.get(name)
617
+ if container is None:
618
+ container = context.globals.get(name)
619
+ if container is None:
620
+ raise NameError(
621
+ f"{name} not found in locals, globals, nor builtins"
622
+ )
623
+ storage_dict = transient_locals
624
+ storage_key = name
625
+ elif isinstance(
626
+ target.value, ast.Attribute
627
+ ) and _is_instance_attribute_assignment(target.value, context):
628
+ attr = target.value.attr
629
+ container = class_transients.get(attr, None)
630
+ if container is None:
631
+ raise NameError(f"{attr} not found in class transients")
632
+ storage_dict = class_transients
633
+ storage_key = attr
634
+ else:
635
+ return
636
+
637
+ key = eval_node(target.slice, context)
638
+ attributes = (
639
+ dict.fromkeys(dir(container))
640
+ if policy.can_call(container.__dir__)
641
+ else {}
642
+ )
643
+ items = {}
644
+
645
+ if policy.can_get_item(container, None):
646
+ try:
647
+ items = dict(container.items())
648
+ except Exception:
649
+ pass
650
+
651
+ items[key] = value
652
+ duck_container = _Duck(attributes=attributes, items=items)
653
+ storage_dict[storage_key] = duck_container
654
+ elif _is_instance_attribute_assignment(target, context):
655
+ class_transients[target.attr] = value
574
656
  else:
575
657
  transient_locals[target.id] = value
576
658
  return None
@@ -590,6 +672,30 @@ def _extract_args_and_kwargs(node: ast.Call, context: EvaluationContext):
590
672
  return args, kwargs
591
673
 
592
674
 
675
+ def _is_instance_attribute_assignment(
676
+ target: ast.AST, context: EvaluationContext
677
+ ) -> bool:
678
+ """Return True if target is an attribute access on the instance argument."""
679
+ return (
680
+ context.class_transients is not None
681
+ and context.instance_arg_name is not None
682
+ and isinstance(target, ast.Attribute)
683
+ and isinstance(getattr(target, "value", None), ast.Name)
684
+ and getattr(target.value, "id", None) == context.instance_arg_name
685
+ )
686
+
687
+
688
+ def _get_coroutine_attributes() -> dict[str, Optional[object]]:
689
+ async def _dummy():
690
+ return None
691
+
692
+ coro = _dummy()
693
+ try:
694
+ return {attr: getattr(coro, attr, None) for attr in dir(coro)}
695
+ finally:
696
+ coro.close()
697
+
698
+
593
699
  def eval_node(node: Union[ast.AST, None], context: EvaluationContext):
594
700
  """Evaluate AST node in provided context.
595
701
 
@@ -626,10 +732,13 @@ def eval_node(node: Union[ast.AST, None], context: EvaluationContext):
626
732
  for child_node in node.body:
627
733
  result = eval_node(child_node, context)
628
734
  return result
629
- if isinstance(node, ast.FunctionDef):
630
- # we ignore body and only extract the return type
735
+ if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
736
+ is_async = isinstance(node, ast.AsyncFunctionDef)
737
+ func_locals = context.transient_locals.copy()
738
+ func_context = context.replace(transient_locals=func_locals)
631
739
  is_property = False
632
-
740
+ is_static = False
741
+ is_classmethod = False
633
742
  for decorator_node in node.decorator_list:
634
743
  try:
635
744
  decorator = eval_node(decorator_node, context)
@@ -639,42 +748,165 @@ def eval_node(node: Union[ast.AST, None], context: EvaluationContext):
639
748
  continue
640
749
  if decorator is property:
641
750
  is_property = True
751
+ elif decorator is staticmethod:
752
+ is_static = True
753
+ elif decorator is classmethod:
754
+ is_classmethod = True
755
+
756
+ if func_context.class_transients is not None:
757
+ if not is_static and not is_classmethod:
758
+ func_context.instance_arg_name = (
759
+ node.args.args[0].arg if node.args.args else None
760
+ )
642
761
 
643
762
  return_type = eval_node(node.returns, context=context)
644
763
 
764
+ for child_node in node.body:
765
+ eval_node(child_node, func_context)
766
+
645
767
  if is_property:
646
- context.transient_locals[node.name] = _resolve_annotation(
647
- return_type, context
648
- )
768
+ if return_type is not None:
769
+ context.transient_locals[node.name] = _resolve_annotation(
770
+ return_type, context
771
+ )
772
+ else:
773
+ return_value = _infer_return_value(node, func_context)
774
+ context.transient_locals[node.name] = return_value
775
+
649
776
  return None
650
777
 
651
778
  def dummy_function(*args, **kwargs):
652
779
  pass
653
780
 
654
- dummy_function.__annotations__["return"] = return_type
781
+ if return_type is not None:
782
+ dummy_function.__annotations__["return"] = return_type
783
+ else:
784
+ inferred_return = _infer_return_value(node, func_context)
785
+ if inferred_return is not None:
786
+ dummy_function.__inferred_return__ = inferred_return
787
+
655
788
  dummy_function.__name__ = node.name
656
789
  dummy_function.__node__ = node
790
+ dummy_function.__is_async__ = is_async
657
791
  context.transient_locals[node.name] = dummy_function
658
792
  return None
793
+ if isinstance(node, ast.Lambda):
794
+
795
+ def dummy_function(*args, **kwargs):
796
+ pass
797
+
798
+ dummy_function.__inferred_return__ = eval_node(node.body, context)
799
+ return dummy_function
659
800
  if isinstance(node, ast.ClassDef):
660
801
  # TODO support class decorators?
661
802
  class_locals = {}
662
- class_context = context.replace(transient_locals=class_locals)
803
+ outer_locals = context.locals.copy()
804
+ outer_locals.update(context.transient_locals)
805
+ class_context = context.replace(
806
+ transient_locals=class_locals, locals=outer_locals
807
+ )
808
+ class_context.class_transients = class_locals
663
809
  for child_node in node.body:
664
810
  eval_node(child_node, class_context)
665
811
  bases = tuple([eval_node(base, context) for base in node.bases])
666
812
  dummy_class = type(node.name, bases, class_locals)
667
813
  context.transient_locals[node.name] = dummy_class
668
814
  return None
815
+ if isinstance(node, ast.Await):
816
+ value = eval_node(node.value, context)
817
+ if hasattr(value, "__awaited_type__"):
818
+ return value.__awaited_type__
819
+ return value
820
+ if isinstance(node, ast.While):
821
+ loop_locals = context.transient_locals.copy()
822
+ loop_context = context.replace(transient_locals=loop_locals)
823
+
824
+ result = None
825
+ for stmt in node.body:
826
+ result = eval_node(stmt, loop_context)
827
+
828
+ policy = get_policy(context)
829
+ merged_locals = _merge_dicts_by_key(
830
+ [loop_locals, context.transient_locals.copy()], policy
831
+ )
832
+ context.transient_locals.update(merged_locals)
833
+
834
+ return result
835
+ if isinstance(node, ast.For):
836
+ try:
837
+ iterable = eval_node(node.iter, context)
838
+ except Exception:
839
+ iterable = None
840
+
841
+ sample = None
842
+ if iterable is not None:
843
+ try:
844
+ if policy.can_call(getattr(iterable, "__iter__", None)):
845
+ sample = next(iter(iterable))
846
+ except Exception:
847
+ sample = None
848
+
849
+ loop_locals = context.transient_locals.copy()
850
+ loop_context = context.replace(transient_locals=loop_locals)
851
+
852
+ if sample is not None:
853
+ try:
854
+ fake_assign = ast.Assign(
855
+ targets=[node.target], value=ast.Constant(value=sample)
856
+ )
857
+ _handle_assign(fake_assign, loop_context)
858
+ except Exception:
859
+ pass
860
+
861
+ result = None
862
+ for stmt in node.body:
863
+ result = eval_node(stmt, loop_context)
864
+
865
+ policy = get_policy(context)
866
+ merged_locals = _merge_dicts_by_key(
867
+ [loop_locals, context.transient_locals.copy()], policy
868
+ )
869
+ context.transient_locals.update(merged_locals)
870
+
871
+ return result
872
+ if isinstance(node, ast.If):
873
+ branches = []
874
+ current = node
875
+ result = None
876
+ while True:
877
+ branch_locals = context.transient_locals.copy()
878
+ branch_context = context.replace(transient_locals=branch_locals)
879
+ for stmt in current.body:
880
+ result = eval_node(stmt, branch_context)
881
+ branches.append(branch_locals)
882
+ if not current.orelse:
883
+ break
884
+ elif len(current.orelse) == 1 and isinstance(current.orelse[0], ast.If):
885
+ # It's an elif - continue loop
886
+ current = current.orelse[0]
887
+ else:
888
+ # It's an else block - process and break
889
+ else_locals = context.transient_locals.copy()
890
+ else_context = context.replace(transient_locals=else_locals)
891
+ for stmt in current.orelse:
892
+ result = eval_node(stmt, else_context)
893
+ branches.append(else_locals)
894
+ break
895
+ branches.append(context.transient_locals.copy())
896
+ policy = get_policy(context)
897
+ merged_locals = _merge_dicts_by_key(branches, policy)
898
+ context.transient_locals.update(merged_locals)
899
+ return result
669
900
  if isinstance(node, ast.Assign):
670
901
  return _handle_assign(node, context)
671
902
  if isinstance(node, ast.AnnAssign):
672
- if not node.simple:
673
- # for now only handle simple annotations
674
- return None
675
- context.transient_locals[node.target.id] = _resolve_annotation(
676
- eval_node(node.annotation, context), context
677
- )
903
+ if node.simple:
904
+ value = _resolve_annotation(eval_node(node.annotation, context), context)
905
+ context.transient_locals[node.target.id] = value
906
+ # Handle non-simple annotated assignments only for self.x: type = value
907
+ if _is_instance_attribute_assignment(node.target, context):
908
+ value = _resolve_annotation(eval_node(node.annotation, context), context)
909
+ context.class_transients[node.target.attr] = value
678
910
  return None
679
911
  if isinstance(node, ast.Expression):
680
912
  return eval_node(node.body, context)
@@ -792,6 +1024,12 @@ def eval_node(node: Union[ast.AST, None], context: EvaluationContext):
792
1024
  if isinstance(node, ast.Name):
793
1025
  return _eval_node_name(node.id, context)
794
1026
  if isinstance(node, ast.Attribute):
1027
+ if (
1028
+ context.class_transients is not None
1029
+ and isinstance(node.value, ast.Name)
1030
+ and node.value.id == context.instance_arg_name
1031
+ ):
1032
+ return context.class_transients.get(node.attr)
795
1033
  value = eval_node(node.value, context)
796
1034
  if policy.can_get_attr(value, node.attr):
797
1035
  return getattr(value, node.attr)
@@ -821,7 +1059,17 @@ def eval_node(node: Union[ast.AST, None], context: EvaluationContext):
821
1059
  return overridden_return_type
822
1060
  return _create_duck_for_heap_type(func)
823
1061
  else:
1062
+ inferred_return = getattr(func, "__inferred_return__", NOT_EVALUATED)
824
1063
  return_type = _eval_return_type(func, node, context)
1064
+ if getattr(func, "__is_async__", False):
1065
+ awaited_type = (
1066
+ inferred_return if inferred_return is not None else return_type
1067
+ )
1068
+ coroutine_duck = _Duck(attributes=_get_coroutine_attributes())
1069
+ coroutine_duck.__awaited_type__ = awaited_type
1070
+ return coroutine_duck
1071
+ if inferred_return is not NOT_EVALUATED:
1072
+ return inferred_return
825
1073
  if return_type is not NOT_EVALUATED:
826
1074
  return return_type
827
1075
  raise GuardRejection(
@@ -838,6 +1086,119 @@ def eval_node(node: Union[ast.AST, None], context: EvaluationContext):
838
1086
  return None
839
1087
 
840
1088
 
1089
+ def _merge_dicts_by_key(dicts: list, policy: EvaluationPolicy):
1090
+ """Merge multiple dictionaries, combining values for each key."""
1091
+ if len(dicts) == 1:
1092
+ return dicts[0]
1093
+
1094
+ all_keys = set()
1095
+ for d in dicts:
1096
+ all_keys.update(d.keys())
1097
+
1098
+ merged = {}
1099
+ for key in all_keys:
1100
+ values = [d[key] for d in dicts if key in d]
1101
+ if values:
1102
+ merged[key] = _merge_values(values, policy)
1103
+
1104
+ return merged
1105
+
1106
+
1107
+ def _merge_values(values, policy: EvaluationPolicy):
1108
+ """Recursively merge multiple values, combining attributes and dict items."""
1109
+ if len(values) == 1:
1110
+ return values[0]
1111
+
1112
+ types = {type(v) for v in values}
1113
+ merged_items = None
1114
+ key_values = {}
1115
+ attributes = set()
1116
+ for v in values:
1117
+ if policy.can_call(v.__dir__):
1118
+ attributes.update(dir(v))
1119
+ try:
1120
+ if policy.can_call(v.items):
1121
+ try:
1122
+ for k, val in v.items():
1123
+ key_values.setdefault(k, []).append(val)
1124
+ except Exception as e:
1125
+ pass
1126
+ elif policy.can_call(v.keys):
1127
+ try:
1128
+ for k in v.keys():
1129
+ key_values.setdefault(k, []).append(None)
1130
+ except Exception as e:
1131
+ pass
1132
+ except Exception as e:
1133
+ pass
1134
+
1135
+ if key_values:
1136
+ merged_items = {
1137
+ k: _merge_values(vals, policy) if vals[0] is not None else None
1138
+ for k, vals in key_values.items()
1139
+ }
1140
+
1141
+ if len(types) == 1:
1142
+ t = next(iter(types))
1143
+ if t not in (dict,) and not (
1144
+ hasattr(next(iter(values)), "__getitem__")
1145
+ and (
1146
+ hasattr(next(iter(values)), "items")
1147
+ or hasattr(next(iter(values)), "keys")
1148
+ )
1149
+ ):
1150
+ if t in (list, set, tuple):
1151
+ return t
1152
+ return values[0]
1153
+
1154
+ return _Duck(attributes=dict.fromkeys(attributes), items=merged_items)
1155
+
1156
+
1157
+ def _infer_return_value(node: ast.FunctionDef, context: EvaluationContext):
1158
+ """Infer the return value(s) of a function by evaluating all return statements."""
1159
+ return_values = _collect_return_values(node.body, context)
1160
+
1161
+ if not return_values:
1162
+ return None
1163
+ if len(return_values) == 1:
1164
+ return return_values[0]
1165
+
1166
+ policy = get_policy(context)
1167
+ return _merge_values(return_values, policy)
1168
+
1169
+
1170
+ def _collect_return_values(body, context):
1171
+ """Recursively collect return values from a list of AST statements."""
1172
+ return_values = []
1173
+ for stmt in body:
1174
+ if isinstance(stmt, ast.Return):
1175
+ if stmt.value is None:
1176
+ continue
1177
+ try:
1178
+ value = eval_node(stmt.value, context)
1179
+ if value is not None and value is not NOT_EVALUATED:
1180
+ return_values.append(value)
1181
+ except Exception:
1182
+ pass
1183
+ if isinstance(
1184
+ stmt, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef, ast.Lambda)
1185
+ ):
1186
+ continue
1187
+ elif hasattr(stmt, "body") and isinstance(stmt.body, list):
1188
+ return_values.extend(_collect_return_values(stmt.body, context))
1189
+ if isinstance(stmt, ast.Try):
1190
+ for h in stmt.handlers:
1191
+ if hasattr(h, "body"):
1192
+ return_values.extend(_collect_return_values(h.body, context))
1193
+ if hasattr(stmt, "orelse"):
1194
+ return_values.extend(_collect_return_values(stmt.orelse, context))
1195
+ if hasattr(stmt, "finalbody"):
1196
+ return_values.extend(_collect_return_values(stmt.finalbody, context))
1197
+ if hasattr(stmt, "orelse") and isinstance(stmt.orelse, list):
1198
+ return_values.extend(_collect_return_values(stmt.orelse, context))
1199
+ return return_values
1200
+
1201
+
841
1202
  def _eval_return_type(func: Callable, node: ast.Call, context: EvaluationContext):
842
1203
  """Evaluate return type of a given callable function.
843
1204
 
@@ -1063,46 +1424,69 @@ set_non_mutating_methods = set(dir(set)) & set(dir(frozenset))
1063
1424
 
1064
1425
 
1065
1426
  dict_keys: type[collections.abc.KeysView] = type({}.keys())
1427
+ dict_values: type = type({}.values())
1428
+ dict_items: type = type({}.items())
1066
1429
 
1067
1430
  NUMERICS = {int, float, complex}
1068
1431
 
1069
1432
  ALLOWED_CALLS = {
1070
1433
  bytes,
1071
1434
  *_list_methods(bytes),
1435
+ bytes.__iter__,
1072
1436
  dict,
1073
1437
  *_list_methods(dict, dict_non_mutating_methods),
1438
+ dict.__iter__,
1439
+ dict_keys.__iter__,
1440
+ dict_values.__iter__,
1441
+ dict_items.__iter__,
1074
1442
  dict_keys.isdisjoint,
1075
1443
  list,
1076
1444
  *_list_methods(list, list_non_mutating_methods),
1445
+ list.__iter__,
1077
1446
  set,
1078
1447
  *_list_methods(set, set_non_mutating_methods),
1448
+ set.__iter__,
1079
1449
  frozenset,
1080
1450
  *_list_methods(frozenset),
1451
+ frozenset.__iter__,
1081
1452
  range,
1453
+ range.__iter__,
1082
1454
  str,
1083
1455
  *_list_methods(str),
1456
+ str.__iter__,
1084
1457
  tuple,
1085
1458
  *_list_methods(tuple),
1459
+ tuple.__iter__,
1086
1460
  bool,
1087
1461
  *_list_methods(bool),
1088
1462
  *NUMERICS,
1089
1463
  *[method for numeric_cls in NUMERICS for method in _list_methods(numeric_cls)],
1090
1464
  collections.deque,
1091
1465
  *_list_methods(collections.deque, list_non_mutating_methods),
1466
+ collections.deque.__iter__,
1092
1467
  collections.defaultdict,
1093
1468
  *_list_methods(collections.defaultdict, dict_non_mutating_methods),
1469
+ collections.defaultdict.__iter__,
1094
1470
  collections.OrderedDict,
1095
1471
  *_list_methods(collections.OrderedDict, dict_non_mutating_methods),
1472
+ collections.OrderedDict.__iter__,
1096
1473
  collections.UserDict,
1097
1474
  *_list_methods(collections.UserDict, dict_non_mutating_methods),
1475
+ collections.UserDict.__iter__,
1098
1476
  collections.UserList,
1099
1477
  *_list_methods(collections.UserList, list_non_mutating_methods),
1478
+ collections.UserList.__iter__,
1100
1479
  collections.UserString,
1101
1480
  *_list_methods(collections.UserString, dir(str)),
1481
+ collections.UserString.__iter__,
1102
1482
  collections.Counter,
1103
1483
  *_list_methods(collections.Counter, dict_non_mutating_methods),
1484
+ collections.Counter.__iter__,
1104
1485
  collections.Counter.elements,
1105
1486
  collections.Counter.most_common,
1487
+ object.__dir__,
1488
+ type.__dir__,
1489
+ _Duck.__dir__,
1106
1490
  }
1107
1491
 
1108
1492
  BUILTIN_GETATTR: set[MayHaveGetattr] = {