python / python/cpython

patch does not correctly restore state on objects without __dict__

Đang mở
#126,886 5 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

stdlib type-bug
Ngôn ngữ chính
Python
Star
77.2k
Fork
35.9k
Chỉ số merge pull request
Chỉ số pull request đang chờ

Mô tả

Bug report

Bug description:
from unittest.mock import patch
class Proxy(object):
    config = {}
    def __getattr__(self, name):
        return self.config[name]
    def __setattr__(self, name, value):
        if name == 'config':
            object.__setattr__(self, name, value)
            return
        self.config[name] = value
    def __delattr__(self, name):
        self.config[name] = 'DEFAULT'

p = Proxy()
p.a = True
print(p.a)
with patch('__main__.p.a', False):
    print(p.a)
print(p.a)

Expected

True
False
True

Actual

True
False
DEFAULT

Note that this is a relatively niche issue, but for example in a config system (i.e. https://github.com/pytorch/pytorch/pull/140779), if you don't want to have a delete work, (i.e. have it set it back to a default value), the code in https://github.com/python/cpython/blob/94a7a4e22fb8f567090514785c69e65298acca42/Lib/unittest/mock.py#L1637 will call delattr, and then not call setattr, because it still has the attr.

Possible fixes:
If delattr throws (maybe NotImplementederror), call setattr instead (this is nice and explicit + removes the hacky workaround I have to do).

If the value after it's been deleted doesn't equal the original value, reassign it? (this might require objects to be comparable, not sure if that is already an issue here).

Either way I wanted to see if there was any interest in fixing this, and if anyone saw a solution that seemed reasonable enough.

CPython versions tested on:

3.12

Operating systems tested on:

Linux

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu với việc tái hiện trong issue và kiểm tra logic khôi phục tại Lib/unittest/mock.py quanh dòng 1637. So sánh cách patch xử lý các thuộc tính trên những đối tượng không có dict khi việc xóa làm thay đổi giá trị được quan sát. Được xem là hoàn tất khi ví dụ khôi phục p.a về True mà vẫn giữ nguyên hành vi hiện có đối với các đối tượng thông thường, đồng thời bổ sung kiểm thử hồi quy trong các bài kiểm thử unittest.mock liên quan.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
python
Lĩnh vực
testing-qa
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
35/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.