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
48 changes: 4 additions & 44 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # v6.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
Expand All @@ -12,54 +12,14 @@ repos:
- id: check-ast

- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.7.1
rev: c59bba8fb259db0fec2bbb77ad8ba51ea7341b56 # v0.15.20
hooks:
# Run the linter.
- id: ruff
args: [--fix]
# Run the formatter.
args: [--fix, --exit-non-zero-on-fix]
- id: ruff-format

- repo: https://github.com/pre-commit/mirrors-isort
rev: v5.10.1
hooks:
- id: isort
additional_dependencies: [toml]

#- repo: https://github.com/PyCQA/doc8
# rev: v1.1.1
# hooks:
# - id: doc8
# additional_dependencies: [myst-parser]

# - repo: https://github.com/myint/docformatter
# rev: v1.7.5
# hooks:
# - id: docformatter
# args: [--in-place, --wrap-summaries, '88', --wrap-descriptions, '88', --black

- repo: https://github.com/pycqa/flake8
rev: 7.0.0
hooks:
- id: flake8
additional_dependencies: [flake8-docstrings, flake8-bugbear, flake8-builtins, flake8-print, flake8-pytest-style, flake8-return, flake8-simplify, flake8-annotations]

- repo: https://github.com/PyCQA/bandit
rev: 1.7.7
hooks:
- id: bandit
args: [-x, 'tests', -x, '**/test_*.py']


- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.8.0
rev: d2823d321df3af8f878f7ee3414dc94d037145b9 # v2.1.0
hooks:
- id: mypy
additional_dependencies: [types-attrs, types-PyYAML, types-requests, types-pytz, types-croniter, types-freezegun]

- repo: https://github.com/asottile/pyupgrade
rev: v3.15.0
hooks:
- id: pyupgrade
args: ['--py311-plus']
2 changes: 1 addition & 1 deletion docs/examples/push_server/gateway_alarm_trigger.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
logging.basicConfig(level="INFO")

gateway_ip = "192.168.1.IP"
token = "TokenTokenToken" # nosec
token = "TokenTokenToken" # noqa: S105


async def asyncio_demo(loop):
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/push_server/gateway_button_press.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
logging.basicConfig(level="INFO")

gateway_ip = "192.168.1.IP"
token = "TokenTokenToken" # nosec
token = "TokenTokenToken" # noqa: S105
button_sid = "lumi.123456789abcdef"


Expand Down
2 changes: 1 addition & 1 deletion miio/click_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def validate_ip(ctx, param, value):
ipaddress.ip_address(value)
return value
except ValueError as ex:
raise click.BadParameter(f"Invalid IP: {ex}")
raise click.BadParameter(f"Invalid IP: {ex}") from ex


def validate_token(ctx, param, value):
Expand Down
8 changes: 4 additions & 4 deletions miio/cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,10 @@ def _login(self):
try:
from micloud import MiCloud # noqa: F811
from micloud.micloudexception import MiCloudAccessDenied
except ImportError:
except ImportError as ex:
raise CloudException(
"You need to install 'micloud' package to use cloud interface"
)
) from ex

self._micloud: MiCloud = MiCloud(username=self.username, password=self.password)
try: # login() can either return False or raise an exception on failure
Expand Down Expand Up @@ -165,9 +165,9 @@ def cloud(ctx: click.Context, username, password):
"""Cloud commands."""
try:
import micloud # noqa: F401
except ImportError:
except ImportError as ex:
_LOGGER.error("micloud is not installed, no cloud access available")
raise CloudException("install micloud for cloud access")
raise CloudException("install micloud for cloud access") from ex

ctx.obj = CloudInterface(username=username, password=password)
if ctx.invoked_subcommand is None:
Expand Down
4 changes: 2 additions & 2 deletions miio/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ def call_action(self, name: str, params=None):
try:
act = self.actions()[name]
except KeyError:
raise ValueError(f"Unable to find action '{name}'")
raise ValueError(f"Unable to find action '{name}'") from None

if params is None:
return act.method()
Expand All @@ -346,7 +346,7 @@ def change_setting(self, name: str, params=None):
try:
setting = self.settings()[name]
except KeyError:
raise ValueError(f"Unable to find setting '{name}'")
raise ValueError(f"Unable to find setting '{name}'") from None

params = params if params is not None else []

Expand Down
2 changes: 1 addition & 1 deletion miio/devtools/pcapparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def read_payloads_from_file(file, tokens: list[str]):
try:
decrypted = Message.parse(data, token=bytes.fromhex(token))
break
except BaseException: # noqa: B036
except BaseException: # noqa: B036, S112
continue

if decrypted is None:
Expand Down
2 changes: 1 addition & 1 deletion miio/devtools/simulators/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def did_and_mac_for_model(model):

These identifiers allow making a simulated device unique for testing.
"""
m = md5() # nosec
m = md5() # noqa: S324
m.update(model.encode())
digest = m.hexdigest()[:12]
did = int(digest[:8], base=16)
Expand Down
10 changes: 5 additions & 5 deletions miio/devtools/simulators/miotsimulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,18 @@ def create_random(values):

if values["choices"] is not None:
choices = values["choices"]
choice = choices[random.randint(0, len(choices) - 1)] # nosec
choice = choices[random.randint(0, len(choices) - 1)] # noqa: S311
_LOGGER.debug("Got enum %r for %s", choice, piid)
return choice.value

if values["range"] is not None:
range = values["range"]
value = random.randint(range[0], range[1]) # nosec
value = random.randint(range[0], range[1]) # noqa: S311
_LOGGER.debug("Got value %r from %s for piid %s", value, range, piid)
return value

if values["format"] == bool:
value = bool(random.randint(0, 1)) # nosec
value = bool(random.randint(0, 1)) # noqa: S311
_LOGGER.debug("Got bool %r for piid %s", value, piid)
return value

Expand Down Expand Up @@ -277,13 +277,13 @@ def miot_simulator(file, model):
dev = SimulatedDeviceModel.parse_obj(schema)
except Exception as ex:
# this is far from optimal, but considering this is a developer tool it can be fixed later
fn = f"/tmp/pythonmiio_unparseable_{model}.json" # nosec
fn = f"/tmp/pythonmiio_unparseable_{model}.json" # noqa: S108
with open(fn, "w") as f:
json.dump(schema, f, indent=4)
_LOGGER.error("Unable to parse the schema, see %s: %s", fn, ex)
return

loop = asyncio.get_event_loop()
random.seed(1) # nosec
random.seed(1) # noqa: S311
loop.run_until_complete(main(dev, model=model))
loop.run_forever()
4 changes: 2 additions & 2 deletions miio/extract_tokens.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def read_android_yeelight(db) -> Iterator[DeviceConfig]:
devicelist = xml.find(".//set[@name='deviceList']")
if not devicelist:
_LOGGER.warning("Unable to find deviceList")
return []
return

for dev_elem in list(devicelist):
dev = json.loads(dev_elem.text)
Expand Down Expand Up @@ -82,7 +82,7 @@ def decrypt_ztoken(ztoken):
key = bytes.fromhex(keystring)
cipher = Cipher(
algorithms.AES(key),
modes.ECB(), # nosec
modes.ECB(), # noqa: S305
backend=default_backend(),
)
decryptor = cipher.decryptor()
Expand Down
4 changes: 3 additions & 1 deletion miio/integrations/airdog/airpurifier/airpurifier_airdog.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ def status(self) -> AirDogStatus:
)
values = self.get_properties(properties, max_properties=10)

return AirDogStatus(defaultdict(lambda: None, zip(properties, values)))
return AirDogStatus(
defaultdict(lambda: None, zip(properties, values, strict=False))
)

@command(default_output=format_output("Powering on"))
def on(self):
Expand Down
2 changes: 1 addition & 1 deletion miio/integrations/cgllc/airmonitor/airqualitymonitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ def status(self) -> AirQualityMonitorStatus:
return AirQualityMonitorStatus(defaultdict(lambda: None, values))
else:
return AirQualityMonitorStatus(
defaultdict(lambda: None, zip(properties, values))
defaultdict(lambda: None, zip(properties, values, strict=False))
)

@command(default_output=format_output("Powering on"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)


@pytest.fixture(scope="function")
@pytest.fixture
def airqualitymonitorcgdn1(request):
request.cls.device = DummyAirQualityMonitorCGDN1()

Expand Down
2 changes: 1 addition & 1 deletion miio/integrations/chuangmi/camera/chuangmi_camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ def status(self) -> CameraStatus:

values = self.get_properties(properties)

return CameraStatus(dict(zip(properties, values)))
return CameraStatus(dict(zip(properties, values, strict=False)))

@command(default_output=format_output("Power on"))
def on(self):
Expand Down
4 changes: 3 additions & 1 deletion miio/integrations/chuangmi/plug/chuangmi_plug.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ def status(self) -> ChuangmiPlugStatus:
properties.append("load_power")
values.append(load_power[0] * 0.01)

return ChuangmiPlugStatus(defaultdict(lambda: None, zip(properties, values)))
return ChuangmiPlugStatus(
defaultdict(lambda: None, zip(properties, values, strict=False))
)

@command(default_output=format_output("Powering on"))
def on(self):
Expand Down
4 changes: 3 additions & 1 deletion miio/integrations/chuangmi/remote/chuangmi_ir.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,9 @@ def play(self, command: str):
play_method = self.play_pronto

try:
converted_command_args = [t(v) for v, t in zip(command_args, arg_types)]
converted_command_args = [
t(v) for v, t in zip(command_args, arg_types, strict=False)
]
except Exception as ex:
raise ValueError("Invalid command arguments") from ex

Expand Down
8 changes: 4 additions & 4 deletions miio/integrations/chuangmi/remote/test_chuangmi_ir.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def test_play_raw(self):
for args in test_data["test_raw_ok"]:
with self.subTest():
self.device._reset_state()
self.assertTrue(self.device.play_raw(*args["in"]))
assert self.device.play_raw(*args["in"])
self.assertSequenceEqual(
self.device.state["last_ir_played"], args["out"]
)
Expand All @@ -84,7 +84,7 @@ def test_play_pronto(self):
for args in test_data["test_pronto_ok"]:
with self.subTest():
self.device._reset_state()
self.assertTrue(self.device.play_pronto(*args["in"]))
assert self.device.play_pronto(*args["in"])
self.assertSequenceEqual(
self.device.state["last_ir_played"], args["out"]
)
Expand All @@ -99,7 +99,7 @@ def test_play_auto(self):
continue
with self.subTest():
self.device._reset_state()
self.assertTrue(self.device.play(*args["in"]))
assert self.device.play(*args["in"])
self.assertSequenceEqual(
self.device.state["last_ir_played"], args["out"]
)
Expand All @@ -112,7 +112,7 @@ def test_play_with_type(self):
for args in tests:
with self.subTest():
command = "{}:{}".format(type_, ":".join(map(str, args["in"])))
self.assertTrue(self.device.play(command))
assert self.device.play(command)
self.assertSequenceEqual(
self.device.state["last_ir_played"], args["out"]
)
Expand Down
4 changes: 3 additions & 1 deletion miio/integrations/chunmi/cooker/cooker.py
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,9 @@ def status(self) -> CookerStatus:
values_count,
)

return CookerStatus(defaultdict(lambda: None, zip(properties, values)))
return CookerStatus(
defaultdict(lambda: None, zip(properties, values, strict=False))
)

@command(
click.argument("profile", type=str),
Expand Down
4 changes: 3 additions & 1 deletion miio/integrations/chunmi/cooker_multi/cooker_multi.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,9 @@ def status(self) -> CookerStatus:
values_count,
)

return CookerStatus(defaultdict(lambda: None, zip(properties, values)))
return CookerStatus(
defaultdict(lambda: None, zip(properties, values, strict=False))
)

@command(
click.argument("profile", type=str, required=True),
Expand Down
4 changes: 3 additions & 1 deletion miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,9 @@ def status(self) -> AirHumidifierStatus:
)
values = self.get_properties(properties, max_properties=1)

return AirHumidifierStatus(defaultdict(lambda: None, zip(properties, values)))
return AirHumidifierStatus(
defaultdict(lambda: None, zip(properties, values, strict=False))
)

@command(default_output=format_output("Powering on"))
def on(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)


@pytest.fixture()
@pytest.fixture
def dev(request):
yield DummyAirHumidifierJsqs()
return DummyAirHumidifierJsqs()


def test_on(dev):
Expand Down
4 changes: 3 additions & 1 deletion miio/integrations/dmaker/airfresh/airfresh_t2017.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,9 @@ def status(self) -> AirFreshStatus:
)
values = self.get_properties(properties, max_properties=15)

return AirFreshStatus(defaultdict(lambda: None, zip(properties, values)))
return AirFreshStatus(
defaultdict(lambda: None, zip(properties, values, strict=False))
)

@command(default_output=format_output("Powering on"))
def on(self):
Expand Down
2 changes: 1 addition & 1 deletion miio/integrations/dmaker/fan/fan.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def status(self) -> FanStatusP5:
properties = AVAILABLE_PROPERTIES[self.model]
values = self.get_properties(properties, max_properties=15)

return FanStatusP5(dict(zip(properties, values)))
return FanStatusP5(dict(zip(properties, values, strict=False)))

@command(default_output=format_output("Powering on"))
def on(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,12 @@ def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)


@pytest.fixture(scope="function")
@pytest.fixture
def dummydreame1cvacuum(request):
request.cls.device = DummyDreame1CVacuumMiot()


@pytest.fixture(scope="function")
@pytest.fixture
def dummydreamef9vacuum(request):
request.cls.device = DummyDreameF9VacuumMiot()

Expand Down
Loading
Loading