diff --git a/machine/scripture/__init__.py b/machine/scripture/__init__.py index 40863708..bb0080a4 100644 --- a/machine/scripture/__init__.py +++ b/machine/scripture/__init__.py @@ -20,7 +20,7 @@ SEPTUAGINT_VERSIFICATION, VULGATE_VERSIFICATION, ) -from .parse import get_books, get_chapters +from .parse import get_books, get_chapters, try_get_chapters from .verse_ref import ( NULL_VERSIFICATION, VERSE_RANGE_SEPARATOR, @@ -44,6 +44,7 @@ "get_bbbcccvvv", "get_books", "get_chapters", + "try_get_chapters", "is_book_id_valid", "is_canonical", "is_nt", diff --git a/machine/scripture/parse.py b/machine/scripture/parse.py index c5878302..5fa52b77 100644 --- a/machine/scripture/parse.py +++ b/machine/scripture/parse.py @@ -1,5 +1,5 @@ import re -from typing import Dict, List, Set, Union +from typing import Dict, List, Optional, Set, Union from .canon import book_id_to_number, book_number_to_id from .constants import ORIGINAL_VERSIFICATION @@ -57,6 +57,8 @@ def _update_selection(book_set: Set[int], book_nums: Set[int], subtraction: bool def parse_selection(selection: str, versification: Versification) -> Dict[int, List[int]]: selection = selection.strip() + if len(selection) == 0: + raise ValueError("Empty book range.") chapters = {} if selection[-1].isdigit() and len(selection) > 3: # Specific chapters from one book @@ -179,3 +181,12 @@ def get_chapters( chapters[book] = selection_chapters[book] return chapters + + +def try_get_chapters( + selections: Union[str, List[str]], versification: Versification = ORIGINAL_VERSIFICATION +) -> Optional[Dict[int, List[int]]]: + try: + return get_chapters(selections, versification) + except ValueError: + return None diff --git a/tests/scripture/test_parse.py b/tests/scripture/test_parse.py index b56c3451..caaae7f2 100644 --- a/tests/scripture/test_parse.py +++ b/tests/scripture/test_parse.py @@ -1,6 +1,6 @@ from pytest import raises -from machine.scripture import get_books, get_chapters +from machine.scripture import get_books, get_chapters, try_get_chapters def test_get_books() -> None: @@ -177,3 +177,30 @@ def test_get_chapters() -> None: get_chapters("OT,MAT1") with raises(ValueError): get_chapters("OT,MAT-LUK") + + # empty segments + with raises(ValueError): + get_chapters("MAT;;MRK") + with raises(ValueError): + get_chapters(" ; ") + with raises(ValueError): + get_chapters(";") + + +def test_try_get_chapters() -> None: + assert try_get_chapters("MAT1-4,12,9") == {40: [1, 2, 3, 4, 9, 12]} + assert try_get_chapters("") == {} + assert try_get_chapters(["MAT", "-MAT 1"]) == {40: list(range(2, 29))} + + # invalid syntax, book, chapter, and subtraction + assert try_get_chapters("OT,MAT1") is None + assert try_get_chapters("ABC") is None + assert try_get_chapters("MAT 500") is None + assert try_get_chapters("MAT3-1") is None + assert try_get_chapters("-MRK") is None + assert try_get_chapters("MRK 2-5;-MRK 6") is None + + # empty segments + assert try_get_chapters("MAT;;MRK") is None + assert try_get_chapters(" ; ") is None + assert try_get_chapters(";") is None