From d9cf9e82bf490c652f623922031600b4eb3b59d8 Mon Sep 17 00:00:00 2001 From: mmporong Date: Sat, 31 Oct 2026 19:47:34 +0900 Subject: [PATCH 1/2] =?UTF-8?q?fix(map):=20=EB=B2=94=EC=9C=84=20=EB=B0=96?= =?UTF-8?q?=20=EC=8B=9C=EC=A0=90=EC=9D=98=20=EA=B0=80=EC=8B=9C=EC=84=B1=20?= =?UTF-8?q?=EB=B2=84=ED=8D=BC=20=EC=B4=88=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tcod/map.py | 2 +- tests/test_tcod.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/tcod/map.py b/tcod/map.py index e1f4403b..c44bed91 100644 --- a/tcod/map.py +++ b/tcod/map.py @@ -246,7 +246,7 @@ def compute_fov( RuntimeWarning, stacklevel=2, ) - map_buffer: NDArray[np.bool_] = np.empty( + map_buffer: NDArray[np.bool_] = np.zeros( transparency.shape, dtype=[("transparent", bool), ("walkable", bool), ("fov", bool)], ) diff --git a/tests/test_tcod.py b/tests/test_tcod.py index 3f8c1d9b..a6afccfa 100644 --- a/tests/test_tcod.py +++ b/tests/test_tcod.py @@ -60,6 +60,17 @@ def test_tcod_bsp() -> None: str(bsp) +@pytest.mark.parametrize("pov", [(-1, 0), (0, -1), (3, 0), (0, 5)]) +def test_compute_fov_out_of_bounds(pov: tuple[int, int], monkeypatch: pytest.MonkeyPatch) -> None: + transparency = np.ones((3, 5), dtype=bool) + # Model an uninitialized allocation containing stale visible cells. + monkeypatch.setattr(np, "empty", np.ones) + with pytest.warns(RuntimeWarning, match="outside the array"): + visible = tcod.map.compute_fov(transparency, pov) + assert visible.shape == transparency.shape + assert not visible.any() + + @pytest.mark.filterwarnings("ignore:Use map.+ to check for this") @pytest.mark.filterwarnings("ignore:This class may perform poorly") def test_tcod_map_set_bits() -> None: From d1e182c3d43712ee17189489e008b99389930793 Mon Sep 17 00:00:00 2001 From: Lim-jooyoung Date: Sun, 1 Nov 2026 08:29:11 +0900 Subject: [PATCH 2/2] Reject out-of-bounds field-of-view origins --- CHANGELOG.md | 4 ++++ tcod/map.py | 12 ++++-------- tests/test_tcod.py | 16 ++++++++++------ 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd1db159..8185d75c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ This project adheres to [Semantic Versioning](https://semver.org/) since version ## [Unreleased] +### Changed + +- `tcod.map.compute_fov` now raises `ValueError` instead of warning when `pov` is outside the transparency array, as previously announced by the warning. + ## [21.2.2] - 2026-10-22 ### Changed diff --git a/tcod/map.py b/tcod/map.py index c44bed91..2ae1725b 100644 --- a/tcod/map.py +++ b/tcod/map.py @@ -180,7 +180,7 @@ def compute_fov( `pov` is the point-of-view origin point. Areas are visible if they can be seen from this position. `pov` should be a 2D index matching the axes of the `transparency` array, and must be within the bounds of the - `transparency` array. + `transparency` array. A `ValueError` is raised if `pov` is out of bounds. `radius` is the maximum view distance from `pov`. If this is zero then the maximum distance is used. @@ -240,13 +240,9 @@ def compute_fov( msg = "The tcod.map.compute_fov function has changed. The `x` and `y` parameters should now be given as a single tuple." raise TypeError(msg) if not (0 <= pov[0] < transparency.shape[0] and 0 <= pov[1] < transparency.shape[1]): - warnings.warn( - f"Given pov index {pov!r} is outside the array of shape {transparency.shape!r}." - "\nThis will raise an error in future versions.", - RuntimeWarning, - stacklevel=2, - ) - map_buffer: NDArray[np.bool_] = np.zeros( + msg = f"Given pov index {pov!r} is outside the array of shape {transparency.shape!r}." + raise ValueError(msg) + map_buffer: NDArray[np.bool_] = np.empty( transparency.shape, dtype=[("transparent", bool), ("walkable", bool), ("fov", bool)], ) diff --git a/tests/test_tcod.py b/tests/test_tcod.py index a6afccfa..27801343 100644 --- a/tests/test_tcod.py +++ b/tests/test_tcod.py @@ -61,14 +61,18 @@ def test_tcod_bsp() -> None: @pytest.mark.parametrize("pov", [(-1, 0), (0, -1), (3, 0), (0, 5)]) -def test_compute_fov_out_of_bounds(pov: tuple[int, int], monkeypatch: pytest.MonkeyPatch) -> None: +def test_compute_fov_out_of_bounds(pov: tuple[int, int]) -> None: transparency = np.ones((3, 5), dtype=bool) - # Model an uninitialized allocation containing stale visible cells. - monkeypatch.setattr(np, "empty", np.ones) - with pytest.warns(RuntimeWarning, match="outside the array"): - visible = tcod.map.compute_fov(transparency, pov) + with pytest.raises(ValueError, match="outside the array"): + tcod.map.compute_fov(transparency, pov) + + +@pytest.mark.parametrize("pov", [(0, 0), (0, 4), (2, 0), (2, 4)]) +def test_compute_fov_at_boundary(pov: tuple[int, int]) -> None: + transparency = np.ones((3, 5), dtype=bool) + visible = tcod.map.compute_fov(transparency, pov) assert visible.shape == transparency.shape - assert not visible.any() + assert visible.all() @pytest.mark.filterwarnings("ignore:Use map.+ to check for this")