Parameters don't respect diamond inheritance
- Dominant language
- Python
- Stars
- 521
- Forks
- 86
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 35
Description
Diamond inheritance occurs when a class inherits from two classes, themselves inheriting from a common class. The example below shows how this is handled by Python. In this example the MRO is D/B/C/A and the resolution of `p` on `D` follows:
- D: `p` has no value
- B: `p` has no value
- C: `p` has a value of `2`, stop there and use that
```python
class A:
p = 1
class B(A):
pass
class C(A):
p = 2
class D(B, C):
pass
assert D.p == 2
```
Parameter attribute inheritance in a hierarchy of Parameterized classes works differently. The resolution of the attributes of `p` on `D` follows:
- D: `default` and `doc` are `None`
- B: `default` and `doc` have their values **already inherited** from `A`, stop there and use that
As such C is never visited in the resolution.
```python
import param
class A(param.Parameterized):
p = param.Parameter(default=1, doc='11')
class B(A):
p = param.Parameter()
class C(A):
p = param.Parameter(default=2, doc='22')
class D(B, C):
p = param.Parameter()
assert D.p == 1
assert D().p == 1
assert D.param.p.doc == '11'
assert D().param.p.doc == '11'
```
To be honest I'm not sure whether this is a bug or a feature. It is quite likely to be an edge-case. I think this behavior deserves to be documented as it diverts from the way regular Python attributes behave.
Contributor guide
Assessment
This issue has not been assessed yet.