You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I would like to save a Quantity with the built-in QSettings tools of PyQt6 in a .ini file. QSettings automatically pickles and unpickles the Quantity, but calling a function wrapped by a @ureg.wraps decorator fails unexpectedly.
I have the following setting in the .ini file (located at QSettings().fileName()):
Here is a minimal example that tries to load this setting:
importsysimportpintfrompintimportUnitRegistryfromPyQt6.QtCoreimportQSettingsfromPyQt6.QtWidgetsimportQApplicationureg=UnitRegistry()
# Some random function with units wrapped around it@ureg.wraps(None, "second")defwrapped_func(value):
print(value)
# QSettings setupapp=QApplication(sys.argv)
app.setOrganizationName("Test")
app.setApplicationName("test")
QSettings.setDefaultFormat(QSettings.Format.IniFormat)
settings=QSettings()
print("QSettings file path", settings.fileName())
print("\nRegular quantity working as expected")
regular_quantity=0.002*ureg.secondprint(regular_quantity) # 0.002 secondprint(type(regular_quantity)) # <class 'pint.Quantity'>print(isinstance(regular_quantity, pint.Quantity)) # Trueprint(isinstance(regular_quantity, ureg.Quantity)) # Trueprint(regular_quantity.__class__.__mro__)
print("\nLoading a quantity from QSettings")
unpickled_quantity=settings.value("my_value_1")
print(unpickled_quantity) # 0.002 secondprint(type(unpickled_quantity)) # <class 'pint.Quantity'>print(isinstance(unpickled_quantity, pint.Quantity)) # True (as expected)print(isinstance(unpickled_quantity, ureg.Quantity)) # False (for some reason?)print(unpickled_quantity.__class__.__mro__) # Exactly the same MRO as regular_quantity above# The unit wrapper checks for isinstance(unpickled_quantity, ureg.Quantity)# Because this is False the following function call throws a ValueError:# ValueError: A wrapped function using strict=True requires quantity or a string for all arguments with not None units. (error found for second, 0.002 second)wrapped_func(unpickled_quantity)
QSettings does unpickle the saved value correctly, but the check isinstance(unpickled_quantity, ureg.Quantity) returns False, even though the value is of type <class 'pint.Quantity'>. If I then try to use this value as an argument for a function with a @ureg.wraps decorator, the decorator checks for isinstance(unpickled_quantity, ureg.Quantity) in line 150 in registry_helpers.py, which returns False and therefore the decorator fails to accept my value as a Quantity, even though it is of type Quantity.
This if check in registry_helpers.py line 150 should return True, but does not:
# third pass: convert other argumentsforndxinunit_args_ndx:
ifisinstance(values[ndx], ureg.Quantity):
I found out that UnitRegistry.Quantity is just a TypeAlias of Quantity. But that confused me even more, because I don't see why isinstance should return differently for pint.Quantity and ureg.Quantity if they are the same type. The Method Resolution Orders are even exactly the same for both regular_quantity and unpickled_quantity, but somehow the isinstance checks are different!
What makes this even more confusing is that I can't seem to reproduce the .ini file that causes this error. The .ini file I showed at the top is produced by a larger program that consistently produces this bug. But when I try to write a minimal program that saves a .ini file itself, the bug does not appear and I don't see any difference between the two files.
As a work around I can save my values without Quantities for now, but that kind of defeats the purpose why we are using pint in our original program.
The text was updated successfully, but these errors were encountered:
I would like to save a Quantity with the built-in QSettings tools of PyQt6 in a .ini file. QSettings automatically pickles and unpickles the Quantity, but calling a function wrapped by a
@ureg.wraps
decorator fails unexpectedly.I have the following setting in the .ini file (located at QSettings().fileName()):
Here is a minimal example that tries to load this setting:
QSettings does unpickle the saved value correctly, but the check
isinstance(unpickled_quantity, ureg.Quantity)
returns False, even though the value is of type<class 'pint.Quantity'>
. If I then try to use this value as an argument for a function with a@ureg.wraps
decorator, the decorator checks forisinstance(unpickled_quantity, ureg.Quantity)
in line 150 inregistry_helpers.py
, which returns False and therefore the decorator fails to accept my value as a Quantity, even though it is of type Quantity.This if check in
registry_helpers.py
line 150 should return True, but does not:I found out that UnitRegistry.Quantity is just a TypeAlias of Quantity. But that confused me even more, because I don't see why
isinstance
should return differently forpint.Quantity
andureg.Quantity
if they are the same type. The Method Resolution Orders are even exactly the same for bothregular_quantity
andunpickled_quantity
, but somehow the isinstance checks are different!What makes this even more confusing is that I can't seem to reproduce the .ini file that causes this error. The .ini file I showed at the top is produced by a larger program that consistently produces this bug. But when I try to write a minimal program that saves a .ini file itself, the bug does not appear and I don't see any difference between the two files.
As a work around I can save my values without Quantities for now, but that kind of defeats the purpose why we are using pint in our original program.
The text was updated successfully, but these errors were encountered: