Skip to content

[fix] driver autoscript_client & xt_client: stop polling thread on termination#3381

Open
pieleric wants to merge 1 commit intodelmic:masterfrom
pieleric:fix-driver-autoscript_client-xt_client-stop-polling-thread-on-termination
Open

[fix] driver autoscript_client & xt_client: stop polling thread on termination#3381
pieleric wants to merge 1 commit intodelmic:masterfrom
pieleric:fix-driver-autoscript_client-xt_client-stop-polling-thread-on-termination

Conversation

@pieleric
Copy link
Member

@pieleric pieleric commented Feb 23, 2026

Make sure that all components which have a polling thread stop it when
the component is terminated.
It's typically not a big deal as the threads would be ended
automatically when the whole process ends, or as soon as they attempts
to connect via the parent, which is gone. However, the errors can be
confusing.
This avoid such error in the log:

2026-02-23 09:57:05,589	ERROR	autoscript_client:1309:	Unexpected failure when polling settings
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/odemis/driver/autoscript_client.py", line 1281, in _updateSettings
    beam_current = self.parent.get_beam_current(self.channel)
AttributeError: 'NoneType' object has no attribute 'get_beam_current'

…rmination

Make sure that all components which have a polling thread stop it when
the component is terminated.
It's typically not a big deal as the threads would be ended
automatically when the whole process ends, or as soon as they attempts
to connect via the parent, which is gone. However, the errors can be
confusing.
This avoid such error in the log:
2026-02-23 09:57:05,589	ERROR	autoscript_client:1309:	Unexpected failure when polling settings
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/odemis/driver/autoscript_client.py", line 1281, in _updateSettings
    beam_current = self.parent.get_beam_current(self.channel)
AttributeError: 'NoneType' object has no attribute 'get_beam_current'
Copilot AI review requested due to automatic review settings February 23, 2026 22:08
@pieleric pieleric requested review from ilyushkin and tepals February 23, 2026 22:08
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request addresses a bug where polling threads in the autoscript_client and xt_client drivers were not being properly stopped during component termination, leading to confusing error messages in logs when components attempted to access their parent after termination.

Changes:

  • Added terminate() methods to multiple component classes to cancel polling threads before component shutdown
  • Ensured super().terminate() is called in all terminate() methods for proper cleanup chain
  • Updated test to use synchronous stage move operation to ensure proper cleanup before test teardown

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 11 comments.

File Description
src/odemis/driver/xt_client.py Added terminate() methods to Main, Scanner, Detector, Chamber, Stage, and Focus classes to cancel polling threads and executor tasks
src/odemis/driver/autoscript_client.py Added terminate() methods to Main, Scanner, Focus classes and updated Detector and Stage terminate() to call super().terminate()
src/odemis/driver/test/xt_client_test.py Changed moveAbs to moveAbsSync in test teardown to ensure synchronous completion and added debug logging

self._fib_detector = Detector(parent=self, daemon=daemon, channel="ion", **ckwargs)
self.children.value.add(self._fib_detector)

def terminate(self):
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The terminate method should include a return type hint (-> None) for consistency with other terminate methods in the codebase and with the coding guideline to always use type hints for function return types.

Copilot generated this review using guidance from repository custom instructions.
self._pos_poll = util.RepeatingTimer(5, self._refreshPosition, "Stage position polling")
self._pos_poll.start()

def terminate(self):
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The terminate method should include a return type hint (-> None) for consistency with other terminate methods in the codebase and with the coding guideline to always use type hints for function return types.

Copilot generated this review using guidance from repository custom instructions.
self._pos_poll = util.RepeatingTimer(5, self._refreshPosition, "Focus position polling")
self._pos_poll.start()

def terminate(self):
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The terminate method should include a return type hint (-> None) for consistency with other terminate methods in the codebase and with the coding guideline to always use type hints for function return types.

Copilot generated this review using guidance from repository custom instructions.
self._detector = Detector(parent=self, daemon=daemon, **ckwargs)
self.children.value.add(self._detector)

def terminate(self):
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The terminate method should include a return type hint (-> None) for consistency with other terminate methods in the codebase and with the coding guideline to always use type hints for function return types.

Copilot generated this review using guidance from repository custom instructions.
self._va_poll = util.RepeatingTimer(5, self._updateSettings, "Settings polling")
self._va_poll.start()

def terminate(self):
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The terminate method should include a return type hint (-> None) for consistency with other terminate methods in the codebase and with the coding guideline to always use type hints for function return types.

Copilot generated this review using guidance from repository custom instructions.
self._pos_poll = util.RepeatingTimer(5, self._refreshPosition, "Focus position polling")
self._pos_poll.start()

def terminate(self):
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The terminate method should include a return type hint (-> None) for consistency with other terminate methods in the codebase and with the coding guideline to always use type hints for function return types.

Copilot generated this review using guidance from repository custom instructions.
Comment on lines +2636 to +2640
def terminate(self):
if self._pos_poll:
self._pos_poll.cancel()
self._pos_poll = None
super().terminate()
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Focus class has an _executor (initialized at line 2622) that should be cancelled and shutdown in the terminate method, similar to how it's done in the Stage class. This prevents potential issues with pending tasks when the component is terminated.

Copilot uses AI. Check for mistakes.
Comment on lines 2153 to 2154
def terminate(self) -> None:
self._polling_thread.cancel()
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Chamber class has an _executor (initialized at line 2106) that should be cancelled and shutdown in the terminate method, similar to how it's done in the Stage class. This ensures that any pending pump/vent operations are properly cleaned up on termination.

Suggested change
def terminate(self) -> None:
self._polling_thread.cancel()
def terminate(self) -> None:
"""
Terminate the chamber component and clean up background tasks.
"""
self._polling_thread.cancel()
self._executor.cancel()
self._executor.shutdown(wait=False)

Copilot uses AI. Check for mistakes.
Comment on lines +2065 to +2069
def terminate(self):
if self._pos_poll:
self._pos_poll.cancel()
self._pos_poll = None
super().terminate()
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Focus class has an _executor (initialized at line 2048) that should be cancelled and shutdown in the terminate method, similar to how it's done in the Stage class. This prevents potential issues with pending tasks when the component is terminated.

Copilot uses AI. Check for mistakes.
self._va_poll = util.RepeatingTimer(5, self._updateSettings, "Settings polling")
self._va_poll.start()

def terminate(self):
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The terminate method should include a return type hint (-> None) for consistency with other terminate methods in the codebase and with the coding guideline to always use type hints for function return types.

Copilot generated this review using guidance from repository custom instructions.
@coderabbitai
Copy link

coderabbitai bot commented Feb 23, 2026

📝 Walkthrough

Walkthrough

This pull request introduces structured cleanup methods across SEM-related driver components in two separate driver files: autoscript_client.py and xt_client.py. Each component class (SEM, Scanner, Detector, Stage, Focus, and Chamber where applicable) now implements a terminate() method that cancels background tasks such as polling timers, executors, and active generators, then delegates to the parent class termination. Additionally, test code in xt_client_test.py was updated to use synchronous movement methods and add a debug log entry during test cleanup.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 54.55% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately describes the main change: adding proper cleanup of polling threads when components are terminated.
Description check ✅ Passed The description is directly related to the changeset, explaining the motivation, the problem being solved, and providing a concrete example of the error being avoided.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
src/odemis/driver/xt_client.py (1)

1810-1819: ⚠️ Potential issue | 🟡 Minor

Add a docstring to Detector.terminate.

Proposed fix
     def terminate(self) -> None:
+        """Stop acquisition resources and polling timers."""
         if self._generator:
             self.stop_generate()
             self._genmsg.put(GEN_TERM)
             self._generator.join(5)
             self._generator = None
         if self._va_poll:
             self._va_poll.cancel()
             self._va_poll = None

As per coding guidelines: "Include docstrings for all functions and classes, following the reStructuredText style guide (without type information)".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/odemis/driver/xt_client.py` around lines 1810 - 1819, The terminate
method on Detector lacks a docstring; add a concise reStructuredText-style
docstring to Detector.terminate describing what the method does (stop
generation, signal termination via GEN_TERM, join the generator thread with
timeout, cancel _va_poll, and call super().terminate), any important side
effects, and any assumptions/preconditions — do not include type annotations in
the docstring and place it immediately under the def terminate(self)
declaration.
src/odemis/driver/autoscript_client.py (2)

1503-1509: ⚠️ Potential issue | 🟡 Minor

Add a docstring to Detector.terminate.

Proposed fix
     def terminate(self) -> None:
+        """Stop acquisition resources and terminate the detector."""
         if self._generator:
             self.stop_generate()
             self._genmsg.put(GEN_TERM)
             self._generator.join(5)

As per coding guidelines: "Include docstrings for all functions and classes, following the reStructuredText style guide (without type information)".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/odemis/driver/autoscript_client.py` around lines 1503 - 1509, Add a
reStructuredText-style docstring to the Detector.terminate method: describe
purpose (cleanly stops the generator, signals termination, joins thread, clears
generator, then calls super().terminate), document side effects (puts GEN_TERM
into _genmsg, may block up to 5s on join, sets _generator to None), and note it
returns None; place the docstring immediately under the def terminate(self)
signature in the Detector class and avoid including type annotations in the
docstring.

1836-1844: ⚠️ Potential issue | 🟡 Minor

Add type hint + docstring to Stage.terminate.

Proposed fix
-    def terminate(self):
+    def terminate(self) -> None:
+        """Stop polling/executor resources and terminate the stage."""
         if self._executor:
             self._executor.cancel()
             self._executor.shutdown()
             self._executor = None

As per coding guidelines: "Always use type hints for function parameters and return types in Python code" and "Include docstrings for all functions and classes, following the reStructuredText style guide (without type information)".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/odemis/driver/autoscript_client.py` around lines 1836 - 1844, The
Stage.terminate method is missing a return type hint and a docstring; update the
method signature to include a return type (def terminate(self) -> None:) and add
a reStructuredText-style docstring (no type annotations in the docstring)
describing its behavior: that it cancels and clears self._executor and
self._pos_poll if present and then calls super().terminate(); keep the
implementation intact and place the docstring immediately under the def,
referencing Stage.terminate, self._executor, self._pos_poll, and
super().terminate() so readers understand the side effects.
🤖 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/odemis/driver/autoscript_client.py`:
- Around line 2065-2070: Add a reStructuredText docstring and Python type hints
to the Focus.terminate method: annotate the method signature as def
terminate(self) -> None, and add a concise docstring (rst style) above the body
describing that it cancels the position poll (self._pos_poll) if present and
then calls super().terminate(); do not include type information in the docstring
itself, only in the signature.
- Around line 1266-1271: Add a return type hint and a reStructuredText docstring
to Scanner.terminate: change the signature to include the return type (-> None)
and add a short docstring (no type annotations inside) that describes what the
method does (cancels self._va_poll if present and delegates to
super().terminate()), any side effects, and what it returns (None); ensure the
docstring follows reST style and keep the existing logic that sets self._va_poll
to None after cancelling.
- Around line 200-207: Add a proper type-annotated signature and
reStructuredText docstring to SEM.terminate: change def terminate(self) to def
terminate(self) -> None and add a short rST docstring describing the method's
purpose, behavior (terminates child processes, removes server attribute to allow
proxy close), and side effects/raises if any; reference the method name
SEM.terminate and the attributes used (self.children, self.server) so the
reviewer can locate and update that function accordingly. Ensure the docstring
does not include type info per guidelines and keep it concise.

In `@src/odemis/driver/xt_client.py`:
- Around line 2153-2155: The method Chamber.terminate lacks a docstring; add a
reStructuredText-style docstring (without type annotations) immediately under
the def terminate(self) signature that briefly describes what the method does
(e.g., "Terminate the chamber: cancel the internal polling thread and call the
superclass terminate routine."), mention any important side effects (cancels
self._polling_thread and invokes super().terminate()), and note any exceptions
or lifecycle expectations if applicable.
- Around line 358-365: Add a reStructuredText docstring and a return type hint
to the SEM.terminate method: change its signature to include -> None and add a
brief docstring (one-line summary plus short description) that explains it
terminates child processes, removes the server attribute to allow the proxy to
close the connection, and then calls super().terminate(); keep the docstring
free of type annotations and reference the attributes used (self.children,
self.server) and the call to super().terminate() in the description.
- Around line 2267-2275: The Stage.terminate method is missing a type hint and a
reStructuredText docstring; update the method signature to include a return type
(-> None) and add a short reST-style docstring describing what terminate does
and any side effects (e.g., cancels and shuts down self._executor, cancels
self._pos_poll, and calls super().terminate()), without embedding type
information in the docstring; keep behavior unchanged and ensure the symbol name
is Stage.terminate.
- Around line 1489-1494: The Scanner.terminate method currently lacks a type
hint and docstring; change its signature to include a return type hint (def
terminate(self) -> None) and add a short reStructuredText-style docstring
(one-line summary and brief description) above the body describing that it
cancels the _va_poll task if present and then calls super().terminate(), keeping
the implementation using self._va_poll.cancel(), setting self._va_poll = None,
and invoking super().terminate().
- Around line 2636-2641: The Focus.terminate method lacks a return type
annotation and a reStructuredText-style docstring; update the method signature
to include a return type (def terminate(self) -> None:) and add a short
docstring (reST style, without type annotations) describing that it cancels any
active position poll (self._pos_poll), clears the reference, and then calls the
superclass terminate; keep the implementation logic (self._pos_poll.cancel();
self._pos_poll = None; super().terminate()) unchanged.

---

Outside diff comments:
In `@src/odemis/driver/autoscript_client.py`:
- Around line 1503-1509: Add a reStructuredText-style docstring to the
Detector.terminate method: describe purpose (cleanly stops the generator,
signals termination, joins thread, clears generator, then calls
super().terminate), document side effects (puts GEN_TERM into _genmsg, may block
up to 5s on join, sets _generator to None), and note it returns None; place the
docstring immediately under the def terminate(self) signature in the Detector
class and avoid including type annotations in the docstring.
- Around line 1836-1844: The Stage.terminate method is missing a return type
hint and a docstring; update the method signature to include a return type (def
terminate(self) -> None:) and add a reStructuredText-style docstring (no type
annotations in the docstring) describing its behavior: that it cancels and
clears self._executor and self._pos_poll if present and then calls
super().terminate(); keep the implementation intact and place the docstring
immediately under the def, referencing Stage.terminate, self._executor,
self._pos_poll, and super().terminate() so readers understand the side effects.

In `@src/odemis/driver/xt_client.py`:
- Around line 1810-1819: The terminate method on Detector lacks a docstring; add
a concise reStructuredText-style docstring to Detector.terminate describing what
the method does (stop generation, signal termination via GEN_TERM, join the
generator thread with timeout, cancel _va_poll, and call super().terminate), any
important side effects, and any assumptions/preconditions — do not include type
annotations in the docstring and place it immediately under the def
terminate(self) declaration.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b6dea6a and c70dc71.

📒 Files selected for processing (3)
  • src/odemis/driver/autoscript_client.py
  • src/odemis/driver/test/xt_client_test.py
  • src/odemis/driver/xt_client.py

Comment on lines +200 to +207
def terminate(self):
for child in self.children.value:
child.terminate()

if hasattr(self, "server"):
del self.server # to let the proxy close the connection

super().terminate()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add type hint + docstring to SEM.terminate.

Proposed fix
-    def terminate(self):
+    def terminate(self) -> None:
+        """Terminate child components and release the Pyro proxy."""
         for child in self.children.value:
             child.terminate()

As per coding guidelines: "Always use type hints for function parameters and return types in Python code" and "Include docstrings for all functions and classes, following the reStructuredText style guide (without type information)".

📝 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.

Suggested change
def terminate(self):
for child in self.children.value:
child.terminate()
if hasattr(self, "server"):
del self.server # to let the proxy close the connection
super().terminate()
def terminate(self) -> None:
"""Terminate child components and release the Pyro proxy."""
for child in self.children.value:
child.terminate()
if hasattr(self, "server"):
del self.server # to let the proxy close the connection
super().terminate()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/odemis/driver/autoscript_client.py` around lines 200 - 207, Add a proper
type-annotated signature and reStructuredText docstring to SEM.terminate: change
def terminate(self) to def terminate(self) -> None and add a short rST docstring
describing the method's purpose, behavior (terminates child processes, removes
server attribute to allow proxy close), and side effects/raises if any;
reference the method name SEM.terminate and the attributes used (self.children,
self.server) so the reviewer can locate and update that function accordingly.
Ensure the docstring does not include type info per guidelines and keep it
concise.

Comment on lines +1266 to +1271
def terminate(self):
if self._va_poll:
self._va_poll.cancel()
self._va_poll = None
super().terminate()

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add type hint + docstring to Scanner.terminate.

Proposed fix
-    def terminate(self):
+    def terminate(self) -> None:
+        """Stop polling timers and terminate the component."""
         if self._va_poll:
             self._va_poll.cancel()
             self._va_poll = None

As per coding guidelines: "Always use type hints for function parameters and return types in Python code" and "Include docstrings for all functions and classes, following the reStructuredText style guide (without type information)".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/odemis/driver/autoscript_client.py` around lines 1266 - 1271, Add a
return type hint and a reStructuredText docstring to Scanner.terminate: change
the signature to include the return type (-> None) and add a short docstring (no
type annotations inside) that describes what the method does (cancels
self._va_poll if present and delegates to super().terminate()), any side
effects, and what it returns (None); ensure the docstring follows reST style and
keep the existing logic that sets self._va_poll to None after cancelling.

Comment on lines +2065 to +2070
def terminate(self):
if self._pos_poll:
self._pos_poll.cancel()
self._pos_poll = None
super().terminate()

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add type hint + docstring to Focus.terminate.

Proposed fix
-    def terminate(self):
+    def terminate(self) -> None:
+        """Stop polling resources and terminate the focus component."""
         if self._pos_poll:
             self._pos_poll.cancel()
             self._pos_poll = None

As per coding guidelines: "Always use type hints for function parameters and return types in Python code" and "Include docstrings for all functions and classes, following the reStructuredText style guide (without type information)".

📝 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.

Suggested change
def terminate(self):
if self._pos_poll:
self._pos_poll.cancel()
self._pos_poll = None
super().terminate()
def terminate(self) -> None:
"""Stop polling resources and terminate the focus component."""
if self._pos_poll:
self._pos_poll.cancel()
self._pos_poll = None
super().terminate()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/odemis/driver/autoscript_client.py` around lines 2065 - 2070, Add a
reStructuredText docstring and Python type hints to the Focus.terminate method:
annotate the method signature as def terminate(self) -> None, and add a concise
docstring (rst style) above the body describing that it cancels the position
poll (self._pos_poll) if present and then calls super().terminate(); do not
include type information in the docstring itself, only in the signature.

Comment on lines +358 to +365
def terminate(self):
for child in self.children.value:
child.terminate()

if hasattr(self, "server"):
del self.server # to let the proxy close the connection

super().terminate()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add type hint + docstring to SEM.terminate.

Proposed fix
-    def terminate(self):
+    def terminate(self) -> None:
+        """Terminate child components and release the Pyro proxy."""
         for child in self.children.value:
             child.terminate()

As per coding guidelines: "Always use type hints for function parameters and return types in Python code" and "Include docstrings for all functions and classes, following the reStructuredText style guide (without type information)".

📝 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.

Suggested change
def terminate(self):
for child in self.children.value:
child.terminate()
if hasattr(self, "server"):
del self.server # to let the proxy close the connection
super().terminate()
def terminate(self) -> None:
"""Terminate child components and release the Pyro proxy."""
for child in self.children.value:
child.terminate()
if hasattr(self, "server"):
del self.server # to let the proxy close the connection
super().terminate()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/odemis/driver/xt_client.py` around lines 358 - 365, Add a
reStructuredText docstring and a return type hint to the SEM.terminate method:
change its signature to include -> None and add a brief docstring (one-line
summary plus short description) that explains it terminates child processes,
removes the server attribute to allow the proxy to close the connection, and
then calls super().terminate(); keep the docstring free of type annotations and
reference the attributes used (self.children, self.server) and the call to
super().terminate() in the description.

Comment on lines +1489 to +1494
def terminate(self):
if self._va_poll:
self._va_poll.cancel()
self._va_poll = None
super().terminate()

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add type hint + docstring to Scanner.terminate.

Proposed fix
-    def terminate(self):
+    def terminate(self) -> None:
+        """Stop polling timers and terminate the scanner."""
         if self._va_poll:
             self._va_poll.cancel()
             self._va_poll = None

As per coding guidelines: "Always use type hints for function parameters and return types in Python code" and "Include docstrings for all functions and classes, following the reStructuredText style guide (without type information)".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/odemis/driver/xt_client.py` around lines 1489 - 1494, The
Scanner.terminate method currently lacks a type hint and docstring; change its
signature to include a return type hint (def terminate(self) -> None) and add a
short reStructuredText-style docstring (one-line summary and brief description)
above the body describing that it cancels the _va_poll task if present and then
calls super().terminate(), keeping the implementation using
self._va_poll.cancel(), setting self._va_poll = None, and invoking
super().terminate().

Comment on lines 2153 to +2155
def terminate(self) -> None:
self._polling_thread.cancel()
super().terminate()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a docstring to Chamber.terminate.

Proposed fix
     def terminate(self) -> None:
+        """Stop polling and terminate the chamber component."""
         self._polling_thread.cancel()
         super().terminate()

As per coding guidelines: "Include docstrings for all functions and classes, following the reStructuredText style guide (without type information)".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/odemis/driver/xt_client.py` around lines 2153 - 2155, The method
Chamber.terminate lacks a docstring; add a reStructuredText-style docstring
(without type annotations) immediately under the def terminate(self) signature
that briefly describes what the method does (e.g., "Terminate the chamber:
cancel the internal polling thread and call the superclass terminate routine."),
mention any important side effects (cancels self._polling_thread and invokes
super().terminate()), and note any exceptions or lifecycle expectations if
applicable.

Comment on lines +2267 to +2275
def terminate(self):
if self._executor:
self._executor.cancel()
self._executor.shutdown()
self._executor = None
if self._pos_poll:
self._pos_poll.cancel()
self._pos_poll = None
super().terminate()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add type hint + docstring to Stage.terminate.

Proposed fix
-    def terminate(self):
+    def terminate(self) -> None:
+        """Stop polling/executor resources and terminate the stage."""
         if self._executor:
             self._executor.cancel()
             self._executor.shutdown()
             self._executor = None
         if self._pos_poll:
             self._pos_poll.cancel()
             self._pos_poll = None

As per coding guidelines: "Always use type hints for function parameters and return types in Python code" and "Include docstrings for all functions and classes, following the reStructuredText style guide (without type information)".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/odemis/driver/xt_client.py` around lines 2267 - 2275, The Stage.terminate
method is missing a type hint and a reStructuredText docstring; update the
method signature to include a return type (-> None) and add a short reST-style
docstring describing what terminate does and any side effects (e.g., cancels and
shuts down self._executor, cancels self._pos_poll, and calls
super().terminate()), without embedding type information in the docstring; keep
behavior unchanged and ensure the symbol name is Stage.terminate.

Comment on lines +2636 to +2641
def terminate(self):
if self._pos_poll:
self._pos_poll.cancel()
self._pos_poll = None
super().terminate()

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add type hint + docstring to Focus.terminate.

Proposed fix
-    def terminate(self):
+    def terminate(self) -> None:
+        """Stop polling resources and terminate the focus component."""
         if self._pos_poll:
             self._pos_poll.cancel()
             self._pos_poll = None

As per coding guidelines: "Always use type hints for function parameters and return types in Python code" and "Include docstrings for all functions and classes, following the reStructuredText style guide (without type information)".

📝 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.

Suggested change
def terminate(self):
if self._pos_poll:
self._pos_poll.cancel()
self._pos_poll = None
super().terminate()
def terminate(self) -> None:
"""Stop polling resources and terminate the focus component."""
if self._pos_poll:
self._pos_poll.cancel()
self._pos_poll = None
super().terminate()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/odemis/driver/xt_client.py` around lines 2636 - 2641, The Focus.terminate
method lacks a return type annotation and a reStructuredText-style docstring;
update the method signature to include a return type (def terminate(self) ->
None:) and add a short docstring (reST style, without type annotations)
describing that it cancels any active position poll (self._pos_poll), clears the
reference, and then calls the superclass terminate; keep the implementation
logic (self._pos_poll.cancel(); self._pos_poll = None; super().terminate())
unchanged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants