From 2ec33839457ff24dd74ea5795d37e361b591f50f Mon Sep 17 00:00:00 2001 From: Liam Gray Date: Tue, 16 Jan 2024 16:37:40 -0800 Subject: [PATCH 1/4] ci(lint): remove an ignored ruff rule --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 66c876e84..f2fa6d8cf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,6 @@ ignore = [ "D413", # D413: Missing blank line after last section "D416", # D416: Section name should end with a colon "NPY002", # NPY002: replace legacy numpy.random calls with np.random.Generator - "RUF012", # RUF012 Mutable class attributes should be annotated with `typing.ClassVar` ] # Ignore the following directories From e13d0839c2a7b5b080f59f6cea48ece440974bc9 Mon Sep 17 00:00:00 2001 From: Liam Gray Date: Wed, 1 May 2024 11:55:40 -0700 Subject: [PATCH 2/4] fix(lint): update deprecated ruff setting --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f2fa6d8cf..aa2b78469 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,10 +18,10 @@ markers = ["mpi: mark a test that should be run under MPI"] # flake8-blind-except ('BLE') # flake8-comprehensions ('C4') # flake8-return ('RET') -select = ["E", "D", "F", "I", "UP", "NPY", "RUF", "BLE", "C4", "RET"] +lint.select = ["E", "D", "F", "I", "UP", "NPY", "RUF", "BLE", "C4", "RET"] # E203, W503 -ignore = [ +lint.ignore = [ "E501", # E501: line length violations. Enforce these with `black` "E741", # E741: Ambiguous variable name "D105", # D105: Missing docstring in magic method From e1c19b5a074b75c27658b25849d8840ba38bf7bf Mon Sep 17 00:00:00 2001 From: Liam Gray Date: Tue, 16 Jan 2024 16:37:59 -0800 Subject: [PATCH 3/4] style: add 'ClassVar' annotation where needed --- draco/core/containers.py | 88 ++++++++++++++++++++-------------------- draco/core/io.py | 4 +- draco/util/random.py | 4 +- 3 files changed, 48 insertions(+), 48 deletions(-) diff --git a/draco/core/containers.py b/draco/core/containers.py index d3fcd3307..14afe733f 100644 --- a/draco/core/containers.py +++ b/draco/core/containers.py @@ -58,7 +58,7 @@ """ import inspect -from typing import List, Optional, Union +from typing import ClassVar, List, Optional, Union import numpy as np from caput import memh5, mpiarray, tod @@ -146,7 +146,7 @@ class ContainerBase(memh5.BasicCont): _axes = () - _dataset_spec = {} + _dataset_spec: ClassVar = {} convert_attribute_strings = True convert_dataset_strings = True @@ -615,7 +615,7 @@ class TableBase(ContainerBase): } """ - _table_spec = {} + _table_spec: ClassVar = {} def __init__(self, *args, **kwargs): # Get the dataset specifiction for this class (not any base classes), or @@ -1140,7 +1140,7 @@ class Map(FreqContainer, HealpixContainer): _axes = ("pol",) - _dataset_spec = { + _dataset_spec: ClassVar = { "map": { "axes": ["freq", "pol", "pixel"], "dtype": np.float64, @@ -1175,7 +1175,7 @@ class SiderealStream( The number of points to divide the RA axis up into. """ - _dataset_spec = { + _dataset_spec: ClassVar = { "vis": { "axes": ["freq", "stack", "ra"], "dtype": np.complex64, @@ -1264,7 +1264,7 @@ class SystemSensitivity(FreqContainer, TODContainer): _axes = ("pol",) - _dataset_spec = { + _dataset_spec: ClassVar = { "measured": { "axes": ["freq", "pol", "time"], "dtype": np.float32, @@ -1324,7 +1324,7 @@ class RFIMask(FreqContainer, TODContainer): `False` for clean samples. """ - _dataset_spec = { + _dataset_spec: ClassVar = { "mask": { "axes": ["freq", "time"], "dtype": bool, @@ -1347,7 +1347,7 @@ class SiderealRFIMask(FreqContainer, SiderealContainer): `False` for clean samples. """ - _dataset_spec = { + _dataset_spec: ClassVar = { "mask": { "axes": ["freq", "ra"], "dtype": bool, @@ -1374,7 +1374,7 @@ class BaselineMask(FreqContainer, TODContainer): _axes = ("stack",) - _dataset_spec = { + _dataset_spec: ClassVar = { "mask": { "axes": ["freq", "stack", "time"], "dtype": bool, @@ -1406,7 +1406,7 @@ class SiderealBaselineMask(FreqContainer, SiderealContainer): _axes = ("stack",) - _dataset_spec = { + _dataset_spec: ClassVar = { "mask": { "axes": ["freq", "stack", "ra"], "dtype": bool, @@ -1435,7 +1435,7 @@ class TimeStream(FreqContainer, VisContainer, TODContainer): interchangably in most cases. """ - _dataset_spec = { + _dataset_spec: ClassVar = { "vis": { "axes": ["freq", "stack", "time"], "dtype": np.complex64, @@ -1491,7 +1491,7 @@ class GridBeam(FreqContainer, DataWeightContainer): _axes = ("pol", "input", "theta", "phi") - _dataset_spec = { + _dataset_spec: ClassVar = { "beam": { "axes": ["freq", "pol", "input", "theta", "phi"], "dtype": np.complex64, @@ -1583,7 +1583,7 @@ class HEALPixBeam(FreqContainer, HealpixContainer, DataWeightContainer): _axes = ("pol", "input") - _dataset_spec = { + _dataset_spec: ClassVar = { "beam": { "axes": ["freq", "pol", "input", "pixel"], "dtype": [("Et", np.complex64), ("Ep", np.complex64)], @@ -1648,7 +1648,7 @@ class TrackBeam(FreqContainer, SampleVarianceContainer, DataWeightContainer): _axes = ("pol", "input", "pix") - _dataset_spec = { + _dataset_spec: ClassVar = { "beam": { "axes": ["freq", "pol", "input", "pix"], "dtype": np.complex64, @@ -1781,7 +1781,7 @@ class MModes(FreqContainer, VisContainer, MContainer): Array of weights for each point. """ - _dataset_spec = { + _dataset_spec: ClassVar = { "vis": { "axes": ["m", "msign", "freq", "stack"], "dtype": np.complex128, @@ -1810,7 +1810,7 @@ class SVDModes(MContainer, VisBase): _axes = ("mode",) - _dataset_spec = { + _dataset_spec: ClassVar = { "vis": { "axes": ["m", "mode"], "dtype": np.complex128, @@ -1860,7 +1860,7 @@ class VisGridStream(FreqContainer, SiderealContainer, VisBase): _axes = ("pol", "ew", "ns") - _dataset_spec = { + _dataset_spec: ClassVar = { "vis": { "axes": ["pol", "freq", "ew", "ns", "ra"], "dtype": np.complex64, @@ -1911,7 +1911,7 @@ class HybridVisStream(FreqContainer, SiderealContainer, VisBase): _axes = ("pol", "ew", "el") - _dataset_spec = { + _dataset_spec: ClassVar = { "vis": { "axes": ["pol", "freq", "ew", "el", "ra"], "dtype": np.complex64, @@ -1950,7 +1950,7 @@ class HybridVisMModes(FreqContainer, MContainer, VisBase): _axes = ("pol", "ew", "el") - _dataset_spec = { + _dataset_spec: ClassVar = { "vis": { "axes": ["m", "msign", "pol", "freq", "ew", "el"], "dtype": np.complex64, @@ -1985,7 +1985,7 @@ class RingMap(FreqContainer, SiderealContainer, DataWeightContainer): _axes = ("pol", "beam", "el") - _dataset_spec = { + _dataset_spec: ClassVar = { "map": { "axes": ["beam", "pol", "freq", "ra", "el"], "dtype": np.float64, @@ -2068,7 +2068,7 @@ class RingMapMask(FreqContainer, SiderealContainer): _axes = ("pol", "el") - _dataset_spec = { + _dataset_spec: ClassVar = { "mask": { "axes": ["pol", "freq", "ra", "el"], "dtype": bool, @@ -2114,7 +2114,7 @@ def weight(self) -> Optional[memh5.MemDataset]: class CommonModeGainData(FreqContainer, TODContainer, GainDataBase): """Parallel container for holding gain data common to all inputs.""" - _dataset_spec = { + _dataset_spec: ClassVar = { "gain": { "axes": ["freq", "time"], "dtype": np.complex128, @@ -2135,7 +2135,7 @@ class CommonModeGainData(FreqContainer, TODContainer, GainDataBase): class CommonModeSiderealGainData(FreqContainer, SiderealContainer, GainDataBase): """Parallel container for holding sidereal gain data common to all inputs.""" - _dataset_spec = { + _dataset_spec: ClassVar = { "gain": { "axes": ["freq", "ra"], "dtype": np.complex128, @@ -2158,7 +2158,7 @@ class GainData(FreqContainer, TODContainer, GainDataBase): _axes = ("input",) - _dataset_spec = { + _dataset_spec: ClassVar = { "gain": { "axes": ["freq", "input", "time"], "dtype": np.complex128, @@ -2200,7 +2200,7 @@ class SiderealGainData(FreqContainer, SiderealContainer, GainDataBase): _axes = ("input",) - _dataset_spec = { + _dataset_spec: ClassVar = { "gain": { "axes": ["freq", "input", "ra"], "dtype": np.complex128, @@ -2228,7 +2228,7 @@ class StaticGainData(FreqContainer, GainDataBase): _axes = ("input",) - _dataset_spec = { + _dataset_spec: ClassVar = { "gain": { "axes": ["freq", "input"], "dtype": np.complex128, @@ -2256,7 +2256,7 @@ class DelayCutoff(ContainerBase): _axes = ("pol", "el") - _dataset_spec = { + _dataset_spec: ClassVar = { "cutoff": { "axes": ["pol", "el"], "dtype": np.float64, @@ -2309,7 +2309,7 @@ class DelaySpectrum(DelayContainer): _axes = ("baseline", "sample") - _dataset_spec = { + _dataset_spec: ClassVar = { "spectrum": { "axes": ["baseline", "delay"], "dtype": np.float64, @@ -2361,7 +2361,7 @@ class DelayTransform(DelayContainer): _axes = ("baseline", "sample") - _dataset_spec = { + _dataset_spec: ClassVar = { "spectrum": { "axes": ["baseline", "sample", "delay"], "dtype": np.complex128, @@ -2400,7 +2400,7 @@ class WaveletSpectrum(FreqContainer, DelayContainer, DataWeightContainer): _axes = ("baseline",) - _dataset_spec = { + _dataset_spec: ClassVar = { "spectrum": { "axes": ["baseline", "delay", "freq"], "dtype": np.float64, @@ -2430,7 +2430,7 @@ class DelayCrossSpectrum(DelaySpectrum): _axes = ("dataset",) - _dataset_spec = { + _dataset_spec: ClassVar = { "spectrum": { "axes": ["dataset", "dataset", "baseline", "delay"], "dtype": np.float64, @@ -2479,7 +2479,7 @@ class Powerspectrum2D(ContainerBase): _axes = ("kperp", "kpar") - _dataset_spec = { + _dataset_spec: ClassVar = { "powerspectrum": { "axes": ["kperp", "kpar"], "dtype": np.float64, @@ -2531,7 +2531,7 @@ class SVDSpectrum(ContainerBase): _axes = ("m", "singularvalue") - _dataset_spec = { + _dataset_spec: ClassVar = { "spectrum": { "axes": ["m", "singularvalue"], "dtype": np.float64, @@ -2555,7 +2555,7 @@ class FrequencyStack(FreqContainer, DataWeightContainer): of sources of interest. """ - _dataset_spec = { + _dataset_spec: ClassVar = { "stack": { "axes": ["freq"], "dtype": np.float64, @@ -2584,7 +2584,7 @@ class FrequencyStackByPol(FrequencyStack): _axes = ("pol",) - _dataset_spec = { + _dataset_spec: ClassVar = { "stack": { "axes": ["pol", "freq"], "dtype": np.float64, @@ -2613,7 +2613,7 @@ class MockFrequencyStack(FrequencyStack): _axes = ("mock",) - _dataset_spec = { + _dataset_spec: ClassVar = { "stack": { "axes": ["mock", "freq"], "dtype": np.float64, @@ -2637,7 +2637,7 @@ class MockFrequencyStackByPol(FrequencyStackByPol): _axes = ("mock",) - _dataset_spec = { + _dataset_spec: ClassVar = { "stack": { "axes": ["mock", "pol", "freq"], "dtype": np.float64, @@ -2658,7 +2658,7 @@ class Stack3D(FreqContainer, DataWeightContainer): _axes = ("pol", "delta_ra", "delta_dec") - _dataset_spec = { + _dataset_spec: ClassVar = { "stack": { "axes": ["pol", "delta_ra", "delta_dec", "freq"], "dtype": np.float64, @@ -2690,7 +2690,7 @@ class SourceCatalog(TableBase): The `ra` and `dec` coordinates should be ICRS. """ - _table_spec = { + _table_spec: ClassVar = { "position": { "columns": [["ra", np.float64], ["dec", np.float64]], "axis": "object_id", @@ -2701,7 +2701,7 @@ class SourceCatalog(TableBase): class SpectroscopicCatalog(SourceCatalog): """A container for spectroscopic catalogs.""" - _table_spec = { + _table_spec: ClassVar = { "redshift": { "columns": [["z", np.float64], ["z_error", np.float64]], "axis": "object_id", @@ -2714,7 +2714,7 @@ class FormedBeam(FreqContainer, DataWeightContainer): _axes = ("object_id", "pol") - _dataset_spec = { + _dataset_spec: ClassVar = { "beam": { "axes": ["object_id", "pol", "freq"], "dtype": np.float64, @@ -2775,7 +2775,7 @@ class FormedBeamHA(FormedBeam): _axes = ("ha",) - _dataset_spec = { + _dataset_spec: ClassVar = { "beam": { "axes": ["object_id", "pol", "freq", "ha"], "dtype": np.float64, @@ -2809,7 +2809,7 @@ class FormedBeamMask(FreqContainer): _axes = ("object_id", "pol") - _dataset_spec = { + _dataset_spec: ClassVar = { "mask": { "axes": ["object_id", "pol", "freq"], "dtype": bool, @@ -2830,7 +2830,7 @@ class FormedBeamHAMask(FormedBeamMask): _axes = ("ha",) - _dataset_spec = { + _dataset_spec: ClassVar = { "mask": { "axes": ["object_id", "pol", "freq", "ha"], "dtype": bool, diff --git a/draco/core/io.py b/draco/core/io.py index 9bd98c2cd..9b9b9db2f 100644 --- a/draco/core/io.py +++ b/draco/core/io.py @@ -26,7 +26,7 @@ import os.path import shutil import subprocess -from typing import Dict, List, Optional, Union +from typing import ClassVar, Dict, List, Optional, Union import numpy as np from caput import config, fileformats, memh5, pipeline, truncate @@ -735,7 +735,7 @@ class Truncate(task.SingleTask): dataset = config.Property(proptype=dict, default=None) ensure_chunked = config.Property(proptype=bool, default=True) - default_params = { + default_params: ClassVar = { "weight_dataset": None, "fixed_precision": 1e-4, "variance_increase": 1e-3, diff --git a/draco/util/random.py b/draco/util/random.py index 54dc36890..6ff1edd72 100644 --- a/draco/util/random.py +++ b/draco/util/random.py @@ -4,7 +4,7 @@ import contextlib import os import zlib -from typing import Callable, Optional +from typing import Callable, ClassVar, Optional import numpy as np from caput import config @@ -287,7 +287,7 @@ class MultithreadedRNG(np.random.Generator): # method name, number of initial parameter arguments, default data type, if there is # a dtype argument, and if there is an out argument. See `_build_method` for # details. - PARALLEL_METHODS = { + PARALLEL_METHODS: ClassVar = { "random": (0, np.float64, True, True), "integers": (2, np.int64, True, False), "uniform": (2, np.float64, False, False), From 4cbbb049e5d21ea9252fab0dfbc49f7b9b6b724e Mon Sep 17 00:00:00 2001 From: Liam Gray Date: Wed, 1 May 2024 12:08:03 -0700 Subject: [PATCH 4/4] style: apply ruff f-string rules --- draco/analysis/dayenu.py | 2 +- draco/analysis/powerspectrum.py | 2 +- draco/analysis/sidereal.py | 2 +- draco/analysis/transform.py | 2 +- draco/core/io.py | 14 +++++++------- draco/core/misc.py | 2 +- draco/core/task.py | 8 ++++---- draco/util/tools.py | 2 +- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/draco/analysis/dayenu.py b/draco/analysis/dayenu.py index 54c97b3b1..cb5a2d950 100644 --- a/draco/analysis/dayenu.py +++ b/draco/analysis/dayenu.py @@ -63,7 +63,7 @@ def setup(self, telescope): """ self.telescope = io.get_telescope(telescope) - self.log.info("Instrumental delay cut set to %0.3f micro-sec." % self.tauw) + self.log.info(f"Instrumental delay cut set to {self.tauw:.3f} micro-sec.") if self.atten_threshold > 0.0: self.log.info( diff --git a/draco/analysis/powerspectrum.py b/draco/analysis/powerspectrum.py index 41ae511ab..e61dc0f75 100644 --- a/draco/analysis/powerspectrum.py +++ b/draco/analysis/powerspectrum.py @@ -52,7 +52,7 @@ def process(self, klmodes): if not isinstance(klmodes, containers.KLModes): raise ValueError( "Input container must be instance of " - "KLModes (received %s)" % klmodes.__class__ + f"KLModes (received {klmodes.__class__!s})" ) klmodes.redistribute("m") diff --git a/draco/analysis/sidereal.py b/draco/analysis/sidereal.py index d6c238d80..a4e727439 100644 --- a/draco/analysis/sidereal.py +++ b/draco/analysis/sidereal.py @@ -553,7 +553,7 @@ def process(self, sdata): self.sum_coeff_sq = np.zeros_like(self.stack.weight[:].view(np.ndarray)) # Accumulate - self.log.info("Adding to stack LSD(s): %s" % input_lsd) + self.log.info(f"Adding to stack LSD(s): {input_lsd!s}") self.lsd_list += input_lsd diff --git a/draco/analysis/transform.py b/draco/analysis/transform.py index 49b440ea6..8b4f85d4e 100644 --- a/draco/analysis/transform.py +++ b/draco/analysis/transform.py @@ -120,7 +120,7 @@ def setup(self, tel): Telescope object to use """ if self.weight not in ["natural", "uniform", "inverse_variance"]: - KeyError("Do not recognize weight = %s" % self.weight) + KeyError(f"Do not recognize weight = {self.weight!s}") self.telescope = io.get_telescope(tel) diff --git a/draco/core/io.py b/draco/core/io.py index 9b9b9db2f..91f3aee64 100644 --- a/draco/core/io.py +++ b/draco/core/io.py @@ -64,7 +64,7 @@ def _list_of_filelists(files: Union[List[str], List[List[str]]]) -> List[List[st for filelist in files: if isinstance(filelist, str): if "*" not in filelist and not os.path.isfile(filelist): - raise ConfigError("File not found: %s" % filelist) + raise ConfigError(f"File not found: {filelist!s}") filelist = glob.glob(filelist) elif isinstance(filelist, list): for i in range(len(filelist)): @@ -116,12 +116,12 @@ def _list_or_glob(files: Union[str, List[str]]) -> List[str]: ) else: if not os.path.isfile(files): - raise ConfigError("File not found: %s" % files) + raise ConfigError(f"File not found: {files!s}") return [files] raise ConfigError( - "Argument must be list, glob pattern, or file path, got %s" % repr(files) + f"Argument must be list, glob pattern, or file path, got {files!r}" ) @@ -167,11 +167,11 @@ def _list_of_filegroups(groups: Union[List[Dict], Dict]) -> List[Dict]: for fname in files: if "*" not in fname and not os.path.isfile(fname): - raise ConfigError("File not found: %s" % fname) + raise ConfigError(f"File not found: {fname!s}") flist += glob.glob(fname) if not len(flist): - raise ConfigError("No files in group exist (%s)." % files) + raise ConfigError(f"No files in group exist ({files!s}).") group["files"] = flist @@ -1164,7 +1164,7 @@ def get_telescope(obj): if isinstance(obj, telescope.TransitTelescope): return obj - raise RuntimeError("Could not get telescope instance out of %s" % repr(obj)) + raise RuntimeError(f"Could not get telescope instance out of {obj!r}") def get_beamtransfer(obj): @@ -1178,4 +1178,4 @@ def get_beamtransfer(obj): if isinstance(obj, manager.ProductManager): return obj.beamtransfer - raise RuntimeError("Could not get BeamTransfer instance out of %s" % repr(obj)) + raise RuntimeError(f"Could not get BeamTransfer instance out of {obj!r}") diff --git a/draco/core/misc.py b/draco/core/misc.py index 3f868c346..20f796260 100644 --- a/draco/core/misc.py +++ b/draco/core/misc.py @@ -54,7 +54,7 @@ def process(self, tstream, gain): gain, (containers.CommonModeGainData, containers.CommonModeSiderealGainData) ): raise ValueError( - "Cannot apply input-dependent gains to stacked data: %s" % tstream + f"Cannot apply input-dependent gains to stacked data: {tstream!s}" ) if isinstance(gain, containers.StaticGainData): diff --git a/draco/core/task.py b/draco/core/task.py index 4559c6ef6..d082dfa05 100644 --- a/draco/core/task.py +++ b/draco/core/task.py @@ -83,7 +83,7 @@ def _log_level(x): if isinstance(x, str) and x in level_dict: return level_dict[x.upper()] - raise ValueError("Logging level %s not understood" % repr(x)) + raise ValueError(f"Logging level {x!r} not understood") class SetMPILogging(pipeline.TaskBase): @@ -334,7 +334,7 @@ def __init__(self): def next(self, *input): """Should not need to override. Implement `process` instead.""" - self.log.info("Starting next for task %s" % self.__class__.__name__) + self.log.info(f"Starting next for task {self.__class__.__name__}") self.comm.Barrier() @@ -376,7 +376,7 @@ def next(self, *input): # Increment internal counter self._count = self._count + 1 - self.log.info("Leaving next for task %s" % self.__class__.__name__) + self.log.info(f"Leaving next for task {self.__class__.__name__}") # Return the output for the next task return output @@ -678,7 +678,7 @@ def process(self, x): """ import gc - self.log.info("Deleting %s" % type(x)) + self.log.info(f"Deleting {type(x)!s}") del x gc.collect() diff --git a/draco/util/tools.py b/draco/util/tools.py index 50c4aac16..688edd1b2 100644 --- a/draco/util/tools.py +++ b/draco/util/tools.py @@ -157,7 +157,7 @@ def find_inputs(input_index, inputs, require_match=False): ) if field_to_match not in inputs.dtype.fields: - raise ValueError("`inputs` array does not have a `%s` field." % field_to_match) + raise ValueError(f"`inputs` array does not have a `{field_to_match!s}` field.") return find_keys( input_index[field_to_match], inputs[field_to_match], require_match=require_match