aboutsummaryrefslogtreecommitdiffstats
path: root/3rdparty/pybind11/tests/test_pytypes.py
diff options
context:
space:
mode:
authorMiodrag Milanovic <mmicko@gmail.com>2021-01-02 10:15:39 +0100
committerMiodrag Milanovic <mmicko@gmail.com>2021-01-02 10:15:39 +0100
commite76cdab6dd77bad411e6ac9372ee527aff89ef17 (patch)
treee9868f05cf455336d75f33b1312d71034f8fb334 /3rdparty/pybind11/tests/test_pytypes.py
parentc6cdf30501dcb2da01361229dd66a05dad73a132 (diff)
downloadnextpnr-e76cdab6dd77bad411e6ac9372ee527aff89ef17.tar.gz
nextpnr-e76cdab6dd77bad411e6ac9372ee527aff89ef17.tar.bz2
nextpnr-e76cdab6dd77bad411e6ac9372ee527aff89ef17.zip
Update pybind11 to version 2.6.1
Diffstat (limited to '3rdparty/pybind11/tests/test_pytypes.py')
-rw-r--r--3rdparty/pybind11/tests/test_pytypes.py263
1 files changed, 244 insertions, 19 deletions
diff --git a/3rdparty/pybind11/tests/test_pytypes.py b/3rdparty/pybind11/tests/test_pytypes.py
index 0e8d6c33..9e5c302e 100644
--- a/3rdparty/pybind11/tests/test_pytypes.py
+++ b/3rdparty/pybind11/tests/test_pytypes.py
@@ -1,11 +1,26 @@
+# -*- coding: utf-8 -*-
from __future__ import division
import pytest
import sys
+import env # noqa: F401
+
from pybind11_tests import pytypes as m
from pybind11_tests import debug_enabled
+def test_int(doc):
+ assert doc(m.get_int) == "get_int() -> int"
+
+
+def test_iterator(doc):
+ assert doc(m.get_iterator) == "get_iterator() -> Iterator"
+
+
+def test_iterable(doc):
+ assert doc(m.get_iterable) == "get_iterable() -> Iterable"
+
+
def test_list(capture, doc):
with capture:
lst = m.get_list()
@@ -13,18 +28,26 @@ def test_list(capture, doc):
lst.append("value2")
m.print_list(lst)
- assert capture.unordered == """
+ assert (
+ capture.unordered
+ == """
Entry at position 0: value
list item 0: inserted-0
list item 1: overwritten
list item 2: inserted-2
list item 3: value2
"""
+ )
assert doc(m.get_list) == "get_list() -> list"
assert doc(m.print_list) == "print_list(arg0: list) -> None"
+def test_none(capture, doc):
+ assert doc(m.get_none) == "get_none() -> None"
+ assert doc(m.print_none) == "print_none(arg0: None) -> None"
+
+
def test_set(capture, doc):
s = m.get_set()
assert s == {"key1", "key2", "key3"}
@@ -32,12 +55,15 @@ def test_set(capture, doc):
with capture:
s.add("key4")
m.print_set(s)
- assert capture.unordered == """
+ assert (
+ capture.unordered
+ == """
key: key1
key: key2
key: key3
key: key4
"""
+ )
assert not m.set_contains(set([]), 42)
assert m.set_contains({42}, 42)
@@ -54,10 +80,13 @@ def test_dict(capture, doc):
with capture:
d["key2"] = "value2"
m.print_dict(d)
- assert capture.unordered == """
+ assert (
+ capture.unordered
+ == """
key: key, value=value
key: key2, value=value2
"""
+ )
assert not m.dict_contains({}, 42)
assert m.dict_contains({42: None}, 42)
@@ -84,18 +113,30 @@ def test_str(doc):
assert m.str_from_object(A()) == "this is a str"
assert m.repr_from_object(A()) == "this is a repr"
+ assert m.str_from_handle(A()) == "this is a str"
s1, s2 = m.str_format()
assert s1 == "1 + 2 = 3"
assert s1 == s2
+ malformed_utf8 = b"\x80"
+ assert m.str_from_object(malformed_utf8) is malformed_utf8 # To be fixed; see #2380
+ if env.PY2:
+ # with pytest.raises(UnicodeDecodeError):
+ # m.str_from_object(malformed_utf8)
+ with pytest.raises(UnicodeDecodeError):
+ m.str_from_handle(malformed_utf8)
+ else:
+ # assert m.str_from_object(malformed_utf8) == "b'\\x80'"
+ assert m.str_from_handle(malformed_utf8) == "b'\\x80'"
+
def test_bytes(doc):
assert m.bytes_from_string().decode() == "foo"
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 env.PY2 else "bytes"
)
@@ -105,28 +146,37 @@ def test_capsule(capture):
a = m.return_capsule_with_destructor()
del a
pytest.gc_collect()
- assert capture.unordered == """
+ assert (
+ capture.unordered
+ == """
creating capsule
destructing capsule
"""
+ )
with capture:
a = m.return_capsule_with_destructor_2()
del a
pytest.gc_collect()
- assert capture.unordered == """
+ assert (
+ capture.unordered
+ == """
creating capsule
destructing capsule: 1234
"""
+ )
with capture:
a = m.return_capsule_with_name_and_destructor()
del a
pytest.gc_collect()
- assert capture.unordered == """
+ assert (
+ capture.unordered
+ == """
created capsule (1234, 'pointer type description')
destructing capsule (1234, 'pointer type description')
"""
+ )
def test_accessors():
@@ -170,11 +220,17 @@ def test_accessors():
def test_constructors():
"""C++ default and converting constructors are equivalent to type calls in Python"""
- types = [str, bool, int, float, tuple, list, dict, set]
+ types = [bytes, str, bool, int, float, tuple, list, dict, set]
expected = {t.__name__: t() for t in types}
+ if env.PY2:
+ # Note that bytes.__name__ == 'str' in Python 2.
+ # pybind11::str is unicode even under Python 2.
+ expected["bytes"] = bytes()
+ expected["str"] = unicode() # noqa: F821
assert m.default_constructors() == expected
data = {
+ bytes: b"41", # Currently no supported or working conversions.
str: 42,
bool: "Not empty",
int: "42",
@@ -183,10 +239,15 @@ def test_constructors():
list: range(3),
dict: [("two", 2), ("one", 1), ("three", 3)],
set: [4, 4, 5, 6, 6, 6],
- memoryview: b'abc'
+ memoryview: b"abc",
}
inputs = {k.__name__: v for k, v in data.items()}
expected = {k.__name__: k(v) for k, v in data.items()}
+ if env.PY2: # Similar to the above. See comments above.
+ inputs["bytes"] = b"41"
+ inputs["str"] = 42
+ expected["bytes"] = b"41"
+ expected["str"] = u"42"
assert m.converting_constructors(inputs) == expected
assert m.cast_functions(inputs) == expected
@@ -202,21 +263,79 @@ def test_constructors():
assert noconv2[k] is expected[k]
+def test_non_converting_constructors():
+ non_converting_test_cases = [
+ ("bytes", range(10)),
+ ("none", 42),
+ ("ellipsis", 42),
+ ]
+ for t, v in non_converting_test_cases:
+ with pytest.raises(TypeError) as excinfo:
+ m.nonconverting_constructor(t, v)
+ expected_error = "Object of type '{}' is not an instance of '{}'".format(
+ type(v).__name__, t
+ )
+ assert str(excinfo.value) == expected_error
+
+
+def test_pybind11_str_raw_str():
+ # specifically to exercise pybind11::str::raw_str
+ cvt = m.convert_to_pybind11_str
+ assert cvt(u"Str") == u"Str"
+ assert cvt(b"Bytes") == u"Bytes" if env.PY2 else "b'Bytes'"
+ assert cvt(None) == u"None"
+ assert cvt(False) == u"False"
+ assert cvt(True) == u"True"
+ assert cvt(42) == u"42"
+ assert cvt(2 ** 65) == u"36893488147419103232"
+ assert cvt(-1.50) == u"-1.5"
+ assert cvt(()) == u"()"
+ assert cvt((18,)) == u"(18,)"
+ assert cvt([]) == u"[]"
+ assert cvt([28]) == u"[28]"
+ assert cvt({}) == u"{}"
+ assert cvt({3: 4}) == u"{3: 4}"
+ assert cvt(set()) == u"set([])" if env.PY2 else "set()"
+ assert cvt({3, 3}) == u"set([3])" if env.PY2 else "{3}"
+
+ valid_orig = u"DZ"
+ valid_utf8 = valid_orig.encode("utf-8")
+ valid_cvt = cvt(valid_utf8)
+ assert type(valid_cvt) == bytes # Probably surprising.
+ assert valid_cvt == b"\xc7\xb1"
+
+ malformed_utf8 = b"\x80"
+ malformed_cvt = cvt(malformed_utf8)
+ assert type(malformed_cvt) == bytes # Probably surprising.
+ assert malformed_cvt == b"\x80"
+
+
def test_implicit_casting():
"""Tests implicit casting when assigning or appending to dicts and lists."""
z = m.get_implicit_casting()
- assert z['d'] == {
- 'char*_i1': 'abc', 'char*_i2': 'abc', 'char*_e': 'abc', 'char*_p': 'abc',
- 'str_i1': 'str', 'str_i2': 'str1', 'str_e': 'str2', 'str_p': 'str3',
- 'int_i1': 42, 'int_i2': 42, 'int_e': 43, 'int_p': 44
+ assert z["d"] == {
+ "char*_i1": "abc",
+ "char*_i2": "abc",
+ "char*_e": "abc",
+ "char*_p": "abc",
+ "str_i1": "str",
+ "str_i2": "str1",
+ "str_e": "str2",
+ "str_p": "str3",
+ "int_i1": 42,
+ "int_i2": 42,
+ "int_e": 43,
+ "int_p": 44,
}
- assert z['l'] == [3, 6, 9, 12, 15]
+ assert z["l"] == [3, 6, 9, 12, 15]
def test_print(capture):
with capture:
m.print_function()
- assert capture == """
+ assert (
+ capture
+ == """
Hello, World!
1 2.0 three True -- multiple args
*args-and-a-custom-separator
@@ -224,14 +343,15 @@ def test_print(capture):
flush
py::print + str.format = this
"""
+ )
assert capture.stderr == "this goes to stderr"
with pytest.raises(RuntimeError) as excinfo:
m.print_failure()
assert str(excinfo.value) == "make_tuple(): unable to convert " + (
"argument of type 'UnregisteredType' to Python object"
- if debug_enabled else
- "arguments to Python object (compile in debug mode for details)"
+ if debug_enabled
+ else "arguments to Python object (compile in debug mode for details)"
)
@@ -253,11 +373,116 @@ def test_hash():
def test_number_protocol():
for a, b in [(1, 1), (3, 5)]:
- li = [a == b, a != b, a < b, a <= b, a > b, a >= b, a + b,
- a - b, a * b, a / b, a | b, a & b, a ^ b, a >> b, a << b]
+ li = [
+ a == b,
+ a != b,
+ a < b,
+ a <= b,
+ a > b,
+ a >= b,
+ a + b,
+ a - b,
+ a * b,
+ a / b,
+ a | b,
+ a & b,
+ a ^ b,
+ a >> b,
+ a << b,
+ ]
assert m.test_number_protocol(a, b) == li
def test_list_slicing():
li = list(range(100))
assert li[::2] == m.test_list_slicing(li)
+
+
+def test_issue2361():
+ # See issue #2361
+ assert m.issue2361_str_implicit_copy_none() == "None"
+ with pytest.raises(TypeError) as excinfo:
+ assert m.issue2361_dict_implicit_copy_none()
+ assert "'NoneType' object is not iterable" in str(excinfo.value)
+
+
+@pytest.mark.parametrize(
+ "method, args, fmt, expected_view",
+ [
+ (m.test_memoryview_object, (b"red",), "B", b"red"),
+ (m.test_memoryview_buffer_info, (b"green",), "B", b"green"),
+ (m.test_memoryview_from_buffer, (False,), "h", [3, 1, 4, 1, 5]),
+ (m.test_memoryview_from_buffer, (True,), "H", [2, 7, 1, 8]),
+ (m.test_memoryview_from_buffer_nativeformat, (), "@i", [4, 7, 5]),
+ ],
+)
+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 not env.PY2:
+ view_as_list = list(view)
+ else:
+ # Using max to pick non-zero byte (big-endian vs little-endian).
+ view_as_list = [max([ord(c) for c in s]) for s in view]
+ assert view_as_list == list(expected_view)
+
+
+@pytest.mark.xfail("env.PYPY", reason="getrefcount is not available")
+@pytest.mark.parametrize(
+ "method",
+ [
+ m.test_memoryview_object,
+ m.test_memoryview_buffer_info,
+ ],
+)
+def test_memoryview_refcount(method):
+ buf = b"\x0a\x0b\x0c\x0d"
+ ref_before = sys.getrefcount(buf)
+ view = method(buf)
+ ref_after = sys.getrefcount(buf)
+ assert ref_before < ref_after
+ assert list(view) == list(buf)
+
+
+def test_memoryview_from_buffer_empty_shape():
+ view = m.test_memoryview_from_buffer_empty_shape()
+ assert isinstance(view, memoryview)
+ assert view.format == "B"
+ if env.PY2:
+ # Python 2 behavior is weird, but Python 3 (the future) is fine.
+ # PyPy3 has <memoryview, while CPython 2 has <memory
+ assert bytes(view).startswith(b"<memory")
+ else:
+ assert bytes(view) == b""
+
+
+def test_test_memoryview_from_buffer_invalid_strides():
+ with pytest.raises(RuntimeError):
+ m.test_memoryview_from_buffer_invalid_strides()
+
+
+def test_test_memoryview_from_buffer_nullptr():
+ if env.PY2:
+ m.test_memoryview_from_buffer_nullptr()
+ else:
+ with pytest.raises(ValueError):
+ m.test_memoryview_from_buffer_nullptr()
+
+
+@pytest.mark.skipif("env.PY2")
+def test_memoryview_from_memory():
+ view = m.test_memoryview_from_memory()
+ assert isinstance(view, memoryview)
+ assert view.format == "B"
+ assert bytes(view) == b"\xff\xe1\xab\x37"
+
+
+def test_builtin_functions():
+ assert m.get_len([i for i in range(42)]) == 42
+ with pytest.raises(TypeError) as exc_info:
+ m.get_len(i for i in range(42))
+ assert str(exc_info.value) in [
+ "object of type 'generator' has no len()",
+ "'generator' has no length",
+ ] # PyPy