diff --git a/docs/conf.py b/docs/conf.py index 134a3249..5bee558b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -99,7 +99,7 @@ # A dictionary for users defined type aliases that maps a type name to the # full-qualified object name. -autodoc_type_aliases = dict(AxesPoints="scanspec.core.AxesPoints") +autodoc_type_aliases = {"AxesPoints": "scanspec.core.AxesPoints"} # Include source in plot directive by default plot_include_source = True diff --git a/pyproject.toml b/pyproject.toml index a49fc1bd..1b28f28e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -120,7 +120,9 @@ commands = [tool.ruff] src = ["src", "tests"] line-length = 88 -lint.select = [ + +[tool.ruff.lint] +extend-select = [ "B", # flake8-bugbear - https://docs.astral.sh/ruff/rules/#flake8-bugbear-b "C4", # flake8-comprehensions - https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4 "E", # pycodestyle errors - https://docs.astral.sh/ruff/rules/#error-e @@ -129,3 +131,8 @@ lint.select = [ "I", # isort - https://docs.astral.sh/ruff/rules/#isort-i "UP", # pyupgrade - https://docs.astral.sh/ruff/rules/#pyupgrade-up ] +# We use pydantic, so don't upgrade to py3.10 syntax yet +pyupgrade.keep-runtime-typing = true +ignore = [ + "B008", # We use function calls in service arguments +] diff --git a/src/scanspec/__init__.py b/src/scanspec/__init__.py index 9dbfcd74..b99257eb 100644 --- a/src/scanspec/__init__.py +++ b/src/scanspec/__init__.py @@ -1,4 +1,4 @@ +from . import regions, specs from ._version import __version__ -from . import specs, regions __all__ = ["__version__", "specs", "regions"] diff --git a/src/scanspec/core.py b/src/scanspec/core.py index 3b1e015b..adda713d 100644 --- a/src/scanspec/core.py +++ b/src/scanspec/core.py @@ -134,7 +134,6 @@ def _discriminated_union_of_subclasses( discriminator: str, config: Optional[Type[BaseConfig]] = None, ) -> Union[Type, Callable[[Type], Type]]: - super_cls._ref_classes = set() super_cls._model = None @@ -253,8 +252,8 @@ def __init__( # Need to calculate gap as not passed one # We have a gap if upper[i] != lower[i+1] for any axes axes_gap = [ - np.roll(u, 1) != l - for u, l in zip(self.upper.values(), self.lower.values()) + np.roll(upper, 1) != lower + for upper, lower in zip(self.upper.values(), self.lower.values()) ] self.gap = np.logical_or.reduce(axes_gap) # Check all axes and ordering are the same @@ -263,11 +262,11 @@ def __init__( f"{list(self.midpoints)} != {list(self.lower)} != {list(self.upper)}" ) # Check all lengths are the same - lengths = set( + lengths = { len(arr) for d in (self.midpoints, self.lower, self.upper) for arr in d.values() - ) + } lengths.add(len(self.gap)) assert len(lengths) <= 1, f"Mismatching lengths {list(lengths)}" @@ -374,7 +373,7 @@ def _merge_frames( dict_merge=Callable[[Sequence[AxesPoints[Axis]]], AxesPoints[Axis]], gap_merge=Callable[[Sequence[np.ndarray]], Optional[np.ndarray]], ) -> Frames[Axis]: - types = set(type(fs) for fs in stack) + types = {type(fs) for fs in stack} assert len(types) == 1, f"Mismatching types for {stack}" cls = types.pop() diff --git a/src/scanspec/plot.py b/src/scanspec/plot.py index 2e1a84c7..d1770d00 100644 --- a/src/scanspec/plot.py +++ b/src/scanspec/plot.py @@ -45,7 +45,10 @@ def _plot_arrow(axes, arrays: List[np.ndarray]): head = [a[-1] for a in reversed(arrays)] tail = [a[-1] - (a[-1] - a[-2]) * 0.1 for a in reversed(arrays)] axes.annotate( - "", head[:2], tail[:2], arrowprops=dict(color="lightgrey", arrowstyle="-|>") + "", + head[:2], + tail[:2], + arrowprops={"color": "lightgrey", "arrowstyle": "-|>"}, ) elif len(arrays) == 3: arrows = [a[-2:] for a in reversed(arrays)] @@ -71,7 +74,7 @@ def _plot_spline(axes, ranges, arrays: List[np.ndarray], index_colours: Dict[int t /= t[-1] # Scale the arrays so splines don't favour larger scaled axes tck, _ = interpolate.splprep(scaled_arrays, k=2, s=0) - starts = sorted(list(index_colours)) + starts = sorted(index_colours) stops = starts[1:] + [len(arrays[0]) - 1] for start, stop in zip(starts, stops): tnew = np.linspace(t[start], t[stop], num=1001) diff --git a/src/scanspec/service.py b/src/scanspec/service.py index 73288c47..64865fed 100644 --- a/src/scanspec/service.py +++ b/src/scanspec/service.py @@ -124,7 +124,7 @@ class SmallestStepResponse: @app.post("/valid", response_model=ValidResponse) def valid( - spec: Spec = Body(..., examples=[_EXAMPLE_SPEC]) + spec: Spec = Body(..., examples=[_EXAMPLE_SPEC]), ) -> Union[ValidResponse, JSONResponse]: """Validate wether a ScanSpec can produce a viable scan. @@ -144,7 +144,7 @@ def midpoints( request: PointsRequest = Body( ..., examples=[_EXAMPLE_POINTS_REQUEST], - ) + ), ) -> MidpointsResponse: """Generate midpoints from a scanspec. @@ -172,7 +172,7 @@ def bounds( request: PointsRequest = Body( ..., examples=[_EXAMPLE_POINTS_REQUEST], - ) + ), ) -> BoundsResponse: """Generate bounds from a scanspec. @@ -199,7 +199,7 @@ def gap( spec: Spec = Body( ..., examples=[_EXAMPLE_SPEC], - ) + ), ) -> GapResponse: """Generate gaps from a scanspec. @@ -221,7 +221,7 @@ def gap( @app.post("/smalleststep", response_model=SmallestStepResponse) def smallest_step( - spec: Spec = Body(..., examples=[_EXAMPLE_SPEC]) + spec: Spec = Body(..., examples=[_EXAMPLE_SPEC]), ) -> SmallestStepResponse: """Calculate the smallest step in a scan, both absolutely and per-axis.