mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-25 06:35:12 +00:00
chore: move to Ruff and add rules (#4483)
This commit is contained in:
parent
a19daeac16
commit
438034c5b8
@ -39,19 +39,6 @@ repos:
|
|||||||
- id: requirements-txt-fixer
|
- id: requirements-txt-fixer
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
|
|
||||||
# Upgrade old Python syntax
|
|
||||||
- repo: https://github.com/asottile/pyupgrade
|
|
||||||
rev: "v3.3.1"
|
|
||||||
hooks:
|
|
||||||
- id: pyupgrade
|
|
||||||
args: [--py36-plus]
|
|
||||||
|
|
||||||
# Nicely sort includes
|
|
||||||
- repo: https://github.com/PyCQA/isort
|
|
||||||
rev: "5.12.0"
|
|
||||||
hooks:
|
|
||||||
- id: isort
|
|
||||||
|
|
||||||
# Black, the code formatter, natively supports pre-commit
|
# Black, the code formatter, natively supports pre-commit
|
||||||
- repo: https://github.com/psf/black
|
- repo: https://github.com/psf/black
|
||||||
rev: "23.1.0" # Keep in sync with blacken-docs
|
rev: "23.1.0" # Keep in sync with blacken-docs
|
||||||
@ -72,47 +59,28 @@ repos:
|
|||||||
hooks:
|
hooks:
|
||||||
- id: remove-tabs
|
- id: remove-tabs
|
||||||
|
|
||||||
|
# Avoid directional quotes
|
||||||
- repo: https://github.com/sirosen/texthooks
|
- repo: https://github.com/sirosen/texthooks
|
||||||
rev: "0.5.0"
|
rev: "0.5.0"
|
||||||
hooks:
|
hooks:
|
||||||
- id: fix-ligatures
|
- id: fix-ligatures
|
||||||
- id: fix-smartquotes
|
- id: fix-smartquotes
|
||||||
|
|
||||||
# Autoremoves unused imports
|
# Ruff, the Python auto-correcting linter written in Rust
|
||||||
- repo: https://github.com/hadialqattan/pycln
|
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||||
rev: "v2.1.3"
|
rev: v0.0.251
|
||||||
hooks:
|
hooks:
|
||||||
- id: pycln
|
- id: ruff
|
||||||
stages: [manual]
|
args: ["--fix", "--show-fixes"]
|
||||||
|
|
||||||
# Checking for common mistakes
|
# Checking for common mistakes
|
||||||
- repo: https://github.com/pre-commit/pygrep-hooks
|
- repo: https://github.com/pre-commit/pygrep-hooks
|
||||||
rev: "v1.10.0"
|
rev: "v1.10.0"
|
||||||
hooks:
|
hooks:
|
||||||
- id: python-check-blanket-noqa
|
|
||||||
- id: python-check-blanket-type-ignore
|
|
||||||
- id: python-no-log-warn
|
|
||||||
- id: python-use-type-annotations
|
|
||||||
- id: rst-backticks
|
- id: rst-backticks
|
||||||
- id: rst-directive-colons
|
- id: rst-directive-colons
|
||||||
- id: rst-inline-touching-normal
|
- id: rst-inline-touching-normal
|
||||||
|
|
||||||
# Automatically remove noqa that are not used
|
|
||||||
- repo: https://github.com/asottile/yesqa
|
|
||||||
rev: "v1.4.0"
|
|
||||||
hooks:
|
|
||||||
- id: yesqa
|
|
||||||
additional_dependencies: &flake8_dependencies
|
|
||||||
- flake8-bugbear
|
|
||||||
- pep8-naming
|
|
||||||
|
|
||||||
# Flake8 also supports pre-commit natively (same author)
|
|
||||||
- repo: https://github.com/PyCQA/flake8
|
|
||||||
rev: "6.0.0"
|
|
||||||
hooks:
|
|
||||||
- id: flake8
|
|
||||||
exclude: ^(docs/.*|tools/.*)$
|
|
||||||
additional_dependencies: *flake8_dependencies
|
|
||||||
|
|
||||||
# PyLint has native support - not always usable, but works for us
|
# PyLint has native support - not always usable, but works for us
|
||||||
- repo: https://github.com/PyCQA/pylint
|
- repo: https://github.com/PyCQA/pylint
|
||||||
|
@ -353,7 +353,7 @@ def prepare(app):
|
|||||||
f.write(contents)
|
f.write(contents)
|
||||||
|
|
||||||
|
|
||||||
def clean_up(app, exception):
|
def clean_up(app, exception): # noqa: ARG001
|
||||||
(DIR / "readme.rst").unlink()
|
(DIR / "readme.rst").unlink()
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
if sys.version_info < (3, 6):
|
if sys.version_info < (3, 6): # noqa: UP036
|
||||||
msg = "pybind11 does not support Python < 3.6. 2.9 was the last release supporting Python 2.7 and 3.5."
|
msg = "pybind11 does not support Python < 3.6. 2.9 was the last release supporting Python 2.7 and 3.5."
|
||||||
raise ImportError(msg)
|
raise ImportError(msg)
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import os
|
|||||||
DIR = os.path.abspath(os.path.dirname(__file__))
|
DIR = os.path.abspath(os.path.dirname(__file__))
|
||||||
|
|
||||||
|
|
||||||
def get_include(user: bool = False) -> str: # pylint: disable=unused-argument
|
def get_include(user: bool = False) -> str: # noqa: ARG001
|
||||||
"""
|
"""
|
||||||
Return the path to the pybind11 include directory. The historical "user"
|
Return the path to the pybind11 include directory. The historical "user"
|
||||||
argument is unused, and may be removed.
|
argument is unused, and may be removed.
|
||||||
|
@ -341,7 +341,7 @@ def naive_recompile(obj: str, src: str) -> bool:
|
|||||||
return os.stat(obj).st_mtime < os.stat(src).st_mtime
|
return os.stat(obj).st_mtime < os.stat(src).st_mtime
|
||||||
|
|
||||||
|
|
||||||
def no_recompile(obg: str, src: str) -> bool: # pylint: disable=unused-argument
|
def no_recompile(obg: str, src: str) -> bool: # noqa: ARG001
|
||||||
"""
|
"""
|
||||||
This is the safest but slowest choice (and is the default) - will always
|
This is the safest but slowest choice (and is the default) - will always
|
||||||
recompile sources.
|
recompile sources.
|
||||||
|
@ -15,12 +15,6 @@ ignore = [
|
|||||||
"noxfile.py",
|
"noxfile.py",
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.isort]
|
|
||||||
# Needs the compiled .so modules and env.py from tests
|
|
||||||
known_first_party = "env,pybind11_cross_module_tests,pybind11_tests,"
|
|
||||||
# For black compatibility
|
|
||||||
profile = "black"
|
|
||||||
|
|
||||||
[tool.mypy]
|
[tool.mypy]
|
||||||
files = ["pybind11"]
|
files = ["pybind11"]
|
||||||
python_version = "3.6"
|
python_version = "3.6"
|
||||||
@ -58,4 +52,44 @@ messages_control.disable = [
|
|||||||
"invalid-name",
|
"invalid-name",
|
||||||
"protected-access",
|
"protected-access",
|
||||||
"missing-module-docstring",
|
"missing-module-docstring",
|
||||||
|
"unused-argument", # covered by Ruff ARG
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[tool.ruff]
|
||||||
|
select = [
|
||||||
|
"E", "F", "W", # flake8
|
||||||
|
"B", "B904", # flake8-bugbear
|
||||||
|
"I", # isort
|
||||||
|
"N", # pep8-naming
|
||||||
|
"ARG", # flake8-unused-arguments
|
||||||
|
"C4", # flake8-comprehensions
|
||||||
|
"EM", # flake8-errmsg
|
||||||
|
"ICN", # flake8-import-conventions
|
||||||
|
"ISC", # flake8-implicit-str-concat
|
||||||
|
"PGH", # pygrep-hooks
|
||||||
|
"PIE", # flake8-pie
|
||||||
|
"PL", # pylint
|
||||||
|
"PT", # flake8-pytest-style
|
||||||
|
"RET", # flake8-return
|
||||||
|
"RUF100", # Ruff-specific
|
||||||
|
"SIM", # flake8-simplify
|
||||||
|
"UP", # pyupgrade
|
||||||
|
"YTT", # flake8-2020
|
||||||
|
]
|
||||||
|
ignore = [
|
||||||
|
"PLR", # Design related pylint
|
||||||
|
"E501", # Line too long (Black is enough)
|
||||||
|
"PT011", # Too broad with raises in pytest
|
||||||
|
"PT004", # Fixture that doesn't return needs underscore (no, it is fine)
|
||||||
|
"SIM118",# iter(x) is not always the same as iter(x.keys())
|
||||||
|
]
|
||||||
|
target-version = "py37"
|
||||||
|
typing-modules = ["scikit_build_core._compat.typing"]
|
||||||
|
src = ["src"]
|
||||||
|
unfixable = ["T20"]
|
||||||
|
exclude = []
|
||||||
|
line-length = 120
|
||||||
|
isort.known-first-party = ["env", "pybind11_cross_module_tests", "pybind11_tests"]
|
||||||
|
|
||||||
|
[tool.ruff.per-file-ignores]
|
||||||
|
"tests/**" = ["EM", "N"]
|
||||||
|
@ -40,11 +40,3 @@ project_urls =
|
|||||||
[options]
|
[options]
|
||||||
python_requires = >=3.6
|
python_requires = >=3.6
|
||||||
zip_safe = False
|
zip_safe = False
|
||||||
|
|
||||||
|
|
||||||
[flake8]
|
|
||||||
max-line-length = 120
|
|
||||||
show_source = True
|
|
||||||
exclude = .git, __pycache__, build, dist, docs, tools, venv
|
|
||||||
extend-ignore = E203, E722
|
|
||||||
extend-select = B902, B904
|
|
||||||
|
@ -83,7 +83,6 @@ class Output:
|
|||||||
b = _strip_and_dedent(other).splitlines()
|
b = _strip_and_dedent(other).splitlines()
|
||||||
if a == b:
|
if a == b:
|
||||||
return True
|
return True
|
||||||
else:
|
|
||||||
self.explanation = _make_explanation(a, b)
|
self.explanation = _make_explanation(a, b)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -96,7 +95,6 @@ class Unordered(Output):
|
|||||||
b = _split_and_sort(other)
|
b = _split_and_sort(other)
|
||||||
if a == b:
|
if a == b:
|
||||||
return True
|
return True
|
||||||
else:
|
|
||||||
self.explanation = _make_explanation(a, b)
|
self.explanation = _make_explanation(a, b)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -119,7 +117,6 @@ class Capture:
|
|||||||
b = other
|
b = other
|
||||||
if a == b:
|
if a == b:
|
||||||
return True
|
return True
|
||||||
else:
|
|
||||||
self.explanation = a.explanation
|
self.explanation = a.explanation
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -138,7 +135,7 @@ class Capture:
|
|||||||
return Output(self.err)
|
return Output(self.err)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture()
|
||||||
def capture(capsys):
|
def capture(capsys):
|
||||||
"""Extended `capsys` with context manager and custom equality operators"""
|
"""Extended `capsys` with context manager and custom equality operators"""
|
||||||
return Capture(capsys)
|
return Capture(capsys)
|
||||||
@ -159,7 +156,6 @@ class SanitizedString:
|
|||||||
b = _strip_and_dedent(other)
|
b = _strip_and_dedent(other)
|
||||||
if a == b:
|
if a == b:
|
||||||
return True
|
return True
|
||||||
else:
|
|
||||||
self.explanation = _make_explanation(a.splitlines(), b.splitlines())
|
self.explanation = _make_explanation(a.splitlines(), b.splitlines())
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -167,17 +163,15 @@ class SanitizedString:
|
|||||||
def _sanitize_general(s):
|
def _sanitize_general(s):
|
||||||
s = s.strip()
|
s = s.strip()
|
||||||
s = s.replace("pybind11_tests.", "m.")
|
s = s.replace("pybind11_tests.", "m.")
|
||||||
s = _long_marker.sub(r"\1", s)
|
return _long_marker.sub(r"\1", s)
|
||||||
return s
|
|
||||||
|
|
||||||
|
|
||||||
def _sanitize_docstring(thing):
|
def _sanitize_docstring(thing):
|
||||||
s = thing.__doc__
|
s = thing.__doc__
|
||||||
s = _sanitize_general(s)
|
return _sanitize_general(s)
|
||||||
return s
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture()
|
||||||
def doc():
|
def doc():
|
||||||
"""Sanitize docstrings and add custom failure explanation"""
|
"""Sanitize docstrings and add custom failure explanation"""
|
||||||
return SanitizedString(_sanitize_docstring)
|
return SanitizedString(_sanitize_docstring)
|
||||||
@ -186,30 +180,20 @@ def doc():
|
|||||||
def _sanitize_message(thing):
|
def _sanitize_message(thing):
|
||||||
s = str(thing)
|
s = str(thing)
|
||||||
s = _sanitize_general(s)
|
s = _sanitize_general(s)
|
||||||
s = _hexadecimal.sub("0", s)
|
return _hexadecimal.sub("0", s)
|
||||||
return s
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture()
|
||||||
def msg():
|
def msg():
|
||||||
"""Sanitize messages and add custom failure explanation"""
|
"""Sanitize messages and add custom failure explanation"""
|
||||||
return SanitizedString(_sanitize_message)
|
return SanitizedString(_sanitize_message)
|
||||||
|
|
||||||
|
|
||||||
# noinspection PyUnusedLocal
|
def pytest_assertrepr_compare(op, left, right): # noqa: ARG001
|
||||||
def pytest_assertrepr_compare(op, left, right):
|
|
||||||
"""Hook to insert custom failure explanation"""
|
"""Hook to insert custom failure explanation"""
|
||||||
if hasattr(left, "explanation"):
|
if hasattr(left, "explanation"):
|
||||||
return left.explanation
|
return left.explanation
|
||||||
|
return None
|
||||||
|
|
||||||
@contextlib.contextmanager
|
|
||||||
def suppress(exception):
|
|
||||||
"""Suppress the desired exception"""
|
|
||||||
try:
|
|
||||||
yield
|
|
||||||
except exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def gc_collect():
|
def gc_collect():
|
||||||
@ -220,7 +204,7 @@ def gc_collect():
|
|||||||
|
|
||||||
|
|
||||||
def pytest_configure():
|
def pytest_configure():
|
||||||
pytest.suppress = suppress
|
pytest.suppress = contextlib.suppress
|
||||||
pytest.gc_collect = gc_collect
|
pytest.gc_collect = gc_collect
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,5 +24,4 @@ def deprecated_call():
|
|||||||
pytest_major_minor = (int(pieces[0]), int(pieces[1]))
|
pytest_major_minor = (int(pieces[0]), int(pieces[1]))
|
||||||
if pytest_major_minor < (3, 9):
|
if pytest_major_minor < (3, 9):
|
||||||
return pytest.warns((DeprecationWarning, PendingDeprecationWarning))
|
return pytest.warns((DeprecationWarning, PendingDeprecationWarning))
|
||||||
else:
|
|
||||||
return pytest.deprecated_call()
|
return pytest.deprecated_call()
|
||||||
|
@ -4,7 +4,7 @@ asyncio = pytest.importorskip("asyncio")
|
|||||||
m = pytest.importorskip("pybind11_tests.async_module")
|
m = pytest.importorskip("pybind11_tests.async_module")
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture()
|
||||||
def event_loop():
|
def event_loop():
|
||||||
loop = asyncio.new_event_loop()
|
loop = asyncio.new_event_loop()
|
||||||
yield loop
|
yield loop
|
||||||
@ -16,7 +16,7 @@ async def get_await_result(x):
|
|||||||
|
|
||||||
|
|
||||||
def test_await(event_loop):
|
def test_await(event_loop):
|
||||||
assert 5 == event_loop.run_until_complete(get_await_result(m.SupportsAsync()))
|
assert event_loop.run_until_complete(get_await_result(m.SupportsAsync())) == 5
|
||||||
|
|
||||||
|
|
||||||
def test_await_missing(event_loop):
|
def test_await_missing(event_loop):
|
||||||
|
@ -54,7 +54,8 @@ def test_to_python():
|
|||||||
mat2 = np.array(mat, copy=False)
|
mat2 = np.array(mat, copy=False)
|
||||||
assert mat2.shape == (5, 4)
|
assert mat2.shape == (5, 4)
|
||||||
assert abs(mat2).sum() == 11
|
assert abs(mat2).sum() == 11
|
||||||
assert mat2[2, 3] == 4 and mat2[3, 2] == 7
|
assert mat2[2, 3] == 4
|
||||||
|
assert mat2[3, 2] == 7
|
||||||
mat2[2, 3] = 5
|
mat2[2, 3] = 5
|
||||||
assert mat2[2, 3] == 5
|
assert mat2[2, 3] == 5
|
||||||
|
|
||||||
|
@ -126,8 +126,8 @@ def test_bytes_to_string():
|
|||||||
|
|
||||||
assert m.strlen(b"hi") == 2
|
assert m.strlen(b"hi") == 2
|
||||||
assert m.string_length(b"world") == 5
|
assert m.string_length(b"world") == 5
|
||||||
assert m.string_length("a\x00b".encode()) == 3
|
assert m.string_length(b"a\x00b") == 3
|
||||||
assert m.strlen("a\x00b".encode()) == 1 # C-string limitation
|
assert m.strlen(b"a\x00b") == 1 # C-string limitation
|
||||||
|
|
||||||
# passing in a utf8 encoded string should work
|
# passing in a utf8 encoded string should work
|
||||||
assert m.string_length("💩".encode()) == 4
|
assert m.string_length("💩".encode()) == 4
|
||||||
@ -421,13 +421,15 @@ def test_reference_wrapper():
|
|||||||
a2 = m.refwrap_list(copy=True)
|
a2 = m.refwrap_list(copy=True)
|
||||||
assert [x.value for x in a1] == [2, 3]
|
assert [x.value for x in a1] == [2, 3]
|
||||||
assert [x.value for x in a2] == [2, 3]
|
assert [x.value for x in a2] == [2, 3]
|
||||||
assert not a1[0] is a2[0] and not a1[1] is a2[1]
|
assert a1[0] is not a2[0]
|
||||||
|
assert a1[1] is not a2[1]
|
||||||
|
|
||||||
b1 = m.refwrap_list(copy=False)
|
b1 = m.refwrap_list(copy=False)
|
||||||
b2 = m.refwrap_list(copy=False)
|
b2 = m.refwrap_list(copy=False)
|
||||||
assert [x.value for x in b1] == [1, 2]
|
assert [x.value for x in b1] == [1, 2]
|
||||||
assert [x.value for x in b2] == [1, 2]
|
assert [x.value for x in b2] == [1, 2]
|
||||||
assert b1[0] is b2[0] and b1[1] is b2[1]
|
assert b1[0] is b2[0]
|
||||||
|
assert b1[1] is b2[1]
|
||||||
|
|
||||||
assert m.refwrap_iiw(IncType(5)) == 5
|
assert m.refwrap_iiw(IncType(5)) == 5
|
||||||
assert m.refwrap_call_iiw(IncType(10), m.refwrap_iiw) == [10, 10, 10, 10]
|
assert m.refwrap_call_iiw(IncType(10), m.refwrap_iiw) == [10, 10, 10, 10]
|
||||||
|
@ -6,10 +6,7 @@ from pybind11_tests import class_ as m
|
|||||||
|
|
||||||
|
|
||||||
def test_obj_class_name():
|
def test_obj_class_name():
|
||||||
if env.PYPY:
|
expected_name = "UserType" if env.PYPY else "pybind11_tests.UserType"
|
||||||
expected_name = "UserType"
|
|
||||||
else:
|
|
||||||
expected_name = "pybind11_tests.UserType"
|
|
||||||
assert m.obj_class_name(UserType(1)) == expected_name
|
assert m.obj_class_name(UserType(1)) == expected_name
|
||||||
assert m.obj_class_name(UserType) == expected_name
|
assert m.obj_class_name(UserType) == expected_name
|
||||||
|
|
||||||
@ -32,7 +29,7 @@ def test_instance(msg):
|
|||||||
assert cstats.alive() == 0
|
assert cstats.alive() == 0
|
||||||
|
|
||||||
|
|
||||||
def test_instance_new(msg):
|
def test_instance_new():
|
||||||
instance = m.NoConstructorNew() # .__new__(m.NoConstructor.__class__)
|
instance = m.NoConstructorNew() # .__new__(m.NoConstructor.__class__)
|
||||||
cstats = ConstructorStats.get(m.NoConstructorNew)
|
cstats = ConstructorStats.get(m.NoConstructorNew)
|
||||||
assert cstats.alive() == 1
|
assert cstats.alive() == 1
|
||||||
@ -221,7 +218,7 @@ def test_automatic_upcasting():
|
|||||||
|
|
||||||
|
|
||||||
def test_isinstance():
|
def test_isinstance():
|
||||||
objects = [tuple(), dict(), m.Pet("Polly", "parrot")] + [m.Dog("Molly")] * 4
|
objects = [(), {}, m.Pet("Polly", "parrot")] + [m.Dog("Molly")] * 4
|
||||||
expected = (True, True, True, True, True, False, False)
|
expected = (True, True, True, True, True, False, False)
|
||||||
assert m.check_instances(objects) == expected
|
assert m.check_instances(objects) == expected
|
||||||
|
|
||||||
@ -427,7 +424,7 @@ def test_exception_rvalue_abort():
|
|||||||
|
|
||||||
|
|
||||||
# https://github.com/pybind/pybind11/issues/1568
|
# https://github.com/pybind/pybind11/issues/1568
|
||||||
def test_multiple_instances_with_same_pointer(capture):
|
def test_multiple_instances_with_same_pointer():
|
||||||
n = 100
|
n = 100
|
||||||
instances = [m.SamePointer() for _ in range(n)]
|
instances = [m.SamePointer() for _ in range(n)]
|
||||||
for i in range(n):
|
for i in range(n):
|
||||||
|
@ -3,9 +3,9 @@ import pytest
|
|||||||
from pybind11_tests import const_name as m
|
from pybind11_tests import const_name as m
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("func", (m.const_name_tests, m.underscore_tests))
|
@pytest.mark.parametrize("func", [m.const_name_tests, m.underscore_tests])
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"selector, expected",
|
("selector", "expected"),
|
||||||
enumerate(
|
enumerate(
|
||||||
(
|
(
|
||||||
"",
|
"",
|
||||||
|
@ -100,7 +100,8 @@ def test_custom_caster_destruction():
|
|||||||
cstats = m.destruction_tester_cstats()
|
cstats = m.destruction_tester_cstats()
|
||||||
# This one *doesn't* have take_ownership: the pointer should be used but not destroyed:
|
# This one *doesn't* have take_ownership: the pointer should be used but not destroyed:
|
||||||
z = m.custom_caster_no_destroy()
|
z = m.custom_caster_no_destroy()
|
||||||
assert cstats.alive() == 1 and cstats.default_constructions == 1
|
assert cstats.alive() == 1
|
||||||
|
assert cstats.default_constructions == 1
|
||||||
assert z
|
assert z
|
||||||
|
|
||||||
# take_ownership applied: this constructs a new object, casts it, then destroys it:
|
# take_ownership applied: this constructs a new object, casts it, then destroys it:
|
||||||
|
@ -7,7 +7,7 @@ import env # noqa: F401
|
|||||||
from pybind11_tests import custom_type_setup as m
|
from pybind11_tests import custom_type_setup as m
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture()
|
||||||
def gc_tester():
|
def gc_tester():
|
||||||
"""Tests that an object is garbage collected.
|
"""Tests that an object is garbage collected.
|
||||||
|
|
||||||
|
@ -263,79 +263,96 @@ def test_eigen_return_references():
|
|||||||
primary = np.ones((10, 10))
|
primary = np.ones((10, 10))
|
||||||
a = m.ReturnTester()
|
a = m.ReturnTester()
|
||||||
a_get1 = a.get()
|
a_get1 = a.get()
|
||||||
assert not a_get1.flags.owndata and a_get1.flags.writeable
|
assert not a_get1.flags.owndata
|
||||||
|
assert a_get1.flags.writeable
|
||||||
assign_both(a_get1, primary, 3, 3, 5)
|
assign_both(a_get1, primary, 3, 3, 5)
|
||||||
a_get2 = a.get_ptr()
|
a_get2 = a.get_ptr()
|
||||||
assert not a_get2.flags.owndata and a_get2.flags.writeable
|
assert not a_get2.flags.owndata
|
||||||
|
assert a_get2.flags.writeable
|
||||||
assign_both(a_get1, primary, 2, 3, 6)
|
assign_both(a_get1, primary, 2, 3, 6)
|
||||||
|
|
||||||
a_view1 = a.view()
|
a_view1 = a.view()
|
||||||
assert not a_view1.flags.owndata and not a_view1.flags.writeable
|
assert not a_view1.flags.owndata
|
||||||
|
assert not a_view1.flags.writeable
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
a_view1[2, 3] = 4
|
a_view1[2, 3] = 4
|
||||||
a_view2 = a.view_ptr()
|
a_view2 = a.view_ptr()
|
||||||
assert not a_view2.flags.owndata and not a_view2.flags.writeable
|
assert not a_view2.flags.owndata
|
||||||
|
assert not a_view2.flags.writeable
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
a_view2[2, 3] = 4
|
a_view2[2, 3] = 4
|
||||||
|
|
||||||
a_copy1 = a.copy_get()
|
a_copy1 = a.copy_get()
|
||||||
assert a_copy1.flags.owndata and a_copy1.flags.writeable
|
assert a_copy1.flags.owndata
|
||||||
|
assert a_copy1.flags.writeable
|
||||||
np.testing.assert_array_equal(a_copy1, primary)
|
np.testing.assert_array_equal(a_copy1, primary)
|
||||||
a_copy1[7, 7] = -44 # Shouldn't affect anything else
|
a_copy1[7, 7] = -44 # Shouldn't affect anything else
|
||||||
c1want = array_copy_but_one(primary, 7, 7, -44)
|
c1want = array_copy_but_one(primary, 7, 7, -44)
|
||||||
a_copy2 = a.copy_view()
|
a_copy2 = a.copy_view()
|
||||||
assert a_copy2.flags.owndata and a_copy2.flags.writeable
|
assert a_copy2.flags.owndata
|
||||||
|
assert a_copy2.flags.writeable
|
||||||
np.testing.assert_array_equal(a_copy2, primary)
|
np.testing.assert_array_equal(a_copy2, primary)
|
||||||
a_copy2[4, 4] = -22 # Shouldn't affect anything else
|
a_copy2[4, 4] = -22 # Shouldn't affect anything else
|
||||||
c2want = array_copy_but_one(primary, 4, 4, -22)
|
c2want = array_copy_but_one(primary, 4, 4, -22)
|
||||||
|
|
||||||
a_ref1 = a.ref()
|
a_ref1 = a.ref()
|
||||||
assert not a_ref1.flags.owndata and a_ref1.flags.writeable
|
assert not a_ref1.flags.owndata
|
||||||
|
assert a_ref1.flags.writeable
|
||||||
assign_both(a_ref1, primary, 1, 1, 15)
|
assign_both(a_ref1, primary, 1, 1, 15)
|
||||||
a_ref2 = a.ref_const()
|
a_ref2 = a.ref_const()
|
||||||
assert not a_ref2.flags.owndata and not a_ref2.flags.writeable
|
assert not a_ref2.flags.owndata
|
||||||
|
assert not a_ref2.flags.writeable
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
a_ref2[5, 5] = 33
|
a_ref2[5, 5] = 33
|
||||||
a_ref3 = a.ref_safe()
|
a_ref3 = a.ref_safe()
|
||||||
assert not a_ref3.flags.owndata and a_ref3.flags.writeable
|
assert not a_ref3.flags.owndata
|
||||||
|
assert a_ref3.flags.writeable
|
||||||
assign_both(a_ref3, primary, 0, 7, 99)
|
assign_both(a_ref3, primary, 0, 7, 99)
|
||||||
a_ref4 = a.ref_const_safe()
|
a_ref4 = a.ref_const_safe()
|
||||||
assert not a_ref4.flags.owndata and not a_ref4.flags.writeable
|
assert not a_ref4.flags.owndata
|
||||||
|
assert not a_ref4.flags.writeable
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
a_ref4[7, 0] = 987654321
|
a_ref4[7, 0] = 987654321
|
||||||
|
|
||||||
a_copy3 = a.copy_ref()
|
a_copy3 = a.copy_ref()
|
||||||
assert a_copy3.flags.owndata and a_copy3.flags.writeable
|
assert a_copy3.flags.owndata
|
||||||
|
assert a_copy3.flags.writeable
|
||||||
np.testing.assert_array_equal(a_copy3, primary)
|
np.testing.assert_array_equal(a_copy3, primary)
|
||||||
a_copy3[8, 1] = 11
|
a_copy3[8, 1] = 11
|
||||||
c3want = array_copy_but_one(primary, 8, 1, 11)
|
c3want = array_copy_but_one(primary, 8, 1, 11)
|
||||||
a_copy4 = a.copy_ref_const()
|
a_copy4 = a.copy_ref_const()
|
||||||
assert a_copy4.flags.owndata and a_copy4.flags.writeable
|
assert a_copy4.flags.owndata
|
||||||
|
assert a_copy4.flags.writeable
|
||||||
np.testing.assert_array_equal(a_copy4, primary)
|
np.testing.assert_array_equal(a_copy4, primary)
|
||||||
a_copy4[8, 4] = 88
|
a_copy4[8, 4] = 88
|
||||||
c4want = array_copy_but_one(primary, 8, 4, 88)
|
c4want = array_copy_but_one(primary, 8, 4, 88)
|
||||||
|
|
||||||
a_block1 = a.block(3, 3, 2, 2)
|
a_block1 = a.block(3, 3, 2, 2)
|
||||||
assert not a_block1.flags.owndata and a_block1.flags.writeable
|
assert not a_block1.flags.owndata
|
||||||
|
assert a_block1.flags.writeable
|
||||||
a_block1[0, 0] = 55
|
a_block1[0, 0] = 55
|
||||||
primary[3, 3] = 55
|
primary[3, 3] = 55
|
||||||
a_block2 = a.block_safe(2, 2, 3, 2)
|
a_block2 = a.block_safe(2, 2, 3, 2)
|
||||||
assert not a_block2.flags.owndata and a_block2.flags.writeable
|
assert not a_block2.flags.owndata
|
||||||
|
assert a_block2.flags.writeable
|
||||||
a_block2[2, 1] = -123
|
a_block2[2, 1] = -123
|
||||||
primary[4, 3] = -123
|
primary[4, 3] = -123
|
||||||
a_block3 = a.block_const(6, 7, 4, 3)
|
a_block3 = a.block_const(6, 7, 4, 3)
|
||||||
assert not a_block3.flags.owndata and not a_block3.flags.writeable
|
assert not a_block3.flags.owndata
|
||||||
|
assert not a_block3.flags.writeable
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
a_block3[2, 2] = -44444
|
a_block3[2, 2] = -44444
|
||||||
|
|
||||||
a_copy5 = a.copy_block(2, 2, 2, 3)
|
a_copy5 = a.copy_block(2, 2, 2, 3)
|
||||||
assert a_copy5.flags.owndata and a_copy5.flags.writeable
|
assert a_copy5.flags.owndata
|
||||||
|
assert a_copy5.flags.writeable
|
||||||
np.testing.assert_array_equal(a_copy5, primary[2:4, 2:5])
|
np.testing.assert_array_equal(a_copy5, primary[2:4, 2:5])
|
||||||
a_copy5[1, 1] = 777
|
a_copy5[1, 1] = 777
|
||||||
c5want = array_copy_but_one(primary[2:4, 2:5], 1, 1, 777)
|
c5want = array_copy_but_one(primary[2:4, 2:5], 1, 1, 777)
|
||||||
|
|
||||||
a_corn1 = a.corners()
|
a_corn1 = a.corners()
|
||||||
assert not a_corn1.flags.owndata and a_corn1.flags.writeable
|
assert not a_corn1.flags.owndata
|
||||||
|
assert a_corn1.flags.writeable
|
||||||
a_corn1 *= 50
|
a_corn1 *= 50
|
||||||
a_corn1[1, 1] = 999
|
a_corn1[1, 1] = 999
|
||||||
primary[0, 0] = 50
|
primary[0, 0] = 50
|
||||||
@ -343,7 +360,8 @@ def test_eigen_return_references():
|
|||||||
primary[9, 0] = 50
|
primary[9, 0] = 50
|
||||||
primary[9, 9] = 999
|
primary[9, 9] = 999
|
||||||
a_corn2 = a.corners_const()
|
a_corn2 = a.corners_const()
|
||||||
assert not a_corn2.flags.owndata and not a_corn2.flags.writeable
|
assert not a_corn2.flags.owndata
|
||||||
|
assert not a_corn2.flags.writeable
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
a_corn2[1, 0] = 51
|
a_corn2[1, 0] = 51
|
||||||
|
|
||||||
@ -503,10 +521,14 @@ def test_numpy_ref_mutators():
|
|||||||
|
|
||||||
assert [zc[1, 2], zcro[1, 2], zr[1, 2], zrro[1, 2]] == [23] * 4
|
assert [zc[1, 2], zcro[1, 2], zr[1, 2], zrro[1, 2]] == [23] * 4
|
||||||
|
|
||||||
assert not zc.flags.owndata and zc.flags.writeable
|
assert not zc.flags.owndata
|
||||||
assert not zr.flags.owndata and zr.flags.writeable
|
assert zc.flags.writeable
|
||||||
assert not zcro.flags.owndata and not zcro.flags.writeable
|
assert not zr.flags.owndata
|
||||||
assert not zrro.flags.owndata and not zrro.flags.writeable
|
assert zr.flags.writeable
|
||||||
|
assert not zcro.flags.owndata
|
||||||
|
assert not zcro.flags.writeable
|
||||||
|
assert not zrro.flags.owndata
|
||||||
|
assert not zrro.flags.writeable
|
||||||
|
|
||||||
zc[1, 2] = 99
|
zc[1, 2] = 99
|
||||||
expect = np.array([[11.0, 12, 13], [21, 22, 99], [31, 32, 33]])
|
expect = np.array([[11.0, 12, 13], [21, 22, 99], [31, 32, 33]])
|
||||||
@ -530,7 +552,8 @@ def test_numpy_ref_mutators():
|
|||||||
# the const should drop away)
|
# the const should drop away)
|
||||||
y1 = np.array(m.get_cm_const_ref())
|
y1 = np.array(m.get_cm_const_ref())
|
||||||
|
|
||||||
assert y1.flags.owndata and y1.flags.writeable
|
assert y1.flags.owndata
|
||||||
|
assert y1.flags.writeable
|
||||||
# We should get copies of the eigen data, which was modified above:
|
# We should get copies of the eigen data, which was modified above:
|
||||||
assert y1[1, 2] == 99
|
assert y1[1, 2] == 99
|
||||||
y1[1, 2] += 12
|
y1[1, 2] += 12
|
||||||
@ -603,38 +626,38 @@ def test_nocopy_wrapper():
|
|||||||
# All but the second should fail with m.get_elem_nocopy:
|
# All but the second should fail with m.get_elem_nocopy:
|
||||||
with pytest.raises(TypeError) as excinfo:
|
with pytest.raises(TypeError) as excinfo:
|
||||||
m.get_elem_nocopy(int_matrix_colmajor)
|
m.get_elem_nocopy(int_matrix_colmajor)
|
||||||
assert "get_elem_nocopy(): incompatible function arguments." in str(
|
assert "get_elem_nocopy(): incompatible function arguments." in str(excinfo.value)
|
||||||
excinfo.value
|
assert ", flags.f_contiguous" in str(excinfo.value)
|
||||||
) and ", flags.f_contiguous" in str(excinfo.value)
|
|
||||||
assert m.get_elem_nocopy(dbl_matrix_colmajor) == 8
|
assert m.get_elem_nocopy(dbl_matrix_colmajor) == 8
|
||||||
with pytest.raises(TypeError) as excinfo:
|
with pytest.raises(TypeError) as excinfo:
|
||||||
m.get_elem_nocopy(int_matrix_rowmajor)
|
m.get_elem_nocopy(int_matrix_rowmajor)
|
||||||
assert "get_elem_nocopy(): incompatible function arguments." in str(
|
assert "get_elem_nocopy(): incompatible function arguments." in str(excinfo.value)
|
||||||
excinfo.value
|
assert ", flags.f_contiguous" in str(excinfo.value)
|
||||||
) and ", flags.f_contiguous" in str(excinfo.value)
|
|
||||||
with pytest.raises(TypeError) as excinfo:
|
with pytest.raises(TypeError) as excinfo:
|
||||||
m.get_elem_nocopy(dbl_matrix_rowmajor)
|
m.get_elem_nocopy(dbl_matrix_rowmajor)
|
||||||
assert "get_elem_nocopy(): incompatible function arguments." in str(
|
assert "get_elem_nocopy(): incompatible function arguments." in str(excinfo.value)
|
||||||
excinfo.value
|
assert ", flags.f_contiguous" in str(excinfo.value)
|
||||||
) and ", flags.f_contiguous" in str(excinfo.value)
|
|
||||||
|
|
||||||
# For the row-major test, we take a long matrix in row-major, so only the third is allowed:
|
# For the row-major test, we take a long matrix in row-major, so only the third is allowed:
|
||||||
with pytest.raises(TypeError) as excinfo:
|
with pytest.raises(TypeError) as excinfo:
|
||||||
m.get_elem_rm_nocopy(int_matrix_colmajor)
|
m.get_elem_rm_nocopy(int_matrix_colmajor)
|
||||||
assert "get_elem_rm_nocopy(): incompatible function arguments." in str(
|
assert "get_elem_rm_nocopy(): incompatible function arguments." in str(
|
||||||
excinfo.value
|
excinfo.value
|
||||||
) and ", flags.c_contiguous" in str(excinfo.value)
|
)
|
||||||
|
assert ", flags.c_contiguous" in str(excinfo.value)
|
||||||
with pytest.raises(TypeError) as excinfo:
|
with pytest.raises(TypeError) as excinfo:
|
||||||
m.get_elem_rm_nocopy(dbl_matrix_colmajor)
|
m.get_elem_rm_nocopy(dbl_matrix_colmajor)
|
||||||
assert "get_elem_rm_nocopy(): incompatible function arguments." in str(
|
assert "get_elem_rm_nocopy(): incompatible function arguments." in str(
|
||||||
excinfo.value
|
excinfo.value
|
||||||
) and ", flags.c_contiguous" in str(excinfo.value)
|
)
|
||||||
|
assert ", flags.c_contiguous" in str(excinfo.value)
|
||||||
assert m.get_elem_rm_nocopy(int_matrix_rowmajor) == 8
|
assert m.get_elem_rm_nocopy(int_matrix_rowmajor) == 8
|
||||||
with pytest.raises(TypeError) as excinfo:
|
with pytest.raises(TypeError) as excinfo:
|
||||||
m.get_elem_rm_nocopy(dbl_matrix_rowmajor)
|
m.get_elem_rm_nocopy(dbl_matrix_rowmajor)
|
||||||
assert "get_elem_rm_nocopy(): incompatible function arguments." in str(
|
assert "get_elem_rm_nocopy(): incompatible function arguments." in str(
|
||||||
excinfo.value
|
excinfo.value
|
||||||
) and ", flags.c_contiguous" in str(excinfo.value)
|
)
|
||||||
|
assert ", flags.c_contiguous" in str(excinfo.value)
|
||||||
|
|
||||||
|
|
||||||
def test_eigen_ref_life_support():
|
def test_eigen_ref_life_support():
|
||||||
|
@ -11,14 +11,15 @@ try:
|
|||||||
submodules += [avoid.c_style, avoid.f_style]
|
submodules += [avoid.c_style, avoid.f_style]
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
# Ensure config, build, toolchain, etc. issues are not masked here:
|
# Ensure config, build, toolchain, etc. issues are not masked here:
|
||||||
raise RuntimeError(
|
msg = (
|
||||||
"import eigen_tensor_avoid_stl_array FAILED, while "
|
"import eigen_tensor_avoid_stl_array FAILED, while "
|
||||||
"import pybind11_tests.eigen_tensor succeeded. "
|
"import pybind11_tests.eigen_tensor succeeded. "
|
||||||
"Please ensure that "
|
"Please ensure that "
|
||||||
"test_eigen_tensor.cpp & "
|
"test_eigen_tensor.cpp & "
|
||||||
"eigen_tensor_avoid_stl_array.cpp "
|
"eigen_tensor_avoid_stl_array.cpp "
|
||||||
"are built together (or both are not built if Eigen is not available)."
|
"are built together (or both are not built if Eigen is not available)."
|
||||||
) from e
|
)
|
||||||
|
raise RuntimeError(msg) from e
|
||||||
|
|
||||||
tensor_ref = np.empty((3, 5, 2), dtype=np.int64)
|
tensor_ref = np.empty((3, 5, 2), dtype=np.int64)
|
||||||
|
|
||||||
@ -147,10 +148,7 @@ def test_bad_python_to_cpp_casts(m):
|
|||||||
m.round_trip_tensor_noconvert(tensor_ref.astype(np.float64))
|
m.round_trip_tensor_noconvert(tensor_ref.astype(np.float64))
|
||||||
)
|
)
|
||||||
|
|
||||||
if m.needed_options == "F":
|
bad_options = "C" if m.needed_options == "F" else "F"
|
||||||
bad_options = "C"
|
|
||||||
else:
|
|
||||||
bad_options = "F"
|
|
||||||
# Shape, dtype and the order need to be correct for a TensorMap cast
|
# Shape, dtype and the order need to be correct for a TensorMap cast
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
TypeError, match=r"^round_trip_view_tensor\(\): incompatible function arguments"
|
TypeError, match=r"^round_trip_view_tensor\(\): incompatible function arguments"
|
||||||
@ -173,19 +171,19 @@ def test_bad_python_to_cpp_casts(m):
|
|||||||
np.zeros((3, 5), dtype=np.float64, order=m.needed_options)
|
np.zeros((3, 5), dtype=np.float64, order=m.needed_options)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
temp = np.zeros((3, 5, 2), dtype=np.float64, order=m.needed_options)
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
TypeError, match=r"^round_trip_view_tensor\(\): incompatible function arguments"
|
TypeError, match=r"^round_trip_view_tensor\(\): incompatible function arguments"
|
||||||
):
|
):
|
||||||
temp = np.zeros((3, 5, 2), dtype=np.float64, order=m.needed_options)
|
|
||||||
m.round_trip_view_tensor(
|
m.round_trip_view_tensor(
|
||||||
temp[:, ::-1, :],
|
temp[:, ::-1, :],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
temp = np.zeros((3, 5, 2), dtype=np.float64, order=m.needed_options)
|
||||||
|
temp.setflags(write=False)
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
TypeError, match=r"^round_trip_view_tensor\(\): incompatible function arguments"
|
TypeError, match=r"^round_trip_view_tensor\(\): incompatible function arguments"
|
||||||
):
|
):
|
||||||
temp = np.zeros((3, 5, 2), dtype=np.float64, order=m.needed_options)
|
|
||||||
temp.setflags(write=False)
|
|
||||||
m.round_trip_view_tensor(temp)
|
m.round_trip_view_tensor(temp)
|
||||||
|
|
||||||
|
|
||||||
@ -282,9 +280,9 @@ def test_doc_string(m, doc):
|
|||||||
order_flag = f"flags.{m.needed_options.lower()}_contiguous"
|
order_flag = f"flags.{m.needed_options.lower()}_contiguous"
|
||||||
assert doc(m.round_trip_view_tensor) == (
|
assert doc(m.round_trip_view_tensor) == (
|
||||||
f"round_trip_view_tensor(arg0: numpy.ndarray[numpy.float64[?, ?, ?], flags.writeable, {order_flag}])"
|
f"round_trip_view_tensor(arg0: numpy.ndarray[numpy.float64[?, ?, ?], flags.writeable, {order_flag}])"
|
||||||
+ f" -> numpy.ndarray[numpy.float64[?, ?, ?], flags.writeable, {order_flag}]"
|
f" -> numpy.ndarray[numpy.float64[?, ?, ?], flags.writeable, {order_flag}]"
|
||||||
)
|
)
|
||||||
assert doc(m.round_trip_const_view_tensor) == (
|
assert doc(m.round_trip_const_view_tensor) == (
|
||||||
f"round_trip_const_view_tensor(arg0: numpy.ndarray[numpy.float64[?, ?, ?], {order_flag}])"
|
f"round_trip_const_view_tensor(arg0: numpy.ndarray[numpy.float64[?, ?, ?], {order_flag}])"
|
||||||
+ " -> numpy.ndarray[numpy.float64[?, ?, ?]]"
|
" -> numpy.ndarray[numpy.float64[?, ?, ?]]"
|
||||||
)
|
)
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
# ruff: noqa: SIM201 SIM300 SIM202
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from pybind11_tests import enums as m
|
from pybind11_tests import enums as m
|
||||||
|
@ -94,7 +94,6 @@ def ignore_pytest_unraisable_warning(f):
|
|||||||
if hasattr(pytest, unraisable): # Python >= 3.8 and pytest >= 6
|
if hasattr(pytest, unraisable): # Python >= 3.8 and pytest >= 6
|
||||||
dec = pytest.mark.filterwarnings(f"ignore::pytest.{unraisable}")
|
dec = pytest.mark.filterwarnings(f"ignore::pytest.{unraisable}")
|
||||||
return dec(f)
|
return dec(f)
|
||||||
else:
|
|
||||||
return f
|
return f
|
||||||
|
|
||||||
|
|
||||||
@ -183,7 +182,7 @@ def test_custom(msg):
|
|||||||
m.throws5_1()
|
m.throws5_1()
|
||||||
assert msg(excinfo.value) == "MyException5 subclass"
|
assert msg(excinfo.value) == "MyException5 subclass"
|
||||||
|
|
||||||
with pytest.raises(m.MyException5) as excinfo:
|
with pytest.raises(m.MyException5) as excinfo: # noqa: PT012
|
||||||
try:
|
try:
|
||||||
m.throws5()
|
m.throws5()
|
||||||
except m.MyException5_1 as err:
|
except m.MyException5_1 as err:
|
||||||
@ -212,7 +211,7 @@ def test_nested_throws(capture):
|
|||||||
m.try_catch(m.MyException5, throw_myex)
|
m.try_catch(m.MyException5, throw_myex)
|
||||||
assert str(excinfo.value) == "nested error"
|
assert str(excinfo.value) == "nested error"
|
||||||
|
|
||||||
def pycatch(exctype, f, *args):
|
def pycatch(exctype, f, *args): # noqa: ARG001
|
||||||
try:
|
try:
|
||||||
f(*args)
|
f(*args)
|
||||||
except m.MyException as e:
|
except m.MyException as e:
|
||||||
@ -303,12 +302,12 @@ class FlakyException(Exception):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"exc_type, exc_value, expected_what",
|
("exc_type", "exc_value", "expected_what"),
|
||||||
(
|
[
|
||||||
(ValueError, "plain_str", "ValueError: plain_str"),
|
(ValueError, "plain_str", "ValueError: plain_str"),
|
||||||
(ValueError, ("tuple_elem",), "ValueError: tuple_elem"),
|
(ValueError, ("tuple_elem",), "ValueError: tuple_elem"),
|
||||||
(FlakyException, ("happy",), "FlakyException: FlakyException.__str__"),
|
(FlakyException, ("happy",), "FlakyException: FlakyException.__str__"),
|
||||||
),
|
],
|
||||||
)
|
)
|
||||||
def test_error_already_set_what_with_happy_exceptions(
|
def test_error_already_set_what_with_happy_exceptions(
|
||||||
exc_type, exc_value, expected_what
|
exc_type, exc_value, expected_what
|
||||||
@ -342,10 +341,7 @@ def test_flaky_exception_failure_point_str():
|
|||||||
)
|
)
|
||||||
assert not py_err_set_after_what
|
assert not py_err_set_after_what
|
||||||
lines = what.splitlines()
|
lines = what.splitlines()
|
||||||
if env.PYPY and len(lines) == 3:
|
n = 3 if env.PYPY and len(lines) == 3 else 5
|
||||||
n = 3 # Traceback is missing.
|
|
||||||
else:
|
|
||||||
n = 5
|
|
||||||
assert (
|
assert (
|
||||||
lines[:n]
|
lines[:n]
|
||||||
== [
|
== [
|
||||||
|
@ -96,7 +96,7 @@ def test_init_factory_signature(msg):
|
|||||||
3. __init__(self: m.factory_constructors.TestFactory1, arg0: m.factory_constructors.tag.pointer_tag) -> None
|
3. __init__(self: m.factory_constructors.TestFactory1, arg0: m.factory_constructors.tag.pointer_tag) -> None
|
||||||
|
|
||||||
4. __init__(self: m.factory_constructors.TestFactory1, arg0: handle, arg1: int, arg2: handle) -> None
|
4. __init__(self: m.factory_constructors.TestFactory1, arg0: handle, arg1: int, arg2: handle) -> None
|
||||||
""" # noqa: E501 line too long
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -148,10 +148,7 @@ ALL_BASIC_TESTS_PLUS_INTENTIONAL_DEADLOCK = ALL_BASIC_TESTS + (_intentional_dead
|
|||||||
|
|
||||||
|
|
||||||
def _run_in_process(target, *args, **kwargs):
|
def _run_in_process(target, *args, **kwargs):
|
||||||
if len(args) == 0:
|
test_fn = target if len(args) == 0 else args[0]
|
||||||
test_fn = target
|
|
||||||
else:
|
|
||||||
test_fn = args[0]
|
|
||||||
# Do not need to wait much, 10s should be more than enough.
|
# Do not need to wait much, 10s should be more than enough.
|
||||||
timeout = 0.1 if test_fn is _intentional_deadlock else 10
|
timeout = 0.1 if test_fn is _intentional_deadlock else 10
|
||||||
process = multiprocessing.Process(target=target, args=args, kwargs=kwargs)
|
process = multiprocessing.Process(target=target, args=args, kwargs=kwargs)
|
||||||
@ -178,7 +175,8 @@ def _run_in_process(target, *args, **kwargs):
|
|||||||
elif test_fn is _intentional_deadlock:
|
elif test_fn is _intentional_deadlock:
|
||||||
assert process.exitcode is None
|
assert process.exitcode is None
|
||||||
return 0
|
return 0
|
||||||
elif process.exitcode is None:
|
|
||||||
|
if process.exitcode is None:
|
||||||
assert t_delta > 0.9 * timeout
|
assert t_delta > 0.9 * timeout
|
||||||
msg = "DEADLOCK, most likely, exactly what this test is meant to detect."
|
msg = "DEADLOCK, most likely, exactly what this test is meant to detect."
|
||||||
if env.PYPY and env.WIN:
|
if env.PYPY and env.WIN:
|
||||||
|
@ -224,8 +224,7 @@ def test_redirect(capfd):
|
|||||||
assert stream.getvalue() == ""
|
assert stream.getvalue() == ""
|
||||||
|
|
||||||
stream = StringIO()
|
stream = StringIO()
|
||||||
with redirect_stdout(stream):
|
with redirect_stdout(stream), m.ostream_redirect():
|
||||||
with m.ostream_redirect():
|
|
||||||
m.raw_output(msg)
|
m.raw_output(msg)
|
||||||
stdout, stderr = capfd.readouterr()
|
stdout, stderr = capfd.readouterr()
|
||||||
assert stdout == ""
|
assert stdout == ""
|
||||||
@ -244,8 +243,7 @@ def test_redirect_err(capfd):
|
|||||||
msg2 = "StdErr"
|
msg2 = "StdErr"
|
||||||
|
|
||||||
stream = StringIO()
|
stream = StringIO()
|
||||||
with redirect_stderr(stream):
|
with redirect_stderr(stream), m.ostream_redirect(stdout=False):
|
||||||
with m.ostream_redirect(stdout=False):
|
|
||||||
m.raw_output(msg)
|
m.raw_output(msg)
|
||||||
m.raw_err(msg2)
|
m.raw_err(msg2)
|
||||||
stdout, stderr = capfd.readouterr()
|
stdout, stderr = capfd.readouterr()
|
||||||
@ -260,9 +258,7 @@ def test_redirect_both(capfd):
|
|||||||
|
|
||||||
stream = StringIO()
|
stream = StringIO()
|
||||||
stream2 = StringIO()
|
stream2 = StringIO()
|
||||||
with redirect_stdout(stream):
|
with redirect_stdout(stream), redirect_stderr(stream2), m.ostream_redirect():
|
||||||
with redirect_stderr(stream2):
|
|
||||||
with m.ostream_redirect():
|
|
||||||
m.raw_output(msg)
|
m.raw_output(msg)
|
||||||
m.raw_err(msg2)
|
m.raw_err(msg2)
|
||||||
stdout, stderr = capfd.readouterr()
|
stdout, stderr = capfd.readouterr()
|
||||||
|
@ -25,7 +25,7 @@ def test_function_signatures(doc):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_named_arguments(msg):
|
def test_named_arguments():
|
||||||
assert m.kw_func0(5, 10) == "x=5, y=10"
|
assert m.kw_func0(5, 10) == "x=5, y=10"
|
||||||
|
|
||||||
assert m.kw_func1(5, 10) == "x=5, y=10"
|
assert m.kw_func1(5, 10) == "x=5, y=10"
|
||||||
@ -43,8 +43,7 @@ def test_named_arguments(msg):
|
|||||||
# noinspection PyArgumentList
|
# noinspection PyArgumentList
|
||||||
m.kw_func2(x=5, y=10, z=12)
|
m.kw_func2(x=5, y=10, z=12)
|
||||||
assert excinfo.match(
|
assert excinfo.match(
|
||||||
r"(?s)^kw_func2\(\): incompatible.*Invoked with: kwargs: ((x=5|y=10|z=12)(, |$))"
|
r"(?s)^kw_func2\(\): incompatible.*Invoked with: kwargs: ((x=5|y=10|z=12)(, |$)){3}$"
|
||||||
+ "{3}$"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
assert m.kw_func4() == "{13 17}"
|
assert m.kw_func4() == "{13 17}"
|
||||||
@ -59,7 +58,7 @@ def test_arg_and_kwargs():
|
|||||||
assert m.args_function(*args) == args
|
assert m.args_function(*args) == args
|
||||||
|
|
||||||
args = "a1", "a2"
|
args = "a1", "a2"
|
||||||
kwargs = dict(arg3="a3", arg4=4)
|
kwargs = {"arg3": "a3", "arg4": 4}
|
||||||
assert m.args_kwargs_function(*args, **kwargs) == (args, kwargs)
|
assert m.args_kwargs_function(*args, **kwargs) == (args, kwargs)
|
||||||
|
|
||||||
|
|
||||||
@ -177,7 +176,7 @@ def test_mixed_args_and_kwargs(msg):
|
|||||||
|
|
||||||
assert (
|
assert (
|
||||||
m.args_kwonly_kwargs_defaults.__doc__
|
m.args_kwonly_kwargs_defaults.__doc__
|
||||||
== "args_kwonly_kwargs_defaults(i: int = 1, j: float = 3.14159, *args, z: int = 42, **kwargs) -> tuple\n" # noqa: E501 line too long
|
== "args_kwonly_kwargs_defaults(i: int = 1, j: float = 3.14159, *args, z: int = 42, **kwargs) -> tuple\n"
|
||||||
)
|
)
|
||||||
assert m.args_kwonly_kwargs_defaults() == (1, 3.14159, (), 42, {})
|
assert m.args_kwonly_kwargs_defaults() == (1, 3.14159, (), 42, {})
|
||||||
assert m.args_kwonly_kwargs_defaults(2) == (2, 3.14159, (), 42, {})
|
assert m.args_kwonly_kwargs_defaults(2) == (2, 3.14159, (), 42, {})
|
||||||
@ -233,15 +232,15 @@ def test_keyword_only_args(msg):
|
|||||||
x.method(i=1, j=2)
|
x.method(i=1, j=2)
|
||||||
assert (
|
assert (
|
||||||
m.first_arg_kw_only.__init__.__doc__
|
m.first_arg_kw_only.__init__.__doc__
|
||||||
== "__init__(self: pybind11_tests.kwargs_and_defaults.first_arg_kw_only, *, i: int = 0) -> None\n" # noqa: E501 line too long
|
== "__init__(self: pybind11_tests.kwargs_and_defaults.first_arg_kw_only, *, i: int = 0) -> None\n"
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
m.first_arg_kw_only.method.__doc__
|
m.first_arg_kw_only.method.__doc__
|
||||||
== "method(self: pybind11_tests.kwargs_and_defaults.first_arg_kw_only, *, i: int = 1, j: int = 2) -> None\n" # noqa: E501 line too long
|
== "method(self: pybind11_tests.kwargs_and_defaults.first_arg_kw_only, *, i: int = 1, j: int = 2) -> None\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_positional_only_args(msg):
|
def test_positional_only_args():
|
||||||
assert m.pos_only_all(1, 2) == (1, 2)
|
assert m.pos_only_all(1, 2) == (1, 2)
|
||||||
assert m.pos_only_all(2, 1) == (2, 1)
|
assert m.pos_only_all(2, 1) == (2, 1)
|
||||||
|
|
||||||
@ -283,7 +282,7 @@ def test_positional_only_args(msg):
|
|||||||
# Mix it with args and kwargs:
|
# Mix it with args and kwargs:
|
||||||
assert (
|
assert (
|
||||||
m.args_kwonly_full_monty.__doc__
|
m.args_kwonly_full_monty.__doc__
|
||||||
== "args_kwonly_full_monty(arg0: int = 1, arg1: int = 2, /, j: float = 3.14159, *args, z: int = 42, **kwargs) -> tuple\n" # noqa: E501 line too long
|
== "args_kwonly_full_monty(arg0: int = 1, arg1: int = 2, /, j: float = 3.14159, *args, z: int = 42, **kwargs) -> tuple\n"
|
||||||
)
|
)
|
||||||
assert m.args_kwonly_full_monty() == (1, 2, 3.14159, (), 42, {})
|
assert m.args_kwonly_full_monty() == (1, 2, 3.14159, (), 42, {})
|
||||||
assert m.args_kwonly_full_monty(8) == (8, 2, 3.14159, (), 42, {})
|
assert m.args_kwonly_full_monty(8) == (8, 2, 3.14159, (), 42, {})
|
||||||
@ -326,18 +325,18 @@ def test_positional_only_args(msg):
|
|||||||
# https://github.com/pybind/pybind11/pull/3402#issuecomment-963341987
|
# https://github.com/pybind/pybind11/pull/3402#issuecomment-963341987
|
||||||
assert (
|
assert (
|
||||||
m.first_arg_kw_only.pos_only.__doc__
|
m.first_arg_kw_only.pos_only.__doc__
|
||||||
== "pos_only(self: pybind11_tests.kwargs_and_defaults.first_arg_kw_only, /, i: int, j: int) -> None\n" # noqa: E501 line too long
|
== "pos_only(self: pybind11_tests.kwargs_and_defaults.first_arg_kw_only, /, i: int, j: int) -> None\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_signatures():
|
def test_signatures():
|
||||||
assert "kw_only_all(*, i: int, j: int) -> tuple\n" == m.kw_only_all.__doc__
|
assert m.kw_only_all.__doc__ == "kw_only_all(*, i: int, j: int) -> tuple\n"
|
||||||
assert "kw_only_mixed(i: int, *, j: int) -> tuple\n" == m.kw_only_mixed.__doc__
|
assert m.kw_only_mixed.__doc__ == "kw_only_mixed(i: int, *, j: int) -> tuple\n"
|
||||||
assert "pos_only_all(i: int, j: int, /) -> tuple\n" == m.pos_only_all.__doc__
|
assert m.pos_only_all.__doc__ == "pos_only_all(i: int, j: int, /) -> tuple\n"
|
||||||
assert "pos_only_mix(i: int, /, j: int) -> tuple\n" == m.pos_only_mix.__doc__
|
assert m.pos_only_mix.__doc__ == "pos_only_mix(i: int, /, j: int) -> tuple\n"
|
||||||
assert (
|
assert (
|
||||||
"pos_kw_only_mix(i: int, /, j: int, *, k: int) -> tuple\n"
|
m.pos_kw_only_mix.__doc__
|
||||||
== m.pos_kw_only_mix.__doc__
|
== "pos_kw_only_mix(i: int, /, j: int, *, k: int) -> tuple\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -183,9 +183,9 @@ def test_static_properties():
|
|||||||
|
|
||||||
# Only static attributes can be deleted
|
# Only static attributes can be deleted
|
||||||
del m.TestPropertiesOverride.def_readonly_static
|
del m.TestPropertiesOverride.def_readonly_static
|
||||||
|
assert hasattr(m.TestPropertiesOverride, "def_readonly_static")
|
||||||
assert (
|
assert (
|
||||||
hasattr(m.TestPropertiesOverride, "def_readonly_static")
|
m.TestPropertiesOverride.def_readonly_static
|
||||||
and m.TestPropertiesOverride.def_readonly_static
|
|
||||||
is m.TestProperties.def_readonly_static
|
is m.TestProperties.def_readonly_static
|
||||||
)
|
)
|
||||||
assert "def_readonly_static" not in m.TestPropertiesOverride.__dict__
|
assert "def_readonly_static" not in m.TestPropertiesOverride.__dict__
|
||||||
@ -256,10 +256,7 @@ def test_no_mixed_overloads():
|
|||||||
|
|
||||||
@pytest.mark.parametrize("access", ["ro", "rw", "static_ro", "static_rw"])
|
@pytest.mark.parametrize("access", ["ro", "rw", "static_ro", "static_rw"])
|
||||||
def test_property_return_value_policies(access):
|
def test_property_return_value_policies(access):
|
||||||
if not access.startswith("static"):
|
obj = m.TestPropRVP() if not access.startswith("static") else m.TestPropRVP
|
||||||
obj = m.TestPropRVP()
|
|
||||||
else:
|
|
||||||
obj = m.TestPropRVP
|
|
||||||
|
|
||||||
ref = getattr(obj, access + "_ref")
|
ref = getattr(obj, access + "_ref")
|
||||||
assert ref.value == 1
|
assert ref.value == 1
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import builtins
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
import env
|
import env
|
||||||
@ -86,12 +88,7 @@ def test_builtin_key_type():
|
|||||||
|
|
||||||
Previous versions of pybind11 would add a unicode key in python 2.
|
Previous versions of pybind11 would add a unicode key in python 2.
|
||||||
"""
|
"""
|
||||||
if hasattr(__builtins__, "keys"):
|
assert all(type(k) == str for k in dir(builtins))
|
||||||
keys = __builtins__.keys()
|
|
||||||
else: # this is to make pypy happy since builtins is different there.
|
|
||||||
keys = __builtins__.__dict__.keys()
|
|
||||||
|
|
||||||
assert {type(k) for k in keys} == {str}
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail("env.PYPY", reason="PyModule_GetName()")
|
@pytest.mark.xfail("env.PYPY", reason="PyModule_GetName()")
|
||||||
|
@ -22,7 +22,7 @@ def test_dtypes():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
@pytest.fixture()
|
||||||
def arr():
|
def arr():
|
||||||
return np.array([[1, 2, 3], [4, 5, 6]], "=u2")
|
return np.array([[1, 2, 3], [4, 5, 6]], "=u2")
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ def test_array_attributes():
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"args, ret", [([], 0), ([0], 0), ([1], 3), ([0, 1], 1), ([1, 2], 5)]
|
("args", "ret"), [([], 0), ([0], 0), ([1], 3), ([0, 1], 1), ([1, 2], 5)]
|
||||||
)
|
)
|
||||||
def test_index_offset(arr, args, ret):
|
def test_index_offset(arr, args, ret):
|
||||||
assert m.index_at(arr, *args) == ret
|
assert m.index_at(arr, *args) == ret
|
||||||
@ -93,7 +93,7 @@ def test_dim_check_fail(arr):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"args, ret",
|
("args", "ret"),
|
||||||
[
|
[
|
||||||
([], [1, 2, 3, 4, 5, 6]),
|
([], [1, 2, 3, 4, 5, 6]),
|
||||||
([1], [4, 5, 6]),
|
([1], [4, 5, 6]),
|
||||||
@ -211,12 +211,14 @@ def test_wrap():
|
|||||||
assert b[0, 0] == 1234
|
assert b[0, 0] == 1234
|
||||||
|
|
||||||
a1 = np.array([1, 2], dtype=np.int16)
|
a1 = np.array([1, 2], dtype=np.int16)
|
||||||
assert a1.flags.owndata and a1.base is None
|
assert a1.flags.owndata
|
||||||
|
assert a1.base is None
|
||||||
a2 = m.wrap(a1)
|
a2 = m.wrap(a1)
|
||||||
assert_references(a1, a2)
|
assert_references(a1, a2)
|
||||||
|
|
||||||
a1 = np.array([[1, 2], [3, 4]], dtype=np.float32, order="F")
|
a1 = np.array([[1, 2], [3, 4]], dtype=np.float32, order="F")
|
||||||
assert a1.flags.owndata and a1.base is None
|
assert a1.flags.owndata
|
||||||
|
assert a1.base is None
|
||||||
a2 = m.wrap(a1)
|
a2 = m.wrap(a1)
|
||||||
assert_references(a1, a2)
|
assert_references(a1, a2)
|
||||||
|
|
||||||
@ -451,13 +453,15 @@ def test_array_resize():
|
|||||||
try:
|
try:
|
||||||
m.array_resize3(a, 3, True)
|
m.array_resize3(a, 3, True)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
assert str(e).startswith("cannot resize an array")
|
assert str(e).startswith("cannot resize an array") # noqa: PT017
|
||||||
# transposed array doesn't own data
|
# transposed array doesn't own data
|
||||||
b = a.transpose()
|
b = a.transpose()
|
||||||
try:
|
try:
|
||||||
m.array_resize3(b, 3, False)
|
m.array_resize3(b, 3, False)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
assert str(e).startswith("cannot resize this array: it does not own its data")
|
assert str(e).startswith( # noqa: PT017
|
||||||
|
"cannot resize this array: it does not own its data"
|
||||||
|
)
|
||||||
# ... but reshape should be fine
|
# ... but reshape should be fine
|
||||||
m.array_reshape2(b)
|
m.array_reshape2(b)
|
||||||
assert b.shape == (8, 8)
|
assert b.shape == (8, 8)
|
||||||
|
@ -130,14 +130,10 @@ def test_dtype(simple_dtype):
|
|||||||
partial_nested_fmt(),
|
partial_nested_fmt(),
|
||||||
"[('a','S3'),('b','S3')]",
|
"[('a','S3'),('b','S3')]",
|
||||||
(
|
(
|
||||||
"{{'names':['a','b','c','d'],"
|
"{'names':['a','b','c','d'],"
|
||||||
+ "'formats':[('S4',(3,)),('"
|
f"'formats':[('S4',(3,)),('{e}i4',(2,)),('u1',(3,)),('{e}f4',(4,2))],"
|
||||||
+ e
|
"'offsets':[0,12,20,24],'itemsize':56}"
|
||||||
+ "i4',(2,)),('u1',(3,)),('"
|
),
|
||||||
+ e
|
|
||||||
+ "f4',(4,2))],"
|
|
||||||
+ "'offsets':[0,12,20,24],'itemsize':56}}"
|
|
||||||
).format(e=e),
|
|
||||||
"[('e1','" + e + "i8'),('e2','u1')]",
|
"[('e1','" + e + "i8'),('e2','u1')]",
|
||||||
"[('x','i1'),('y','" + e + "u8')]",
|
"[('x','i1'),('y','" + e + "u8')]",
|
||||||
"[('cflt','" + e + "c8'),('cdbl','" + e + "c16')]",
|
"[('cflt','" + e + "c8'),('cdbl','" + e + "c16')]",
|
||||||
@ -291,19 +287,17 @@ def test_array_array():
|
|||||||
|
|
||||||
arr = m.create_array_array(3)
|
arr = m.create_array_array(3)
|
||||||
assert str(arr.dtype).replace(" ", "") == (
|
assert str(arr.dtype).replace(" ", "") == (
|
||||||
"{{'names':['a','b','c','d'],"
|
"{'names':['a','b','c','d'],"
|
||||||
+ "'formats':[('S4',(3,)),('"
|
f"'formats':[('S4',(3,)),('{e}i4',(2,)),('u1',(3,)),('{e}f4',(4,2))],"
|
||||||
+ e
|
"'offsets':[0,12,20,24],'itemsize':56}"
|
||||||
+ "i4',(2,)),('u1',(3,)),('{e}f4',(4,2))],"
|
)
|
||||||
+ "'offsets':[0,12,20,24],'itemsize':56}}"
|
|
||||||
).format(e=e)
|
|
||||||
assert m.print_array_array(arr) == [
|
assert m.print_array_array(arr) == [
|
||||||
"a={{A,B,C,D},{K,L,M,N},{U,V,W,X}},b={0,1},"
|
"a={{A,B,C,D},{K,L,M,N},{U,V,W,X}},b={0,1},"
|
||||||
+ "c={0,1,2},d={{0,1},{10,11},{20,21},{30,31}}",
|
"c={0,1,2},d={{0,1},{10,11},{20,21},{30,31}}",
|
||||||
"a={{W,X,Y,Z},{G,H,I,J},{Q,R,S,T}},b={1000,1001},"
|
"a={{W,X,Y,Z},{G,H,I,J},{Q,R,S,T}},b={1000,1001},"
|
||||||
+ "c={10,11,12},d={{100,101},{110,111},{120,121},{130,131}}",
|
"c={10,11,12},d={{100,101},{110,111},{120,121},{130,131}}",
|
||||||
"a={{S,T,U,V},{C,D,E,F},{M,N,O,P}},b={2000,2001},"
|
"a={{S,T,U,V},{C,D,E,F},{M,N,O,P}},b={2000,2001},"
|
||||||
+ "c={20,21,22},d={{200,201},{210,211},{220,221},{230,231}}",
|
"c={20,21,22},d={{200,201},{210,211},{220,221},{230,231}}",
|
||||||
]
|
]
|
||||||
assert arr["a"].tolist() == [
|
assert arr["a"].tolist() == [
|
||||||
[b"ABCD", b"KLMN", b"UVWX"],
|
[b"ABCD", b"KLMN", b"UVWX"],
|
||||||
|
@ -149,7 +149,7 @@ def test_docs(doc):
|
|||||||
doc(m.vectorized_func)
|
doc(m.vectorized_func)
|
||||||
== """
|
== """
|
||||||
vectorized_func(arg0: numpy.ndarray[numpy.int32], arg1: numpy.ndarray[numpy.float32], arg2: numpy.ndarray[numpy.float64]) -> object
|
vectorized_func(arg0: numpy.ndarray[numpy.int32], arg1: numpy.ndarray[numpy.float32], arg2: numpy.ndarray[numpy.float64]) -> object
|
||||||
""" # noqa: E501 line too long
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ def test_obj_class_name():
|
|||||||
assert m.obj_class_name([]) == "list"
|
assert m.obj_class_name([]) == "list"
|
||||||
|
|
||||||
|
|
||||||
def test_handle_from_move_only_type_with_operator_PyObject(): # noqa: N802
|
def test_handle_from_move_only_type_with_operator_PyObject():
|
||||||
assert m.handle_from_move_only_type_with_operator_PyObject_ncnst()
|
assert m.handle_from_move_only_type_with_operator_PyObject_ncnst()
|
||||||
assert m.handle_from_move_only_type_with_operator_PyObject_const()
|
assert m.handle_from_move_only_type_with_operator_PyObject_const()
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ def test_iterator(doc):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"pytype, from_iter_func",
|
("pytype", "from_iter_func"),
|
||||||
[
|
[
|
||||||
(frozenset, m.get_frozenset_from_iterable),
|
(frozenset, m.get_frozenset_from_iterable),
|
||||||
(list, m.get_list_from_iterable),
|
(list, m.get_list_from_iterable),
|
||||||
@ -87,7 +87,7 @@ def test_list(capture, doc):
|
|||||||
assert doc(m.print_list) == "print_list(arg0: list) -> None"
|
assert doc(m.print_list) == "print_list(arg0: list) -> None"
|
||||||
|
|
||||||
|
|
||||||
def test_none(capture, doc):
|
def test_none(doc):
|
||||||
assert doc(m.get_none) == "get_none() -> None"
|
assert doc(m.get_none) == "get_none() -> None"
|
||||||
assert doc(m.print_none) == "print_none(arg0: None) -> None"
|
assert doc(m.print_none) == "print_none(arg0: None) -> None"
|
||||||
|
|
||||||
@ -182,10 +182,10 @@ class CustomContains:
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"arg,func",
|
("arg", "func"),
|
||||||
[
|
[
|
||||||
(set(), m.anyset_contains),
|
(set(), m.anyset_contains),
|
||||||
(dict(), m.dict_contains),
|
({}, m.dict_contains),
|
||||||
(CustomContains(), m.obj_contains),
|
(CustomContains(), m.obj_contains),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -273,7 +273,7 @@ def test_bytes(doc):
|
|||||||
assert doc(m.bytes_from_str) == "bytes_from_str() -> bytes"
|
assert doc(m.bytes_from_str) == "bytes_from_str() -> bytes"
|
||||||
|
|
||||||
|
|
||||||
def test_bytearray(doc):
|
def test_bytearray():
|
||||||
assert m.bytearray_from_char_ssize_t().decode() == "$%"
|
assert m.bytearray_from_char_ssize_t().decode() == "$%"
|
||||||
assert m.bytearray_from_char_size_t().decode() == "@$!"
|
assert m.bytearray_from_char_size_t().decode() == "@$!"
|
||||||
assert m.bytearray_from_string().decode() == "foo"
|
assert m.bytearray_from_string().decode() == "foo"
|
||||||
@ -385,7 +385,7 @@ def test_accessors():
|
|||||||
assert d["implicit_list"] == [1, 2, 3]
|
assert d["implicit_list"] == [1, 2, 3]
|
||||||
assert all(x in TestObject.__dict__ for x in d["implicit_dict"])
|
assert all(x in TestObject.__dict__ for x in d["implicit_dict"])
|
||||||
|
|
||||||
assert m.tuple_accessor(tuple()) == (0, 1, 2)
|
assert m.tuple_accessor(()) == (0, 1, 2)
|
||||||
|
|
||||||
d = m.accessor_assignment()
|
d = m.accessor_assignment()
|
||||||
assert d["get"] == 0
|
assert d["get"] == 0
|
||||||
@ -593,7 +593,7 @@ def test_issue2361():
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"method, args, fmt, expected_view",
|
("method", "args", "fmt", "expected_view"),
|
||||||
[
|
[
|
||||||
(m.test_memoryview_object, (b"red",), "B", b"red"),
|
(m.test_memoryview_object, (b"red",), "B", b"red"),
|
||||||
(m.test_memoryview_buffer_info, (b"green",), "B", b"green"),
|
(m.test_memoryview_buffer_info, (b"green",), "B", b"green"),
|
||||||
@ -651,7 +651,7 @@ def test_memoryview_from_memory():
|
|||||||
|
|
||||||
|
|
||||||
def test_builtin_functions():
|
def test_builtin_functions():
|
||||||
assert m.get_len([i for i in range(42)]) == 42
|
assert m.get_len(list(range(42))) == 42
|
||||||
with pytest.raises(TypeError) as exc_info:
|
with pytest.raises(TypeError) as exc_info:
|
||||||
m.get_len(i for i in range(42))
|
m.get_len(i for i in range(42))
|
||||||
assert str(exc_info.value) in [
|
assert str(exc_info.value) in [
|
||||||
@ -695,7 +695,7 @@ def test_pass_bytes_or_unicode_to_string_types():
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"create_weakref, create_weakref_with_callback",
|
("create_weakref", "create_weakref_with_callback"),
|
||||||
[
|
[
|
||||||
(m.weakref_from_handle, m.weakref_from_handle_and_function),
|
(m.weakref_from_handle, m.weakref_from_handle_and_function),
|
||||||
(m.weakref_from_object, m.weakref_from_object_and_function),
|
(m.weakref_from_object, m.weakref_from_object_and_function),
|
||||||
@ -710,7 +710,7 @@ def test_weakref(create_weakref, create_weakref_with_callback):
|
|||||||
|
|
||||||
callback_called = False
|
callback_called = False
|
||||||
|
|
||||||
def callback(wr):
|
def callback(_):
|
||||||
nonlocal callback_called
|
nonlocal callback_called
|
||||||
callback_called = True
|
callback_called = True
|
||||||
|
|
||||||
@ -730,7 +730,7 @@ def test_weakref(create_weakref, create_weakref_with_callback):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"create_weakref, has_callback",
|
("create_weakref", "has_callback"),
|
||||||
[
|
[
|
||||||
(m.weakref_from_handle, False),
|
(m.weakref_from_handle, False),
|
||||||
(m.weakref_from_object, False),
|
(m.weakref_from_object, False),
|
||||||
@ -748,10 +748,7 @@ def test_weakref_err(create_weakref, has_callback):
|
|||||||
ob = C()
|
ob = C()
|
||||||
# Should raise TypeError on CPython
|
# Should raise TypeError on CPython
|
||||||
with pytest.raises(TypeError) if not env.PYPY else contextlib.nullcontext():
|
with pytest.raises(TypeError) if not env.PYPY else contextlib.nullcontext():
|
||||||
if has_callback:
|
_ = create_weakref(ob, callback) if has_callback else create_weakref(ob)
|
||||||
_ = create_weakref(ob, callback)
|
|
||||||
else:
|
|
||||||
_ = create_weakref(ob)
|
|
||||||
|
|
||||||
|
|
||||||
def test_cpp_iterators():
|
def test_cpp_iterators():
|
||||||
@ -814,33 +811,36 @@ def test_populate_obj_str_attrs():
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"a,b", [("foo", "bar"), (1, 2), (1.0, 2.0), (list(range(3)), list(range(3, 6)))]
|
("a", "b"),
|
||||||
|
[("foo", "bar"), (1, 2), (1.0, 2.0), (list(range(3)), list(range(3, 6)))],
|
||||||
)
|
)
|
||||||
def test_inplace_append(a, b):
|
def test_inplace_append(a, b):
|
||||||
expected = a + b
|
expected = a + b
|
||||||
assert m.inplace_append(a, b) == expected
|
assert m.inplace_append(a, b) == expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("a,b", [(3, 2), (3.0, 2.0), (set(range(3)), set(range(2)))])
|
@pytest.mark.parametrize(
|
||||||
|
("a", "b"), [(3, 2), (3.0, 2.0), (set(range(3)), set(range(2)))]
|
||||||
|
)
|
||||||
def test_inplace_subtract(a, b):
|
def test_inplace_subtract(a, b):
|
||||||
expected = a - b
|
expected = a - b
|
||||||
assert m.inplace_subtract(a, b) == expected
|
assert m.inplace_subtract(a, b) == expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("a,b", [(3, 2), (3.0, 2.0), ([1], 3)])
|
@pytest.mark.parametrize(("a", "b"), [(3, 2), (3.0, 2.0), ([1], 3)])
|
||||||
def test_inplace_multiply(a, b):
|
def test_inplace_multiply(a, b):
|
||||||
expected = a * b
|
expected = a * b
|
||||||
assert m.inplace_multiply(a, b) == expected
|
assert m.inplace_multiply(a, b) == expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("a,b", [(6, 3), (6.0, 3.0)])
|
@pytest.mark.parametrize(("a", "b"), [(6, 3), (6.0, 3.0)])
|
||||||
def test_inplace_divide(a, b):
|
def test_inplace_divide(a, b):
|
||||||
expected = a / b
|
expected = a / b
|
||||||
assert m.inplace_divide(a, b) == expected
|
assert m.inplace_divide(a, b) == expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"a,b",
|
("a", "b"),
|
||||||
[
|
[
|
||||||
(False, True),
|
(False, True),
|
||||||
(
|
(
|
||||||
@ -857,7 +857,7 @@ def test_inplace_or(a, b):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"a,b",
|
("a", "b"),
|
||||||
[
|
[
|
||||||
(True, False),
|
(True, False),
|
||||||
(
|
(
|
||||||
@ -873,13 +873,13 @@ def test_inplace_and(a, b):
|
|||||||
assert m.inplace_and(a, b) == expected
|
assert m.inplace_and(a, b) == expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("a,b", [(8, 1), (-3, 2)])
|
@pytest.mark.parametrize(("a", "b"), [(8, 1), (-3, 2)])
|
||||||
def test_inplace_lshift(a, b):
|
def test_inplace_lshift(a, b):
|
||||||
expected = a << b
|
expected = a << b
|
||||||
assert m.inplace_lshift(a, b) == expected
|
assert m.inplace_lshift(a, b) == expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("a,b", [(8, 1), (-2, 2)])
|
@pytest.mark.parametrize(("a", "b"), [(8, 1), (-2, 2)])
|
||||||
def test_inplace_rshift(a, b):
|
def test_inplace_rshift(a, b):
|
||||||
expected = a >> b
|
expected = a >> b
|
||||||
assert m.inplace_rshift(a, b) == expected
|
assert m.inplace_rshift(a, b) == expected
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import pytest
|
import pytest
|
||||||
from pytest import approx
|
from pytest import approx # noqa: PT013
|
||||||
|
|
||||||
from pybind11_tests import ConstructorStats
|
from pybind11_tests import ConstructorStats
|
||||||
from pybind11_tests import sequences_and_iterators as m
|
from pybind11_tests import sequences_and_iterators as m
|
||||||
@ -103,7 +103,8 @@ def test_sequence():
|
|||||||
|
|
||||||
assert "Sequence" in repr(s)
|
assert "Sequence" in repr(s)
|
||||||
assert len(s) == 5
|
assert len(s) == 5
|
||||||
assert s[0] == 0 and s[3] == 0
|
assert s[0] == 0
|
||||||
|
assert s[3] == 0
|
||||||
assert 12.34 not in s
|
assert 12.34 not in s
|
||||||
s[0], s[3] = 12.34, 56.78
|
s[0], s[3] = 12.34, 56.78
|
||||||
assert 12.34 in s
|
assert 12.34 in s
|
||||||
@ -245,7 +246,7 @@ def test_iterator_rvp():
|
|||||||
|
|
||||||
def test_carray_iterator():
|
def test_carray_iterator():
|
||||||
"""#4100: Check for proper iterator overload with C-Arrays"""
|
"""#4100: Check for proper iterator overload with C-Arrays"""
|
||||||
args_gt = list(float(i) for i in range(3))
|
args_gt = [float(i) for i in range(3)]
|
||||||
arr_h = m.CArrayHolder(*args_gt)
|
arr_h = m.CArrayHolder(*args_gt)
|
||||||
args = list(arr_h)
|
args = list(arr_h)
|
||||||
assert args_gt == args
|
assert args_gt == args
|
||||||
|
@ -14,7 +14,7 @@ def test_vector(doc):
|
|||||||
|
|
||||||
assert m.cast_bool_vector() == [True, False]
|
assert m.cast_bool_vector() == [True, False]
|
||||||
assert m.load_bool_vector([True, False])
|
assert m.load_bool_vector([True, False])
|
||||||
assert m.load_bool_vector(tuple([True, False]))
|
assert m.load_bool_vector((True, False))
|
||||||
|
|
||||||
assert doc(m.cast_vector) == "cast_vector() -> List[int]"
|
assert doc(m.cast_vector) == "cast_vector() -> List[int]"
|
||||||
assert doc(m.load_vector) == "load_vector(arg0: List[int]) -> bool"
|
assert doc(m.load_vector) == "load_vector(arg0: List[int]) -> bool"
|
||||||
@ -23,7 +23,7 @@ def test_vector(doc):
|
|||||||
assert m.cast_ptr_vector() == ["lvalue", "lvalue"]
|
assert m.cast_ptr_vector() == ["lvalue", "lvalue"]
|
||||||
|
|
||||||
|
|
||||||
def test_deque(doc):
|
def test_deque():
|
||||||
"""std::deque <-> list"""
|
"""std::deque <-> list"""
|
||||||
lst = m.cast_deque()
|
lst = m.cast_deque()
|
||||||
assert lst == [1]
|
assert lst == [1]
|
||||||
@ -95,7 +95,8 @@ def test_recursive_casting():
|
|||||||
|
|
||||||
# Issue #853 test case:
|
# Issue #853 test case:
|
||||||
z = m.cast_unique_ptr_vector()
|
z = m.cast_unique_ptr_vector()
|
||||||
assert z[0].value == 7 and z[1].value == 42
|
assert z[0].value == 7
|
||||||
|
assert z[1].value == 42
|
||||||
|
|
||||||
|
|
||||||
def test_move_out_container():
|
def test_move_out_container():
|
||||||
|
@ -186,9 +186,9 @@ def test_map_string_double():
|
|||||||
um["ua"] = 1.1
|
um["ua"] = 1.1
|
||||||
um["ub"] = 2.6
|
um["ub"] = 2.6
|
||||||
|
|
||||||
assert sorted(list(um)) == ["ua", "ub"]
|
assert sorted(um) == ["ua", "ub"]
|
||||||
assert list(um.keys()) == list(um)
|
assert list(um.keys()) == list(um)
|
||||||
assert sorted(list(um.items())) == [("ua", 1.1), ("ub", 2.6)]
|
assert sorted(um.items()) == [("ua", 1.1), ("ub", 2.6)]
|
||||||
assert list(zip(um.keys(), um.values())) == list(um.items())
|
assert list(zip(um.keys(), um.values())) == list(um.items())
|
||||||
assert "UnorderedMapStringDouble" in str(um)
|
assert "UnorderedMapStringDouble" in str(um)
|
||||||
|
|
||||||
@ -304,11 +304,11 @@ def test_map_delitem():
|
|||||||
um["ua"] = 1.1
|
um["ua"] = 1.1
|
||||||
um["ub"] = 2.6
|
um["ub"] = 2.6
|
||||||
|
|
||||||
assert sorted(list(um)) == ["ua", "ub"]
|
assert sorted(um) == ["ua", "ub"]
|
||||||
assert sorted(list(um.items())) == [("ua", 1.1), ("ub", 2.6)]
|
assert sorted(um.items()) == [("ua", 1.1), ("ub", 2.6)]
|
||||||
del um["ua"]
|
del um["ua"]
|
||||||
assert sorted(list(um)) == ["ub"]
|
assert sorted(um) == ["ub"]
|
||||||
assert sorted(list(um.items())) == [("ub", 2.6)]
|
assert sorted(um.items()) == [("ub", 2.6)]
|
||||||
|
|
||||||
|
|
||||||
def test_map_view_types():
|
def test_map_view_types():
|
||||||
|
@ -192,8 +192,7 @@ def test_move_support():
|
|||||||
class NCVirtExt(m.NCVirt):
|
class NCVirtExt(m.NCVirt):
|
||||||
def get_noncopyable(self, a, b):
|
def get_noncopyable(self, a, b):
|
||||||
# Constructs and returns a new instance:
|
# Constructs and returns a new instance:
|
||||||
nc = m.NonCopyable(a * a, b * b)
|
return m.NonCopyable(a * a, b * b)
|
||||||
return nc
|
|
||||||
|
|
||||||
def get_movable(self, a, b):
|
def get_movable(self, a, b):
|
||||||
# Return a referenced copy
|
# Return a referenced copy
|
||||||
@ -256,7 +255,7 @@ def test_dispatch_issue(msg):
|
|||||||
assert m.dispatch_issue_go(b) == "Yay.."
|
assert m.dispatch_issue_go(b) == "Yay.."
|
||||||
|
|
||||||
|
|
||||||
def test_recursive_dispatch_issue(msg):
|
def test_recursive_dispatch_issue():
|
||||||
"""#3357: Recursive dispatch fails to find python function override"""
|
"""#3357: Recursive dispatch fails to find python function override"""
|
||||||
|
|
||||||
class Data(m.Data):
|
class Data(m.Data):
|
||||||
@ -269,7 +268,7 @@ def test_recursive_dispatch_issue(msg):
|
|||||||
# lambda is a workaround, which adds extra frame to the
|
# lambda is a workaround, which adds extra frame to the
|
||||||
# current CPython thread. Removing lambda reveals the bug
|
# current CPython thread. Removing lambda reveals the bug
|
||||||
# [https://github.com/pybind/pybind11/issues/3357]
|
# [https://github.com/pybind/pybind11/issues/3357]
|
||||||
(lambda: visitor(Data(first.value + second.value)))()
|
(lambda: visitor(Data(first.value + second.value)))() # noqa: PLC3002
|
||||||
|
|
||||||
class StoreResultVisitor:
|
class StoreResultVisitor:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -17,14 +17,18 @@ def run(args: List[str]) -> None:
|
|||||||
assert len(args) == 1, "codespell_errors.txt"
|
assert len(args) == 1, "codespell_errors.txt"
|
||||||
cache = {}
|
cache = {}
|
||||||
done = set()
|
done = set()
|
||||||
for line in sorted(open(args[0]).read().splitlines()):
|
with open(args[0]) as f:
|
||||||
|
lines = f.read().splitlines()
|
||||||
|
|
||||||
|
for line in sorted(lines):
|
||||||
i = line.find(" ==> ")
|
i = line.find(" ==> ")
|
||||||
if i > 0:
|
if i > 0:
|
||||||
flds = line[:i].split(":")
|
flds = line[:i].split(":")
|
||||||
if len(flds) >= 2:
|
if len(flds) >= 2:
|
||||||
filename, line_num = flds[:2]
|
filename, line_num = flds[:2]
|
||||||
if filename not in cache:
|
if filename not in cache:
|
||||||
cache[filename] = open(filename).read().splitlines()
|
with open(filename) as f:
|
||||||
|
cache[filename] = f.read().splitlines()
|
||||||
supp = cache[filename][int(line_num) - 1]
|
supp = cache[filename][int(line_num) - 1]
|
||||||
if supp not in done:
|
if supp not in done:
|
||||||
print(supp)
|
print(supp)
|
||||||
|
Loading…
Reference in New Issue
Block a user