Skip to content

Commit 01ac557

Browse files
author
TNFR AI Agent
committed
Fix NumPy boolean radius admission across supported versions
1 parent c15b596 commit 01ac557

3 files changed

Lines changed: 18 additions & 2 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ All notable changes to this project will be documented in this file.
2929
- Centralize represented-real admission for pressure, phase, capacity, nodal
3030
arithmetic, coherence observations and validation consumers. Retain explicit
3131
unavailable evidence and reject invalid inputs before coercion or caching.
32+
- Reject NumPy booleans as neighborhood radii across supported NumPy versions,
33+
while preserving integer-index inputs for structural and phase observations.
3234
- Consolidate JSON input/output and detached report serialization, including
3335
duplicate/colliding keys, unsupported labels and non-finite values. Reports
3436
and construction recipes remain distinct from resumable checkpoints.

‎src/tnfr/metrics/local_coherence.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@
1313
from operator import index as integer_index
1414
from typing import Any
1515

16+
from ..mathematics.unified_numerical import np
1617
from .common import _coherence_on_nodes
1718

1819

1920
def _radius_nodes(G: Any, node: Any, radius: int) -> tuple[Any, ...]:
2021
"""Return the validated center-inclusive outgoing graph ball once per node."""
21-
if isinstance(radius, bool) or type(radius).__name__ == "bool_":
22+
if isinstance(radius, bool) or (np is not None and isinstance(radius, np.bool_)):
2223
raise TypeError("radius must be a nonnegative integer")
2324
try:
2425
resolved_radius = integer_index(radius)

‎tests/test_phase_coherence_admission.py‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ def test_phase_observations_reject_invalid_authoritative_alias(invalid, nodes):
3838
observe(graph)
3939

4040

41-
@pytest.mark.parametrize("radius", [True, np.bool_(True), -1, 0.5, "1", None])
41+
@pytest.mark.parametrize(
42+
"radius", [True, False, np.bool_(True), np.bool_(False), -1, 0.5, "1", None]
43+
)
4244
def test_structural_and_phase_observations_share_radius_admission(radius):
4345
graph = nx.path_graph(2)
4446
for observe in (
@@ -50,6 +52,17 @@ def test_structural_and_phase_observations_share_radius_admission(radius):
5052
observe(graph, 0, radius)
5153

5254

55+
def test_radius_admission_preserves_integer_index_protocol():
56+
class Radius:
57+
def __index__(self):
58+
return 1
59+
60+
graph = nx.path_graph(3)
61+
graph.nodes[2][ALIAS_THETA[0]] = "outside radius one"
62+
for radius in (1, np.int64(1), Radius()):
63+
assert phase_coherence.compute_phase_alignment(graph, 0, radius) == 1.0
64+
65+
5366
@pytest.mark.parametrize("radius", [0, 1, 2])
5467
def test_missing_center_never_becomes_a_perfect_phase_observation(radius):
5568
with pytest.raises(KeyError):

0 commit comments

Comments
 (0)