Skip to content

Commit 5f75bcf

Browse files
Support pickle serialization (#53)
2 parents b0cf038 + 4c3e134 commit 5f75bcf

4 files changed

Lines changed: 63 additions & 0 deletions

File tree

test/test_value.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,14 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17+
import itertools
18+
import pickle
19+
1720
import numpy as np
1821
import pytest
1922

2023
from tunits import Value, UnitMismatchError
24+
import tunits as tu
2125

2226

2327
def test_construction() -> None:
@@ -263,3 +267,15 @@ def test_dimensionless() -> None:
263267
_ = A.dimensionless()
264268

265269
assert B.dimensionless() == 1.2
270+
271+
272+
def test_pick_roundtrip() -> None:
273+
units = itertools.product(
274+
[tu.ns, tu.GHz, tu.dBm, tu.deg, 1, tu.GHz**0.5, tu.m**0.75, tu.s**0.25], repeat=3
275+
)
276+
for value in np.random.random(20):
277+
for unit_list in units:
278+
unit = np.prod(unit_list) # type: ignore[arg-type]
279+
x = value * unit
280+
s = pickle.dumps(x)
281+
assert x == pickle.loads(s)

test/test_value_array.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,15 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import itertools
16+
import pickle
17+
1518
import numpy as np
1619
import pytest
1720
from tunits.core import raw_WithUnit, raw_UnitArray
1821

1922
from tunits import ValueArray, UnitMismatchError, Value
23+
import tunits as tu
2024

2125

2226
def test_construction() -> None:
@@ -238,3 +242,15 @@ def test_dimensionless() -> None:
238242
_ = A.dimensionless()
239243

240244
np.testing.assert_equal(B.dimensionless(), np.arange(5) / 1000)
245+
246+
247+
def test_pick_roundtrip() -> None:
248+
units = itertools.product(
249+
[tu.ns, tu.GHz, tu.dBm, tu.deg, 1, tu.GHz**0.5, tu.m**0.75, tu.s**0.25], repeat=3
250+
)
251+
for value in np.random.random((5, 20)):
252+
for unit_list in units:
253+
unit = np.prod(unit_list) # type: ignore[arg-type]
254+
x = value * unit
255+
s = pickle.dumps(x)
256+
assert all(x == pickle.loads(s))

tunits/core/cython/unit_array.pyx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,4 +237,19 @@ cdef class UnitArray:
237237
raise ValueError("UnitArray power does not support third argument")
238238
return self.pow_frac(float_to_twelths_frac(exponent));
239239

240+
def __getstate__(self):
241+
return {
242+
'unit_count': self.unit_count,
243+
'units': [*self],
244+
}
245+
246+
def __setstate__(self, pickle_info: dict[str, Any]):
247+
self.unit_count = pickle_info['unit_count']
248+
self.units = <UnitTerm *>PyMem_Malloc(self.unit_count*sizeof(UnitTerm))
249+
for i, (name, numer, denom) in enumerate(pickle_info['units']):
250+
Py_INCREF(name)
251+
self.units[i].name = <PyObject *>name
252+
self.units[i].power.numer = numer
253+
self.units[i].power.denom = denom
254+
240255
_EmptyUnit = UnitArray()

tunits/core/cython/with_unit.pyx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,22 @@ cdef class WithUnit:
685685
def _from_json_dict_(cls, **kwargs):
686686
return cls(kwargs["value"], kwargs["unit"])
687687

688+
def __getstate__(self):
689+
return {
690+
'value': self.value,
691+
'conv': self.conv,
692+
'display_units': self.display_units.__getstate__(),
693+
'base_units': self.base_units.__getstate__(),
694+
}
695+
696+
def __setstate__(self, pickle_info):
697+
self.value = pickle_info['value']
698+
self.conv = pickle_info['conv']
699+
self.display_units = UnitArray()
700+
self.base_units = UnitArray()
701+
self.display_units.__setstate__(pickle_info['display_units'])
702+
self.base_units.__setstate__(pickle_info['base_units'])
703+
688704
_try_interpret_as_with_unit = None
689705
_is_value_consistent_with_default_unit_database = None
690706
def init_base_unit_functions(

0 commit comments

Comments
 (0)