From b5230181b6a684e56a619bc34287009de0c44aab Mon Sep 17 00:00:00 2001 From: Virgile Andreani Date: Tue, 17 Sep 2024 11:30:36 -0400 Subject: [PATCH 1/4] Enable pygrep-hooks --- .pre-commit-config.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9a332ffb08..a65931dfe5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,6 +16,19 @@ repos: - id: requirements-txt-fixer exclude: ^requirements-dev\.txt$ - id: trailing-whitespace +- repo: https://github.com/pre-commit/pygrep-hooks + rev: v1.10.0 + hooks: + - id: python-check-blanket-noqa + - id: python-check-blanket-type-ignore + - id: python-check-mock-methods + # - id: python-no-eval # gets confused with all the `.eval()` + - id: python-no-log-warn + - id: python-use-type-annotations + - id: rst-backticks + - id: rst-directive-colons + - id: rst-inline-touching-normal + - id: text-unicode-replacement-char - repo: https://github.com/citation-file-format/cffconvert rev: 054bda51dbe278b3e86f27c890e3f3ac877d616c hooks: From ac3d4313a2b4d61634020675c05b004fb3b31e6d Mon Sep 17 00:00:00 2001 From: Virgile Andreani Date: Tue, 17 Sep 2024 11:30:50 -0400 Subject: [PATCH 2/4] Fix single backticks for code --- docs/source/api.rst | 4 ++-- docs/source/api/distributions/discrete.rst | 2 +- docs/source/api/shape_utils.rst | 4 ++-- docs/source/guides/Gaussian_Processes.rst | 8 ++++---- .../source/learn/core_notebooks/Gaussian_Processes.rst | 10 +++++----- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/source/api.rst b/docs/source/api.rst index 4aa717a2dc..a82da9bc99 100644 --- a/docs/source/api.rst +++ b/docs/source/api.rst @@ -41,10 +41,10 @@ Plots, stats and diagnostics are delegated to the library, a general purpose library for "exploratory analysis of Bayesian models". -* Functions from the `arviz.plots` module are available through ``pymc.`` or ``pymc.plots.``, +* Functions from the ``arviz.plots`` module are available through ``pymc.`` or ``pymc.plots.``, but for their API documentation please refer to the :ref:`ArviZ documentation `. -* Functions from the `arviz.stats` module are available through ``pymc.`` or ``pymc.stats.``, +* Functions from the ``arviz.stats`` module are available through ``pymc.`` or ``pymc.stats.``, but for their API documentation please refer to the :ref:`ArviZ documentation `. ArviZ is a dependency of PyMC and so, in addition to the locations described above, diff --git a/docs/source/api/distributions/discrete.rst b/docs/source/api/distributions/discrete.rst index 79e66bab8b..76856d54df 100644 --- a/docs/source/api/distributions/discrete.rst +++ b/docs/source/api/distributions/discrete.rst @@ -23,4 +23,4 @@ Discrete .. note:: **OrderedLogistic and OrderedProbit:** - The `OrderedLogistic` and `OrderedProbit` distributions expect the observed values to be 0-based, i.e., they should range from `0` to `K-1`. Using 1-based indexing (like `1, 2, 3,...K`) can result in errors. + The ``OrderedLogistic`` and ``OrderedProbit`` distributions expect the observed values to be 0-based, i.e., they should range from ``0`` to ``K-1``. Using 1-based indexing (like ``1, 2, 3,...K``) can result in errors. diff --git a/docs/source/api/shape_utils.rst b/docs/source/api/shape_utils.rst index 7f78052f87..586a6535d1 100644 --- a/docs/source/api/shape_utils.rst +++ b/docs/source/api/shape_utils.rst @@ -4,9 +4,9 @@ shape_utils This submodule contains various functions that apply numpy's broadcasting rules to shape tuples, and also to samples drawn from probability distributions. -The main challenge when broadcasting samples drawn from a generative model, is that each random variate has a core shape. When we draw many i.i.d samples from a given RV, for example if we ask for `size_tuple` i.i.d draws, the result usually is a `size_tuple + RV_core_shape`. In the generative model's hierarchy, the downstream RVs that are conditionally dependent on our above sampled values, will get an array with a shape that is inconsistent with the core shape they expect to see for their parameters. This is a problem sometimes because it prevents regular broadcasting in complex hierarchical models, and thus make prior and posterior predictive sampling difficult. +The main challenge when broadcasting samples drawn from a generative model, is that each random variate has a core shape. When we draw many i.i.d samples from a given RV, for example if we ask for ``size_tuple`` i.i.d draws, the result usually is a ``size_tuple + RV_core_shape``. In the generative model's hierarchy, the downstream RVs that are conditionally dependent on our above sampled values, will get an array with a shape that is inconsistent with the core shape they expect to see for their parameters. This is a problem sometimes because it prevents regular broadcasting in complex hierarchical models, and thus make prior and posterior predictive sampling difficult. -This module introduces functions that are made aware of the requested `size_tuple` of i.i.d samples, and does the broadcasting on the core shapes, transparently ignoring or moving the i.i.d `size_tuple` prepended axes around. +This module introduces functions that are made aware of the requested ``size_tuple`` of i.i.d samples, and does the broadcasting on the core shapes, transparently ignoring or moving the i.i.d ``size_tuple`` prepended axes around. .. currentmodule:: pymc.distributions.shape_utils diff --git a/docs/source/guides/Gaussian_Processes.rst b/docs/source/guides/Gaussian_Processes.rst index 3d1fbc80b3..513caac7fd 100644 --- a/docs/source/guides/Gaussian_Processes.rst +++ b/docs/source/guides/Gaussian_Processes.rst @@ -126,7 +126,7 @@ variable models and also some fast approximations. Their usage all follows a similar pattern: First, a GP is instantiated with a mean function and a covariance function. Then, GP objects can be added together, allowing for function characteristics to be carefully modeled and separated. Finally, one -of `prior`, `marginal_likelihood` or `conditional` methods is called on the GP +of ``prior``, ``marginal_likelihood`` or ``conditional`` methods is called on the GP object to actually construct the PyMC random variable that represents the function prior. @@ -148,7 +148,7 @@ conditioned on. or other, depending on the implementation. See the notebooks for examples. The :code:`conditional` method works similarly. -Calling the `prior` method will create a PyMC random variable that represents +Calling the ``prior`` method will create a PyMC random variable that represents the latent function :math:`f(x) = \mathbf{f}`:: f = gp.prior("f", X) @@ -218,7 +218,7 @@ thesis `_. The GP objects in PyMC keeps track of these marginals automatically. The following code sketch shows how to define the conditional distribution of -:math:`f_2^*`. We use `gp.Marginal` in the example, but the same works for +:math:`f_2^*`. We use ``gp.Marginal`` in the example, but the same works for other implementations. The first block fits the GP prior. We denote :math:`f_1 + f_2` as just :math:`f` for brevity:: @@ -255,7 +255,7 @@ arguments are required for conditionals of :math:`f1` and :math:`f2`, but not .. note:: When constructing conditionals, the additional arguments :code:`X`, :code:`y`, - :code:`noise` and :code:`gp` must be provided as a dict called `given`! + :code:`noise` and :code:`gp` must be provided as a dict called ``given``! Since the marginal likelihoood method of :code:`gp1` or :code:`gp2` weren't called, their conditionals need to be provided with the required inputs. In the same diff --git a/docs/source/learn/core_notebooks/Gaussian_Processes.rst b/docs/source/learn/core_notebooks/Gaussian_Processes.rst index f076a6f651..46f9974481 100644 --- a/docs/source/learn/core_notebooks/Gaussian_Processes.rst +++ b/docs/source/learn/core_notebooks/Gaussian_Processes.rst @@ -123,8 +123,8 @@ variable models and also some fast approximations. Their usage all follows a similar pattern: First, a GP is instantiated with a mean function and a covariance function. Then, GP objects can be added together, allowing for function characteristics to be carefully modeled and separated. Finally, one -of `prior`, `marginal_likelihood` or `conditional` methods is called on the GP -object to actually construct the PyMC random variable that represents the +of ``prior``, ``marginal_likelihood`` or ``conditional`` methods is called on +the GP object to actually construct the PyMC random variable that represents the function prior. Using :code:`gp.Latent` for the example, the syntax to first specify the GP @@ -145,7 +145,7 @@ conditioned on. or other, depending on the implementation. See the notebooks for examples. The :code:`conditional` method works similarly. -Calling the `prior` method will create a PyMC random variable that represents +Calling the ``prior`` method will create a PyMC random variable that represents the latent function :math:`f(x) = \mathbf{f}`:: f = gp.prior("f", X) @@ -217,7 +217,7 @@ thesis `_. The GP objects in PyMC keeps track of these marginals automatically. The following code sketch shows how to define the conditional distribution of -:math:`f_2^*`. We use `gp.Marginal` in the example, but the same works for +:math:`f_2^*`. We use ``gp.Marginal`` in the example, but the same works for other implementations. The first block fits the GP prior. We denote :math:`f_1 + f_2` as just :math:`f` for brevity:: @@ -254,7 +254,7 @@ arguments are required for conditionals of :math:`f1` and :math:`f2`, but not .. note:: When constructing conditionals, the additional arguments :code:`X`, :code:`y`, - :code:`sigma` and :code:`gp` must be provided as a dict called `given`! + :code:`sigma` and :code:`gp` must be provided as a dict called ``given``! Since the marginal likelihoood method of :code:`gp1` or :code:`gp2` weren't called, their conditionals need to be provided with the required inputs. In the same From 9f10cc40228adcf5454a77b414ee209c371652bc Mon Sep 17 00:00:00 2001 From: Virgile Andreani Date: Tue, 17 Sep 2024 11:31:47 -0400 Subject: [PATCH 3/4] Precise blanket type ignore and noqa statements --- pymc/backends/__init__.py | 4 ++-- pymc/distributions/shape_utils.py | 11 +++++------ pymc/distributions/simulator.py | 4 ++-- pymc/distributions/transforms.py | 2 +- pymc/gp/cov.py | 2 +- pymc/gp/hsgp_approx.py | 12 ++++++------ pymc/logprob/basic.py | 2 +- pymc/logprob/tensor.py | 5 ++--- pymc/model/transform/optimization.py | 10 +++++----- pymc/model_graph.py | 2 +- pymc/sampling/forward.py | 6 +++--- pymc/sampling/mcmc.py | 4 ++-- pymc/sampling/parallel.py | 4 ++-- pymc/testing.py | 2 +- pymc/tuning/scaling.py | 2 +- pymc/tuning/starting.py | 4 ++-- pymc/util.py | 4 ++-- pymc/variational/callbacks.py | 4 ++-- pymc/variational/minibatch_rv.py | 4 ++-- tests/distributions/test_continuous.py | 10 +++++----- tests/distributions/test_custom.py | 4 ++-- tests/distributions/test_discrete.py | 2 +- tests/distributions/test_distribution.py | 2 +- tests/distributions/test_multivariate.py | 8 ++++---- tests/distributions/test_timeseries.py | 2 +- 25 files changed, 57 insertions(+), 59 deletions(-) diff --git a/pymc/backends/__init__.py b/pymc/backends/__init__.py index 9b1af4bd41..34f958abc1 100644 --- a/pymc/backends/__init__.py +++ b/pymc/backends/__init__.py @@ -85,8 +85,8 @@ RunType: TypeAlias = Run HAS_MCB = True except ImportError: - TraceOrBackend = BaseTrace # type: ignore - RunType = type(None) # type: ignore + TraceOrBackend = BaseTrace # type: ignore[misc] + RunType = type(None) # type: ignore[assignment, misc] __all__ = ["to_inference_data", "predictions_to_inference_data"] diff --git a/pymc/distributions/shape_utils.py b/pymc/distributions/shape_utils.py index 220abac80d..bdcc5ab4da 100644 --- a/pymc/distributions/shape_utils.py +++ b/pymc/distributions/shape_utils.py @@ -260,13 +260,13 @@ def change_dist_size( """ # Check the dimensionality of the `new_size` kwarg - new_size_ndim = np.ndim(new_size) # type: ignore + new_size_ndim = np.ndim(new_size) # type: ignore[arg-type] if new_size_ndim > 1: raise ShapeError("The `new_size` must be ≤1-dimensional.", actual=new_size_ndim) elif new_size_ndim == 0: - new_size = (new_size,) # type: ignore + new_size = (new_size,) # type: ignore[assignment] else: - new_size = tuple(new_size) # type: ignore + new_size = tuple(new_size) # type: ignore[arg-type] op = dist.owner.op new_dist = _change_dist_size(op, dist, new_size=new_size, expand=expand) @@ -331,7 +331,7 @@ def change_specify_shape_size(op, ss, new_size, expand) -> TensorVariable: new_shapes[-ndim_supp:] = shapes[-ndim_supp:] # specify_shape has a wrong signature https://github.com/aesara-devs/aesara/issues/1164 - return pt.specify_shape(new_var, new_shapes) # type: ignore + return pt.specify_shape(new_var, new_shapes) # type: ignore[arg-type] def get_support_shape( @@ -395,8 +395,7 @@ def get_support_shape( raise ValueError(f"Number of dims is too small for ndim_supp of {ndim_supp}") model = modelcontext(None) inferred_support_shape = [ - model.dim_lengths[dims[i]] - support_shape_offset[i] # type: ignore - for i in np.arange(-ndim_supp, 0) + model.dim_lengths[dims[i]] - support_shape_offset[i] for i in np.arange(-ndim_supp, 0) ] if inferred_support_shape is None and observed is not None: diff --git a/pymc/distributions/simulator.py b/pymc/distributions/simulator.py index 02c76e2c6d..d1a59cd077 100644 --- a/pymc/distributions/simulator.py +++ b/pymc/distributions/simulator.py @@ -144,7 +144,7 @@ def __new__(cls, name, *args, **kwargs): return super().__new__(cls, name, *args, **kwargs) @classmethod - def dist( # type: ignore + def dist( # type: ignore[override] cls, fn, *unnamed_params, @@ -256,7 +256,7 @@ def rv_op( return sim_op(*params, **kwargs) -@_support_point.register(SimulatorRV) # type: ignore +@_support_point.register(SimulatorRV) def simulator_support_point(op, rv, *inputs): sim_inputs = op.dist_params(rv.owner) # Take the mean of 10 draws diff --git a/pymc/distributions/transforms.py b/pymc/distributions/transforms.py index 0c2a43b1f1..faf38ffeec 100644 --- a/pymc/distributions/transforms.py +++ b/pymc/distributions/transforms.py @@ -21,7 +21,7 @@ # ignore mypy error because it somehow considers that # "numpy.core.numeric has no attribute normalize_axis_tuple" -from numpy.core.numeric import normalize_axis_tuple # type: ignore +from numpy.core.numeric import normalize_axis_tuple # type: ignore[attr-defined] from pytensor.graph import Op from pytensor.tensor import TensorVariable diff --git a/pymc/gp/cov.py b/pymc/gp/cov.py index d7f5c66569..79cbd2d9d0 100644 --- a/pymc/gp/cov.py +++ b/pymc/gp/cov.py @@ -147,7 +147,7 @@ def __array_wrap__(self, result): @staticmethod def _alloc(X, *shape: int) -> TensorVariable: - return pt.alloc(X, *shape) # type: ignore + return pt.alloc(X, *shape) # type: ignore[return-value] class Covariance(BaseCovariance): diff --git a/pymc/gp/hsgp_approx.py b/pymc/gp/hsgp_approx.py index f1adf331dd..3ea0a626cd 100644 --- a/pymc/gp/hsgp_approx.py +++ b/pymc/gp/hsgp_approx.py @@ -425,7 +425,7 @@ def prior( gp_dims: str | None = None, *args, **kwargs, - ): # type: ignore + ): R""" Returns the (approximate) GP prior distribution evaluated over the input locations `X`. For usage examples, refer to `pm.gp.Latent`. @@ -488,7 +488,7 @@ def _build_conditional(self, Xnew): elif self._parametrization == "centered": return self.mean_func(Xnew) + phi[:, i:] @ beta - def conditional(self, name: str, Xnew: TensorLike, dims: str | None = None): # type: ignore + def conditional(self, name: str, Xnew: TensorLike, dims: str | None = None): # type: ignore[override] R""" Returns the (approximate) conditional distribution evaluated over new input locations `Xnew`. @@ -683,7 +683,7 @@ def prior_linearized(self, X: TensorLike): psd = self.scale * self.cov_func.power_spectral_density_approx(J) return (phi_cos, phi_sin), psd - def prior(self, name: str, X: TensorLike, dims: str | None = None): # type: ignore + def prior(self, name: str, X: TensorLike, dims: str | None = None): # type: ignore[override] R""" Returns the (approximate) GP prior distribution evaluated over the input locations `X`. For usage examples, refer to `pm.gp.Latent`. @@ -705,8 +705,8 @@ def prior(self, name: str, X: TensorLike, dims: str | None = None): # type: ign # and so does not contribute to the approximation. f = ( self.mean_func(X) - + phi_cos @ (psd * self._beta[:m]) # type: ignore - + phi_sin[..., 1:] @ (psd[1:] * self._beta[m:]) # type: ignore + + phi_cos @ (psd * self._beta[:m]) # type: ignore[index] + + phi_sin[..., 1:] @ (psd[1:] * self._beta[m:]) # type: ignore[index] ) self.f = pm.Deterministic(name, f, dims=dims) @@ -734,7 +734,7 @@ def _build_conditional(self, Xnew): phi = phi_cos @ (psd * beta[:m]) + phi_sin[..., 1:] @ (psd[1:] * beta[m:]) return self.mean_func(Xnew) + phi - def conditional(self, name: str, Xnew: TensorLike, dims: str | None = None): # type: ignore + def conditional(self, name: str, Xnew: TensorLike, dims: str | None = None): # type: ignore[override] R""" Returns the (approximate) conditional distribution evaluated over new input locations `Xnew`. diff --git a/pymc/logprob/basic.py b/pymc/logprob/basic.py index e1a5d2911a..176fc91a27 100644 --- a/pymc/logprob/basic.py +++ b/pymc/logprob/basic.py @@ -588,7 +588,7 @@ def transformed_conditional_logp( } if values_to_transforms: # There seems to be an incorrect type hint in TransformValuesRewrite - transform_rewrite = TransformValuesRewrite(values_to_transforms) # type: ignore + transform_rewrite = TransformValuesRewrite(values_to_transforms) # type: ignore[arg-type] kwargs.setdefault("warn_rvs", False) temp_logp_terms = conditional_logp( diff --git a/pymc/logprob/tensor.py b/pymc/logprob/tensor.py index a4f1324c99..634654c9e9 100644 --- a/pymc/logprob/tensor.py +++ b/pymc/logprob/tensor.py @@ -34,7 +34,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. - from pathlib import Path from pytensor import tensor as pt @@ -165,7 +164,7 @@ def find_measurable_stacks(fgraph, node) -> list[TensorVariable] | None: # the IR construction replacements = [(base_var, promised_valued_rv(base_var)) for base_var in base_vars] temp_fgraph = FunctionGraph(outputs=base_vars, clone=False) - toposort_replace(temp_fgraph, replacements) # type: ignore + toposort_replace(temp_fgraph, replacements) # type: ignore[arg-type] new_base_vars = temp_fgraph.outputs if is_join: @@ -182,7 +181,7 @@ class MeasurableDimShuffle(MeasurableOp, DimShuffle): # Need to get the absolute path of `c_func_file`, otherwise it tries to # find it locally and fails when a new `Op` is initialized - c_func_file = str(DimShuffle.get_path(Path(DimShuffle.c_func_file))) + c_func_file = str(DimShuffle.get_path(Path(DimShuffle.c_func_file))) # type: ignore[arg-type] @_logprob.register(MeasurableDimShuffle) diff --git a/pymc/model/transform/optimization.py b/pymc/model/transform/optimization.py index 32ea617482..bcf828ba3e 100644 --- a/pymc/model/transform/optimization.py +++ b/pymc/model/transform/optimization.py @@ -77,14 +77,14 @@ def freeze_dims_and_data( if isinstance(datum, SharedVariable) } - old_outs, old_coords, old_dim_lenghts = fg.outputs, fg._coords, fg._dim_lengths # type: ignore + old_outs, old_coords, old_dim_lenghts = fg.outputs, fg._coords, fg._dim_lengths # type: ignore[attr-defined] # Rebuild strict will force the recreation of RV nodes with updated static types - new_outs = clone_replace(old_outs, replace=frozen_replacements, rebuild_strict=False) # type: ignore + new_outs = clone_replace(old_outs, replace=frozen_replacements, rebuild_strict=False) # type: ignore[arg-type] for old_out, new_out in zip(old_outs, new_outs): new_out.name = old_out.name fg = FunctionGraph(outputs=new_outs, clone=False) - fg._coords = old_coords # type: ignore - fg._dim_lengths = { # type: ignore + fg._coords = old_coords # type: ignore[attr-defined] + fg._dim_lengths = { # type: ignore[attr-defined] dim: frozen_replacements.get(dim_length, dim_length) for dim, dim_length in old_dim_lenghts.items() } @@ -99,7 +99,7 @@ def freeze_dims_and_data( if transform is None: new_value = rv.type() else: - new_value = transform.forward(rv, *rv.owner.inputs).type() # type: ignore + new_value = transform.forward(rv, *rv.owner.inputs).type() # type: ignore[arg-type] new_value.name = old_value.name replacements[old_value] = new_value fg.replace_all(tuple(replacements.items()), import_missing=True) diff --git a/pymc/model_graph.py b/pymc/model_graph.py index 1c230fc5a1..00921f8a6d 100644 --- a/pymc/model_graph.py +++ b/pymc/model_graph.py @@ -234,7 +234,7 @@ def _make_node( kwargs["cluster"] = cluster var_name: str = cast(str, node.var.name) - add_node(var_name.replace(":", "&"), **kwargs) # type: ignore + add_node(var_name.replace(":", "&"), **kwargs) # type: ignore[call-arg] class ModelGraph: diff --git a/pymc/sampling/forward.py b/pymc/sampling/forward.py index b506aa7baa..41ceaa17d0 100644 --- a/pymc/sampling/forward.py +++ b/pymc/sampling/forward.py @@ -219,7 +219,7 @@ def shared_value_matches(var): # Walk the graph from inputs to outputs and tag the volatile variables nodes: list[Variable] = general_toposort( fg.outputs, deps=lambda x: x.owner.inputs if x.owner else [] - ) # type: ignore + ) # type: ignore[call-overload] volatile_nodes: set[Any] = set() for node in nodes: if ( @@ -446,7 +446,7 @@ def sample_prior_predictive( ) # All model variables have a name, but mypy does not know this - _log.info(f"Sampling: {list(sorted(volatile_basic_rvs, key=lambda var: var.name))}") # type: ignore + _log.info(f"Sampling: {list(sorted(volatile_basic_rvs, key=lambda var: var.name))}") # type: ignore[arg-type, return-value] values = zip(*(sampler_fn() for i in range(draws))) data = {k: np.stack(v) for k, v in zip(names, values)} @@ -850,7 +850,7 @@ def sample_posterior_predictive( ) sampler_fn = point_wrapper(_sampler_fn) # All model variables have a name, but mypy does not know this - _log.info(f"Sampling: {list(sorted(volatile_basic_rvs, key=lambda var: var.name))}") # type: ignore + _log.info(f"Sampling: {list(sorted(volatile_basic_rvs, key=lambda var: var.name))}") # type: ignore[arg-type, return-value] ppc_trace_t = _DefaultTrace(samples) progress = CustomProgress( diff --git a/pymc/sampling/mcmc.py b/pymc/sampling/mcmc.py index 32d2702ff2..5c4ace2bc0 100644 --- a/pymc/sampling/mcmc.py +++ b/pymc/sampling/mcmc.py @@ -220,7 +220,7 @@ def assign_step_methods( has_gradient = getattr(var, "dtype") not in discrete_types if has_gradient: try: - tg.grad(model_logp, var) # type: ignore + tg.grad(model_logp, var) # type: ignore[arg-type] except (NotImplementedError, tg.NullTypeGradError): has_gradient = False @@ -228,7 +228,7 @@ def assign_step_methods( rv_var = model.values_to_rvs[var] selected = max( methods_list, - key=lambda method, var=rv_var, has_gradient=has_gradient: method._competence( # type: ignore + key=lambda method, var=rv_var, has_gradient=has_gradient: method._competence( # type: ignore[misc] var, has_gradient ), ) diff --git a/pymc/sampling/parallel.py b/pymc/sampling/parallel.py index a34947c706..2b4c0835ad 100644 --- a/pymc/sampling/parallel.py +++ b/pymc/sampling/parallel.py @@ -359,8 +359,8 @@ def terminate_all(processes, patience=2): raise multiprocessing.TimeoutError() process.join(timeout) except multiprocessing.TimeoutError: - logger.warn( - "Chain processes did not terminate as expected. " "Terminating forcefully..." + logger.warning( + "Chain processes did not terminate as expected. Terminating forcefully..." ) for process in processes: process.terminate() diff --git a/pymc/testing.py b/pymc/testing.py index 7a43c63766..75932b7c08 100644 --- a/pymc/testing.py +++ b/pymc/testing.py @@ -214,7 +214,7 @@ def RandomPdMatrix(n): Rdunif = Domain([-np.inf, -1, 0, 1, np.inf], "int64") Rplusunif = Domain([0, 0.5, np.inf]) Rplusdunif = Domain([0, 10, np.inf], "int64") -I = Domain([-np.inf, -3, -2, -1, 0, 1, 2, 3, np.inf], "int64") # noqa E741 +I = Domain([-np.inf, -3, -2, -1, 0, 1, 2, 3, np.inf], "int64") # noqa: E741 NatSmall = Domain([0, 3, 4, 5, np.inf], "int64") Nat = Domain([0, 1, 2, 3, np.inf], "int64") NatBig = Domain([0, 1, 2, 3, 5000, np.inf], "int64") diff --git a/pymc/tuning/scaling.py b/pymc/tuning/scaling.py index 08d267adb5..1438436c52 100644 --- a/pymc/tuning/scaling.py +++ b/pymc/tuning/scaling.py @@ -100,7 +100,7 @@ def adjust_precision(tau, scaling_bound=1e-8): return exp(bounded) ** 2 -def bound(a, l, u): # noqa E741 +def bound(a, l, u): # noqa: E741 return np.maximum(np.minimum(a, u), l) diff --git a/pymc/tuning/starting.py b/pymc/tuning/starting.py index cb8ae010d7..763acdab7c 100644 --- a/pymc/tuning/starting.py +++ b/pymc/tuning/starting.py @@ -142,7 +142,7 @@ def find_MAP( # TODO: If the mapping is fixed, we can simply create graphs for the # mapping and avoid all this bijection overhead compiled_logp_func = DictToArrayBijection.mapf(model.compile_logp(jacobian=False), start) - logp_func = lambda x: compiled_logp_func(RaveledVars(x, x0.point_map_info)) # noqa E731 + logp_func = lambda x: compiled_logp_func(RaveledVars(x, x0.point_map_info)) # noqa: E731 rvs = [model.values_to_rvs[vars_dict[name]] for name, _, _ in x0.point_map_info] try: @@ -151,7 +151,7 @@ def find_MAP( compiled_dlogp_func = DictToArrayBijection.mapf( model.compile_dlogp(rvs, jacobian=False), start ) - dlogp_func = lambda x: compiled_dlogp_func(RaveledVars(x, x0.point_map_info)) # noqa E731 + dlogp_func = lambda x: compiled_dlogp_func(RaveledVars(x, x0.point_map_info)) # noqa: E731 compute_gradient = True except (AttributeError, NotImplementedError, tg.NullTypeGradError): compute_gradient = False diff --git a/pymc/util.py b/pymc/util.py index fe55813385..a658e9daf7 100644 --- a/pymc/util.py +++ b/pymc/util.py @@ -98,7 +98,7 @@ def __init__(self, iterable=(), parent=None): if self.parent is not None: self.parent.extend(self) - # typechecking here works bad + # here typechecking works bad append = withparent(list.append) __iadd__ = withparent(list.__iadd__) extend = withparent(list.extend) @@ -143,7 +143,7 @@ def __init__(self, iterable=(), parent=None, **kwargs): if self.parent is not None: self.parent.update(self) - # typechecking here works bad + # here typechecking works bad __setitem__ = withparent(dict.__setitem__) update = withparent(dict.update) diff --git a/pymc/variational/callbacks.py b/pymc/variational/callbacks.py index 3c911e1ba2..19151d3a09 100644 --- a/pymc/variational/callbacks.py +++ b/pymc/variational/callbacks.py @@ -27,12 +27,12 @@ def __call__(self, approx, loss, i): def relative(current: np.ndarray, prev: np.ndarray, eps=1e-6) -> np.ndarray: - diff = current - prev # type: ignore + diff = current - prev return (np.abs(diff) + eps) / (np.abs(prev) + eps) def absolute(current: np.ndarray, prev: np.ndarray) -> np.ndarray: - diff = current - prev # type: ignore + diff = current - prev return np.abs(diff) diff --git a/pymc/variational/minibatch_rv.py b/pymc/variational/minibatch_rv.py index be71a358c9..8ee05f942c 100644 --- a/pymc/variational/minibatch_rv.py +++ b/pymc/variational/minibatch_rv.py @@ -84,10 +84,10 @@ def get_scaling(total_size: Sequence[Variable], shape: TensorVariable) -> Tensor """Gets scaling constant for logp.""" # mypy doesn't understand we can convert a shape TensorVariable into a tuple - shape = tuple(shape) # type: ignore + shape = tuple(shape) # type: ignore[assignment] # Scalar RV - if len(shape) == 0: # type: ignore + if len(shape) == 0: # type: ignore[arg-type] coef = total_size[0] if not NoneConst.equals(total_size[0]) else 1.0 else: coefs = [t / shape[i] for i, t in enumerate(total_size) if not NoneConst.equals(t)] diff --git a/tests/distributions/test_continuous.py b/tests/distributions/test_continuous.py index 73ab07d3c1..41504816ae 100644 --- a/tests/distributions/test_continuous.py +++ b/tests/distributions/test_continuous.py @@ -1932,7 +1932,7 @@ def halfstudentt_rng_fn(self, df, loc, scale, size, rng): pymc_dist_params = {"nu": 5.0, "sigma": 2.0} expected_rv_op_params = {"nu": 5.0, "sigma": 2.0} reference_dist_params = {"df": 5.0, "loc": 0, "scale": 2.0} - reference_dist = lambda self: ft.partial(self.halfstudentt_rng_fn, rng=self.get_random_state()) # noqa E731 + reference_dist = lambda self: ft.partial(self.halfstudentt_rng_fn, rng=self.get_random_state()) # noqa: E731 checks_to_run = [ "check_pymc_params_match_rv_op", "check_pymc_draws_match_reference", @@ -2166,7 +2166,7 @@ def logit_normal_rng_fn(self, rng, size, loc, scale): pymc_dist_params = {"mu": 5.0, "sigma": 10.0} expected_rv_op_params = {"mu": 5.0, "sigma": 10.0} reference_dist_params = {"loc": 5.0, "scale": 10.0} - reference_dist = lambda self: ft.partial(self.logit_normal_rng_fn, rng=self.get_random_state()) # noqa E731 + reference_dist = lambda self: ft.partial(self.logit_normal_rng_fn, rng=self.get_random_state()) # noqa: E731 checks_to_run = [ "check_pymc_params_match_rv_op", "check_pymc_draws_match_reference", @@ -2237,7 +2237,7 @@ class TestBeta(BaseTestDistributionRandom): expected_rv_op_params = {"alpha": 2.0, "beta": 5.0} reference_dist_params = {"a": 2.0, "b": 5.0} size = 15 - reference_dist = lambda self: ft.partial(clipped_beta_rvs, random_state=self.get_random_state()) # noqa E731 + reference_dist = lambda self: ft.partial(clipped_beta_rvs, random_state=self.get_random_state()) # noqa: E731 checks_to_run = [ "check_pymc_params_match_rv_op", "check_pymc_draws_match_reference", @@ -2443,7 +2443,7 @@ def polyagamma_rng_fn(self, size, h, z, rng): pymc_dist_params = {"h": 1.0, "z": 0.0} expected_rv_op_params = {"h": 1.0, "z": 0.0} reference_dist_params = {"h": 1.0, "z": 0.0} - reference_dist = lambda self: ft.partial(self.polyagamma_rng_fn, rng=self.get_random_state()) # noqa E731 + reference_dist = lambda self: ft.partial(self.polyagamma_rng_fn, rng=self.get_random_state()) # noqa: E731 checks_to_run = [ "check_pymc_params_match_rv_op", "check_pymc_draws_match_reference", @@ -2464,7 +2464,7 @@ def interpolated_rng_fn(self, size, mu, sigma, rng): pymc_dist_params = {"x_points": x_points, "pdf_points": pdf_points} reference_dist_params = {"mu": mu, "sigma": sigma} - reference_dist = lambda self: ft.partial(self.interpolated_rng_fn, rng=self.get_random_state()) # noqa E731 + reference_dist = lambda self: ft.partial(self.interpolated_rng_fn, rng=self.get_random_state()) # noqa: E731 checks_to_run = [ "check_rv_size", "check_draws", diff --git a/tests/distributions/test_custom.py b/tests/distributions/test_custom.py index 45a902b8e5..5b1de16178 100644 --- a/tests/distributions/test_custom.py +++ b/tests/distributions/test_custom.py @@ -189,14 +189,14 @@ def logp(value, mu): ) def test_custom_dist_default_support_point_univariate(self, support_point, size, expected): if support_point == "custom_support_point": - support_point = lambda rv, size, *rv_inputs: 5 * pt.ones(size, dtype=rv.dtype) # noqa E731 + support_point = lambda rv, size, *rv_inputs: 5 * pt.ones(size, dtype=rv.dtype) # noqa: E731 with Model() as model: x = CustomDist("x", support_point=support_point, size=size) assert isinstance(x.owner.op, CustomDistRV) assert_support_point_is_expected(model, expected, check_finite_logp=False) def test_custom_dist_moment_future_warning(self): - moment = lambda rv, size, *rv_inputs: 5 * pt.ones(size, dtype=rv.dtype) # noqa E731 + moment = lambda rv, size, *rv_inputs: 5 * pt.ones(size, dtype=rv.dtype) # noqa: E731 with Model() as model: with pytest.warns( FutureWarning, match="`moment` argument is deprecated. Use `support_point` instead." diff --git a/tests/distributions/test_discrete.py b/tests/distributions/test_discrete.py index b727c8a9d1..f57b0efedf 100644 --- a/tests/distributions/test_discrete.py +++ b/tests/distributions/test_discrete.py @@ -853,7 +853,7 @@ def discrete_uniform_rng_fn(self, size, lower, upper, rng): pymc_dist_params = {"lower": -1, "upper": 9} expected_rv_op_params = {"lower": -1, "upper": 9} reference_dist_params = {"lower": -1, "upper": 9} - reference_dist = lambda self: ft.partial( # noqa E731 + reference_dist = lambda self: ft.partial( # noqa: E731 self.discrete_uniform_rng_fn, rng=self.get_random_state() ) checks_to_run = [ diff --git a/tests/distributions/test_distribution.py b/tests/distributions/test_distribution.py index 8974a6017a..83173c5dd3 100644 --- a/tests/distributions/test_distribution.py +++ b/tests/distributions/test_distribution.py @@ -284,7 +284,7 @@ def diracdelta_rng_fn(self, size, c): pymc_dist_params = {"c": 3} expected_rv_op_params = {"c": 3} reference_dist_params = {"c": 3} - reference_dist = lambda self: self.diracdelta_rng_fn # noqa E731 + reference_dist = lambda self: self.diracdelta_rng_fn # noqa: E731 checks_to_run = [ "check_pymc_params_match_rv_op", "check_pymc_draws_match_reference", diff --git a/tests/distributions/test_multivariate.py b/tests/distributions/test_multivariate.py index 74199fa107..1fd1b7e6d8 100644 --- a/tests/distributions/test_multivariate.py +++ b/tests/distributions/test_multivariate.py @@ -1797,7 +1797,7 @@ def mvstudentt_rng_fn(self, size, nu, mu, scale, rng): "mu": np.array([1.0, 2.0]), "scale": np.array([[2.0, 0.0], [0.0, 3.5]]), } - reference_dist = lambda self: ft.partial(self.mvstudentt_rng_fn, rng=self.get_random_state()) # noqa E731 + reference_dist = lambda self: ft.partial(self.mvstudentt_rng_fn, rng=self.get_random_state()) # noqa: E731 checks_to_run = [ "check_pymc_params_match_rv_op", "check_pymc_draws_match_reference", @@ -2000,7 +2000,7 @@ def wishart_rng_fn(self, size, nu, V, rng): (1, 3, 3), (4, 5, 3, 3), ] - reference_dist = lambda self: ft.partial(self.wishart_rng_fn, rng=self.get_random_state()) # noqa E731 + reference_dist = lambda self: ft.partial(self.wishart_rng_fn, rng=self.get_random_state()) # noqa: E731 checks_to_run = [ "check_rv_size", "check_pymc_params_match_rv_op", @@ -2129,7 +2129,7 @@ def kronecker_rng_fn(self, size, mu, covs=None, sigma=None, rng=None): sizes_to_check = [None, (), 1, (1,), 5, (4, 5), (2, 4, 2)] sizes_expected = [(N,), (N,), (1, N), (1, N), (5, N), (4, 5, N), (2, 4, 2, N)] - reference_dist = lambda self: ft.partial(self.kronecker_rng_fn, rng=self.get_random_state()) # noqa E731 + reference_dist = lambda self: ft.partial(self.kronecker_rng_fn, rng=self.get_random_state()) # noqa: E731 checks_to_run = [ "check_pymc_draws_match_reference", "check_rv_size", @@ -2382,7 +2382,7 @@ def test_mvnormal_no_cholesky_in_model_logp(): data = np.ones((batch_size, n)) pm.MvNormal("y", mu=mu, chol=pt.broadcast_to(chol, (batch_size, n, n)), observed=data) - contains_cholesky_op = lambda fgraph: any( # noqa E731 + contains_cholesky_op = lambda fgraph: any( # noqa: E731 isinstance(node.op, Cholesky) for node in fgraph.apply_nodes ) diff --git a/tests/distributions/test_timeseries.py b/tests/distributions/test_timeseries.py index 771894737a..b30e49bc54 100644 --- a/tests/distributions/test_timeseries.py +++ b/tests/distributions/test_timeseries.py @@ -957,7 +957,7 @@ def _gen_sde_path(sde, pars, dt, n, x0): xs.append(xs[-1] + f * dt + np.sqrt(dt) * g * wt[i]) return np.array(xs) - sde = lambda x, lam: (lam * x, sig2) # noqa E731 + sde = lambda x, lam: (lam * x, sig2) # noqa: E731 x = floatX(_gen_sde_path(sde, (lam,), dt, N, 5.0)) z = x + numpy_rng.standard_normal(size=x.size) * sig2 # build model From 0be7ee513a8edfb9567f3f1f0b1796e0994fcd46 Mon Sep 17 00:00:00 2001 From: Virgile Andreani Date: Tue, 17 Sep 2024 11:46:27 -0400 Subject: [PATCH 4/4] Tweak ruff config --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a65931dfe5..71e948ae0f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -52,7 +52,7 @@ repos: rev: v0.6.5 hooks: - id: ruff - args: ["--fix", "--output-format=full"] + args: [--fix, --show-fixes] - id: ruff-format - repo: https://github.com/MarcoGorelli/madforhooks rev: 0.4.1