Skip to content
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

Adding documentation to classes and methods that did not have documentation prior #1832

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
15 changes: 15 additions & 0 deletions can/bit_timing.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ def __init__(
self._restrict_to_minimum_range()

def _validate(self) -> None:
"""
Validates CAN bus nominal timing parameters.
"""
if not 1 <= self.brp <= 64:
raise ValueError(f"bitrate prescaler (={self.brp}) must be in [1...64].")

Expand Down Expand Up @@ -105,6 +108,10 @@ def _validate(self) -> None:
raise ValueError("nof_samples must be 1 or 3")

def _restrict_to_minimum_range(self) -> None:
"""
Restricts and error checks for nominal bit time, bitrate prescaler
and bit range to the specified ranges.
"""
if not 8 <= self.nbt <= 25:
raise ValueError(f"nominal bit time (={self.nbt}) must be in [8...25].")

Expand Down Expand Up @@ -584,6 +591,9 @@ def __init__( # pylint: disable=too-many-arguments
self._restrict_to_minimum_range()

def _validate(self) -> None:
"""
Validates CAN bus nominal timing parameters.
"""
for param, value in self._data.items():
if value < 0: # type: ignore[operator]
err_msg = f"'{param}' (={value}) must not be negative."
Expand Down Expand Up @@ -630,6 +640,11 @@ def _validate(self) -> None:
)

def _restrict_to_minimum_range(self) -> None:
"""
Restricts and error checks for nominal bit time, time segment 1 and 2
for both nominal and data phases, and synchronization jump width for both
nominal and data pahses to ranges as specified in ISO 11898.
"""
# restrict to minimum required range as defined in ISO 11898
if not 8 <= self.nbt <= 80:
raise ValueError(f"Nominal bit time (={self.nbt}) must be in [8...80]")
Expand Down
10 changes: 10 additions & 0 deletions can/broadcastmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,12 +269,18 @@ def __init__(
self.start()

def stop(self) -> None:
"""
Stops cyclic send task.
"""
self.stopped = True
if USE_WINDOWS_EVENTS:
# Reset and signal any pending wait by setting the timer to 0
win32event.SetWaitableTimer(self.event.handle, 0, 0, None, None, False)

def start(self) -> None:
"""
Starts cyclic send task using a daemon thread.
"""
self.stopped = False
if self.thread is None or not self.thread.is_alive():
name = f"Cyclic send task for 0x{self.messages[0].arbitration_id:X}"
Expand All @@ -289,6 +295,10 @@ def start(self) -> None:
self.thread.start()

def _run(self) -> None:
"""
Sends messages on the bus periodically using a daemon thread.
Handles error conditions to maintain thread integrity.
"""
msg_index = 0
msg_due_time_ns = time.perf_counter_ns()

Expand Down
6 changes: 6 additions & 0 deletions can/bus.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,9 @@ def _detect_available_configs() -> List[can.typechecking.AutoDetectedConfig]:
raise NotImplementedError()

def fileno(self) -> int:
""" Raises error which indicates fileno method is not implemented for
the current CAN bus
"""
raise NotImplementedError("fileno is not implemented using current CAN bus")


Expand All @@ -540,4 +543,7 @@ class _SelfRemovingCyclicTask(CyclicSendTaskABC, ABC):
"""

def stop(self, remove_task: bool = True) -> None:
"""
Stops cyclic task and raises not implemented error.
"""
raise NotImplementedError()
8 changes: 8 additions & 0 deletions can/io/asc.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ def __init__(
self.internal_events_logged = False

def _extract_header(self) -> None:
"""
Takes a file and reads line by line looking for header
information and parses that data out, setting it to the appropriate
variable.

Comment lines will be skipped and parsing will be stopped after
necessary information is acquired.
"""
for _line in self.file:
line = _line.strip()

Expand Down
5 changes: 5 additions & 0 deletions can/io/canutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@ def __init__(
self.last_timestamp = None

def on_message_received(self, msg):
"""
Processes and logs incoming CAN messages in appropriate format.

:param msg: Received CAN message.
"""
# this is the case for the very first message:
if self.last_timestamp is None:
self.last_timestamp = msg.timestamp or 0.0
Expand Down
5 changes: 5 additions & 0 deletions can/io/csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ def __init__(
self.file.write("timestamp,arbitration_id,extended,remote,error,dlc,data\n")

def on_message_received(self, msg: Message) -> None:
"""
Processes and logs CAN message in CSV format.

:param msg: Received CAN message.
"""
row = ",".join(
[
repr(msg.timestamp), # cannot use str() here because that is rounding
Expand Down
4 changes: 4 additions & 0 deletions can/io/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,12 @@ def file_size(self) -> int:


class TextIOMessageWriter(FileIOMessageWriter, metaclass=ABCMeta):
"""The base class for writing messages to a text file."""
file: TextIO


class BinaryIOMessageWriter(FileIOMessageWriter, metaclass=ABCMeta):
"""The base class for writing messages to a binary file."""
file: Union[BinaryIO, gzip.GzipFile]


Expand All @@ -124,8 +126,10 @@ class MessageReader(BaseIOHandler, Iterable[Message], metaclass=ABCMeta):


class TextIOMessageReader(MessageReader, metaclass=ABCMeta):
"""The base class for reading messages from a text file."""
file: TextIO


class BinaryIOMessageReader(MessageReader, metaclass=ABCMeta):
"""The base class for reading messages from a binary file."""
file: Union[BinaryIO, gzip.GzipFile]
14 changes: 14 additions & 0 deletions can/io/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ def _update_writer_plugins() -> None:


def _get_logger_for_suffix(suffix: str) -> Type[MessageWriter]:
"""Retrieves logger class associated with file suffix.

:param suffix: File suffix for logger."""
try:
return MESSAGE_WRITERS[suffix]
except KeyError:
Expand Down Expand Up @@ -372,9 +375,17 @@ def __init__(

@property
def writer(self) -> FileIOMessageWriter:
"""
Returns current message wrtier.
"""
return self._writer

def should_rollover(self, msg: Message) -> bool:
"""
Determines if log file should be rolled over.

:param msg: Incoming message for determining rollover.
"""
if self.max_bytes <= 0:
return False

Expand All @@ -384,6 +395,9 @@ def should_rollover(self, msg: Message) -> bool:
return False

def do_rollover(self) -> None:
"""
Perform log rollover.
"""
if self.writer:
self.writer.stop()

Expand Down
5 changes: 5 additions & 0 deletions can/io/mf4.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,11 +183,15 @@ def file_size(self) -> int:
return cast(int, self._mdf._tempfile.tell()) # pylint: disable=protected-access

def stop(self) -> None:
"""Stops CAN bus logging process and saved recorded data."""
self._mdf.save(self.file, compression=self._compression_level)
self._mdf.close()
super().stop()

def on_message_received(self, msg: Message) -> None:
"""Processes and logs CAN messsage based on its type
:param msg: CAN message received
"""
channel = channel2int(msg.channel)

timestamp = msg.timestamp
Expand Down Expand Up @@ -481,5 +485,6 @@ def __iter__(self) -> Generator[Message, None, None]:
self.stop()

def stop(self) -> None:
"""Stops CAN logging and closes MDF file."""
self._mdf.close()
super().stop()
4 changes: 4 additions & 0 deletions can/io/printer.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ def __init__(
super().__init__(file, mode=mode)

def on_message_received(self, msg: Message) -> None:
"""Receives CAN message and either writes message to file or
prints message to console.
:param msg: CAN message received.
"""
if self.write_to_file:
cast(TextIO, self.file).write(str(msg) + "\n")
else:
Expand Down
10 changes: 10 additions & 0 deletions can/io/sqlite.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ def __iter__(self) -> Generator[Message, None, None]:

@staticmethod
def _assemble_message(frame_data):
"""
Assembles CAN message from given frame data.

:param frame_data: Frame containing data for timestamp information,
CAN ID, if CAN ID is extended, if message is remote frame, if message
is an error frame, the dlc of the message, and the payload of the message.
"""
timestamp, can_id, is_extended, is_remote, is_error, dlc, data = frame_data
return Message(
timestamp=timestamp,
Expand Down Expand Up @@ -192,6 +199,9 @@ def _create_db(self):
self._conn.commit()

def _db_writer_thread(self):
"""
Writes buffered CAN messages to database in a separate thread.
"""
self._create_db()

try:
Expand Down
8 changes: 8 additions & 0 deletions can/listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ def __init__(self, bus: BusABC, *args: Any, **kwargs: Any) -> None:
self.bus = bus

def on_message_received(self, msg: Message) -> None:
"""
Sends received message to CAN bus.

:param msg: Message object to send.
"""
self.bus.send(msg)


Expand Down Expand Up @@ -176,4 +181,7 @@ async def __anext__(self) -> Message:
return await self.buffer.get()

def stop(self) -> None:
"""
Stops buffer from accepting new messages.
"""
self._is_stopped = True
3 changes: 3 additions & 0 deletions can/logconvert.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@


class ArgumentParser(argparse.ArgumentParser):
"""
Prints help message and exits with error status.
"""
def error(self, message):
self.print_help(sys.stderr)
self.exit(errno.EINVAL, f"{self.prog}: error: {message}\n")
Expand Down
19 changes: 19 additions & 0 deletions can/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ def _append_filter_argument(


def _create_bus(parsed_args: argparse.Namespace, **kwargs: Any) -> can.BusABC:
"""
Creates and configures a CAN bus based on the passed arguments.

:param parsed_args: Parsed arguments.
"""
logging_level_names = ["critical", "error", "warning", "info", "debug", "subdebug"]
can.set_logging_level(logging_level_names[min(5, parsed_args.verbosity)])

Expand All @@ -114,6 +119,9 @@ def _create_bus(parsed_args: argparse.Namespace, **kwargs: Any) -> can.BusABC:


class _CanFilterAction(argparse.Action):
"""
Argparse action for handling CAN filter arguments.
"""
def __call__(
self,
parser: argparse.ArgumentParser,
Expand Down Expand Up @@ -144,11 +152,22 @@ def __call__(


def _parse_additional_config(unknown_args: Sequence[str]) -> TAdditionalCliArgs:
"""
Parses additional arguments from a sequence of unknown arguements.

:param unknown_args: Unknown arguments.
"""
for arg in unknown_args:
if not re.match(r"^--[a-zA-Z\-]*?=\S*?$", arg):
raise ValueError(f"Parsing argument {arg} failed")

def _split_arg(_arg: str) -> Tuple[str, str]:
"""
Helper function to split arguments in --key=value format
and returns as tuple with the newly formatted key_value.

:param _arg: Argument to be split
"""
left, right = _arg.split("=", 1)
return left.lstrip("-").replace("-", "_"), right

Expand Down
14 changes: 14 additions & 0 deletions can/notifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ def stop(self, timeout: float = 5) -> None:
listener.stop()

def _rx_thread(self, bus: BusABC) -> None:
"""Receives messages from CAN Bus and processes them.

:param bus: CAN bus from which messages are received.
"""
# determine message handling callable early, not inside while loop
handle_message = cast(
Callable[[Message], None],
Expand Down Expand Up @@ -140,10 +144,20 @@ def _rx_thread(self, bus: BusABC) -> None:
logger.debug("suppressed exception: %s", exc)

def _on_message_available(self, bus: BusABC) -> None:
"""Processes available messages on CAN bus as soon as it is
received.

: param bus: CAN bus from which messages are received.
"""
if msg := bus.recv(0):
self._on_message_received(msg)

def _on_message_received(self, msg: Message) -> None:
"""Handles received CAN message by notifying registered listeners. If
the listener returns a coroutine, event loop will be scheduled to run.

:param msg: CAN message received.
"""
for callback in self.listeners:
res = callback(msg)
if res and self._loop and asyncio.iscoroutine(res):
Expand Down
Loading