From ebdd0d368cb53f6e8f4bafb4368332f8426f2001 Mon Sep 17 00:00:00 2001 From: Eric Cousineau Date: Fri, 14 Aug 2020 14:03:43 -0400 Subject: [PATCH] tests: Consolidate version (2 vs. 3) and platform (CPython vs. PyPy) checks (#2376) Fix logic in test_bytes_to_string Co-authored-by: Henry Schreiner --- tests/conftest.py | 16 ++++++++++------ tests/test_buffers.py | 9 +++------ tests/test_builtin_casters.py | 23 ++++++++++++++--------- tests/test_kwargs_and_defaults.py | 7 +------ tests/test_pytypes.py | 10 +++++----- tests/test_stl_binders.py | 5 ++--- 6 files changed, 35 insertions(+), 35 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index d317c49db..45a264a3a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -205,7 +205,11 @@ def pytest_configure(): from pybind11_tests.eigen import have_eigen except ImportError: have_eigen = False - pypy = platform.python_implementation() == "PyPy" + + # Provide simple `six`-like aliases. + pytest.PY2 = (sys.version_info.major == 2) + pytest.CPYTHON = (platform.python_implementation() == "CPython") + pytest.PYPY = (platform.python_implementation() == "PyPy") skipif = pytest.mark.skipif pytest.suppress = suppress @@ -215,13 +219,13 @@ def pytest_configure(): reason="eigen and/or numpy are not installed") pytest.requires_eigen_and_scipy = skipif( not have_eigen or not scipy, reason="eigen and/or scipy are not installed") - pytest.unsupported_on_pypy = skipif(pypy, reason="unsupported on PyPy") - pytest.bug_in_pypy = pytest.mark.xfail(pypy, reason="bug in PyPy") - pytest.unsupported_on_pypy3 = skipif(pypy and sys.version_info.major >= 3, + pytest.unsupported_on_pypy = skipif(pytest.PYPY, reason="unsupported on PyPy") + pytest.bug_in_pypy = pytest.mark.xfail(pytest.PYPY, reason="bug in PyPy") + pytest.unsupported_on_pypy3 = skipif(pytest.PYPY and not pytest.PY2, reason="unsupported on PyPy3") - pytest.unsupported_on_pypy_lt_6 = skipif(pypy and sys.pypy_version_info[0] < 6, + pytest.unsupported_on_pypy_lt_6 = skipif(pytest.PYPY and sys.pypy_version_info[0] < 6, reason="unsupported on PyPy<6") - pytest.unsupported_on_py2 = skipif(sys.version_info.major < 3, + pytest.unsupported_on_py2 = skipif(pytest.PY2, reason="unsupported on Python 2.x") pytest.gc_collect = gc_collect diff --git a/tests/test_buffers.py b/tests/test_buffers.py index e264311d7..db1871e6a 100644 --- a/tests/test_buffers.py +++ b/tests/test_buffers.py @@ -1,15 +1,12 @@ # -*- coding: utf-8 -*- import io import struct -import sys import pytest from pybind11_tests import buffers as m from pybind11_tests import ConstructorStats -PY3 = sys.version_info[0] >= 3 - pytestmark = pytest.requires_numpy with pytest.suppress(ImportError): @@ -98,7 +95,7 @@ def test_pointer_to_member_fn(): def test_readonly_buffer(): buf = m.BufferReadOnly(0x64) view = memoryview(buf) - assert view[0] == 0x64 if PY3 else b'd' + assert view[0] == b'd' if pytest.PY2 else 0x64 assert view.readonly @@ -106,7 +103,7 @@ def test_readonly_buffer(): def test_selective_readonly_buffer(): buf = m.BufferReadOnlySelect() - memoryview(buf)[0] = 0x64 if PY3 else b'd' + memoryview(buf)[0] = b'd' if pytest.PY2 else 0x64 assert buf.value == 0x64 io.BytesIO(b'A').readinto(buf) @@ -114,6 +111,6 @@ def test_selective_readonly_buffer(): buf.readonly = True with pytest.raises(TypeError): - memoryview(buf)[0] = 0 if PY3 else b'\0' + memoryview(buf)[0] = b'\0' if pytest.PY2 else 0 with pytest.raises(TypeError): io.BytesIO(b'1').readinto(buf) diff --git a/tests/test_builtin_casters.py b/tests/test_builtin_casters.py index af44bda71..c905766f8 100644 --- a/tests/test_builtin_casters.py +++ b/tests/test_builtin_casters.py @@ -115,13 +115,19 @@ def test_bytes_to_string(): """Tests the ability to pass bytes to C++ string-accepting functions. Note that this is one-way: the only way to return bytes to Python is via the pybind11::bytes class.""" # Issue #816 - import sys - byte = bytes if sys.version_info[0] < 3 else str - assert m.strlen(byte("hi")) == 2 - assert m.string_length(byte("world")) == 5 - assert m.string_length(byte("a\x00b")) == 3 - assert m.strlen(byte("a\x00b")) == 1 # C-string limitation + def to_bytes(s): + if pytest.PY2: + b = s + else: + b = s.encode("utf8") + assert isinstance(b, bytes) + return b + + assert m.strlen(to_bytes("hi")) == 2 + assert m.string_length(to_bytes("world")) == 5 + assert m.string_length(to_bytes("a\x00b")) == 3 + assert m.strlen(to_bytes("a\x00b")) == 1 # C-string limitation # passing in a utf8 encoded string should work assert m.string_length(u'💩'.encode("utf8")) == 4 @@ -187,12 +193,11 @@ def test_string_view(capture): def test_integer_casting(): """Issue #929 - out-of-range integer values shouldn't be accepted""" - import sys assert m.i32_str(-1) == "-1" assert m.i64_str(-1) == "-1" assert m.i32_str(2000000000) == "2000000000" assert m.u32_str(2000000000) == "2000000000" - if sys.version_info < (3,): + if pytest.PY2: assert m.i32_str(long(-1)) == "-1" # noqa: F821 undefined name 'long' assert m.i64_str(long(-1)) == "-1" # noqa: F821 undefined name 'long' assert m.i64_str(long(-999999999999)) == "-999999999999" # noqa: F821 undefined name @@ -214,7 +219,7 @@ def test_integer_casting(): m.i32_str(3000000000) assert "incompatible function arguments" in str(excinfo.value) - if sys.version_info < (3,): + if pytest.PY2: with pytest.raises(TypeError) as excinfo: m.u32_str(long(-1)) # noqa: F821 undefined name 'long' assert "incompatible function arguments" in str(excinfo.value) diff --git a/tests/test_kwargs_and_defaults.py b/tests/test_kwargs_and_defaults.py index dad40dbeb..df354ad3f 100644 --- a/tests/test_kwargs_and_defaults.py +++ b/tests/test_kwargs_and_defaults.py @@ -2,11 +2,6 @@ import pytest from pybind11_tests import kwargs_and_defaults as m -import platform -import sys - -pypy = platform.python_implementation() == "PyPy" - def test_function_signatures(doc): assert doc(m.kw_func0) == "kw_func0(arg0: int, arg1: int) -> str" @@ -151,7 +146,7 @@ def test_keyword_only_args(msg): """ -@pytest.mark.xfail(pypy and sys.version_info < (3, 0), +@pytest.mark.xfail(pytest.PYPY and pytest.PY2, reason="PyPy2 doesn't seem to double count") def test_args_refcount(): """Issue/PR #1216 - py::args elements get double-inc_ref()ed when combined with regular diff --git a/tests/test_pytypes.py b/tests/test_pytypes.py index 1c7b1dd1f..e5d8355d7 100644 --- a/tests/test_pytypes.py +++ b/tests/test_pytypes.py @@ -113,7 +113,7 @@ def test_bytes(doc): assert m.bytes_from_str().decode() == "bar" assert doc(m.bytes_from_str) == "bytes_from_str() -> {}".format( - "bytes" if sys.version_info[0] == 3 else "str" + "str" if pytest.PY2 else "bytes" ) @@ -324,7 +324,7 @@ def test_memoryview(method, args, fmt, expected_view): view = method(*args) assert isinstance(view, memoryview) assert view.format == fmt - if isinstance(expected_view, bytes) or sys.version_info[0] >= 3: + if isinstance(expected_view, bytes) or not pytest.PY2: view_as_list = list(view) else: # Using max to pick non-zero byte (big-endian vs little-endian). @@ -352,7 +352,7 @@ def test_memoryview_from_buffer_empty_shape(): view = m.test_memoryview_from_buffer_empty_shape() assert isinstance(view, memoryview) assert view.format == 'B' - if sys.version_info.major < 3: + if pytest.PY2: # Python 2 behavior is weird, but Python 3 (the future) is fine. # PyPy3 has 2: + if not pytest.PY2: assert mv[2] == 5 mv[2] = 6 else: @@ -85,7 +84,7 @@ def test_vector_buffer(): mv[2] = '\x06' assert v[2] == 6 - if sys.version_info.major > 2: + if not pytest.PY2: mv = memoryview(b) v = m.VectorUChar(mv[::2]) assert v[1] == 3