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.Ord
A 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
Failure
is 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
update
method,None
otherwise
-
end
¶ End time of the operation in seconds since the UNIX epoch if specified in the constructor or with the
update
method,None
otherwise
-
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: Try
objectReturns: 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
Try
to Success instancesApplies function to the value if and only if this is a
Success
.
-
map_failure
(function)[source]¶ The map operation of
Try
to Failure instancesApplies function to the value if and only if this is a
Success
.
-
message
¶ Return the message for the Try. If the
message
argument 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
exception
is 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
update
method,None
otherwise
-
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
stderr
instead 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
Failure
orSuccess
and 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.Try
Failure of
Try
.
-
class
tryme.
Success
(value, message=None, start=None, end=None, count=1)[source]¶ Bases:
tryme.tryme.Try
Success of
Try
.
-
class
tryme.
Again
(value, message=None, start=None, end=None, count=1)[source]¶ Bases:
tryme.tryme.Failure
Again of
Failure
. A handy alias ofFailure
to indicate that an operation should be retried
-
class
tryme.
Stop
(value, message=None, start=None, end=None, count=1)[source]¶ Bases:
tryme.tryme.Success
Stop of
Success
. A handy alias ofSuccess
to indicate that an operation should not be retried
-
class
tryme.
Maybe
(value)[source]¶ Bases:
tryme.tryme.Monad
,tryme.tryme.Ord
A 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,map
returns 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: Maybe
objectReturns: Maybe
-
classmethod
from_value
(value)[source]¶ Wraps
value
in aMaybe
monad.Returns a
Some
if the value is evaluated as true.Nothing
otherwise.
-
-
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
exception
is 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
stderr
instead 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
300
seconds. - delay (int) – (optional) delay between retries in seconds. Defaults to
5
seconds. - 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")