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
17 changes: 15 additions & 2 deletions bibtexparser/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,12 @@ def get(self, key: str, default=None) -> Optional[Field]:
return self.fields_dict.get(key, default)

def __contains__(self, key: str) -> bool:
"""Dict-mimicking ``in`` operator."""
"""Dict-mimicking ``in`` operator.

As in ``__getitem__``, ``ENTRYTYPE`` and ``ID`` are always contained.
"""
if key in ("ENTRYTYPE", "ID"):
return True
return key in self.fields_dict

def __getitem__(self, key: str) -> Any:
Expand All @@ -400,8 +405,16 @@ def __setitem__(self, key: str, value: Any):

This serves for partial v1.x backwards compatibility,
as well as for a shorthand for `set_field`.

Mirroring ``__getitem__``, the keys ``ENTRYTYPE`` and ``ID``
set ``entry_type`` and ``key`` instead of a field.
"""
self.set_field(Field(key, value))
if key == "ENTRYTYPE":
self.entry_type = value
elif key == "ID":
self.key = value
else:
self.set_field(Field(key, value))

def __delitem__(self, key: str) -> None:
"""Dict-mimicking index.
Expand Down
24 changes: 24 additions & 0 deletions tests/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,30 @@ def test_entry_contains():
entry = Entry("article", "key", [Field("field", "value", 1)], 1, "raw")
assert "field" in entry
assert "other" not in entry
# ENTRYTYPE and ID are exposed by `__getitem__`, hence always contained
assert "ENTRYTYPE" in entry
assert "ID" in entry


def test_entry_setitem_field():
entry = Entry("article", "key", [Field("field", "value", 1)], 1, "raw")
entry["field"] = "new_value"
entry["other"] = "other_value"
assert entry["field"] == "new_value"
assert entry["other"] == "other_value"
assert [f.key for f in entry.fields] == ["field", "other"]


def test_entry_setitem_entrytype_and_id():
entry = Entry("article", "key", [Field("field", "value", 1)], 1, "raw")
entry["ENTRYTYPE"] = "book"
entry["ID"] = "new_key"
assert entry.entry_type == "book"
assert entry.key == "new_key"
assert entry["ENTRYTYPE"] == "book"
assert entry["ID"] == "new_key"
# No literal fields must be created for these keys
assert [f.key for f in entry.fields] == ["field"]


def test_string_equality():
Expand Down
Loading