Skip to content

Comments

Speedup normalize_kwargs by storing aliases in a more practical format.#31023

Merged
timhoffm merged 1 commit intomatplotlib:mainfrom
anntzer:nk
Jan 24, 2026
Merged

Speedup normalize_kwargs by storing aliases in a more practical format.#31023
timhoffm merged 1 commit intomatplotlib:mainfrom
anntzer:nk

Conversation

@anntzer
Copy link
Contributor

@anntzer anntzer commented Jan 23, 2026

Directly store property alias information in {"alias": "propety", ...} format, which greatly speeds up normalize_kwargs.

In order to not worry about two different dict formats (the new one, and the old one, which was {"property": ["alias", ...], ...}) in normalize_kwargs, deprecate support for directly passing an alias map -- callers should always pass an artist (or artist type) directly, which hides the detail of the format of the alias map. Also deprecate passing alias_mapping=None, which doesn't really seem needed (unlike kw=None, which is regularly used).

Whether the format of aliases passed to _api.define_aliases should also be changed to match the new format is a separate question that doesn't have to be addressed here (it can be changed later, being fully private anyways).

See discussion at #30979, which this partially addresses.

PR summary

PR checklist

(
{"a": 1, "b": 2},
_api.define_aliases({"a": ["b"]})(
type("Type", (mpl.artist.Artist,), {"get_a": lambda self: None})),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the undecorated type is always the same, is it worth defining it inside the tests and only parametrizing the dictionary? Or defining it once before fail_mapping and pass_mapping?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The decorator modifies the underlying class in-place (it does not return a new class), so you need to generate a new class each time (because the aliases are not always the same).

Copy link
Member

@rcomer rcomer Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes of course, so you cannot define it before. But I still think it could be defined within the tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good idea, done

raise NotImplementedError(
f"Parent class already defines conflicting aliases: {conflicting}")
cls._alias_map = {**preexisting_aliases, **alias_d}
cls._alias_map = {**preexisting_aliases, **alias_to_prop}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For clarity of the mapping, and to make the semantic change more obvious, can we rename this

Suggested change
cls._alias_map = {**preexisting_aliases, **alias_to_prop}
cls._alias_to_prop = {**preexisting_aliases, **alias_to_prop}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure

def normalize_kwargs(
kw: dict[str, Any],
alias_mapping: dict[str, list[str]] | type[Artist] | Artist | None = ...,
alias_mapping: type[Artist] | Artist = ...,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
alias_mapping: type[Artist] | Artist = ...,
alias_mapping: type[Artist] | Artist | None = ...,

I haven't checked but I think this will clear up the stubtest failure. We do not have guidance for removal of a default in the guide, but I think the closest is

Items decorated with @_api.delete_parameter should include a default value hint for the deleted parameter
https://matplotlib.org/devdocs/devel/api_changes.html#introduce-deprecation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for looking into it, hopefully fixed now.

Directly store property alias information in `{"alias": "propety", ...}`
format, which greatly speeds up normalize_kwargs.

In order to not worry about two different dict formats (the new one, and
the old one, which was `{"property": ["alias", ...], ...}`) in
normalize_kwargs, deprecate support for directly passing an alias map --
callers should always pass an artist (or artist type) directly, which
hides the detail of the format of the alias map.  Also deprecate passing
`alias_mapping=None`, which doesn't really seem needed (unlike
`kw=None`, which is regularly used).

Whether the format of aliases passed to `_api.define_aliases` should
also be changed to match the new format is a separate question that
doesn't have to be addressed here (it can be changed later, being fully
private anyways).
@timhoffm timhoffm merged commit 5dee947 into matplotlib:main Jan 24, 2026
40 checks passed
@anntzer anntzer deleted the nk branch January 24, 2026 17:42
@QuLogic QuLogic added this to the v3.11.0 milestone Jan 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants