Skip to content

Commit

Permalink
✨ Optionally raise an exception when adding duplicate blocks (#425)
Browse files Browse the repository at this point in the history
  • Loading branch information
MiWeiss authored Nov 24, 2023
1 parent 40db93b commit 34dc875
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
20 changes: 19 additions & 1 deletion bibtexparser/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,40 @@ def __init__(self, blocks: Union[List[Block], None] = None):
if blocks is not None:
self.add(blocks)

def add(self, blocks: Union[List[Block], Block]):
def add(
self, blocks: Union[List[Block], Block], fail_on_duplicate_key: bool = False
):
"""Add blocks to library.
The adding is key-safe, i.e., it is made sure that no duplicate keys are added.
for the same type (i.e., String or Entry). Duplicates are silently replaced with
a DuplicateKeyBlock.
:param blocks: Block or list of blocks to add.
:param fail_on_duplicate_key: If True, raises ValueError if a block was replaced with a DuplicateKeyBlock.
"""
if isinstance(blocks, Block):
blocks = [blocks]

_added_blocks = []
for block in blocks:
# This may replace block with a DuplicateEntryKeyBlock
block = self._add_to_dicts(block)
self._blocks.append(block)
_added_blocks.append(block)

if fail_on_duplicate_key:
duplicate_keys = []
for original, added in zip(blocks, _added_blocks):
if not original is added and isinstance(added, DuplicateBlockKeyBlock):
duplicate_keys.append(added.key)

if len(duplicate_keys) > 0:
raise ValueError(
f"Duplicate keys found: {duplicate_keys}. "
f"Duplicate entries have been added to the library as DuplicateBlockKeyBlock."
f"Use `library.failed_blocks` to access them. "
)

def remove(self, blocks: Union[List[Block], Block]):
"""Remove blocks from library.
Expand Down
9 changes: 9 additions & 0 deletions tests/test_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,12 @@ def test_replace_fail_on_duplicate():
assert len(library.failed_blocks) == 0
assert library.entries[0].key == "Just a regular entry, to be replaced"
assert library.entries[1].key == "duplicateKey"


def test_fail_on_duplicate_add():
library = Library()
library.add(get_dummy_entry())
with pytest.raises(ValueError):
library.add(get_dummy_entry(), fail_on_duplicate_key=True)
assert len(library.blocks) == 2
assert len(library.failed_blocks) == 1

0 comments on commit 34dc875

Please sign in to comment.