Skip to content

Commit

Permalink
Avoid fataling on StrictMock(template=str).garbage
Browse files Browse the repository at this point in the history
Summary:
Accessing nonexistent attributes of `StrictMock`s templated on `str` causes fatals.
This is because of an unfortunate self-reference, where when a `UndefinedAttribute` or `AttributeError` is thrown, it tries to include `f"{self}"`, which invokes `self.__format__`, which hits the attribute handling, which triggers another UndefinedAttribute...

The solution is just to directly point those prints to `repr(self`)`, which works.

Reviewed By: deathowl

Differential Revision: D30966913

fbshipit-source-id: fd84a5ac256b9010acb676a32c6b9b4f8bba7fe0
  • Loading branch information
mrkmndz authored and facebook-github-bot committed Sep 21, 2021
1 parent a4ec5c6 commit 013b319
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 2 deletions.
12 changes: 12 additions & 0 deletions tests/strict_mock_testslide.py
Expand Up @@ -814,6 +814,18 @@ def it_yields_the_mock(self):
with self.strict_mock as target:
self.assertTrue(target is self.strict_mock)

@context.sub_context
def string_template(context):
@context.example
async def undefined_attribute(self) -> None:
with self.assertRaises(UndefinedAttribute):
StrictMock(template=str).join

@context.example
async def attribute_error(self) -> None:
with self.assertRaises(AttributeError):
StrictMock(template=str).garbage

@context.sub_context
def async_attributes(context):
@context.memoize_before
Expand Down
4 changes: 2 additions & 2 deletions testslide/strict_mock.py
Expand Up @@ -44,7 +44,7 @@ def __init__(
def __str__(self) -> str:
message = (
f"'{self.name}' is not set.\n"
f"{self.strict_mock} must have a value set for this attribute "
f"{repr(self.strict_mock)} must have a value set for this attribute "
"if it is going to be accessed."
)
if self.extra_msg is not None:
Expand Down Expand Up @@ -767,7 +767,7 @@ def __getattr__(self, name: str) -> Any:
if self._template and self.__template_has_attr(name):
raise UndefinedAttribute(self, name)
else:
raise AttributeError(f"'{name}' was not set for {self}.")
raise AttributeError(f"'{name}' was not set for {repr(self)}.")

def __delattr__(self, name: str) -> None:
if name in type(self).__dict__:
Expand Down

0 comments on commit 013b319

Please sign in to comment.