diff --git a/betty/functools.py b/betty/functools.py index 643090a3a..2c4ec005b 100644 --- a/betty/functools.py +++ b/betty/functools.py @@ -22,38 +22,12 @@ TYPE_CHECKING, ) -from betty.warnings import deprecated - if TYPE_CHECKING: from collections.abc import MutableSequence _T = TypeVar("_T") -@deprecated( - "This function is deprecated as of Betty 0.3.5, and will be removed in Betty 0.4.x. Instead, use a custom function, tailored to your data type." -) -def walk(item: Any, attribute_name: str) -> Iterable[Any]: - """ - Walk over a graph of objects by following a single attribute. - """ - child = getattr(item, attribute_name) - - # If the child has the requested attribute, yield it, - if hasattr(child, attribute_name): - yield child - yield from walk(child, attribute_name) - - # Otherwise loop over the children and yield their attributes. - try: - child_children = iter(child) - except TypeError: - return - for child_child in child_children: - yield child_child - yield from walk(child_child, attribute_name) - - def slice_to_range(indices: slice, iterable: Sized) -> Iterable[int]: """ Apply a slice to an iterable, and return the corresponding range. diff --git a/betty/jinja2/filter.py b/betty/jinja2/filter.py index 59bf84da2..9e8c93f33 100644 --- a/betty/jinja2/filter.py +++ b/betty/jinja2/filter.py @@ -35,7 +35,6 @@ from pdf2image.pdf2image import convert_from_path from betty import _resizeimage -from betty.functools import walk from betty.hashid import hashid_file_meta, hashid from betty.locale import ( negotiate_localizeds, @@ -147,13 +146,6 @@ async def filter_flatten(values_of_values: Iterable[Iterable[_T]]) -> AsyncItera yield value -def filter_walk(value: Any, attribute_name: str) -> Iterable[Any]: - """ - Walk over a data structure. - """ - return walk(value, attribute_name) - - _paragraph_re = re.compile(r"(?:\r\n|\r|\n){2,}") @@ -588,7 +580,6 @@ def filter_public_js(context: Context, public_path: str) -> None: "upper_camel_case_to_lower_camel_case": upper_camel_case_to_lower_camel_case, "url": filter_url, "void_none": void_none, - "walk": filter_walk, "public_css": filter_public_css, "public_js": filter_public_js, } diff --git a/betty/tests/test_functools.py b/betty/tests/test_functools.py index 364536fc1..6d0ca8516 100644 --- a/betty/tests/test_functools.py +++ b/betty/tests/test_functools.py @@ -1,74 +1,13 @@ from collections.abc import Awaitable, Callable, Iterable -from typing import Any, Self, TypeVar +from typing import Any, TypeVar import pytest -from betty.functools import walk, slice_to_range, Do, Uniquifier -from betty.warnings import BettyDeprecationWarning +from betty.functools import slice_to_range, Do, Uniquifier _T = TypeVar("_T") -class TestWalk: - class _Item: - def __init__(self, child: Self | Iterable[Self] | None): - self.child = child - - @pytest.mark.parametrize( - "item", - [ - None, - True, - object(), - [], - ], - ) - async def test_with_invalid_attribute(self, item: Any) -> None: - with pytest.warns(BettyDeprecationWarning), pytest.raises(AttributeError): - list(walk(item, "invalid_attribute_name")) - - async def test_one_to_one_without_descendants(self) -> None: - with pytest.warns(BettyDeprecationWarning): - item = self._Item(None) - actual = walk(item, "child") - expected: list[None] = [] - assert expected == list(actual) - - async def test_one_to_one_with_descendants(self) -> None: - with pytest.warns(BettyDeprecationWarning): - grandchild = self._Item(None) - child = self._Item(grandchild) - item = self._Item(child) - actual = walk(item, "child") - expected = [child, grandchild] - assert expected == list(actual) - - async def test_one_to_many_without_descendants(self) -> None: - with pytest.warns(BettyDeprecationWarning): - item = self._Item([]) - actual = walk(item, "child") - expected: list[None] = [] - assert expected == list(actual) - - async def test_with_one_to_many_descendants(self) -> None: - with pytest.warns(BettyDeprecationWarning): - grandchild = self._Item([]) - child = self._Item([grandchild]) - item = self._Item([child]) - actual = walk(item, "child") - expected = [child, grandchild] - assert expected == list(actual) - - async def test_with_mixed_descendants(self) -> None: - with pytest.warns(BettyDeprecationWarning): - grandchild = self._Item([]) - child = self._Item(grandchild) - item = self._Item([child]) - actual = walk(item, "child") - expected = [child, grandchild] - assert expected == list(actual) - - class TestSliceToRange: @pytest.mark.parametrize( ("expected_range_items", "ranged_slice"), diff --git a/betty/tests/test_jinja2.py b/betty/tests/test_jinja2.py index 861899b1b..f25c563e6 100644 --- a/betty/tests/test_jinja2.py +++ b/betty/tests/test_jinja2.py @@ -1,7 +1,7 @@ from __future__ import annotations from pathlib import Path -from typing import Iterable, Any, Self +from typing import Iterable, Any import aiofiles import pytest @@ -24,7 +24,6 @@ Citation, ) from betty.tests import TemplateTestCase -from betty.warnings import BettyDeprecationWarning class TestJinja2Provider: @@ -71,43 +70,6 @@ async def test(self, expected: str, template: str) -> None: assert expected == actual -class TestFilterWalk(TemplateTestCase): - class WalkData: - def __init__(self, label: str, children: Iterable[Self] | None = None): - self._label = label - self.children = children or [] - - def __str__(self) -> str: - return self._label - - @pytest.mark.parametrize( - ("expected", "template", "data"), - [ - ("", '{{ data | walk("children") | join }}', WalkData("parent")), - ( - "child1, child1child1, child2", - '{{ data | walk("children") | join(", ") }}', - WalkData( - "parent", - [ - WalkData("child1", [WalkData("child1child1")]), - WalkData("child2"), - ], - ), - ), - ], - ) - async def test(self, expected: str, template: str, data: WalkData) -> None: - with pytest.warns(BettyDeprecationWarning): - async with self._render( - template_string=template, - data={ - "data": data, - }, - ) as (actual, _): - assert expected == actual - - class TestFilterParagraphs(TemplateTestCase): @pytest.mark.parametrize( ("expected", "template"),