API Reference¶
tryme - error handling for humans
-
class
tryme.Try(value, message=None, start=None, end=None, count=1)[source]¶ Bases:
tryme.tryme.Monad,tryme.tryme.OrdA wrapper for operations that may fail
Represents values/computations with two possibilities.
Parameters: - value – value to contain
- message – (optional) message to output to console if to_console is called.
If None, a string representation of the contained value is output.
Defaults to
None - start (int) – (optional) start time for the operation, in seconds since the UNIX epoch
time.time() is typically used for this value. Defaults to
None. - end (int) – (optional) end time for the operation, in seconds since the UNIX epoch
time.time()is typically used for this value. Defaults toNone. - count – (optional) number of times the operation has been executed. Defaults to
1
Usage:
>>> Success(42) Success(42) >>> Success([1, 2, 3]) Success([1, 2, 3]) >>> Failure('Error') Failure('Error') >>> Success(Failure('Error')) Success(Failure('Error')) >>> isinstance(Success(1), Try) True >>> isinstance(Failure(None), Try) True >>> saving = 100 >>> insolvent = Failure('I am insolvent') >>> spend = lambda cost: insolvent if cost > saving else Success(saving - cost) >>> spend(90) Success(10) >>> spend(120) Failure('I am insolvent')
Map operation with
map, applies function to value only if it is a Success and returns a Success>>> inc = lambda n: n + 1 >>> Success(0) Success(0) >>> Success(0).map(inc) Success(1) >>> Success(0).map(inc).map(inc) Success(2) >>> Failure(0).map(inc) Failure(0)
Comparison with
==, as long as they are the same type and what’s wrapped inside are comparable.>>> Failure(42) == Failure(42) True >>> Success(42) == Success(42) True >>> Failure(42) == Success(42) False
A
Failureis less than aSuccess, or compare the two by the values inside if thay are of the same type.>>> Failure(42) < Success(42) True >>> Success(0) > Failure(100) True >>> Failure('Error message') > Success(42) False >>> Failure(100) > Failure(42) True >>> Success(-2) < Success(-1) True
-
count¶ Number of times the operation has been tried
-
elapsed¶ End time of the operation in seconds since the UNIX epoch if the start and end arguments were specified in the constructor or with the
updatemethod,Noneotherwise
-
end¶ End time of the operation in seconds since the UNIX epoch if specified in the constructor or with the
updatemethod,Noneotherwise
-
fail_for_error(exit_status=1)[source]¶ If a Failure, write the message to stderr and exit with return code of exit_status Does nothing if a Success
Parameters: exit_status (int) – (optional) the numeric exist status to return if exit is True
-
failed()[source]¶ Return a Boolean that indicates if the value is an instance of Failure
>>> Failure('shit is fucked up').failed() True >>> Success('it worked!').failed() False
-
filter(predicate)[source]¶ If a Success, convert this to a Failure if the predicate is not satisfied. Applies predicate to the wrapped value
Parameters: predicate – a function that takes the wrapped value as its argument and returns a boolean value Return type: TryobjectReturns: Try
-
get_or_else(default)[source]¶ Returns the value from this Success or the given default argument if this is a Failure.
-
map(function)[source]¶ The map operation of
Tryto Success instancesApplies function to the value if and only if this is a
Success.
-
map_failure(function)[source]¶ The map operation of
Tryto Failure instancesApplies function to the value if and only if this is a
Success.
-
message¶ Return the message for the Try. If the
messageargument was provided to the constructor that value is returned. Otherwise the string representation of the contained value is returened
-
raise_for_error(exception=<class 'tryme.tryme.FailureError'>)[source]¶ Raise an exception if self is an instance of Failure. If the wrapped value is an instance of Exeception or one of its subclasses, it is raised directly. The the optional argument
exceptionis specified, that type is raised with the wrapped value as its argument. Otherwise, FailureError is raised. This method has no effect is self is an instance of Success.Parameters: exception – (optional) type of Exception to raise
-
start¶ Start time of the operation in seconds since the UNIX epoch if specified in the constructor or with the
updatemethod,Noneotherwise
-
succeeded()[source]¶ Return a Boolean that indicates if the value is an instance of Success
>>> Success(True).succeeded() True >>> Failure('fubar').succeeded() False
-
to_console(nl=True, exit_err=False, exit_status=1)[source]¶ Write a message to the console. By convention, Success messages are written to stdout and Failure messages are written to stderr. The Failure’s cause is written to stderr while the string repesentation of the Success’s _value is written.
Parameters: - message – the message to print
- err – (optional) if set to true the file defaults to
stderrinstead ofstdout. - nl – (optional) if set to True (the default) a newline is printed afterwards.
- exit_err – (optional) if set to True, exit the running program with a non-zero exit code
- exit_status – (optional) the numeric exist status to return if exit is True
-
update(message=None, start=None, end=None, count=1)[source]¶ Update the Try with new properties but the same value. Returns a new
FailureorSuccessand does not actually update in place.Parameters: - message – (optional) message to output to console if to_console is called.
If None, a string representation of the contained value is output.
Defaults to
None - start (int) – (optional) start time for the operation, in seconds since the UNIX epoch
time.time() is typically used for this value. Defaults to
None. - end (int) – (optional) end time for the operation, in seconds since the UNIX epoch
time.time()is typically used for this value. Defaults toNone. - count – (optional) number of times the operation has been executed. Defaults to
1
- message – (optional) message to output to console if to_console is called.
If None, a string representation of the contained value is output.
Defaults to
-
class
tryme.Failure(value, message=None, start=None, end=None, count=1)[source]¶ Bases:
tryme.tryme.TryFailure of
Try.
-
class
tryme.Success(value, message=None, start=None, end=None, count=1)[source]¶ Bases:
tryme.tryme.TrySuccess of
Try.
-
class
tryme.Again(value, message=None, start=None, end=None, count=1)[source]¶ Bases:
tryme.tryme.FailureAgain of
Failure. A handy alias ofFailureto indicate that an operation should be retried
-
class
tryme.Stop(value, message=None, start=None, end=None, count=1)[source]¶ Bases:
tryme.tryme.SuccessStop of
Success. A handy alias ofSuccessto indicate that an operation should not be retried
-
class
tryme.Maybe(value)[source]¶ Bases:
tryme.tryme.Monad,tryme.tryme.OrdA wrapper for values that be None
>>> Some(42) Some(42) >>> Some([1, 2, 3]) Some([1, 2, 3]) >>> Some(Nothing) Some(Nothing) >>> Some(Some(2)) Some(Some(2)) >>> isinstance(Some(1), Maybe) True >>> isinstance(Nothing, Maybe) True >>> saving = 100 >>> spend = lambda cost: Nothing if cost > saving else Some(saving - cost) >>> spend(90) Some(10) >>> spend(120) Nothing >>> safe_div = lambda a, b: Nothing if b == 0 else Some(a / b) >>> safe_div(12.0, 6) Some(2.0) >>> safe_div(12.0, 0) Nothing
Map operation with
map. Not that map only applies a function if the object is an instance of Some. In the case of a Some,mapreturns the transformed value inside a Some. No action is taken for a Nothing.>>> inc = lambda n: n + 1 >>> Some(0) Some(0) >>> Some(0).map(inc) Some(1) >>> Some(0).map(inc).map(inc) Some(2) >>> Nothing.map(inc) Nothing
Comparison with
==, as long as what’s wrapped inside are comparable.>>> Some(42) == Some(42) True >>> Some(42) == Nothing False >>> Nothing == Nothing True
-
filter(predicate)[source]¶ Returns Some(value) if this is a Some and the value satisfies the given predicate.
Parameters: predicate – a function that takes the wrapped value as its argument and returns a boolean value Return type: MaybeobjectReturns: Maybe
-
classmethod
from_value(value)[source]¶ Wraps
valuein aMaybemonad.Returns a
Someif the value is evaluated as true.Nothingotherwise.
-
-
tryme.try_out(callable, exception=None)[source]¶ Executes a callable and wraps a raised exception in a Failure class. If an exception was not raised, a Success is returned. If the keyword argument
exceptionis not None, only wrap the specified exception. Raise all other exceptions. The stacktrace related to the exception is added to the wrapped exception as the stracktrace propertyParameters: callable – A callable reference, should return a value other than None Rtype Try: a Success or Failure
-
tryme.to_console(message=None, nl=True, err=False, exit_err=False, exit_status=1)[source]¶ Write a message to the console
Parameters: - message – the message to print
- err – (optional) if set to true the file defaults to
stderrinstead ofstdout. - nl – (optional) if set to True (the default) a newline is printed afterwards.
- exit_err – (optional) if set to True, exit the running program with a non-zero exit code
- exit_status – (optional) the numeric exist status to return if exit is True
-
tryme.retry(*args, **kwargs)[source]¶ Function that wraps a callable with a retry loop. The callable should only return :class:Failure, :class:Success, or raise an exception. This function can be used as a decorator or directly wrap a function. This method returns a a result object which is an instance of py:class:Success or py:class:Failure. This function updates the result with the time of the first attempt, the time of the last attempt, and the total count of attempts
Parameters: - acallable (function) – object that can be called
- timeout (int) – (optional) maximum period, in seconds, to wait until an individual try succeeds.
Defaults to
300seconds. - delay (int) – (optional) delay between retries in seconds. Defaults to
5seconds. - status_callback (function) – (optional) callback to invoke after each retry, is passed the result
as an argument. Defaults to
None.
- Usage::
>>> deadline = time.time() + 300 >>> dinner_iterator = iter([False, False, True]) >>> def dinner_is_ready(): ... return next(dinner_iterator) >>> breakfast_iterator = iter([False, False, True]) >>> def breakfast_is_ready(): ... return next(breakfast_iterator) >>> @retry ... def wait_for_dinner(): ... if dinner_is_ready(): ... return Success("Ready!") ... else: ... return Failure("not ready yet") >>> result = wait_for_dinner() >>> result Success("Ready!") >>> result.elapsed 8 >>> result.count 3 >>> @retry ... def wait_for_breakfast(): ... if breakfast_is_ready(): ... return Success("Ready!") ... else: ... return Failure("not ready yet") >>> result = wait_for_breakfast() Success("Ready!") >>> result.elapsed 8 >>> result.count 3
The names py:class:Success and py:class:Failure do not always map well to operations that need to be retried. The subclasses py:class:Stop and py:class:Again can be more intuitive.:
>>> breakfast_iterator = iter([False, False, True]) >>> def breakfast_is_ready(): ... return next(breakfast_iterator) >>> @retry ... def wait_for_breakfast(): ... if breakfast_is_ready(): ... return Stop("Ready!") ... else: ... return Again("not ready yet")