Browse Source

Bump version

- Enable checks for shadowed builtins
- fix issues with shadowed builtins
Jason Rumney 1 month ago
parent
commit
a02a53c8a3

+ 1 - 0
.gitignore

@@ -2,6 +2,7 @@
 /.vs/
 /.vscode/
 /.env/
+/.venv/
 /*.egg-info/
 __pycache__/
 .pytest_cache/

+ 6 - 6
custom_components/tuya_local/climate.py

@@ -213,9 +213,9 @@ class TuyaLocalClimate(TuyaLocalEntity, ClimateEntity):
         """Return the minimum supported target temperature."""
         # if a separate min_temperature dps is specified, the device tells us.
         if self._mintemp_dps is not None:
-            min = self._mintemp_dps.get_value(self._device)
-            if min is not None:
-                return min
+            m = self._mintemp_dps.get_value(self._device)
+            if m is not None:
+                return m
 
         if self._temperature_dps is None:
             if self._temp_low_dps is None:
@@ -230,9 +230,9 @@ class TuyaLocalClimate(TuyaLocalEntity, ClimateEntity):
         """Return the maximum supported target temperature."""
         # if a separate max_temperature dps is specified, the device tells us.
         if self._maxtemp_dps is not None:
-            max = self._maxtemp_dps.get_value(self._device)
-            if max is not None:
-                return max
+            m = self._maxtemp_dps.get_value(self._device)
+            if m is not None:
+                return m
 
         if self._temperature_dps is None:
             if self._temp_high_dps is None:

+ 2 - 2
custom_components/tuya_local/config_flow.py

@@ -691,5 +691,5 @@ async def async_test_connection(config: dict, hass: HomeAssistant):
     return retval
 
 
-def scan_for_device(id):
-    return tinytuya.find_device(dev_id=id)
+def scan_for_device(devid):
+    return tinytuya.find_device(dev_id=devid)

+ 1 - 4
custom_components/tuya_local/device.py

@@ -701,10 +701,7 @@ class TuyaLocalDevice(object):
         return {**cached_state, **self._get_pending_properties()}
 
     def _get_pending_properties(self):
-        return {
-            key: property["value"]
-            for key, property in self._get_pending_updates().items()
-        }
+        return {key: prop["value"] for key, prop in self._get_pending_updates().items()}
 
     def _get_unsent_properties(self):
         return {

+ 4 - 4
custom_components/tuya_local/helpers/device_config.py

@@ -61,14 +61,14 @@ _signed_fmts = {
 }
 
 
-def _bytes_to_fmt(bytes, signed=False):
+def _bytes_to_fmt(b, signed=False):
     """Convert a byte count to an unpack format."""
     fmt = _signed_fmts if signed else _unsigned_fmts
 
-    if bytes in fmt:
-        return fmt[bytes]
+    if b in fmt:
+        return fmt[b]
     else:
-        return f"{bytes}s"
+        return f"{b}s"
 
 
 def _equal_or_in(value1, values2):

+ 2 - 2
custom_components/tuya_local/helpers/log.py

@@ -5,9 +5,9 @@ Functions for logging
 import json
 
 
-def non_json(input):
+def non_json(in):
     """Handler for json_dumps when used for debugging."""
-    return f"Non-JSON: ({input})"
+    return f"Non-JSON: ({in})"
 
 
 def log_json(data):

+ 3 - 3
custom_components/tuya_local/lock.py

@@ -143,14 +143,14 @@ class TuyaLocalLock(TuyaLocalEntity, LockEntity):
             return r".{8}"
         return None
 
-    def unlocker_id(self, dp, type):
+    def unlocker_id(self, dp, how):
         if dp:
             unlock = dp.get_value(self._device)
             if unlock:
                 if unlock is True:
-                    return f"{type}"
+                    return f"{how}"
                 else:
-                    return f"{type} #{unlock}"
+                    return f"{how} #{unlock}"
 
     @property
     def changed_by(self):

+ 1 - 1
custom_components/tuya_local/manifest.json

@@ -18,5 +18,5 @@
         "tinytuya==1.18.0",
         "tuya-device-sharing-sdk~=0.2.4"
     ],
-    "version": "2026.4.2"
+    "version": "2026.4.3"
 }

+ 4 - 4
custom_components/tuya_local/text.py

@@ -50,10 +50,10 @@ class TuyaLocalText(TuyaLocalEntity, TextEntity):
         self._attr_mode = TextMode.PASSWORD if self._value_dp.hidden else TextMode.TEXT
         self._extra_info = {ATTR_MODE: self._attr_mode}
 
-        range = self._value_dp.range(device, False)
-        if range:
-            self._attr_native_min = range[0]
-            self._attr_native_max = range[1]
+        rng = self._value_dp.range(device, False)
+        if rng:
+            self._attr_native_min = rng[0]
+            self._attr_native_max = rng[1]
             self._extra_info[ATTR_MIN] = self._attr_native_min
             self._extra_info[ATTR_MAX] = self._attr_native_max
 

+ 2 - 2
pyproject.toml

@@ -1,7 +1,7 @@
 [project]
 name = "Tuya-Local"
 description = "A Home Assistant integration for local control of Tuya devices."
-version = "2026.4.2"
+version = "2026.4.3"
 requires-python = ">3.14.2"
 dependencies = [
   "tinytuya~=1.18.0",
@@ -39,7 +39,7 @@ select = [
   "W",     # pycodestyle warnings
 #  "S",     # flake8-bandit
 #  "B",     # flake8-bugbear
-#  "A",    # flake8-builtins
+  "A",    # flake8-builtins
 ]
 ignore = [
   "E501",  # Duplicate of format rule, hits on tests

+ 1 - 1
tests/devices/base_device_tests.py

@@ -72,7 +72,7 @@ class TuyaDeviceTestCase(IsolatedAsyncioTestCase):
         self.addCleanup(device_patcher.stop)
         self.mock_device = device_patcher.start()
         self.dps = payload.copy()
-        self.mock_device.get_property.side_effect = lambda id: self.dps.get(id)
+        self.mock_device.get_property.side_effect = lambda dpid: self.dps.get(dpid)
         cfg = TuyaDeviceConfig(config_file)
         self.conf_type = cfg.legacy_type
         type(self.mock_device).has_returned_state = PropertyMock(return_value=True)

+ 2 - 2
tests/devices/test_simple_switch_with_timerv2.py

@@ -28,8 +28,8 @@ class TestTimedSwitch(SwitchableTests, TuyaDeviceTestCase):
         )
 
     def test_available(self):
-        for id, e in self.entities.items():
-            if id == "select_initial_state":
+        for entid, e in self.entities.items():
+            if entid == "select_initial_state":
                 self.dps[INITIAL_STATE_DPS] = None
                 self.assertFalse(e.available)
                 self.dps[INITIAL_STATE_DPS] = "on"

+ 1 - 1
tests/helpers.py

@@ -82,7 +82,7 @@ async def assert_device_properties_set_optional(
 def mock_device(dps, mocker):
     """Helper function to create a mock device with specified dps."""
     device = mocker.MagicMock()
-    device.get_property.side_effect = lambda id: dps.get(id)
+    device.get_property.side_effect = lambda dpid: dps.get(dpid)
     device.has_returned_state = True
     device.unique_id = "test_device_id"
     device.name = "Test Device"

+ 3 - 3
tests/mixins/climate.py

@@ -5,11 +5,11 @@ from ..helpers import assert_device_properties_set
 
 
 class TargetTemperatureTests:
-    def setUpTargetTemperature(self, dps, subject, min=15, max=35, step=1, scale=1):
+    def setUpTargetTemperature(self, dps, subject, mini=15, maxi=35, step=1, scale=1):
         self.targetTemp = subject
         self.targetTempDps = dps
-        self.targetTempMin = min
-        self.targetTempMax = max
+        self.targetTempMin = mini
+        self.targetTempMax = maxi
         self.targetTempStep = step
         self.targetTempScale = scale
 

+ 4 - 4
tests/mixins/number.py

@@ -7,8 +7,8 @@ class BasicNumberTests:
         self,
         dps,
         subject,
-        max,
-        min=0,
+        maxi,
+        mini=0,
         step=1,
         mode="auto",
         scale=1,
@@ -18,8 +18,8 @@ class BasicNumberTests:
     ):
         self.basicNumber = subject
         self.basicNumberDps = dps
-        self.basicNumberMin = min
-        self.basicNumberMax = max
+        self.basicNumberMin = mini
+        self.basicNumberMax = maxi
         self.basicNumberStep = step
         self.basicNumberMode = mode
         self.basicNumberScale = scale

+ 4 - 4
tests/mixins/text.py

@@ -18,8 +18,8 @@ class BasicTextTests:
         self,
         dp,
         subject,
-        max=None,
-        min=None,
+        maxi=None,
+        mini=None,
         mode=TextMode.TEXT,
         pattern=None,
         testdata=None,
@@ -27,8 +27,8 @@ class BasicTextTests:
     ):
         self.basicText = subject
         self.basicTextDp = dp
-        self.basicTextMin = min
-        self.basicTextMax = max
+        self.basicTextMin = mini
+        self.basicTextMax = maxi
         self.basicTextMode = mode
         self.basicTextPattern = pattern
         self.basicTextTestData = testdata

+ 3 - 3
tests/test_config_flow.py

@@ -391,10 +391,10 @@ async def test_flow_user_init_invalid_config(hass, mocker):
     assert {"base": "connection"} == result["errors"]
 
 
-def setup_device_mock(mock, mocker, failure=False, type="test"):
+def setup_device_mock(mock, mocker, failure=False, devtype="test"):
     mock_type = mocker.MagicMock()
-    mock_type.legacy_type = type
-    mock_type.config_type = type
+    mock_type.legacy_type = devtype
+    mock_type.config_type = devtype
     mock_type.match_quality.return_value = 100
     mock_type.product_display_entries.return_value = [(None, None)]
     mock.async_possible_types = mocker.AsyncMock(

+ 2 - 2
tests/test_device_config.py

@@ -758,8 +758,8 @@ def test_values_with_mirror(mocker):
     mock_device = mocker.MagicMock()
     mock_device.get_property.return_value = "1"
     cfg = TuyaDpsConfig(mock_entity, mock_config)
-    map = TuyaDpsConfig(mock_entity, mock_map_config)
-    mock_entity.find_dps.return_value = map
+    mapping = TuyaDpsConfig(mock_entity, mock_map_config)
+    mock_entity.find_dps.return_value = mapping
 
     assert set(cfg.values(mock_device)) == {"unmirrored", "map_one", "map_two"}
     assert len(cfg.values(mock_device)) == 3

+ 2 - 2
util/common_funcs.py

@@ -9,8 +9,8 @@ class FakeDevice:
     def __init__(self, dps):
         self._dps = dps
 
-    def get_property(self, id):
-        return self._dps.get(id)
+    def get_property(self, dpid):
+        return self._dps.get(dpid)
 
     @property
     def name(self):