Unverified Commit 6493f496 authored by Ralf W. Grosse-Kunstleve's avatar Ralf W. Grosse-Kunstleve Committed by GitHub
Browse files

Python 2 removal part 1: tests (C++ code is intentionally ~untouched) (#3688)



* `#error BYE_BYE_GOLDEN_SNAKE`

* Removing everything related to 2.7 from ci.yml

* Commenting-out Centos7

* Removing `PYTHON: 27` from .appveyor.yml

* "PY2" removal, mainly from tests. C++ code is not touched.

* Systematic removal of `u` prefix from `u"..."` and `u'...'` literals. Collateral cleanup of a couple minor other things.

* Cleaning up around case-insensitive hits for `[^a-z]py.*2` in tests/.

* Removing obsolete Python 2 mention in compiling.rst

* Proper `#error` for Python 2.

* Using PY_VERSION_HEX to guard `#error "PYTHON 2 IS NO LONGER SUPPORTED.`

* chore: bump pre-commit

* style: run pre-commit for pyupgrade 3+

* tests: use sys.version_info, not PY

* chore: more Python 2 removal

* Uncommenting Centos7 block (PR #3691 showed that it is working again).

* Update pre-commit hooks

* Fix pre-commit hook

* refactor: remove Python 2 from CMake

* refactor: remove Python 2 from setup code

* refactor: simplify, better static typing

* feat: fail with nice messages

* refactor: drop Python 2 C++ code

* docs: cleanup for Python 3

* revert: intree

revert: intree

* docs: minor touchup to py2 statement
Co-authored-by: default avatarHenry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: default avatarAaron Gokaslan <skylion.aaron@gmail.com>
parent 46dcd9bc
# -*- coding: utf-8 -*-
"""pytest configuration
Extends output capture as needed by pybind11: ignore constructors, optional unordered lines.
Adds docstring and exceptions message sanitizers: ignore Python 2 vs 3 differences.
Adds docstring and exceptions message sanitizers.
"""
import contextlib
......@@ -13,19 +12,14 @@ import textwrap
import pytest
import env
# Early diagnostic for failed imports
import pybind11_tests # noqa: F401
_unicode_marker = re.compile(r"u(\'[^\']*\')")
_long_marker = re.compile(r"([0-9])L")
_hexadecimal = re.compile(r"0x[0-9a-fA-F]+")
# Avoid collecting Python3 only files
collect_ignore = []
if env.PY2:
collect_ignore.append("test_async.py")
def _strip_and_dedent(s):
......@@ -45,7 +39,7 @@ def _make_explanation(a, b):
]
class Output(object):
class Output:
"""Basic output post-processing and comparison"""
def __init__(self, string):
......@@ -83,7 +77,7 @@ class Unordered(Output):
return False
class Capture(object):
class Capture:
def __init__(self, capfd):
self.capfd = capfd
self.out = ""
......@@ -126,7 +120,7 @@ def capture(capsys):
return Capture(capsys)
class SanitizedString(object):
class SanitizedString:
def __init__(self, sanitizer):
self.sanitizer = sanitizer
self.string = ""
......@@ -149,9 +143,7 @@ class SanitizedString(object):
def _sanitize_general(s):
s = s.strip()
s = s.replace("pybind11_tests.", "m.")
s = s.replace("unicode", "str")
s = _long_marker.sub(r"\1", s)
s = _unicode_marker.sub(r"\1", s)
return s
......
......@@ -25,31 +25,14 @@ void gil_acquire() { py::gil_scoped_acquire gil; }
constexpr char kModuleName[] = "cross_module_gil_utils";
#if PY_MAJOR_VERSION >= 3
struct PyModuleDef moduledef
= {PyModuleDef_HEAD_INIT, kModuleName, NULL, 0, NULL, NULL, NULL, NULL, NULL};
#else
PyMethodDef module_methods[] = {{NULL, NULL, 0, NULL}};
#endif
} // namespace
extern "C" PYBIND11_EXPORT
#if PY_MAJOR_VERSION >= 3
PyObject *
PyInit_cross_module_gil_utils()
#else
void
initcross_module_gil_utils()
#endif
{
extern "C" PYBIND11_EXPORT PyObject *PyInit_cross_module_gil_utils() {
PyObject *m =
#if PY_MAJOR_VERSION >= 3
PyModule_Create(&moduledef);
#else
Py_InitModule(kModuleName, module_methods);
#endif
PyObject *m = PyModule_Create(&moduledef);
if (m != NULL) {
static_assert(sizeof(&gil_acquire) == sizeof(void *),
......@@ -58,7 +41,5 @@ extern "C" PYBIND11_EXPORT
m, "gil_acquire_funcaddr", PyLong_FromVoidPtr(reinterpret_cast<void *>(&gil_acquire)));
}
#if PY_MAJOR_VERSION >= 3
return m;
#endif
}
# -*- coding: utf-8 -*-
import platform
import sys
......@@ -11,10 +10,6 @@ WIN = sys.platform.startswith("win32") or sys.platform.startswith("cygwin")
CPYTHON = platform.python_implementation() == "CPython"
PYPY = platform.python_implementation() == "PyPy"
PY2 = sys.version_info.major == 2
PY = sys.version_info
def deprecated_call():
"""
......
# -*- coding: utf-8 -*-
import contextlib
import os
import string
......@@ -64,11 +63,9 @@ py_files = {
"__init__.py",
"__main__.py",
"_version.py",
"_version.pyi",
"commands.py",
"py.typed",
"setup_helpers.py",
"setup_helpers.pyi",
}
headers = main_headers | detail_headers | stl_headers
......
# -*- coding: utf-8 -*-
import os
import subprocess
import sys
......@@ -19,7 +18,7 @@ def test_simple_setup_py(monkeypatch, tmpdir, parallel, std):
(tmpdir / "setup.py").write_text(
dedent(
u"""\
"""\
import sys
sys.path.append({MAIN_DIR!r})
......@@ -58,7 +57,7 @@ def test_simple_setup_py(monkeypatch, tmpdir, parallel, std):
(tmpdir / "main.cpp").write_text(
dedent(
u"""\
"""\
#include <pybind11/pybind11.h>
int f(int x) {
......@@ -96,7 +95,7 @@ def test_simple_setup_py(monkeypatch, tmpdir, parallel, std):
(tmpdir / "test.py").write_text(
dedent(
u"""\
"""\
import simple_setup
assert simple_setup.f(3) == 9
"""
......@@ -121,10 +120,11 @@ def test_intree_extensions(monkeypatch, tmpdir):
subdir.ensure_dir()
src = subdir / "ext.cpp"
src.ensure()
(ext,) = intree_extensions([src.relto(tmpdir)])
relpath = src.relto(tmpdir)
(ext,) = intree_extensions([relpath])
assert ext.name == "ext"
subdir.ensure("__init__.py")
(ext,) = intree_extensions([src.relto(tmpdir)])
(ext,) = intree_extensions([relpath])
assert ext.name == "dir.ext"
......
# -*- coding: utf-8 -*-
import pytest
asyncio = pytest.importorskip("asyncio")
......
# -*- coding: utf-8 -*-
import ctypes
import io
import struct
......@@ -93,16 +92,16 @@ def test_pointer_to_member_fn():
def test_readonly_buffer():
buf = m.BufferReadOnly(0x64)
view = memoryview(buf)
assert view[0] == b"d" if env.PY2 else 0x64
assert view[0] == 0x64
assert view.readonly
with pytest.raises(TypeError):
view[0] = b"\0" if env.PY2 else 0
view[0] = 0
def test_selective_readonly_buffer():
buf = m.BufferReadOnlySelect()
memoryview(buf)[0] = b"d" if env.PY2 else 0x64
memoryview(buf)[0] = 0x64
assert buf.value == 0x64
io.BytesIO(b"A").readinto(buf)
......@@ -110,7 +109,7 @@ def test_selective_readonly_buffer():
buf.readonly = True
with pytest.raises(TypeError):
memoryview(buf)[0] = b"\0" if env.PY2 else 0
memoryview(buf)[0] = 0
with pytest.raises(TypeError):
io.BytesIO(b"1").readinto(buf)
......@@ -145,9 +144,6 @@ def test_ctypes_array_2d():
assert not info.readonly
@pytest.mark.skipif(
"env.PYPY and env.PY2", reason="PyPy2 bytes buffer not reported as readonly"
)
def test_ctypes_from_buffer():
test_pystr = b"0123456789"
for pyarray in (test_pystr, bytearray(test_pystr)):
......
......@@ -110,8 +110,7 @@ TEST_SUBMODULE(builtin_casters, m) {
"def");
});
m.def("bad_utf16_string", [=]() { return std::u16string({b16, char16_t(0xd800), z16}); });
#if PY_MAJOR_VERSION >= 3
// Under Python 2.7, invalid unicode UTF-32 characters don't appear to trigger
// Under Python 2.7, invalid unicode UTF-32 characters didn't appear to trigger
// UnicodeDecodeError
m.def("bad_utf32_string", [=]() { return std::u32string({a32, char32_t(0xd800), z32}); });
if (PYBIND11_SILENCE_MSVC_C4127(sizeof(wchar_t) == 2)) {
......@@ -119,7 +118,6 @@ TEST_SUBMODULE(builtin_casters, m) {
return std::wstring({wchar_t(0x61), wchar_t(0xd800)});
});
}
#endif
m.def("u8_Z", []() -> char { return 'Z'; });
m.def("u8_eacute", []() -> char { return '\xe9'; });
m.def("u16_ibang", [=]() -> char16_t { return ib16; });
......@@ -198,12 +196,10 @@ TEST_SUBMODULE(builtin_casters, m) {
[]() { return [](py::str s) { return s; }("abc \342\200\275 def"sv); });
m.def("string_view_from_bytes",
[](const py::bytes &b) { return [](std::string_view s) { return s; }(b); });
# if PY_MAJOR_VERSION >= 3
m.def("string_view_memoryview", []() {
static constexpr auto val = "Have some \360\237\216\202"sv;
return py::memoryview::from_memory(val);
});
# endif
# ifdef PYBIND11_HAS_U8STRING
m.def("string_view8_print", [](std::u8string_view s) { py::print(s, s.size()); });
......
# -*- coding: utf-8 -*-
import sys
import pytest
import env
......@@ -12,12 +13,12 @@ def test_simple_string():
def test_unicode_conversion():
"""Tests unicode conversion and error reporting."""
assert m.good_utf8_string() == u"Say utf8‽ 🎂 𝐀"
assert m.good_utf16_string() == u"b‽🎂𝐀z"
assert m.good_utf32_string() == u"a𝐀🎂‽z"
assert m.good_wchar_string() == u"a⸘𝐀z"
assert m.good_utf8_string() == "Say utf8‽ 🎂 𝐀"
assert m.good_utf16_string() == "b‽🎂𝐀z"
assert m.good_utf32_string() == "a𝐀🎂‽z"
assert m.good_wchar_string() == "a⸘𝐀z"
if hasattr(m, "has_u8string"):
assert m.good_utf8_u8string() == u"Say utf8‽ 🎂 𝐀"
assert m.good_utf8_u8string() == "Say utf8‽ 🎂 𝐀"
with pytest.raises(UnicodeDecodeError):
m.bad_utf8_string()
......@@ -25,7 +26,7 @@ def test_unicode_conversion():
with pytest.raises(UnicodeDecodeError):
m.bad_utf16_string()
# These are provided only if they actually fail (they don't when 32-bit and under Python 2.7)
# These are provided only if they actually fail (they don't when 32-bit)
if hasattr(m, "bad_utf32_string"):
with pytest.raises(UnicodeDecodeError):
m.bad_utf32_string()
......@@ -37,10 +38,10 @@ def test_unicode_conversion():
m.bad_utf8_u8string()
assert m.u8_Z() == "Z"
assert m.u8_eacute() == u"é"
assert m.u16_ibang() == u"‽"
assert m.u32_mathbfA() == u"𝐀"
assert m.wchar_heart() == u"♥"
assert m.u8_eacute() == "é"
assert m.u16_ibang() == "‽"
assert m.u32_mathbfA() == "𝐀"
assert m.wchar_heart() == "♥"
if hasattr(m, "has_u8string"):
assert m.u8_char8_Z() == "Z"
......@@ -53,68 +54,68 @@ def test_single_char_arguments():
toolong_message = "Expected a character, but multi-character string found"
assert m.ord_char(u"a") == 0x61 # simple ASCII
assert m.ord_char_lv(u"b") == 0x62
assert m.ord_char("a") == 0x61 # simple ASCII
assert m.ord_char_lv("b") == 0x62
assert (
m.ord_char(u"é") == 0xE9
m.ord_char("é") == 0xE9
) # requires 2 bytes in utf-8, but can be stuffed in a char
with pytest.raises(ValueError) as excinfo:
assert m.ord_char(u"Ā") == 0x100 # requires 2 bytes, doesn't fit in a char
assert m.ord_char("Ā") == 0x100 # requires 2 bytes, doesn't fit in a char
assert str(excinfo.value) == toobig_message(0x100)
with pytest.raises(ValueError) as excinfo:
assert m.ord_char(u"ab")
assert m.ord_char("ab")
assert str(excinfo.value) == toolong_message
assert m.ord_char16(u"a") == 0x61
assert m.ord_char16(u"é") == 0xE9
assert m.ord_char16_lv(u"ê") == 0xEA
assert m.ord_char16(u"Ā") == 0x100
assert m.ord_char16(u"‽") == 0x203D
assert m.ord_char16(u"♥") == 0x2665
assert m.ord_char16_lv(u"♡") == 0x2661
assert m.ord_char16("a") == 0x61
assert m.ord_char16("é") == 0xE9
assert m.ord_char16_lv("ê") == 0xEA
assert m.ord_char16("Ā") == 0x100
assert m.ord_char16("‽") == 0x203D
assert m.ord_char16("♥") == 0x2665
assert m.ord_char16_lv("♡") == 0x2661
with pytest.raises(ValueError) as excinfo:
assert m.ord_char16(u"🎂") == 0x1F382 # requires surrogate pair
assert m.ord_char16("🎂") == 0x1F382 # requires surrogate pair
assert str(excinfo.value) == toobig_message(0x10000)
with pytest.raises(ValueError) as excinfo:
assert m.ord_char16(u"aa")
assert m.ord_char16("aa")
assert str(excinfo.value) == toolong_message
assert m.ord_char32(u"a") == 0x61
assert m.ord_char32(u"é") == 0xE9
assert m.ord_char32(u"Ā") == 0x100
assert m.ord_char32(u"‽") == 0x203D
assert m.ord_char32(u"♥") == 0x2665
assert m.ord_char32(u"🎂") == 0x1F382
assert m.ord_char32("a") == 0x61
assert m.ord_char32("é") == 0xE9
assert m.ord_char32("Ā") == 0x100
assert m.ord_char32("‽") == 0x203D
assert m.ord_char32("♥") == 0x2665
assert m.ord_char32("🎂") == 0x1F382
with pytest.raises(ValueError) as excinfo:
assert m.ord_char32(u"aa")
assert m.ord_char32("aa")
assert str(excinfo.value) == toolong_message
assert m.ord_wchar(u"a") == 0x61
assert m.ord_wchar(u"é") == 0xE9
assert m.ord_wchar(u"Ā") == 0x100
assert m.ord_wchar(u"‽") == 0x203D
assert m.ord_wchar(u"♥") == 0x2665
assert m.ord_wchar("a") == 0x61
assert m.ord_wchar("é") == 0xE9
assert m.ord_wchar("Ā") == 0x100
assert m.ord_wchar("‽") == 0x203D
assert m.ord_wchar("♥") == 0x2665
if m.wchar_size == 2:
with pytest.raises(ValueError) as excinfo:
assert m.ord_wchar(u"🎂") == 0x1F382 # requires surrogate pair
assert m.ord_wchar("🎂") == 0x1F382 # requires surrogate pair
assert str(excinfo.value) == toobig_message(0x10000)
else:
assert m.ord_wchar(u"🎂") == 0x1F382
assert m.ord_wchar("🎂") == 0x1F382
with pytest.raises(ValueError) as excinfo:
assert m.ord_wchar(u"aa")
assert m.ord_wchar("aa")
assert str(excinfo.value) == toolong_message
if hasattr(m, "has_u8string"):
assert m.ord_char8(u"a") == 0x61 # simple ASCII
assert m.ord_char8_lv(u"b") == 0x62
assert m.ord_char8("a") == 0x61 # simple ASCII
assert m.ord_char8_lv("b") == 0x62
assert (
m.ord_char8(u"é") == 0xE9
m.ord_char8("é") == 0xE9
) # requires 2 bytes in utf-8, but can be stuffed in a char
with pytest.raises(ValueError) as excinfo:
assert m.ord_char8(u"Ā") == 0x100 # requires 2 bytes, doesn't fit in a char
assert m.ord_char8("Ā") == 0x100 # requires 2 bytes, doesn't fit in a char
assert str(excinfo.value) == toobig_message(0x100)
with pytest.raises(ValueError) as excinfo:
assert m.ord_char8(u"ab")
assert m.ord_char8("ab")
assert str(excinfo.value) == toolong_message
......@@ -123,18 +124,13 @@ def test_bytes_to_string():
one-way: the only way to return bytes to Python is via the pybind11::bytes class."""
# Issue #816
def to_bytes(s):
b = s if env.PY2 else 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
assert m.strlen(b"hi") == 2
assert m.string_length(b"world") == 5
assert m.string_length("a\x00b".encode()) == 3
assert m.strlen("a\x00b".encode()) == 1 # C-string limitation
# passing in a utf8 encoded string should work
assert m.string_length(u"💩".encode("utf8")) == 4
assert m.string_length("💩".encode()) == 4
@pytest.mark.skipif(not hasattr(m, "has_string_view"), reason="no <string_view>")
......@@ -142,26 +138,26 @@ def test_string_view(capture):
"""Tests support for C++17 string_view arguments and return values"""
assert m.string_view_chars("Hi") == [72, 105]
assert m.string_view_chars("Hi 🎂") == [72, 105, 32, 0xF0, 0x9F, 0x8E, 0x82]
assert m.string_view16_chars(u"Hi 🎂") == [72, 105, 32, 0xD83C, 0xDF82]
assert m.string_view32_chars(u"Hi 🎂") == [72, 105, 32, 127874]
assert m.string_view16_chars("Hi 🎂") == [72, 105, 32, 0xD83C, 0xDF82]
assert m.string_view32_chars("Hi 🎂") == [72, 105, 32, 127874]
if hasattr(m, "has_u8string"):
assert m.string_view8_chars("Hi") == [72, 105]
assert m.string_view8_chars(u"Hi 🎂") == [72, 105, 32, 0xF0, 0x9F, 0x8E, 0x82]
assert m.string_view8_chars("Hi 🎂") == [72, 105, 32, 0xF0, 0x9F, 0x8E, 0x82]
assert m.string_view_return() == u"utf8 secret 🎂"
assert m.string_view16_return() == u"utf16 secret 🎂"
assert m.string_view32_return() == u"utf32 secret 🎂"
assert m.string_view_return() == "utf8 secret 🎂"
assert m.string_view16_return() == "utf16 secret 🎂"
assert m.string_view32_return() == "utf32 secret 🎂"
if hasattr(m, "has_u8string"):
assert m.string_view8_return() == u"utf8 secret 🎂"
assert m.string_view8_return() == "utf8 secret 🎂"
with capture:
m.string_view_print("Hi")
m.string_view_print("utf8 🎂")
m.string_view16_print(u"utf16 🎂")
m.string_view32_print(u"utf32 🎂")
m.string_view16_print("utf16 🎂")
m.string_view32_print("utf32 🎂")
assert (
capture
== u"""
== """
Hi 2
utf8 🎂 9
utf16 🎂 8
......@@ -171,10 +167,10 @@ def test_string_view(capture):
if hasattr(m, "has_u8string"):
with capture:
m.string_view8_print("Hi")
m.string_view8_print(u"utf8 🎂")
m.string_view8_print("utf8 🎂")
assert (
capture
== u"""
== """
Hi 2
utf8 🎂 9
"""
......@@ -183,11 +179,11 @@ def test_string_view(capture):
with capture:
m.string_view_print("Hi, ascii")
m.string_view_print("Hi, utf8 🎂")
m.string_view16_print(u"Hi, utf16 🎂")
m.string_view32_print(u"Hi, utf32 🎂")
m.string_view16_print("Hi, utf16 🎂")
m.string_view32_print("Hi, utf32 🎂")
assert (
capture
== u"""
== """
Hi, ascii 9
Hi, utf8 🎂 13
Hi, utf16 🎂 12
......@@ -197,22 +193,21 @@ def test_string_view(capture):
if hasattr(m, "has_u8string"):
with capture:
m.string_view8_print("Hi, ascii")
m.string_view8_print(u"Hi, utf8 🎂")
m.string_view8_print("Hi, utf8 🎂")
assert (
capture
== u"""
== """
Hi, ascii 9
Hi, utf8 🎂 13
"""
)
assert m.string_view_bytes() == b"abc \x80\x80 def"
assert m.string_view_str() == u"abc ‽ def"
assert m.string_view_from_bytes(u"abc ‽ def".encode("utf-8")) == u"abc ‽ def"
assert m.string_view_str() == "abc ‽ def"
assert m.string_view_from_bytes("abc ‽ def".encode()) == "abc ‽ def"
if hasattr(m, "has_u8string"):
assert m.string_view8_str() == u"abc ‽ def"
if not env.PY2:
assert m.string_view_memoryview() == "Have some 🎂".encode()
assert m.string_view8_str() == "abc ‽ def"
assert m.string_view_memoryview() == "Have some 🎂".encode()
assert m.bytes_from_type_with_both_operator_string_and_string_view() == b"success"
assert m.str_from_type_with_both_operator_string_and_string_view() == "success"
......@@ -224,20 +219,8 @@ def test_integer_casting():
assert m.i64_str(-1) == "-1"
assert m.i32_str(2000000000) == "2000000000"
assert m.u32_str(2000000000) == "2000000000"
if env.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)) # noqa: F821 undefined name 'long'
== "-999999999999"
)
assert (
m.u64_str(long(999999999999)) # noqa: F821 undefined name 'long'
== "999999999999"
)
else:
assert m.i64_str(-999999999999) == "-999999999999"
assert m.u64_str(999999999999) == "999999999999"
assert m.i64_str(-999999999999) == "-999999999999"
assert m.u64_str(999999999999) == "999999999999"
with pytest.raises(TypeError) as excinfo:
m.u32_str(-1)
......@@ -252,46 +235,38 @@ def test_integer_casting():
m.i32_str(3000000000)
assert "incompatible function arguments" in str(excinfo.value)
if env.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)
with pytest.raises(TypeError) as excinfo:
m.u64_str(long(-1)) # noqa: F821 undefined name 'long'
assert "incompatible function arguments" in str(excinfo.value)
def test_int_convert():
class Int(object):
class Int:
def __int__(self):
return 42
class NotInt(object):
class NotInt:
pass
class Float(object):
class Float:
def __float__(self):
return 41.99999
class Index(object):
class Index:
def __index__(self):
return 42
class IntAndIndex(object):
class IntAndIndex:
def __int__(self):
return 42
def __index__(self):
return 0
class RaisingTypeErrorOnIndex(object):
class RaisingTypeErrorOnIndex:
def __index__(self):
raise TypeError
def __int__(self):
return 42
class RaisingValueErrorOnIndex(object):
class RaisingValueErrorOnIndex:
def __index__(self):
raise ValueError
......@@ -311,7 +286,7 @@ def test_int_convert():
cant_convert(3.14159)
# TODO: Avoid DeprecationWarning in `PyLong_AsLong` (and similar)
# TODO: PyPy 3.8 does not behave like CPython 3.8 here yet (7.3.7)
if (3, 8) <= env.PY < (3, 10) and env.CPYTHON:
if (3, 8) <= sys.version_info < (3, 10) and env.CPYTHON:
with env.deprecated_call():
assert convert(Int()) == 42
else:
......@@ -348,7 +323,7 @@ def test_numpy_int_convert():
# TODO: Avoid DeprecationWarning in `PyLong_AsLong` (and similar)
# TODO: PyPy 3.8 does not behave like CPython 3.8 here yet (7.3.7)
# https://github.com/pybind/pybind11/issues/3408
if (3, 8) <= env.PY < (3, 10) and env.CPYTHON:
if (3, 8) <= sys.version_info < (3, 10) and env.CPYTHON:
with env.deprecated_call():
assert convert(np.float32(3.14159)) == 3
else:
......@@ -475,7 +450,7 @@ def test_bool_caster():
require_implicit(None)
assert convert(None) is False
class A(object):
class A:
def __init__(self, x):
self.x = x
......@@ -485,7 +460,7 @@ def test_bool_caster():
def __bool__(self):
return self.x
class B(object):
class B:
pass
# Arbitrary objects are not accepted
......@@ -515,17 +490,9 @@ def test_numpy_bool():
def test_int_long():
"""In Python 2, a C++ int should return a Python int rather than long
if possible: longs are not always accepted where ints are used (such
as the argument to sys.exit()). A C++ long long is always a Python
long."""
import sys
must_be_long = type(getattr(sys, "maxint", 1) + 1)
assert isinstance(m.int_cast(), int)
assert isinstance(m.long_cast(), int)
assert isinstance(m.longlong_cast(), must_be_long)
assert isinstance(m.longlong_cast(), int)
def test_void_caster_2():
......
# -*- coding: utf-8 -*-
import pytest
import env # noqa: F401
......
# -*- coding: utf-8 -*-
import time
from threading import Thread
......
# -*- coding: utf-8 -*-
import datetime
import pytest
......
# -*- coding: utf-8 -*-
import pytest
import env # noqa: F401
......@@ -7,7 +6,6 @@ from pybind11_tests import class_ as m
def test_repr():
# In Python 3.3+, repr() accesses __qualname__
assert "pybind11_type" in repr(type(UserType))
assert "UserType" in repr(UserType)
......@@ -103,8 +101,8 @@ def test_docstrings(doc):
def test_qualname(doc):
"""Tests that a properly qualified name is set in __qualname__ (even in pre-3.3, where we
backport the attribute) and that generated docstrings properly use it and the module name"""
"""Tests that a properly qualified name is set in __qualname__ and that
generated docstrings properly use it and the module name"""
assert m.NestBase.__qualname__ == "NestBase"
assert m.NestBase.Nested.__qualname__ == "NestBase.Nested"
......@@ -130,13 +128,13 @@ def test_qualname(doc):
doc(m.NestBase.Nested.fn)
== """
fn(self: m.class_.NestBase.Nested, arg0: int, arg1: m.class_.NestBase, arg2: m.class_.NestBase.Nested) -> None
""" # noqa: E501 line too long
"""
)
assert (
doc(m.NestBase.Nested.fa)
== """
fa(self: m.class_.NestBase.Nested, a: int, b: m.class_.NestBase, c: m.class_.NestBase.Nested) -> None
""" # noqa: E501 line too long
"""
)
assert m.NestBase.__module__ == "pybind11_tests.class_"
assert m.NestBase.Nested.__module__ == "pybind11_tests.class_"
......
# -*- coding: utf-8 -*-
import sys
import test_cmake_build
if str is not bytes: # If not Python2
assert isinstance(__file__, str) # Test this is properly set
assert isinstance(__file__, str) # Test this is properly set
assert test_cmake_build.add(1, 2) == 3
print("{} imports, runs, and adds: 1 + 2 = 3".format(sys.argv[1]))
# -*- coding: utf-8 -*-
import pytest
import env
from pybind11_tests import const_name as m
......@@ -25,7 +23,7 @@ from pybind11_tests import const_name as m
),
)
def test_const_name(func, selector, expected):
if isinstance(func, type(u"") if env.PY2 else str):
if isinstance(func, str):
pytest.skip(func)
text = func(selector)
assert text == expected
# -*- coding: utf-8 -*-
import pytest
m = pytest.importorskip("pybind11_tests.constants_and_functions")
......
# -*- coding: utf-8 -*-
import pytest
from pybind11_tests import copy_move_policies as m
......
# -*- coding: utf-8 -*-
import pytest
from pybind11_tests import custom_type_casters as m
......@@ -19,7 +18,7 @@ def test_noconvert_args(msg):
loading ArgInspector1 argument WITH conversion allowed. Argument value = this is b
13
loading ArgInspector2 argument WITH conversion allowed. Argument value = (default arg inspector 2)
""" # noqa: E501 line too long
"""
)
assert (
msg(a.g("this is a", "this is b", 42))
......@@ -28,7 +27,7 @@ def test_noconvert_args(msg):
loading ArgInspector1 argument WITH conversion allowed. Argument value = this is b
42
loading ArgInspector2 argument WITH conversion allowed. Argument value = (default arg inspector 2)
""" # noqa: E501 line too long
"""
)
assert (
msg(a.g("this is a", "this is b", 42, "this is d"))
......@@ -76,7 +75,7 @@ def test_noconvert_args(msg):
1. (i: int) -> int
Invoked with: 4.0
""" # noqa: E501 line too long
"""
)
assert m.ints_only(4) == 2
......
# -*- coding: utf-8 -*-
import gc
import weakref
......
# -*- coding: utf-8 -*-
from pybind11_tests import docstring_options as m
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment