Skip to content

Commit

Permalink
Document and type scenarios.py
Browse files Browse the repository at this point in the history
  • Loading branch information
Qalthos committed Oct 9, 2024
1 parent 3d144cb commit b6c2b40
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 42 deletions.
7 changes: 0 additions & 7 deletions .config/pydoclint-baseline.txt
Original file line number Diff line number Diff line change
Expand Up @@ -404,13 +404,6 @@ src/molecule/provisioner/base.py
DOC107: Method `Base.__init__`: The option `--arg-type-hints-in-signature` is `True` but not all args in the signature have type hints
DOC202: Method `Base.name` has a return section in docstring, but there are no return statements or annotations
--------------------
src/molecule/scenarios.py
DOC601: Class `Scenarios`: Class docstring contains fewer class attributes than actual class attributes. (Please read https://jsh9.github.io/pydoclint/checking_class_attributes.html on how to correctly document class attributes.)
DOC603: Class `Scenarios`: Class docstring attributes are different from actual class attributes. (Or could be other formatting issues: https://jsh9.github.io/pydoclint/violation_codes.html#notes-on-doc103 ). Attributes in the class definition but not in the docstring: [__next__: ]. (Please read https://jsh9.github.io/pydoclint/checking_class_attributes.html on how to correctly document class attributes.)
DOC106: Method `Scenarios.__init__`: The option `--arg-type-hints-in-signature` is `True` but there are no argument type hints in the signature
DOC107: Method `Scenarios.__init__`: The option `--arg-type-hints-in-signature` is `True` but not all args in the signature have type hints
DOC201: Method `Scenarios.__iter__` does not have a return section in docstring
--------------------
src/molecule/shell.py
DOC101: Function `print_version`: Docstring contains fewer arguments than in function signature.
DOC106: Function `print_version`: The option `--arg-type-hints-in-signature` is `True` but there are no argument type hints in the signature
Expand Down
2 changes: 1 addition & 1 deletion src/molecule/scenario.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ def sequence(self) -> list[str]:
"""
result = []
our_scenarios = scenarios.Scenarios([self.config])
matrix = our_scenarios._get_matrix() # type: ignore[no-untyped-call] # noqa: SLF001
matrix = our_scenarios._get_matrix() # noqa: SLF001

try:
result = matrix[self.name][self.config.subcommand]
Expand Down
81 changes: 47 additions & 34 deletions src/molecule/scenarios.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@

import logging

from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Self

from molecule import util


if TYPE_CHECKING:
from molecule.config import Config
from molecule.scenario import Scenario


Expand All @@ -37,46 +38,61 @@
class Scenarios:
"""The Scenarios groups one or more scenario objects Molecule will execute."""

def __init__(self, configs, scenario_name=None) -> None: # type: ignore[no-untyped-def] # noqa: ANN001
def __init__(
self,
configs: list[Config],
scenario_name: str | None = None,
) -> None:
"""Initialize a new scenarios class and returns None.
Args:
configs: A list containing Molecule config instances.
scenario_name: A string containing the name of the scenario.
configs: Molecule config instances.
scenario_name: The name of the scenario.
"""
self._configs = configs
self._scenario_name = scenario_name
self._scenarios = self.all

def next(self) -> Scenario: # noqa: D102
if not self._scenarios:
raise StopIteration
return self._scenarios.pop(0)
def __iter__(self) -> Self:
"""Make object iterable.
def __iter__(self): # type: ignore[no-untyped-def] # noqa: ANN204
"""Make object iterable."""
Returns:
The object itself, as Scenarios is iterable.
"""
return self

__next__ = next # Python 3.X compatibility
def __next__(self) -> Scenario:
"""Iterate over Scenario objects.
Returns:
The next Scenario in the sequence.
Raises:
StopIteration: When the scenarios are exhausted.
"""
if not self._scenarios:
raise StopIteration
return self._scenarios.pop(0)

@property
def all(self) -> list[Scenario]:
"""Return a list containing all scenario objects.
Returns:
list
All Scenario objects.
"""
if self._scenario_name:
scenarios = self._filter_for_scenario()
self._verify() # type: ignore[no-untyped-call]
self._verify()

return scenarios

scenarios = [c.scenario for c in self._configs]
scenarios.sort(key=lambda x: x.directory)
return scenarios

def print_matrix(self) -> None: # noqa: D102
def print_matrix(self) -> None:
"""Show the test matrix for all scenarios."""
msg = "Test matrix"
LOG.info(msg)

Expand All @@ -85,16 +101,27 @@ def print_matrix(self) -> None: # noqa: D102
tree[scenario.name] = list(scenario.sequence)
util.print_as_yaml(tree)

def sequence(self, scenario_name: str) -> list[str]: # noqa: D102
def sequence(self, scenario_name: str) -> list[str]:
"""Sequence for a given scenario.
Args:
scenario_name: Name of the scenario to determine the sequence of.
Returns:
A list of steps for that scenario.
Raises:
RuntimeError: If the scenario cannot be found.
"""
for scenario in self.all:
if scenario.name == scenario_name:
return list(scenario.sequence)
raise RuntimeError( # noqa: TRY003
f"Unable to find sequence for {scenario_name} scenario.", # noqa: EM102
)

def _verify(self): # type: ignore[no-untyped-def] # noqa: ANN202
"""Verify the specified scenario was found and returns None."""
def _verify(self) -> None:
"""Verify the specified scenario was found."""
scenario_names = [c.scenario.name for c in self._configs]
if self._scenario_name not in scenario_names:
msg = f"Scenario '{self._scenario_name}' not found. Exiting."
Expand All @@ -108,25 +135,11 @@ def _filter_for_scenario(self) -> list[Scenario]:
"""
return [c.scenario for c in self._configs if c.scenario.name == self._scenario_name]

def _get_matrix(self): # type: ignore[no-untyped-def] # noqa: ANN202
"""Build a matrix of scenarios with sequence to include and returns a dict.
{
scenario_1: {
'subcommand': [
'action-1',
'action-2',
],
},
scenario_2: {
'subcommand': [
'action-1',
],
},
}
def _get_matrix(self) -> dict[str, dict[str, list[str]]]:
"""Build a matrix of scenarios and step sequences.
Returns:
dict
A dictionary for each scenario listing action sequences for each step.
"""
return {
scenario.name: {
Expand Down

0 comments on commit b6c2b40

Please sign in to comment.