Version: pm_auto 2.0.4 (commit 373e30f)
File: pm_auto/addons/system.py, _on_shutdown (around line 59)
Description
The guard condition in _on_shutdown always evaluates to True for every possible value of reason, so it provides no protection:
def _on_shutdown(self, *args):
if len(args) == 0:
reason = 'None'
else:
reason = args[0]
if reason != 'None' or reason != None or reason != 0: # always True
...
shutdown()
Because the three comparisons are OR'd, at least one is always true regardless of reason:
reason = 'None' → 'None' != None is True → passes
reason = None → None != 'None' is True → passes
reason = 0 → 0 != 'None' is True → passes
The if len(args) == 0: reason = 'None' branch directly above implies the intent was for a missing/empty reason to be a no-op sentinel that skips shutdown. That suppression never happens — the condition can't reject anything.
Current impact
In 2.0.4 this is latent rather than active: every event mapped to shutdown is published with a truthy value (e.g. pipower5.py publishes shutdown_req of 1/2/3), so real shutdowns carry a real reason and behave correctly. The defect is that the guard offers no safety for any future or external caller that publishes shutdown with no args or a falsy reason — that would trigger a real shutdown() / shutdown -h now.
Corroborating evidence the sentinel path is vestigial
The no-args case appears never to have been exercised: OLEDAddon.show_shutdown_screen(self, reason) (in addons/oled/__init__.py) is also subscribed to shutdown and takes reason as a required positional argument, so a bare shutdown publish would raise TypeError there before _on_shutdown even ran.
Suggested fix
Change the OR to AND so the sentinels are correctly treated as no-ops (and use is not None):
if reason != 'None' and reason is not None and reason != 0:
Happy to open a PR with this one-line change against whichever branch you prefer if that's useful.
Version: pm_auto 2.0.4 (commit
373e30f)File:
pm_auto/addons/system.py,_on_shutdown(around line 59)Description
The guard condition in
_on_shutdownalways evaluates toTruefor every possible value ofreason, so it provides no protection:Because the three comparisons are OR'd, at least one is always true regardless of
reason:reason = 'None'→'None' != NoneisTrue→ passesreason = None→None != 'None'isTrue→ passesreason = 0→0 != 'None'isTrue→ passesThe
if len(args) == 0: reason = 'None'branch directly above implies the intent was for a missing/empty reason to be a no-op sentinel that skips shutdown. That suppression never happens — the condition can't reject anything.Current impact
In 2.0.4 this is latent rather than active: every event mapped to
shutdownis published with a truthy value (e.g.pipower5.pypublishesshutdown_reqof 1/2/3), so real shutdowns carry a real reason and behave correctly. The defect is that the guard offers no safety for any future or external caller that publishesshutdownwith no args or a falsy reason — that would trigger a realshutdown()/shutdown -h now.Corroborating evidence the sentinel path is vestigial
The no-args case appears never to have been exercised:
OLEDAddon.show_shutdown_screen(self, reason)(inaddons/oled/__init__.py) is also subscribed toshutdownand takesreasonas a required positional argument, so a bareshutdownpublish would raiseTypeErrorthere before_on_shutdowneven ran.Suggested fix
Change the OR to AND so the sentinels are correctly treated as no-ops (and use
is not None):Happy to open a PR with this one-line change against whichever branch you prefer if that's useful.