|
2 | 2 | 9.x Series |
3 | 3 | ============ |
4 | 4 |
|
| 5 | +.. _version 9.16: |
| 6 | + |
| 7 | +IPython 9.16 |
| 8 | +------------ |
| 9 | + |
| 10 | +Summary |
| 11 | +~~~~~~~ |
| 12 | + |
| 13 | +This release contains two security-hardening fixes — HTML-attribute escaping in |
| 14 | +the display objects and closing an arbitrary-code-execution path in completion — |
| 15 | +a new ``cell_meta`` field on |
| 16 | +:class:`~IPython.core.interactiveshell.ExecutionInfo`, several completion, autoreload, |
| 17 | +and path-handling fixes, and two backwards-incompatible changes (``%lsmagic`` |
| 18 | +default output and the removal of long-deprecated APIs). It also includes a |
| 19 | +large amount of internal typing, test, and CI modernization. |
| 20 | + |
| 21 | +- :ghpull:`15337` Resolve attribute annotations under the policy in :func:`~IPython.core.guarded_eval.eval_node` |
| 22 | +- :ghpull:`15335` Make ``%lsmagic`` return plain text by default |
| 23 | +- :ghpull:`15334` Escape URLs and file names interpolated into display HTML attributes |
| 24 | +- :ghpull:`15332` Add yakuake to the list of Kitty-compatible terminals |
| 25 | +- :ghpull:`15330` Add version information to deprecation warnings |
| 26 | +- :ghpull:`15317` Only substitute ``~`` in :func:`~IPython.utils.path.compress_user` on a path-component boundary |
| 27 | +- :ghpull:`15314` Refactor banner property logic |
| 28 | +- :ghpull:`15310` Deprecation cleanup and decorator-dependency removal |
| 29 | +- :ghpull:`15289` Make caller locals visible to nested scopes in embedded shells |
| 30 | +- :ghpull:`15288` Limit file completions to path contexts |
| 31 | +- :ghpull:`15287` Centralize image format handling |
| 32 | +- :ghpull:`15285` Disable path elision in tab-completion with ``min_elide=0`` |
| 33 | +- :ghpull:`15276` Make :class:`~IPython.display.Image` with ``retina=True`` work with WebP |
| 34 | +- :ghpull:`15275` Fix memory leak and error handling in the LLM autosuggester |
| 35 | +- :ghpull:`15274` Reload ``__kwdefaults__``, ``__annotations__``, and ``__type_params__`` in autoreload |
| 36 | +- :ghpull:`15273` Close the history database during shell shutdown |
| 37 | +- :ghpull:`15266` Add test covering ``%%timeit`` cell magic output format with multiline code |
| 38 | +- :ghpull:`15260` Fix doctest prompt stripping regression |
| 39 | +- :ghpull:`15071` Add ``cell_meta`` to :class:`~IPython.core.interactiveshell.ExecutionInfo` and pass it through :meth:`~IPython.core.interactiveshell.InteractiveShell.run_cell` |
| 40 | + |
| 41 | +In addition, this release lands a broad sweep of internal maintenance: strict |
| 42 | +``mypy`` type checking and many new annotations, ``pyupgrade``/modernized type |
| 43 | +annotations, additional ``ruff`` rules, narrowed bare ``except:`` clauses, |
| 44 | +removal of the deprecated ``IPython.utils.py3compat`` module, new test coverage, |
| 45 | +and a number of test-suite resource-leak and CI fixes. |
| 46 | + |
| 47 | + |
| 48 | +Security Hardening |
| 49 | +~~~~~~~~~~~~~~~~~~~ |
| 50 | + |
| 51 | +Two fixes close paths that could execute unintended code or inject markup: |
| 52 | + |
| 53 | +- Values passed to the display objects were interpolated unescaped into quoted |
| 54 | + HTML attributes, so a quote character could close the attribute and have the |
| 55 | + remainder parsed as markup. :class:`~IPython.display.Image` and |
| 56 | + :class:`~IPython.display.Video` (``src``), :class:`~IPython.display.IFrame` |
| 57 | + and its :class:`~IPython.display.YouTubeVideo`/:class:`~IPython.display.VimeoVideo`/:class:`~IPython.display.ScribdDocument` |
| 58 | + subclasses (``src``, ``width``, ``height``, reachable through the id argument), |
| 59 | + :class:`~IPython.display.Audio` (url and ``element_id``), and the |
| 60 | + :class:`~IPython.display.FileLinks` formatter (names read off disk) now escape |
| 61 | + these values. For example ``YouTubeVideo('abc"><script>')`` no longer closes |
| 62 | + the iframe and injects markup (:ghpull:`15334`). |
| 63 | + |
| 64 | +- The attribute-completion branch in :func:`~IPython.core.guarded_eval.eval_node` |
| 65 | + fell back to :func:`typing.get_type_hints` after the completion policy had |
| 66 | + already refused an attribute. That call resolves stringized annotations with |
| 67 | + :func:`eval`, so completing ``obj.attr`` could run whatever an annotation |
| 68 | + contained under the default ``limited`` policy. Annotations are now collected |
| 69 | + with :func:`inspect.get_annotations` (``eval_str=False``) and resolved through |
| 70 | + :func:`~IPython.core.guarded_eval.eval_node`, routing them through the same |
| 71 | + policy checks as the rest of the input (:ghpull:`15337`). |
| 72 | + |
| 73 | + |
| 74 | +``cell_meta`` in ``ExecutionInfo`` |
| 75 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 76 | + |
| 77 | +The ``cell_meta`` field is now part of the |
| 78 | +:class:`~IPython.core.interactiveshell.ExecutionInfo` object passed to IPython |
| 79 | +extensions in the ``pre_run_cell`` and ``post_run_cell`` callbacks, letting |
| 80 | +extensions read per-cell metadata forwarded through |
| 81 | +:meth:`~IPython.core.interactiveshell.InteractiveShell.run_cell` |
| 82 | +(:ghpull:`15071`). |
| 83 | + |
| 84 | + |
| 85 | +Completion Improvements |
| 86 | +~~~~~~~~~~~~~~~~~~~~~~~~ |
| 87 | + |
| 88 | +File-name completions are now limited to contexts where a path is expected: |
| 89 | +string literals, shell and magic contexts, and explicit path-looking tokens. |
| 90 | +Direct path completion is preserved for prefixes such as ``./``, ``../``, ``~``, |
| 91 | +absolute paths, and Windows drive paths, and ``name = !command`` shell |
| 92 | +assignment is still recognized (:ghpull:`15288`, fixes :ghissue:`14501`). |
| 93 | + |
| 94 | +Setting ``c.TerminalInteractiveShell.min_elide = 0`` now completely disables |
| 95 | +filename abbreviation (path elision) in tab-completion output, for users who |
| 96 | +prefer to always see full completion paths (:ghpull:`15285`). |
| 97 | + |
| 98 | + |
| 99 | +Autoreload and Embedded Shells |
| 100 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 101 | + |
| 102 | +- ``%autoreload`` now also refreshes ``__kwdefaults__``, ``__annotations__``, |
| 103 | + and ``__type_params__`` when reloading functions, keeping reloaded objects |
| 104 | + consistent with the edited source (:ghpull:`15274`). |
| 105 | +- Local variables of the calling frame are now visible to nested scopes (such |
| 106 | + as comprehensions and nested functions) in embedded shells (:ghpull:`15289`). |
| 107 | + |
| 108 | + |
| 109 | +Doctest Prompt Stripping Regression |
| 110 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 111 | + |
| 112 | +A regression introduced in IPython 9.10 caused doctest prompts (``>>>`` and |
| 113 | +``...``) to stop being stripped inside multiline strings, after the input |
| 114 | +transformer's regex was tightened from ``\s`` to ``[ \t]`` to avoid eating |
| 115 | +newlines on bare continuation lines. The prompt stripper now strips leading |
| 116 | +PS1/PS2 prompts inside multiline strings only when they agree with the |
| 117 | +indentation of the outer stripped prompts, so genuine ``>>>``/``...`` text |
| 118 | +inside a multiline string is preserved (:ghpull:`15260`, fixes |
| 119 | +:ghissue:`15259`). |
| 120 | + |
| 121 | + |
| 122 | +Other Fixes |
| 123 | +~~~~~~~~~~~ |
| 124 | + |
| 125 | +- :func:`~IPython.utils.path.compress_user` — the reverse of |
| 126 | + :func:`os.path.expanduser` used when |
| 127 | + displaying paths — tested ``path.startswith(home)`` with no path-component |
| 128 | + boundary, so a path merely sharing a string prefix with ``$HOME`` (for example |
| 129 | + ``/home/alice-backup/...`` when ``$HOME`` is ``/home/alice``) was rewritten |
| 130 | + into a different, nonexistent ``~``-path. The substitution now only happens on |
| 131 | + a path separator boundary (:ghpull:`15317`). |
| 132 | +- :class:`~IPython.display.Image` with ``retina=True`` now works with WebP |
| 133 | + images (:ghpull:`15276`). |
| 134 | +- A memory leak in the LLM autosuggester was fixed and its errors are now |
| 135 | + handled gracefully (:ghpull:`15275`). |
| 136 | +- The history database is now closed during shell shutdown, avoiding a leaked |
| 137 | + connection (:ghpull:`15273`). |
| 138 | +- ``yakuake`` is now recognized as a Kitty-graphics-compatible terminal |
| 139 | + (:ghpull:`15332`). |
| 140 | + |
| 141 | + |
| 142 | +Backwards incompatible changes |
| 143 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 144 | + |
| 145 | +``%lsmagic`` now returns plain text by default so that frontends render its |
| 146 | +human-readable output consistently. Use ``%lsmagic --json`` to retrieve the |
| 147 | +machine-readable mapping of registered magics (:ghpull:`15335`). |
| 148 | + |
| 149 | +A number of APIs that had been emitting deprecation warnings for several years |
| 150 | +have been removed (:ghpull:`15310`): |
| 151 | + |
| 152 | +- ``IPCompleter.limit_to__all__`` configuration option (deprecated since |
| 153 | + IPython 5.0). Completion on ``object.<tab>`` now always uses :func:`dir`-based |
| 154 | + discovery, regardless of ``__all__``. |
| 155 | +- ``IPCompleter.python_matches`` method (deprecated since IPython 8.27). Use |
| 156 | + :meth:`~IPython.core.completer.IPCompleter.python_matcher` instead. |
| 157 | +- ``OInfo.get()`` (deprecated since IPython 8.13). Access the dataclass fields |
| 158 | + directly, e.g. ``oinfo.found`` instead of ``oinfo.get('found')``. |
| 159 | +- The module-level ``backends`` and ``backend2gui`` attributes of |
| 160 | + :mod:`IPython.core.pylabtools` (deprecated since IPython 8.24). Matplotlib |
| 161 | + backends are resolved by Matplotlib itself since 3.9. |
| 162 | +- :meth:`~IPython.core.interactiveshell.InteractiveShell.run_cell_async` and |
| 163 | + :meth:`~IPython.core.interactiveshell.InteractiveShell.should_run_async` no |
| 164 | + longer call :meth:`~IPython.core.interactiveshell.InteractiveShell.transform_cell` |
| 165 | + automatically when ``transformed_cell`` is not passed (this fallback had |
| 166 | + emitted a :exc:`DeprecationWarning` since IPython 7.17); they now raise a |
| 167 | + :exc:`TypeError`. Run |
| 168 | + :meth:`~IPython.core.interactiveshell.InteractiveShell.transform_cell` |
| 169 | + yourself and pass the result via the ``transformed_cell`` keyword argument (as |
| 170 | + ipykernel 6.0 and newer already do). |
| 171 | + :meth:`~IPython.core.interactiveshell.InteractiveShell.run_cell` is unaffected. |
| 172 | + |
| 173 | +The deprecated ``IPython.utils.py3compat`` module has also been removed, and its |
| 174 | +utilities inlined at their call sites (:ghpull:`15292`). |
| 175 | + |
| 176 | + |
| 177 | +Deprecations |
| 178 | +~~~~~~~~~~~~ |
| 179 | + |
| 180 | +Deprecation warnings emitted by IPython now include the version in which the |
| 181 | +feature was deprecated, making it easier to tell how long a warning has been |
| 182 | +outstanding (:ghpull:`15330`). |
| 183 | + |
| 184 | + |
| 185 | +Thanks |
| 186 | +~~~~~~ |
| 187 | + |
| 188 | +Thanks as well to the `D. E. Shaw group <https://deshaw.com/>`_ for sponsoring |
| 189 | +work on IPython. |
| 190 | + |
| 191 | +As usual, you can find the full list of PRs on GitHub under `the 9.16 |
| 192 | +<https://github.com/ipython/ipython/milestone/168?closed=1>`__ milestone. |
| 193 | + |
| 194 | + |
5 | 195 | .. _version 9.15: |
6 | 196 |
|
7 | 197 | IPython 9.15 |
|
0 commit comments