GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Refactor exception classes · python-kasa/python-kasa@277ac5d

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
  • devtools
    • dump_devinfo.py
  • kasa
    • __init__.py
    • aestransport.py
    • cli.py
    • device.py
    • device_factory.py
    • deviceconfig.py
    • discover.py
    • exceptions.py
    • httpclient.py
    • iotprotocol.py
    • iot
      • iotbulb.py
      • iotdevice.py
      • iotdimmer.py
      • iotlightstrip.py
      • iotmodule.py
      • iotplug.py
      • iotstrip.py
      • modules
        • motion.py
        • time.py
    • klaptransport.py
    • module.py
    • smartprotocol.py
    • smart
      • smartbulb.py
      • smartdevice.py
      • smartmodule.py
    • tests
      • fakeprotocol_smart.py
      • test_aestransport.py
      • test_bulb.py
      • test_cli.py
      • test_device_factory.py
      • test_deviceconfig.py
      • test_discovery.py
      • test_emeter.py
      • test_httpclient.py
      • test_klapprotocol.py
      • test_lightstrip.py
      • test_protocol.py
      • test_smartdevice.py
      • test_smartprotocol.py
      • test_strip.py
    • xortransport.py

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Dismiss banner
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎devtools/dump_devinfo.py‎

Copy file name to clipboardExpand all lines: devtools/dump_devinfo.py
+7-10Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@
2222

2323
from devtools.helpers.smartrequests import SmartRequest, get_component_requests
2424
from kasa import (
25-
AuthenticationException,
25+
AuthenticationError,
2626
Credentials,
2727
Device,
2828
Discover,
29-
SmartDeviceException,
30-
TimeoutException,
29+
KasaException,
30+
TimeoutError,
3131
)
3232
from kasa.discover import DiscoveryResult
3333
from kasa.exceptions import SmartErrorCode
@@ -303,19 +303,16 @@ async def _make_requests_or_exit(
303303
for method, result in responses.items():
304304
final[method] = result
305305
return final
306-
except AuthenticationException as ex:
306+
except AuthenticationError as ex:
307307
_echo_error(
308308
f"Unable to query the device due to an authentication error: {ex}",
309309
)
310310
exit(1)
311-
except SmartDeviceException as ex:
311+
except KasaException as ex:
312312
_echo_error(
313313
f"Unable to query {name} at once: {ex}",
314314
)
315-
if (
316-
isinstance(ex, TimeoutException)
317-
or ex.error_code == SmartErrorCode.SESSION_TIMEOUT_ERROR
318-
):
315+
if isinstance(ex, TimeoutError):
319316
_echo_error(
320317
"Timeout, try reducing the batch size via --batch-size option.",
321318
)
@@ -400,7 +397,7 @@ async def get_smart_fixture(device: SmartDevice, batch_size: int):
400397
response = await device.protocol.query(
401398
SmartRequest._create_request_dict(test_call.request)
402399
)
403-
except AuthenticationException as ex:
400+
except AuthenticationError as ex:
404401
_echo_error(
405402
f"Unable to query the device due to an authentication error: {ex}",
406403
)
Collapse file

‎kasa/__init__.py‎

Copy file name to clipboardExpand all lines: kasa/__init__.py
+27-9Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
For device type specific actions `SmartBulb`, `SmartPlug`, or `SmartStrip`
99
should be used instead.
1010
11-
Module-specific errors are raised as `SmartDeviceException` and are expected
11+
Module-specific errors are raised as `KasaException` and are expected
1212
to be handled by the user of the library.
1313
"""
1414
from importlib.metadata import version
@@ -28,10 +28,11 @@
2828
from kasa.discover import Discover
2929
from kasa.emeterstatus import EmeterStatus
3030
from kasa.exceptions import (
31-
AuthenticationException,
32-
SmartDeviceException,
33-
TimeoutException,
34-
UnsupportedDeviceException,
31+
AuthenticationError,
32+
DeviceError,
33+
KasaException,
34+
TimeoutError,
35+
UnsupportedDeviceError,
3536
)
3637
from kasa.feature import Feature, FeatureType
3738
from kasa.iot.iotbulb import BulbPreset, TurnOnBehavior, TurnOnBehaviors
@@ -61,10 +62,11 @@
6162
"Device",
6263
"Bulb",
6364
"Plug",
64-
"SmartDeviceException",
65-
"AuthenticationException",
66-
"UnsupportedDeviceException",
67-
"TimeoutException",
65+
"KasaException",
66+
"AuthenticationError",
67+
"DeviceError",
68+
"UnsupportedDeviceError",
69+
"TimeoutError",
6870
"Credentials",
6971
"DeviceConfig",
7072
"ConnectionType",
@@ -84,6 +86,12 @@
8486
"SmartDimmer": iot.IotDimmer,
8587
"SmartBulbPreset": BulbPreset,
8688
}
89+
deprecated_exceptions = {
90+
"SmartDeviceException": KasaException,
91+
"UnsupportedDeviceException": UnsupportedDeviceError,
92+
"AuthenticationException": AuthenticationError,
93+
"TimeoutException": TimeoutError,
94+
}
8795

8896

8997
def __getattr__(name):
@@ -101,6 +109,11 @@ def __getattr__(name):
101109
stacklevel=1,
102110
)
103111
return new_class
112+
if name in deprecated_exceptions:
113+
new_class = deprecated_exceptions[name]
114+
msg = f"{name} is deprecated, use {new_class.__name__} instead"
115+
warn(msg, DeprecationWarning, stacklevel=1)
116+
return new_class
104117
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
105118

106119

@@ -112,6 +125,11 @@ def __getattr__(name):
112125
SmartStrip = iot.IotStrip
113126
SmartDimmer = iot.IotDimmer
114127
SmartBulbPreset = BulbPreset
128+
129+
SmartDeviceException = KasaException
130+
UnsupportedDeviceException = UnsupportedDeviceError
131+
AuthenticationException = AuthenticationError
132+
TimeoutException = TimeoutError
115133
# Instanstiate all classes so the type checkers catch abstract issues
116134
from . import smart
117135

Collapse file

‎kasa/aestransport.py‎

Copy file name to clipboardExpand all lines: kasa/aestransport.py
+14-17Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,11 @@
2222
from .exceptions import (
2323
SMART_AUTHENTICATION_ERRORS,
2424
SMART_RETRYABLE_ERRORS,
25-
SMART_TIMEOUT_ERRORS,
26-
AuthenticationException,
27-
RetryableException,
28-
SmartDeviceException,
25+
AuthenticationError,
26+
DeviceError,
27+
KasaException,
2928
SmartErrorCode,
30-
TimeoutException,
29+
_RetryableError,
3130
)
3231
from .httpclient import HttpClient
3332
from .json import dumps as json_dumps
@@ -141,14 +140,12 @@ def _handle_response_error_code(self, resp_dict: Any, msg: str) -> None:
141140
if error_code == SmartErrorCode.SUCCESS:
142141
return
143142
msg = f"{msg}: {self._host}: {error_code.name}({error_code.value})"
144-
if error_code in SMART_TIMEOUT_ERRORS:
145-
raise TimeoutException(msg, error_code=error_code)
146143
if error_code in SMART_RETRYABLE_ERRORS:
147-
raise RetryableException(msg, error_code=error_code)
144+
raise _RetryableError(msg, error_code=error_code)
148145
if error_code in SMART_AUTHENTICATION_ERRORS:
149146
self._state = TransportState.HANDSHAKE_REQUIRED
150-
raise AuthenticationException(msg, error_code=error_code)
151-
raise SmartDeviceException(msg, error_code=error_code)
147+
raise AuthenticationError(msg, error_code=error_code)
148+
raise DeviceError(msg, error_code=error_code)
152149

153150
async def send_secure_passthrough(self, request: str) -> Dict[str, Any]:
154151
"""Send encrypted message as passthrough."""
@@ -171,7 +168,7 @@ async def send_secure_passthrough(self, request: str) -> Dict[str, Any]:
171168
# _LOGGER.debug(f"secure_passthrough response is {status_code}: {resp_dict}")
172169

173170
if status_code != 200:
174-
raise SmartDeviceException(
171+
raise KasaException(
175172
f"{self._host} responded with an unexpected "
176173
+ f"status code {status_code} to passthrough"
177174
)
@@ -197,7 +194,7 @@ async def send_secure_passthrough(self, request: str) -> Dict[str, Any]:
197194
self._host,
198195
)
199196
except Exception:
200-
raise SmartDeviceException(
197+
raise KasaException(
201198
f"Unable to decrypt response from {self._host}, "
202199
+ f"error: {ex}, response: {raw_response}",
203200
ex,
@@ -208,7 +205,7 @@ async def perform_login(self):
208205
"""Login to the device."""
209206
try:
210207
await self.try_login(self._login_params)
211-
except AuthenticationException as aex:
208+
except AuthenticationError as aex:
212209
try:
213210
if aex.error_code is not SmartErrorCode.LOGIN_ERROR:
214211
raise aex
@@ -223,10 +220,10 @@ async def perform_login(self):
223220
"%s: logged in with default credentials",
224221
self._host,
225222
)
226-
except AuthenticationException:
223+
except AuthenticationError:
227224
raise
228225
except Exception as ex:
229-
raise SmartDeviceException(
226+
raise KasaException(
230227
"Unable to login and trying default "
231228
+ f"login raised another exception: {ex}",
232229
ex,
@@ -292,7 +289,7 @@ async def perform_handshake(self) -> None:
292289
_LOGGER.debug("Device responded with: %s", resp_dict)
293290

294291
if status_code != 200:
295-
raise SmartDeviceException(
292+
raise KasaException(
296293
f"{self._host} responded with an unexpected "
297294
+ f"status code {status_code} to handshake"
298295
)
@@ -347,7 +344,7 @@ async def send(self, request: str) -> Dict[str, Any]:
347344
await self.perform_login()
348345
# After a login failure handshake needs to
349346
# be redone or a 9999 error is received.
350-
except AuthenticationException as ex:
347+
except AuthenticationError as ex:
351348
self._state = TransportState.HANDSHAKE_REQUIRED
352349
raise ex
353350

Collapse file

‎kasa/cli.py‎

Copy file name to clipboardExpand all lines: kasa/cli.py
+6-6Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import asyncclick as click
1414

1515
from kasa import (
16-
AuthenticationException,
16+
AuthenticationError,
1717
Bulb,
1818
ConnectionType,
1919
Credentials,
@@ -22,8 +22,8 @@
2222
DeviceFamilyType,
2323
Discover,
2424
EncryptType,
25-
SmartDeviceException,
26-
UnsupportedDeviceException,
25+
KasaException,
26+
UnsupportedDeviceError,
2727
)
2828
from kasa.discover import DiscoveryResult
2929
from kasa.iot import IotBulb, IotDevice, IotDimmer, IotLightStrip, IotPlug, IotStrip
@@ -458,7 +458,7 @@ async def discover(ctx):
458458
unsupported = []
459459
auth_failed = []
460460

461-
async def print_unsupported(unsupported_exception: UnsupportedDeviceException):
461+
async def print_unsupported(unsupported_exception: UnsupportedDeviceError):
462462
unsupported.append(unsupported_exception)
463463
async with sem:
464464
if unsupported_exception.discovery_result:
@@ -476,7 +476,7 @@ async def print_discovered(dev: Device):
476476
async with sem:
477477
try:
478478
await dev.update()
479-
except AuthenticationException:
479+
except AuthenticationError:
480480
auth_failed.append(dev._discovery_info)
481481
echo("== Authentication failed for device ==")
482482
_echo_discovery_info(dev._discovery_info)
@@ -677,7 +677,7 @@ async def cmd_command(dev: Device, module, command, parameters):
677677
elif isinstance(dev, SmartDevice):
678678
res = await dev._query_helper(command, parameters)
679679
else:
680-
raise SmartDeviceException("Unexpected device type %s.", dev)
680+
raise KasaException("Unexpected device type %s.", dev)
681681
echo(json.dumps(res))
682682
return res
683683

Collapse file

‎kasa/device.py‎

Copy file name to clipboardExpand all lines: kasa/device.py
+4-4Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from .device_type import DeviceType
1010
from .deviceconfig import DeviceConfig
1111
from .emeterstatus import EmeterStatus
12-
from .exceptions import SmartDeviceException
12+
from .exceptions import KasaException
1313
from .feature import Feature
1414
from .iotprotocol import IotProtocol
1515
from .protocol import BaseProtocol
@@ -242,12 +242,12 @@ def get_plug_by_name(self, name: str) -> "Device":
242242
if p.alias == name:
243243
return p
244244

245-
raise SmartDeviceException(f"Device has no child with {name}")
245+
raise KasaException(f"Device has no child with {name}")
246246

247247
def get_plug_by_index(self, index: int) -> "Device":
248248
"""Return child device for the given index."""
249249
if index + 1 > len(self.children) or index < 0:
250-
raise SmartDeviceException(
250+
raise KasaException(
251251
f"Invalid index {index}, device has {len(self.children)} plugs"
252252
)
253253
return self.children[index]
@@ -306,7 +306,7 @@ def _add_feature(self, feature: Feature):
306306
"""Add a new feature to the device."""
307307
desc_name = feature.name.lower().replace(" ", "_")
308308
if desc_name in self._features:
309-
raise SmartDeviceException("Duplicate feature name %s" % desc_name)
309+
raise KasaException("Duplicate feature name %s" % desc_name)
310310
self._features[desc_name] = feature
311311

312312
@property
Collapse file

‎kasa/device_factory.py‎

Copy file name to clipboardExpand all lines: kasa/device_factory.py
+7-7Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from .aestransport import AesTransport
77
from .device import Device
88
from .deviceconfig import DeviceConfig
9-
from .exceptions import SmartDeviceException, UnsupportedDeviceException
9+
from .exceptions import KasaException, UnsupportedDeviceError
1010
from .iot import IotBulb, IotDevice, IotDimmer, IotLightStrip, IotPlug, IotStrip
1111
from .iotprotocol import IotProtocol
1212
from .klaptransport import KlapTransport, KlapTransportV2
@@ -45,12 +45,12 @@ async def connect(*, host: Optional[str] = None, config: DeviceConfig) -> "Devic
4545
:return: Object for querying/controlling found device.
4646
"""
4747
if host and config or (not host and not config):
48-
raise SmartDeviceException("One of host or config must be provded and not both")
48+
raise KasaException("One of host or config must be provded and not both")
4949
if host:
5050
config = DeviceConfig(host=host)
5151

5252
if (protocol := get_protocol(config=config)) is None:
53-
raise UnsupportedDeviceException(
53+
raise UnsupportedDeviceError(
5454
f"Unsupported device for {config.host}: "
5555
+ f"{config.connection_type.device_family.value}"
5656
)
@@ -99,7 +99,7 @@ def _perf_log(has_params, perf_type):
9999
_perf_log(True, "update")
100100
return device
101101
else:
102-
raise UnsupportedDeviceException(
102+
raise UnsupportedDeviceError(
103103
f"Unsupported device for {config.host}: "
104104
+ f"{config.connection_type.device_family.value}"
105105
)
@@ -108,12 +108,12 @@ def _perf_log(has_params, perf_type):
108108
def get_device_class_from_sys_info(info: Dict[str, Any]) -> Type[IotDevice]:
109109
"""Find SmartDevice subclass for device described by passed data."""
110110
if "system" not in info or "get_sysinfo" not in info["system"]:
111-
raise SmartDeviceException("No 'system' or 'get_sysinfo' in response")
111+
raise KasaException("No 'system' or 'get_sysinfo' in response")
112112

113113
sysinfo: Dict[str, Any] = info["system"]["get_sysinfo"]
114114
type_: Optional[str] = sysinfo.get("type", sysinfo.get("mic_type"))
115115
if type_ is None:
116-
raise SmartDeviceException("Unable to find the device type field!")
116+
raise KasaException("Unable to find the device type field!")
117117

118118
if "dev_name" in sysinfo and "Dimmer" in sysinfo["dev_name"]:
119119
return IotDimmer
@@ -129,7 +129,7 @@ def get_device_class_from_sys_info(info: Dict[str, Any]) -> Type[IotDevice]:
129129
return IotLightStrip
130130

131131
return IotBulb
132-
raise UnsupportedDeviceException("Unknown device type: %s" % type_)
132+
raise UnsupportedDeviceError("Unknown device type: %s" % type_)
133133

134134

135135
def get_device_class_from_family(device_type: str) -> Optional[Type[Device]]:
Collapse file

‎kasa/deviceconfig.py‎

Copy file name to clipboardExpand all lines: kasa/deviceconfig.py
+5-7Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from typing import TYPE_CHECKING, Dict, Optional, Union
66

77
from .credentials import Credentials
8-
from .exceptions import SmartDeviceException
8+
from .exceptions import KasaException
99

1010
if TYPE_CHECKING:
1111
from aiohttp import ClientSession
@@ -46,7 +46,7 @@ def _dataclass_from_dict(klass, in_val):
4646
fieldtypes[dict_key], in_val[dict_key]
4747
)
4848
else:
49-
raise SmartDeviceException(
49+
raise KasaException(
5050
f"Cannot create dataclass from dict, unknown key: {dict_key}"
5151
)
5252
return klass(**val)
@@ -92,7 +92,7 @@ def from_values(
9292
login_version,
9393
)
9494
except (ValueError, TypeError) as ex:
95-
raise SmartDeviceException(
95+
raise KasaException(
9696
f"Invalid connection parameters for {device_family}."
9797
+ f"{encryption_type}.{login_version}"
9898
) from ex
@@ -113,9 +113,7 @@ def from_dict(connection_type_dict: Dict[str, str]) -> "ConnectionType":
113113
login_version, # type: ignore[arg-type]
114114
)
115115

116-
raise SmartDeviceException(
117-
f"Invalid connection type data for {connection_type_dict}"
118-
)
116+
raise KasaException(f"Invalid connection type data for {connection_type_dict}")
119117

120118
def to_dict(self) -> Dict[str, Union[str, int]]:
121119
"""Convert connection params to dict."""
@@ -185,4 +183,4 @@ def from_dict(config_dict: Dict[str, Dict[str, str]]) -> "DeviceConfig":
185183
"""Return device config from dict."""
186184
if isinstance(config_dict, dict):
187185
return _dataclass_from_dict(DeviceConfig, config_dict)
188-
raise SmartDeviceException(f"Invalid device config data: {config_dict}")
186+
raise KasaException(f"Invalid device config data: {config_dict}")

0 commit comments

Comments
0 (0)
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.