Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,18 @@ jobs:
- name: Build
run: cmake --build build -j 2

pylint:
runs-on: ubuntu-latest
name: PyLint

steps:
- uses: actions/checkout@v1
with:
submodules: true

- name: Run PyLint
run: pipx run nox -s pylint


cmake:
runs-on: ubuntu-latest
Expand Down
11 changes: 11 additions & 0 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ def lint(session: nox.Session) -> None:
session.run("pre-commit", "run", "--all-files", *session.posargs)


@nox.session
def pylint(session: nox.Session) -> None:
"""
Run pylint.
"""

session.install("pylint")
session.install("-e", ".")
session.run("pylint", "src")


@nox.session
def make_pickle(session: nox.Session) -> None:
"""
Expand Down
25 changes: 25 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,28 @@ manylinux-i686-image = "manylinux2014"
select = "cp3?-*"
manylinux-x86_64-image = "manylinux2010"
manylinux-i686-image = "manylinux2010"

[tool.pylint]

master.py-version = "3.6"
master.extension-pkg-allow-list = ["boost_histogram._core"]
similarities.ignore-imports = "yes"
messages_control.disable = [
"fixme",
"invalid-name",
"line-too-long",
"missing-class-docstring",
"missing-function-docstring",
"missing-module-docstring",
"no-member", # C extensions mess with this
"protected-access",
"too-few-public-methods",
"too-many-arguments",
"too-many-branches",
"too-many-lines",
"too-many-locals",
"too-many-return-statements",
"too-many-statements",
"wrong-import-position",
"cyclic-import", # TODO: move files out of _internal
]
8 changes: 7 additions & 1 deletion src/boost_histogram/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
from . import accumulators, axis, numpy, storage
from ._internal.enum import Kind
from ._internal.hist import Histogram, IndexingExpr
from .tag import loc, overflow, rebin, sum, underflow
from .tag import ( # pylint: disable=redefined-builtin
loc,
overflow,
rebin,
sum,
underflow,
)
from .version import version as __version__

try:
Expand Down
7 changes: 4 additions & 3 deletions src/boost_histogram/_internal/axestuple.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ class ArrayTuple(tuple): # type: ignore[type-arg]
def __getattr__(self, name: str) -> Any:
if name in self._REDUCTIONS:
return partial(getattr(np, name), np.broadcast_arrays(*self)) # type: ignore[no-untyped-call]
else:
return self.__class__(getattr(a, name) for a in self)

return self.__class__(getattr(a, name) for a in self)

def __dir__(self) -> List[str]:
names = dir(self.__class__) + dir("np.typing.NDArray[Any]")
Expand Down Expand Up @@ -51,6 +51,7 @@ def __init__(self, __iterable: Iterable[Axis]) -> None:
raise TypeError(
f"Only an iterable of Axis supported in AxesTuple, got {item}"
)
super().__init__()

@property
def size(self) -> Tuple[int, ...]:
Expand Down Expand Up @@ -105,7 +106,7 @@ def __getattr__(self, attr: str) -> Tuple[Any, ...]:

def __setattr__(self, attr: str, values: Any) -> None:
try:
return super().__setattr__(attr, values)
super().__setattr__(attr, values)
except AttributeError:
for s, v in zip_strict(self, values):
s.__setattr__(attr, v)
Expand Down
40 changes: 18 additions & 22 deletions src/boost_histogram/_internal/axis.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
Union,
)

import numpy as np
import numpy as np # pylint: disable=unused-import

import boost_histogram

Expand All @@ -31,10 +31,9 @@ def _isstr(value: Any) -> bool:

if isinstance(value, (str, bytes)):
return True
elif hasattr(value, "__iter__"):
if hasattr(value, "__iter__"):
return all(_isstr(v) for v in value)
else:
return False
return False


def _opts(**kwargs: bool) -> Set[str]:
Expand Down Expand Up @@ -87,7 +86,7 @@ def __init__(
raise KeyError(
"Cannot provide metadata by keyword and __dict__, use __dict__ only"
)
elif __dict__ is not None:
if __dict__ is not None:
self._ax.metadata = __dict__
elif metadata is not None:
self._ax.metadata["metadata"] = metadata
Expand All @@ -112,14 +111,11 @@ def index(self, value: Union[float, str]) -> int:
Return the fractional index(es) given a value (or values) on the axis.
"""

if not _isstr(value):
return self._ax.index(value) # type: ignore[no-any-return]
else:
raise TypeError(
"index({value}) cannot be a string for a numerical axis".format(
value=value
)
)
if _isstr(value):
msg = f"index({value}) cannot be a string for a numerical axis"
raise TypeError(msg)

return self._ax.index(value) # type: ignore[no-any-return]

def value(self, index: float) -> float:
"""
Expand Down Expand Up @@ -486,7 +482,8 @@ def _repr_args_(self) -> List[str]:
if len(self) > 20:
ret = [repr(self.edges)]
else:
ret = ["[{}]".format(", ".join(format(v, "g") for v in self.edges))]
args = ", ".join(format(v, "g") for v in self.edges)
ret = [f"[{args}]"]

if self.traits.growth:
ret.append("growth=True")
Expand Down Expand Up @@ -670,17 +667,15 @@ def index(self, value: Union[float, str]) -> int:

if _isstr(value):
return self._ax.index(value) # type: ignore[no-any-return]
else:
raise TypeError(
"index({value}) must be a string or iterable of strings for a StrCategory axis".format(
value=value
)
)

msg = f"index({value}) must be a string or iterable of strings for a StrCategory axis"
raise TypeError(msg)

def _repr_args_(self) -> List[str]:
"Return inner part of signature for use in repr"

ret = ["[{}]".format(", ".join(repr(c) for c in self))]
args = ", ".join(repr(c) for c in self)
ret = [f"[{args}]"]
ret += super()._repr_args_()
return ret

Expand Down Expand Up @@ -732,7 +727,8 @@ def __init__(
def _repr_args_(self) -> List[str]:
"Return inner part of signature for use in repr"

ret = ["[{}]".format(", ".join(format(c, "g") for c in self))]
args = ", ".join(format(c, "g") for c in self)
ret = [f"[{args}]"]
ret += super()._repr_args_()
return ret

Expand Down
8 changes: 4 additions & 4 deletions src/boost_histogram/_internal/axis_transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ def _convert_cpp(cls: Type[T], this: Any) -> T:
def __repr__(self) -> str:
if hasattr(self, "_this"):
return repr(self._this)
else:
return f"{self.__class__.__name__}() # Missing _this, broken class"

return f"{self.__class__.__name__}() # Missing _this, broken class"

def _produce(self, bins: int, start: float, stop: float) -> Any:
# Note: this is an ABC; _type must be defined on children
Expand Down Expand Up @@ -62,7 +62,7 @@ class Pow(AxisTransform, family=boost_histogram):
__slots__ = ()
_type = ca.regular_pow

def __init__(self, power: float):
def __init__(self, power: float): # pylint: disable=super-init-not-called
"Create a new transform instance"
# Note: this comes from family
(cpp_class,) = self._types # type: ignore[attr-defined]
Expand All @@ -84,7 +84,7 @@ class Function(AxisTransform, family=boost_histogram):
__slots__ = ()
_type = ca.regular_trans

def __init__(
def __init__( # pylint: disable=super-init-not-called
self, forward: Any, inverse: Any, *, convert: Any = None, name: str = ""
):
"""
Expand Down
6 changes: 2 additions & 4 deletions src/boost_histogram/_internal/deprecated.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,11 @@ def __call__(self, func: Any) -> Any:
@functools.wraps(func)
def decorated_func(*args: Any, **kwargs: Any) -> Any:
warnings.warn(
"{} is deprecated: {}".format(
self._name or func.__name__, self._reason
),
f"{self._name or func.__name__} is deprecated: {self._reason}",
category=FutureWarning,
stacklevel=2,
)
return func(*args, **kwargs)

decorated_func.__doc__ = "DEPRECATED: " + self._reason + "\n" + func.__doc__
decorated_func.__doc__ = f"DEPRECATED: {self._reason}\n{func.__doc__}"
return decorated_func
Loading