Skip to content

Commit

Permalink
test: add docstring tests for generated dunder methods
Browse files Browse the repository at this point in the history
  • Loading branch information
XuehaiPan committed Nov 11, 2024
1 parent 14ef500 commit 601e499
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 5 deletions.
1 change: 1 addition & 0 deletions include/pybind11/pybind11.h
Original file line number Diff line number Diff line change
Expand Up @@ -2481,6 +2481,7 @@ iterator make_iterator_impl(Iterator first, Sentinel last, Extra &&...extra) {
// NOLINTNEXTLINE(readability-const-return-type) // PR #3263
},
std::forward<Extra>(extra)...,
pos_only(),
Policy);
}

Expand Down
60 changes: 60 additions & 0 deletions tests/test_enum.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# ruff: noqa: SIM201 SIM300 SIM202
from __future__ import annotations

import re

import pytest

import env # noqa: F401
Expand Down Expand Up @@ -271,3 +273,61 @@ def test_docstring_signatures():
def test_str_signature():
for enum_type in [m.ScopedEnum, m.UnscopedEnum]:
assert enum_type.__str__.__doc__.startswith("__str__")


def test_generated_dunder_methods_pos_only():
for enum_type in [m.ScopedEnum, m.UnscopedEnum]:
for binary_op in [
"__eq__",
"__ne__",
"__ge__",
"__gt__",
"__lt__",
"__le__",
"__and__",
"__rand__",
"__or__",
"__ror__",
"__xor__",
"__rxor__",
"__rxor__",
]:
method = getattr(enum_type, binary_op, None)
if method is not None:
assert (

Check failure on line 297 in tests/test_enum.py

View workflow job for this annotation

GitHub Actions / 🐍 3.11 • ubuntu-latest • x64

test_generated_dunder_methods_pos_only AssertionError: assert None is not None + where None = <function match at 0x7f6fa8152d40>('^__or__\\(self: [\\w\\.]+, other: [\\w\\.]+, /\\)', 'Return self|value.') + where <function match at 0x7f6fa8152d40> = re.match + and 'Return self|value.' = <method-wrapper '__or__' of pybind11_type object at 0x56289a23fd60>.__doc__

Check failure on line 297 in tests/test_enum.py

View workflow job for this annotation

GitHub Actions / 🐍 3.13 • ubuntu-20.04 • x64

test_generated_dunder_methods_pos_only AssertionError: assert None is not None + where None = <function match at 0x7fb0b5af79c0>('^__or__\\(self: [\\w\\.]+, other: [\\w\\.]+, /\\)', 'Return self|value.') + where <function match at 0x7fb0b5af79c0> = re.match + and 'Return self|value.' = <method-wrapper '__or__' of pybind11_type object at 0x55ded55515e0>.__doc__

Check failure on line 297 in tests/test_enum.py

View workflow job for this annotation

GitHub Actions / 🐍 3.12 • ubuntu-20.04 • x64

test_generated_dunder_methods_pos_only AssertionError: assert None is not None + where None = <function match at 0x7f5da4591940>('^__or__\\(self: [\\w\\.]+, other: [\\w\\.]+, /\\)', 'Return self|value.') + where <function match at 0x7f5da4591940> = re.match + and 'Return self|value.' = <method-wrapper '__or__' of pybind11_type object at 0x55b9bd607a60>.__doc__

Check failure on line 297 in tests/test_enum.py

View workflow job for this annotation

GitHub Actions / 🐍 pypy-3.10 • ubuntu-20.04 • x64

test_generated_dunder_methods_pos_only TypeError: can't use a string pattern on a bytes-like object
re.match(

Check failure on line 298 in tests/test_enum.py

View workflow job for this annotation

GitHub Actions / 🐍 graalpy-24.1 • ubuntu-20.04 • x64

test_generated_dunder_methods_pos_only TypeError: object of type 'NoneType' has no len()
rf"^{binary_op}\(self: [\w\.]+, other: [\w\.]+, /\)",
method.__doc__,
)
is not None
)
for unary_op in [
"__int__",
"__index__",
"__hash__",
"__str__",
"__repr__",
]:
method = getattr(enum_type, unary_op, None)
if method is not None:
assert (
re.match(
rf"^{unary_op}\(self: [\w\.]+, /\)",
method.__doc__,
)
is not None
)
assert (
re.match(
r"^__getstate__\(self: [\w\.]+, /\)",
enum_type.__getstate__.__doc__,
)
is not None
)
assert (
re.match(
r"^__setstate__\(self: [\w\.]+, state: [\w\.]+, /\)",
enum_type.__setstate__.__doc__,
)
is not None
)
16 changes: 16 additions & 0 deletions tests/test_pickling.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,19 @@ def test_roundtrip_simple_cpp_derived():
# Issue #3062: pickleable base C++ classes can incur object slicing
# if derived typeid is not registered with pybind11
assert not m.check_dynamic_cast_SimpleCppDerived(p2)


def test_new_style_pickle_getstate_pos_only():
assert (
re.match(
r"^__getstate__\(self: [\w\.]+, /\)", m.PickleableNew.__getstate__.__doc__
)
is not None
)
assert (

Check failure on line 105 in tests/test_pickling.py

View workflow job for this annotation

GitHub Actions / 🐍 pypy-3.10 • ubuntu-20.04 • x64

test_new_style_pickle_getstate_pos_only AttributeError: module 'pybind11_tests.pickling' has no attribute 'PickleableWithDictNew'

Check failure on line 105 in tests/test_pickling.py

View workflow job for this annotation

GitHub Actions / 🐍 pypy-3.9 • ubuntu-20.04 • x64

test_new_style_pickle_getstate_pos_only AttributeError: module 'pybind11_tests.pickling' has no attribute 'PickleableWithDictNew'

Check failure on line 105 in tests/test_pickling.py

View workflow job for this annotation

GitHub Actions / 🐍 pypy-3.8 • ubuntu-20.04 • x64 -DPYBIND11_FINDPYTHON=ON

test_new_style_pickle_getstate_pos_only AttributeError: module 'pybind11_tests.pickling' has no attribute 'PickleableWithDictNew'
re.match(
r"^__getstate__\(self: [\w\.]+, /\)",
m.PickleableWithDictNew.__getstate__.__doc__,
)
is not None
)
30 changes: 25 additions & 5 deletions tests/test_sequences_and_iterators.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from __future__ import annotations

import re

import pytest
from pytest import approx # noqa: PT013

Expand Down Expand Up @@ -253,16 +255,12 @@ def bad_next_call():

def test_iterator_passthrough():
"""#181: iterator passthrough did not compile"""
from pybind11_tests.sequences_and_iterators import iterator_passthrough

values = [3, 5, 7, 9, 11, 13, 15]
assert list(iterator_passthrough(iter(values))) == values
assert list(m.iterator_passthrough(iter(values))) == values


def test_iterator_rvp():
"""#388: Can't make iterators via make_iterator() with different r/v policies"""
import pybind11_tests.sequences_and_iterators as m

assert list(m.make_iterator_1()) == [1, 2, 3]
assert list(m.make_iterator_2()) == [1, 2, 3]
assert not isinstance(m.make_iterator_1(), type(m.make_iterator_2()))
Expand All @@ -274,3 +272,25 @@ def test_carray_iterator():
arr_h = m.CArrayHolder(*args_gt)
args = list(arr_h)
assert args_gt == args


def test_generated_dunder_methods_pos_only():
string_map = m.StringMap({"hi": "bye", "black": "white"})
for it in (
m.make_iterator_1(),
m.make_iterator_2(),
m.iterator_passthrough(iter([3, 5, 7])),
iter(m.Sequence(5)),
iter(string_map),
string_map.items(),
string_map.values(),
iter(m.CArrayHolder(*[float(i) for i in range(3)])),
):
assert (
re.match(r"^__iter__\(self: [\w\.]+, /\)", type(it).__iter__.__doc__)
is not None
)
assert (
re.match(r"^__next__\(self: [\w\.]+, /\)", type(it).__next__.__doc__)
is not None
)

0 comments on commit 601e499

Please sign in to comment.