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

Class attributes changes at load if the object is in a list or tuple. #625

Closed
baeminbo opened this issue Oct 20, 2023 · 1 comment
Closed
Labels
Milestone

Comments

@baeminbo
Copy link

I created a simple test code like the following. I expect the a in unpickled B objects (b1, b2, l1[0], l2[0]) should have the same value as the a in the original B object (b).

import dill

class A:
  pass

class B:
  a = A()
  def get_value(self):
    return self.a

b = B()
print(f'b: {b.get_value()}')

pickled_b = dill.dumps(b)

b1 = dill.loads(pickled_b)
print(f'b1: {b1.get_value()}')
b2 = dill.loads(pickled_b)
print(f'b2: {b2.get_value()}')


####

l = [B()]
print(f'l[0]: {l[0].get_value()}')

pickled_l = dill.dumps(l)

l1 = dill.loads(pickled_l)
print(f'l1[0]: {l1[0].get_value()}')
l2 = dill.loads(pickled_l)
print(f'l2[0]: {l2[0].get_value()}')

But, it worked as expected when dumping with the object directly, but not when dumping a list including the object. See below. Is this an intended behavior?

baeminbo$ python --version
Python 3.11.4
baeminbo$ pip list
Package    Version
---------- -------
dill       0.3.7
pip        23.1.2
setuptools 65.5.0

[notice] A new release of pip is available: 23.1.2 -> 23.3
[notice] To update, run: pip install --upgrade pip
baeminbo$ python dilltest.py 
b: <__main__.A object at 0x108d04d90>
b1: <__main__.A object at 0x108d04d90>
b2: <__main__.A object at 0x108d04d90>
l[0]: <__main__.A object at 0x108d04d90>
l1[0]: <__main__.A object at 0x1093e3150>
l2[0]: <__main__.A object at 0x1093e3950>
@baeminbo
Copy link
Author

I close this ticket as I confirmed this is an intended behavior. The loads has ignore option that decides if using a reconstructed class or using the existing class in the __main__ module. The code is here.

In my sample, b=B() is a class in __main__, but l=[B()] is a type in builtins. For b1 and b2, newly reconstructed classes were discarded and replaced with the existing __main__.B. l1 and l2 didn't change the class for their elements, so the elements use the newly reconstructed classes which have different values for the class attribute a.

@mmckerns mmckerns added this to the dill-0.3.8 milestone Oct 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants