Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make astropy.utils.masked.Masked work with dill #16352

Open
Jerry-Ma opened this issue Apr 27, 2024 · 1 comment
Open

Make astropy.utils.masked.Masked work with dill #16352

Jerry-Ma opened this issue Apr 27, 2024 · 1 comment

Comments

@Jerry-Ma
Copy link
Contributor

Description

It appears that the following code to pickle a MaskedQuantity object does not work because the __setstate__ does not handle non-bound case:

import astropy.units as u
import dill as pickle
import numpy as np
from astropy.utils.masked import Masked

a = np.arange(3) << u.m
m = np.array([True, False, False])

a_masked = Masked(a, mask=m)

print(a_masked)


print(pickle.loads(pickle.dumps(a_masked)))

The fix seems to be simple: add logic to handle the uninitialized _attrs attribute on the astropy.utils.data_info.DataInfo class:

    def __getstate__(self):
        return getattr(self, "_attrs", None)

    def __setstate__(self, state):
        if state is not None:
            self._attrs = state

Any additional thoughts or caveats?

Expected behavior

The above code works without error.

How to Reproduce

No response

Versions

Linux-5.15.85-penguins-rule-x86_64-with-glibc2.35
Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]
astropy 6.0.1
Numpy 1.24.2
pyerfa 2.0.1.4
Scipy 1.10.1
Matplotlib 3.7.1
@Jerry-Ma Jerry-Ma added the Bug label Apr 27, 2024
@mhvk mhvk added the utils label Apr 28, 2024
@mhvk
Copy link
Contributor

mhvk commented Apr 28, 2024

@Jerry-Ma - thanks for reporting! So, if I understand correctly, the actual problem is not specific to dill but really that an unbound info cannot be pickled, i.e., that the following fails:

import pickle
from astropy.utils.data_info import DataInfo
di = DataInfo()
pickle.dumps(di)

AttributeError: 'DataInfo' object has no attribute '_attrs'

I think your fix seems logical (though perhaps an alternative is to always set _attrs, maybe _attrs=None for the unbound case? your fix has the advantage of not changing any other behaviour, though). Would you be willing to make a PR? I think the test would just be with pickle on DataInfo rather than with dill on Masked - I don't think we want to add another dependency just for the tests if we can avoid it!

Aside - it is a bit curious that Masked instances can be pickled, i.e., pickle clearly does something a bit different from dill - this suggests that perhaps there is a bug in dill? Or is this an expected difference?

@pllim pllim added utils.masked and removed utils labels Apr 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants