Skip to content

Commit a698cb0

Browse files
Merge pull request #1 from DiogoRibeiro7/solver_fix
fix: Replace solver asserts with explicit runtime checks
2 parents afd397c + 3e91d88 commit a698cb0

File tree

2 files changed

+73
-24
lines changed

2 files changed

+73
-24
lines changed

min_ratio_cycle/solver.py

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,10 @@ def _solve_exact(self, **kwargs) -> SolverResult:
666666
error_message="Exact mode requires integer weights",
667667
)
668668

669-
assert self._Ci is not None and self._Ti is not None
669+
if self._Ci is None or self._Ti is None:
670+
raise RuntimeError(
671+
"Integer weight arrays (_Ci, _Ti) must be initialized before solving"
672+
)
670673

671674
max_den = kwargs.get("max_denominator", self.config.exact_max_denominator)
672675
max_steps = kwargs.get("max_steps", self.config.exact_max_steps)
@@ -702,7 +705,10 @@ def _stern_brocot_search(
702705
self, max_den: Optional[int], max_steps: Optional[int]
703706
) -> Tuple[List[int], int, int, Tuple[int, int], float]:
704707
"""Implement Stern-Brocot tree search for exact optimal ratio."""
705-
assert self._Ci is not None and self._Ti is not None
708+
if self._Ci is None or self._Ti is None:
709+
raise RuntimeError(
710+
"Integer weight arrays (_Ci, _Ti) must be initialized before searching"
711+
)
706712

707713
# Set defaults
708714
if max_den is None:
@@ -772,9 +778,18 @@ def _combine_weights_exact(self, a: int, b: int) -> np.ndarray:
772778

773779
def _has_negative_cycle_exact(self, a: int, b: int) -> bool:
774780
"""Check for negative cycle with exact integer arithmetic."""
775-
assert self._U is not None and self._V is not None
776-
assert self._Ci is not None and self._Ti is not None
777-
assert self._starts is not None and self._counts is not None
781+
if self._U is None or self._V is None:
782+
raise RuntimeError(
783+
"Edge endpoint arrays (_U, _V) must be initialized before cycle checks"
784+
)
785+
if self._Ci is None or self._Ti is None:
786+
raise RuntimeError(
787+
"Integer weight arrays (_Ci, _Ti) must be initialized before cycle checks"
788+
)
789+
if self._starts is None or self._counts is None:
790+
raise RuntimeError(
791+
"Segment arrays (_starts, _counts) must be initialized before cycle checks"
792+
)
778793

779794
W = self._combine_weights_exact(a, b)
780795
dist = np.zeros(self.n, dtype=np.int64)
@@ -815,8 +830,14 @@ def _find_zero_cycle_exact(
815830
if not ok:
816831
return None
817832

818-
assert self._U is not None and self._V is not None
819-
assert self._Ci is not None and self._Ti is not None
833+
if self._U is None or self._V is None:
834+
raise RuntimeError(
835+
"Edge endpoint arrays (_U, _V) must be initialized before cycle extraction"
836+
)
837+
if self._Ci is None or self._Ti is None:
838+
raise RuntimeError(
839+
"Integer weight arrays (_Ci, _Ti) must be initialized before cycle extraction"
840+
)
820841

821842
W = self._combine_weights_exact(a, b)
822843
equal_mask = (dist[self._U] + W) == dist[self._V]
@@ -864,9 +885,18 @@ def dfs(u: int) -> Optional[List[int]]:
864885

865886
def _compute_potentials_exact(self, a: int, b: int) -> Tuple[bool, np.ndarray]:
866887
"""Compute shortest path potentials with exact arithmetic."""
867-
assert self._U is not None and self._V is not None
868-
assert self._Ci is not None and self._Ti is not None
869-
assert self._starts is not None and self._counts is not None
888+
if self._U is None or self._V is None:
889+
raise RuntimeError(
890+
"Edge endpoint arrays (_U, _V) must be initialized before computing potentials"
891+
)
892+
if self._Ci is None or self._Ti is None:
893+
raise RuntimeError(
894+
"Integer weight arrays (_Ci, _Ti) must be initialized before computing potentials"
895+
)
896+
if self._starts is None or self._counts is None:
897+
raise RuntimeError(
898+
"Segment arrays (_starts, _counts) must be initialized before computing potentials"
899+
)
870900

871901
W = self._combine_weights_exact(a, b)
872902
dist = np.zeros(self.n, dtype=np.int64)
@@ -1053,9 +1083,18 @@ def _detect_negative_cycle_numeric(
10531083
self, lam: float, slack: float = 0.0
10541084
) -> Tuple[bool, Optional[Tuple[List[int], float, float, float]]]:
10551085
"""Detect negative cycle using vectorized Bellman-Ford."""
1056-
assert self._U is not None and self._V is not None
1057-
assert self._C is not None and self._T is not None
1058-
assert self._starts is not None and self._counts is not None
1086+
if self._U is None or self._V is None:
1087+
raise RuntimeError(
1088+
"Edge endpoint arrays (_U, _V) must be initialized before numeric cycle detection"
1089+
)
1090+
if self._C is None or self._T is None:
1091+
raise RuntimeError(
1092+
"Weight arrays (_C, _T) must be initialized before numeric cycle detection"
1093+
)
1094+
if self._starts is None or self._counts is None:
1095+
raise RuntimeError(
1096+
"Segment arrays (_starts, _counts) must be initialized before numeric cycle detection"
1097+
)
10591098

10601099
n = self.n
10611100
W = self._C - lam * self._T

pyproject.toml

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,27 @@ psutil = "^7.0" # Resource monitoring
1616

1717
[tool.poetry.group.dev.dependencies]
1818
pytest = "^8.0"
19-
hypothesis = "^6.100" # Property-based testing
20-
pytest-cov = "^4.1" # Coverage reporting
21-
pytest-benchmark = "^4.0" # Performance benchmarking
22-
pytest-xdist = "^3.3" # Parallel test execution
23-
black = "^23.0" # Code formatting
24-
isort = "^5.12" # Import sorting
25-
mypy = "^1.5" # Type checking
26-
flake8 = "^6.0" # Linting
27-
sphinx = "^7.0" # Documentation generator
28-
pre-commit = "^3.5" # Git hook management
29-
bandit = "^1.7" # Security scanning
19+
hypothesis = "^6.100"
20+
pytest-cov = "^4.1"
21+
pytest-benchmark = "^4.0"
22+
pytest-xdist = "^3.3"
23+
black = "^23.0"
24+
isort = "^5.12"
25+
mypy = "^1.5"
26+
flake8 = "^6.0"
27+
sphinx = "^7.0"
28+
pre-commit = "^3.5"
29+
bandit = "^1.7"
30+
requests = ">=2.32.4,<3.0.0"
31+
urllib3 = ">=2.5.0,<3.0.0"
32+
idna = ">=3.7,<4.0.0"
33+
certifi = ">=2024.7.4,<2026.0.0"
34+
cryptography = ">=42.0.5,<43.0.0"
35+
configobj = ">=5.0.9,<6.0.0"
36+
pyjwt = ">=2.10.1,<3.0.0"
37+
jinja2 = ">=3.1.6,<4.0.0"
38+
setuptools = ">=78.1.1"
39+
twisted = ">=24.7.0"
3040

3141
[tool.poetry.group.test.dependencies]
3242
# Additional test utilities

0 commit comments

Comments
 (0)