-
-
Notifications
You must be signed in to change notification settings - Fork 282
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
Add retry_if_exception_message #127
Conversation
b226357
to
3c7e03c
Compare
tenacity/retry.py
Outdated
"{}() missing 1 required argument 'message' or 'match'".format( | ||
self.__class__.__name__)) | ||
|
||
def _no_failure(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@staticmethod
Not sure it's worth having a method, just an attribute would be enough.
tenacity/retry.py
Outdated
|
||
return inverted_predicate | ||
|
||
def _no_failure(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure it's worth having a method, just an attribute would be enough.
tenacity/retry.py
Outdated
"{}() takes either 'message' or 'match', not both".format( | ||
self.__class__.__name__)) | ||
self.predicate = self._predicate_factory(message, match) | ||
self.require_exception = require_exception |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That does not seem to be related to the heart of the function. I'd remove that, and put that in a different class (and PR) if that's needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a shortcut that may be too specific to my use case. I'm happy to remove it and simply inherit from this in my projects.
@tenacity.retry(retry=tenacity.retry_if_exception_message("My message")
def my_fnc():
try:
# sometimes raise MyException("My message")
except Exception as e:
raise e
else:
raise ShouldveBeenException("We expected an exception to check message of, but didn't receive one")
whereas with the optional input it can be shorter and also not risk having the no-exception exception message matching the retry predicate.
@tenacity.retry(retry=tenacity.retry_if_exception_message("My message", require_exception=True))
def my_fnc():
# sometimes raise MyException("My message")
I think I was too focused on my negative testing use case though. Happy to remove as it simplifies the classes.
tenacity/retry.py
Outdated
@@ -111,6 +112,61 @@ def __call__(self, attempt): | |||
return not self.predicate(attempt.result()) | |||
|
|||
|
|||
class retry_if_exception_message(retry_base): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you should inherit from retry_if_exception
tenacity/retry.py
Outdated
"""Retry logic for no failure.""" | ||
return False | ||
|
||
def __call__(self, attempt): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not needed if you inherit from retry_if_exception
tenacity/retry.py
Outdated
raise TypeError( | ||
"{}() takes either 'message' or 'match', not both".format( | ||
self.__class__.__name__)) | ||
self.predicate = self._predicate_factory(message, match) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just pass the result to the __init__
method of retry_if_exception
here (since you will inherit from it). The factory method is not even really needed IMHO, you can put that code in __init__
.
|
||
class retry_if_not_exception_message(retry_if_exception_message): | ||
"""Retries until an exception message equals or matches.""" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just set invert the predicate in __init__
with a lambda I'd say.
Thanks for the review! Removed Removed Fixed a bug in the assumption of the errormessage retrieval and wrote an additional unit test to handle the positive case of Rebased on jd/master to a single commit. |
The _predicate_factory was originally wrapped. Wrapping made it more confusing. Easier to just have it clearly be the inverted predicate. Considered using an anti-pattern to set a dynamic name, but in reality the method that is decorated should make it obvious if it's initialized with message or match. Add imports to init
From issue #125.
Add retry classes for exception messages.
I'm very open to name suggestions. Specifically wondering if
retry_if_not_exception_message
orretry_until_exception_message
is best.retry_if_exception_message
and it's complement act different out of necessity. The normal class can end if there is no exception whereas it's inverse needs to retry if there is no exception message.It's worth noting in my branch unit tests are intermittently failing on wait class backwards incompatibility. I don't believe this is caused by any of my changes, but it's worth noting.