ipython 9.7.0__tar.gz → 9.8.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.
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/completer.py +73 -24
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/debugger.py +6 -1
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/display_functions.py +1 -1
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/displayhook.py +2 -2
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/displaypub.py +1 -1
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/doctb.py +2 -1
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/events.py +26 -12
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/formatters.py +1 -1
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/guarded_eval.py +124 -20
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/history.py +26 -15
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/interactiveshell.py +24 -22
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/magics/execution.py +3 -8
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/magics/history.py +6 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/oinspect.py +0 -1
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/pylabtools.py +3 -4
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/release.py +1 -1
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/tbtools.py +2 -1
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/ultratb.py +7 -2
- {ipython-9.7.0 → ipython-9.8.0}/IPython/extensions/deduperreload/deduperreload.py +2 -1
- {ipython-9.7.0 → ipython-9.8.0}/IPython/extensions/deduperreload/deduperreload_patching.py +0 -1
- {ipython-9.7.0 → ipython-9.8.0}/IPython/lib/display.py +2 -1
- {ipython-9.7.0 → ipython-9.8.0}/IPython/lib/pretty.py +1 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/terminal/prompts.py +1 -1
- {ipython-9.7.0 → ipython-9.8.0}/IPython/terminal/pt_inputhooks/__init__.py +2 -1
- {ipython-9.7.0 → ipython-9.8.0}/IPython/terminal/shortcuts/__init__.py +2 -1
- {ipython-9.7.0 → ipython-9.8.0}/IPython/terminal/shortcuts/auto_suggest.py +2 -1
- {ipython-9.7.0 → ipython-9.8.0}/IPython/terminal/shortcuts/filters.py +2 -1
- {ipython-9.7.0 → ipython-9.8.0}/IPython/testing/decorators.py +0 -1
- {ipython-9.7.0 → ipython-9.8.0}/IPython/testing/plugin/pytest_ipdoctest.py +2 -5
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/PyColorize.py +43 -23
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/_process_common.py +2 -1
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/_sysinfo.py +1 -1
- ipython-9.8.0/IPython/utils/data.py +50 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/decorators.py +1 -1
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/encoding.py +7 -4
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/generics.py +6 -2
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/importstring.py +3 -1
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/module_paths.py +8 -2
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/sentinel.py +2 -2
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/syspathcontext.py +18 -3
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/text.py +5 -8
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/tokenutil.py +2 -1
- {ipython-9.7.0/ipython.egg-info → ipython-9.8.0}/PKG-INFO +1 -1
- {ipython-9.7.0 → ipython-9.8.0}/README.rst +3 -15
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/conf.py +0 -13
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/config/custommagics.rst +2 -6
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/config/eventloops.rst +6 -2
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/config/extensions/index.rst +1 -1
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/config/integrating.rst +1 -1
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/index.rst +1 -1
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/install/install.rst +3 -31
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/interactive/autoawait.rst +11 -12
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/interactive/plotting.rst +6 -8
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/interactive/reference.rst +4 -4
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/interactive/shell.rst +2 -2
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/interactive/tutorial.rst +9 -9
- ipython-9.8.0/docs/source/links.txt +97 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/overview.rst +1 -5
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/sphinx.toml +3 -1
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/sphinxext.rst +3 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/development.rst +1 -1
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/index.rst +5 -11
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/version1.0.rst +1 -1
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/version2.0.rst +0 -2
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/version3.rst +2 -2
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/version5.rst +1 -1
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/version6.rst +4 -4
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/version9.rst +89 -4
- {ipython-9.7.0 → ipython-9.8.0}/examples/auto_suggest_llm.py +2 -1
- {ipython-9.7.0 → ipython-9.8.0/ipython.egg-info}/PKG-INFO +1 -1
- {ipython-9.7.0 → ipython-9.8.0}/ipython.egg-info/SOURCES.txt +0 -1
- {ipython-9.7.0 → ipython-9.8.0}/pyproject.toml +15 -26
- {ipython-9.7.0 → ipython-9.8.0}/tests/fake_llm.py +0 -1
- {ipython-9.7.0 → ipython-9.8.0}/tests/refbug.py +0 -1
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_completer.py +180 -6
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_display.py +0 -1
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_display_2.py +0 -1
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_events.py +4 -2
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_formatters.py +2 -3
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_guarded_eval.py +38 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_history.py +57 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_interactiveshell.py +0 -6
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_io.py +0 -2
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_path.py +0 -2
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_pretty.py +0 -1
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_run.py +0 -3
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_ultratb.py +0 -1
- ipython-9.7.0/IPython/utils/data.py +0 -30
- ipython-9.7.0/docs/source/development/pycompat.rst +0 -32
- ipython-9.7.0/docs/source/links.txt +0 -97
- {ipython-9.7.0 → ipython-9.8.0}/.flake8 +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/.mailmap +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/.pre-commit-config.yaml +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/COPYING.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/__init__.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/__main__.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/__init__.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/alias.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/application.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/async_helpers.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/autocall.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/builtin_trap.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/compilerop.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/completerlib.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/crashhandler.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/debugger_backport.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/display.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/display_trap.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/error.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/extensions.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/getipython.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/historyapp.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/hooks.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/inputtransformer2.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/latex_symbols.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/logger.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/macro.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/magic.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/magic_arguments.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/magics/__init__.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/magics/ast_mod.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/magics/auto.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/magics/basic.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/magics/code.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/magics/config.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/magics/display.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/magics/extension.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/magics/logging.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/magics/namespace.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/magics/osm.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/magics/packaging.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/magics/pylab.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/magics/script.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/page.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/payload.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/payloadpage.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/prefilter.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/profile/README_STARTUP +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/profileapp.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/profiledir.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/shellapp.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/splitinput.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/tips.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/core/usage.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/display.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/extensions/__init__.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/extensions/autoreload.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/extensions/deduperreload/__init__.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/extensions/storemagic.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/extensions/tests/test_deduperreload.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/external/__init__.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/external/pickleshare.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/external/qt_for_kernel.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/external/qt_loaders.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/lib/__init__.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/lib/backgroundjobs.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/lib/clipboard.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/lib/deepreload.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/lib/demo.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/lib/editorhooks.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/lib/guisupport.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/lib/latextools.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/lib/lexers.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/paths.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/py.typed +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/sphinxext/__init__.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/sphinxext/custom_doctests.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/sphinxext/ipython_console_highlighting.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/sphinxext/ipython_directive.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/terminal/__init__.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/terminal/debugger.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/terminal/embed.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/terminal/interactiveshell.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/terminal/ipapp.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/terminal/magics.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/terminal/pt_inputhooks/asyncio.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/terminal/pt_inputhooks/glut.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/terminal/pt_inputhooks/gtk.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/terminal/pt_inputhooks/gtk3.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/terminal/pt_inputhooks/gtk4.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/terminal/pt_inputhooks/osx.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/terminal/pt_inputhooks/pyglet.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/terminal/pt_inputhooks/qt.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/terminal/pt_inputhooks/tk.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/terminal/pt_inputhooks/wx.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/terminal/ptutils.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/terminal/shortcuts/auto_match.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/testing/__init__.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/testing/globalipapp.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/testing/ipunittest.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/testing/plugin/Makefile +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/testing/plugin/__init__.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/testing/plugin/dtexample.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/testing/plugin/ipdoctest.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/testing/plugin/setup.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/testing/plugin/simple.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/testing/plugin/simplevars.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/testing/plugin/test_combo.txt +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/testing/plugin/test_example.txt +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/testing/plugin/test_exampleip.txt +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/testing/plugin/test_ipdoctest.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/testing/plugin/test_refs.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/testing/skipdoctest.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/testing/tools.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/__init__.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/_process_cli.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/_process_emscripten.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/_process_posix.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/_process_win32.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/_process_win32_controller.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/capture.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/coloransi.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/contexts.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/dir2.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/docs.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/eventful.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/frame.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/io.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/ipstruct.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/jsonutil.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/log.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/openpy.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/path.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/process.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/py3compat.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/strdispatch.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/sysinfo.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/tempdir.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/terminal.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/timing.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/IPython/utils/wildcard.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/LICENSE +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/MANIFEST.in +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/_build_meta.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/Makefile +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/README.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/autogen_api.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/autogen_config.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/autogen_magics.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/autogen_shortcuts.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/make.cmd +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/man/ipython.1 +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/requirements.txt +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/2.0/running-crop.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/2.0/running.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/2.0/treeview.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/2.0/user-interface.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/2.0/widgets.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/8.0/auto_suggest_1_prompt_no_text.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/8.0/auto_suggest_2_print_hello_suggest.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/8.0/auto_suggest_3_print_hello_suggest.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/8.0/auto_suggest_4_print_hello.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/8.0/auto_suggest_d_completions.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/8.0/auto_suggest_d_phantom.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/8.0/auto_suggest_def_completions.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/8.0/auto_suggest_def_phantom.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/8.0/auto_suggest_match_parens.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/8.0/auto_suggest_second_prompt.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/8.0/pathlib_pathlib_everywhere.jpg +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/autosuggest.gif +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/ipy_013_dashboard.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/ipy_013_dashboard_cluster.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/ipy_013_notebook_cythonmagic.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/ipy_013_notebook_long_out.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/ipy_013_notebook_octavemagic.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/ipy_013_notebook_rmagic.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/ipy_013_notebook_script_cells.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/ipy_013_notebook_spectrogram.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/ipy_013_notebook_tooltip.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/ipy_013_par_tb.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/ipy_013_qtconsole_baboon.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/ipy_013_qtconsole_completer.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/ipython-6-screenshot.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/jedi_type_inference_60.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/kernel_selector_screenshot.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/ms_visual_studio.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/notebook_specgram.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/ptshell_features.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/qtconsole.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/qtconsole_tabbed.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_images/unicode_completion.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_static/favicon.ico +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_static/logo.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_static/theme_overrides.css +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_templates/breadcrumbs.html +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/_templates/notebook_redirect.html +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/about/history.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/about/index.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/about/license_and_copyright.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/api/index.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/config/callbacks.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/config/details.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/config/extensions/autoreload.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/config/extensions/storemagic.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/config/index.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/config/inputtransforms.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/config/intro.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/config/options/index.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/config/shell_mimerenderer.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/config/shortcuts/index.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/coredev/index.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/development/config.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/development/execution.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/development/figs/ipy_kernel_and_terminal.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/development/figs/ipy_kernel_and_terminal.svg +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/development/figs/other_kernels.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/development/figs/other_kernels.svg +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/development/how_ipython_works.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/development/index.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/development/inputhook_app.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/development/kernels.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/development/messaging.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/development/wrapperkernels.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/install/index.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/install/kernel_install.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/interactive/index.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/interactive/magics.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/interactive/python-ipython-diff.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/interactive/tips.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/parallel/index.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/github-stats-0.11.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/github-stats-0.12.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/github-stats-0.13.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/github-stats-1.0.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/github-stats-2.0.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/github-stats-3.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/github-stats-4.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/github-stats-5.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/github-stats-6.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/github-stats-7.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/github-stats-8.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/pr/README.md +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/pr/antigravity-feature.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/pr/incompat-switching-to-perl.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/version0.10.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/version0.11.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/version0.12.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/version0.13.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/version0.8.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/version0.9.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/version3_widget_migration.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/version4.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/version7.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/source/whatsnew/version8.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/sphinxext/apigen.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/sphinxext/configtraits.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/sphinxext/github.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/docs/sphinxext/magics.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/examples/Embedding/embed_class_long.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/examples/Embedding/embed_class_short.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/examples/Embedding/embed_function.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/examples/Embedding/start_ipython_config.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/examples/IPython Kernel/example-demo.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/examples/IPython Kernel/gui/gui-glut.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/examples/IPython Kernel/gui/gui-gtk4.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/examples/IPython Kernel/gui/gui-qt.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/examples/IPython Kernel/ipython-completion.bash +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/examples/IPython Kernel/ipython-get-history.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/examples/IPython Kernel/ipython.desktop +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/examples/utils/cwd_prompt.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/examples/utils/list_pyfiles.ipy +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/examples/utils/list_subdirs.ipy +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/ipython.egg-info/dependency_links.txt +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/ipython.egg-info/entry_points.txt +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/ipython.egg-info/not-zip-safe +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/ipython.egg-info/requires.txt +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/ipython.egg-info/top_level.txt +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/long_description.rst +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/scripts/ipython.ico +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/scripts/ipython_nb.ico +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/setup.cfg +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/setup.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/setupbase.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/2x2.jpg +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/2x2.png +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/__init__.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/bad_all.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/conftest.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/cve.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/fake_ext_dir/daft_extension.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/nonascii.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/nonascii2.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/print_argv.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/simpleerr.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/tclass.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test.wav +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_alias.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_application.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_async_helpers.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_autocall.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_backgroundjobs.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_capture.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_clipboard.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_compilerop.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_completerlib.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_debug_magic.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_debugger.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_decorators.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_decorators_2.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_deepreload.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_dir2.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_displayhook.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_editorhooks.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_embed.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_exceptiongroup_tb.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_extension.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_handlers.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_help.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_hooks.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_imports.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_importstring.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_inputtransformer2.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_inputtransformer2_line.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_interactivshell.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_iplib.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_ipunittest.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_latextools.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_logger.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_magic.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_magic_arguments.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_magic_terminal.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_module_paths.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_oinspect.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_openpy.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_page.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_paths.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_prefilter.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_process.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_profile.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_pt_inputhooks.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_pycolorize.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_pylabtools.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_qt_loaders.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_shellapp.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_shortcuts.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_splitinput.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_storemagic.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_sysinfo.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_tempdir.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_text.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_tips.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_tokenutil.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_tools.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_wildcard.py +0 -0
- {ipython-9.7.0 → ipython-9.8.0}/tests/test_zzz_autoreload.py +0 -0
|
@@ -85,9 +85,9 @@ You will find that the following are experimental:
|
|
|
85
85
|
|
|
86
86
|
We welcome any feedback on these new API, and we also encourage you to try this
|
|
87
87
|
module in debug mode (start IPython with ``--Completer.debug=True``) in order
|
|
88
|
-
to have extra logging information if :
|
|
88
|
+
to have extra logging information if :mod:`jedi` is crashing, or if current
|
|
89
89
|
IPython completer pending deprecations are returning results not yet handled
|
|
90
|
-
by :
|
|
90
|
+
by :mod:`jedi`
|
|
91
91
|
|
|
92
92
|
Using Jedi for tab completion allow snippets like the following to work without
|
|
93
93
|
having to execute any code:
|
|
@@ -99,7 +99,7 @@ Tab completion will be able to infer that ``myvar[1]`` is a real number without
|
|
|
99
99
|
executing almost any code unlike the deprecated :any:`IPCompleter.greedy`
|
|
100
100
|
option.
|
|
101
101
|
|
|
102
|
-
Be sure to update :
|
|
102
|
+
Be sure to update :mod:`jedi` to the latest stable version or to try the
|
|
103
103
|
current development version to get better completions.
|
|
104
104
|
|
|
105
105
|
Matchers
|
|
@@ -149,7 +149,7 @@ More precisely, the API allows to omit ``matcher_api_version`` for v1 Matchers,
|
|
|
149
149
|
and requires a literal ``2`` for v2 Matchers.
|
|
150
150
|
|
|
151
151
|
Once the API stabilises future versions may relax the requirement for specifying
|
|
152
|
-
``matcher_api_version`` by switching to :
|
|
152
|
+
``matcher_api_version`` by switching to :func:`functools.singledispatch`, therefore
|
|
153
153
|
please do not rely on the presence of ``matcher_api_version`` for any purposes.
|
|
154
154
|
|
|
155
155
|
Suppression of competing matchers
|
|
@@ -201,17 +201,14 @@ from dataclasses import dataclass
|
|
|
201
201
|
from functools import cached_property, partial
|
|
202
202
|
from types import SimpleNamespace
|
|
203
203
|
from typing import (
|
|
204
|
-
Iterable,
|
|
205
|
-
Iterator,
|
|
206
204
|
Union,
|
|
207
205
|
Any,
|
|
208
|
-
Sequence,
|
|
209
206
|
Optional,
|
|
210
207
|
TYPE_CHECKING,
|
|
211
|
-
Sized,
|
|
212
208
|
TypeVar,
|
|
213
209
|
Literal,
|
|
214
210
|
)
|
|
211
|
+
from collections.abc import Iterable, Iterator, Sequence, Sized
|
|
215
212
|
|
|
216
213
|
from IPython.core.guarded_eval import (
|
|
217
214
|
guarded_eval,
|
|
@@ -247,7 +244,8 @@ import __main__
|
|
|
247
244
|
from typing import cast
|
|
248
245
|
|
|
249
246
|
if sys.version_info < (3, 12):
|
|
250
|
-
from typing_extensions import TypedDict,
|
|
247
|
+
from typing_extensions import TypedDict, Protocol
|
|
248
|
+
from typing import NotRequired, TypeAlias, TypeGuard
|
|
251
249
|
else:
|
|
252
250
|
from typing import TypedDict, NotRequired, Protocol, TypeAlias, TypeGuard
|
|
253
251
|
|
|
@@ -489,7 +487,7 @@ class Completion:
|
|
|
489
487
|
It will also raise unless use in proper context manager.
|
|
490
488
|
|
|
491
489
|
This act as a middle ground :any:`Completion` object between the
|
|
492
|
-
:
|
|
490
|
+
:class:`jedi.api.classes.Completion` object and the Prompt Toolkit completion
|
|
493
491
|
object. While Jedi need a lot of information about evaluator and how the
|
|
494
492
|
code should be ran/inspected, PromptToolkit (and other frontend) mostly
|
|
495
493
|
need user facing information.
|
|
@@ -860,7 +858,7 @@ def rectify_completions(text: str, completions: _IC, *, _debug: bool = False) ->
|
|
|
860
858
|
|
|
861
859
|
Notes
|
|
862
860
|
-----
|
|
863
|
-
:
|
|
861
|
+
:class:`jedi.api.classes.Completion` s returned by Jedi may not have the same start and end, though
|
|
864
862
|
the Jupyter Protocol requires them to behave like so. This will readjust
|
|
865
863
|
the completion to have the same ``start`` and ``end`` by padding both
|
|
866
864
|
extremities with surrounding text.
|
|
@@ -990,9 +988,9 @@ class Completer(Configurable):
|
|
|
990
988
|
no item/attribute evaluation, no access to locals/globals,
|
|
991
989
|
no evaluation of any operations or comparisons.
|
|
992
990
|
- ``limited``: access to all namespaces, evaluation of hard-coded methods
|
|
993
|
-
(for example: :
|
|
994
|
-
:
|
|
995
|
-
:
|
|
991
|
+
(for example: :py:meth:`dict.keys`, :py:meth:`object.__getattr__`,
|
|
992
|
+
:py:meth:`object.__getitem__`) on allow-listed objects (for example:
|
|
993
|
+
:py:class:`dict`, :py:class:`list`, :py:class:`tuple`, ``pandas.Series``),
|
|
996
994
|
- ``unsafe``: evaluation of all methods and function calls but not of
|
|
997
995
|
syntax with side-effects like `del x`,
|
|
998
996
|
- ``dangerous``: completely arbitrary evaluation; does not support auto-import.
|
|
@@ -1352,6 +1350,8 @@ class Completer(Configurable):
|
|
|
1352
1350
|
assert res is not None
|
|
1353
1351
|
if len(res.body) != 1:
|
|
1354
1352
|
continue
|
|
1353
|
+
if not isinstance(res.body[0], ast.Expr):
|
|
1354
|
+
continue
|
|
1355
1355
|
expr = res.body[0].value
|
|
1356
1356
|
if isinstance(expr, ast.Tuple) and not code[-1] == ")":
|
|
1357
1357
|
# we skip implicit tuple, like when trimming `fun(a,b`<completion>
|
|
@@ -1538,9 +1538,9 @@ def match_dict_keys(
|
|
|
1538
1538
|
# All checks passed!
|
|
1539
1539
|
return True
|
|
1540
1540
|
|
|
1541
|
-
filtered_key_is_final: dict[
|
|
1542
|
-
|
|
1543
|
-
)
|
|
1541
|
+
filtered_key_is_final: dict[
|
|
1542
|
+
Union[str, bytes, int, float], _DictKeyState
|
|
1543
|
+
] = defaultdict(lambda: _DictKeyState.BASELINE)
|
|
1544
1544
|
|
|
1545
1545
|
for k in keys:
|
|
1546
1546
|
# If at least one of the matches is not final, mark as undetermined.
|
|
@@ -2211,6 +2211,17 @@ class IPCompleter(Completer):
|
|
|
2211
2211
|
# starts with `/home/`, `C:\`, etc)
|
|
2212
2212
|
|
|
2213
2213
|
text = context.token
|
|
2214
|
+
code_until_cursor = self._extract_code(context.text_until_cursor)
|
|
2215
|
+
completion_type = self._determine_completion_context(code_until_cursor)
|
|
2216
|
+
in_cli_context = self._is_completing_in_cli_context(code_until_cursor)
|
|
2217
|
+
if (
|
|
2218
|
+
completion_type == self._CompletionContextType.ATTRIBUTE
|
|
2219
|
+
and not in_cli_context
|
|
2220
|
+
):
|
|
2221
|
+
return {
|
|
2222
|
+
"completions": [],
|
|
2223
|
+
"suppress": False,
|
|
2224
|
+
}
|
|
2214
2225
|
|
|
2215
2226
|
# chars that require escaping with backslash - i.e. chars
|
|
2216
2227
|
# that readline treats incorrectly as delimiters, but we
|
|
@@ -2480,8 +2491,9 @@ class IPCompleter(Completer):
|
|
|
2480
2491
|
)
|
|
2481
2492
|
return {
|
|
2482
2493
|
"completions": matches,
|
|
2483
|
-
# static analysis should not suppress other
|
|
2484
|
-
|
|
2494
|
+
# static analysis should not suppress other matcher
|
|
2495
|
+
# NOTE: file_matcher is automatically suppressed on attribute completions
|
|
2496
|
+
"suppress": False,
|
|
2485
2497
|
}
|
|
2486
2498
|
|
|
2487
2499
|
def _jedi_matches(
|
|
@@ -2597,12 +2609,47 @@ class IPCompleter(Completer):
|
|
|
2597
2609
|
return self._CompletionContextType.GLOBAL
|
|
2598
2610
|
|
|
2599
2611
|
# Handle all other attribute matches np.ran, d[0].k, (a,b).count
|
|
2600
|
-
chain_match = re.search(r".*(
|
|
2612
|
+
chain_match = re.search(r".*(.+(?<!\s)\.(?:[a-zA-Z]\w*)?)$", line)
|
|
2601
2613
|
if chain_match:
|
|
2602
2614
|
return self._CompletionContextType.ATTRIBUTE
|
|
2603
2615
|
|
|
2604
2616
|
return self._CompletionContextType.GLOBAL
|
|
2605
2617
|
|
|
2618
|
+
def _is_completing_in_cli_context(self, text: str) -> bool:
|
|
2619
|
+
"""
|
|
2620
|
+
Determine if we are completing in a CLI alias, line magic, or bang expression context.
|
|
2621
|
+
"""
|
|
2622
|
+
stripped = text.lstrip()
|
|
2623
|
+
if stripped.startswith("!") or stripped.startswith("%"):
|
|
2624
|
+
return True
|
|
2625
|
+
# Check for CLI aliases
|
|
2626
|
+
try:
|
|
2627
|
+
tokens = stripped.split(None, 1)
|
|
2628
|
+
if not tokens:
|
|
2629
|
+
return False
|
|
2630
|
+
first_token = tokens[0]
|
|
2631
|
+
|
|
2632
|
+
# Must have arguments after the command for this to apply
|
|
2633
|
+
if len(tokens) < 2:
|
|
2634
|
+
return False
|
|
2635
|
+
|
|
2636
|
+
# Check if first token is a known alias
|
|
2637
|
+
if not any(
|
|
2638
|
+
alias[0] == first_token for alias in self.shell.alias_manager.aliases
|
|
2639
|
+
):
|
|
2640
|
+
return False
|
|
2641
|
+
|
|
2642
|
+
try:
|
|
2643
|
+
if first_token in self.shell.user_ns:
|
|
2644
|
+
# There's a variable defined, so the alias is overshadowed
|
|
2645
|
+
return False
|
|
2646
|
+
except (AttributeError, KeyError):
|
|
2647
|
+
pass
|
|
2648
|
+
|
|
2649
|
+
return True
|
|
2650
|
+
except Exception:
|
|
2651
|
+
return False
|
|
2652
|
+
|
|
2606
2653
|
def _is_in_string_or_comment(self, text):
|
|
2607
2654
|
"""
|
|
2608
2655
|
Determine if the cursor is inside a string or comment.
|
|
@@ -2724,7 +2771,11 @@ class IPCompleter(Completer):
|
|
|
2724
2771
|
"""Match attributes or global python names"""
|
|
2725
2772
|
text = context.text_until_cursor
|
|
2726
2773
|
text = self._extract_code(text)
|
|
2727
|
-
|
|
2774
|
+
in_cli_context = self._is_completing_in_cli_context(text)
|
|
2775
|
+
if in_cli_context:
|
|
2776
|
+
completion_type = self._CompletionContextType.GLOBAL
|
|
2777
|
+
else:
|
|
2778
|
+
completion_type = self._determine_completion_context(text)
|
|
2728
2779
|
if completion_type == self._CompletionContextType.ATTRIBUTE:
|
|
2729
2780
|
try:
|
|
2730
2781
|
matches, fragment = self._attr_matches(
|
|
@@ -2744,8 +2795,6 @@ class IPCompleter(Completer):
|
|
|
2744
2795
|
matches = _convert_matcher_v1_result_to_v2(
|
|
2745
2796
|
matches, type="attribute", fragment=fragment
|
|
2746
2797
|
)
|
|
2747
|
-
if matches["completions"]:
|
|
2748
|
-
matches["suppress"] = {_get_matcher_id(self.file_matcher)}
|
|
2749
2798
|
return matches
|
|
2750
2799
|
except NameError:
|
|
2751
2800
|
# catches <undefined attributes>.<tab>
|
|
@@ -3256,7 +3305,7 @@ class IPCompleter(Completer):
|
|
|
3256
3305
|
|
|
3257
3306
|
.. note::
|
|
3258
3307
|
|
|
3259
|
-
If ``IPCompleter.debug`` is :
|
|
3308
|
+
If ``IPCompleter.debug`` is :py:data:`True` will yield a ``--jedi/ipython--``
|
|
3260
3309
|
fake Completion token to distinguish completion returned by Jedi
|
|
3261
3310
|
and usual IPython completion.
|
|
3262
3311
|
|
|
@@ -275,6 +275,10 @@ class Pdb(OldPdb):
|
|
|
275
275
|
|
|
276
276
|
# `kwargs` ensures full compatibility with stdlib's `pdb.Pdb`.
|
|
277
277
|
OldPdb.__init__(self, completekey, stdin, stdout, **kwargs)
|
|
278
|
+
# Python 3.15+ should define this, so no need to initialize
|
|
279
|
+
# this avoids some getattr(self, 'curframe')
|
|
280
|
+
if sys.version_info < (3, 15):
|
|
281
|
+
self.curframe = None
|
|
278
282
|
|
|
279
283
|
# IPython changes...
|
|
280
284
|
self.shell = get_ipython()
|
|
@@ -609,7 +613,7 @@ class Pdb(OldPdb):
|
|
|
609
613
|
So if frame is self.current_frame we instead return self.curframe_locals
|
|
610
614
|
|
|
611
615
|
"""
|
|
612
|
-
if frame is
|
|
616
|
+
if frame is self.curframe:
|
|
613
617
|
return self.curframe_locals
|
|
614
618
|
else:
|
|
615
619
|
return frame.f_locals
|
|
@@ -728,6 +732,7 @@ class Pdb(OldPdb):
|
|
|
728
732
|
|
|
729
733
|
new_line, err = self.parser.format2(line, "str")
|
|
730
734
|
if not err:
|
|
735
|
+
assert new_line is not None
|
|
731
736
|
line = new_line
|
|
732
737
|
|
|
733
738
|
bp = None
|
|
@@ -137,7 +137,7 @@ def display(
|
|
|
137
137
|
-------
|
|
138
138
|
handle: DisplayHandle
|
|
139
139
|
Returns a handle on updatable displays for use with :func:`update_display`,
|
|
140
|
-
if `display_id` is given. Returns :
|
|
140
|
+
if `display_id` is given. Returns :py:data:`None` if no `display_id` is given
|
|
141
141
|
(default).
|
|
142
142
|
|
|
143
143
|
Examples
|
|
@@ -63,7 +63,7 @@ class DisplayHook(Configurable):
|
|
|
63
63
|
|
|
64
64
|
@property
|
|
65
65
|
def prompt_count(self):
|
|
66
|
-
return self.shell.execution_count
|
|
66
|
+
return self.shell.execution_count - 1
|
|
67
67
|
|
|
68
68
|
#-------------------------------------------------------------------------
|
|
69
69
|
# Methods used in __call__. Override these methods to modify the behavior
|
|
@@ -127,7 +127,7 @@ class DisplayHook(Configurable):
|
|
|
127
127
|
"""
|
|
128
128
|
# Use write, not print which adds an extra space.
|
|
129
129
|
sys.stdout.write(self.shell.separate_out)
|
|
130
|
-
outprompt = 'Out[{}]: '.format(self.shell.execution_count)
|
|
130
|
+
outprompt = 'Out[{}]: '.format(self.shell.execution_count - 1)
|
|
131
131
|
if self.do_full_cache:
|
|
132
132
|
sys.stdout.write(outprompt)
|
|
133
133
|
|
|
@@ -149,7 +149,7 @@ class DisplayPublisher(Configurable):
|
|
|
149
149
|
|
|
150
150
|
outputs = self.shell.history_manager.outputs
|
|
151
151
|
|
|
152
|
-
target_execution_count = self.shell.execution_count
|
|
152
|
+
target_execution_count = self.shell.execution_count - 1
|
|
153
153
|
if self._in_post_execute:
|
|
154
154
|
# We're in post_execute, so this is likely a matplotlib flush
|
|
155
155
|
# Use execution_count - 1 to associate with the cell that created the plot
|
|
@@ -3,7 +3,8 @@ import linecache
|
|
|
3
3
|
import sys
|
|
4
4
|
from collections.abc import Sequence
|
|
5
5
|
from types import TracebackType
|
|
6
|
-
from typing import Any,
|
|
6
|
+
from typing import Any, Optional
|
|
7
|
+
from collections.abc import Callable
|
|
7
8
|
|
|
8
9
|
import stack_data
|
|
9
10
|
from pygments.formatters.terminal256 import Terminal256Formatter
|
|
@@ -13,6 +13,13 @@ events and the arguments which will be passed to them.
|
|
|
13
13
|
This API is experimental in IPython 2.0, and may be revised in future versions.
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
from typing import TYPE_CHECKING, Any, Callable, Iterable
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from IPython.core.interactiveshell import InteractiveShell
|
|
22
|
+
|
|
16
23
|
|
|
17
24
|
class EventManager:
|
|
18
25
|
"""Manage a collection of events and a sequence of callbacks for each.
|
|
@@ -25,7 +32,12 @@ class EventManager:
|
|
|
25
32
|
This API is experimental in IPython 2.0, and may be revised in future versions.
|
|
26
33
|
"""
|
|
27
34
|
|
|
28
|
-
def __init__(
|
|
35
|
+
def __init__(
|
|
36
|
+
self,
|
|
37
|
+
shell: InteractiveShell,
|
|
38
|
+
available_events: Iterable[str],
|
|
39
|
+
print_on_error: bool = True,
|
|
40
|
+
) -> None:
|
|
29
41
|
"""Initialise the :class:`CallbackManager`.
|
|
30
42
|
|
|
31
43
|
Parameters
|
|
@@ -38,10 +50,12 @@ class EventManager:
|
|
|
38
50
|
A boolean flag to set whether the EventManager will print a warning which a event errors.
|
|
39
51
|
"""
|
|
40
52
|
self.shell = shell
|
|
41
|
-
self.callbacks
|
|
53
|
+
self.callbacks: dict[str, list[Callable[..., Any]]] = {
|
|
54
|
+
n: [] for n in available_events
|
|
55
|
+
}
|
|
42
56
|
self.print_on_error = print_on_error
|
|
43
57
|
|
|
44
|
-
def register(self, event, function):
|
|
58
|
+
def register(self, event: str, function: Callable[..., Any]) -> None:
|
|
45
59
|
"""Register a new event callback.
|
|
46
60
|
|
|
47
61
|
Parameters
|
|
@@ -64,14 +78,14 @@ class EventManager:
|
|
|
64
78
|
if function not in self.callbacks[event]:
|
|
65
79
|
self.callbacks[event].append(function)
|
|
66
80
|
|
|
67
|
-
def unregister(self, event, function):
|
|
81
|
+
def unregister(self, event: str, function: Callable[..., Any]) -> None:
|
|
68
82
|
"""Remove a callback from the given event."""
|
|
69
83
|
if function in self.callbacks[event]:
|
|
70
84
|
return self.callbacks[event].remove(function)
|
|
71
85
|
|
|
72
86
|
raise ValueError('Function {!r} is not registered as a {} callback'.format(function, event))
|
|
73
87
|
|
|
74
|
-
def trigger(self, event, *args, **kwargs):
|
|
88
|
+
def trigger(self, event: str, *args: Any, **kwargs: Any) -> None:
|
|
75
89
|
"""Call callbacks for ``event``.
|
|
76
90
|
|
|
77
91
|
Any additional arguments are passed to all callbacks registered for this
|
|
@@ -90,9 +104,9 @@ class EventManager:
|
|
|
90
104
|
self.shell.showtraceback()
|
|
91
105
|
|
|
92
106
|
# event_name -> prototype mapping
|
|
93
|
-
available_events = {}
|
|
107
|
+
available_events: dict[str, Callable[..., Any]] = {}
|
|
94
108
|
|
|
95
|
-
def _define_event(callback_function):
|
|
109
|
+
def _define_event(callback_function: Callable[..., Any]) -> Callable[..., Any]:
|
|
96
110
|
available_events[callback_function.__name__] = callback_function
|
|
97
111
|
return callback_function
|
|
98
112
|
|
|
@@ -104,7 +118,7 @@ def _define_event(callback_function):
|
|
|
104
118
|
# ------------------------------------------------------------------------------
|
|
105
119
|
|
|
106
120
|
@_define_event
|
|
107
|
-
def pre_execute():
|
|
121
|
+
def pre_execute() -> None:
|
|
108
122
|
"""Fires before code is executed in response to user/frontend action.
|
|
109
123
|
|
|
110
124
|
This includes comm and widget messages and silent execution, as well as user
|
|
@@ -113,7 +127,7 @@ def pre_execute():
|
|
|
113
127
|
pass
|
|
114
128
|
|
|
115
129
|
@_define_event
|
|
116
|
-
def pre_run_cell(info):
|
|
130
|
+
def pre_run_cell(info: Any) -> None:
|
|
117
131
|
"""Fires before user-entered code runs.
|
|
118
132
|
|
|
119
133
|
Parameters
|
|
@@ -124,7 +138,7 @@ def pre_run_cell(info):
|
|
|
124
138
|
pass
|
|
125
139
|
|
|
126
140
|
@_define_event
|
|
127
|
-
def post_execute():
|
|
141
|
+
def post_execute() -> None:
|
|
128
142
|
"""Fires after code is executed in response to user/frontend action.
|
|
129
143
|
|
|
130
144
|
This includes comm and widget messages and silent execution, as well as user
|
|
@@ -133,7 +147,7 @@ def post_execute():
|
|
|
133
147
|
pass
|
|
134
148
|
|
|
135
149
|
@_define_event
|
|
136
|
-
def post_run_cell(result):
|
|
150
|
+
def post_run_cell(result: Any) -> None:
|
|
137
151
|
"""Fires after user-entered code runs.
|
|
138
152
|
|
|
139
153
|
Parameters
|
|
@@ -144,7 +158,7 @@ def post_run_cell(result):
|
|
|
144
158
|
pass
|
|
145
159
|
|
|
146
160
|
@_define_event
|
|
147
|
-
def shell_initialized(ip):
|
|
161
|
+
def shell_initialized(ip: InteractiveShell) -> None:
|
|
148
162
|
"""Fires after initialisation of :class:`~IPython.core.interactiveshell.InteractiveShell`.
|
|
149
163
|
|
|
150
164
|
This is before extensions and startup scripts are loaded, so it can only be
|
|
@@ -366,7 +366,7 @@ class BaseFormatter(Configurable):
|
|
|
366
366
|
dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
|
|
367
367
|
methods.
|
|
368
368
|
|
|
369
|
-
If no function/callable is found to compute the format data,
|
|
369
|
+
If no function/callable is found to compute the format data, :py:data:`None` is
|
|
370
370
|
returned and this format type is not used.
|
|
371
371
|
"""
|
|
372
372
|
|
|
@@ -3,19 +3,18 @@ from inspect import isclass, signature, Signature, getmodule
|
|
|
3
3
|
from typing import (
|
|
4
4
|
Annotated,
|
|
5
5
|
AnyStr,
|
|
6
|
-
Callable,
|
|
7
6
|
Literal,
|
|
8
7
|
NamedTuple,
|
|
9
8
|
NewType,
|
|
10
9
|
Optional,
|
|
11
10
|
Protocol,
|
|
12
|
-
Sequence,
|
|
13
11
|
TypeGuard,
|
|
14
12
|
Union,
|
|
15
13
|
get_args,
|
|
16
14
|
get_origin,
|
|
17
15
|
is_typeddict,
|
|
18
16
|
)
|
|
17
|
+
from collections.abc import Callable, Sequence
|
|
19
18
|
import ast
|
|
20
19
|
import builtins
|
|
21
20
|
import collections
|
|
@@ -30,8 +29,8 @@ from types import MethodDescriptorType, ModuleType, MethodType
|
|
|
30
29
|
|
|
31
30
|
from IPython.utils.decorators import undoc
|
|
32
31
|
|
|
33
|
-
|
|
34
|
-
from typing import Self, LiteralString
|
|
32
|
+
import types
|
|
33
|
+
from typing import Self, LiteralString, get_type_hints
|
|
35
34
|
|
|
36
35
|
if sys.version_info < (3, 12):
|
|
37
36
|
from typing_extensions import TypeAliasType
|
|
@@ -41,17 +40,20 @@ else:
|
|
|
41
40
|
|
|
42
41
|
@undoc
|
|
43
42
|
class HasGetItem(Protocol):
|
|
44
|
-
def __getitem__(self, key) -> None:
|
|
43
|
+
def __getitem__(self, key) -> None:
|
|
44
|
+
...
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
@undoc
|
|
48
48
|
class InstancesHaveGetItem(Protocol):
|
|
49
|
-
def __call__(self, *args, **kwargs) -> HasGetItem:
|
|
49
|
+
def __call__(self, *args, **kwargs) -> HasGetItem:
|
|
50
|
+
...
|
|
50
51
|
|
|
51
52
|
|
|
52
53
|
@undoc
|
|
53
54
|
class HasGetAttr(Protocol):
|
|
54
|
-
def __getattr__(self, key) -> None:
|
|
55
|
+
def __getattr__(self, key) -> None:
|
|
56
|
+
...
|
|
55
57
|
|
|
56
58
|
|
|
57
59
|
@undoc
|
|
@@ -391,7 +393,7 @@ class EvaluationContext:
|
|
|
391
393
|
#: Useful for evaluating ``:-1, 'col'`` in ``df[:-1, 'col']``.
|
|
392
394
|
in_subscript: bool = False
|
|
393
395
|
#: Auto import method
|
|
394
|
-
auto_import: Callable[
|
|
396
|
+
auto_import: Callable[[Sequence[str]], ModuleType] | None = None
|
|
395
397
|
#: Overrides for evaluation policy
|
|
396
398
|
policy_overrides: dict = field(default_factory=dict)
|
|
397
399
|
#: Transient local namespace used to store mocks
|
|
@@ -400,6 +402,9 @@ class EvaluationContext:
|
|
|
400
402
|
class_transients: dict | None = None
|
|
401
403
|
#: Instance variable name used in the method definition
|
|
402
404
|
instance_arg_name: str | None = None
|
|
405
|
+
#: Currently associated value
|
|
406
|
+
#: Useful for adding items to _Duck on annotated assignment
|
|
407
|
+
current_value: ast.AST | None = None
|
|
403
408
|
|
|
404
409
|
def replace(self, /, **changes):
|
|
405
410
|
"""Return a new copy of the context, with specified changes"""
|
|
@@ -496,6 +501,8 @@ UNARY_OP_DUNDERS: dict[type[ast.unaryop], tuple[str, ...]] = {
|
|
|
496
501
|
ast.Not: ("__not__",),
|
|
497
502
|
}
|
|
498
503
|
|
|
504
|
+
GENERIC_CONTAINER_TYPES = (dict, list, set, tuple, frozenset)
|
|
505
|
+
|
|
499
506
|
|
|
500
507
|
class ImpersonatingDuck:
|
|
501
508
|
"""A dummy class used to create objects of other classes without calling their ``__init__``"""
|
|
@@ -561,6 +568,30 @@ def _validate_policy_overrides(
|
|
|
561
568
|
return all_good
|
|
562
569
|
|
|
563
570
|
|
|
571
|
+
def _is_type_annotation(obj) -> bool:
|
|
572
|
+
"""
|
|
573
|
+
Returns True if obj is a type annotation, False otherwise.
|
|
574
|
+
"""
|
|
575
|
+
if isinstance(obj, type):
|
|
576
|
+
return True
|
|
577
|
+
if isinstance(obj, types.GenericAlias):
|
|
578
|
+
return True
|
|
579
|
+
if hasattr(types, "UnionType") and isinstance(obj, types.UnionType):
|
|
580
|
+
return True
|
|
581
|
+
if isinstance(obj, (typing._SpecialForm, typing._BaseGenericAlias)):
|
|
582
|
+
return True
|
|
583
|
+
if isinstance(obj, typing.TypeVar):
|
|
584
|
+
return True
|
|
585
|
+
# Types that support __class_getitem__
|
|
586
|
+
if isinstance(obj, type) and hasattr(obj, "__class_getitem__"):
|
|
587
|
+
return True
|
|
588
|
+
# Fallback: check if get_origin returns something
|
|
589
|
+
if hasattr(typing, "get_origin") and get_origin(obj) is not None:
|
|
590
|
+
return True
|
|
591
|
+
|
|
592
|
+
return False
|
|
593
|
+
|
|
594
|
+
|
|
564
595
|
def _handle_assign(node: ast.Assign, context: EvaluationContext):
|
|
565
596
|
value = eval_node(node.value, context)
|
|
566
597
|
transient_locals = context.transient_locals
|
|
@@ -658,6 +689,41 @@ def _handle_assign(node: ast.Assign, context: EvaluationContext):
|
|
|
658
689
|
return None
|
|
659
690
|
|
|
660
691
|
|
|
692
|
+
def _handle_annassign(node, context):
|
|
693
|
+
context_with_value = context.replace(current_value=getattr(node, "value", None))
|
|
694
|
+
annotation_result = eval_node(node.annotation, context_with_value)
|
|
695
|
+
if _is_type_annotation(annotation_result):
|
|
696
|
+
annotation_value = _resolve_annotation(annotation_result, context)
|
|
697
|
+
# Use Value for generic types
|
|
698
|
+
use_value = (
|
|
699
|
+
isinstance(annotation_value, GENERIC_CONTAINER_TYPES) and node.value is not None
|
|
700
|
+
)
|
|
701
|
+
else:
|
|
702
|
+
annotation_value = annotation_result
|
|
703
|
+
use_value = False
|
|
704
|
+
|
|
705
|
+
# LOCAL VARIABLE
|
|
706
|
+
if getattr(node, "simple", False) and isinstance(node.target, ast.Name):
|
|
707
|
+
name = node.target.id
|
|
708
|
+
if use_value:
|
|
709
|
+
return _handle_assign(
|
|
710
|
+
ast.Assign(targets=[node.target], value=node.value), context
|
|
711
|
+
)
|
|
712
|
+
context.transient_locals[name] = annotation_value
|
|
713
|
+
return None
|
|
714
|
+
|
|
715
|
+
# INSTANCE ATTRIBUTE
|
|
716
|
+
if _is_instance_attribute_assignment(node.target, context):
|
|
717
|
+
attr = node.target.attr
|
|
718
|
+
if use_value:
|
|
719
|
+
return _handle_assign(
|
|
720
|
+
ast.Assign(targets=[node.target], value=node.value), context
|
|
721
|
+
)
|
|
722
|
+
context.class_transients[attr] = annotation_value
|
|
723
|
+
return None
|
|
724
|
+
|
|
725
|
+
return None
|
|
726
|
+
|
|
661
727
|
def _extract_args_and_kwargs(node: ast.Call, context: EvaluationContext):
|
|
662
728
|
args = [eval_node(arg, context) for arg in node.args]
|
|
663
729
|
kwargs = {
|
|
@@ -766,9 +832,12 @@ def eval_node(node: Union[ast.AST, None], context: EvaluationContext):
|
|
|
766
832
|
|
|
767
833
|
if is_property:
|
|
768
834
|
if return_type is not None:
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
835
|
+
if _is_type_annotation(return_type):
|
|
836
|
+
context.transient_locals[node.name] = _resolve_annotation(
|
|
837
|
+
return_type, context
|
|
838
|
+
)
|
|
839
|
+
else:
|
|
840
|
+
context.transient_locals[node.name] = return_type
|
|
772
841
|
else:
|
|
773
842
|
return_value = _infer_return_value(node, func_context)
|
|
774
843
|
context.transient_locals[node.name] = return_value
|
|
@@ -779,7 +848,10 @@ def eval_node(node: Union[ast.AST, None], context: EvaluationContext):
|
|
|
779
848
|
pass
|
|
780
849
|
|
|
781
850
|
if return_type is not None:
|
|
782
|
-
|
|
851
|
+
if _is_type_annotation(return_type):
|
|
852
|
+
dummy_function.__annotations__["return"] = return_type
|
|
853
|
+
else:
|
|
854
|
+
dummy_function.__inferred_return__ = return_type
|
|
783
855
|
else:
|
|
784
856
|
inferred_return = _infer_return_value(node, func_context)
|
|
785
857
|
if inferred_return is not None:
|
|
@@ -900,14 +972,7 @@ def eval_node(node: Union[ast.AST, None], context: EvaluationContext):
|
|
|
900
972
|
if isinstance(node, ast.Assign):
|
|
901
973
|
return _handle_assign(node, context)
|
|
902
974
|
if isinstance(node, ast.AnnAssign):
|
|
903
|
-
|
|
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
|
|
910
|
-
return None
|
|
975
|
+
return _handle_annassign(node, context)
|
|
911
976
|
if isinstance(node, ast.Expression):
|
|
912
977
|
return eval_node(node.body, context)
|
|
913
978
|
if isinstance(node, ast.Expr):
|
|
@@ -924,6 +989,29 @@ def eval_node(node: Union[ast.AST, None], context: EvaluationContext):
|
|
|
924
989
|
if isinstance(node, ast.BinOp):
|
|
925
990
|
left = eval_node(node.left, context)
|
|
926
991
|
right = eval_node(node.right, context)
|
|
992
|
+
if (
|
|
993
|
+
isinstance(node.op, ast.BitOr)
|
|
994
|
+
and _is_type_annotation(left)
|
|
995
|
+
and _is_type_annotation(right)
|
|
996
|
+
):
|
|
997
|
+
left_duck = (
|
|
998
|
+
_Duck(dict.fromkeys(dir(left)))
|
|
999
|
+
if policy.can_call(left.__dir__)
|
|
1000
|
+
else _Duck()
|
|
1001
|
+
)
|
|
1002
|
+
right_duck = (
|
|
1003
|
+
_Duck(dict.fromkeys(dir(right)))
|
|
1004
|
+
if policy.can_call(right.__dir__)
|
|
1005
|
+
else _Duck()
|
|
1006
|
+
)
|
|
1007
|
+
value_node = context.current_value
|
|
1008
|
+
if value_node is not None and isinstance(value_node, ast.Dict):
|
|
1009
|
+
if dict in [left, right]:
|
|
1010
|
+
return _merge_values(
|
|
1011
|
+
[left_duck, right_duck, ast.literal_eval(value_node)],
|
|
1012
|
+
policy=get_policy(context),
|
|
1013
|
+
)
|
|
1014
|
+
return _merge_values([left_duck, right_duck], policy=get_policy(context))
|
|
927
1015
|
dunders = _find_dunder(node.op, BINARY_OP_DUNDERS)
|
|
928
1016
|
if dunders:
|
|
929
1017
|
if policy.can_operate(dunders, left, right):
|
|
@@ -1033,6 +1121,22 @@ def eval_node(node: Union[ast.AST, None], context: EvaluationContext):
|
|
|
1033
1121
|
value = eval_node(node.value, context)
|
|
1034
1122
|
if policy.can_get_attr(value, node.attr):
|
|
1035
1123
|
return getattr(value, node.attr)
|
|
1124
|
+
try:
|
|
1125
|
+
cls = (
|
|
1126
|
+
value if isinstance(value, type) else getattr(value, "__class__", None)
|
|
1127
|
+
)
|
|
1128
|
+
if cls is not None:
|
|
1129
|
+
resolved_hints = get_type_hints(
|
|
1130
|
+
cls,
|
|
1131
|
+
globalns=(context.globals or {}),
|
|
1132
|
+
localns=(context.locals or {}),
|
|
1133
|
+
)
|
|
1134
|
+
if node.attr in resolved_hints:
|
|
1135
|
+
annotated = resolved_hints[node.attr]
|
|
1136
|
+
return _resolve_annotation(annotated, context)
|
|
1137
|
+
except Exception:
|
|
1138
|
+
# Fall through to the guard rejection
|
|
1139
|
+
pass
|
|
1036
1140
|
raise GuardRejection(
|
|
1037
1141
|
"Attribute access (`__getattr__`) for",
|
|
1038
1142
|
type(value), # not joined to avoid calling `repr`
|