NumPy 2 regression with attribute property writing

Using numpy v2, when writing an attribute property and sending a numpy value e.g. np.float64(1.234) the value will be serialized as np.float64(1.234) instead of the expected 1.234.

db.put_device_attribute_property("sys/tg_test/1", {"ampli": {"max_value": numpy.float64(1.234)}})
db.get_device_attribute_property("sys/tg_test/1", "ampli")
{'ampli': {'max_value': ['np.float64(1.234)']}}

With numpy 1 this works as expected. We found this causes a bug in Sardana when e.g. a pseudomotor returns a numpy scalar for its DialPosition attribute.

We think the core reason is that the behavior of repr() on a numpy scalar has changed https://numpy.org/devdocs/release/2.0.0-notes.html#representation-of-numpy-scalars-changed repr() appears to be used to serialize non-string values into strings, see https://gitlab.com/tango-controls/pytango/-/blob/develop/tango/db.py?ref_type=heads#L324

Curiously, for properties in general, str() is apparently used instead https://gitlab.com/tango-controls/pytango/-/blob/develop/tango/utils.py?ref_type=heads#L1300 and I can't reproduce the problem there. I don't see any reason why they should use different ways of serialization. Maybe these two cases could share the same code?

I think using str is the right call here as repr is intended for "developer" use, e.g. logging. The numpy change log also recommends using str for serialization.

Of course it is a bit "unsafe" to send arbitrary things to PyTango to be written to properties, and the best way should be to turn them into strings before sending them. But PyTango should probably do its best (and be consistent!)

PyTango: 10.0.2 NumPy: 2.3.0 and 1.26.4

Assignee Loading
Time tracking Loading