Skip to content

Commit 91ff0a9

Browse files
committed
feat: add stricter ruff rules
1 parent a68434f commit 91ff0a9

75 files changed

Lines changed: 377 additions & 364 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/source/conf.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
# -*- coding: utf-8 -*-
2-
import sys
3-
import os
41
import datetime
5-
6-
from sphinx_gallery.sorting import ExampleTitleSortKey
2+
import os
3+
import sys
74

85
from pyproximal import __version__
6+
from sphinx_gallery.sorting import ExampleTitleSortKey
97

108
# Sphinx needs to be able to import the package to use autodoc and
119
# get the version number
@@ -93,17 +91,17 @@
9391
# General information about the project
9492
year = datetime.date.today().year
9593
project = "PyProximal"
96-
copyright = "{}, PyLops Development Team".format(year)
94+
copyright = f"{year}, PyLops Development Team"
9795

9896
# Version
9997
version = __version__
10098
if len(version.split("+")) > 1 or version == "unknown":
10199
version = "dev"
102100

103101
# These enable substitutions using |variable| in the rst files
104-
rst_epilog = """
102+
rst_epilog = f"""
105103
.. |year| replace:: {year}
106-
""".format(year=year)
104+
"""
107105

108106
html_static_path = ["_static"]
109107
html_last_updated_fmt = "%b %d, %Y"
@@ -146,7 +144,11 @@
146144
"doc_path": "docs/source",
147145
"galleries": sphinx_gallery_conf["gallery_dirs"],
148146
"gallery_dir": dict(
149-
zip(sphinx_gallery_conf["gallery_dirs"], sphinx_gallery_conf["examples_dirs"])
147+
zip(
148+
sphinx_gallery_conf["gallery_dirs"],
149+
sphinx_gallery_conf["examples_dirs"],
150+
strict=False,
151+
)
150152
),
151153
"github_project": "PyLops",
152154
"github_repo": "pyproximal",

examples/plot_concave_penalties.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
import matplotlib.pyplot as plt
99
import numpy as np
10-
1110
import pyproximal
1211

1312
plt.close("all")

examples/plot_dykstra.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
from matplotlib.colors import to_rgba
1616
from matplotlib.patches import Circle, Rectangle
1717
from pylops import MatrixMult
18-
1918
from pyproximal.projection import BoxProj, EuclideanBallProj, GenericIntersectionProj
2019
from pyproximal.proximal import L1, L2, Box, EuclideanBall, GenericIntersectionProx, Sum
2120

examples/plot_indicators.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
import matplotlib.pyplot as plt
1010
import numpy as np
11-
1211
import pyproximal
1312

1413
plt.close("all")

examples/plot_norms.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import matplotlib.pyplot as plt
1515
import numpy as np
1616
import pylops
17-
1817
import pyproximal
1918

2019
plt.close("all")

examples/plot_quadratic.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import matplotlib.pyplot as plt
1616
import numpy as np
1717
import pylops
18-
1918
import pyproximal
2019

2120
plt.close("all")

pyproject.toml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,25 @@ python_files = ["pytests/*.py"]
8282

8383
[tool.ruff]
8484
src = ["pyproximal"]
85+
exclude = ["pyproximal/version.py", ]
8586
line-length = 88
87+
target-version = "py310"
88+
89+
[tool.ruff.lint]
90+
select = [
91+
"E", # pycodestyle errors
92+
"F", # pyflakes
93+
"W", # pycodestyle warnings
94+
"B", # flake8-bugbear
95+
"EM", # flake8-errmsg
96+
"UP", # pyupgrade
97+
"I" # isort
98+
]
99+
ignore = [
100+
"E501", # line too long (handled by formatter like Black)
101+
"I001", # allow usorted imports
102+
"UP031", # use of old '%' formatting instead of f-strings
103+
]
86104

87105
[tool.ruff.lint.per-file-ignores]
88106
"__init__.py" = [
@@ -102,10 +120,10 @@ mypy_path = "pyproximal"
102120
strict = true
103121
enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
104122
disable_error_code = ["untyped-decorator"]
105-
warn_unreachable = true
106123
allow_redefinition = true
107124
disallow_untyped_defs = true
108125
disallow_incomplete_defs = true
126+
warn_unreachable = false
109127

110128
[[tool.mypy.overrides]]
111129
module = ["cupy.*", "numpy.*", "numba.*", "pylops.*", "scipy.*", "scooby.*", "pyproximal.*"]

pyproximal/ProxOperator.py

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from typing import TYPE_CHECKING, Any, Callable, Optional, Union
1+
from typing import TYPE_CHECKING, Any, Optional, Union
2+
from collections.abc import Callable
23

34
import numpy as np
45
from pylops.utils.typing import NDArray
@@ -19,13 +20,14 @@ def _check_tau(func: Callable[..., NDArray]) -> Callable[..., NDArray]:
1920

2021
def wrapper(*args: Any, **kwargs: Any) -> Any:
2122
if np.any(args[2] <= 0):
22-
raise ValueError("tau must be positive")
23+
msg = "tau must be positive"
24+
raise ValueError(msg)
2325
return func(*args, **kwargs)
2426

2527
return wrapper
2628

2729

28-
class ProxOperator(object):
30+
class ProxOperator:
2931
r"""Common interface for proximal operators of a function.
3032
3133
This class defines the overarching structure of any proximal operator. It
@@ -87,10 +89,11 @@ def __call__(self, x: NDArray) -> bool | float | int:
8789
Subclasses should implement this. Returns the
8890
value of the function.
8991
"""
90-
raise NotImplementedError(
92+
msg = (
9193
"This ProxOperator's __call__ method "
9294
"must be implemented by subclasses to return a float."
9395
)
96+
raise NotImplementedError(msg)
9497

9598
@_check_tau
9699
def _prox_moreau(self, x: NDArray, tau: float, **kwargs: Any) -> NDArray:
@@ -207,7 +210,8 @@ def affine_addition(self, v: NDArray) -> "ProxOperator":
207210
if isinstance(v, (np.ndarray, cp_dtype)):
208211
return _SumOperator(self, v)
209212
else:
210-
raise NotImplementedError("v must be a numpy.ndarray or cupy.ndarray")
213+
msg = "v must be a numpy.ndarray or cupy.ndarray"
214+
raise NotImplementedError(msg)
211215

212216
def postcomposition(self, sigma: float) -> "ProxOperator":
213217
r"""Postcomposition
@@ -235,7 +239,8 @@ def postcomposition(self, sigma: float) -> "ProxOperator":
235239
if isinstance(sigma, float):
236240
return _PostcompositionOperator(self, sigma)
237241
else:
238-
raise NotImplementedError("sigma must be of type float")
242+
msg = "sigma must be of type float"
243+
raise NotImplementedError(msg)
239244

240245
def precomposition(self, a: float, b: float | NDArray) -> "ProxOperator":
241246
r"""Precomposition
@@ -264,11 +269,8 @@ def precomposition(self, a: float, b: float | NDArray) -> "ProxOperator":
264269
if isinstance(a, float) and isinstance(b, (float, np.ndarray, cp_dtype)): # type: ignore[redundant-expr]
265270
return _PrecompositionOperator(self, a, b)
266271
else:
267-
raise NotImplementedError(
268-
"a must be of type float and b "
269-
"must be of type float or "
270-
"numpy.ndarray"
271-
)
272+
msg = "a must be of type float and b must be of type float or numpy.ndarray"
273+
raise NotImplementedError(msg)
272274

273275
def chain(self, g: "ProxOperator") -> "ProxOperator":
274276
r"""Chain
@@ -336,7 +338,8 @@ def __init__(self, f: ProxOperator, v: NDArray) -> None:
336338
# if not isinstance(f, ProxOperator):
337339
# raise ValueError('First input must be a ProxOperator')
338340
if not isinstance(v, (np.ndarray, cp_dtype)):
339-
raise ValueError("Second input must be a numpy.ndarray or cupy.ndarray")
341+
msg = "Second input must be a numpy.ndarray or cupy.ndarray"
342+
raise ValueError(msg)
340343
self.f, self.v = f, v
341344
super().__init__(None, f.hasgrad)
342345

@@ -375,7 +378,8 @@ def __init__(self, f: ProxOperator, sigma: float) -> None:
375378
# if not isinstance(f, ProxOperator):
376379
# raise ValueError('First input must be a ProxOperator')
377380
if not isinstance(sigma, float):
378-
raise ValueError("Second input must be a float")
381+
msg = "Second input must be a float"
382+
raise ValueError(msg)
379383
self.f, self.sigma = f, sigma
380384
super().__init__(None, f.hasgrad)
381385

@@ -395,11 +399,11 @@ def __init__(self, f: ProxOperator, a: float, b: float | NDArray) -> None:
395399
# if not isinstance(f, ProxOperator):
396400
# raise ValueError('First input must be a ProxOperator')
397401
if not isinstance(a, float):
398-
raise ValueError("Second input must be a float")
402+
msg = "Second input must be a float"
403+
raise ValueError(msg)
399404
if not isinstance(b, (float, np.ndarray, cp_dtype)):
400-
raise ValueError(
401-
"Third input must be a float, numpy.ndarray, or cupy.ndarray"
402-
)
405+
msg = "Third input must be a float, numpy.ndarray, or cupy.ndarray"
406+
raise ValueError(msg)
403407
self.f, self.a, self.b = f, a, b
404408
super().__init__(None, f.hasgrad)
405409

pyproximal/optimization/bregman.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import time
22
from copy import deepcopy
3-
from typing import TYPE_CHECKING, Any, Callable, Dict, Optional
3+
from typing import TYPE_CHECKING, Any, Optional
4+
from collections.abc import Callable
45

56
import numpy as np
67
from pylops.utils.typing import NDArray
@@ -22,9 +23,9 @@ def Bregman(
2223
warm: bool = False,
2324
tolx: float = 1e-10,
2425
tolf: float = 1e-10,
25-
bregcallback: Optional[Callable[[NDArray], None]] = None,
26+
bregcallback: Callable[[NDArray], None] | None = None,
2627
show: bool = False,
27-
**kwargs_solver: Dict[str, Any],
28+
**kwargs_solver: dict[str, Any],
2829
) -> NDArray:
2930
r"""Bregman iterations with Proximal Solver
3031

pyproximal/optimization/palm.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import time
2-
from typing import Callable, List, Optional, Tuple
2+
from collections.abc import Callable
33

44
import numpy as np
55
from pylops.utils.typing import NDArray
@@ -9,14 +9,14 @@
99

1010

1111
def _backtracking(
12-
x: List[NDArray],
12+
x: list[NDArray],
1313
tau: float,
1414
H: BilinearOperator,
15-
proxf: Optional[ProxOperator],
15+
proxf: ProxOperator | None,
1616
ix: int,
1717
beta: float = 0.5,
1818
niterback: int = 10,
19-
) -> Tuple[NDArray, float]:
19+
) -> tuple[NDArray, float]:
2020
r"""Backtracking
2121
2222
Line-search algorithm for finding step sizes in PALM algorithms when
@@ -27,7 +27,7 @@ def _backtracking(
2727

2828
def ftilde(
2929
x: NDArray,
30-
y: List[NDArray],
30+
y: list[NDArray],
3131
f: BilinearOperator,
3232
g: NDArray,
3333
tau: float,
@@ -59,18 +59,18 @@ def ftilde(
5959

6060
def PALM(
6161
H: BilinearOperator,
62-
proxf: Optional[ProxOperator],
63-
proxg: Optional[ProxOperator],
62+
proxf: ProxOperator | None,
63+
proxg: ProxOperator | None,
6464
x0: NDArray,
6565
y0: NDArray,
66-
gammaf: Optional[float] = 1.0,
67-
gammag: Optional[float] = 1.0,
66+
gammaf: float | None = 1.0,
67+
gammag: float | None = 1.0,
6868
beta: float = 0.5,
6969
niter: int = 10,
7070
niterback: int = 100,
71-
callback: Optional[Callable[[NDArray, NDArray], None]] = None,
71+
callback: Callable[[NDArray, NDArray], None] | None = None,
7272
show: bool = False,
73-
) -> Tuple[NDArray, NDArray]:
73+
) -> tuple[NDArray, NDArray]:
7474
r"""Proximal Alternating Linearized Minimization
7575
7676
Solves the following minimization problem using the Proximal Alternating
@@ -220,19 +220,19 @@ def PALM(
220220

221221
def iPALM(
222222
H: BilinearOperator,
223-
proxf: Optional[ProxOperator],
224-
proxg: Optional[ProxOperator],
223+
proxf: ProxOperator | None,
224+
proxg: ProxOperator | None,
225225
x0: NDArray,
226226
y0: NDArray,
227-
gammaf: Optional[float] = 1.0,
228-
gammag: Optional[float] = 1.0,
229-
a: List[float] = [1.0, 1.0],
227+
gammaf: float | None = 1.0,
228+
gammag: float | None = 1.0,
229+
a: tuple[float, float] = (1.0, 1.0),
230230
beta: float = 0.5,
231231
niter: int = 10,
232232
niterback: int = 100,
233-
callback: Optional[Callable[[NDArray, NDArray], None]] = None,
233+
callback: Callable[[NDArray, NDArray], None] | None = None,
234234
show: bool = False,
235-
) -> Tuple[NDArray, NDArray]:
235+
) -> tuple[NDArray, NDArray]:
236236
r"""Inertial Proximal Alternating Linearized Minimization
237237
238238
Solves the following minimization problem using the Inertial Proximal

0 commit comments

Comments
 (0)