import contextlib
import sys
import types

import pytest

import env
from pybind11_tests import detailed_error_messages_enabled
from pybind11_tests import pytypes as m


def test_obj_class_name():
    assert m.obj_class_name(None) == "NoneType"
    assert m.obj_class_name(list) == "list"
    assert m.obj_class_name([]) == "list"


def test_handle_from_move_only_type_with_operator_PyObject():  # noqa: N802
    assert m.handle_from_move_only_type_with_operator_PyObject_ncnst()
    assert m.handle_from_move_only_type_with_operator_PyObject_const()


def test_bool(doc):
    assert doc(m.get_bool) == "get_bool() -> bool"


def test_int(doc):
    assert doc(m.get_int) == "get_int() -> int"


def test_iterator(doc):
    assert doc(m.get_iterator) == "get_iterator() -> Iterator"


@pytest.mark.parametrize(
    "pytype, from_iter_func",
    [
        (frozenset, m.get_frozenset_from_iterable),
        (list, m.get_list_from_iterable),
        (set, m.get_set_from_iterable),
        (tuple, m.get_tuple_from_iterable),
    ],
)
def test_from_iterable(pytype, from_iter_func):
    my_iter = iter(range(10))
    s = from_iter_func(my_iter)
    assert type(s) == pytype
    assert s == pytype(range(10))


def test_iterable(doc):
    assert doc(m.get_iterable) == "get_iterable() -> Iterable"


def test_float(doc):
    assert doc(m.get_float) == "get_float() -> float"


def test_list(capture, doc):
    assert m.list_no_args() == []
    assert m.list_ssize_t() == []
    assert m.list_size_t() == []
    lins = [1, 2]
    m.list_insert_ssize_t(lins)
    assert lins == [1, 83, 2]
    m.list_insert_size_t(lins)
    assert lins == [1, 83, 2, 57]

    with capture:
        lst = m.get_list()
        assert lst == ["inserted-0", "overwritten", "inserted-2"]

        lst.append("value2")
        m.print_list(lst)
    assert (
        capture.unordered
        == """
        Entry at position 0: value
        list item 0: inserted-0
        list item 1: overwritten
        list item 2: inserted-2
        list item 3: value2
    """
    )

    assert doc(m.get_list) == "get_list() -> list"
    assert doc(m.print_list) == "print_list(arg0: list) -> None"


def test_none(capture, doc):
    assert doc(m.get_none) == "get_none() -> None"
    assert doc(m.print_none) == "print_none(arg0: None) -> None"


def test_set(capture, doc):
    s = m.get_set()
    assert isinstance(s, set)
    assert s == {"key1", "key2", "key3"}

    s.add("key4")
    with capture:
        m.print_anyset(s)
    assert (
        capture.unordered
        == """
        key: key1
        key: key2
        key: key3
        key: key4
    """
    )

    m.set_add(s, "key5")
    assert m.anyset_size(s) == 5

    m.set_clear(s)
    assert m.anyset_empty(s)

    assert not m.anyset_contains(set(), 42)
    assert m.anyset_contains({42}, 42)
    assert m.anyset_contains({"foo"}, "foo")

    assert doc(m.get_set) == "get_set() -> set"
    assert doc(m.print_anyset) == "print_anyset(arg0: anyset) -> None"


def test_frozenset(capture, doc):
    s = m.get_frozenset()
    assert isinstance(s, frozenset)
    assert s == frozenset({"key1", "key2", "key3"})

    with capture:
        m.print_anyset(s)
    assert (
        capture.unordered
        == """
        key: key1
        key: key2
        key: key3
    """
    )
    assert m.anyset_size(s) == 3
    assert not m.anyset_empty(s)

    assert not m.anyset_contains(frozenset(), 42)
    assert m.anyset_contains(frozenset({42}), 42)
    assert m.anyset_contains(frozenset({"foo"}), "foo")

    assert doc(m.get_frozenset) == "get_frozenset() -> frozenset"


def test_dict(capture, doc):
    d = m.get_dict()
    assert d == {"key": "value"}

    with capture:
        d["key2"] = "value2"
        m.print_dict(d)
    assert (
        capture.unordered
        == """
        key: key, value=value
        key: key2, value=value2
    """
    )

    assert not m.dict_contains({}, 42)
    assert m.dict_contains({42: None}, 42)
    assert m.dict_contains({"foo": None}, "foo")

    assert doc(m.get_dict) == "get_dict() -> dict"
    assert doc(m.print_dict) == "print_dict(arg0: dict) -> None"

    assert m.dict_keyword_constructor() == {"x": 1, "y": 2, "z": 3}


class CustomContains:
    d = {"key": None}

    def __contains__(self, m):
        return m in self.d


@pytest.mark.parametrize(
    "arg,func",
    [
        (set(), m.anyset_contains),
        (dict(), m.dict_contains),
        (CustomContains(), m.obj_contains),
    ],
)
@pytest.mark.xfail("env.PYPY and sys.pypy_version_info < (7, 3, 10)", strict=False)
def test_unhashable_exceptions(arg, func):
    class Unhashable:
        __hash__ = None

    with pytest.raises(TypeError) as exc_info:
        func(arg, Unhashable())
    assert "unhashable type:" in str(exc_info.value)


def test_tuple():
    assert m.tuple_no_args() == ()
    assert m.tuple_ssize_t() == ()
    assert m.tuple_size_t() == ()
    assert m.get_tuple() == (42, None, "spam")


def test_simple_namespace():
    ns = m.get_simple_namespace()
    assert ns.attr == 42
    assert ns.x == "foo"
    assert ns.right == 2
    assert not hasattr(ns, "wrong")


def test_str(doc):
    assert m.str_from_char_ssize_t().encode().decode() == "red"
    assert m.str_from_char_size_t().encode().decode() == "blue"
    assert m.str_from_string().encode().decode() == "baz"
    assert m.str_from_bytes().encode().decode() == "boo"

    assert doc(m.str_from_bytes) == "str_from_bytes() -> str"

    class A:
        def __str__(self):
            return "this is a str"

        def __repr__(self):
            return "this is a repr"

    assert m.str_from_object(A()) == "this is a str"
    assert m.repr_from_object(A()) == "this is a repr"
    assert m.str_from_handle(A()) == "this is a str"

    s1, s2 = m.str_format()
    assert s1 == "1 + 2 = 3"
    assert s1 == s2

    malformed_utf8 = b"\x80"
    if hasattr(m, "PYBIND11_STR_LEGACY_PERMISSIVE"):
        assert m.str_from_object(malformed_utf8) is malformed_utf8
    else:
        assert m.str_from_object(malformed_utf8) == "b'\\x80'"
    assert m.str_from_handle(malformed_utf8) == "b'\\x80'"

    assert m.str_from_string_from_str("this is a str") == "this is a str"
    ucs_surrogates_str = "\udcc3"
    with pytest.raises(UnicodeEncodeError):
        m.str_from_string_from_str(ucs_surrogates_str)


@pytest.mark.parametrize(
    "func",
    [
        m.str_from_bytes_input,
        m.str_from_cstr_input,
        m.str_from_std_string_input,
    ],
)
def test_surrogate_pairs_unicode_error(func):
    input_str = "\ud83d\ude4f".encode("utf-8", "surrogatepass")
    with pytest.raises(UnicodeDecodeError):
        func(input_str)


def test_bytes(doc):
    assert m.bytes_from_char_ssize_t().decode() == "green"
    assert m.bytes_from_char_size_t().decode() == "purple"
    assert m.bytes_from_string().decode() == "foo"
    assert m.bytes_from_str().decode() == "bar"

    assert doc(m.bytes_from_str) == "bytes_from_str() -> bytes"


def test_bytearray(doc):
    assert m.bytearray_from_char_ssize_t().decode() == "$%"
    assert m.bytearray_from_char_size_t().decode() == "@$!"
    assert m.bytearray_from_string().decode() == "foo"
    assert m.bytearray_size() == len("foo")


def test_capsule(capture):
    pytest.gc_collect()
    with capture:
        a = m.return_capsule_with_destructor()
        del a
        pytest.gc_collect()
    assert (
        capture.unordered
        == """
        creating capsule
        destructing capsule
    """
    )

    with capture:
        a = m.return_renamed_capsule_with_destructor()
        del a
        pytest.gc_collect()
    assert (
        capture.unordered
        == """
        creating capsule
        renaming capsule
        destructing capsule
    """
    )

    with capture:
        a = m.return_capsule_with_destructor_2()
        del a
        pytest.gc_collect()
    assert (
        capture.unordered
        == """
        creating capsule
        destructing capsule: 1234
    """
    )

    with capture:
        a = m.return_renamed_capsule_with_destructor_2()
        del a
        pytest.gc_collect()
    assert (
        capture.unordered
        == """
        creating capsule
        renaming capsule
        destructing capsule: 1234
    """
    )

    with capture:
        a = m.return_capsule_with_name_and_destructor()
        del a
        pytest.gc_collect()
    assert (
        capture.unordered
        == """
        created capsule (1234, 'pointer type description')
        destructing capsule (1234, 'pointer type description')
    """
    )

    with capture:
        a = m.return_capsule_with_explicit_nullptr_dtor()
        del a
        pytest.gc_collect()
    assert (
        capture.unordered
        == """
        creating capsule with explicit nullptr dtor
    """
    )


def test_accessors():
    class SubTestObject:
        attr_obj = 1
        attr_char = 2

    class TestObject:
        basic_attr = 1
        begin_end = [1, 2, 3]
        d = {"operator[object]": 1, "operator[char *]": 2}
        sub = SubTestObject()

        def func(self, x, *args):
            return self.basic_attr + x + sum(args)

    d = m.accessor_api(TestObject())
    assert d["basic_attr"] == 1
    assert d["begin_end"] == [1, 2, 3]
    assert d["operator[object]"] == 1
    assert d["operator[char *]"] == 2
    assert d["attr(object)"] == 1
    assert d["attr(char *)"] == 2
    assert d["missing_attr_ptr"] == "raised"
    assert d["missing_attr_chain"] == "raised"
    assert d["is_none"] is False
    assert d["operator()"] == 2
    assert d["operator*"] == 7
    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)

    d = m.accessor_assignment()
    assert d["get"] == 0
    assert d["deferred_get"] == 0
    assert d["set"] == 1
    assert d["deferred_set"] == 1
    assert d["var"] == 99


def test_accessor_moves():
    inc_refs = m.accessor_moves()
    if inc_refs:
        assert inc_refs == [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0]
    else:
        pytest.skip("Not defined: PYBIND11_HANDLE_REF_DEBUG")


def test_constructors():
    """C++ default and converting constructors are equivalent to type calls in Python"""
    types = [bytes, bytearray, str, bool, int, float, tuple, list, dict, set]
    expected = {t.__name__: t() for t in types}
    assert m.default_constructors() == expected

    data = {
        bytes: b"41",  # Currently no supported or working conversions.
        bytearray: bytearray(b"41"),
        str: 42,
        bool: "Not empty",
        int: "42",
        float: "+1e3",
        tuple: range(3),
        list: range(3),
        dict: [("two", 2), ("one", 1), ("three", 3)],
        set: [4, 4, 5, 6, 6, 6],
        frozenset: [4, 4, 5, 6, 6, 6],
        memoryview: b"abc",
    }
    inputs = {k.__name__: v for k, v in data.items()}
    expected = {k.__name__: k(v) for k, v in data.items()}

    assert m.converting_constructors(inputs) == expected
    assert m.cast_functions(inputs) == expected

    # Converting constructors and cast functions should just reference rather
    # than copy when no conversion is needed:
    noconv1 = m.converting_constructors(expected)
    for k in noconv1:
        assert noconv1[k] is expected[k]

    noconv2 = m.cast_functions(expected)
    for k in noconv2:
        assert noconv2[k] is expected[k]


def test_non_converting_constructors():
    non_converting_test_cases = [
        ("bytes", range(10)),
        ("none", 42),
        ("ellipsis", 42),
        ("type", 42),
    ]
    for t, v in non_converting_test_cases:
        for move in [True, False]:
            with pytest.raises(TypeError) as excinfo:
                m.nonconverting_constructor(t, v, move)
            expected_error = (
                f"Object of type '{type(v).__name__}' is not an instance of '{t}'"
            )
            assert str(excinfo.value) == expected_error


def test_pybind11_str_raw_str():
    # specifically to exercise pybind11::str::raw_str
    cvt = m.convert_to_pybind11_str
    assert cvt("Str") == "Str"
    assert cvt(b"Bytes") == "b'Bytes'"
    assert cvt(None) == "None"
    assert cvt(False) == "False"
    assert cvt(True) == "True"
    assert cvt(42) == "42"
    assert cvt(2**65) == "36893488147419103232"
    assert cvt(-1.50) == "-1.5"
    assert cvt(()) == "()"
    assert cvt((18,)) == "(18,)"
    assert cvt([]) == "[]"
    assert cvt([28]) == "[28]"
    assert cvt({}) == "{}"
    assert cvt({3: 4}) == "{3: 4}"
    assert cvt(set()) == "set()"
    assert cvt({3, 3}) == "{3}"

    valid_orig = "Ǳ"
    valid_utf8 = valid_orig.encode("utf-8")
    valid_cvt = cvt(valid_utf8)
    if hasattr(m, "PYBIND11_STR_LEGACY_PERMISSIVE"):
        assert valid_cvt is valid_utf8
    else:
        assert type(valid_cvt) is str
        assert valid_cvt == "b'\\xc7\\xb1'"

    malformed_utf8 = b"\x80"
    if hasattr(m, "PYBIND11_STR_LEGACY_PERMISSIVE"):
        assert cvt(malformed_utf8) is malformed_utf8
    else:
        malformed_cvt = cvt(malformed_utf8)
        assert type(malformed_cvt) is str
        assert malformed_cvt == "b'\\x80'"


def test_implicit_casting():
    """Tests implicit casting when assigning or appending to dicts and lists."""
    z = m.get_implicit_casting()
    assert z["d"] == {
        "char*_i1": "abc",
        "char*_i2": "abc",
        "char*_e": "abc",
        "char*_p": "abc",
        "str_i1": "str",
        "str_i2": "str1",
        "str_e": "str2",
        "str_p": "str3",
        "int_i1": 42,
        "int_i2": 42,
        "int_e": 43,
        "int_p": 44,
    }
    assert z["l"] == [3, 6, 9, 12, 15]


def test_print(capture):
    with capture:
        m.print_function()
    assert (
        capture
        == """
        Hello, World!
        1 2.0 three True -- multiple args
        *args-and-a-custom-separator
        no new line here -- next print
        flush
        py::print + str.format = this
    """
    )
    assert capture.stderr == "this goes to stderr"

    with pytest.raises(RuntimeError) as excinfo:
        m.print_failure()
    assert str(excinfo.value) == "Unable to convert call argument " + (
        "'1' of type 'UnregisteredType' to Python object"
        if detailed_error_messages_enabled
        else "to Python object (#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)"
    )


def test_hash():
    class Hashable:
        def __init__(self, value):
            self.value = value

        def __hash__(self):
            return self.value

    class Unhashable:
        __hash__ = None

    assert m.hash_function(Hashable(42)) == 42
    with pytest.raises(TypeError):
        m.hash_function(Unhashable())


def test_number_protocol():
    for a, b in [(1, 1), (3, 5)]:
        li = [
            a == b,
            a != b,
            a < b,
            a <= b,
            a > b,
            a >= b,
            a + b,
            a - b,
            a * b,
            a / b,
            a | b,
            a & b,
            a ^ b,
            a >> b,
            a << b,
        ]
        assert m.test_number_protocol(a, b) == li


def test_list_slicing():
    li = list(range(100))
    assert li[::2] == m.test_list_slicing(li)


def test_issue2361():
    # See issue #2361
    assert m.issue2361_str_implicit_copy_none() == "None"
    with pytest.raises(TypeError) as excinfo:
        assert m.issue2361_dict_implicit_copy_none()
    assert "NoneType" in str(excinfo.value)
    assert "iterable" in str(excinfo.value)


@pytest.mark.parametrize(
    "method, args, fmt, expected_view",
    [
        (m.test_memoryview_object, (b"red",), "B", b"red"),
        (m.test_memoryview_buffer_info, (b"green",), "B", b"green"),
        (m.test_memoryview_from_buffer, (False,), "h", [3, 1, 4, 1, 5]),
        (m.test_memoryview_from_buffer, (True,), "H", [2, 7, 1, 8]),
        (m.test_memoryview_from_buffer_nativeformat, (), "@i", [4, 7, 5]),
    ],
)
def test_memoryview(method, args, fmt, expected_view):
    view = method(*args)
    assert isinstance(view, memoryview)
    assert view.format == fmt
    assert list(view) == list(expected_view)


@pytest.mark.xfail("env.PYPY", reason="getrefcount is not available")
@pytest.mark.parametrize(
    "method",
    [
        m.test_memoryview_object,
        m.test_memoryview_buffer_info,
    ],
)
def test_memoryview_refcount(method):
    buf = b"\x0a\x0b\x0c\x0d"
    ref_before = sys.getrefcount(buf)
    view = method(buf)
    ref_after = sys.getrefcount(buf)
    assert ref_before < ref_after
    assert list(view) == list(buf)


def test_memoryview_from_buffer_empty_shape():
    view = m.test_memoryview_from_buffer_empty_shape()
    assert isinstance(view, memoryview)
    assert view.format == "B"
    assert bytes(view) == b""


def test_test_memoryview_from_buffer_invalid_strides():
    with pytest.raises(RuntimeError):
        m.test_memoryview_from_buffer_invalid_strides()


def test_test_memoryview_from_buffer_nullptr():
    with pytest.raises(ValueError):
        m.test_memoryview_from_buffer_nullptr()


def test_memoryview_from_memory():
    view = m.test_memoryview_from_memory()
    assert isinstance(view, memoryview)
    assert view.format == "B"
    assert bytes(view) == b"\xff\xe1\xab\x37"


def test_builtin_functions():
    assert m.get_len([i for i in range(42)]) == 42
    with pytest.raises(TypeError) as exc_info:
        m.get_len(i for i in range(42))
    assert str(exc_info.value) in [
        "object of type 'generator' has no len()",
        "'generator' has no length",
    ]  # PyPy


def test_isinstance_string_types():
    assert m.isinstance_pybind11_bytes(b"")
    assert not m.isinstance_pybind11_bytes("")

    assert m.isinstance_pybind11_str("")
    if hasattr(m, "PYBIND11_STR_LEGACY_PERMISSIVE"):
        assert m.isinstance_pybind11_str(b"")
    else:
        assert not m.isinstance_pybind11_str(b"")


def test_pass_bytes_or_unicode_to_string_types():
    assert m.pass_to_pybind11_bytes(b"Bytes") == 5
    with pytest.raises(TypeError):
        m.pass_to_pybind11_bytes("Str")

    if hasattr(m, "PYBIND11_STR_LEGACY_PERMISSIVE"):
        assert m.pass_to_pybind11_str(b"Bytes") == 5
    else:
        with pytest.raises(TypeError):
            m.pass_to_pybind11_str(b"Bytes")
    assert m.pass_to_pybind11_str("Str") == 3

    assert m.pass_to_std_string(b"Bytes") == 5
    assert m.pass_to_std_string("Str") == 3

    malformed_utf8 = b"\x80"
    if hasattr(m, "PYBIND11_STR_LEGACY_PERMISSIVE"):
        assert m.pass_to_pybind11_str(malformed_utf8) == 1
    else:
        with pytest.raises(TypeError):
            m.pass_to_pybind11_str(malformed_utf8)


@pytest.mark.parametrize(
    "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),
    ],
)
def test_weakref(create_weakref, create_weakref_with_callback):
    from weakref import getweakrefcount

    # Apparently, you cannot weakly reference an object()
    class WeaklyReferenced:
        pass

    callback_called = False

    def callback(wr):
        nonlocal callback_called
        callback_called = True

    obj = WeaklyReferenced()
    assert getweakrefcount(obj) == 0
    wr = create_weakref(obj)
    assert getweakrefcount(obj) == 1

    obj = WeaklyReferenced()
    assert getweakrefcount(obj) == 0
    wr = create_weakref_with_callback(obj, callback)  # noqa: F841
    assert getweakrefcount(obj) == 1
    assert not callback_called
    del obj
    pytest.gc_collect()
    assert callback_called


@pytest.mark.parametrize(
    "create_weakref, has_callback",
    [
        (m.weakref_from_handle, False),
        (m.weakref_from_object, False),
        (m.weakref_from_handle_and_function, True),
        (m.weakref_from_object_and_function, True),
    ],
)
def test_weakref_err(create_weakref, has_callback):
    class C:
        __slots__ = []

    def callback(_):
        pass

    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)


def test_cpp_iterators():
    assert m.tuple_iterator() == 12
    assert m.dict_iterator() == 305 + 711
    assert m.passed_iterator(iter((-7, 3))) == -4


def test_implementation_details():
    lst = [39, 43, 92, 49, 22, 29, 93, 98, 26, 57, 8]
    tup = tuple(lst)
    assert m.sequence_item_get_ssize_t(lst) == 43
    assert m.sequence_item_set_ssize_t(lst) is None
    assert lst[1] == "peppa"
    assert m.sequence_item_get_size_t(lst) == 92
    assert m.sequence_item_set_size_t(lst) is None
    assert lst[2] == "george"
    assert m.list_item_get_ssize_t(lst) == 49
    assert m.list_item_set_ssize_t(lst) is None
    assert lst[3] == "rebecca"
    assert m.list_item_get_size_t(lst) == 22
    assert m.list_item_set_size_t(lst) is None
    assert lst[4] == "richard"
    assert m.tuple_item_get_ssize_t(tup) == 29
    assert m.tuple_item_set_ssize_t() == ("emely", "edmond")
    assert m.tuple_item_get_size_t(tup) == 93
    assert m.tuple_item_set_size_t() == ("candy", "cat")


def test_external_float_():
    r1 = m.square_float_(2.0)
    assert r1 == 4.0


def test_tuple_rvalue_getter():
    pop = 1000
    tup = tuple(range(pop))
    m.tuple_rvalue_getter(tup)


def test_list_rvalue_getter():
    pop = 1000
    my_list = list(range(pop))
    m.list_rvalue_getter(my_list)


def test_populate_dict_rvalue():
    pop = 1000
    my_dict = {i: i for i in range(pop)}
    assert m.populate_dict_rvalue(pop) == my_dict


def test_populate_obj_str_attrs():
    pop = 1000
    o = types.SimpleNamespace(**{str(i): i for i in range(pop)})
    new_o = m.populate_obj_str_attrs(o, pop)
    new_attrs = {k: v for k, v in new_o.__dict__.items() if not k.startswith("_")}
    assert all(isinstance(v, str) for v in new_attrs.values())
    assert len(new_attrs) == pop


@pytest.mark.parametrize(
    "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)))])
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)])
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)])
def test_inplace_divide(a, b):
    expected = a / b
    assert m.inplace_divide(a, b) == expected


@pytest.mark.parametrize(
    "a,b",
    [
        (False, True),
        (
            set(),
            {
                1,
            },
        ),
    ],
)
def test_inplace_or(a, b):
    expected = a | b
    assert m.inplace_or(a, b) == expected


@pytest.mark.parametrize(
    "a,b",
    [
        (True, False),
        (
            {1, 2, 3},
            {
                1,
            },
        ),
    ],
)
def test_inplace_and(a, b):
    expected = a & b
    assert m.inplace_and(a, b) == expected


@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)])
def test_inplace_rshift(a, b):
    expected = a >> b
    assert m.inplace_rshift(a, b) == expected
