8000 Refactoring: Removing axis parameter from scales by vagnermcj · Pull Request #29988 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

Refactoring: Removing axis parameter from scales #29988

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 60 additions & 5 deletions lib/matplotlib/scale.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""
Scales define the distribution of data values on an axis, e.g. a log scaling.

Expand Down Expand Up @@ -31,6 +31,8 @@

import inspect
import textwrap
import warnings
from functools import wraps

import numpy as np

Expand Down Expand Up @@ -103,14 +105,49 @@
return vmin, vmax


def handle_axis_parameter(init_func):
"""
Allow scale classes to work with or without the `axis` parameter.

This decorator enables scale constructors to maintain backward
compatibility with older code that passes `axis`, while allowing
future implementations to omit it entirely.

If the wrapped constructor defines `axis` as its first argument,
the parameter is preserved. Otherwise, it is safely removed from
positional or keyword arguments.

Parameters
----------
init_func : callable
The original __init__ method of a scale class.

Returns
-------
callable
A wrapped version of `init_func` that handles the optional `axis`.
"""
@wraps(init_func)
def wrapper(self, *args, **kwargs):
sig = inspect.signature(init_func)
params = list(sig.parameters.values())
if params and params[1].name == "axis":
return init_func(self, *args, **kwargs)
if args:
args = args[1:]
kwargs.pop("axis", None)
return init_func(self, *args, **kwargs)

Check warning on line 139 in lib/matplotlib/scale.py

View check run for this annotation

Codecov / codecov/patch

lib/matplotlib/scale.py#L137-L139

Added lines #L137 - L139 were not covered by tests
return wrapper

class LinearScale(ScaleBase):

Check failure on line 142 in lib/matplotlib/scale.py

View workflow job for this annotation

GitHub Actions / ruff

[rdjson] reported by reviewdog 🐶 Expected 2 blank lines, found 1 Raw Output: message:"Expected 2 blank lines, found 1" location:{path:"/home/runner/work/matplotlib/matplotlib/lib/matplotlib/scale.py" range:{start:{line:142 column:1} end:{line:142 column:6}}} source:{name:"ruff" url:"https://docs.astral.sh/ruff"} code:{value:"E302" url:"https://docs.astral.sh/ruff/rules/blank-lines-top-level"} suggestions:{range:{start:{line:141 column:1} end:{line:142 column:1}} text:"\n\n"}
"""
The default linear scale.
"""

name = 'linear'

def __init__(self, axis):
@handle_axis_parameter
def __init__(self, axis=None):
# This method is present only to prevent inheritance of the base class'
# constructor docstring, which would otherwise end up interpolated into
# the docstring of Axis.set_scale.
Expand Down Expand Up @@ -180,6 +217,7 @@

name = 'function'

@handle_axis_parameter
def __init__(self, axis, functions):
"""
Parameters
Expand Down Expand Up @@ -279,7 +317,8 @@
"""
name = 'log'

def __init__(self, axis, *, base=10, subs=None, nonpositive="clip"):
@handle_axis_parameter

Check failure on line 320 in lib/matplotlib/scale.py

View workflow job for this annotation

GitHub Actions / ruff

[rdjson] reported by reviewdog 🐶 Trailing whitespace Raw Output: message:"Trailing whitespace" location:{path:"/home/runner/work/matplotlib/matplotlib/lib/matplotlib/scale.py" range:{start:{line:320 column:27} end:{line:320 column:29}}} source:{name:"ruff" url:"https://docs.astral.sh/ruff"} code:{value:"W291" url:"https://docs.astral.sh/ruff/rules/trailing-whitespace"} suggestions:{range:{start:{line:320 column:27} end:{line:320 column:29}}}
def __init__(self, axis=None, *, base=10, subs=None, nonpositive="clip"):
"""
Parameters
----------
Expand Down Expand Up @@ -330,6 +369,7 @@

name = 'functionlog'

@handle_axis_parameter
def __init__(self, axis, functions, base=10):
"""
Parameters
Expand Down Expand Up @@ -455,7 +495,8 @@
"""
name = 'symlog'

def __init__(self, axis, *, base=10, linthresh=2, subs=None, linscale=1):
@handle_axis_parameter
def __init__(self, axis=None, *, base=10, linthresh=2, subs=None, linscale=1):
self._transform = SymmetricalLogTransform(base, linthresh, linscale)
self.subs = subs

Expand Down Expand Up @@ -547,6 +588,7 @@
1024: (256, 512)
}

@handle_axis_parameter
def __init__(self, axis, *, linear_width=1.0,
base=10, subs='auto', **kwargs):
"""
Expand Down Expand Up @@ -645,7 +687,8 @@
"""
name = 'logit'

def __init__(self, axis, nonpositive='mask', *,
@handle_axis_parameter
def __init__(self, axis=None, nonpositive='mask', *,
one_half=r"\frac{1}{2}", use_overline=False):
r"""
Parameters
Expand Down Expand Up @@ -725,7 +768,12 @@
axis : `~matplotlib.axis.Axis`
"""
scale_cls = _api.check_getitem(_scale_mapping, scale=scale)
return scale_cls(axis, **kwargs)
try:
return scale_cls(axis, **kwargs)
except TypeError as e:
if 'unexpected keyword argument' in str(e) or 'positional argument' in str(e):
return scale_cls(**kwargs)
raise

Check warning on line 776 in lib/matplotlib/scale.py

View check run for this annotation

Codecov / codecov/patch

lib/matplotlib/scale.py#L776

Added line #L776 was not covered by tests


if scale_factory.__doc__:
Expand All @@ -742,6 +790,13 @@
scale_class : subclass of `ScaleBase`
The scale to register.
"""
sig = inspect.signature(scale_class.__init__)

Check warning on line 793 in lib/matplotlib/scale.py

View check run for this annotation

Codecov / codecov/patch

lib/matplotlib/scale.py#L793

Added line #L793 was not covered by tests
if 'axis' in sig.parameters:
warnings.warn(

Check warning on line 795 in lib/matplotlib/scale.py

View check run for this annotation

Codecov / codecov/patch

lib/matplotlib/scale.py#L795

Added line #L795 was not covered by tests
f"The scale class {scale_class.__name__} still uses the 'axis' parameter in its constructor. "

Check failure on line 796 in lib/matplotlib/scale.py

View workflow job for this annotation

GitHub Actions / ruff

[rdjson] reported by reviewdog 🐶 Line too long (106 > 88) Raw Output: message:"Line too long (106 > 88)" location:{path:"/home/runner/work/matplotlib/matplotlib/lib/matplotlib/scale.py" range:{start:{line:796 column:89} end:{line:796 column:107}}} source:{name:"ruff" url:"https://docs.astral.sh/ruff"} code:{value:"E501" url:"https://docs.astral.sh/ruff/rules/line-too-long"}
"Consider refactoring it to remove this dependency.",
DeprecationWarning
)
_scale_mapping[scale_class.name] = scale_class


Expand Down
Loading
0