mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-21 20:55:11 +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: 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
|
||||
- repo: https://github.com/psf/black
|
||||
rev: "23.1.0" # Keep in sync with blacken-docs
|
||||
@ -72,47 +59,28 @@ repos:
|
||||
hooks:
|
||||
- id: remove-tabs
|
||||
|
||||
# Avoid directional quotes
|
||||
- repo: https://github.com/sirosen/texthooks
|
||||
rev: "0.5.0"
|
||||
hooks:
|
||||
- id: fix-ligatures
|
||||
- id: fix-smartquotes
|
||||
|
||||
# Autoremoves unused imports
|
||||
- repo: https://github.com/hadialqattan/pycln
|
||||
rev: "v2.1.3"
|
||||
# Ruff, the Python auto-correcting linter written in Rust
|
||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||
rev: v0.0.251
|
||||
hooks:
|
||||
- id: pycln
|
||||
stages: [manual]
|
||||
- id: ruff
|
||||
args: ["--fix", "--show-fixes"]
|
||||
|
||||
# Checking for common mistakes
|
||||
- repo: https://github.com/pre-commit/pygrep-hooks
|
||||
rev: "v1.10.0"
|
||||
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-directive-colons
|
||||
- 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
|
||||
- repo: https://github.com/PyCQA/pylint
|
||||
|
@ -353,7 +353,7 @@ def prepare(app):
|
||||
f.write(contents)
|
||||
|
||||
|
||||
def clean_up(app, exception):
|
||||
def clean_up(app, exception): # noqa: ARG001
|
||||
(DIR / "readme.rst").unlink()
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
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."
|
||||
raise ImportError(msg)
|
||||
|
||||
|
@ -3,7 +3,7 @@ import os
|
||||
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"
|
||||
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
|
||||
|
||||
|
||||
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
|
||||
recompile sources.
|
||||
|
@ -15,12 +15,6 @@ ignore = [
|
||||
"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]
|
||||
files = ["pybind11"]
|
||||
python_version = "3.6"
|
||||
@ -58,4 +52,44 @@ messages_control.disable = [
|
||||
"invalid-name",
|
||||
"protected-access",
|
||||
"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]
|
||||
python_requires = >=3.6
|
||||
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,9 +83,8 @@ class Output:
|
||||
b = _strip_and_dedent(other).splitlines()
|
||||
if a == b:
|
||||
return True
|
||||
else:
|
||||
self.explanation = _make_explanation(a, b)
|
||||
return False
|
||||
self.explanation = _make_explanation(a, b)
|
||||
return False
|
||||
|
||||
|
||||
class Unordered(Output):
|
||||
@ -96,9 +95,8 @@ class Unordered(Output):
|
||||
b = _split_and_sort(other)
|
||||
if a == b:
|
||||
return True
|
||||
else:
|
||||
self.explanation = _make_explanation(a, b)
|
||||
return False
|
||||
self.explanation = _make_explanation(a, b)
|
||||
return False
|
||||
|
||||
|
||||
class Capture:
|
||||
@ -119,9 +117,8 @@ class Capture:
|
||||
b = other
|
||||
if a == b:
|
||||
return True
|
||||
else:
|
||||
self.explanation = a.explanation
|
||||
return False
|
||||
self.explanation = a.explanation
|
||||
return False
|
||||
|
||||
def __str__(self):
|
||||
return self.out
|
||||
@ -138,7 +135,7 @@ class Capture:
|
||||
return Output(self.err)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@pytest.fixture()
|
||||
def capture(capsys):
|
||||
"""Extended `capsys` with context manager and custom equality operators"""
|
||||
return Capture(capsys)
|
||||
@ -159,25 +156,22 @@ class SanitizedString:
|
||||
b = _strip_and_dedent(other)
|
||||
if a == b:
|
||||
return True
|
||||
else:
|
||||
self.explanation = _make_explanation(a.splitlines(), b.splitlines())
|
||||
return False
|
||||
self.explanation = _make_explanation(a.splitlines(), b.splitlines())
|
||||
return False
|
||||
|
||||
|
||||
def _sanitize_general(s):
|
||||
s = s.strip()
|
||||
s = s.replace("pybind11_tests.", "m.")
|
||||
s = _long_marker.sub(r"\1", s)
|
||||
return s
|
||||
return _long_marker.sub(r"\1", s)
|
||||
|
||||
|
||||
def _sanitize_docstring(thing):
|
||||
s = thing.__doc__
|
||||
s = _sanitize_general(s)
|
||||
return s
|
||||
return _sanitize_general(s)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@pytest.fixture()
|
||||
def doc():
|
||||
"""Sanitize docstrings and add custom failure explanation"""
|
||||
return SanitizedString(_sanitize_docstring)
|
||||
@ -186,30 +180,20 @@ def doc():
|
||||
def _sanitize_message(thing):
|
||||
s = str(thing)
|
||||
s = _sanitize_general(s)
|
||||
s = _hexadecimal.sub("0", s)
|
||||
return s
|
||||
return _hexadecimal.sub("0", s)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@pytest.fixture()
|
||||
def msg():
|
||||
"""Sanitize messages and add custom failure explanation"""
|
||||
return SanitizedString(_sanitize_message)
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal
|
||||
def pytest_assertrepr_compare(op, left, right):
|
||||
def pytest_assertrepr_compare(op, left, right): # noqa: ARG001
|
||||
"""Hook to insert custom failure explanation"""
|
||||
if hasattr(left, "explanation"):
|
||||
return left.explanation
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def suppress(exception):
|
||||
"""Suppress the desired exception"""
|
||||
try:
|
||||
yield
|
||||
except exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
def gc_collect():
|
||||
@ -220,7 +204,7 @@ def gc_collect():
|
||||
|
||||
|
||||
def pytest_configure():
|
||||
pytest.suppress = suppress
|
||||
pytest.suppress = contextlib.suppress
|
||||
pytest.gc_collect = gc_collect
|
||||
|
||||
|
||||
|
@ -24,5 +24,4 @@ def deprecated_call():
|
||||
pytest_major_minor = (int(pieces[0]), int(pieces[1]))
|
||||
if pytest_major_minor < (3, 9):
|
||||
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")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@pytest.fixture()
|
||||
def event_loop():
|
||||
loop = asyncio.new_event_loop()
|
||||
yield loop
|
||||
@ -16,7 +16,7 @@ async def get_await_result(x):
|
||||
|
||||
|
||||
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):
|
||||
|
@ -54,7 +54,8 @@ def test_to_python():
|
||||
mat2 = np.array(mat, copy=False)
|
||||
assert mat2.shape == (5, 4)
|
||||
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
|
||||
assert mat2[2, 3] == 5
|
||||
|
||||
|
@ -126,8 +126,8 @@ def test_bytes_to_string():
|
||||
|
||||
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
|
||||
assert m.string_length(b"a\x00b") == 3
|
||||
assert m.strlen(b"a\x00b") == 1 # C-string limitation
|
||||
|
||||
# passing in a utf8 encoded string should work
|
||||
assert m.string_length("💩".encode()) == 4
|
||||
@ -421,13 +421,15 @@ def test_reference_wrapper():
|
||||
a2 = m.refwrap_list(copy=True)
|
||||
assert [x.value for x in a1] == [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)
|
||||
b2 = m.refwrap_list(copy=False)
|
||||
assert [x.value for x in b1] == [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_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():
|
||||
if env.PYPY:
|
||||
expected_name = "UserType"
|
||||
else:
|
||||
expected_name = "pybind11_tests.UserType"
|
||||
expected_name = "UserType" if env.PYPY else "pybind11_tests.UserType"
|
||||
assert m.obj_class_name(UserType(1)) == expected_name
|
||||
assert m.obj_class_name(UserType) == expected_name
|
||||
|
||||
@ -32,7 +29,7 @@ def test_instance(msg):
|
||||
assert cstats.alive() == 0
|
||||
|
||||
|
||||
def test_instance_new(msg):
|
||||
def test_instance_new():
|
||||
instance = m.NoConstructorNew() # .__new__(m.NoConstructor.__class__)
|
||||
cstats = ConstructorStats.get(m.NoConstructorNew)
|
||||
assert cstats.alive() == 1
|
||||
@ -221,7 +218,7 @@ def test_automatic_upcasting():
|
||||
|
||||
|
||||
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)
|
||||
assert m.check_instances(objects) == expected
|
||||
|
||||
@ -427,7 +424,7 @@ def test_exception_rvalue_abort():
|
||||
|
||||
|
||||
# https://github.com/pybind/pybind11/issues/1568
|
||||
def test_multiple_instances_with_same_pointer(capture):
|
||||
def test_multiple_instances_with_same_pointer():
|
||||
n = 100
|
||||
instances = [m.SamePointer() for _ in range(n)]
|
||||
for i in range(n):
|
||||
|
@ -3,9 +3,9 @@ import pytest
|
||||
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(
|
||||
"selector, expected",
|
||||
("selector", "expected"),
|
||||
enumerate(
|
||||
(
|
||||
"",
|
||||
|
@ -100,7 +100,8 @@ def test_custom_caster_destruction():
|
||||
cstats = m.destruction_tester_cstats()
|
||||
# This one *doesn't* have take_ownership: the pointer should be used but not destroyed:
|
||||
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
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@pytest.fixture()
|
||||
def gc_tester():
|
||||
"""Tests that an object is garbage collected.
|
||||
|
||||
|
@ -263,79 +263,96 @@ def test_eigen_return_references():
|
||||
primary = np.ones((10, 10))
|
||||
a = m.ReturnTester()
|
||||
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)
|
||||
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)
|
||||
|
||||
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):
|
||||
a_view1[2, 3] = 4
|
||||
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):
|
||||
a_view2[2, 3] = 4
|
||||
|
||||
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)
|
||||
a_copy1[7, 7] = -44 # Shouldn't affect anything else
|
||||
c1want = array_copy_but_one(primary, 7, 7, -44)
|
||||
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)
|
||||
a_copy2[4, 4] = -22 # Shouldn't affect anything else
|
||||
c2want = array_copy_but_one(primary, 4, 4, -22)
|
||||
|
||||
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)
|
||||
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):
|
||||
a_ref2[5, 5] = 33
|
||||
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)
|
||||
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):
|
||||
a_ref4[7, 0] = 987654321
|
||||
|
||||
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)
|
||||
a_copy3[8, 1] = 11
|
||||
c3want = array_copy_but_one(primary, 8, 1, 11)
|
||||
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)
|
||||
a_copy4[8, 4] = 88
|
||||
c4want = array_copy_but_one(primary, 8, 4, 88)
|
||||
|
||||
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
|
||||
primary[3, 3] = 55
|
||||
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
|
||||
primary[4, 3] = -123
|
||||
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):
|
||||
a_block3[2, 2] = -44444
|
||||
|
||||
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])
|
||||
a_copy5[1, 1] = 777
|
||||
c5want = array_copy_but_one(primary[2:4, 2:5], 1, 1, 777)
|
||||
|
||||
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[1, 1] = 999
|
||||
primary[0, 0] = 50
|
||||
@ -343,7 +360,8 @@ def test_eigen_return_references():
|
||||
primary[9, 0] = 50
|
||||
primary[9, 9] = 999
|
||||
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):
|
||||
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 not zc.flags.owndata and zc.flags.writeable
|
||||
assert not zr.flags.owndata and zr.flags.writeable
|
||||
assert not zcro.flags.owndata and not zcro.flags.writeable
|
||||
assert not zrro.flags.owndata and not zrro.flags.writeable
|
||||
assert not zc.flags.owndata
|
||||
assert zc.flags.writeable
|
||||
assert not zr.flags.owndata
|
||||
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
|
||||
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)
|
||||
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:
|
||||
assert y1[1, 2] == 99
|
||||
y1[1, 2] += 12
|
||||
@ -603,38 +626,38 @@ def test_nocopy_wrapper():
|
||||
# All but the second should fail with m.get_elem_nocopy:
|
||||
with pytest.raises(TypeError) as excinfo:
|
||||
m.get_elem_nocopy(int_matrix_colmajor)
|
||||
assert "get_elem_nocopy(): incompatible function arguments." in str(
|
||||
excinfo.value
|
||||
) and ", flags.f_contiguous" in str(excinfo.value)
|
||||
assert "get_elem_nocopy(): incompatible function arguments." in str(excinfo.value)
|
||||
assert ", flags.f_contiguous" in str(excinfo.value)
|
||||
assert m.get_elem_nocopy(dbl_matrix_colmajor) == 8
|
||||
with pytest.raises(TypeError) as excinfo:
|
||||
m.get_elem_nocopy(int_matrix_rowmajor)
|
||||
assert "get_elem_nocopy(): incompatible function arguments." in str(
|
||||
excinfo.value
|
||||
) and ", flags.f_contiguous" in str(excinfo.value)
|
||||
assert "get_elem_nocopy(): incompatible function arguments." in str(excinfo.value)
|
||||
assert ", flags.f_contiguous" in str(excinfo.value)
|
||||
with pytest.raises(TypeError) as excinfo:
|
||||
m.get_elem_nocopy(dbl_matrix_rowmajor)
|
||||
assert "get_elem_nocopy(): incompatible function arguments." in str(
|
||||
excinfo.value
|
||||
) and ", flags.f_contiguous" in str(excinfo.value)
|
||||
assert "get_elem_nocopy(): incompatible function arguments." in str(excinfo.value)
|
||||
assert ", 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:
|
||||
with pytest.raises(TypeError) as excinfo:
|
||||
m.get_elem_rm_nocopy(int_matrix_colmajor)
|
||||
assert "get_elem_rm_nocopy(): incompatible function arguments." in str(
|
||||
excinfo.value
|
||||
) and ", flags.c_contiguous" in str(excinfo.value)
|
||||
)
|
||||
assert ", flags.c_contiguous" in str(excinfo.value)
|
||||
with pytest.raises(TypeError) as excinfo:
|
||||
m.get_elem_rm_nocopy(dbl_matrix_colmajor)
|
||||
assert "get_elem_rm_nocopy(): incompatible function arguments." in str(
|
||||
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
|
||||
with pytest.raises(TypeError) as excinfo:
|
||||
m.get_elem_rm_nocopy(dbl_matrix_rowmajor)
|
||||
assert "get_elem_rm_nocopy(): incompatible function arguments." in str(
|
||||
excinfo.value
|
||||
) and ", flags.c_contiguous" in str(excinfo.value)
|
||||
)
|
||||
assert ", flags.c_contiguous" in str(excinfo.value)
|
||||
|
||||
|
||||
def test_eigen_ref_life_support():
|
||||
|
@ -11,14 +11,15 @@ try:
|
||||
submodules += [avoid.c_style, avoid.f_style]
|
||||
except ImportError as e:
|
||||
# Ensure config, build, toolchain, etc. issues are not masked here:
|
||||
raise RuntimeError(
|
||||
msg = (
|
||||
"import eigen_tensor_avoid_stl_array FAILED, while "
|
||||
"import pybind11_tests.eigen_tensor succeeded. "
|
||||
"Please ensure that "
|
||||
"test_eigen_tensor.cpp & "
|
||||
"eigen_tensor_avoid_stl_array.cpp "
|
||||
"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)
|
||||
|
||||
@ -147,10 +148,7 @@ def test_bad_python_to_cpp_casts(m):
|
||||
m.round_trip_tensor_noconvert(tensor_ref.astype(np.float64))
|
||||
)
|
||||
|
||||
if m.needed_options == "F":
|
||||
bad_options = "C"
|
||||
else:
|
||||
bad_options = "F"
|
||||
bad_options = "C" if m.needed_options == "F" else "F"
|
||||
# Shape, dtype and the order need to be correct for a TensorMap cast
|
||||
with pytest.raises(
|
||||
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)
|
||||
)
|
||||
|
||||
temp = np.zeros((3, 5, 2), dtype=np.float64, order=m.needed_options)
|
||||
with pytest.raises(
|
||||
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(
|
||||
temp[:, ::-1, :],
|
||||
)
|
||||
|
||||
temp = np.zeros((3, 5, 2), dtype=np.float64, order=m.needed_options)
|
||||
temp.setflags(write=False)
|
||||
with pytest.raises(
|
||||
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)
|
||||
|
||||
|
||||
@ -282,9 +280,9 @@ def test_doc_string(m, doc):
|
||||
order_flag = f"flags.{m.needed_options.lower()}_contiguous"
|
||||
assert doc(m.round_trip_view_tensor) == (
|
||||
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) == (
|
||||
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
|
||||
|
||||
from pybind11_tests import enums as m
|
||||
|
@ -94,8 +94,7 @@ def ignore_pytest_unraisable_warning(f):
|
||||
if hasattr(pytest, unraisable): # Python >= 3.8 and pytest >= 6
|
||||
dec = pytest.mark.filterwarnings(f"ignore::pytest.{unraisable}")
|
||||
return dec(f)
|
||||
else:
|
||||
return f
|
||||
return f
|
||||
|
||||
|
||||
# TODO: find out why this fails on PyPy, https://foss.heptapod.net/pypy/pypy/-/issues/3583
|
||||
@ -183,7 +182,7 @@ def test_custom(msg):
|
||||
m.throws5_1()
|
||||
assert msg(excinfo.value) == "MyException5 subclass"
|
||||
|
||||
with pytest.raises(m.MyException5) as excinfo:
|
||||
with pytest.raises(m.MyException5) as excinfo: # noqa: PT012
|
||||
try:
|
||||
m.throws5()
|
||||
except m.MyException5_1 as err:
|
||||
@ -212,7 +211,7 @@ def test_nested_throws(capture):
|
||||
m.try_catch(m.MyException5, throw_myex)
|
||||
assert str(excinfo.value) == "nested error"
|
||||
|
||||
def pycatch(exctype, f, *args):
|
||||
def pycatch(exctype, f, *args): # noqa: ARG001
|
||||
try:
|
||||
f(*args)
|
||||
except m.MyException as e:
|
||||
@ -303,12 +302,12 @@ class FlakyException(Exception):
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"exc_type, exc_value, expected_what",
|
||||
(
|
||||
("exc_type", "exc_value", "expected_what"),
|
||||
[
|
||||
(ValueError, "plain_str", "ValueError: plain_str"),
|
||||
(ValueError, ("tuple_elem",), "ValueError: tuple_elem"),
|
||||
(FlakyException, ("happy",), "FlakyException: FlakyException.__str__"),
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_error_already_set_what_with_happy_exceptions(
|
||||
exc_type, exc_value, expected_what
|
||||
@ -342,10 +341,7 @@ def test_flaky_exception_failure_point_str():
|
||||
)
|
||||
assert not py_err_set_after_what
|
||||
lines = what.splitlines()
|
||||
if env.PYPY and len(lines) == 3:
|
||||
n = 3 # Traceback is missing.
|
||||
else:
|
||||
n = 5
|
||||
n = 3 if env.PYPY and len(lines) == 3 else 5
|
||||
assert (
|
||||
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
|
||||
|
||||
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):
|
||||
if len(args) == 0:
|
||||
test_fn = target
|
||||
else:
|
||||
test_fn = args[0]
|
||||
test_fn = target if len(args) == 0 else args[0]
|
||||
# Do not need to wait much, 10s should be more than enough.
|
||||
timeout = 0.1 if test_fn is _intentional_deadlock else 10
|
||||
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:
|
||||
assert process.exitcode is None
|
||||
return 0
|
||||
elif process.exitcode is None:
|
||||
|
||||
if process.exitcode is None:
|
||||
assert t_delta > 0.9 * timeout
|
||||
msg = "DEADLOCK, most likely, exactly what this test is meant to detect."
|
||||
if env.PYPY and env.WIN:
|
||||
|
@ -224,9 +224,8 @@ def test_redirect(capfd):
|
||||
assert stream.getvalue() == ""
|
||||
|
||||
stream = StringIO()
|
||||
with redirect_stdout(stream):
|
||||
with m.ostream_redirect():
|
||||
m.raw_output(msg)
|
||||
with redirect_stdout(stream), m.ostream_redirect():
|
||||
m.raw_output(msg)
|
||||
stdout, stderr = capfd.readouterr()
|
||||
assert stdout == ""
|
||||
assert stream.getvalue() == msg
|
||||
@ -244,10 +243,9 @@ def test_redirect_err(capfd):
|
||||
msg2 = "StdErr"
|
||||
|
||||
stream = StringIO()
|
||||
with redirect_stderr(stream):
|
||||
with m.ostream_redirect(stdout=False):
|
||||
m.raw_output(msg)
|
||||
m.raw_err(msg2)
|
||||
with redirect_stderr(stream), m.ostream_redirect(stdout=False):
|
||||
m.raw_output(msg)
|
||||
m.raw_err(msg2)
|
||||
stdout, stderr = capfd.readouterr()
|
||||
assert stdout == msg
|
||||
assert stderr == ""
|
||||
@ -260,11 +258,9 @@ def test_redirect_both(capfd):
|
||||
|
||||
stream = StringIO()
|
||||
stream2 = StringIO()
|
||||
with redirect_stdout(stream):
|
||||
with redirect_stderr(stream2):
|
||||
with m.ostream_redirect():
|
||||
m.raw_output(msg)
|
||||
m.raw_err(msg2)
|
||||
with redirect_stdout(stream), redirect_stderr(stream2), m.ostream_redirect():
|
||||
m.raw_output(msg)
|
||||
m.raw_err(msg2)
|
||||
stdout, stderr = capfd.readouterr()
|
||||
assert stdout == ""
|
||||
assert stderr == ""
|
||||
|
@ -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_func1(5, 10) == "x=5, y=10"
|
||||
@ -43,8 +43,7 @@ def test_named_arguments(msg):
|
||||
# noinspection PyArgumentList
|
||||
m.kw_func2(x=5, y=10, z=12)
|
||||
assert excinfo.match(
|
||||
r"(?s)^kw_func2\(\): incompatible.*Invoked with: kwargs: ((x=5|y=10|z=12)(, |$))"
|
||||
+ "{3}$"
|
||||
r"(?s)^kw_func2\(\): incompatible.*Invoked with: kwargs: ((x=5|y=10|z=12)(, |$)){3}$"
|
||||
)
|
||||
|
||||
assert m.kw_func4() == "{13 17}"
|
||||
@ -59,7 +58,7 @@ def test_arg_and_kwargs():
|
||||
assert m.args_function(*args) == args
|
||||
|
||||
args = "a1", "a2"
|
||||
kwargs = dict(arg3="a3", arg4=4)
|
||||
kwargs = {"arg3": "a3", "arg4": 4}
|
||||
assert m.args_kwargs_function(*args, **kwargs) == (args, kwargs)
|
||||
|
||||
|
||||
@ -177,7 +176,7 @@ def test_mixed_args_and_kwargs(msg):
|
||||
|
||||
assert (
|
||||
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(2) == (2, 3.14159, (), 42, {})
|
||||
@ -233,15 +232,15 @@ def test_keyword_only_args(msg):
|
||||
x.method(i=1, j=2)
|
||||
assert (
|
||||
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 (
|
||||
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(2, 1) == (2, 1)
|
||||
|
||||
@ -283,7 +282,7 @@ def test_positional_only_args(msg):
|
||||
# Mix it with args and kwargs:
|
||||
assert (
|
||||
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(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
|
||||
assert (
|
||||
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():
|
||||
assert "kw_only_all(*, i: int, j: int) -> tuple\n" == m.kw_only_all.__doc__
|
||||
assert "kw_only_mixed(i: int, *, j: int) -> tuple\n" == m.kw_only_mixed.__doc__
|
||||
assert "pos_only_all(i: int, j: int, /) -> tuple\n" == m.pos_only_all.__doc__
|
||||
assert "pos_only_mix(i: int, /, j: int) -> tuple\n" == m.pos_only_mix.__doc__
|
||||
assert m.kw_only_all.__doc__ == "kw_only_all(*, i: int, j: int) -> tuple\n"
|
||||
assert m.kw_only_mixed.__doc__ == "kw_only_mixed(i: int, *, j: int) -> tuple\n"
|
||||
assert m.pos_only_all.__doc__ == "pos_only_all(i: int, j: int, /) -> tuple\n"
|
||||
assert m.pos_only_mix.__doc__ == "pos_only_mix(i: int, /, j: int) -> tuple\n"
|
||||
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
|
||||
del m.TestPropertiesOverride.def_readonly_static
|
||||
assert hasattr(m.TestPropertiesOverride, "def_readonly_static")
|
||||
assert (
|
||||
hasattr(m.TestPropertiesOverride, "def_readonly_static")
|
||||
and m.TestPropertiesOverride.def_readonly_static
|
||||
m.TestPropertiesOverride.def_readonly_static
|
||||
is m.TestProperties.def_readonly_static
|
||||
)
|
||||
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"])
|
||||
def test_property_return_value_policies(access):
|
||||
if not access.startswith("static"):
|
||||
obj = m.TestPropRVP()
|
||||
else:
|
||||
obj = m.TestPropRVP
|
||||
obj = m.TestPropRVP() if not access.startswith("static") else m.TestPropRVP
|
||||
|
||||
ref = getattr(obj, access + "_ref")
|
||||
assert ref.value == 1
|
||||
|
@ -1,3 +1,5 @@
|
||||
import builtins
|
||||
|
||||
import pytest
|
||||
|
||||
import env
|
||||
@ -86,12 +88,7 @@ def test_builtin_key_type():
|
||||
|
||||
Previous versions of pybind11 would add a unicode key in python 2.
|
||||
"""
|
||||
if hasattr(__builtins__, "keys"):
|
||||
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}
|
||||
assert all(type(k) == str for k in dir(builtins))
|
||||
|
||||
|
||||
@pytest.mark.xfail("env.PYPY", reason="PyModule_GetName()")
|
||||
|
@ -22,7 +22,7 @@ def test_dtypes():
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
@pytest.fixture()
|
||||
def arr():
|
||||
return np.array([[1, 2, 3], [4, 5, 6]], "=u2")
|
||||
|
||||
@ -67,7 +67,7 @@ def test_array_attributes():
|
||||
|
||||
|
||||
@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):
|
||||
assert m.index_at(arr, *args) == ret
|
||||
@ -93,7 +93,7 @@ def test_dim_check_fail(arr):
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"args, ret",
|
||||
("args", "ret"),
|
||||
[
|
||||
([], [1, 2, 3, 4, 5, 6]),
|
||||
([1], [4, 5, 6]),
|
||||
@ -211,12 +211,14 @@ def test_wrap():
|
||||
assert b[0, 0] == 1234
|
||||
|
||||
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)
|
||||
assert_references(a1, a2)
|
||||
|
||||
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)
|
||||
assert_references(a1, a2)
|
||||
|
||||
@ -451,13 +453,15 @@ def test_array_resize():
|
||||
try:
|
||||
m.array_resize3(a, 3, True)
|
||||
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
|
||||
b = a.transpose()
|
||||
try:
|
||||
m.array_resize3(b, 3, False)
|
||||
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
|
||||
m.array_reshape2(b)
|
||||
assert b.shape == (8, 8)
|
||||
|
@ -130,14 +130,10 @@ def test_dtype(simple_dtype):
|
||||
partial_nested_fmt(),
|
||||
"[('a','S3'),('b','S3')]",
|
||||
(
|
||||
"{{'names':['a','b','c','d'],"
|
||||
+ "'formats':[('S4',(3,)),('"
|
||||
+ e
|
||||
+ "i4',(2,)),('u1',(3,)),('"
|
||||
+ e
|
||||
+ "f4',(4,2))],"
|
||||
+ "'offsets':[0,12,20,24],'itemsize':56}}"
|
||||
).format(e=e),
|
||||
"{'names':['a','b','c','d'],"
|
||||
f"'formats':[('S4',(3,)),('{e}i4',(2,)),('u1',(3,)),('{e}f4',(4,2))],"
|
||||
"'offsets':[0,12,20,24],'itemsize':56}"
|
||||
),
|
||||
"[('e1','" + e + "i8'),('e2','u1')]",
|
||||
"[('x','i1'),('y','" + e + "u8')]",
|
||||
"[('cflt','" + e + "c8'),('cdbl','" + e + "c16')]",
|
||||
@ -291,19 +287,17 @@ def test_array_array():
|
||||
|
||||
arr = m.create_array_array(3)
|
||||
assert str(arr.dtype).replace(" ", "") == (
|
||||
"{{'names':['a','b','c','d'],"
|
||||
+ "'formats':[('S4',(3,)),('"
|
||||
+ e
|
||||
+ "i4',(2,)),('u1',(3,)),('{e}f4',(4,2))],"
|
||||
+ "'offsets':[0,12,20,24],'itemsize':56}}"
|
||||
).format(e=e)
|
||||
"{'names':['a','b','c','d'],"
|
||||
f"'formats':[('S4',(3,)),('{e}i4',(2,)),('u1',(3,)),('{e}f4',(4,2))],"
|
||||
"'offsets':[0,12,20,24],'itemsize':56}"
|
||||
)
|
||||
assert m.print_array_array(arr) == [
|
||||
"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},"
|
||||
+ "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},"
|
||||
+ "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() == [
|
||||
[b"ABCD", b"KLMN", b"UVWX"],
|
||||
|
@ -149,7 +149,7 @@ def test_docs(doc):
|
||||
doc(m.vectorized_func)
|
||||
== """
|
||||
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"
|
||||
|
||||
|
||||
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_const()
|
||||
|
||||
@ -33,7 +33,7 @@ def test_iterator(doc):
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"pytype, from_iter_func",
|
||||
("pytype", "from_iter_func"),
|
||||
[
|
||||
(frozenset, m.get_frozenset_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"
|
||||
|
||||
|
||||
def test_none(capture, doc):
|
||||
def test_none(doc):
|
||||
assert doc(m.get_none) == "get_none() -> None"
|
||||
assert doc(m.print_none) == "print_none(arg0: None) -> None"
|
||||
|
||||
@ -182,10 +182,10 @@ class CustomContains:
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"arg,func",
|
||||
("arg", "func"),
|
||||
[
|
||||
(set(), m.anyset_contains),
|
||||
(dict(), m.dict_contains),
|
||||
({}, m.dict_contains),
|
||||
(CustomContains(), m.obj_contains),
|
||||
],
|
||||
)
|
||||
@ -273,7 +273,7 @@ def test_bytes(doc):
|
||||
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_size_t().decode() == "@$!"
|
||||
assert m.bytearray_from_string().decode() == "foo"
|
||||
@ -385,7 +385,7 @@ def test_accessors():
|
||||
assert d["implicit_list"] == [1, 2, 3]
|
||||
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()
|
||||
assert d["get"] == 0
|
||||
@ -593,7 +593,7 @@ def test_issue2361():
|
||||
|
||||
|
||||
@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_buffer_info, (b"green",), "B", b"green"),
|
||||
@ -651,7 +651,7 @@ def test_memoryview_from_memory():
|
||||
|
||||
|
||||
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:
|
||||
m.get_len(i for i in range(42))
|
||||
assert str(exc_info.value) in [
|
||||
@ -695,7 +695,7 @@ def test_pass_bytes_or_unicode_to_string_types():
|
||||
|
||||
|
||||
@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_object, m.weakref_from_object_and_function),
|
||||
@ -710,7 +710,7 @@ def test_weakref(create_weakref, create_weakref_with_callback):
|
||||
|
||||
callback_called = False
|
||||
|
||||
def callback(wr):
|
||||
def callback(_):
|
||||
nonlocal callback_called
|
||||
callback_called = True
|
||||
|
||||
@ -730,7 +730,7 @@ def test_weakref(create_weakref, create_weakref_with_callback):
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"create_weakref, has_callback",
|
||||
("create_weakref", "has_callback"),
|
||||
[
|
||||
(m.weakref_from_handle, False),
|
||||
(m.weakref_from_object, False),
|
||||
@ -748,10 +748,7 @@ def test_weakref_err(create_weakref, has_callback):
|
||||
ob = C()
|
||||
# Should raise TypeError on CPython
|
||||
with pytest.raises(TypeError) if not env.PYPY else contextlib.nullcontext():
|
||||
if has_callback:
|
||||
_ = create_weakref(ob, callback)
|
||||
else:
|
||||
_ = create_weakref(ob)
|
||||
_ = create_weakref(ob, callback) if has_callback else create_weakref(ob)
|
||||
|
||||
|
||||
def test_cpp_iterators():
|
||||
@ -814,33 +811,36 @@ def test_populate_obj_str_attrs():
|
||||
|
||||
|
||||
@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):
|
||||
expected = a + b
|
||||
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):
|
||||
expected = a - b
|
||||
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):
|
||||
expected = a * b
|
||||
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):
|
||||
expected = a / b
|
||||
assert m.inplace_divide(a, b) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"a,b",
|
||||
("a", "b"),
|
||||
[
|
||||
(False, True),
|
||||
(
|
||||
@ -857,7 +857,7 @@ def test_inplace_or(a, b):
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"a,b",
|
||||
("a", "b"),
|
||||
[
|
||||
(True, False),
|
||||
(
|
||||
@ -873,13 +873,13 @@ def test_inplace_and(a, b):
|
||||
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):
|
||||
expected = a << b
|
||||
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):
|
||||
expected = a >> b
|
||||
assert m.inplace_rshift(a, b) == expected
|
||||
|
@ -1,5 +1,5 @@
|
||||
import pytest
|
||||
from pytest import approx
|
||||
from pytest import approx # noqa: PT013
|
||||
|
||||
from pybind11_tests import ConstructorStats
|
||||
from pybind11_tests import sequences_and_iterators as m
|
||||
@ -103,7 +103,8 @@ def test_sequence():
|
||||
|
||||
assert "Sequence" in repr(s)
|
||||
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
|
||||
s[0], s[3] = 12.34, 56.78
|
||||
assert 12.34 in s
|
||||
@ -245,7 +246,7 @@ def test_iterator_rvp():
|
||||
|
||||
def test_carray_iterator():
|
||||
"""#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)
|
||||
args = list(arr_h)
|
||||
assert args_gt == args
|
||||
|
@ -14,7 +14,7 @@ def test_vector(doc):
|
||||
|
||||
assert m.cast_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.load_vector) == "load_vector(arg0: List[int]) -> bool"
|
||||
@ -23,7 +23,7 @@ def test_vector(doc):
|
||||
assert m.cast_ptr_vector() == ["lvalue", "lvalue"]
|
||||
|
||||
|
||||
def test_deque(doc):
|
||||
def test_deque():
|
||||
"""std::deque <-> list"""
|
||||
lst = m.cast_deque()
|
||||
assert lst == [1]
|
||||
@ -95,7 +95,8 @@ def test_recursive_casting():
|
||||
|
||||
# Issue #853 test case:
|
||||
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():
|
||||
|
@ -186,9 +186,9 @@ def test_map_string_double():
|
||||
um["ua"] = 1.1
|
||||
um["ub"] = 2.6
|
||||
|
||||
assert sorted(list(um)) == ["ua", "ub"]
|
||||
assert sorted(um) == ["ua", "ub"]
|
||||
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 "UnorderedMapStringDouble" in str(um)
|
||||
|
||||
@ -304,11 +304,11 @@ def test_map_delitem():
|
||||
um["ua"] = 1.1
|
||||
um["ub"] = 2.6
|
||||
|
||||
assert sorted(list(um)) == ["ua", "ub"]
|
||||
assert sorted(list(um.items())) == [("ua", 1.1), ("ub", 2.6)]
|
||||
assert sorted(um) == ["ua", "ub"]
|
||||
assert sorted(um.items()) == [("ua", 1.1), ("ub", 2.6)]
|
||||
del um["ua"]
|
||||
assert sorted(list(um)) == ["ub"]
|
||||
assert sorted(list(um.items())) == [("ub", 2.6)]
|
||||
assert sorted(um) == ["ub"]
|
||||
assert sorted(um.items()) == [("ub", 2.6)]
|
||||
|
||||
|
||||
def test_map_view_types():
|
||||
|
@ -192,8 +192,7 @@ def test_move_support():
|
||||
class NCVirtExt(m.NCVirt):
|
||||
def get_noncopyable(self, a, b):
|
||||
# Constructs and returns a new instance:
|
||||
nc = m.NonCopyable(a * a, b * b)
|
||||
return nc
|
||||
return m.NonCopyable(a * a, b * b)
|
||||
|
||||
def get_movable(self, a, b):
|
||||
# Return a referenced copy
|
||||
@ -256,7 +255,7 @@ def test_dispatch_issue(msg):
|
||||
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"""
|
||||
|
||||
class Data(m.Data):
|
||||
@ -269,7 +268,7 @@ def test_recursive_dispatch_issue(msg):
|
||||
# lambda is a workaround, which adds extra frame to the
|
||||
# current CPython thread. Removing lambda reveals the bug
|
||||
# [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:
|
||||
def __init__(self):
|
||||
|
@ -17,14 +17,18 @@ def run(args: List[str]) -> None:
|
||||
assert len(args) == 1, "codespell_errors.txt"
|
||||
cache = {}
|
||||
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(" ==> ")
|
||||
if i > 0:
|
||||
flds = line[:i].split(":")
|
||||
if len(flds) >= 2:
|
||||
filename, line_num = flds[:2]
|
||||
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]
|
||||
if supp not in done:
|
||||
print(supp)
|
||||
|
Loading…
Reference in New Issue
Block a user