pytest 3.2 breaks pytest.mark.parametrize with null bytes

Created on 2 Aug 2017  ·  12Comments  ·  Source: pytest-dev/pytest

(tempenv-543d64822ecc) ~/.v/tempenv-543d64822ecc ❯❯❯ pip install "pytest<3.2"
Collecting pytest<3.2
  Using cached pytest-3.1.3-py2.py3-none-any.whl
Requirement already satisfied: py>=1.4.33 in ./lib/python2.7/site-packages (from pytest<3.2)
Requirement already satisfied: setuptools in ./lib/python2.7/site-packages (from pytest<3.2)
Installing collected packages: pytest
  Found existing installation: pytest 3.2.0
    Uninstalling pytest-3.2.0:
      Successfully uninstalled pytest-3.2.0
Successfully installed pytest-3.1.3
(tempenv-543d64822ecc) ~/.v/tempenv-543d64822ecc ❯❯❯ cat test.py
import pytest


@pytest.mark.parametrize("data", ["\x00"])
def test_foo(data):
    assert data
(tempenv-543d64822ecc) ~/.v/tempenv-543d64822ecc ❯❯❯ py.test  test.py
====================================================== test session starts =======================================================
platform darwin -- Python 2.7.13, pytest-3.1.3, py-1.4.34, pluggy-0.4.0
rootdir: /Users/alex_gaynor/.virtualenvs/tempenv-543d64822ecc, inifile:
collected 1 item s

test.py .

==================================================== 1 passed in 0.01 seconds ====================================================
(tempenv-543d64822ecc) ~/.v/tempenv-543d64822ecc ❯❯❯ pip install -U pytest
Collecting pytest
  Using cached pytest-3.2.0-py2.py3-none-any.whl
Requirement already up-to-date: py>=1.4.33 in ./lib/python2.7/site-packages (from pytest)
Requirement already up-to-date: setuptools in ./lib/python2.7/site-packages (from pytest)
Installing collected packages: pytest
  Found existing installation: pytest 3.1.3
    Uninstalling pytest-3.1.3:
      Successfully uninstalled pytest-3.1.3
Successfully installed pytest-3.2.0
(tempenv-543d64822ecc) ~/.v/tempenv-543d64822ecc ❯❯❯ py.test  test.py
====================================================== test session starts =======================================================
platform darwin -- Python 2.7.13, pytest-3.2.0, py-1.4.34, pluggy-0.4.0
rootdir: /Users/alex_gaynor/.virtualenvs/tempenv-543d64822ecc, inifile:
collected 1 item s

test.py EE

============================================================= ERRORS =============================================================
_________________________________________________ ERROR at setup of test_foo[] __________________________________________________

self = {'TERM_PROGRAM_VERSION': '3.0.15', 'LOGNAME': 'alex_gaynor', 'USER': 'alex_gaynor', 'HOME': '/Users/alex_gaynor', 'PAT..._ENCODING': '0x1F5:0x0:0x0', 'PWD': '/Users/alex_gaynor/.virtualenvs/tempenv-543d64822ecc', 'COMMAND_MODE': 'unix2003'}
key = 'PYTEST_CURRENT_TEST', item = 'test.py::test_foo[\x00] (setup)'

    def __setitem__(self, key, item):
>       putenv(key, item)
E       TypeError: putenv() argument 2 must be string without null bytes, not str

lib/python2.7/os.py:473: TypeError
________________________________________________ ERROR at teardown of test_foo[] ________________________________________________

self = {'TERM_PROGRAM_VERSION': '3.0.15', 'LOGNAME': 'alex_gaynor', 'USER': 'alex_gaynor', 'HOME': '/Users/alex_gaynor', 'PAT..._ENCODING': '0x1F5:0x0:0x0', 'PWD': '/Users/alex_gaynor/.virtualenvs/tempenv-543d64822ecc', 'COMMAND_MODE': 'unix2003'}
key = 'PYTEST_CURRENT_TEST', item = 'test.py::test_foo[\x00] (teardown)'

    def __setitem__(self, key, item):
>       putenv(key, item)
E       TypeError: putenv() argument 2 must be string without null bytes, not str

lib/python2.7/os.py:473: TypeError
==================================================== 2 error in 0.07 seconds =====================================================
(tempenv-543d64822ecc) ~/.v/tempenv-543d64822ecc ❯❯❯
bug regression

All 12 comments

Thanks for the quick report @alex.

This is due to the new PYTEST_CURRENT_TEST environment variable which is set during testing. I will work on a fix ASAP.

Yeah, looks like you'll want some sort of escaping scheme. (Maybe also truncation for really long values?)

Thanks for jumping on this!

2646 is up. This fix will be released in 3.2.1.

Thanks again for the quick report!

While this is not released, a workaround is to set an id to the parametrized value:

import pytest
@pytest.mark.parametrize("data", [pytest.param("\x00", id='null')])
def test_foo(data):
    assert data

# alternatively
import pytest
@pytest.mark.parametrize("data", ["\x00"], ids=['null'])
def test_foo(data):
    assert data

This has the additional benefit of showing nicely on the terminal.

Is there a plan for when 3.2.1 will be released?

Hi @alex, I was thinking about releasing 3.2.1 next Monday/Tuesday. Is that acceptable for you guys?

@nicoddemus It actually doesn't affect us really, I'm asking because one of our distributors (Fedora Raw Hide) was complaining :-) /cc @tiran

@alex thanks. @tiran does next Monday/Tuesday work for you?

@nicoddemus sure, that's fine with me. Thanks for your fix!

For rawhide I simply removed the test case. F26 has an older pytest version.

It seems that the same issue occurs again with pytest 3.3. Our build was working fine with pytest 3.2.5 and now we get this:
> self.putenv(key, value) E ValueError: embedded null byte
Don't know if it also happens with parameterize, we are using yield_fixtures (for python 2 compatibility).

@pnbat See #2957

Was this page helpful?
0 / 5 - 0 ratings