2011-12-05 31 views
6

Có cách nào để làm cho trăn pickle bỏ qua "nó không phải là cùng một đối tượng" lỗi?Có cách nào để làm cho trăn trăn bỏ qua "nó không phải là cùng một đối tượng" lỗi

Tôi đang viết một thử nghiệm bằng cách sử dụng Mock để kiểm soát hạt mịn trên các kết quả mà datetime.utcnow() tạo ra. Mã tôi đang sử dụng là thời gian nhạy cảm nên bản vá của mô hình giúp dễ dàng kiểm tra.

Các thử nghiệm tương tự cần phải chọn đối tượng và gửi kết quả đến máy chủ từ xa. Với mục đích của thử nghiệm nếu một datetime tiêu chuẩn đã được chọn và nhận bởi máy chủ từ xa, mọi thứ sẽ ổn.

Đáng tiếc là các module dưa được barfing với các lỗi sau:

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

Dưới đây là một ví dụ nhỏ để tạo lại lỗi.

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() 

Có một số kết hợp của __reduce____getstate__ phương pháp có thể đánh lừa các máy móc thiết bị dưa vào suy nghĩ MockDatetime là một datetime khi tôi dưa?

Trả lời

5

Nhìn vào where to patch phần trong tài liệu tôi thấy lời khuyên này:

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

Tiếp theo đề nghị này, tôi đã cố gắng để thay thế:

@patch('datetime.datetime', MockDatetime) 

với:

@patch('__main__.datetime', MockDatetime) 

và tôi không nhận được bất kỳ lỗi nào từ pickle. Ngoài ra, tôi đã thêm một tuyên bố print để đảm bảo rằng datetime thực sự đang được vá và tôi nhận được giá trị mong đợi.

2

Trong trường hợp ai đó muốn một giải pháp tổng quát để dưa chế giễu:

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

Lưu ý rằng điều này dường như không lưu nội dung bên trong của mô hình được sử dụng (ví dụ các cuộc gọi).

Các vấn đề liên quan