Conversation
for more information, see https://pre-commit.ci
📝 WalkthroughWalkthroughThe monolithic Changes
Sequence Diagram(s)sequenceDiagram
participant Caller as Client
participant API as stk.build.sqs_structures
participant Parser as sqsgenerator.parse_config
participant Worker as WorkerThread
participant Core as sqsgenerator.core.optimize
participant ResultWrap as SqsResultPack
Caller->>API: call sqs_structures(Atoms, composition, ...)
API->>Parser: parse configuration
alt parse ok
API->>Worker: start optimizer thread (with stop callback)
Worker->>Core: run optimize(config, callback)
Core-->>Worker: optimization result
Worker->>API: signal completion
API->>ResultWrap: wrap optimizer result
API-->>Caller: return SqsResultPack
else parse failure
Parser-->>API: raise ValueError
API-->>Caller: raise ValueError
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (2)
src/structuretoolkit/build/sqs/__init__.py (1)
19-35: Optional:__all__is not sorted.Per static analysis (RUF022),
__all__entries should follow isort-style sorting for consistency.♻️ Sorted `__all__`
__all__ = [ "Composition", "Element", "IterationMode", "Prec", - "ResultType", "Shell", "ShellRadii", "ShellWeights", "Site", + "SqsResult", "SroParameter", - "SqsResult", "SqsResultInteract", "SqsResultSplit", "SublatticeMode", "sqs_structures", ]🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/structuretoolkit/build/sqs/__init__.py` around lines 19 - 35, The __all__ list in this module is not alphabetically sorted; update the __all__ variable to use isort-style (alphabetical) ordering so exports are consistent and satisfy RUF022. Locate the __all__ declaration (the list containing "Composition", "Element", ..., "sqs_structures") and reorder its string entries alphabetically (preserving exact symbol names and casing), then run the project's linters/formatters to confirm the change.src/structuretoolkit/build/sqs/_interface.py (1)
284-288: Exception in worker thread is silently lost.If
sqs_optimizeraises an exception, it's swallowed by the thread andoptimization_resultremainsNone, resulting in a genericRuntimeError. Consider capturing and re-raising the actual exception for better debugging.♻️ Proposed enhancement to preserve exception info
+ optimization_exception: BaseException | None = None + def _optimize(): + nonlocal optimization_exception try: result_local = sqs_optimize(config, log_level=level, callback=_callback) - stop_event.set() nonlocal optimization_result optimization_result = result_local + except BaseException as e: + optimization_exception = e + finally: + stop_event.set()Then at line 300:
if optimization_result is None: + if optimization_exception is not None: + raise RuntimeError("Optimization failed") from optimization_exception raise RuntimeError("Optimization failed to produce a result.")🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/structuretoolkit/build/sqs/_interface.py` around lines 284 - 288, The worker thread function _optimize currently calls sqs_optimize and assigns optimization_result but swallows exceptions; change _optimize to catch Exception as e, store that exception (e) or its traceback into a shared variable (e.g., optimization_result or a new optimization_exception) and ensure stop_event.set() is still called, then in the main thread where optimization_result is inspected re-raise the captured exception (or raise RuntimeError from the captured exception) so the actual error/traceback from sqs_optimize is preserved; reference _optimize, sqs_optimize, optimization_result and stop_event when implementing this change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/structuretoolkit/build/sqs/__init__.py`:
- Around line 1-16: The import of ResultType in
src/structuretoolkit/build/sqs/__init__.py is invalid because ResultType is not
defined in _types.py; either remove ResultType from the import list in
__init__.py (and from any __all__ export there) or add a proper ResultType
definition to _types.py if it's required; update usages referencing ResultType
(search for ResultType in the package) to use the new type or appropriate
existing type to avoid broken references.
In `@src/structuretoolkit/build/sqs/_interface.py`:
- Around line 99-118: The overload for sqs_structures has a type mismatch:
objective is annotated as list[float] but given a default 0.0; update the
overload signature for sqs_structures so the objective parameter matches the
implementation (accepts list[float] | float with default 0.0) — i.e., change the
overload's objective type to list[float] | float = 0.0 (or alternatively provide
a list default like [0.0] if you prefer list-only), ensuring the overload and
the implementation (which declares objective: list[float] | float = 0.0) are
consistent.
- Around line 292-298: The loop waiting on stop_event can block forever if the
worker thread (t running sqs_optimize) crashes before setting stop_event; change
the wait to a timed wait so the main thread wakes periodically and re-checks
thread liveness. Update the loop around t.is_alive() and stop_event.wait() to
call stop_event.wait(timeout=...) (e.g., 0.5–1s) or replace with
t.join(timeout=...) so that if t.is_alive() becomes False the loop breaks; keep
the existing except/finally behavior (including t.join()) but ensure the timed
wait lets the main thread detect a dead worker and exit instead of hanging.
In `@src/structuretoolkit/build/sqs/_types.py`:
- Line 131: The Composition type fails because Element is currently defined as a
list object rather than a type alias; change the Element symbol into a proper
type alias (e.g., a Literal union or Typed alias) so Composition = dict[Element
| Literal["sites"], Union[int, Site]] is valid; update the Element declaration
(and imports if necessary) to use typing/typing_extensions TypeAlias or
Literal/Union types and ensure Site and Composition use those type names
consistently.
- Around line 9-125: Element is currently a runtime list literal, not a type, so
using it in annotations like Composition causes errors; replace it with a proper
type definition and keep the runtime list separate: create a runtime constant
(e.g., ELEMENT_SYMBOLS) holding the list of symbols and define Element as a type
alias or a Literal union (e.g., Element: TypeAlias = Literal["0","H","He",...])
or simply Element: TypeAlias = str if you don't need strict literals, then
update usages (e.g., Composition) to reference the new Element type alias
instead of the list object.
- Around line 1-195: Define the missing exported type alias ResultType in this
module by adding a TypeAlias that points to the existing union SqsResult (e.g.
ResultType: TypeAlias = SqsResult) so imports from __init__.py succeed; place
the declaration near the other aliases (after SqsResult) and ensure the name
ResultType is available at module level for export.
---
Nitpick comments:
In `@src/structuretoolkit/build/sqs/__init__.py`:
- Around line 19-35: The __all__ list in this module is not alphabetically
sorted; update the __all__ variable to use isort-style (alphabetical) ordering
so exports are consistent and satisfy RUF022. Locate the __all__ declaration
(the list containing "Composition", "Element", ..., "sqs_structures") and
reorder its string entries alphabetically (preserving exact symbol names and
casing), then run the project's linters/formatters to confirm the change.
In `@src/structuretoolkit/build/sqs/_interface.py`:
- Around line 284-288: The worker thread function _optimize currently calls
sqs_optimize and assigns optimization_result but swallows exceptions; change
_optimize to catch Exception as e, store that exception (e) or its traceback
into a shared variable (e.g., optimization_result or a new
optimization_exception) and ensure stop_event.set() is still called, then in the
main thread where optimization_result is inspected re-raise the captured
exception (or raise RuntimeError from the captured exception) so the actual
error/traceback from sqs_optimize is preserved; reference _optimize,
sqs_optimize, optimization_result and stop_event when implementing this change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 529c7ba7-59c5-4ed0-90a3-6e9e805cb137
📒 Files selected for processing (6)
.ci_support/environment.ymlsrc/structuretoolkit/build/sqs.pysrc/structuretoolkit/build/sqs/__init__.pysrc/structuretoolkit/build/sqs/_interface.pysrc/structuretoolkit/build/sqs/_types.pytests/test_sqs.py
💤 Files with no reviewable changes (1)
- src/structuretoolkit/build/sqs.py
| import numpy as np | ||
| from ase import Atoms | ||
| from typing import Literal, TypeAlias, Protocol, overload, Union | ||
|
|
||
| Shell: TypeAlias = int | ||
|
|
||
| SublatticeMode = Literal["split", "interact"] | ||
| IterationMode = Literal["random", "systematic"] | ||
| Element = [ | ||
| "0", | ||
| "H", | ||
| "He", | ||
| "Li", | ||
| "Be", | ||
| "B", | ||
| "C", | ||
| "N", | ||
| "O", | ||
| "F", | ||
| "Ne", | ||
| "Na", | ||
| "Mg", | ||
| "Al", | ||
| "Si", | ||
| "P", | ||
| "S", | ||
| "Cl", | ||
| "Ar", | ||
| "K", | ||
| "Ca", | ||
| "Sc", | ||
| "Ti", | ||
| "V", | ||
| "Cr", | ||
| "Mn", | ||
| "Fe", | ||
| "Co", | ||
| "Ni", | ||
| "Cu", | ||
| "Zn", | ||
| "Ga", | ||
| "Ge", | ||
| "As", | ||
| "Se", | ||
| "Br", | ||
| "Kr", | ||
| "Rb", | ||
| "Sr", | ||
| "Y", | ||
| "Zr", | ||
| "Nb", | ||
| "Mo", | ||
| "Tc", | ||
| "Ru", | ||
| "Rh", | ||
| "Pd", | ||
| "Ag", | ||
| "Cd", | ||
| "In", | ||
| "Sn", | ||
| "Sb", | ||
| "Te", | ||
| "I", | ||
| "Xe", | ||
| "Cs", | ||
| "Ba", | ||
| "La", | ||
| "Ce", | ||
| "Pr", | ||
| "Nd", | ||
| "Pm", | ||
| "Sm", | ||
| "Eu", | ||
| "Gd", | ||
| "Tb", | ||
| "Dy", | ||
| "Ho", | ||
| "Er", | ||
| "Tm", | ||
| "Yb", | ||
| "Lu", | ||
| "Hf", | ||
| "Ta", | ||
| "W", | ||
| "Re", | ||
| "Os", | ||
| "Ir", | ||
| "Pt", | ||
| "Au", | ||
| "Hg", | ||
| "Tl", | ||
| "Pb", | ||
| "Bi", | ||
| "Po", | ||
| "At", | ||
| "Rn", | ||
| "Fr", | ||
| "Ra", | ||
| "Ac", | ||
| "Th", | ||
| "Pa", | ||
| "U", | ||
| "Np", | ||
| "Pu", | ||
| "Am", | ||
| "Cm", | ||
| "Bk", | ||
| "Cf", | ||
| "Es", | ||
| "Fm", | ||
| "Md", | ||
| "No", | ||
| "Lr", | ||
| "Rf", | ||
| "Db", | ||
| "Sg", | ||
| "Bh", | ||
| "Hs", | ||
| "Mt", | ||
| "Ds", | ||
| "Rg", | ||
| "Cn", | ||
| "Uut", | ||
| "Fl", | ||
| ] | ||
|
|
||
| Site = Union[str, list[int]] | ||
|
|
||
| Prec = Literal["single", "double"] | ||
|
|
||
| Composition = dict[Element | Literal["sites"], Union[int, Site]] | ||
|
|
||
| ShellWeights = dict[Shell, float] | ||
|
|
||
| ShellRadii = list[float] | ||
|
|
||
| LogLevel = Literal["warn", "info", "debug", "error", "trace"] | ||
|
|
||
|
|
||
| class SroParameter: | ||
| @property | ||
| def i(self) -> int: ... | ||
|
|
||
| @property | ||
| def j(self) -> int: ... | ||
|
|
||
| @property | ||
| def shell(self) -> int: ... | ||
|
|
||
| def __float__(self) -> float: ... | ||
|
|
||
| @property | ||
| def value(self) -> float: ... | ||
|
|
||
|
|
||
| class SqsResultInteract(Protocol): | ||
| def shell_index(self, shell: int) -> int: ... | ||
|
|
||
| def species_index(self, species: int) -> int: ... | ||
|
|
||
| def rank(self) -> str: ... | ||
|
|
||
| @overload | ||
| def sro( | ||
| self, | ||
| ) -> ( | ||
| np.ndarray[tuple[int, int, int], np.dtype[np.float32]] | ||
| | np.ndarray[tuple[int, int, int], np.dtype[np.float64]] | ||
| ): ... | ||
|
|
||
| @overload | ||
| def sro(self, shell: int) -> list[SroParameter]: ... | ||
|
|
||
| @overload | ||
| def sro(self, i: int, j: int) -> list[SroParameter]: ... | ||
|
|
||
| @overload | ||
| def sro(self, shell: int, i: int, j: int) -> SroParameter: ... | ||
|
|
||
| @property | ||
| def objective(self) -> float: ... | ||
|
|
||
| def atoms(self) -> Atoms: ... | ||
|
|
||
|
|
||
| class SqsResultSplit(Protocol): | ||
| @property | ||
| def objective(self) -> float: ... | ||
|
|
||
| def atoms(self) -> Atoms: ... | ||
|
|
||
| def sublattices(self) -> list[SqsResultInteract]: ... | ||
|
|
||
|
|
||
| SqsResult = SqsResultSplit | SqsResultInteract |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify ResultType is not defined in _types.py
echo "Searching for ResultType definition in _types.py:"
rg -n "ResultType" src/structuretoolkit/build/sqs/_types.py || echo "ResultType NOT found in _types.py"
echo ""
echo "Checking if ResultType is imported in __init__.py:"
rg -n "ResultType" src/structuretoolkit/build/sqs/__init__.pyRepository: pyiron/structuretoolkit
Length of output: 241
Critical: ResultType is not defined in this file but is imported in __init__.py.
The pipeline fails because __init__.py imports ResultType from this module (line 9) and exports it (line 24), but it's not defined here. Add the ResultType definition to this file—likely as a type alias for SqsResult or another result type.
🧰 Tools
🪛 GitHub Actions: Pipeline
[error] 1-1: ImportError during test collection: cannot import name 'ResultType' from 'structuretoolkit.build.sqs._types' (/home/runner/miniconda3/envs/test/lib/python3.14/site-packages/structuretoolkit/build/sqs/_types.py).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/structuretoolkit/build/sqs/_types.py` around lines 1 - 195, Define the
missing exported type alias ResultType in this module by adding a TypeAlias that
points to the existing union SqsResult (e.g. ResultType: TypeAlias = SqsResult)
so imports from __init__.py succeed; place the declaration near the other
aliases (after SqsResult) and ensure the name ResultType is available at module
level for export.
| Element = [ | ||
| "0", | ||
| "H", | ||
| "He", | ||
| "Li", | ||
| "Be", | ||
| "B", | ||
| "C", | ||
| "N", | ||
| "O", | ||
| "F", | ||
| "Ne", | ||
| "Na", | ||
| "Mg", | ||
| "Al", | ||
| "Si", | ||
| "P", | ||
| "S", | ||
| "Cl", | ||
| "Ar", | ||
| "K", | ||
| "Ca", | ||
| "Sc", | ||
| "Ti", | ||
| "V", | ||
| "Cr", | ||
| "Mn", | ||
| "Fe", | ||
| "Co", | ||
| "Ni", | ||
| "Cu", | ||
| "Zn", | ||
| "Ga", | ||
| "Ge", | ||
| "As", | ||
| "Se", | ||
| "Br", | ||
| "Kr", | ||
| "Rb", | ||
| "Sr", | ||
| "Y", | ||
| "Zr", | ||
| "Nb", | ||
| "Mo", | ||
| "Tc", | ||
| "Ru", | ||
| "Rh", | ||
| "Pd", | ||
| "Ag", | ||
| "Cd", | ||
| "In", | ||
| "Sn", | ||
| "Sb", | ||
| "Te", | ||
| "I", | ||
| "Xe", | ||
| "Cs", | ||
| "Ba", | ||
| "La", | ||
| "Ce", | ||
| "Pr", | ||
| "Nd", | ||
| "Pm", | ||
| "Sm", | ||
| "Eu", | ||
| "Gd", | ||
| "Tb", | ||
| "Dy", | ||
| "Ho", | ||
| "Er", | ||
| "Tm", | ||
| "Yb", | ||
| "Lu", | ||
| "Hf", | ||
| "Ta", | ||
| "W", | ||
| "Re", | ||
| "Os", | ||
| "Ir", | ||
| "Pt", | ||
| "Au", | ||
| "Hg", | ||
| "Tl", | ||
| "Pb", | ||
| "Bi", | ||
| "Po", | ||
| "At", | ||
| "Rn", | ||
| "Fr", | ||
| "Ra", | ||
| "Ac", | ||
| "Th", | ||
| "Pa", | ||
| "U", | ||
| "Np", | ||
| "Pu", | ||
| "Am", | ||
| "Cm", | ||
| "Bk", | ||
| "Cf", | ||
| "Es", | ||
| "Fm", | ||
| "Md", | ||
| "No", | ||
| "Lr", | ||
| "Rf", | ||
| "Db", | ||
| "Sg", | ||
| "Bh", | ||
| "Hs", | ||
| "Mt", | ||
| "Ds", | ||
| "Rg", | ||
| "Cn", | ||
| "Uut", | ||
| "Fl", | ||
| ] |
There was a problem hiding this comment.
Element is defined as a list, not a type alias.
Element is assigned a list literal, which makes it a runtime list object rather than a type. This will cause issues when used in type annotations like Composition = dict[Element | Literal["sites"], ...] at line 131 — a list cannot be used as a type key.
If the intent is to define a type for valid element symbols, use Literal:
🔧 Proposed fix using Literal type
-Element = [
- "0",
- "H",
- "He",
- ...
- "Fl",
-]
+Element: TypeAlias = Literal[
+ "0", "H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne",
+ "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K", "Ca",
+ "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn",
+ "Ga", "Ge", "As", "Se", "Br", "Kr", "Rb", "Sr", "Y", "Zr",
+ "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn",
+ "Sb", "Te", "I", "Xe", "Cs", "Ba", "La", "Ce", "Pr", "Nd",
+ "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb",
+ "Lu", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg",
+ "Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr", "Ra", "Ac", "Th",
+ "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm",
+ "Md", "No", "Lr", "Rf", "Db", "Sg", "Bh", "Hs", "Mt", "Ds",
+ "Rg", "Cn", "Uut", "Fl",
+]Alternatively, if you want to keep the list for runtime validation and have a separate type, define both:
ELEMENT_SYMBOLS = ["0", "H", "He", ...] # runtime list
Element: TypeAlias = str # simple type alias🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/structuretoolkit/build/sqs/_types.py` around lines 9 - 125, Element is
currently a runtime list literal, not a type, so using it in annotations like
Composition causes errors; replace it with a proper type definition and keep the
runtime list separate: create a runtime constant (e.g., ELEMENT_SYMBOLS) holding
the list of symbols and define Element as a type alias or a Literal union (e.g.,
Element: TypeAlias = Literal["0","H","He",...]) or simply Element: TypeAlias =
str if you don't need strict literals, then update usages (e.g., Composition) to
reference the new Element type alias instead of the list object.
…improve-interface
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #476 +/- ##
==========================================
+ Coverage 82.69% 83.03% +0.33%
==========================================
Files 25 27 +2
Lines 1832 1904 +72
==========================================
+ Hits 1515 1581 +66
- Misses 317 323 +6 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/structuretoolkit/build/sqs/__init__.py (1)
18-33: Consider sorting__all__for consistency.Ruff flags that
__all__is not sorted. Sorting the list alphabetically improves consistency and makes future additions easier to review.📋 Proposed alphabetical sort
__all__ = [ "Composition", "Element", "IterationMode", "Prec", "Shell", "ShellRadii", "ShellWeights", "Site", - "SroParameter", "SqsResult", "SqsResultInteract", "SqsResultSplit", + "SroParameter", "SublatticeMode", "sqs_structures", ]🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/structuretoolkit/build/sqs/__init__.py` around lines 18 - 33, The __all__ list in the module is unsorted; sort the entries in the __all__ list alphabetically (by string) while keeping the same items and punctuation so semantics don't change—update the __all__ definition (which currently contains "Composition", "Element", "IterationMode", "Prec", "Shell", "ShellRadii", "ShellWeights", "Site", "SroParameter", "SqsResult", "SqsResultInteract", "SqsResultSplit", "SublatticeMode", "sqs_structures") to an alphabetically ordered sequence to satisfy the linter.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/structuretoolkit/build/sqs/__init__.py`:
- Around line 18-33: The __all__ list in the module is unsorted; sort the
entries in the __all__ list alphabetically (by string) while keeping the same
items and punctuation so semantics don't change—update the __all__ definition
(which currently contains "Composition", "Element", "IterationMode", "Prec",
"Shell", "ShellRadii", "ShellWeights", "Site", "SroParameter", "SqsResult",
"SqsResultInteract", "SqsResultSplit", "SublatticeMode", "sqs_structures") to an
alphabetically ordered sequence to satisfy the linter.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: eb11e8f4-48e2-4d88-b418-239b2b8743cb
📒 Files selected for processing (1)
src/structuretoolkit/build/sqs/__init__.py
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/structuretoolkit/build/sqs/_interface.py`:
- Around line 298-305: The current except TimeoutError after calling
t.join(timeout=5.0) is ineffective because Thread.join never raises
TimeoutError; instead check t.is_alive() after join and raise the RuntimeError
if the thread remains alive. Update the block around t.join(timeout=5.0) (the
thread variable `t`) to call t.join(timeout=5.0) then if t.is_alive(): raise the
same RuntimeError (leave message unchanged) rather than relying on an except
TimeoutError branch so stopping logic in sqs_structures becomes effective.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 23325877-d56f-4034-bb90-09a2e736845b
📒 Files selected for processing (3)
src/structuretoolkit/build/sqs/_interface.pysrc/structuretoolkit/build/sqs/_types.pytests/test_sqs.py
✅ Files skipped from review due to trivial changes (1)
- src/structuretoolkit/build/sqs/_types.py
| try: | ||
| t.join(timeout=5.0) | ||
| except TimeoutError: | ||
| raise RuntimeError( | ||
| "Optimization thread did not finish within the timeout period after requesting it to stop. " | ||
| "The optimization may still be running in the background. Try to decrease chunk_size by passing it as a " | ||
| "keyword argument to sqs_structures to make the optimization more responsive to stop requests." | ||
| ) |
There was a problem hiding this comment.
Thread.join() does not raise TimeoutError—the timeout check is ineffective.
Thread.join(timeout=5.0) returns None regardless of whether the thread terminated or the timeout elapsed. To detect a timeout, you must check t.is_alive() afterwards. The current code's except TimeoutError block will never execute.
🐛 Proposed fix
finally:
- try:
- t.join(timeout=5.0)
- except TimeoutError:
+ t.join(timeout=5.0)
+ if t.is_alive():
raise RuntimeError(
"Optimization thread did not finish within the timeout period after requesting it to stop. "
"The optimization may still be running in the background. Try to decrease chunk_size by passing it as a "
"keyword argument to sqs_structures to make the optimization more responsive to stop requests."
)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| try: | |
| t.join(timeout=5.0) | |
| except TimeoutError: | |
| raise RuntimeError( | |
| "Optimization thread did not finish within the timeout period after requesting it to stop. " | |
| "The optimization may still be running in the background. Try to decrease chunk_size by passing it as a " | |
| "keyword argument to sqs_structures to make the optimization more responsive to stop requests." | |
| ) | |
| finally: | |
| t.join(timeout=5.0) | |
| if t.is_alive(): | |
| raise RuntimeError( | |
| "Optimization thread did not finish within the timeout period after requesting it to stop. " | |
| "The optimization may still be running in the background. Try to decrease chunk_size by passing it as a " | |
| "keyword argument to sqs_structures to make the optimization more responsive to stop requests." | |
| ) |
🧰 Tools
🪛 Ruff (0.15.7)
[warning] 301-305: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/structuretoolkit/build/sqs/_interface.py` around lines 298 - 305, The
current except TimeoutError after calling t.join(timeout=5.0) is ineffective
because Thread.join never raises TimeoutError; instead check t.is_alive() after
join and raise the RuntimeError if the thread remains alive. Update the block
around t.join(timeout=5.0) (the thread variable `t`) to call t.join(timeout=5.0)
then if t.is_alive(): raise the same RuntimeError (leave message unchanged)
rather than relying on an except TimeoutError branch so stopping logic in
sqs_structures becomes effective.
Add more features to the sqsgenerator interface (>0.4.9)
Summary by CodeRabbit
Refactor
New Features
Tests
Chores