Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions tests/test_items.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from __future__ import annotations

import copy
import ctypes
import math
import pickle
import sys

from collections.abc import Callable
from datetime import date
Expand Down Expand Up @@ -101,6 +103,18 @@ def test_float_unwrap() -> None:
elementary_test(item(2.78), float)


@pytest.mark.skipif(
sys.implementation.name != "cpython", reason="PySequence_Check is CPython-specific"
)
def test_float_is_not_a_sequence() -> None:
value = parse("a = [1.0, 2.0, 3.0]")["a"][0]
py_sequence_check = ctypes.pythonapi.PySequence_Check
py_sequence_check.argtypes = [ctypes.py_object]
py_sequence_check.restype = ctypes.c_int

assert not py_sequence_check(value)


def test_false_unwrap() -> None:
elementary_test(item(False), bool)

Expand Down
19 changes: 5 additions & 14 deletions tomlkit/items.py
Original file line number Diff line number Diff line change
Expand Up @@ -540,15 +540,6 @@ def __reduce__(self) -> tuple[type, tuple[object, ...]]:
def __reduce_ex__(self, protocol: int) -> tuple[type, tuple[object, ...]]: # type: ignore[override]
return self.__class__, self._getstate(protocol)

def __getitem__(self, key: Key | str | int) -> Any:
raise TypeError(f"{type(self).__name__} does not support item access")

def __setitem__(self, key: Key | str | int, value: Any) -> None:
raise TypeError(f"{type(self).__name__} does not support item assignment")

def __delitem__(self, key: Key | str | int) -> None:
raise TypeError(f"{type(self).__name__} does not support item deletion")


class Whitespace(Item):
"""
Expand Down Expand Up @@ -1824,10 +1815,10 @@ def __iter__(self) -> Iterator[str]:
def __len__(self) -> int:
return len(self._value)

def __delitem__(self, key: Key | str) -> None: # type: ignore[override]
def __delitem__(self, key: Key | str) -> None:
self.remove(key)

def __getitem__(self, key: Key | str) -> Any: # type: ignore[override]
def __getitem__(self, key: Key | str) -> Any:
return self._value[key]

def __contains__(self, key: object) -> bool:
Expand All @@ -1839,7 +1830,7 @@ def __contains__(self, key: object) -> bool:
# for an out-of-order entry, so validation runs exactly as before.
return key in self._value

def __setitem__(self, key: Key | str, value: Any) -> None: # type: ignore[override]
def __setitem__(self, key: Key | str, value: Any) -> None:
if not isinstance(value, Item):
value = item(value, _parent=self)

Expand Down Expand Up @@ -2181,7 +2172,7 @@ def _render_dotted(self, key: Key, table: Table) -> list[str]:
)
return parts

def __setitem__(self, key: Key | str, value: Any) -> None: # type: ignore[override]
def __setitem__(self, key: Key | str, value: Any) -> None:
if hasattr(value, "trivia") and value.trivia.comment:
value.trivia.comment = ""
if not isinstance(value, Item):
Expand All @@ -2196,7 +2187,7 @@ def _getstate(self, protocol: int = 3) -> tuple[container.Container, Trivia]:
return (self._value, self._trivia)


class String(str, Item): # type: ignore[misc]
class String(str, Item):
"""
A string literal.
"""
Expand Down