Skip to content

Commit

Permalink
executable examples (#1452)
Browse files Browse the repository at this point in the history
* Fix permissions of executable scripts

* Add shebang to examples/print_notifier.py

- it's executable
- it has a __name__=='__main__' section

* dos2unix

* make sure all python-files have a consistent line-ending

* make sure all ASC-files have a consistent line-ending
  • Loading branch information
umlaeute committed Nov 29, 2022
1 parent cc7f81e commit 486dafb
Show file tree
Hide file tree
Showing 7 changed files with 332 additions and 330 deletions.
244 changes: 122 additions & 122 deletions can/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,122 +1,122 @@
"""
There are several specific :class:`Exception` classes to allow user
code to react to specific scenarios related to CAN busses::
Exception (Python standard library)
+-- ...
+-- CanError (python-can)
+-- CanInterfaceNotImplementedError
+-- CanInitializationError
+-- CanOperationError
+-- CanTimeoutError
Keep in mind that some functions and methods may raise different exceptions.
For example, validating typical arguments and parameters might result in a
:class:`ValueError`. This should always be documented for the function at hand.
"""

import sys
from contextlib import contextmanager

from typing import Optional
from typing import Type

if sys.version_info >= (3, 9):
from collections.abc import Generator
else:
from typing import Generator


class CanError(Exception):
"""Base class for all CAN related exceptions.
If specified, the error code is automatically appended to the message:
>>> # With an error code (it also works with a specific error):
>>> error = CanOperationError(message="Failed to do the thing", error_code=42)
>>> str(error)
'Failed to do the thing [Error Code 42]'
>>>
>>> # Missing the error code:
>>> plain_error = CanError(message="Something went wrong ...")
>>> str(plain_error)
'Something went wrong ...'
:param error_code:
An optional error code to narrow down the cause of the fault
:arg error_code:
An optional error code to narrow down the cause of the fault
"""

def __init__(
self,
message: str = "",
error_code: Optional[int] = None,
) -> None:
self.error_code = error_code
super().__init__(
message if error_code is None else f"{message} [Error Code {error_code}]"
)


class CanInterfaceNotImplementedError(CanError, NotImplementedError):
"""Indicates that the interface is not supported on the current platform.
Example scenarios:
- No interface with that name exists
- The interface is unsupported on the current operating system or interpreter
- The driver could not be found or has the wrong version
"""


class CanInitializationError(CanError):
"""Indicates an error the occurred while initializing a :class:`can.BusABC`.
If initialization fails due to a driver or platform missing/being unsupported,
a :exc:`~can.exceptions.CanInterfaceNotImplementedError` is raised instead.
If initialization fails due to a value being out of range, a :class:`ValueError`
is raised.
Example scenarios:
- Try to open a non-existent device and/or channel
- Try to use an invalid setting, which is ok by value, but not ok for the interface
- The device or other resources are already used
"""


class CanOperationError(CanError):
"""Indicates an error while in operation.
Example scenarios:
- A call to a library function results in an unexpected return value
- An invalid message was received
- The driver rejected a message that was meant to be sent
- Cyclic redundancy check (CRC) failed
- A message remained unacknowledged
- A buffer is full
"""


class CanTimeoutError(CanError, TimeoutError):
"""Indicates the timeout of an operation.
Example scenarios:
- Some message could not be sent after the timeout elapsed
- No message was read within the given time
"""


@contextmanager
def error_check(
error_message: Optional[str] = None,
exception_type: Type[CanError] = CanOperationError,
) -> Generator[None, None, None]:
"""Catches any exceptions and turns them into the new type while preserving the stack trace."""
try:
yield
except Exception as error: # pylint: disable=broad-except
if error_message is None:
raise exception_type(str(error)) from error
else:
raise exception_type(error_message) from error
"""
There are several specific :class:`Exception` classes to allow user
code to react to specific scenarios related to CAN busses::
Exception (Python standard library)
+-- ...
+-- CanError (python-can)
+-- CanInterfaceNotImplementedError
+-- CanInitializationError
+-- CanOperationError
+-- CanTimeoutError
Keep in mind that some functions and methods may raise different exceptions.
For example, validating typical arguments and parameters might result in a
:class:`ValueError`. This should always be documented for the function at hand.
"""

import sys
from contextlib import contextmanager

from typing import Optional
from typing import Type

if sys.version_info >= (3, 9):
from collections.abc import Generator
else:
from typing import Generator


class CanError(Exception):
"""Base class for all CAN related exceptions.
If specified, the error code is automatically appended to the message:
>>> # With an error code (it also works with a specific error):
>>> error = CanOperationError(message="Failed to do the thing", error_code=42)
>>> str(error)
'Failed to do the thing [Error Code 42]'
>>>
>>> # Missing the error code:
>>> plain_error = CanError(message="Something went wrong ...")
>>> str(plain_error)
'Something went wrong ...'
:param error_code:
An optional error code to narrow down the cause of the fault
:arg error_code:
An optional error code to narrow down the cause of the fault
"""

def __init__(
self,
message: str = "",
error_code: Optional[int] = None,
) -> None:
self.error_code = error_code
super().__init__(
message if error_code is None else f"{message} [Error Code {error_code}]"
)


class CanInterfaceNotImplementedError(CanError, NotImplementedError):
"""Indicates that the interface is not supported on the current platform.
Example scenarios:
- No interface with that name exists
- The interface is unsupported on the current operating system or interpreter
- The driver could not be found or has the wrong version
"""


class CanInitializationError(CanError):
"""Indicates an error the occurred while initializing a :class:`can.BusABC`.
If initialization fails due to a driver or platform missing/being unsupported,
a :exc:`~can.exceptions.CanInterfaceNotImplementedError` is raised instead.
If initialization fails due to a value being out of range, a :class:`ValueError`
is raised.
Example scenarios:
- Try to open a non-existent device and/or channel
- Try to use an invalid setting, which is ok by value, but not ok for the interface
- The device or other resources are already used
"""


class CanOperationError(CanError):
"""Indicates an error while in operation.
Example scenarios:
- A call to a library function results in an unexpected return value
- An invalid message was received
- The driver rejected a message that was meant to be sent
- Cyclic redundancy check (CRC) failed
- A message remained unacknowledged
- A buffer is full
"""


class CanTimeoutError(CanError, TimeoutError):
"""Indicates the timeout of an operation.
Example scenarios:
- Some message could not be sent after the timeout elapsed
- No message was read within the given time
"""


@contextmanager
def error_check(
error_message: Optional[str] = None,
exception_type: Type[CanError] = CanOperationError,
) -> Generator[None, None, None]:
"""Catches any exceptions and turns them into the new type while preserving the stack trace."""
try:
yield
except Exception as error: # pylint: disable=broad-except
if error_message is None:
raise exception_type(str(error)) from error
else:
raise exception_type(error_message) from error

0 comments on commit 486dafb

Please sign in to comment.