Skip to content

Commit

Permalink
Migrate code linting to Ruff, apply fixes (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
koenvervloesem committed Apr 25, 2023
1 parent 2716505 commit 549de50
Show file tree
Hide file tree
Showing 20 changed files with 216 additions and 217 deletions.
62 changes: 3 additions & 59 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,6 @@ repos:
- id: mixed-line-ending
args: ['--fix=auto'] # replace 'auto' with 'lf' to enforce Linux/Mac line endings or 'crlf' for Windows

## If you want to avoid flake8 errors due to unused vars or imports:
# - repo: https://github.com/myint/autoflake
# rev: v1.4
# hooks:
# - id: autoflake
# args: [
# --in-place,
# --remove-all-unused-imports,
# --remove-unused-variables,
# ]

- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort

- repo: https://github.com/psf/black
rev: 23.1.0
hooks:
Expand All @@ -46,44 +30,10 @@ repos:
# - id: blacken-docs
# additional_dependencies: [black]

- repo: https://github.com/PyCQA/flake8
rev: 6.0.0
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.0.261
hooks:
- id: flake8
additional_dependencies:
- flake8-bugbear
- pep8-naming
- flake8-length
- tryceratops
- flake8-return
- flake8-newspaper-style
- flake8-warnings
- flake8-encodings
- flake8-simplify
- flake8-pie
- flake8-comprehensions
- flake8-picky-parentheses
# Documentation
- flake8-docstrings
- flake8-rst
- flake8-rst-docstrings
# Typing
- flake8-future-annotations
- flake8-annotations
- flake-type-annotations-plugin
# Tests
- flake8-pytest-style

- repo: https://github.com/pycqa/pylint
rev: v2.16.0b1
hooks:
- id: pylint
args:
[
--disable=duplicate-code,
--disable=logging-fstring-interpolation,
src,
]
- id: ruff
additional_dependencies:
- bleak
- pytest
Expand All @@ -95,12 +45,6 @@ repos:
- id: interrogate
args: [--verbose, --omit-covered-files, --fail-under=100]

- repo: https://github.com/asottile/pyupgrade
rev: "v3.3.1"
hooks:
- id: pyupgrade
args: ["--py37-plus"]

- repo: https://github.com/codespell-project/codespell
rev: v2.2.2
hooks:
Expand Down
26 changes: 26 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,29 @@ build-backend = "setuptools.build_meta"
# For smarter version schemes and other configuration options,
# check out https://github.com/pypa/setuptools_scm
version_scheme = "no-guess-dev"

[tool.ruff]
select = ["ALL"]
ignore = [
"ANN101", # flake8-annotations
"ANN102",
"ARG002", # flake8-unused-arguments
"ARG003",
"DTZ001", # flake8-datetimez
"DTZ006",
"FBT", # flake8-boolean-trap
"T20", # flake8-print
]
# Always generate Python 3.7-compatible code
target-version = "py37"

src = ["src", "test"]

[tool.ruff.per-file-ignores]
"tests/*" = [
"INP001", # implicit namespace
"S101", # assert
]

[tool.ruff.pydocstyle]
convention = "google"
40 changes: 0 additions & 40 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -114,46 +114,6 @@ testpaths = tests
no_vcs = 1
formats = bdist_wheel

[flake8]
# Some sane defaults for the code style checker flake8
max_line_length = 88
# flake8-docstrings config
docstring-convention = google
# For flake8-rst-docstrings:
rst-roles =
class,
func,
ref,
meth,
mod,
obj,
rst-directives =
envvar,
exception,
rst-substitutions =
version,
extend_ignore = E203, W503
# ^ Black-compatible
# E203 and W503 have edge cases handled by black
RST307,
# Google Python style is not RST until after processed by Napoleon
# See https://github.com/peterjc/flake8-rst-docstrings/issues/17
RST201,RST203,RST301,
# Missing type annotations for self and cls in (class) method
ANN101,ANN102,
# Handled by flake8-length
E501, W505,
# Opinionated check by flake8-picky-parentheses
PAR101,
exclude =
.tox
build
dist
.eggs
docs/conf.py
# flake8-pytest-style config
pytest-parametrize-names-type = csv

[pyscaffold]
# PyScaffold's parameters when the project was created.
# This will be used when updating. Do not change!
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
if __name__ == "__main__":
try:
setup(use_scm_version={"version_scheme": "no-guess-dev"})
except: # noqa
except:
print(
"\n\nAn error occurred while building the project, "
"please ensure you have the most updated version of setuptools, "
"setuptools_scm and wheel with:\n"
" pip install -U setuptools setuptools_scm wheel\n\n"
" pip install -U setuptools setuptools_scm wheel\n\n",
)
raise
52 changes: 29 additions & 23 deletions src/bluetooth_clocks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@
from pathlib import Path
from pkgutil import iter_modules
from time import time
from typing import ClassVar, Type # noqa: F401
from uuid import UUID
from typing import TYPE_CHECKING, ClassVar

if TYPE_CHECKING:
from uuid import UUID

from bleak import BleakClient
from bleak.backends.device import BLEDevice
from bleak.backends.scanner import AdvertisementData

if TYPE_CHECKING:
from bleak.backends.device import BLEDevice
from bleak.backends.scanner import AdvertisementData

from bluetooth_clocks.exceptions import TimeNotReadableError, UnsupportedDeviceError

Expand All @@ -29,7 +33,7 @@

try:
# Change here if project is renamed and does not equal the package name
dist_name = "bluetooth-clocks" # pylint: disable=invalid-name
dist_name = "bluetooth-clocks"
__version__ = version(dist_name)
except PackageNotFoundError: # pragma: no cover
__version__ = "unknown"
Expand Down Expand Up @@ -83,33 +87,33 @@ class BluetoothClock(ABC):
have a name.
"""

DEVICE_TYPE: ClassVar[str] # noqa: CCE001
DEVICE_TYPE: ClassVar[str]
"""The name of the device type."""

SERVICE_UUID: ClassVar[UUID] # noqa: CCE001
SERVICE_UUID: ClassVar[UUID]
"""The UUID of the service used to read/write the time."""

CHAR_UUID: ClassVar[UUID] # noqa: CCE001
CHAR_UUID: ClassVar[UUID]
"""The UUID of the characteristic used to read/write the time."""

TIME_GET_FORMAT: ClassVar[str | None] # noqa: CCE001
TIME_GET_FORMAT: ClassVar[str | None]
"""The format string to convert bytes read from the device to a time.
This is ``None`` if the device doesn't support reading the time.
"""

TIME_SET_FORMAT: ClassVar[str] # noqa: CCE001
TIME_SET_FORMAT: ClassVar[str]
"""The format string to convert a time to bytes written to the device."""

WRITE_WITH_RESPONSE: ClassVar[bool] # noqa: CCE001
WRITE_WITH_RESPONSE: ClassVar[bool]
"""``True`` if the bytes to set the time should use write with response."""

LOCAL_NAME: ClassVar[str | None] # noqa: CCE001
LOCAL_NAME: ClassVar[str | None]
"""The local name used to recognize this type of device.
This is ``None`` if the local name isn't used to recognize the device."""

LOCAL_NAME_STARTS_WITH: ClassVar[bool | None] # noqa: CCE001
LOCAL_NAME_STARTS_WITH: ClassVar[bool | None]
"""Whether the local name should start with `LOCAL_NAME`.
``True`` if the start of `LOCAL_NAME` is used to recognize this type of device.
Expand All @@ -128,7 +132,9 @@ def __init__(self, device: BLEDevice) -> None:

@classmethod
def create_from_advertisement(
cls, device: BLEDevice, advertisement_data: AdvertisementData
cls,
device: BLEDevice,
advertisement_data: AdvertisementData,
) -> BluetoothClock:
"""Create object of a :class:`BluetoothClock` subclass from advertisement data.
Expand Down Expand Up @@ -175,7 +181,7 @@ def is_readable(cls) -> bool:
@classmethod
def recognize(
cls,
device: BLEDevice, # pylint: disable=unused-argument
device: BLEDevice,
advertisement_data: AdvertisementData,
) -> bool:
"""Recognize this device type from advertisement data.
Expand Down Expand Up @@ -246,9 +252,7 @@ def recognize_from_local_name(
return local_name.startswith(cls.LOCAL_NAME)
return local_name == cls.LOCAL_NAME

def get_time_from_bytes( # pylint: disable=unused-argument
self, time_bytes: bytes
) -> float:
def get_time_from_bytes(self, time_bytes: bytes) -> float:
"""Convert bytes read from a device to a timestamp.
Override this method in a subclass for a device that supports getting the time.
Expand All @@ -267,12 +271,12 @@ def get_time_from_bytes( # pylint: disable=unused-argument
>>> from bluetooth_clocks.devices.xiaomi import LYWSD02
>>> from bleak.backends.device import BLEDevice
>>> from datetime import datetime
>>> clock = LYWSD02(BLEDevice("E7:2E:00:B1:38:96"))
>>> clock = LYWSD02(BLEDevice("E7:2E:00:B1:38:96", "", {}, -67))
>>> timestamp = clock.get_time_from_bytes(
... bytes([0xdd, 0xbc, 0xb9, 0x63, 0x00]))
>>> print(datetime.utcfromtimestamp(timestamp).strftime("%Y-%m-%d %H:%M:%S"))
2023-01-07 18:41:33
"""
""" # noqa: E501
raise TimeNotReadableError

@abstractmethod
Expand All @@ -294,7 +298,7 @@ def get_bytes_from_time(self, timestamp: float, ampm: bool = False) -> bytes:
>>> from bluetooth_clocks.devices.thermopro import TP393
>>> from bleak.backends.device import BLEDevice
>>> from datetime import datetime
>>> clock = TP393(BLEDevice("10:76:36:14:2A:3D"))
>>> clock = TP393(BLEDevice("10:76:36:14:2A:3D", "TP393 (2A3D)", {}, -67))
>>> timestamp = datetime.fromisoformat("2023-01-07 17:32:50").timestamp()
>>> clock.get_bytes_from_time(timestamp, ampm=True).hex()
'a517010711203206005a'
Expand All @@ -321,7 +325,9 @@ async def get_time(self) -> float:
return self.get_time_from_bytes(time_bytes)

async def set_time(
self, timestamp: float | None = None, ampm: bool = False
self,
timestamp: float | None = None,
ampm: bool = False,
) -> None:
"""Set the time of the Bluetooth clock.
Expand All @@ -347,7 +353,7 @@ async def set_time(

# Iterate through the modules in the module `device`.
package_dir = Path(__file__).resolve().parent / "devices"
for _, module_name, _ in iter_modules([str(package_dir)]): # type: ignore
for _, module_name, _ in iter_modules([str(package_dir)]): # type: ignore[assignment]
# Import the module and iterate through its attributes
module = import_module(f"{__name__}.devices.{module_name}")
for attribute_name in dir(module):
Expand Down
13 changes: 9 additions & 4 deletions src/bluetooth_clocks/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ def parse_args(args: list[str]) -> Namespace:

# Parser for the "discover" subcommand
parser_discover = subparsers.add_parser(
"discover", help="discover supported Bluetooth clocks"
"discover",
help="discover supported Bluetooth clocks",
)
parser_discover.add_argument(
"-s",
Expand All @@ -92,7 +93,8 @@ def parse_args(args: list[str]) -> Namespace:

# Parser for the "get" subcommand
parser_get = subparsers.add_parser(
"get", help="get the time from a Bluetooth clock"
"get",
help="get the time from a Bluetooth clock",
)
parser_get.add_argument(
"-a",
Expand Down Expand Up @@ -128,7 +130,7 @@ def parse_args(args: list[str]) -> Namespace:
"-t",
"--time",
type=str,
help="the time to set, in ISO 8601 format (e.g. 2023-01-10T16:20, default: current time)",
help="the time to set, in ISO 8601 format (e.g. 2023-01-10T16:20, default: current time)", # noqa: E501
)
parser_set.add_argument(
"-p",
Expand All @@ -150,7 +152,10 @@ def setup_logging(loglevel: int) -> None:
"""
logformat = "[%(asctime)s] %(levelname)s:%(name)s:%(message)s"
logging.basicConfig(
level=loglevel, stream=sys.stdout, format=logformat, datefmt="%Y-%m-%d %H:%M:%S"
level=loglevel,
stream=sys.stdout,
format=logformat,
datefmt="%Y-%m-%d %H:%M:%S",
)


Expand Down
Loading

0 comments on commit 549de50

Please sign in to comment.