From 3d8593f9ba7b7370dbe693912aa1ca74d3118765 Mon Sep 17 00:00:00 2001 From: Michael Weiss Date: Fri, 2 Oct 2026 17:50:03 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Support=20dict(entry)=20by=20adding?= =?UTF-8?q?=20Entry.keys()=20and=20=5F=5Fiter=5F=5F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Entry mimicked dicts via items(), __getitem__ etc., but lacked keys() and __iter__, so dict(entry) and list(entry) raised KeyError: 0 and {**entry} raised TypeError. Both return the keys in items() order. Refs #629 --- bibtexparser/model.py | 11 +++++++++++ tests/test_model.py | 8 ++++++++ 2 files changed, 19 insertions(+) diff --git a/bibtexparser/model.py b/bibtexparser/model.py index de332d2..e801bc9 100644 --- a/bibtexparser/model.py +++ b/bibtexparser/model.py @@ -1,4 +1,5 @@ import abc +from collections.abc import Iterator from typing import Any _ALLOWED_ENCLOSINGS = (None, "{", '"', "no-enclosing") @@ -454,6 +455,16 @@ def items(self) -> list[tuple[str, Any]]: ("ID", self.key), ] + [(f.key, f.value) for f in self.fields] + def keys(self) -> list[str]: + """Dict-mimicking, for partial v1.x backwards compatibility. + + Same keys and order as in `items()`, e.g. allowing ``dict(entry)``.""" + return [key for key, _ in self.items()] + + def __iter__(self) -> Iterator[str]: + """Dict-mimicking iteration over the keys, as in `keys()`.""" + return iter(self.keys()) + def __hash__(self) -> int: return hash((type(self), self._start_line_in_file, self._raw, self._entry_type, self._key)) diff --git a/tests/test_model.py b/tests/test_model.py index 575875f..fad6500 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -103,6 +103,14 @@ def test_entry_contains(): assert "ID" in entry +def test_entry_dict_conversion(): + entry = Entry("article", "key", [Field("field", "value", 1), Field("foo", "bar", 2)], 1, "raw") + assert list(entry) == ["ENTRYTYPE", "ID", "field", "foo"] + expected = {"ENTRYTYPE": "article", "ID": "key", "field": "value", "foo": "bar"} + assert dict(entry) == dict(entry.items()) == expected + assert {**entry} == expected + + def test_entry_setitem_field(): entry = Entry("article", "key", [Field("field", "value", 1)], 1, "raw") entry["field"] = "new_value"