Skip to content

Commit

Permalink
using Self now that it's available in typing_extensions (#124)
Browse files Browse the repository at this point in the history
* using `Self` now that it's available in typing_extensions
* updated ruff configuration to move all possible imports into TYPE_CHECKING
  • Loading branch information
bandophahita authored Feb 14, 2024
1 parent 60e6da8 commit 1c8a8b2
Show file tree
Hide file tree
Showing 11 changed files with 112 additions and 89 deletions.
15 changes: 15 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,17 @@ ignore = [
"ANN102", # missing cls annotation, we only annotate cls when we return it.
]

extend-safe-fixes = [
"EM101",
"EM102",
"TCH001", "TCH002", "TCH003", "TCH004",
"C419",
"D200", "D205", "D415",
"PT003", "PT006", "PT018",
"RET504",
"UP006", "UP007",
]

[tool.ruff.lint.per-file-ignores]
"tests/**" = [
"D", # we don't need public-API-polished docstrings in tests.
Expand Down Expand Up @@ -206,6 +217,10 @@ ignore-overlong-task-comments = true
convention = "google"


[tool.ruff.lint.flake8-type-checking]
strict = true


[build-system]
requires = ["poetry-core>=1.2.0"]
build-backend = "poetry.core.masonry.api"
6 changes: 4 additions & 2 deletions screenpy/actions/either.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
from screenpy.speech_tools import get_additive_description

if TYPE_CHECKING:
from typing_extensions import Self

from screenpy import Actor
from screenpy.protocols import Performable

Expand Down Expand Up @@ -62,7 +64,7 @@ def perform_as(self, the_actor: Actor) -> None:
the_actor.will(*self.except_performables)
return

def or_(self, *except_performables: Performable) -> Either:
def or_(self, *except_performables: Performable) -> Self:
"""Provide the alternative routine to perform.
Aliases:
Expand All @@ -77,7 +79,7 @@ def or_(self, *except_performables: Performable) -> Either:

except_ = else_ = otherwise = alternatively = failing_that = or_

def ignoring(self, *ignored_exceptions: type[BaseException]) -> Either:
def ignoring(self, *ignored_exceptions: type[BaseException]) -> Self:
"""Set the expception classes to ignore."""
self.ignore_exceptions = ignored_exceptions
return self
Expand Down
9 changes: 4 additions & 5 deletions screenpy/actions/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,20 @@

from __future__ import annotations

from typing import TYPE_CHECKING, TypeVar
from typing import TYPE_CHECKING

from screenpy.pacing import aside, beat
from screenpy.protocols import Answerable
from screenpy.speech_tools import get_additive_description, represent_prop

if TYPE_CHECKING:
from typing_extensions import Self

from screenpy.actor import Actor

from .see import T_Q


SelfLog = TypeVar("SelfLog", bound="Log")


class Log:
"""Log the answer to a Question, or anything.
Expand All @@ -30,7 +29,7 @@ class Log:
"""

@classmethod
def the(cls: type[SelfLog], question: T_Q) -> SelfLog:
def the(cls, question: T_Q) -> Self:
"""Supply the Question to answer."""
return cls(question)

Expand Down
17 changes: 9 additions & 8 deletions screenpy/actions/make_note.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@
from screenpy.speech_tools import represent_prop

if TYPE_CHECKING:
from typing import TypeVar, Union
from typing import Union

from typing_extensions import Self

from screenpy.actor import Actor

SelfMakeNote = TypeVar("SelfMakeNote", bound="MakeNote")
T_Q = Union[Answerable, object]


Expand All @@ -39,7 +40,7 @@ class MakeNote:
question: T_Q

@classmethod
def of(cls: type[SelfMakeNote], question: T_Q) -> SelfMakeNote:
def of(cls, question: T_Q) -> Self:
"""Supply the Question to answer and its arguments.
Aliases:
Expand All @@ -48,21 +49,21 @@ def of(cls: type[SelfMakeNote], question: T_Q) -> SelfMakeNote:
return cls(question)

@classmethod
def of_the(cls: type[SelfMakeNote], question: T_Q) -> SelfMakeNote:
def of_the(cls, question: T_Q) -> Self:
"""Alias for :meth:`~screenpy.actions.MakeNote.of`."""
return cls.of(question)

def as_(self: SelfMakeNote, key: str) -> SelfMakeNote:
def as_(self, key: str) -> Self:
"""Set the key to use to recall this noted value."""
self.key = key
return self

def describe(self: SelfMakeNote) -> str:
def describe(self) -> str:
"""Describe the Action in present tense."""
return f"Make a note under {represent_prop(self.key)}."

@beat("{} jots something down under {key_to_log}.")
def perform_as(self: SelfMakeNote, the_actor: Actor) -> None:
def perform_as(self, the_actor: Actor) -> None:
"""Direct the Actor to take a note."""
if self.key is None:
msg = "No key was provided to name this note."
Expand All @@ -81,7 +82,7 @@ def perform_as(self: SelfMakeNote, the_actor: Actor) -> None:
Director().notes(self.key, value)

def __init__(
self: SelfMakeNote,
self,
question: T_Q,
key: str | None = None,
) -> None:
Expand Down
21 changes: 10 additions & 11 deletions screenpy/actions/pause.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@
from screenpy.pacing import beat

if TYPE_CHECKING:
from typing import TypeVar

from screenpy.actor import Actor
from typing_extensions import Self

SelfPause = TypeVar("SelfPause", bound="Pause")
from screenpy.actor import Actor


class Pause:
Expand Down Expand Up @@ -43,11 +42,11 @@ class Pause:
reason: str

@classmethod
def for_(cls: type[SelfPause], number: float) -> SelfPause:
def for_(cls, number: float) -> Self:
"""Specify how many seconds or milliseconds to wait for."""
return cls(number)

def seconds_because(self: SelfPause, reason: str) -> SelfPause:
def seconds_because(self, reason: str) -> Self:
"""Use seconds and provide a reason for the pause.
Aliases:
Expand All @@ -57,23 +56,23 @@ def seconds_because(self: SelfPause, reason: str) -> SelfPause:
self.reason = self._massage_reason(reason)
return self

def second_because(self: SelfPause, reason: str) -> SelfPause:
def second_because(self, reason: str) -> Self:
"""Alias for :meth:`~screenpy.actions.Pause.seconds_because`."""
return self.seconds_because(reason)

def milliseconds_because(self: SelfPause, reason: str) -> SelfPause:
def milliseconds_because(self, reason: str) -> Self:
"""Use milliseconds and provide a reason for the pause."""
self.unit = f"millisecond{'s' if self.number != 1 else ''}"
self.time = self.time / 1000.0
self.reason = self._massage_reason(reason)
return self

def describe(self: SelfPause) -> str:
def describe(self) -> str:
"""Describe the Action in present tense."""
return f"Pause for {self.number} {self.unit} {self.reason}."

@beat("{} pauses for {number} {unit} {reason}.")
def perform_as(self: SelfPause, _: Actor) -> None:
def perform_as(self, _: Actor) -> None:
"""Direct the Actor to take their union-mandated break."""
if not self.reason:
msg = (
Expand All @@ -84,14 +83,14 @@ def perform_as(self: SelfPause, _: Actor) -> None:

sleep(self.time)

def _massage_reason(self: SelfPause, reason: str) -> str:
def _massage_reason(self, reason: str) -> str:
"""Apply some gentle massaging to the reason string."""
if not reason.startswith("because"):
reason = f"because {reason}"

return re.sub(r"\W*$", "", reason)

def __init__(self: SelfPause, number: float) -> None:
def __init__(self, number: float) -> None:
self.number = number
self.time = number
self.unit = f"second{'s' if self.number != 1 else ''}"
Expand Down
16 changes: 9 additions & 7 deletions screenpy/actions/see.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@
from hamcrest import assert_that

from screenpy.pacing import aside, beat
from screenpy.protocols import Answerable, ErrorKeeper, Resolvable
from screenpy.protocols import Answerable, ErrorKeeper
from screenpy.speech_tools import get_additive_description, represent_prop

if TYPE_CHECKING:
from typing import TypeVar, Union
from typing import Union

from typing_extensions import Self

from screenpy.actor import Actor
from screenpy.protocols import Resolvable

SelfSee = TypeVar("SelfSee", bound="See")
T_Q = Union[Answerable, object]
T_R = Resolvable

Expand Down Expand Up @@ -44,16 +46,16 @@ class See:
resolution_to_log: str

@classmethod
def the(cls: type[SelfSee], question: T_Q, resolution: T_R) -> SelfSee:
def the(cls, question: T_Q, resolution: T_R) -> Self:
"""Supply the Question (or value) and Resolution to test."""
return cls(question, resolution)

def describe(self: SelfSee) -> str:
def describe(self) -> str:
"""Describe the Action in present tense."""
return f"See if {self.question_to_log} is {self.resolution_to_log}."

@beat("{} sees if {question_to_log} is {resolution_to_log}.")
def perform_as(self: SelfSee, the_actor: Actor) -> None:
def perform_as(self, the_actor: Actor) -> None:
"""Direct the Actor to make an observation."""
if isinstance(self.question, Answerable):
value: object = self.question.answered_by(the_actor)
Expand All @@ -68,7 +70,7 @@ def perform_as(self: SelfSee, the_actor: Actor) -> None:

assert_that(value, self.resolution.resolve(), reason)

def __init__(self: SelfSee, question: T_Q, resolution: T_R) -> None:
def __init__(self, question: T_Q, resolution: T_R) -> None:
self.question = question
self.question_to_log = get_additive_description(question)
self.resolution = resolution
Expand Down
13 changes: 7 additions & 6 deletions screenpy/actions/see_all_of.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@

from __future__ import annotations

from typing import TYPE_CHECKING, Tuple, TypeVar
from typing import TYPE_CHECKING, Tuple

from screenpy.exceptions import UnableToAct
from screenpy.pacing import beat

from .see import See

if TYPE_CHECKING:
from typing_extensions import Self

from screenpy.actor import Actor

from .see import T_Q, T_R

SelfSeeAllOf = TypeVar("SelfSeeAllOf", bound="SeeAllOf")
T_T = Tuple[T_Q, T_R]


Expand Down Expand Up @@ -43,21 +44,21 @@ class SeeAllOf:
tests: tuple[T_T, ...]

@classmethod
def the(cls: type[SelfSeeAllOf], *tests: T_T) -> SelfSeeAllOf:
def the(cls, *tests: T_T) -> Self:
"""Supply any number of Question/value + Resolution tuples to test."""
return cls(*tests)

def describe(self: SelfSeeAllOf) -> str:
def describe(self) -> str:
"""Describe the Action in present tense."""
return f"See if {self.log_message}."

@beat("{} sees if {log_message}:")
def perform_as(self: SelfSeeAllOf, the_actor: Actor) -> None:
def perform_as(self, the_actor: Actor) -> None:
"""Direct the Actor to make a series of observations."""
for question, resolution in self.tests:
the_actor.should(See.the(question, resolution))

def __init__(self: SelfSeeAllOf, *tests: T_T) -> None:
def __init__(self, *tests: T_T) -> None:
for tup in tests:
if isinstance(tup, tuple):
if len(tup) != 2: # noqa: PLR2004
Expand Down
13 changes: 7 additions & 6 deletions screenpy/actions/see_any_of.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@
from .see import See

if TYPE_CHECKING:
from typing import Tuple, TypeVar
from typing import Tuple

from typing_extensions import Self

from screenpy.actor import Actor

from .see import T_Q, T_R

SelfSeeAnyOf = TypeVar("SelfSeeAnyOf", bound="SeeAnyOf")
T_T = Tuple[T_Q, T_R]


Expand Down Expand Up @@ -46,16 +47,16 @@ class SeeAnyOf:
tests: tuple[T_T, ...]

@classmethod
def the(cls: type[SelfSeeAnyOf], *tests: T_T) -> SelfSeeAnyOf:
def the(cls, *tests: T_T) -> Self:
"""Supply any number of Question/value + Resolution tuples to test."""
return cls(*tests)

def describe(self: SelfSeeAnyOf) -> str:
def describe(self) -> str:
"""Describe the Action in present tense."""
return f"See if {self.log_message}."

@beat("{} sees if {log_message}:")
def perform_as(self: SelfSeeAnyOf, the_actor: Actor) -> None:
def perform_as(self, the_actor: Actor) -> None:
"""Direct the Actor to make a series of observations."""
if not self.tests:
# No tests is OK!
Expand All @@ -72,7 +73,7 @@ def perform_as(self: SelfSeeAnyOf, the_actor: Actor) -> None:
msg = f"{the_actor} did not find any expected answers!"
raise AssertionError(msg)

def __init__(self: SelfSeeAnyOf, *tests: T_T) -> None:
def __init__(self, *tests: T_T) -> None:
for tup in tests:
if isinstance(tup, tuple):
if len(tup) != 2: # noqa: PLR2004
Expand Down
Loading

0 comments on commit 1c8a8b2

Please sign in to comment.