Skip to content

Improved error messages #52

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions commands2/commandscheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,11 @@ def setDefaultCommand(self, subsystem: Subsystem, defaultCommand: Command) -> No
self.requireNotComposed(defaultCommand)

if subsystem not in defaultCommand.getRequirements():
raise IllegalCommandUse("Default commands must require their subsystem!")
raise IllegalCommandUse(
"Default commands must require their subsystem!",
command=defaultCommand,
subsystem=subsystem,
)

if (
defaultCommand.getInterruptionBehavior()
Expand Down Expand Up @@ -589,7 +593,8 @@ def requireNotComposed(self, *commands: Command) -> None:
if location is not None:
raise IllegalCommandUse(
"Commands that have been composed may not be added to another"
f"composition or scheduled individually (originally composed at {location})"
f"composition or scheduled individually (originally composed at {location})",
command=command,
)

def requireNotComposedOrScheduled(self, *commands: Command) -> None:
Expand All @@ -604,7 +609,8 @@ def requireNotComposedOrScheduled(self, *commands: Command) -> None:
for command in commands:
if self.isScheduled(command):
raise IllegalCommandUse(
"Commands that have been scheduled individually may not be added to a composition!"
"Commands that have been scheduled individually may not be added to a composition!",
command=command,
)
self.requireNotComposed(command)

Expand Down
11 changes: 11 additions & 0 deletions commands2/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
# notrack

import typing


class IllegalCommandUse(Exception):
"""
This exception is raised when a command is used in a way that it shouldn't be.

You shouldn't try to catch this exception, if it occurs it means your code is
doing something it probably shouldn't be doing
"""

def __init__(self, msg: str, **kwargs: typing.Any) -> None:
if kwargs:
args_repr = ", ".join(f"{k}={v!r}" for k, v in kwargs.items())
msg = f"{msg} ({args_repr})"

super().__init__(msg)
6 changes: 4 additions & 2 deletions commands2/parallelcommandgroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,11 @@ def addCommands(self, *commands: Command):
CommandScheduler.getInstance().registerComposedCommands(commands)

for command in commands:
if not command.getRequirements().isdisjoint(self.requirements):
in_common = command.getRequirements().intersection(self.requirements)
if in_common:
raise IllegalCommandUse(
"Multiple comands in a parallel composition cannot require the same subsystems."
"Multiple commands in a parallel composition cannot require the same subsystems.",
common=in_common,
)

self._commands[command] = False
Expand Down
9 changes: 6 additions & 3 deletions commands2/paralleldeadlinegroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ def setDeadline(self, deadline: Command):

if deadline in self._commands:
raise IllegalCommandUse(
f"The deadline command cannot also be in the other commands!"
f"The deadline command cannot also be in the other commands!",
deadline=deadline,
)
self.addCommands(deadline)
self._deadline = deadline
Expand All @@ -82,9 +83,11 @@ def addCommands(self, *commands: Command):
CommandScheduler.getInstance().registerComposedCommands(commands)

for command in commands:
if not command.getRequirements().isdisjoint(self.requirements):
in_common = command.getRequirements().intersection(self.requirements)
if in_common:
raise IllegalCommandUse(
"Multiple commands in a parallel composition cannot require the same subsystems."
"Multiple commands in a parallel composition cannot require the same subsystems.",
common=in_common,
)

self._commands[command] = False
Expand Down
6 changes: 4 additions & 2 deletions commands2/parallelracegroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@ def addCommands(self, *commands: Command):
CommandScheduler.getInstance().registerComposedCommands(commands)

for command in commands:
if not command.getRequirements().isdisjoint(self.requirements):
in_common = command.getRequirements().intersection(self.requirements)
if in_common:
raise IllegalCommandUse(
"Multiple comands in a parallel composition cannot require the same subsystems."
"Multiple commands in a parallel composition cannot require the same subsystems.",
common=in_common,
)

self._commands.add(command)
Expand Down
4 changes: 2 additions & 2 deletions commands2/pidsubsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,15 @@ def useOutput(self, output: float, setpoint: float):
:param output: The output of the PIDController.
:param setpoint: The setpoint of the PIDController (for feedforward).
"""
raise NotImplementedError("Subclasses must implement this method")
raise NotImplementedError(f"{self.__class__} must implement useOutput")

def getMeasurement(self) -> float:
"""
Returns the measurement of the process variable used by the PIDController.

:return: The measurement of the process variable.
"""
raise NotImplementedError("Subclasses must implement this method")
raise NotImplementedError(f"{self.__class__} must implement getMeasurement")

def enable(self):
"""Enables the PID control. Resets the controller."""
Expand Down
2 changes: 1 addition & 1 deletion commands2/trapezoidprofilesubsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,4 @@ def useState(self, state: TrapezoidProfile.State):

:param state: The current state of the motion profile.
"""
raise NotImplementedError("Subclasses must implement this method")
raise NotImplementedError(f"{self.__class__} must implement useState")