Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork7.9k
Description
Bug report
Bug summary
Inbasic_units.py
, theTaggedValue
has a__new__
method that does the following:
matplotlib/examples/units/basic_units.py
Lines 120 to 128 inf710ad3
def__new__(cls,value,unit): | |
# generate a new subclass for value | |
value_class=type(value) | |
try: | |
subcls=type(f'TaggedValue_of_{value_class.__name__}', | |
(cls,value_class), {}) | |
returnobject.__new__(subcls) | |
exceptTypeError: | |
returnobject.__new__(cls) |
However, whenvalue_class
is notobject
, thenobject.__new__(subcls)
raises:
In [1]: class A: ...: def __new__(cls, value): ...: value_class = type(value) ...: subcls = type(f'A_{value_class.__name__}', (cls, value_class), {}) ...: return object.__new__(subcls) ...: In [2]: A(object()) Out[2]: <__main__.A_object at 0x7f9ce8a684c0>In [3]: A(1.0) ---------------------------------------------------------------------------TypeError Traceback (most recent call last)<ipython-input-6-04f0da727658> in <module>----> 1 A(1.0)<ipython-input-5-3b6ef5f2aee2> in __new__(cls, value) 3 value_class = type(value) 4 subcls = type(f'A_{value_class.__name__}', (cls, value_class), {})----> 5 return object.__new__(subcls) 6 TypeError: object.__new__(A_float) is not safe, use float.__new__()
This means that the intended subclassing there never happens, as it falls back to the genericobject.__new__
in the exception handler. I came across this while trying to fix#19535 with a conditional method, but of course, that never worked because the code always ended up using the generic non-subclass.
I tried to fix this by doingsuper().__new__
orvalue_class.__new__
(and then someobject.<method>
needed to besuper().<method>
in other methods), but this runs into issues with other classes that also override__new__
, namelyMaskedArray
.
I think it makes sense to create subclasses (and then fix it so it actually leaves out methods that shouldn't be there), but I'm not sure that multiple inheritance is the right way to do it.
Matplotlib version
- Matplotlib version (
import matplotlib; print(matplotlib.__version__)
):master
at the moment - Matplotlib backend (
print(matplotlib.get_backend())
): n/a - Python version: 3.7.6