MNT: Add type information to rcParams by timhoffm · Pull Request #32159 · matplotlib/matplotlib · GitHub
Skip to content

MNT: Add type information to rcParams - #32159

Merged
timhoffm merged 3 commits into
matplotlib:mainfrom
timhoffm:rcparams-type
Aug 6, 2026
Merged

timhoffm merged 3 commits into
matplotlib:mainfrom
timhoffm:rcparams-type

Conversation

@timhoffm

@timhoffm timhoffm commented Aug 1, 2026

Copy link
Copy Markdown
Member

PR summary

The added _Param.type attribute is currently used only for documentation, not for validation.
This allows to be more flexible and conveniently use type annotations such as int and list[float] | None, but also strings such as ":mpltype:`color`".

Additional notes:
type has a strong overlap with validators. Keeping them separate and have the duplication for now is a conscious design decision. In addtion to type checking, validators do more: They convert from string, because they are primarily built as a tooling to parse matplotlibrc. They can also do value validation beyond type validation (e.g. _validate_greaterthan_minushalf).
It is furthermore intentional to mostly standardize type towards type annotation and not use free text, even if that means we cannot express "greater thatn minus half". It is anticipated that we may use this information for type checking / validation eventually, e.g. we could build a TypedDict from this information, or maybe at some point we want to switch from a _Param specification to a specification via dataclasses. Proper type annotations will facilitate this.

AI Disclosure

no AI

PR quality check

  • Use an expressive title, e.g. "Fix title font property precedence"
  • [N/A] New and changed code is tested
  • [N/A] Plotting related features are demonstrated in an example
  • [N/A] New features and API changes have release notes
  • Documentation complies with general and docstring guidelines

@timhoffm
timhoffm force-pushed the rcparams-type branch 3 times, most recently from 1c203be to 6e24b6c Compare August 1, 2026 09:54
The added `_Param.type` attribute is currently used only for
documentation, not for validation.
This allows to be more flexible and conveniently use type annotations such as int and
list[float] | None, but also strings such as ":mpltype:`color`".
Comment thread lib/matplotlib/rcsetup.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

validate_fontsize() performs a s.lower(), so technically isn't this list too narrow? I don't think there's a way to specify a case-insensitive string as a type, however.

@timhoffm timhoffm Aug 3, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Correct. Here I define the "normalized" version as recommended spelling. It's ok if the parser is more permissive. For now, this is just for documentation, so a user is directed to use these forms. Even if we at some point in the future use this for type checking, it may prompt corrections in some cases, where they are not strictly necessary, but IMHO this is bearable and perferrable compared to doing a permissive specification.

The lower() is a historic artifact. I wouldn't do these nowadays because it's unnecessarily lax. But it's not important enough to narrow down the implementation and break user code.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

That makes a lot of sense! I figured that this was the case, but I wanted to mention every case where the type and the validator were mismatched.

Comment thread lib/matplotlib/rcsetup.py
"mathtext.fallback",
default="cm",
type=Literal["cm", "stix", "stixsans"] | None,
validator=_validate_mathtext_fallback,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

_validate_mathtext_fallback also does a s.lower()

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

As above. If in doubt, make the specification more strict and the implementation more permissive.

Comment thread lib/matplotlib/rcsetup.py Outdated
Comment thread lib/matplotlib/rcsetup.py
"xtick.minor.ndivs",
default="auto",
type=int | Literal["auto"],
validator=_validate_minor_tick_ndivs,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

_validate_minor_tick_ndivs() calls cbook._str_lower_equal

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

As above.

Comment thread lib/matplotlib/rcsetup.py
Comment thread lib/matplotlib/rcsetup.py
"center", "top", "bottom", "baseline", "center_baseline"],

"grid.color": validate_color, # grid color
"grid.linestyle": _validate_linestyle, # solid

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this is the mismatch causing the current test failure. I'm not sure if this can be _LineStyleType or not.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Whoops, the quick fix was too quick. I intended to update the type not the validator. Fixed.

Co-authored-by: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com>
@story645

story645 commented Aug 5, 2026

Copy link
Copy Markdown
Member

even if that means we cannot express "greater thatn minus half".

That can get encapsulated in a proper datatype though? (the __post_init__(self) method of a dataclass)

@timhoffm

timhoffm commented Aug 5, 2026

Copy link
Copy Markdown
Member Author

I don't follow. You could create a type LimitedFloat that does only accept this, but as far as I understand typing, a user supplied val: float = 0,1 will not be compatible with this. Or are you saying you want to internally store the values in a dataclass that does validation in __post_init__? Well first we are not using dataclasses, and second this would be runtime validation not static type limitation. In I expect that some form of normalization and validation will stay around and replace the _validate_* methods. The _validate_* methods are awkward because they convert everything from string. This was handy for simply parsing matplotlibrc files. But it's mixing concerns and we'll want to separate this in the future.

But that's all for later PRs.

@story645

story645 commented Aug 5, 2026

Copy link
Copy Markdown
Member

But it's mixing concerns and we'll want to separate this in the future.

Yeah, was just mentioning it as I think there's a way to encapsulate those constraints in types, with the implication being it's fine if this less precise form gets dropped now. Going down this rabbit hole, looks like Annotated is the way to do this cleanly.

@story645 story645 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Mostly questions/nits but useful info for docs.

Comment thread lib/matplotlib/rcsetup.py
Comment on lines +1489 to +1492

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just to make sure I'm understanding, this is why you can't use the colortypes in typing and the like and are using the doc types instead?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Correct.

Comment thread lib/matplotlib/rcsetup.py Outdated
Comment thread lib/matplotlib/rcsetup.py Outdated
Comment thread lib/matplotlib/rcsetup.py Outdated
Comment thread lib/matplotlib/rcsetup.py
@timhoffm
timhoffm merged commit f38d4ac into matplotlib:main Aug 6, 2026
40 of 41 checks passed
@timhoffm
timhoffm deleted the rcparams-type branch August 6, 2026 20:58
@QuLogic QuLogic added this to the v3.12.0 milestone Aug 7, 2026
clin1234 pushed a commit to clin1234/matplotlib that referenced this pull request Aug 23, 2026
* MNT: Add type information to rcParams

The added `_Param.type` attribute is currently used only for
documentation, not for validation.
This allows to be more flexible and conveniently use type annotations such as int and
list[float] | None, but also strings such as ":mpltype:`color`".

* Apply suggestions from code review

Co-authored-by: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com>

* Add review suggestions
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