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