How Do I Patch A Sys Attribute Using A Decorator?
Solution 1:
Edit:
Yes it works. The original function returns a named tuple with major, minor and micro fields. You can mimic it by building your own named tuple. I just use a simple tuple as you access with int index instead. Problem with your code is in the way you indexed with [0] which was not right.
Edit2:
As Zaur Nasibov pointed out sys.version_info is not a function, and so my code was wrong despite looking fine with the mocks (as GenError also found). I have done a little change to fix it (see GenError answer for an alternative using PropertyMock)
import sys
from unittest.mock import patch
defmy_func():
    version = sys.version_info # removed the ()print('Detected version:', version)
    if version[0] < 3:
        print('Error: Python 3 required.')
@patch('__main__.sys')deftest_python_version(mock_sys):
        mock_sys.version_info = (3,6,2)
        my_func()
        print()
        mock_sys.version_info = (2,7,0)
        my_func()
test_python_version()
Outputs
Detected version:(3,6,2)Detected version:(2,7,0)Error:Python3required.Solution 2:
I found the answer by progmatico but it has a serious issue for me, as it requires to call sys.version_info() instead of sys.version_info which would break the code if ran normally.
Example:
#filename: a.pyimport sys
defdo_something():
    if sys.version_info > (3,5):
        print('Python 3.5 or newer')
    else:
        print('Python pre 3.5')
Now if I want to test both cases in a unit test @patch("sys.version_info") will lead to an error as given by OP. Changing do_something() to use sys.version_info() would break it if the mock is not used. 
Test file:
#filename: test_a.pyfrom unittest.mock import patch, PropertyMock
import a
@patch('a.sys')deftest_a(mock_sys):
    type(mock_sys).version_info = PropertyMock(return_value=(3,4))
    a.do_something() # will show mocked python versionSo you have to mock the sys module imported in the module a and set a PropertyMock on it.
Post a Comment for "How Do I Patch A Sys Attribute Using A Decorator?"