Repository: rytilahti/python-miio (language: python)

Issue:
Consider adding `__getattr__` to `miio` to inform about the breaking changes.



Discussion / hints:

Fix patch:
diff --git a/miio/__init__.py b/miio/__init__.py
index 894ba3b3c..2e36067d0 100644
--- a/miio/__init__.py
+++ b/miio/__init__.py
@@ -85,4 +85,32 @@
 
 from miio.discovery import Discovery
 
+
+def __getattr__(name):
+    """Create deprecation warnings on classes that are going away."""
+    from warnings import warn
+
+    current_globals = globals()
+
+    def _is_miio_integration(x):
+        """Return True if miio.integrations is in the module 'path'."""
+        module_ = current_globals[x]
+        if "miio.integrations" in str(module_):
+            return True
+
+        return False
+
+    deprecated_module_mapping = {
+        str(x): current_globals[x] for x in current_globals if _is_miio_integration(x)
+    }
+    if new_module := deprecated_module_mapping.get(name):
+        warn(
+            f"Importing {name} directly from 'miio' is deprecated, import {new_module} or use DeviceFactory.create() instead",
+            DeprecationWarning,
+        )
+        return globals()[new_module.__name__]
+
+    raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
+
+
 __version__ = version("python-miio")


Test patch:
diff --git a/miio/tests/test_miio.py b/miio/tests/test_miio.py
new file mode 100644
index 000000000..37c9b2247
--- /dev/null
+++ b/miio/tests/test_miio.py
@@ -0,0 +1,16 @@
+"""Tests for the main module."""
+import pytest
+
+import miio
+
+
+@pytest.mark.parametrize(
+    ("old_name", "new_name"),
+    [("RoborockVacuum", "miio.integrations.roborock.vacuum.vacuum.RoborockVacuum")],
+)
+def test_deprecation_warning(old_name, new_name):
+    """Check that deprecation warning gets emitted for deprecated imports."""
+    with pytest.deprecated_call(
+        match=rf"Importing {old_name} directly from 'miio' is deprecated, import <class '{new_name}'> or use DeviceFactory.create\(\) instead"
+    ):
+        miio.__getattr__(old_name)