diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b29774d..06993b2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,14 +1,10 @@ files: "spglm\/" repos: - - repo: https://github.com/psf/black - rev: "24.3.0" - hooks: - - id: black - language_version: python3 - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.3.5" + rev: "v0.5.1" hooks: - id: ruff + - id: ruff-format ci: autofix_prs: false diff --git a/pyproject.toml b/pyproject.toml index 4da727b..38753c9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,6 @@ Repository = "https://github.com/pysal/spglm" [project.optional-dependencies] dev = [ - "black", "ruff", "pre-commit", ] @@ -63,33 +62,22 @@ include = [ "spglm.*", ] -[tool.black] -line-length = 88 -extend-exclude = ''' -( - docs/conf.py -) -#''' - [tool.ruff] line-length = 88 -select = ["E", "F", "W", "I", "UP", "N", "B", "A", "C4", "SIM", "ARG"] -target-version = "py39" -ignore = [ - "B006", - "B008", - "B009", - "B010", - "C408", - "E731", +lint.select = ["E", "F", "W", "I", "UP", "N", "B", "A", "C4", "SIM", "ARG"] +lint.ignore = [ + "ARG002", # Unused method argument + "B008", # Do not perform function call in argument defaults + "N801", # Class name should use CapWords convention + "N802", # Function name should be lowercase + "N806", # Variable in function should be lowercase +] + +[tool.ruff.lint.per-file-ignores] +"*__init__.py" = [ "F401", "F403", - "N803", - "N806", - "N999", - "UP007" ] -exclude = ["spglm/tests/*", "docs/*"] [tool.coverage.run] source = ["./spglm"] @@ -103,4 +91,4 @@ exclude_lines = [ "except ImportError", ] ignore_errors = true -omit = ["spglm/tests/*", "spglm/conf.py"] +omit = ["spglm/tests/*", "spglm/docs/conf.py"] diff --git a/spglm/__init__.py b/spglm/__init__.py index 2cbca23..4590e8d 100644 --- a/spglm/__init__.py +++ b/spglm/__init__.py @@ -2,10 +2,10 @@ from importlib.metadata import PackageNotFoundError, version from . import ( - family, # noqa F401 - glm, # noqa F401 - iwls, # noqa F401 - utils, # noqa F401 + family, + glm, + iwls, + utils, ) with contextlib.suppress(PackageNotFoundError): diff --git a/spglm/base.py b/spglm/base.py index f2191eb..ab2f944 100644 --- a/spglm/base.py +++ b/spglm/base.py @@ -20,7 +20,7 @@ def __init__(self, model, params, **kwd): self.initialize(model, params, **kwd) self._data_attr = [] - def initialize(self, model, params, **kwd): # noqa ARG002 + def initialize(self, model, params, **kwd): self.params = params self.model = model if hasattr(model, "k_constant"): @@ -306,7 +306,7 @@ def cov_params( ]: ###################################################################### # TODO - remove GH#38 - dot_fun = nan_dot # noqa F821 - `nan_dot` not defined - should remove + dot_fun = nan_dot # noqa: F821 - `nan_dot` not defined - should remove ###################################################################### else: dot_fun = np.dot @@ -350,7 +350,7 @@ def cov_params( else: # if r_matrix is None and column is None: return cov_p - def conf_int(self, alpha=0.05, cols=None, method="default"): # noqa ARG002 + def conf_int(self, alpha=0.05, cols=None, method="default"): """ Returns the confidence interval of the fitted parameters. diff --git a/spglm/family.py b/spglm/family.py index be7eb84..8cc0c56 100644 --- a/spglm/family.py +++ b/spglm/family.py @@ -9,8 +9,8 @@ import numpy as np from scipy import special -from . import links as L # noqa N812 -from . import varfuncs as V # noqa N812 +from . import links as L # noqa: N812 - Lowercase imported as non-lowercase +from . import varfuncs as V # noqa: N812 FLOAT_EPS = np.finfo(float).eps @@ -455,7 +455,7 @@ def deviance(self, endog, mu, freq_weights=1.0, scale=1.0): endog_mu = self._clean(endog / mu) return 2 * np.sum(endog * freq_weights * np.log(endog_mu)) / scale - def loglike(self, endog, mu, freq_weights=1.0, scale=1.0): # noqa ARG002 + def loglike(self, endog, mu, freq_weights=1.0, scale=1.0): r""" The log-likelihood function in terms of the fitted mean response. @@ -654,7 +654,7 @@ def _clean(self, x): """ return np.clip(x, FLOAT_EPS, np.inf) - def deviance(self, endog, mu, freq_weights=1.0, scale=1.0): # noqa ARG002 + def deviance(self, endog, mu, freq_weights=1.0, scale=1.0): r""" Gamma deviance function @@ -678,7 +678,7 @@ def deviance(self, endog, mu, freq_weights=1.0, scale=1.0): # noqa ARG002 endog_mu = self._clean(endog / mu) return 2 * np.sum(freq_weights * ((endog - mu) / mu - np.log(endog_mu))) - def resid_dev(self, endog, mu, scale=1.0): # noqa ARG002 + def resid_dev(self, endog, mu, scale=1.0): r""" Gamma deviance residuals @@ -805,7 +805,7 @@ def starting_mu(self, y): """ return (y + 0.5) / 2 - def initialize(self, endog, freq_weights): # noqa ARG002 + def initialize(self, endog, freq_weights): """ Initialize the response variable. @@ -833,7 +833,7 @@ def initialize(self, endog, freq_weights): # noqa ARG002 else: return endog, np.ones(endog.shape[0]) - def deviance(self, endog, mu, freq_weights=1, scale=1.0, axis=None): # noqa ARG002 + def deviance(self, endog, mu, freq_weights=1, scale=1.0, axis=None): r""" Deviance function for either Bernoulli or Binomial data. @@ -982,7 +982,7 @@ def resid_anscombe(self, endog, mu): Journal of the Royal Statistical Society B. 30, 248-75. """ - cox_snell = lambda x: ( # noqa E731 - skip "don't use lambda" + cox_snell = lambda x: ( # noqa: E731 - skip "don't use lambda" special.betainc(2 / 3.0, 2 / 3.0, x) * special.beta(2 / 3.0, 2 / 3.0) ) return np.sqrt(self.n) * ( diff --git a/spglm/glm.py b/spglm/glm.py index 962e4be..3573ccc 100644 --- a/spglm/glm.py +++ b/spglm/glm.py @@ -82,7 +82,13 @@ class GLM(RegressionPropsY): """ def __init__( - self, y, X, family=family.Gaussian(), offset=None, y_fix=None, constant=True + self, + y, + X, # noqa: N803 - Argument name should be lowercase + family=family.Gaussian(), + offset=None, + y_fix=None, + constant=True, ): """ Initialize class @@ -340,7 +346,7 @@ def pearson_chi2(self): @cache_readonly def null(self): y = np.reshape(self.y, (-1, 1)) - model = self.model # noqa F841 - `model` never used + model = self.model # noqa: F841 - `model` never used X = np.ones((len(y), 1)) null_mod = GLM(y, X, family=self.family, offset=self.offset, constant=False) return null_mod.fit().mu @@ -382,25 +388,25 @@ def bic(self): return self.deviance - (self.model.n - self.df_model - 1) * np.log(self.model.n) @cache_readonly - def D2(self): # noqa N802 + def D2(self): return 1 - (self.deviance / self.null_deviance) @cache_readonly - def adj_D2(self): # noqa N802 + def adj_D2(self): return 1.0 - (float(self.n) - 1.0) / (float(self.n) - float(self.k)) * ( 1.0 - self.D2 ) @cache_readonly - def pseudoR2(self): # noqa N802 + def pseudoR2(self): return 1 - (self.llf / self.llnull) @cache_readonly - def adj_pseudoR2(self): # noqa N802 + def adj_pseudoR2(self): return 1 - ((self.llf - self.k) / self.llnull) @cache_readonly - def tr_S(self): # noqa N802 + def tr_S(self): xtx_inv = np.linalg.inv(np.dot(self.X.T, self.X)) xtx_inv_xt = np.dot(xtx_inv, self.X.T) S = np.dot(self.X, xtx_inv_xt) diff --git a/spglm/iwls.py b/spglm/iwls.py index d8d9433..889919c 100644 --- a/spglm/iwls.py +++ b/spglm/iwls.py @@ -44,7 +44,7 @@ def iwls( x, family, offset, - y_fix, # noqa ARG001 + y_fix, # noqa: ARG001 - Unused function argument ini_betas=None, tol=1.0e-8, max_iter=200, diff --git a/spglm/links.py b/spglm/links.py index 2ba13bd..5a5af4e 100644 --- a/spglm/links.py +++ b/spglm/links.py @@ -15,7 +15,7 @@ class Link: `Link` does nothing, but lays out the methods expected of any subclass. """ - def __call__(self, p): # noqa ARG002 + def __call__(self, p): """ Return the value of the link function. This is just a placeholder. @@ -31,7 +31,7 @@ def __call__(self, p): # noqa ARG002 """ return NotImplementedError - def inverse(self, z): # noqa ARG002 + def inverse(self, z): """ Inverse of the link function. Just a placeholder. @@ -50,7 +50,7 @@ def inverse(self, z): # noqa ARG002 """ return NotImplementedError - def deriv(self, p): # noqa ARG002 + def deriv(self, p): """ Derivative of the link function g'(p). Just a placeholder. @@ -230,7 +230,7 @@ def deriv2(self, p): return (2 * p - 1) / v**2 -class logit(Logit): # noqa N801 +class logit(Logit): pass @@ -357,7 +357,7 @@ def inverse_deriv(self, z): return np.power(z, (1 - self.power) / self.power) / self.power -class inverse_power(Power): # noqa N801 +class inverse_power(Power): """ The inverse transform @@ -372,7 +372,7 @@ def __init__(self): super().__init__(power=-1.0) -class sqrt(Power): # noqa N801 +class sqrt(Power): """ The square-root transform @@ -387,7 +387,7 @@ def __init__(self): super().__init__(power=0.5) -class inverse_squared(Power): # noqa N801 +class inverse_squared(Power): r""" The inverse squared transform @@ -402,7 +402,7 @@ def __init__(self): super().__init__(power=-2.0) -class identity(Power): # noqa N801 +class identity(Power): """ The identity transform @@ -531,7 +531,7 @@ def inverse_deriv(self, z): return np.exp(z) -class log(Log): # noqa N801 +class log(Log): """ The log transform @@ -655,7 +655,7 @@ def inverse_deriv(self, z): return 1 / self.deriv(self.inverse(z)) -class probit(CDFLink): # noqa N801 +class probit(CDFLink): """ The probit (standard normal CDF) transform @@ -669,7 +669,7 @@ class probit(CDFLink): # noqa N801 pass -class cauchy(CDFLink): # noqa N801 +class cauchy(CDFLink): """ The Cauchy (standard Cauchy CDF) transform @@ -814,7 +814,7 @@ def inverse_deriv(self, z): return np.exp(z - np.exp(z)) -class cloglog(CLogLog): # noqa N801 +class cloglog(CLogLog): """ The CLogLog transform link function. @@ -950,7 +950,7 @@ def inverse_deriv(self, z): return t / (self.alpha * (1 - t) ** 2) -class nbinom(NegativeBinomial): # noqa N801 +class nbinom(NegativeBinomial): """ The negative binomial link function. diff --git a/spglm/utils.py b/spglm/utils.py index da02159..1e1a574 100644 --- a/spglm/utils.py +++ b/spglm/utils.py @@ -20,7 +20,7 @@ def _bit_length_26(x): ###################################################################### # TODO - remove GH#39 - string_types = basestring # noqa F821 - `basestring` not defined - should remove + string_types = basestring # noqa: F821 - `basestring` not defined - should remove ###################################################################### class NumpyVersion: @@ -155,7 +155,7 @@ def __ge__(self, other): return self._compare(other) >= 0 def __repr(self): - return "NumpyVersion(%s)" % self.vstring + return f"NumpyVersion({self.vstring})" class ResettableCache(dict): @@ -255,7 +255,7 @@ def _next_regular(target): np_matrix_rank = np.linalg.matrix_rank else: - def np_matrix_rank(M, tol=None): + def np_matrix_rank(M, tol=None): # noqa: N803 - Argument name should be lowercase """ Return matrix rank of array using SVD method Rank of the array is the number of SVD singular values of the array that are @@ -377,11 +377,11 @@ def __get__(self, obj, type_=None): return _cachedval def __set__(self, obj, value): - errmsg = "The attribute '%s' cannot be overwritten" % self.name + errmsg = f"The attribute '{self.name}' cannot be overwritten" warnings.warn(errmsg, CacheWriteWarning, stacklevel=2) -class _cache_readonly: # noqa N801 +class _cache_readonly: """ Decorator for CachedAttribute """ diff --git a/spglm/varfuncs.py b/spglm/varfuncs.py index 0f7c0c8..0594f99 100644 --- a/spglm/varfuncs.py +++ b/spglm/varfuncs.py @@ -117,7 +117,7 @@ def deriv(self, mu): ######################################################################## # `approx_fprime_cs` is imported by unused - from statsmodels.tools.numdiff import approx_fprime_cs # noqa F401 + from statsmodels.tools.numdiff import approx_fprime_cs # noqa: F401, I001 # return approx_fprime_cs(mu, self) # TODO fix breaks in `fabs ########################################################################