Coverage fails if mock sys.getfilesystemcoding

Issue #467 invalid
Brant Knudson
created an issue

We've got some code that does

with mock.patch('sys.getfilesystemencoding', return_value='koi8_r'): ... calls something that calls sys.getfilesystemencoding

http://git.openstack.org/cgit/openstack/oslo.utils/tree/oslo_utils/tests/tests_encodeutils.py?id=f76a96fedcf7abb155b92fdcb401abe0d92eadba#n155

When this is run with coverage, it says

File "/opt/stack/oslo.utils/.tox/cover/local/lib/python2.7/site-packages/coverage/files.py", line 137, in unicode_filename filename = filename.decode(encoding, "replace") LookupError: unknown encoding: koi8_r

If you want to recreate, get the oslo.utils code ( https://git.openstack.org/openstack/oslo.utils ) and run tox -e cover on it.

I haven't been able to figure out a way to work around this. It might help if coverage didn't try to convert the name again since the function was used before so it should have seen the filename for the function in this same test.

Comments (4)

  1. Brant Knudson reporter

    I did find a workaround, you can tell mock to return a sequence of values, so if I return the new value on the first call and then the old value on subsequent calls that ought to work. You can close this bug if you feel like it, or just add some docs or something.

  2. Ned Batchelder repo owner

    A better fix would be to narrow the focus of your mock. If you are using sys.getfilesystemencoding in your product.py file, then instead of mocking "sys.getfilesystemencoding", mock "product.sys.getfilesystemencoding". This makes it so that only your code sees the mock. Would that work?

  3. Ned Batchelder repo owner

    I'm going to close this issue. I don't think it's reasonable for coverage to try to avoid the standard library so that overly aggressive mocks will continue to work. Maybe I'm wrong. Let me know.

  4. Brant Knudson reporter

    Mocking "product.sys.getfilesystemencoding" didn't work because product.sys.getfilesystemencoding winds up changing "sys.getfilesystemencoding". I was able to get a new variable that I could override by defining a new reference in the "product" module. For example, in "product.py":

    import six _getfilesystemencoding = sys.getfilesystemencoding encoding = _getfilesystemencoding()

    then "test.py" can do:

    with mock.patch.object(product, '_getfilesystemencoding', return_value=test_value)

    Thanks!

  5. Log in to comment