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
patch.object doesn't restore function defaults #66336
Comments
Following a patch, a function's __defaults__ attribute is reset to None. def foo(x=5):
return x
|
The issue seems to affect special attributes that can't be deleted.
In Lib/unittest/mock.py:1329, patch() tried to delete the attribute, and then, if it doesn't exist, it restores the previous value. However some special attributes exist even after they are deleted, but their initial value is lost:
>>> def foo(x:int=5, y:int=3): return x + y
...
>>> foo.__defaults__
(5, 3)
>>> del foo.__defaults__
>>> foo.__defaults__
>>> foo.__annotations__
{'y': <class 'int'>, 'x': <class 'int'>}
>>> del foo.__annotations__
>>> foo.__annotations__
{}
>>> foo.__qualname__
'foo'
>>> del foo.__qualname__
TypeError: __qualname__ must be set to a string object |
Is special casing the special attrs a permament enough solution? |
Thanks for the patch, however I don't think this is a robust solution. The current code can delete an attribute without restoring it so an easy solution would be removing the hasattr() check, but that seems to be there to deal with proxy objects, so doing that will probably break them (Lib/unittest/test/testmock/testpatch.py:821 seems to test proxy object). |
It might have to be. There's no general purpose solution that will fit every possible behaviour for a Python descriptor I'm afraid. |
And yes, there's deliberate proxy object support in mock.patch (django settings being one specific use-case). |
So the changes submitted, take into the attributes that are part of the standard Python Data Model/Descriptors and defined as editable per documentation. The thought is if a user is needing to support outside of Proxy Object (currently supported) and default descriptor attributes then mock should be special cased by user/developer. Please advise on current solution. |
How's the issue going on? The situation to mock function's def access_db(statement, backend=default_db_backend):
return default_db_backend.execute(statement) that we must mock It has one year past, though I could patch the |
Sean's patch looks good to me. |
New changeset b67ed559a7d3 by Senthil Kumaran in branch '3.5': New changeset 9b21dfd71561 by Senthil Kumaran in branch 'default': |
This was an interesting issue. Thanks for the patch, Sean to fix this bug. I have committed it in 3.5 and 3.6. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: