Suggestions to improve `Comparator.is_equal`
- Dominant language
- Python
- Stars
- 521
- Forks
- 86
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 35
Description
The `Comparator` class is used internally by Param to compare if two objects are equal with the `is_equal` class method. This is used to decide whether setting a new attribute on a Parameter should trigger or not its attached callbacks.
`Comparator.is_equal` returns False if the two objects compared aren't of one of the types supported by `Comparator` (string, number, byte, None, list, set, tuple, dict, datetime). In https://github.com/holoviz/param/pull/629 I suggested that `is_equal` could start with an identity comparison. Philipp rightfully pointed out that this would fail for complex types that are modified in place, i.e.:
```python
import param
class Complex:
def __init__(self, x):
self.x = x
cpl = Complex(x='test')
class P(param.Parameterized):
a = param.Parameter()
def __init__(self, **params):
super().__init__(**params)
self.param.watch(self.cb, 'a')
@param.depends('a', watch=True)
def cb(self):
print('cb')
p = P(a=cpl)
# Modify the complex obj in place
cpl.x = 'another'
# With an identity comparison, this would not trigger the callback
# even if the object has been modified.
p.b = cpl
```
So this is definitely a behavior that is not desired. Yet having callbacks triggered when resetting an attribute to the same/equal object is a behavior that I think is quite surprising for Param users. I've opened this issue to discuss how to improve the situation. I'd suggest:
* Making sure `Comparator` supports all the types supported by Param. I guess that Pandas DataFrames/Series and Numpy Arrays should be supported.
* If an object isn't of one of the supported types and if it implements `__eq__`, use it (maybe wrapped in a try/except).
Contributor guide
Assessment
This issue has not been assessed yet.