ipython 9.4.0__tar.gz → 9.5.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.4.0 → ipython-9.5.0}/IPython/core/completer.py +26 -6
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/debugger.py +21 -1
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/guarded_eval.py +76 -22
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/history.py +1 -1
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/interactiveshell.py +2 -2
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/magics/basic.py +40 -3
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/magics/namespace.py +6 -8
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/magics/script.py +6 -1
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/release.py +1 -1
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/ultratb.py +1 -4
- {ipython-9.4.0 → ipython-9.5.0}/IPython/extensions/deduperreload/deduperreload.py +55 -34
- {ipython-9.4.0 → ipython-9.5.0}/IPython/extensions/deduperreload/deduperreload_patching.py +15 -8
- {ipython-9.4.0 → ipython-9.5.0}/IPython/extensions/tests/test_deduperreload.py +36 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/_sysinfo.py +1 -1
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/text.py +5 -1
- {ipython-9.4.0/ipython.egg-info → ipython-9.5.0}/PKG-INFO +2 -2
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/version9.rst +39 -0
- {ipython-9.4.0 → ipython-9.5.0/ipython.egg-info}/PKG-INFO +2 -2
- {ipython-9.4.0 → ipython-9.5.0}/ipython.egg-info/requires.txt +1 -1
- {ipython-9.4.0 → ipython-9.5.0}/pyproject.toml +1 -1
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_completer.py +69 -1
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_debugger.py +5 -6
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_interactiveshell.py +10 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_magic.py +98 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_oinspect.py +2 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_pycolorize.py +1 -1
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_text.py +11 -1
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_ultratb.py +15 -0
- {ipython-9.4.0 → ipython-9.5.0}/.flake8 +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/.mailmap +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/.pre-commit-config.yaml +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/COPYING.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/__init__.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/__main__.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/__init__.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/alias.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/application.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/async_helpers.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/autocall.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/builtin_trap.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/compilerop.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/completerlib.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/crashhandler.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/debugger_backport.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/display.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/display_functions.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/display_trap.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/displayhook.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/displaypub.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/doctb.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/error.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/events.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/extensions.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/formatters.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/getipython.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/historyapp.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/hooks.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/inputtransformer2.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/latex_symbols.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/logger.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/macro.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/magic.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/magic_arguments.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/magics/__init__.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/magics/ast_mod.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/magics/auto.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/magics/code.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/magics/config.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/magics/display.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/magics/execution.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/magics/extension.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/magics/history.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/magics/logging.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/magics/osm.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/magics/packaging.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/magics/pylab.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/oinspect.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/page.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/payload.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/payloadpage.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/prefilter.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/profile/README_STARTUP +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/profileapp.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/profiledir.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/pylabtools.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/shellapp.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/splitinput.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/tbtools.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/tips.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/core/usage.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/display.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/extensions/__init__.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/extensions/autoreload.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/extensions/deduperreload/__init__.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/extensions/storemagic.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/external/__init__.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/external/pickleshare.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/external/qt_for_kernel.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/external/qt_loaders.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/lib/__init__.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/lib/backgroundjobs.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/lib/clipboard.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/lib/deepreload.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/lib/demo.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/lib/display.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/lib/editorhooks.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/lib/guisupport.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/lib/latextools.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/lib/lexers.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/lib/pretty.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/paths.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/py.typed +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/sphinxext/__init__.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/sphinxext/custom_doctests.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/sphinxext/ipython_console_highlighting.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/sphinxext/ipython_directive.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/terminal/__init__.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/terminal/debugger.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/terminal/embed.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/terminal/interactiveshell.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/terminal/ipapp.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/terminal/magics.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/terminal/prompts.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/terminal/pt_inputhooks/__init__.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/terminal/pt_inputhooks/asyncio.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/terminal/pt_inputhooks/glut.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/terminal/pt_inputhooks/gtk.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/terminal/pt_inputhooks/gtk3.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/terminal/pt_inputhooks/gtk4.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/terminal/pt_inputhooks/osx.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/terminal/pt_inputhooks/pyglet.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/terminal/pt_inputhooks/qt.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/terminal/pt_inputhooks/tk.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/terminal/pt_inputhooks/wx.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/terminal/ptutils.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/terminal/shortcuts/__init__.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/terminal/shortcuts/auto_match.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/terminal/shortcuts/auto_suggest.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/terminal/shortcuts/filters.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/testing/__init__.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/testing/decorators.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/testing/globalipapp.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/testing/ipunittest.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/testing/plugin/Makefile +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/testing/plugin/__init__.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/testing/plugin/dtexample.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/testing/plugin/ipdoctest.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/testing/plugin/pytest_ipdoctest.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/testing/plugin/setup.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/testing/plugin/simple.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/testing/plugin/simplevars.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/testing/plugin/test_combo.txt +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/testing/plugin/test_example.txt +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/testing/plugin/test_exampleip.txt +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/testing/plugin/test_ipdoctest.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/testing/plugin/test_refs.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/testing/skipdoctest.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/testing/tools.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/PyColorize.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/__init__.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/_process_cli.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/_process_common.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/_process_emscripten.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/_process_posix.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/_process_win32.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/_process_win32_controller.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/capture.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/coloransi.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/contexts.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/data.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/decorators.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/dir2.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/docs.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/encoding.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/eventful.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/frame.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/generics.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/importstring.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/io.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/ipstruct.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/jsonutil.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/log.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/module_paths.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/openpy.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/path.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/process.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/py3compat.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/sentinel.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/strdispatch.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/sysinfo.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/syspathcontext.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/tempdir.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/terminal.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/timing.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/tokenutil.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/IPython/utils/wildcard.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/LICENSE +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/MANIFEST.in +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/README.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/_build_meta.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/Makefile +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/README.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/autogen_api.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/autogen_config.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/autogen_magics.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/autogen_shortcuts.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/make.cmd +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/man/ipython.1 +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/requirements.txt +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/2.0/running-crop.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/2.0/running.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/2.0/treeview.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/2.0/user-interface.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/2.0/widgets.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/8.0/auto_suggest_1_prompt_no_text.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/8.0/auto_suggest_2_print_hello_suggest.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/8.0/auto_suggest_3_print_hello_suggest.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/8.0/auto_suggest_4_print_hello.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/8.0/auto_suggest_d_completions.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/8.0/auto_suggest_d_phantom.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/8.0/auto_suggest_def_completions.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/8.0/auto_suggest_def_phantom.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/8.0/auto_suggest_match_parens.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/8.0/auto_suggest_second_prompt.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/8.0/pathlib_pathlib_everywhere.jpg +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/autosuggest.gif +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/ipy_013_dashboard.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/ipy_013_dashboard_cluster.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/ipy_013_notebook_cythonmagic.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/ipy_013_notebook_long_out.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/ipy_013_notebook_octavemagic.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/ipy_013_notebook_rmagic.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/ipy_013_notebook_script_cells.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/ipy_013_notebook_spectrogram.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/ipy_013_notebook_tooltip.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/ipy_013_par_tb.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/ipy_013_qtconsole_baboon.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/ipy_013_qtconsole_completer.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/ipython-6-screenshot.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/jedi_type_inference_60.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/kernel_selector_screenshot.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/ms_visual_studio.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/notebook_specgram.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/ptshell_features.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/qtconsole.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/qtconsole_tabbed.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_images/unicode_completion.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_static/favicon.ico +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_static/logo.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_static/theme_overrides.css +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_templates/breadcrumbs.html +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/_templates/notebook_redirect.html +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/about/history.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/about/index.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/about/license_and_copyright.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/api/index.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/conf.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/config/callbacks.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/config/custommagics.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/config/details.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/config/eventloops.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/config/extensions/autoreload.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/config/extensions/index.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/config/extensions/storemagic.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/config/index.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/config/inputtransforms.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/config/integrating.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/config/intro.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/config/options/index.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/config/shell_mimerenderer.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/config/shortcuts/index.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/coredev/index.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/development/config.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/development/execution.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/development/figs/ipy_kernel_and_terminal.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/development/figs/ipy_kernel_and_terminal.svg +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/development/figs/other_kernels.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/development/figs/other_kernels.svg +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/development/how_ipython_works.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/development/index.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/development/inputhook_app.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/development/kernels.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/development/messaging.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/development/pycompat.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/development/wrapperkernels.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/index.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/install/index.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/install/install.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/install/kernel_install.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/interactive/autoawait.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/interactive/index.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/interactive/magics.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/interactive/plotting.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/interactive/python-ipython-diff.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/interactive/reference.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/interactive/shell.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/interactive/tips.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/interactive/tutorial.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/links.txt +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/overview.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/parallel/index.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/sphinx.toml +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/sphinxext.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/development.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/github-stats-0.11.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/github-stats-0.12.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/github-stats-0.13.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/github-stats-1.0.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/github-stats-2.0.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/github-stats-3.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/github-stats-4.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/github-stats-5.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/github-stats-6.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/github-stats-7.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/github-stats-8.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/index.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/pr/README.md +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/pr/antigravity-feature.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/pr/incompat-switching-to-perl.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/version0.10.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/version0.11.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/version0.12.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/version0.13.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/version0.8.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/version0.9.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/version1.0.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/version2.0.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/version3.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/version3_widget_migration.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/version4.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/version5.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/version6.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/version7.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/source/whatsnew/version8.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/sphinxext/apigen.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/sphinxext/configtraits.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/sphinxext/github.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/docs/sphinxext/magics.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/examples/Embedding/embed_class_long.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/examples/Embedding/embed_class_short.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/examples/Embedding/embed_function.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/examples/Embedding/start_ipython_config.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/examples/IPython Kernel/example-demo.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/examples/IPython Kernel/gui/gui-glut.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/examples/IPython Kernel/gui/gui-gtk4.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/examples/IPython Kernel/gui/gui-qt.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/examples/IPython Kernel/ipython-completion.bash +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/examples/IPython Kernel/ipython-get-history.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/examples/IPython Kernel/ipython.desktop +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/examples/auto_suggest_llm.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/examples/utils/cwd_prompt.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/examples/utils/list_pyfiles.ipy +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/examples/utils/list_subdirs.ipy +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/ipython.egg-info/SOURCES.txt +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/ipython.egg-info/dependency_links.txt +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/ipython.egg-info/entry_points.txt +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/ipython.egg-info/not-zip-safe +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/ipython.egg-info/top_level.txt +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/long_description.rst +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/scripts/ipython.ico +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/scripts/ipython_nb.ico +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/setup.cfg +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/setup.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/setupbase.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/2x2.jpg +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/2x2.png +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/__init__.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/bad_all.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/conftest.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/cve.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/fake_ext_dir/daft_extension.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/fake_llm.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/nonascii.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/nonascii2.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/print_argv.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/refbug.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/simpleerr.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/tclass.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test.wav +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_alias.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_application.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_async_helpers.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_autocall.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_backgroundjobs.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_capture.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_clipboard.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_compilerop.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_completerlib.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_debug_magic.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_decorators.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_decorators_2.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_deepreload.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_dir2.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_display.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_display_2.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_displayhook.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_editorhooks.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_embed.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_events.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_exceptiongroup_tb.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_extension.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_formatters.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_guarded_eval.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_handlers.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_help.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_history.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_hooks.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_imports.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_importstring.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_inputtransformer2.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_inputtransformer2_line.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_interactivshell.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_io.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_iplib.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_ipunittest.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_latextools.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_logger.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_magic_arguments.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_magic_terminal.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_module_paths.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_openpy.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_page.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_path.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_paths.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_prefilter.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_pretty.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_process.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_profile.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_pt_inputhooks.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_pylabtools.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_qt_loaders.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_run.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_shellapp.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_shortcuts.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_splitinput.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_storemagic.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_sysinfo.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_tempdir.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_tips.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_tokenutil.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_tools.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_wildcard.py +0 -0
- {ipython-9.4.0 → ipython-9.5.0}/tests/test_zzz_autoreload.py +0 -0
|
@@ -213,7 +213,11 @@ from typing import (
|
|
|
213
213
|
Literal,
|
|
214
214
|
)
|
|
215
215
|
|
|
216
|
-
from IPython.core.guarded_eval import
|
|
216
|
+
from IPython.core.guarded_eval import (
|
|
217
|
+
guarded_eval,
|
|
218
|
+
EvaluationContext,
|
|
219
|
+
_validate_policy_overrides,
|
|
220
|
+
)
|
|
217
221
|
from IPython.core.error import TryNext
|
|
218
222
|
from IPython.core.inputtransformer2 import ESC_MAGIC
|
|
219
223
|
from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
|
|
@@ -222,7 +226,6 @@ from IPython.utils import generics
|
|
|
222
226
|
from IPython.utils.PyColorize import theme_table
|
|
223
227
|
from IPython.utils.decorators import sphinx_options
|
|
224
228
|
from IPython.utils.dir2 import dir2, get_real_method
|
|
225
|
-
from IPython.utils.docs import GENERATING_DOCUMENTATION
|
|
226
229
|
from IPython.utils.path import ensure_dir_exists
|
|
227
230
|
from IPython.utils.process import arg_split
|
|
228
231
|
from traitlets import (
|
|
@@ -953,7 +956,6 @@ class CompletionSplitter:
|
|
|
953
956
|
return self._delim_re.split(cut_line)[-1]
|
|
954
957
|
|
|
955
958
|
|
|
956
|
-
|
|
957
959
|
class Completer(Configurable):
|
|
958
960
|
|
|
959
961
|
greedy = Bool(
|
|
@@ -1045,6 +1047,18 @@ class Completer(Configurable):
|
|
|
1045
1047
|
""",
|
|
1046
1048
|
).tag(config=True)
|
|
1047
1049
|
|
|
1050
|
+
@observe("evaluation")
|
|
1051
|
+
def _evaluation_changed(self, _change):
|
|
1052
|
+
_validate_policy_overrides(
|
|
1053
|
+
policy_name=self.evaluation, policy_overrides=self.policy_overrides
|
|
1054
|
+
)
|
|
1055
|
+
|
|
1056
|
+
@observe("policy_overrides")
|
|
1057
|
+
def _policy_overrides_changed(self, _change):
|
|
1058
|
+
_validate_policy_overrides(
|
|
1059
|
+
policy_name=self.evaluation, policy_overrides=self.policy_overrides
|
|
1060
|
+
)
|
|
1061
|
+
|
|
1048
1062
|
auto_import_method = DottedObjectName(
|
|
1049
1063
|
default_value="importlib.import_module",
|
|
1050
1064
|
allow_none=True,
|
|
@@ -1313,14 +1327,19 @@ class Completer(Configurable):
|
|
|
1313
1327
|
),
|
|
1314
1328
|
)
|
|
1315
1329
|
done = True
|
|
1316
|
-
except
|
|
1317
|
-
|
|
1318
|
-
|
|
1330
|
+
except (SyntaxError, TypeError):
|
|
1331
|
+
# TypeError can show up with something like `+ d`
|
|
1332
|
+
# where `d` is a dictionary.
|
|
1333
|
+
|
|
1319
1334
|
# trim the expression to remove any invalid prefix
|
|
1320
1335
|
# e.g. user starts `(d[`, so we get `expr = '(d'`,
|
|
1321
1336
|
# where parenthesis is not closed.
|
|
1322
1337
|
# TODO: make this faster by reusing parts of the computation?
|
|
1323
1338
|
expr = self._trim_expr(expr)
|
|
1339
|
+
except Exception as e:
|
|
1340
|
+
if self.debug:
|
|
1341
|
+
print("Evaluation exception", e)
|
|
1342
|
+
done = True
|
|
1324
1343
|
return obj
|
|
1325
1344
|
|
|
1326
1345
|
@property
|
|
@@ -1331,6 +1350,7 @@ class Completer(Configurable):
|
|
|
1331
1350
|
self._auto_import_func = import_item(self.auto_import_method)
|
|
1332
1351
|
return self._auto_import_func
|
|
1333
1352
|
|
|
1353
|
+
|
|
1334
1354
|
def get__all__entries(obj):
|
|
1335
1355
|
"""returns the strings in the __all__ attribute"""
|
|
1336
1356
|
try:
|
|
@@ -353,6 +353,26 @@ class Pdb(OldPdb):
|
|
|
353
353
|
self.initial_frame = frame
|
|
354
354
|
return super().set_trace(frame)
|
|
355
355
|
|
|
356
|
+
def get_stack(self, *args, **kwargs):
|
|
357
|
+
stack, pos = super().get_stack(*args, **kwargs)
|
|
358
|
+
if len(stack) >= 0 and self._is_internal_frame(stack[0][0]):
|
|
359
|
+
stack.pop(0)
|
|
360
|
+
pos -= 1
|
|
361
|
+
return stack, pos
|
|
362
|
+
|
|
363
|
+
def _is_internal_frame(self, frame):
|
|
364
|
+
"""Determine if this frame should be skipped as internal"""
|
|
365
|
+
filename = frame.f_code.co_filename
|
|
366
|
+
|
|
367
|
+
# Skip bdb.py runcall and internal operations
|
|
368
|
+
if filename.endswith("bdb.py"):
|
|
369
|
+
func_name = frame.f_code.co_name
|
|
370
|
+
# Skip internal bdb operations but allow breakpoint hits
|
|
371
|
+
if func_name in ("runcall", "run", "runeval"):
|
|
372
|
+
return True
|
|
373
|
+
|
|
374
|
+
return False
|
|
375
|
+
|
|
356
376
|
def _hidden_predicate(self, frame):
|
|
357
377
|
"""
|
|
358
378
|
Given a frame return whether it it should be hidden or not by IPython.
|
|
@@ -754,7 +774,7 @@ class Pdb(OldPdb):
|
|
|
754
774
|
bp,
|
|
755
775
|
(Token.LinenoEm, num),
|
|
756
776
|
(Token, " "),
|
|
757
|
-
# TODO:
|
|
777
|
+
# TODO: investigate Token.Line here
|
|
758
778
|
(Token, colored_line),
|
|
759
779
|
]
|
|
760
780
|
)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from copy import copy
|
|
2
|
-
from inspect import isclass, signature, Signature
|
|
2
|
+
from inspect import isclass, signature, Signature, getmodule
|
|
3
3
|
from typing import (
|
|
4
4
|
Annotated,
|
|
5
5
|
AnyStr,
|
|
@@ -21,6 +21,7 @@ import builtins
|
|
|
21
21
|
import collections
|
|
22
22
|
import operator
|
|
23
23
|
import sys
|
|
24
|
+
import warnings
|
|
24
25
|
from functools import cached_property
|
|
25
26
|
from dataclasses import dataclass, field
|
|
26
27
|
from types import MethodDescriptorType, ModuleType
|
|
@@ -122,14 +123,24 @@ class EvaluationPolicy:
|
|
|
122
123
|
def _get_external(module_name: str, access_path: Sequence[str]):
|
|
123
124
|
"""Get value from external module given a dotted access path.
|
|
124
125
|
|
|
126
|
+
Only gets value if the module is already imported.
|
|
127
|
+
|
|
125
128
|
Raises:
|
|
126
129
|
* `KeyError` if module is removed not found, and
|
|
127
130
|
* `AttributeError` if access path does not match an exported object
|
|
128
131
|
"""
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
132
|
+
try:
|
|
133
|
+
member_type = sys.modules[module_name]
|
|
134
|
+
# standard module
|
|
135
|
+
for attr in access_path:
|
|
136
|
+
member_type = getattr(member_type, attr)
|
|
137
|
+
return member_type
|
|
138
|
+
except (KeyError, AttributeError):
|
|
139
|
+
# handle modules in namespace packages
|
|
140
|
+
module_path = ".".join([module_name, *access_path])
|
|
141
|
+
if module_path in sys.modules:
|
|
142
|
+
return sys.modules[module_path]
|
|
143
|
+
raise
|
|
133
144
|
|
|
134
145
|
|
|
135
146
|
def _has_original_dunder_external(
|
|
@@ -139,18 +150,26 @@ def _has_original_dunder_external(
|
|
|
139
150
|
method_name: str,
|
|
140
151
|
):
|
|
141
152
|
if module_name not in sys.modules:
|
|
142
|
-
|
|
143
|
-
|
|
153
|
+
full_module_path = ".".join([module_name, *access_path])
|
|
154
|
+
if full_module_path not in sys.modules:
|
|
155
|
+
# LBYLB as it is faster
|
|
156
|
+
return False
|
|
144
157
|
try:
|
|
145
158
|
member_type = _get_external(module_name, access_path)
|
|
146
159
|
value_type = type(value)
|
|
147
160
|
if type(value) == member_type:
|
|
148
161
|
return True
|
|
162
|
+
if isinstance(member_type, ModuleType):
|
|
163
|
+
value_module = getmodule(value_type)
|
|
164
|
+
if not value_module or not value_module.__name__:
|
|
165
|
+
return False
|
|
166
|
+
if value_module.__name__.startswith(member_type.__name__):
|
|
167
|
+
return True
|
|
149
168
|
if method_name == "__getattribute__":
|
|
150
169
|
# we have to short-circuit here due to an unresolved issue in
|
|
151
170
|
# `isinstance` implementation: https://bugs.python.org/issue32683
|
|
152
171
|
return False
|
|
153
|
-
if isinstance(value, member_type):
|
|
172
|
+
if not isinstance(member_type, ModuleType) and isinstance(value, member_type):
|
|
154
173
|
method = getattr(value_type, method_name, None)
|
|
155
174
|
member_method = getattr(member_type, method_name, None)
|
|
156
175
|
if member_method == method:
|
|
@@ -185,35 +204,47 @@ def _has_original_dunder(
|
|
|
185
204
|
return False
|
|
186
205
|
|
|
187
206
|
|
|
207
|
+
def _coerce_path_to_tuples(
|
|
208
|
+
allow_list: set[tuple[str, ...] | str],
|
|
209
|
+
) -> set[tuple[str, ...]]:
|
|
210
|
+
"""Replace dotted paths on the provided allow-list with tuples."""
|
|
211
|
+
return {
|
|
212
|
+
path if isinstance(path, tuple) else tuple(path.split("."))
|
|
213
|
+
for path in allow_list
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
|
|
188
217
|
@undoc
|
|
189
218
|
@dataclass
|
|
190
219
|
class SelectivePolicy(EvaluationPolicy):
|
|
191
220
|
allowed_getitem: set[InstancesHaveGetItem] = field(default_factory=set)
|
|
192
|
-
allowed_getitem_external: set[tuple[str, ...]] = field(default_factory=set)
|
|
221
|
+
allowed_getitem_external: set[tuple[str, ...] | str] = field(default_factory=set)
|
|
193
222
|
|
|
194
223
|
allowed_getattr: set[MayHaveGetattr] = field(default_factory=set)
|
|
195
|
-
allowed_getattr_external: set[tuple[str, ...]] = field(default_factory=set)
|
|
224
|
+
allowed_getattr_external: set[tuple[str, ...] | str] = field(default_factory=set)
|
|
196
225
|
|
|
197
226
|
allowed_operations: set = field(default_factory=set)
|
|
198
|
-
allowed_operations_external: set[tuple[str, ...]] = field(default_factory=set)
|
|
227
|
+
allowed_operations_external: set[tuple[str, ...] | str] = field(default_factory=set)
|
|
199
228
|
|
|
200
229
|
_operation_methods_cache: dict[str, set[Callable]] = field(
|
|
201
230
|
default_factory=dict, init=False
|
|
202
231
|
)
|
|
203
232
|
|
|
204
233
|
def can_get_attr(self, value, attr):
|
|
234
|
+
allowed_getattr_external = _coerce_path_to_tuples(self.allowed_getattr_external)
|
|
235
|
+
|
|
205
236
|
has_original_attribute = _has_original_dunder(
|
|
206
237
|
value,
|
|
207
238
|
allowed_types=self.allowed_getattr,
|
|
208
239
|
allowed_methods=self._getattribute_methods,
|
|
209
|
-
allowed_external=
|
|
240
|
+
allowed_external=allowed_getattr_external,
|
|
210
241
|
method_name="__getattribute__",
|
|
211
242
|
)
|
|
212
243
|
has_original_attr = _has_original_dunder(
|
|
213
244
|
value,
|
|
214
245
|
allowed_types=self.allowed_getattr,
|
|
215
246
|
allowed_methods=self._getattr_methods,
|
|
216
|
-
allowed_external=
|
|
247
|
+
allowed_external=allowed_getattr_external,
|
|
217
248
|
method_name="__getattr__",
|
|
218
249
|
)
|
|
219
250
|
|
|
@@ -245,7 +276,7 @@ class SelectivePolicy(EvaluationPolicy):
|
|
|
245
276
|
return True # pragma: no cover
|
|
246
277
|
|
|
247
278
|
# Properties in subclasses of allowed types may be ok if not changed
|
|
248
|
-
for module_name, *access_path in
|
|
279
|
+
for module_name, *access_path in allowed_getattr_external:
|
|
249
280
|
try:
|
|
250
281
|
external_class = _get_external(module_name, access_path)
|
|
251
282
|
external_class_attr_val = getattr(external_class, attr)
|
|
@@ -257,15 +288,19 @@ class SelectivePolicy(EvaluationPolicy):
|
|
|
257
288
|
|
|
258
289
|
def can_get_item(self, value, item):
|
|
259
290
|
"""Allow accessing `__getiitem__` of allow-listed instances unless it was not modified."""
|
|
291
|
+
allowed_getitem_external = _coerce_path_to_tuples(self.allowed_getitem_external)
|
|
260
292
|
return _has_original_dunder(
|
|
261
293
|
value,
|
|
262
294
|
allowed_types=self.allowed_getitem,
|
|
263
295
|
allowed_methods=self._getitem_methods,
|
|
264
|
-
allowed_external=
|
|
296
|
+
allowed_external=allowed_getitem_external,
|
|
265
297
|
method_name="__getitem__",
|
|
266
298
|
)
|
|
267
299
|
|
|
268
300
|
def can_operate(self, dunders: tuple[str, ...], a, b=None):
|
|
301
|
+
allowed_operations_external = _coerce_path_to_tuples(
|
|
302
|
+
self.allowed_operations_external
|
|
303
|
+
)
|
|
269
304
|
objects = [a]
|
|
270
305
|
if b is not None:
|
|
271
306
|
objects.append(b)
|
|
@@ -275,7 +310,7 @@ class SelectivePolicy(EvaluationPolicy):
|
|
|
275
310
|
obj,
|
|
276
311
|
allowed_types=self.allowed_operations,
|
|
277
312
|
allowed_methods=self._operator_dunder_methods(dunder),
|
|
278
|
-
allowed_external=
|
|
313
|
+
allowed_external=allowed_operations_external,
|
|
279
314
|
method_name=dunder,
|
|
280
315
|
)
|
|
281
316
|
for dunder in dunders
|
|
@@ -315,15 +350,16 @@ class _DummyNamedTuple(NamedTuple):
|
|
|
315
350
|
"""Used internally to retrieve methods of named tuple instance."""
|
|
316
351
|
|
|
317
352
|
|
|
353
|
+
EvaluationPolicyName = Literal["forbidden", "minimal", "limited", "unsafe", "dangerous"]
|
|
354
|
+
|
|
355
|
+
|
|
318
356
|
class EvaluationContext(NamedTuple):
|
|
319
357
|
#: Local namespace
|
|
320
358
|
locals: dict
|
|
321
359
|
#: Global namespace
|
|
322
360
|
globals: dict
|
|
323
361
|
#: Evaluation policy identifier
|
|
324
|
-
evaluation:
|
|
325
|
-
"forbidden"
|
|
326
|
-
)
|
|
362
|
+
evaluation: EvaluationPolicyName = "forbidden"
|
|
327
363
|
#: Whether the evaluation of code takes place inside of a subscript.
|
|
328
364
|
#: Useful for evaluating ``:-1, 'col'`` in ``df[:-1, 'col']``.
|
|
329
365
|
in_subscript: bool = False
|
|
@@ -470,11 +506,24 @@ def get_policy(context: EvaluationContext) -> EvaluationPolicy:
|
|
|
470
506
|
for key, value in context.policy_overrides.items():
|
|
471
507
|
if hasattr(policy, key):
|
|
472
508
|
setattr(policy, key, value)
|
|
473
|
-
else:
|
|
474
|
-
print(f"Incorrect policy override key: {key}")
|
|
475
509
|
return policy
|
|
476
510
|
|
|
477
511
|
|
|
512
|
+
def _validate_policy_overrides(
|
|
513
|
+
policy_name: EvaluationPolicyName, policy_overrides: dict
|
|
514
|
+
) -> bool:
|
|
515
|
+
policy = EVALUATION_POLICIES[policy_name]
|
|
516
|
+
|
|
517
|
+
all_good = True
|
|
518
|
+
for key, value in policy_overrides.items():
|
|
519
|
+
if not hasattr(policy, key):
|
|
520
|
+
warnings.warn(
|
|
521
|
+
f"Override {key!r} is not valid with {policy_name!r} evaluation policy"
|
|
522
|
+
)
|
|
523
|
+
all_good = False
|
|
524
|
+
return all_good
|
|
525
|
+
|
|
526
|
+
|
|
478
527
|
def eval_node(node: Union[ast.AST, None], context: EvaluationContext):
|
|
479
528
|
"""Evaluate AST node in provided context.
|
|
480
529
|
|
|
@@ -586,7 +635,12 @@ def eval_node(node: Union[ast.AST, None], context: EvaluationContext):
|
|
|
586
635
|
dunders = _find_dunder(node.op, UNARY_OP_DUNDERS)
|
|
587
636
|
if dunders:
|
|
588
637
|
if policy.can_operate(dunders, value):
|
|
589
|
-
|
|
638
|
+
try:
|
|
639
|
+
return getattr(value, dunders[0])()
|
|
640
|
+
except AttributeError:
|
|
641
|
+
raise TypeError(
|
|
642
|
+
f"bad operand type for unary {node.op}: {type(value)}"
|
|
643
|
+
)
|
|
590
644
|
else:
|
|
591
645
|
raise GuardRejection(
|
|
592
646
|
f"Operation (`{dunders}`) for",
|
|
@@ -590,7 +590,7 @@ class HistoryOutput:
|
|
|
590
590
|
output_type: typing.Literal[
|
|
591
591
|
"out_stream", "err_stream", "display_data", "execute_result"
|
|
592
592
|
]
|
|
593
|
-
bundle: typing.Dict[str, str]
|
|
593
|
+
bundle: typing.Dict[str, str | list[str]]
|
|
594
594
|
|
|
595
595
|
|
|
596
596
|
class HistoryManager(HistoryAccessor):
|
|
@@ -3063,11 +3063,11 @@ class InteractiveShell(SingletonConfigurable):
|
|
|
3063
3063
|
output_stream = outputs[-1]
|
|
3064
3064
|
if output_stream is None:
|
|
3065
3065
|
output_stream = HistoryOutput(
|
|
3066
|
-
output_type=output_type, bundle={"stream":
|
|
3066
|
+
output_type=output_type, bundle={"stream": []}
|
|
3067
3067
|
)
|
|
3068
3068
|
outputs_by_counter[execution_count].append(output_stream)
|
|
3069
3069
|
|
|
3070
|
-
output_stream.bundle["stream"]
|
|
3070
|
+
output_stream.bundle["stream"].append(data) # Append to existing stream
|
|
3071
3071
|
return result
|
|
3072
3072
|
|
|
3073
3073
|
stream.write = write
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
from logging import error
|
|
5
5
|
import io
|
|
6
6
|
import os
|
|
7
|
+
import platform
|
|
7
8
|
from pprint import pformat
|
|
8
9
|
import sys
|
|
9
10
|
from warnings import warn
|
|
@@ -571,9 +572,11 @@ Currently the magic system has the following functions:""",
|
|
|
571
572
|
for output in outputs[execution_count]:
|
|
572
573
|
for mime_type, data in output.bundle.items():
|
|
573
574
|
if output.output_type == "out_stream":
|
|
574
|
-
|
|
575
|
+
text = data if isinstance(data, list) else [data]
|
|
576
|
+
cell.outputs.append(v4.new_output("stream", text=text))
|
|
575
577
|
elif output.output_type == "err_stream":
|
|
576
|
-
|
|
578
|
+
text = data if isinstance(data, list) else [data]
|
|
579
|
+
err_output = v4.new_output("stream", text=text)
|
|
577
580
|
err_output.name = "stderr"
|
|
578
581
|
cell.outputs.append(err_output)
|
|
579
582
|
elif output.output_type == "execute_result":
|
|
@@ -601,10 +604,44 @@ Currently the magic system has the following functions:""",
|
|
|
601
604
|
)
|
|
602
605
|
cells.append(cell)
|
|
603
606
|
|
|
604
|
-
|
|
607
|
+
kernel_language_info = self._get_kernel_language_info()
|
|
608
|
+
|
|
609
|
+
nb = v4.new_notebook(
|
|
610
|
+
cells=cells,
|
|
611
|
+
metadata={
|
|
612
|
+
"kernelspec": {
|
|
613
|
+
"display_name": "Python 3 (ipykernel)",
|
|
614
|
+
"language": "python",
|
|
615
|
+
"name": "python3",
|
|
616
|
+
},
|
|
617
|
+
"language_info": kernel_language_info
|
|
618
|
+
or {
|
|
619
|
+
"codemirror_mode": {
|
|
620
|
+
"name": "ipython",
|
|
621
|
+
"version": sys.version_info[0],
|
|
622
|
+
},
|
|
623
|
+
"file_extension": ".py",
|
|
624
|
+
"mimetype": "text/x-python",
|
|
625
|
+
"name": "python",
|
|
626
|
+
"nbconvert_exporter": "python",
|
|
627
|
+
"pygments_lexer": "ipython3",
|
|
628
|
+
"version": platform.python_version(),
|
|
629
|
+
},
|
|
630
|
+
},
|
|
631
|
+
)
|
|
605
632
|
with io.open(outfname, "w", encoding="utf-8") as f:
|
|
606
633
|
write(nb, f, version=4)
|
|
607
634
|
|
|
635
|
+
def _get_kernel_language_info(self) -> dict | None:
|
|
636
|
+
"""Get language info from kernel, useful when used in Jupyter Console where kernels exist."""
|
|
637
|
+
if not hasattr(self.shell, "kernel"):
|
|
638
|
+
return
|
|
639
|
+
if not hasattr(self.shell.kernel, "language_info"):
|
|
640
|
+
return
|
|
641
|
+
if not isinstance(self.shell.kernel.language_info, dict):
|
|
642
|
+
return
|
|
643
|
+
return self.shell.kernel.language_info
|
|
644
|
+
|
|
608
645
|
@magics_class
|
|
609
646
|
class AsyncMagics(BasicMagics):
|
|
610
647
|
|
|
@@ -361,8 +361,7 @@ class NamespaceMagics(Magics):
|
|
|
361
361
|
- For numpy arrays, a summary with shape, number of
|
|
362
362
|
elements, typecode and size in memory.
|
|
363
363
|
|
|
364
|
-
- For
|
|
365
|
-
objects, will print the shape.
|
|
364
|
+
- For DataFrame and Series types: their shape.
|
|
366
365
|
|
|
367
366
|
- Everything else: a string representation, snipping their middle if
|
|
368
367
|
too long.
|
|
@@ -450,7 +449,9 @@ class NamespaceMagics(Magics):
|
|
|
450
449
|
Mb = 1048576 # kb**2
|
|
451
450
|
for vname,var,vtype in zip(varnames,varlist,typelist):
|
|
452
451
|
print(vformat.format(vname, vtype, varwidth=varwidth, typewidth=typewidth), end=' ')
|
|
453
|
-
if vtype
|
|
452
|
+
if vtype in seq_types:
|
|
453
|
+
print("n="+str(len(var)))
|
|
454
|
+
elif vtype == ndarray_type:
|
|
454
455
|
vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
|
|
455
456
|
if vtype==ndarray_type:
|
|
456
457
|
# numpy
|
|
@@ -463,16 +464,13 @@ class NamespaceMagics(Magics):
|
|
|
463
464
|
else:
|
|
464
465
|
print(aformat % (vshape, vsize, vdtype, vbytes), end=' ')
|
|
465
466
|
if vbytes < Mb:
|
|
466
|
-
print(
|
|
467
|
+
print("(%s kb)" % (vbytes / kb,))
|
|
467
468
|
else:
|
|
468
469
|
print("(%s Mb)" % (vbytes / Mb,))
|
|
469
|
-
elif
|
|
470
|
+
elif vtype in ["DataFrame", "Series"]:
|
|
470
471
|
# Useful for DataFrames and Series
|
|
471
472
|
# Ought to work for both pandas and polars
|
|
472
473
|
print(f"Shape: {var.shape}")
|
|
473
|
-
elif hasattr(var, "__len__"):
|
|
474
|
-
## types that can be used in len function
|
|
475
|
-
print(var if isinstance(var, str) else f"n={len(var)}")
|
|
476
474
|
else:
|
|
477
475
|
try:
|
|
478
476
|
vstr = str(var)
|
|
@@ -237,7 +237,7 @@ class ScriptMagics(Magics):
|
|
|
237
237
|
chunk = decoder.decode("", final=True)
|
|
238
238
|
should_break = True
|
|
239
239
|
if stream_arg:
|
|
240
|
-
self.shell.user_ns[stream_arg]
|
|
240
|
+
self.shell.user_ns[stream_arg] += chunk
|
|
241
241
|
else:
|
|
242
242
|
file_object.write(chunk)
|
|
243
243
|
file_object.flush()
|
|
@@ -259,6 +259,11 @@ class ScriptMagics(Magics):
|
|
|
259
259
|
argv = arg_split(line, posix=not sys.platform.startswith("win"))
|
|
260
260
|
args, cmd = self.shebang.parser.parse_known_args(argv)
|
|
261
261
|
|
|
262
|
+
if args.out:
|
|
263
|
+
self.shell.user_ns[args.out] = ""
|
|
264
|
+
if args.err:
|
|
265
|
+
self.shell.user_ns[args.err] = ""
|
|
266
|
+
|
|
262
267
|
try:
|
|
263
268
|
p = in_thread(
|
|
264
269
|
asyncio.create_subprocess_exec(
|
|
@@ -4,6 +4,7 @@ import builtins
|
|
|
4
4
|
import contextlib
|
|
5
5
|
import itertools
|
|
6
6
|
import os
|
|
7
|
+
import pickle
|
|
7
8
|
import platform
|
|
8
9
|
import sys
|
|
9
10
|
import textwrap
|
|
@@ -25,7 +26,7 @@ if TYPE_CHECKING:
|
|
|
25
26
|
)
|
|
26
27
|
|
|
27
28
|
|
|
28
|
-
def get_module_file_name(module: ModuleType | str) -> str:
|
|
29
|
+
def get_module_file_name(module: ModuleType | str) -> str | None:
|
|
29
30
|
"""Returns the module's file path, or the empty string if it's inaccessible"""
|
|
30
31
|
if (mod := sys.modules.get(module) if isinstance(module, str) else module) is None:
|
|
31
32
|
return ""
|
|
@@ -200,8 +201,7 @@ class DeduperReloader(DeduperReloaderPatchingMixin):
|
|
|
200
201
|
for new_modname in sys.modules.keys() - self.source_by_modname.keys():
|
|
201
202
|
new_module = sys.modules[new_modname]
|
|
202
203
|
if (
|
|
203
|
-
(fname := get_module_file_name(new_module))
|
|
204
|
-
is None # type:ignore [redundant-expr]
|
|
204
|
+
(fname := get_module_file_name(new_module)) is None
|
|
205
205
|
or "site-packages" in fname
|
|
206
206
|
or "dist-packages" in fname
|
|
207
207
|
or not os.access(fname, os.R_OK)
|
|
@@ -287,7 +287,7 @@ class DeduperReloader(DeduperReloaderPatchingMixin):
|
|
|
287
287
|
result.inplace_merge(
|
|
288
288
|
cls._gather_children(handler.body, parent_node)
|
|
289
289
|
)
|
|
290
|
-
elif not isinstance(ast_elt, (ast.
|
|
290
|
+
elif not isinstance(ast_elt, (ast.Constant, ast.Pass)):
|
|
291
291
|
if cls.is_constexpr_assign(ast_elt, parent_node):
|
|
292
292
|
assert isinstance(ast_elt, (ast.Assign, ast.AnnAssign))
|
|
293
293
|
targets = (
|
|
@@ -416,7 +416,11 @@ class DeduperReloader(DeduperReloaderPatchingMixin):
|
|
|
416
416
|
namespace_to_check = ns
|
|
417
417
|
for prefix in prefixes:
|
|
418
418
|
namespace_to_check = namespace_to_check.__dict__[prefix]
|
|
419
|
+
seen_names: set[str] = set()
|
|
419
420
|
for names, new_ast_def in cur.defs_to_reload:
|
|
421
|
+
if len(names) == 1 and names[0] in seen_names:
|
|
422
|
+
continue
|
|
423
|
+
seen_names.update(names)
|
|
420
424
|
local_env: dict[str, Any] = {}
|
|
421
425
|
if (
|
|
422
426
|
isinstance(new_ast_def, (ast.FunctionDef, ast.AsyncFunctionDef))
|
|
@@ -435,37 +439,54 @@ class DeduperReloader(DeduperReloaderPatchingMixin):
|
|
|
435
439
|
global_env = ns.__dict__
|
|
436
440
|
if not isinstance(global_env, dict):
|
|
437
441
|
global_env = dict(global_env)
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
self.try_patch_attr(to_patch_to, to_patch_from, attr)
|
|
455
|
-
else:
|
|
456
|
-
self.patch_function(
|
|
457
|
-
getattr(to_patch_to, attr),
|
|
458
|
-
getattr(to_patch_from, attr),
|
|
459
|
-
is_method,
|
|
460
|
-
)
|
|
461
|
-
elif not isinstance(to_patch_to, property) and not isinstance(
|
|
462
|
-
to_patch_from, property
|
|
463
|
-
):
|
|
464
|
-
self.patch_function(to_patch_to, to_patch_from, is_method)
|
|
465
|
-
else:
|
|
466
|
-
raise ValueError(
|
|
467
|
-
"adding or removing property decorations not supported"
|
|
442
|
+
# Compile with correct filename to preserve in traceback
|
|
443
|
+
filename = (
|
|
444
|
+
getattr(to_patch_to, "__code__", None)
|
|
445
|
+
and to_patch_to.__code__.co_filename
|
|
446
|
+
or "<string>"
|
|
447
|
+
)
|
|
448
|
+
func_asts = [ast.parse(func_code)]
|
|
449
|
+
if len(cast(ast.FunctionDef, func_asts[0].body[0]).decorator_list) > 0:
|
|
450
|
+
without_decorator_list = pickle.loads(pickle.dumps(func_asts[0]))
|
|
451
|
+
cast(
|
|
452
|
+
ast.FunctionDef, without_decorator_list.body[0]
|
|
453
|
+
).decorator_list = []
|
|
454
|
+
func_asts.insert(0, without_decorator_list)
|
|
455
|
+
for func_ast in func_asts:
|
|
456
|
+
compiled_code = compile(
|
|
457
|
+
func_ast, filename, mode="exec", dont_inherit=True
|
|
468
458
|
)
|
|
459
|
+
exec(compiled_code, global_env, local_env) # type: ignore[arg-type]
|
|
460
|
+
# local_env contains the function exec'd from new version of function
|
|
461
|
+
if is_method:
|
|
462
|
+
to_patch_from = getattr(local_env["__autoreload_class__"], name)
|
|
463
|
+
else:
|
|
464
|
+
to_patch_from = local_env[name]
|
|
465
|
+
if isinstance(to_patch_from, (staticmethod, classmethod)):
|
|
466
|
+
to_patch_from = to_patch_from.__func__
|
|
467
|
+
if isinstance(to_patch_to, property) and isinstance(
|
|
468
|
+
to_patch_from, property
|
|
469
|
+
):
|
|
470
|
+
for attr in ("fget", "fset", "fdel"):
|
|
471
|
+
if (
|
|
472
|
+
getattr(to_patch_to, attr) is None
|
|
473
|
+
or getattr(to_patch_from, attr) is None
|
|
474
|
+
):
|
|
475
|
+
self.try_patch_attr(to_patch_to, to_patch_from, attr)
|
|
476
|
+
else:
|
|
477
|
+
self.patch_function(
|
|
478
|
+
getattr(to_patch_to, attr),
|
|
479
|
+
getattr(to_patch_from, attr),
|
|
480
|
+
is_method,
|
|
481
|
+
)
|
|
482
|
+
elif not isinstance(to_patch_to, property) and not isinstance(
|
|
483
|
+
to_patch_from, property
|
|
484
|
+
):
|
|
485
|
+
self.patch_function(to_patch_to, to_patch_from, is_method)
|
|
486
|
+
else:
|
|
487
|
+
raise ValueError(
|
|
488
|
+
"adding or removing property decorations not supported"
|
|
489
|
+
)
|
|
469
490
|
else:
|
|
470
491
|
exec(
|
|
471
492
|
ast.unparse(new_ast_def),
|