Is there a way to make python pickle ignore “it's not the same object ” errors

我的未来我决定 提交于 2019-12-23 09:22:25

问题


Is there a way to make python pickle ignore "it's not the same object " errors?

I'm writing a test using Mock to have fine grain control over the results that datetime.utcnow() produces. The code I'm using is time sensitive so mock's patch makes it easy to test.

The same tests need to pickle objects and send the results to a remote server. For the purpose of the test if a standard datetime was pickled and received by the remote server everything would be fine.

Unfortunately the pickle module is barfing with the following error:

Can't pickle <type 'datetime.datetime'>: it's not the same object as datetime.datetime

Here is a minimal example to reproduce the error.

from mock import patch
from datetime import datetime
import pickle

class MockDatetime(datetime):
  frozendt = datetime(2011,05,31)

  @classmethod
  def advance(cls, **kw):
    cls.frozendt = cls.frozendt + timedelta(**kw)

  @classmethod
  def utcnow(cls):
    return cls.frozendt

@patch('datetime.datetime', MockDatetime)
def test():
  pickle.dumps(datetime.utcnow())

if __name__ == '__main__':
  test()

Is there some combo of __reduce__ and __getstate__ methods that might trick the pickle machinery into thinking MockDatetime is a datetime when I pickle?


回答1:


Looking at the where to patch section in the documentation I see this advice:

The basic principle is that you patch where an object is used, which is not necessarily the same place as where it is defined.

Following this recommendation, I've tried to replace:

@patch('datetime.datetime', MockDatetime)

with:

@patch('__main__.datetime', MockDatetime)

and I didn't get any error from pickle. Also, I added a print statement to make sure that datetime was really being patched and I got the expected value.




回答2:


In case someone wants a generic solution to pickle mocks:

m = mock.MagicMock()
m.__reduce__ = lambda self: (mock.MagicMock, ())

Note that this doesn't seem to save internal content of the used mock (e.g calls).



来源:https://stackoverflow.com/questions/8381049/is-there-a-way-to-make-python-pickle-ignore-its-not-the-same-object-errors

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!