diff --git a/bibtexparser/entrypoint.py b/bibtexparser/entrypoint.py index 52a2505..380607a 100644 --- a/bibtexparser/entrypoint.py +++ b/bibtexparser/entrypoint.py @@ -31,6 +31,7 @@ def _build_parse_stack( if append_middleware is None: return list(parse_stack) + append_middleware = list(append_middleware) parse_stack_types = [type(m) for m in parse_stack] append_stack_types = {type(m) for m in append_middleware} stack_types_intersect = set(parse_stack_types).intersection(append_stack_types) @@ -61,13 +62,14 @@ def _build_unparse_stack( if prepend_middleware is None: return list(unparse_stack) - parse_stack_types = [type(m) for m in unparse_stack] - append_stack_types = {type(m) for m in prepend_middleware} - stack_types_intersect = set(parse_stack_types).intersection(append_stack_types) + prepend_middleware = list(prepend_middleware) + unparse_stack_types = [type(m) for m in unparse_stack] + prepend_stack_types = {type(m) for m in prepend_middleware} + stack_types_intersect = set(unparse_stack_types).intersection(prepend_stack_types) if len(stack_types_intersect) > 0: warnings.warn( - "Some middleware passed in append_middleware are " - f"already in the default parse_stack ({stack_types_intersect})." + "Some middleware passed in prepend_middleware are " + f"already in the default unparse_stack ({stack_types_intersect})." ) return list(prepend_middleware) + list(unparse_stack) diff --git a/tests/test_entrypoint.py b/tests/test_entrypoint.py index 43ace6c..b76e8a0 100644 --- a/tests/test_entrypoint.py +++ b/tests/test_entrypoint.py @@ -7,13 +7,49 @@ import pytest from bibtexparser import parse_file +from bibtexparser import parse_string from bibtexparser import write_file from bibtexparser import write_string from bibtexparser.library import Library +from bibtexparser.middlewares import NormalizeFieldKeys +from bibtexparser.middlewares import SortFieldsCustomMiddleware from bibtexparser.model import Entry from bibtexparser.model import Field +def test_parse_string_applies_append_middleware_from_iterator(): + """One-shot middleware iterables must not be exhausted while checking duplicates.""" + middleware = iter([NormalizeFieldKeys()]) + + library = parse_string( + "@article{test, TITLE = {Iterator middleware}}", + append_middleware=middleware, + ) + + assert library.entries[0].fields[0].key == "title" + + +def test_write_string_applies_prepend_middleware_from_iterator(): + """One-shot unparse middleware iterables must execute before the default stack.""" + library = Library( + [ + Entry( + entry_type="article", + key="test", + fields=[ + Field(key="title", value="Iterator middleware"), + Field(key="year", value="2026"), + ], + ) + ] + ) + middleware = iter([SortFieldsCustomMiddleware(order=("year", "title"))]) + + written = write_string(library, prepend_middleware=middleware) + + assert written.index("\tyear") < written.index("\ttitle") + + def test_gbk(): library = parse_file("tests/resources/gbk_test.bib", encoding="gbk") assert library.entries[0]["author"] == "凯撒"