diff --git a/homeassistant/components/number/__init__.py b/homeassistant/components/number/__init__.py index 13ba47e87dc..f0dc77b7dfb 100644 --- a/homeassistant/components/number/__init__.py +++ b/homeassistant/components/number/__init__.py @@ -133,8 +133,11 @@ class NumberEntityDescription(EntityDescription): or self.step is not None or self.unit_of_measurement is not None ): - caller = inspect.stack()[2] - module = inspect.getmodule(caller[0]) + if self.__class__.__name__ == "NumberEntityDescription": + caller = inspect.stack()[2] + module = inspect.getmodule(caller[0]) + else: + module = inspect.getmodule(self) if module and module.__file__ and "custom_components" in module.__file__: report_issue = "report it to the custom component author." else: @@ -187,6 +190,38 @@ class NumberEntity(Entity): _attr_native_unit_of_measurement: str | None _deprecated_number_entity_reported = False + def __init_subclass__(cls, **kwargs: Any) -> None: + """Post initialisation processing.""" + super().__init_subclass__(**kwargs) + if any( + method in cls.__dict__ + for method in ( + "async_set_value", + "max_value", + "min_value", + "set_value", + "step", + "unit_of_measurement", + "value", + ) + ): + module = inspect.getmodule(cls) + if module and module.__file__ and "custom_components" in module.__file__: + report_issue = "report it to the custom component author." + else: + report_issue = ( + "create a bug report at " + "https://github.com/home-assistant/core/issues?q=is%3Aopen+is%3Aissue" + ) + _LOGGER.warning( + "%s::%s is overriding deprecated methods on an instance of " + "NumberEntity, this is not valid and will be unsupported " + "from Home Assistant 2022.10. Please %s", + cls.__module__, + cls.__name__, + report_issue, + ) + @property def capability_attributes(self) -> dict[str, Any]: """Return capability attributes.""" diff --git a/tests/components/number/test_init.py b/tests/components/number/test_init.py index 0df7f79e4a4..9921d2a639e 100644 --- a/tests/components/number/test_init.py +++ b/tests/components/number/test_init.py @@ -229,8 +229,8 @@ async def test_attributes(hass: HomeAssistant) -> None: assert number_4.value is None -async def test_attributes_deprecated(hass: HomeAssistant, caplog) -> None: - """Test overriding the deprecated attributes.""" +async def test_deprecation_warnings(hass: HomeAssistant, caplog) -> None: + """Test overriding the deprecated attributes is possible and warnings are logged.""" number = MockDefaultNumberEntityDeprecated() number.hass = hass assert number.max_value == 100.0 @@ -263,6 +263,10 @@ async def test_attributes_deprecated(hass: HomeAssistant, caplog) -> None: assert number_4.unit_of_measurement == "rabbits" assert number_4.value == 0.5 + assert ( + "tests.components.number.test_init::MockNumberEntityDeprecated is overriding " + " deprecated methods on an instance of NumberEntity" + ) assert ( "Entity None () " "is using deprecated NumberEntity features" in caplog.text