Skip to content

Commit

Permalink
[python] Fix Cluster objects datatypes on Python 3.11 (#26729)
Browse files Browse the repository at this point in the history
* [python] Fix Cluster objects datatypes on Python 3.11

It seems that Python 3.11 requires the custom data type Nullable to
implement the __hash__() function, otherwise initializing dataclass
annotated objects fail with the following stack trace:

```
  File "/home/sag/projects/project-chip/connectedhomeip-v1.1/.environment/pigweed-venv/lib/python3.11/site-packages/chip/clusters/Objects.py", line 385, in Commands
    @DataClass
     ^^^^^^^^^
  File "/usr/lib/python3.11/dataclasses.py", line 1223, in dataclass
    return wrap(cls)
           ^^^^^^^^^
  File "/usr/lib/python3.11/dataclasses.py", line 1213, in wrap
    return _process_class(cls, init, repr, eq, order, unsafe_hash,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/dataclasses.py", line 958, in _process_class
    cls_fields.append(_get_field(cls, name, type, kw_only))
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/dataclasses.py", line 815, in _get_field
    raise ValueError(f'mutable default {type(f.default)} for field '
ValueError: mutable default <class 'chip.clusters.Types.Nullable'> for field capacity is not allowed: use default_factory
```

Since all instances of Nullable are the same "value", we can return a
static 0 as hash value.

* [python] Mark Nullable type frozen

* address linter error

* Revert dataclass frozen

* Add comment
  • Loading branch information
agners authored and pull[bot] committed Jul 11, 2023
1 parent 7876bb0 commit 1096084
Showing 1 changed file with 8 additions and 1 deletion.
9 changes: 8 additions & 1 deletion src/controller/python/chip/clusters/Types.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
# limitations under the License.
#


class Nullable():
def __repr__(self):
return 'Null'
Expand All @@ -32,5 +31,13 @@ def __ne__(self, other):
def __lt__(self, other):
return True

def __hash__(self):
''' Explicitly implement __hash__() to imply immutability when used in
dataclasses.
See also: https://docs.python.org/3/library/dataclasses.html#dataclasses.dataclass
'''
return 0


NullValue = Nullable()

0 comments on commit 1096084

Please sign in to comment.