mirror of
				https://github.com/python-kasa/python-kasa.git
				synced 2025-11-03 22:22:06 +00:00 
			
		
		
		
	Use stacklevel=2 for warnings to report on callsites (#1219)
Use stacklevel=2 for warnings, as this will correctly show the callsite
instead of the line where the warning is reported.
Currently:
```
kasa/__init__.py:110
  /home/tpr/code/python-kasa/kasa/__init__.py:110: DeprecationWarning: SmartDevice is deprecated, use IotDevice from package kasa.iot instead or use Discover.discover_single() and Device.connect() to support new protocols
    warn(
```
After:
```
kasa/tests/smart/modules/test_contact.py:3
  /home/tpr/code/python-kasa/kasa/tests/smart/modules/test_contact.py:3: DeprecationWarning: SmartDevice is deprecated, use IotDevice from package kasa.iot instead or use Discover.discover_single() and Device.connect() to support new protocols
    from kasa import Module, SmartDevice
``` 
Currently:
```
kasa/tests/test_lightstrip.py: 56 warnings
  /home/tpr/code/python-kasa/kasa/device.py:559: DeprecationWarning: effect is deprecated, use: Module.LightEffect in device.modules instead
    warn(msg, DeprecationWarning, stacklevel=1)
```
After:
```
kasa/tests/test_lightstrip.py::test_effects_lightstrip_set_effect_transition[500-KL430(US)_2.0_1.0.9.json]
  /home/tpr/code/python-kasa/kasa/tests/test_lightstrip.py:62: DeprecationWarning: set_effect is deprecated, use: Module.LightEffect in device.modules instead
    await dev.set_effect("Candy Cane")
```
			
			
This commit is contained in:
		@@ -102,7 +102,7 @@ deprecated_classes = {
 | 
			
		||||
 | 
			
		||||
def __getattr__(name):
 | 
			
		||||
    if name in deprecated_names:
 | 
			
		||||
        warn(f"{name} is deprecated", DeprecationWarning, stacklevel=1)
 | 
			
		||||
        warn(f"{name} is deprecated", DeprecationWarning, stacklevel=2)
 | 
			
		||||
        return globals()[f"_deprecated_{name}"]
 | 
			
		||||
    if name in deprecated_smart_devices:
 | 
			
		||||
        new_class = deprecated_smart_devices[name]
 | 
			
		||||
@@ -112,13 +112,13 @@ def __getattr__(name):
 | 
			
		||||
            + f"from package {package_name} instead or use Discover.discover_single()"
 | 
			
		||||
            + " and Device.connect() to support new protocols",
 | 
			
		||||
            DeprecationWarning,
 | 
			
		||||
            stacklevel=1,
 | 
			
		||||
            stacklevel=2,
 | 
			
		||||
        )
 | 
			
		||||
        return new_class
 | 
			
		||||
    if name in deprecated_classes:
 | 
			
		||||
        new_class = deprecated_classes[name]
 | 
			
		||||
        msg = f"{name} is deprecated, use {new_class.__name__} instead"
 | 
			
		||||
        warn(msg, DeprecationWarning, stacklevel=1)
 | 
			
		||||
        warn(msg, DeprecationWarning, stacklevel=2)
 | 
			
		||||
        return new_class
 | 
			
		||||
    raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -545,7 +545,7 @@ class Device(ABC):
 | 
			
		||||
            msg = f"{name} is deprecated"
 | 
			
		||||
            if module:
 | 
			
		||||
                msg += f", use: {module} in device.modules instead"
 | 
			
		||||
            warn(msg, DeprecationWarning, stacklevel=1)
 | 
			
		||||
            warn(msg, DeprecationWarning, stacklevel=2)
 | 
			
		||||
            return self.device_type == dep_device_type_attr[1]
 | 
			
		||||
        # Other deprecated attributes
 | 
			
		||||
        if (dep_attr := self._deprecated_other_attributes.get(name)) and (
 | 
			
		||||
@@ -556,6 +556,6 @@ class Device(ABC):
 | 
			
		||||
            dev_or_mod = self.modules[mod] if mod else self
 | 
			
		||||
            replacing = f"Module.{mod} in device.modules" if mod else replacing_attr
 | 
			
		||||
            msg = f"{name} is deprecated, use: {replacing} instead"
 | 
			
		||||
            warn(msg, DeprecationWarning, stacklevel=1)
 | 
			
		||||
            warn(msg, DeprecationWarning, stacklevel=2)
 | 
			
		||||
            return getattr(dev_or_mod, replacing_attr)
 | 
			
		||||
        raise AttributeError(f"Device has no attribute {name!r}")
 | 
			
		||||
 
 | 
			
		||||
@@ -182,6 +182,6 @@ class Energy(Module, ABC):
 | 
			
		||||
    def __getattr__(self, name):
 | 
			
		||||
        if attr := self._deprecated_attributes.get(name):
 | 
			
		||||
            msg = f"{name} is deprecated, use {attr} instead"
 | 
			
		||||
            warn(msg, DeprecationWarning, stacklevel=1)
 | 
			
		||||
            warn(msg, DeprecationWarning, stacklevel=2)
 | 
			
		||||
            return getattr(self, attr)
 | 
			
		||||
        raise AttributeError(f"Energy module has no attribute {name!r}")
 | 
			
		||||
 
 | 
			
		||||
@@ -472,7 +472,7 @@ class IotDevice(Device):
 | 
			
		||||
    async def get_time(self) -> datetime:
 | 
			
		||||
        """Return current time from the device, if available."""
 | 
			
		||||
        msg = "Use `time` property instead, this call will be removed in the future."
 | 
			
		||||
        warn(msg, DeprecationWarning, stacklevel=1)
 | 
			
		||||
        warn(msg, DeprecationWarning, stacklevel=2)
 | 
			
		||||
        return self.time
 | 
			
		||||
 | 
			
		||||
    async def get_timezone(self) -> tzinfo:
 | 
			
		||||
@@ -480,7 +480,7 @@ class IotDevice(Device):
 | 
			
		||||
        msg = (
 | 
			
		||||
            "Use `timezone` property instead, this call will be removed in the future."
 | 
			
		||||
        )
 | 
			
		||||
        warn(msg, DeprecationWarning, stacklevel=1)
 | 
			
		||||
        warn(msg, DeprecationWarning, stacklevel=2)
 | 
			
		||||
        return self.timezone
 | 
			
		||||
 | 
			
		||||
    @property  # type: ignore
 | 
			
		||||
 
 | 
			
		||||
@@ -202,12 +202,12 @@ class FakeSmartTransport(BaseTransport):
 | 
			
		||||
                else:
 | 
			
		||||
                    warn(
 | 
			
		||||
                        f"Could not find child SMART fixture for {child_info}",
 | 
			
		||||
                        stacklevel=1,
 | 
			
		||||
                        stacklevel=2,
 | 
			
		||||
                    )
 | 
			
		||||
            else:
 | 
			
		||||
                warn(
 | 
			
		||||
                    f"Child is a cameraprotocol which needs to be implemented {child_info}",
 | 
			
		||||
                    stacklevel=1,
 | 
			
		||||
                    stacklevel=2,
 | 
			
		||||
                )
 | 
			
		||||
        # Replace parent child infos with the infos from the child fixtures so
 | 
			
		||||
        # that updates update both
 | 
			
		||||
@@ -223,7 +223,7 @@ class FakeSmartTransport(BaseTransport):
 | 
			
		||||
        if device_id not in self.child_protocols:
 | 
			
		||||
            warn(
 | 
			
		||||
                f"Could not find child fixture {device_id} in {self.fixture_name}",
 | 
			
		||||
                stacklevel=1,
 | 
			
		||||
                stacklevel=2,
 | 
			
		||||
            )
 | 
			
		||||
            return self._handle_control_child_missing(params)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user