Issue40805
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2020-05-28 12:19 by Rob Taft, last changed 2022-04-11 14:59 by admin. This issue is now closed.
Messages (9) | |||
---|---|---|---|
msg370197 - (view) | Author: Rob Taft (Rob Taft) | Date: 2020-05-28 12:19 | |
Whenever I try to patch flask.g, it appears to do nothing. This happened when I upgraded mock from 3.x to 4.x. I reported it on the mock github page https://github.com/testing-cabal/mock/issues/490 and was asked to report it here. The folllowing code run with pytest works fine in mock 3.0.5, but fails to patch in 4.0.0 and up. from mock import patch import flask def some_function(): flask.g.somevariable = True return flask.g.somevariable @patch('flask.g') def test_some_function(mock_flask_global): assert some_function() |
|||
msg370356 - (view) | Author: Terry J. Reedy (terry.reedy) * | Date: 2020-05-30 03:01 | |
Sorry, but I believe you were misdirected*. mock, as opposed to unittest.mock, pytest, flask, and werkzeug are 3rd party modules. The error report seems to be missing part of the stacktrace at both ends. What line is your file resulted in the error? (This time we can guess == @patch. @What called _lookup_app_object in flask? (I have no idea.) However, once contextlib._GeneratorContextManager calls next(self.gen), the rest of the trace is outside the stdlib. At the end, the RuntimeError is raised by flask, not by python, because the flask _app_ctx_stack.top does not exist. If you do not understand their error message, ask flask people. * I assume that cjw296 *glanced* at your report, saw 'RuntimeError', and too quickly assumed 'cpython error'. flask could have defined, for instance, FlaskRuntimeError for its error reporting. |
|||
msg370368 - (view) | Author: Rob Taft (Rob Taft) | Date: 2020-05-30 10:42 | |
The test was supposed to patch the flask component during the unit test, the error indicates the patch did not work. The actual error message is not relevant to the actual issue. I don't know why I was directed to here. When I replace it with unittest.mock, it appears to work fine, so my solution might end up being to dump the 3rd party mock library. On Fri, May 29, 2020 at 11:02 PM Terry J. Reedy <report@bugs.python.org> wrote: > > Terry J. Reedy <tjreedy@udel.edu> added the comment: > > Sorry, but I believe you were misdirected*. mock, as opposed to > unittest.mock, pytest, flask, and werkzeug are 3rd party modules. The > error report seems to be missing part of the stacktrace at both ends. What > line is your file resulted in the error? (This time we can guess == > @patch. @What called _lookup_app_object in flask? (I have no idea.) > > However, once contextlib._GeneratorContextManager calls next(self.gen), > the rest of the trace is outside the stdlib. At the end, the RuntimeError > is raised by flask, not by python, because the flask _app_ctx_stack.top > does not exist. If you do not understand their error message, ask flask > people. > > * I assume that cjw296 *glanced* at your report, saw 'RuntimeError', and > too quickly assumed 'cpython error'. flask could have defined, for > instance, FlaskRuntimeError for its error reporting. > > ---------- > nosy: +terry.reedy > resolution: -> third party > stage: -> resolved > status: open -> closed > > _______________________________________ > Python tracker <report@bugs.python.org> > <https://bugs.python.org/issue40805> > _______________________________________ > |
|||
msg370650 - (view) | Author: Chris Withers (cjw296) * | Date: 2020-06-03 10:09 | |
Terry, mock is now a rolling backport of unittest.mock with all development taking place in cpython's repo. If issues are reported there, they need to be triaged here first, as it's most likely a bug in unittest.mock that needs fixing here. Rob, please can you see if this is reproducible on Python 3.8 or 3.9, replacing `from mock import` with `from unittest.mock` import? |
|||
msg370651 - (view) | Author: Chris Withers (cjw296) * | Date: 2020-06-03 10:14 | |
Rob, you're welcome to dump `mock` and use `unittest.mock`, and that might be best for now, but this will then likely come back to bite you when you end up on the version of Python, probably 3.9, where it is present ;-) |
|||
msg370673 - (view) | Author: Rob Taft (Rob Taft) | Date: 2020-06-03 13:33 | |
I have confirmed that using unittest.mock instead of the 3rd party mock library in python 3.8.3 and 3.9-dev fails to patch flask.g. 3.7.7 works correctly. |
|||
msg370675 - (view) | Author: Terry J. Reedy (terry.reedy) * | Date: 2020-06-03 15:23 | |
Chris, I see no evidence in the *incomplete* traceback not posted here that there is a bug in mock. Mock calls "hasattr(obj, '__func__') and apparently flask, called via werkzeug, answers 'RuntimeError'. The overt bug is that calling werkzeug.local.(type(obj)?).__getattr__ fails by doing something other than "return the (computed) attribute value or raise an AttributeError exception". https://docs.python.org/3/reference/datamodel.html#object.__getattr__ |
|||
msg370678 - (view) | Author: Rob Taft (Rob Taft) | Date: 2020-06-03 16:23 | |
I updated the test with 2 cases and the traceback is different for each when I expected them to be the same if this was purely a mock issue, the line throwing the error is the same. I can post this over with flask and see what they think. from unittest.mock import patch import flask def some_function(): flask.g.somevariable = True return flask.g.somevariable @patch('flask.g') def test_patch(mock_flask_global): assert some_function() def test_no_patch(): assert some_function() $ pytest -vv temp_test.py ============================================================================================================ test session starts ============================================================================================================= platform linux -- Python 3.8.3, pytest-5.4.3, py-1.8.1, pluggy-0.13.1 -- collected 2 items temp_test.py::test_patch FAILED [ 50%] temp_test.py::test_no_patch FAILED [100%] ================================================================================================================== FAILURES ================================================================================================================== _________________________________________________________________________________________________________________ test_patch _________________________________________________________________________________________________________________ args = (), keywargs = {} @wraps(func) def patched(*args, **keywargs): > with self.decoration_helper(patched, args, keywargs) as (newargs, newkeywargs): ../../../.pyenv/versions/3.8.3/lib/python3.8/unittest/mock.py:1322: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../../.pyenv/versions/3.8.3/lib/python3.8/contextlib.py:113: in __enter__ return next(self.gen) ../../../.pyenv/versions/3.8.3/lib/python3.8/unittest/mock.py:1304: in decoration_helper arg = exit_stack.enter_context(patching) ../../../.pyenv/versions/3.8.3/lib/python3.8/contextlib.py:425: in enter_context result = _cm_type.__enter__(cm) ../../../.pyenv/versions/3.8.3/lib/python3.8/unittest/mock.py:1416: in __enter__ if spec is None and _is_async_obj(original): ../../../.pyenv/versions/3.8.3/lib/python3.8/unittest/mock.py:51: in _is_async_obj if hasattr(obj, '__func__'): pyvenv/lib/python3.8/site-packages/werkzeug/local.py:347: in __getattr__ return getattr(self._get_current_object(), name) pyvenv/lib/python3.8/site-packages/werkzeug/local.py:306: in _get_current_object return self.__local() _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ name = 'g' def _lookup_app_object(name): top = _app_ctx_stack.top if top is None: > raise RuntimeError(_app_ctx_err_msg) E RuntimeError: Working outside of application context. E E This typically means that you attempted to use functionality that needed E to interface with the current application object in some way. To solve E this, set up an application context with app.app_context(). See the E documentation for more information. pyvenv/lib/python3.8/site-packages/flask/globals.py:45: RuntimeError _______________________________________________________________________________________________________________ test_no_patch ________________________________________________________________________________________________________________ def test_no_patch(): > assert some_function() temp_test.py:14: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ temp_test.py:6: in some_function flask.g.somevariable = True pyvenv/lib/python3.8/site-packages/werkzeug/local.py:364: in <lambda> __setattr__ = lambda x, n, v: setattr(x._get_current_object(), n, v) pyvenv/lib/python3.8/site-packages/werkzeug/local.py:306: in _get_current_object return self.__local() _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ name = 'g' def _lookup_app_object(name): top = _app_ctx_stack.top if top is None: > raise RuntimeError(_app_ctx_err_msg) E RuntimeError: Working outside of application context. E E This typically means that you attempted to use functionality that needed E to interface with the current application object in some way. To solve E this, set up an application context with app.app_context(). See the E documentation for more information. pyvenv/lib/python3.8/site-packages/flask/globals.py:45: RuntimeError |
|||
msg370981 - (view) | Author: Rob Taft (Rob Taft) | Date: 2020-06-08 13:38 | |
https://github.com/pallets/flask/issues/3637 I've worked around the issue and accept that this will not work in the future. |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:59:31 | admin | set | github: 84982 |
2020-06-08 13:38:19 | Rob Taft | set | status: open -> closed messages: + msg370981 |
2020-06-03 16:23:15 | Rob Taft | set | messages: + msg370678 |
2020-06-03 15:23:32 | terry.reedy | set | messages: + msg370675 |
2020-06-03 14:36:24 | Rob Taft | set | versions: + Python 3.9, - Python 3.6 |
2020-06-03 13:33:01 | Rob Taft | set | messages: + msg370673 |
2020-06-03 10:14:10 | cjw296 | set | messages: + msg370651 |
2020-06-03 10:09:29 | cjw296 | set | status: closed -> open |
2020-06-03 10:09:23 | cjw296 | set | nosy:
+ cjw296 messages: + msg370650 |
2020-05-30 10:42:18 | Rob Taft | set | messages: + msg370368 |
2020-05-30 03:01:56 | terry.reedy | set | status: open -> closed nosy: + terry.reedy messages: + msg370356 resolution: third party stage: resolved |
2020-05-29 12:15:58 | rkm | set | nosy:
+ rkm |
2020-05-28 12:52:45 | xtreak | set | nosy:
+ xtreak |
2020-05-28 12:19:57 | Rob Taft | create |