|
| 1 | +.. _api_changes: |
| 2 | + |
| 3 | +API changes |
| 4 | +=========== |
| 5 | + |
| 6 | +API consistency and stability are of great value; Therefore, API changes |
| 7 | +(e.g. signature changes, behavior changes, removals) will only be conducted |
| 8 | +if the added benefit is worth the effort of adapting existing code. |
| 9 | + |
| 10 | +Because we are a visualization library, our primary output is the final |
| 11 | +visualization the user sees; therefore, the appearance of the figure is part of |
| 12 | +the API and any changes, either semantic or :ref:`aesthetic <color_changes>`, |
| 13 | +are backwards-incompatible API changes. |
| 14 | + |
| 15 | +.. toctree:: |
| 16 | + :hidden: |
| 17 | + |
| 18 | + color_changes.rst |
| 19 | + |
| 20 | +.. _api_whats_new: |
| 21 | + |
| 22 | +Announce changes, deprecations, and new features |
| 23 | +------------------------------------------------ |
| 24 | + |
| 25 | +When adding or changing the API in a backward in-compatible way, please add the |
| 26 | +appropriate :ref:`versioning directive <versioning-directives>` and document it |
| 27 | +for the release notes and add the entry to the appropriate folder: |
| 28 | + |
| 29 | ++-------------------+-----------------------------+----------------------------------------------+ |
| 30 | +| addition | versioning directive | announcement folder | |
| 31 | ++===================+=============================+==============================================+ |
| 32 | +| new feature | ``.. versionadded:: 3.N`` | :file:`doc/users/next_whats_new/` | |
| 33 | ++-------------------+-----------------------------+----------------------------------------------+ |
| 34 | +| API change | ``.. versionchanged:: 3.N`` | :file:`doc/api/next_api_changes/[kind]` | |
| 35 | ++-------------------+-----------------------------+----------------------------------------------+ |
| 36 | + |
| 37 | +API deprecations are first introduced and then expired. During the introduction |
| 38 | +period, users are warned that the API *will* change in the future. |
| 39 | +During the expiration period, code is changed as described in the notice posted |
| 40 | +during the introductory period. |
| 41 | + |
| 42 | ++-----------+--------------------------------------------------+----------------------------------------------+ |
| 43 | +| stage | required changes | announcement folder | |
| 44 | ++===========+==================================================+==============================================+ |
| 45 | +| introduce | :ref:`introduce deprecation <intro-deprecation>` | :file:`doc/api/next_api_changes/deprecation` | |
| 46 | ++-----------+--------------------------------------------------+----------------------------------------------+ |
| 47 | +| expire | :ref:`expire deprecation <expire-deprecation>` | :file:`doc/api/next_api_changes/[kind]` | |
| 48 | ++-----------+--------------------------------------------------+----------------------------------------------+ |
| 49 | + |
| 50 | +For both change notes and what's new, please avoid using references in section |
| 51 | +titles, as it causes links to be confusing in the table of contents. Instead, |
| 52 | +ensure that a reference is included in the descriptive text. |
| 53 | + |
| 54 | +API Change Notes |
| 55 | +^^^^^^^^^^^^^^^^ |
| 56 | + |
| 57 | +.. include:: ../api/next_api_changes/README.rst |
| 58 | + :start-line: 5 |
| 59 | + :end-line: 31 |
| 60 | + |
| 61 | +What's new |
| 62 | +^^^^^^^^^^ |
| 63 | + |
| 64 | +.. include:: ../users/next_whats_new/README.rst |
| 65 | + :start-line: 5 |
| 66 | + :end-line: 24 |
| 67 | + |
| 68 | + |
| 69 | +Deprecation |
| 70 | +----------- |
| 71 | + |
| 72 | +API changes in Matplotlib have to be performed following the deprecation process |
| 73 | +below, except in very rare circumstances as deemed necessary by the development |
| 74 | +team. This ensures that users are notified before the change will take effect |
| 75 | +and thus prevents unexpected breaking of code. |
| 76 | + |
| 77 | +Rules |
| 78 | +^^^^^ |
| 79 | +- Deprecations are targeted at the next point.release (e.g. 3.x) |
| 80 | +- Deprecated API is generally removed two point-releases after introduction |
| 81 | + of the deprecation. Longer deprecations can be imposed by core developers on |
| 82 | + a case-by-case basis to give more time for the transition |
| 83 | +- The old API must remain fully functional during the deprecation period |
| 84 | +- If alternatives to the deprecated API exist, they should be available |
| 85 | + during the deprecation period |
| 86 | +- If in doubt, decisions about API changes are finally made by the |
| 87 | + `API consistency lead <https://matplotlib.org/governance/people.html>`_ developer. |
| 88 | + |
| 89 | +.. _intro-deprecation: |
| 90 | + |
| 91 | +Introduce deprecation |
| 92 | +^^^^^^^^^^^^^^^^^^^^^ |
| 93 | + |
| 94 | +#. Create :ref:`deprecation notice <api_whats_new>` |
| 95 | + |
| 96 | +#. If possible, issue a `~matplotlib.MatplotlibDeprecationWarning` when the |
| 97 | + deprecated API is used. There are a number of helper tools for this: |
| 98 | + |
| 99 | + - Use ``_api.warn_deprecated()`` for general deprecation warnings |
| 100 | + - Use the decorator ``@_api.deprecated`` to deprecate classes, functions, |
| 101 | + methods, or properties |
| 102 | + - Use ``@_api.deprecate_privatize_attribute`` to annotate deprecation of |
| 103 | + attributes while keeping the internal private version. |
| 104 | + - To warn on changes of the function signature, use the decorators |
| 105 | + ``@_api.delete_parameter``, ``@_api.rename_parameter``, and |
| 106 | + ``@_api.make_keyword_only`` |
| 107 | + |
| 108 | + All these helpers take a first parameter *since*, which should be set to |
| 109 | + the next point release, e.g. "3.x". |
| 110 | + |
| 111 | + You can use standard rst cross references in *alternative*. |
| 112 | + |
| 113 | +#. Make appropriate changes to the type hints in the associated ``.pyi`` file. |
| 114 | + The general guideline is to match runtime reported behavior. |
| 115 | + |
| 116 | + - Items marked with ``@_api.deprecated`` or ``@_api.deprecate_privatize_attribute`` |
| 117 | + are generally kept during the expiry period, and thus no changes are needed on |
| 118 | + introduction. |
| 119 | + - Items decorated with ``@_api.rename_parameter`` or ``@_api.make_keyword_only`` |
| 120 | + report the *new* (post deprecation) signature at runtime, and thus *should* be |
| 121 | + updated on introduction. |
| 122 | + - Items decorated with ``@_api.delete_parameter`` should include a default value hint |
| 123 | + for the deleted parameter, even if it did not previously have one (e.g. |
| 124 | + ``param: <type> = ...``). |
| 125 | + |
| 126 | +.. _expire-deprecation: |
| 127 | + |
| 128 | +Expire deprecation |
| 129 | +^^^^^^^^^^^^^^^^^^ |
| 130 | + |
| 131 | +#. Create :ref:`deprecation announcement <api_whats_new>`. For the content, |
| 132 | + you can usually copy the deprecation notice and adapt it slightly. |
| 133 | + |
| 134 | +#. Change the code functionality and remove any related deprecation warnings. |
| 135 | + |
| 136 | +#. Make appropriate changes to the type hints in the associated ``.pyi`` file. |
| 137 | + |
| 138 | + - Items marked with ``@_api.deprecated`` or ``@_api.deprecate_privatize_attribute`` |
| 139 | + are to be removed on expiry. |
| 140 | + - Items decorated with ``@_api.rename_parameter`` or ``@_api.make_keyword_only`` |
| 141 | + will have been updated at introduction, and require no change now. |
| 142 | + - Items decorated with ``@_api.delete_parameter`` will need to be updated to the |
| 143 | + final signature, in the same way as the ``.py`` file signature is updated. |
| 144 | + - Any entries in :file:`ci/mypy-stubtest-allowlist.txt` which indicate a deprecation |
| 145 | + version should be double checked. In most cases this is not needed, though some |
| 146 | + items were never type hinted in the first place and were added to this file |
| 147 | + instead. For removed items that were not in the stub file, only deleting from the |
| 148 | + allowlist is required. |
| 149 | + |
| 150 | +Adding new API and features |
| 151 | +--------------------------- |
| 152 | + |
| 153 | +Every new function, parameter and attribute that is not explicitly marked as |
| 154 | +private (i.e., starts with an underscore) becomes part of Matplotlib's public |
| 155 | +API. As discussed above, changing the existing API is cumbersome. Therefore, |
| 156 | +take particular care when adding new API: |
| 157 | + |
| 158 | +- Mark helper functions and internal attributes as private by prefixing them |
| 159 | + with an underscore. |
| 160 | +- Carefully think about good names for your functions and variables. |
| 161 | +- Try to adopt patterns and naming conventions from existing parts of the |
| 162 | + Matplotlib API. |
| 163 | +- Consider making as many arguments keyword-only as possible. See also |
| 164 | + `API Evolution the Right Way -- Add Parameters Compatibly`__. |
| 165 | + |
| 166 | + __ https://emptysqua.re/blog/api-evolution-the-right-way/#adding-parameters |
| 167 | + |
| 168 | + |
| 169 | +.. _versioning-directives: |
| 170 | + |
| 171 | +Versioning directives |
| 172 | +--------------------- |
| 173 | + |
| 174 | +When making a backward incompatible change, please add a versioning directive in |
| 175 | +the docstring. The directives should be placed at the end of a description block. |
| 176 | +For example:: |
| 177 | + |
| 178 | + class Foo: |
| 179 | + """ |
| 180 | + This is the summary. |
| 181 | + |
| 182 | + Followed by a longer description block. |
| 183 | + |
| 184 | + Consisting of multiple lines and paragraphs. |
| 185 | + |
| 186 | + .. versionadded:: 3.5 |
| 187 | + |
| 188 | + Parameters |
| 189 | + ---------- |
| 190 | + a : int |
| 191 | + The first parameter. |
| 192 | + b: bool, default: False |
| 193 | + This was added later. |
| 194 | + |
| 195 | + .. versionadded:: 3.6 |
| 196 | + """ |
| 197 | + |
| 198 | + def set_b(b): |
| 199 | + """ |
| 200 | + Set b. |
| 201 | + |
| 202 | + .. versionadded:: 3.6 |
| 203 | + |
| 204 | + Parameters |
| 205 | + ---------- |
| 206 | + b: bool |
| 207 | + |
| 208 | +For classes and functions, the directive should be placed before the |
| 209 | +*Parameters* section. For parameters, the directive should be placed at the |
| 210 | +end of the parameter description. The patch release version is omitted and |
| 211 | +the directive should not be added to entire modules. |
0 commit comments