From 6422e9ca08dcb32c72b8db3018dae2c0e7b0e68e Mon Sep 17 00:00:00 2001 From: Mark Matchynski Date: Tue, 8 Sep 2026 14:25:51 -0700 Subject: [PATCH 1/4] Issue 168 - Fix parsing references with trailing periods after book names (#168) Fixes examples reported in #168 such as 'Micah. 2Ch. 34:20', 'Psalm. 46', 'Psalms. 74', and '1Peter. 1:22'. The parser now strips punctuation after the matched book name before interpreting chapter and verse values, avoiding empty-string int conversion errors. --- CHANGELOG.md | 4 ++ pythonbible/pythonbible/parser.py | 14 +++-- pythonbible/tests/parser/parser_test.py | 69 +++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0927888..5c29c40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- [Issue #168](https://github.com/avendesora/pythonbible/issues/168) - Parse references when book names are followed by periods. + ## [0.15.5] - 2026-01-24 ### Fixed diff --git a/pythonbible/pythonbible/parser.py b/pythonbible/pythonbible/parser.py index 4545fcb..7708c76 100644 --- a/pythonbible/pythonbible/parser.py +++ b/pythonbible/pythonbible/parser.py @@ -158,12 +158,19 @@ def _process_sub_references( start_chapter: int | None = None for sub_reference in reference.split(COMMA): - if (not sub_reference or sub_reference in {DASH, PERIOD}) and not references: + normalized_sub_reference = sub_reference.strip().lstrip(" .,:;-") + + if ( + not normalized_sub_reference + or normalized_sub_reference in {DASH, PERIOD} + ) and not references: references.append(NormalizedReference(book, None, None, None, None, book)) continue start_chapter, start_verse, end_chapter, end_verse = _process_sub_reference( - sub_reference[:-1] if sub_reference.endswith(DASH) else sub_reference, + normalized_sub_reference[:-1] + if normalized_sub_reference.endswith(DASH) + else normalized_sub_reference, book, start_chapter, ) @@ -195,7 +202,8 @@ def _process_sub_reference( end_verse: int | None = None no_verses: bool = False - clean_sub_reference: str = sub_reference.replace(PERIOD, COLON) + clean_sub_reference: str = sub_reference.strip().lstrip(" .,:;-") + clean_sub_reference = clean_sub_reference.replace(PERIOD, COLON) chapter_and_verse_range: list[str] = clean_sub_reference.split(DASH) min_chapter_and_verse: list[str] = chapter_and_verse_range[0].strip().split(COLON) diff --git a/pythonbible/tests/parser/parser_test.py b/pythonbible/tests/parser/parser_test.py index fc3a46a..c01b228 100644 --- a/pythonbible/tests/parser/parser_test.py +++ b/pythonbible/tests/parser/parser_test.py @@ -116,6 +116,75 @@ def test_normalize_reference_range_without_verse_numbers( ) +@pytest.mark.parametrize( + ("text", "expected"), + [ + ( + "Micah. 2", + [ + bible.NormalizedReference( + bible.Book.MICAH, + 2, + None, + 2, + None, + bible.Book.MICAH, + ) + ], + ), + ( + "Psalm. 46", + [ + bible.NormalizedReference( + bible.Book.PSALMS, + 46, + None, + 46, + None, + bible.Book.PSALMS, + ) + ], + ), + ( + "Psalms. 74", + [ + bible.NormalizedReference( + bible.Book.PSALMS, + 74, + None, + 74, + None, + bible.Book.PSALMS, + ) + ], + ), + ( + "1Peter. 1:22", + [ + bible.NormalizedReference( + bible.Book.PETER_1, + 1, + 22, + 1, + 22, + bible.Book.PETER_1, + ) + ], + ), + ], +) +def test_get_references_book_name_followed_by_period( + text: str, + expected: list[bible.NormalizedReference], +) -> None: + # Given a reference where a book name is immediately followed by a period + # When it is parsed + references: list[bible.NormalizedReference] = bible.get_references(text) + + # Then the reference is returned without crashing or discarding the chapter/verse + assert references == expected + + def test_get_references_roman_numerals( roman_numeral_references: str, normalized_references_complex: list[bible.NormalizedReference], From aaf45af368fc47a941aaf4bb18af25c884d1d015 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2026 22:18:48 +0000 Subject: [PATCH 2/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pythonbible/pythonbible/parser.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pythonbible/pythonbible/parser.py b/pythonbible/pythonbible/parser.py index 7708c76..f98cd46 100644 --- a/pythonbible/pythonbible/parser.py +++ b/pythonbible/pythonbible/parser.py @@ -161,8 +161,7 @@ def _process_sub_references( normalized_sub_reference = sub_reference.strip().lstrip(" .,:;-") if ( - not normalized_sub_reference - or normalized_sub_reference in {DASH, PERIOD} + not normalized_sub_reference or normalized_sub_reference in {DASH, PERIOD} ) and not references: references.append(NormalizedReference(book, None, None, None, None, book)) continue From d9d042f34d7cffc8ee4505e11b0d6b0d3135140c Mon Sep 17 00:00:00 2001 From: Mark Matchynski Date: Wed, 9 Sep 2026 12:28:33 -0700 Subject: [PATCH 3/4] Address parser review feedback --- pythonbible/pythonbible/parser.py | 3 ++- pythonbible/tests/parser/parser_test.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pythonbible/pythonbible/parser.py b/pythonbible/pythonbible/parser.py index f98cd46..6683bc6 100644 --- a/pythonbible/pythonbible/parser.py +++ b/pythonbible/pythonbible/parser.py @@ -161,7 +161,8 @@ def _process_sub_references( normalized_sub_reference = sub_reference.strip().lstrip(" .,:;-") if ( - not normalized_sub_reference or normalized_sub_reference in {DASH, PERIOD} + not normalized_sub_reference + or normalized_sub_reference in {DASH} ) and not references: references.append(NormalizedReference(book, None, None, None, None, book)) continue diff --git a/pythonbible/tests/parser/parser_test.py b/pythonbible/tests/parser/parser_test.py index c01b228..cadf09b 100644 --- a/pythonbible/tests/parser/parser_test.py +++ b/pythonbible/tests/parser/parser_test.py @@ -182,7 +182,8 @@ def test_get_references_book_name_followed_by_period( references: list[bible.NormalizedReference] = bible.get_references(text) # Then the reference is returned without crashing or discarding the chapter/verse - assert references == expected + if references != expected: + raise AssertionError(f"Expected {expected!r}, got {references!r}") def test_get_references_roman_numerals( From 4d3c4c8d03bfe560094ca53d670681c12d1f31da Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 9 Sep 2026 19:34:48 +0000 Subject: [PATCH 4/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pythonbible/pythonbible/parser.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pythonbible/pythonbible/parser.py b/pythonbible/pythonbible/parser.py index 6683bc6..a32dcf7 100644 --- a/pythonbible/pythonbible/parser.py +++ b/pythonbible/pythonbible/parser.py @@ -161,8 +161,7 @@ def _process_sub_references( normalized_sub_reference = sub_reference.strip().lstrip(" .,:;-") if ( - not normalized_sub_reference - or normalized_sub_reference in {DASH} + not normalized_sub_reference or normalized_sub_reference in {DASH} ) and not references: references.append(NormalizedReference(book, None, None, None, None, book)) continue