diff --git a/tests/test_types.py b/tests/test_types.py new file mode 100644 index 00000000..a035dde0 --- /dev/null +++ b/tests/test_types.py @@ -0,0 +1,48 @@ +import tomlkit + +from tomlkit.items import Array +from tomlkit.items import Table + + +def test_custom_list_add_returns_combined_items() -> None: + arr = tomlkit.array() + arr.extend([1, 2, 3]) + + result = arr + [4, 5] # noqa: RUF005 (exercising __add__ itself) + + assert result == [1, 2, 3, 4, 5] + + +def test_custom_list_iadd_mutates_in_place_and_keeps_wrapper_type() -> None: + arr = tomlkit.array() + arr.extend([1, 2]) + original_id = id(arr) + + arr += [9] + + assert arr == [1, 2, 9] + assert isinstance(arr, Array) + assert id(arr) == original_id + + +def test_custom_dict_or_returns_new_table_with_merged_items() -> None: + table = tomlkit.table() + table["a"] = 1 + table["b"] = 2 + + result = table | {"c": 3} + + assert dict(result) == {"a": 1, "b": 2, "c": 3} + assert isinstance(result, Table) + assert result is not table + + +def test_custom_dict_ior_mutates_in_place() -> None: + table = tomlkit.table() + table["x"] = 1 + original_id = id(table) + + table |= {"y": 2} + + assert dict(table) == {"x": 1, "y": 2} + assert id(table) == original_id diff --git a/tomlkit/_types.py b/tomlkit/_types.py index 3585d56c..5f5f66c1 100644 --- a/tomlkit/_types.py +++ b/tomlkit/_types.py @@ -12,7 +12,6 @@ "_CustomFloat", "_CustomInt", "_CustomList", - "wrap_method", ] if TYPE_CHECKING: # pragma: no cover @@ -31,13 +30,8 @@ from builtins import float as _CustomFloat from builtins import int as _CustomInt from builtins import list as _CustomList - from typing import Callable - from typing import Concatenate - from typing import ParamSpec from typing import Protocol - P = ParamSpec("P") - class WrapperType(Protocol): def _new(self: WT, value: Any) -> WT: ... @@ -76,15 +70,3 @@ class _CustomInt(Integral, int): class _CustomFloat(Real, float): """Adds Real mixin while pretending to be a builtin float""" - - -def wrap_method( - original_method: Callable[Concatenate[WT, P], Any], -) -> Callable[Concatenate[WT, P], Any]: - def wrapper(self: WT, /, *args: P.args, **kwargs: P.kwargs) -> Any: - result = original_method(self, *args, **kwargs) - if result is NotImplemented: - return result - return self._new(result) - - return wrapper