cs.result


Namecs.result JSON
Version 20240412 PyPI version JSON
download
home_pageNone
SummaryResult and friends: various subclassable classes for deferred delivery of values.
upload_time2024-04-12 04:38:17
maintainerNone
docs_urlNone
authorNone
requires_pythonNone
licenseGNU General Public License v3 or later (GPLv3+)
keywords python2 python3
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            Result and friends: various subclassable classes for deferred delivery of values.

*Latest release 20240412*:
Result.bg: plumb _foo arguments to cs.threads.bg as foo.

A `Result` is the base class for several callable subclasses
which will receive values at a later point in time,
and can also be used standalone without subclassing.

A call to a `Result` will block until the value is received or the `Result` is cancelled,
which will raise an exception in the caller.
A `Result` may be called by multiple users, before or after the value has been delivered;
if the value has been delivered the caller returns with it immediately.
A `Result`'s state may be inspected (pending, running, ready, cancelled).
Callbacks can be registered via a `Result`'s .notify method.

An incomplete `Result` can be told to call a function to compute its value;
the function return will be stored as the value unless the function raises an exception,
in which case the exception information is recorded instead.
If an exception occurred, it will be reraised for any caller of the `Result`.

Trite example:

    R = Result(name="my demo")

Thread 1:

    # this blocks until the Result is ready
    value = R()
    print(value)
    # prints 3 once Thread 2 (below) assigns to it

Thread 2:

    R.result = 3

Thread 3:

    value = R()
    # returns immediately with 3

You can also collect multiple `Result`s in completion order using the `report()` function:

    Rs = [ ... list of Results of whatever type ... ]
    ...
    for R in report(Rs):
        x = R()     # collect result, will return immediately because
                    # the Result is complete
        print(x)    # print result

## Function `after(Rs, R, func, *a, **kw)`

After the completion of `Rs` call `func(*a,**kw)` and return
its result via `R`; return the `Result` object.

Parameters:
* `Rs`: an iterable of Results.
* `R`: a `Result` to collect to result of calling `func`.
  If `None`, one will be created.
* `func`, `a`, `kw`: a callable and its arguments.

## Function `bg(func, *a, **kw)`

Dispatch a `Thread` to run `func`, return a `Result` to collect its value.

Parameters:
* `_name`: optional name for the `Result`, passed to the initialiser
* `_extra`: optional extra data for the `Result`, passed to the initialiser

Other parameters are passed to `func`.

## Function `call_in_thread(func, *a, **kw)`

Run `func(*a,**kw)` in a separate `Thread` via the `@in_thread` decorator.
Return or exception is as for the original function.

## Class `CancellationError(builtins.Exception)`

Raised when accessing `result` or `exc_info` after cancellation.

*Method `CancellationError.__init__(self, message=None, **kw)`*:
Initialise the `CancellationError`.

The optional `message` parameter (default `"cancelled"`)
is set as the `message` attribute.
Other keyword parameters set their matching attributes.

## Function `in_thread(func)`

Decorator to evaluate `func` in a separate `Thread`.
Return or exception is as for the original function.

This exists to step out of the current `Thread's` thread
local context, such as a database transaction associated
with Django's implicit per-`Thread` database context.

## Class `OnDemandFunction(Result)`

Wrap a callable, run it when required.

## Class `OnDemandResult(Result)`

Wrap a callable, run it when required.

## Function `report(LFs)`

Generator which yields completed `Result`s.

This is a generator that yields `Result`s as they complete,
useful for waiting for a sequence of `Result`s
that may complete in an arbitrary order.

## Class `Result(cs.fsm.FSM)`

Base class for asynchronous collection of a result.
This is used to make `Result`, `OnDemandFunction`s, `LateFunction`s
and other objects with asynchronous termination.

In addition to the methods below, for each state value such
as `self.PENDING` there is a corresponding attribute `is_pending`
testing whether the `Result` is in that state.

*Method `Result.__init__(self, name=None, lock=None, result=None, state=None, extra=None)`*:
Base initialiser for `Result` objects and subclasses.

Parameter:
* `name`: optional parameter naming this object.
* `lock`: optional locking object, defaults to a new `threading.Lock`.
* `result`: if not `None`, prefill the `.result` property.
* `extra`: an optional mapping of extra information to
  associate with the `Result`, useful to provide context
  when collecting the result; the `Result` has a public
  attribute `.extra` which is an `AttrableMapping` to hold
  this information.

*Method `Result.__call__(self, *a, **kw)`*:
Call the `Result`: wait for it to be ready and then return or raise.

You can optionally supply a callable and arguments,
in which case `callable(*args,**kwargs)` will be called
via `Result.call` and the results applied to this `Result`.

Basic example:

    R = Result()
    ... hand R to something which will fulfil it later ...
    x = R() # wait for fulfilment - value lands in x

Direct call:

    R = Result()
    ... pass R to something which wants the result ...
    # call func(1,2,z=3), save result in R
    # ready for collection by whatever received R
    R(func,1,2,z=3)

*Method `Result.bg(self, func, *a, **kw)`*:
Submit a function to compute the result in a separate `Thread`,
returning the `Thread`.

Keyword arguments for `cs.threads.bg` may be supplied by
prefixing their names with an underscore, for example:

    T = R.bg(mainloop, _pre_enter_objects=(S, fs))

This dispatches a `Thread` to run `self.run_func(func,*a,**kw)`
and as such the `Result` must be in "pending" state,
and transitions to "running".

*Method `Result.cancel(self)`*:
Cancel this function.
If `self.fsm_state` is `PENDING`` or `'CANCELLED'`, return `True`.
Otherwise return `False` (too late to cancel).

*Property `Result.cancelled`*:
Test whether this `Result` has been cancelled.
Obsolete: use `.is_cancelled`.

*Method `Result.empty(self)`*:
Analogue to `Queue.empty()`.

*Property `Result.exc_info`*:
The exception information from a completed `Result`.
This is not available before completion.

*Method `Result.get(self, default=None)`*:
Wait for readiness; return the result if `self.exc_info` is `None`,
otherwise `default`.

*Method `Result.join(self)`*:
Calling the `.join()` method waits for the function to run to
completion and returns a tuple of `(result,exc_info)`.

On completion the sequence `(result,None)` is returned.
If an exception occurred computing the result the sequence
`(None,exc_info)` is returned
where `exc_info` is a tuple of `(exc_type,exc_value,exc_traceback)`.
If the function was cancelled the sequence `(None,None)`
is returned.

*Method `Result.notify(self, notifier: Callable[[ForwardRef('Result')], NoneType])`*:
After the `Result` completes, call `notifier(self)`.

If the `Result` has already completed this will happen immediately.
If you'd rather `self` got put on some queue `Q`, supply `Q.put`.

*Property `Result.pending`*:
Whether the `Result` is pending.
Obsolete: use `.is_pending`.

*Method `Result.post_notify(self, post_func) -> 'Result'`*:
Return a secondary `Result` which processes the result of `self`.

After the `self` completes, call `post_func(retval)` where
`retval` is the result of `self`, and use that to complete
the secondary `Result`.

Example:

    # submit packet to data stream
    R = submit_packet()
    # arrange that when the response is received, decode the response
    R2 = R.post_notify(lambda response: decode(response))
    # collect decoded response
    decoded = R2()

If the `Result` has already completed this will happen immediately.

*Method `Result.put(self, value)`*:
Store the value. `Queue`-like idiom.

*Method `Result.raise_(self, exc=None)`*:
Convenience wrapper for `self.exc_info` to store an exception result `exc`.
If `exc` is omitted or `None`, uses `sys.exc_info()`.

*Property `Result.ready`*:
True if the `Result` state is `DONE` or `CANCELLED`..

*Property `Result.result`*:
The result.
This property is not available before completion.

*Method `Result.run_func(self, func, *a, **kw)`*:
Fulfil the `Result` by running `func(*a,**kw)`.

*Method `Result.run_func_in_thread(self, func, *a, **kw)`*:
Fulfil the `Result` by running `func(*a,**kw)`
in a separate `Thread`.

This exists to step out of the current `Thread's` thread
local context, such as a database transaction associated
with Django's implicit per-`Thread` database context.

*Property `Result.state`*:
The `FSM` state (obsolete).
Obsolete: use `.fsm_state`.

## Class `ResultSet(builtins.set)`

A `set` subclass containing `Result`s,
on which one may iterate as `Result`s complete.

*Method `ResultSet.__iter__(self)`*:
Iterating on a `ResultSet` yields `Result`s as they complete.

*Method `ResultSet.wait(self)`*:
Convenience function to wait for all the `Result`s.

# Release Log



*Release 20240412*:
Result.bg: plumb _foo arguments to cs.threads.bg as foo.

*Release 20240316*:
Fixed release upload artifacts.

*Release 20240305*:
Result.__str__: handle early use where __dict__ lacks various entries.

*Release 20231221*:
Doc update.

*Release 20231129*:
Result.__del__: issue a warning about no collection instead of raising an exception.

*Release 20230331*:
Result.join: access self._result instead of the property.

*Release 20230212*:
* Result._complete: release self._get_lock before firing the event, as the event is what fires the notifiers.
* Result.notify: when we make a direct notifier call, call the notifier outside the lock and remember to set self.collected=True.
* Result: new post_notify() method to queue a function of the Result.result, returning a Result for the completion of the post function.

*Release 20221207*:
CancellationError: accept keyword arguments, apply as attributes.

*Release 20221118*:
* CancellationError: rename msg to message.
* Result.run_func_in_thread: new method to run an arbitrary function in a separate Thread and return it via the Result.
* New @in_thread decorator to cause a function to run in a separate Thread using Result.run_in_thread.
* New call_in_thread to run an arbitrary function in a distinct Thread.
* @in_thread: expose the original function as the decorated function's .direct attribute.

*Release 20220918*:
OnDemandResult: modern "pending" check.

*Release 20220805*:
Result now subclasses cs.fsm.FSM.

*Release 20220311*:
* Result: class local Seq instance.
* Result.call: thread safe runtime check of self.state==pending.
* New Task and @task decorator, prototype for rerunnable blocking chaining tasks scheme - very alpha.

*Release 20210420*:
Update dependencies, add docstring.

*Release 20210407*:
New ResultSet(set) class, with context manager and wait methods, and whose __iter__ iterates completed Results.

*Release 20210123*:
bg: accept optional _extra parameter for use by the Result.

*Release 20201102*:
Result: now .extra attribute for associated data and a new optional "extra" parameter in the initialiser.

*Release 20200521*:
* OnDemandResult: bugfixes and improvements.
* Result.bg: accept optional _name parameter to specify the Result.name.

*Release 20191007*:
* Simplify ResultState definition.
* Result.bg: use cs.threads.bg to dispatch the Thread.

*Release 20190522*:
* Result.__call__ now accepts an optional callable and args.
* Result.call: set the Result state to "running" before dispatching the function.
* Rename OnDemandFunction to OnDemandResult, keep old name around for compatibility.
* Result._complete: also permitted if state==cancelled.

*Release 20190309*:
Small bugfix.

*Release 20181231*:
* Result.call: report baser exceptions than BaseException.
* Drop _PendingFunction abstract class.

*Release 20181109.1*:
DISTINFO update.

*Release 20181109*:
* Derive CancellationError from Exception instead of RuntimeError, fix initialiser.
* Rename AsynchState to ResultState and make it an Enum.
* Make Results hashable and comparable for equality for use as mapping keys: equality is identity.
* New Result.collected attribute, set true if .result or .exc_info are accessed, logs an error if Result.__del__ is called when false, may be set true externally if a Result is not required.
* Drop `final` parameter; never used and supplanted by Result.notify.
* Result.join: return the .result and .exc_info properties in order to mark the Result as collected.
* Result: set .collected to True when a notifier has been called successfully.
* Bugfix Result.cancel: apply the new cancelled state.

*Release 20171231*:
* Bugfix Result.call to catch BaseException instead of Exception.
* New convenience function bg(func) to dispatch `func` in a separate Thread and return a Result to collect its value.

*Release 20171030.1*:
Fix module requirements specification.

*Release 20171030*:
New Result.bg(func, *a, **kw) method to dispatch function in separate Thread to compute the Result value.

*Release 20170903*:
rename cs.asynchron to cs.result


            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "cs.result",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "python2, python3",
    "author": null,
    "author_email": "Cameron Simpson <cs@cskk.id.au>",
    "download_url": "https://files.pythonhosted.org/packages/b0/9a/c509bf0c3e41bf51cf952377fb4b4d12bc2bd159ebc27ad51c71cc65ae0a/cs.result-20240412.tar.gz",
    "platform": null,
    "description": "Result and friends: various subclassable classes for deferred delivery of values.\n\n*Latest release 20240412*:\nResult.bg: plumb _foo arguments to cs.threads.bg as foo.\n\nA `Result` is the base class for several callable subclasses\nwhich will receive values at a later point in time,\nand can also be used standalone without subclassing.\n\nA call to a `Result` will block until the value is received or the `Result` is cancelled,\nwhich will raise an exception in the caller.\nA `Result` may be called by multiple users, before or after the value has been delivered;\nif the value has been delivered the caller returns with it immediately.\nA `Result`'s state may be inspected (pending, running, ready, cancelled).\nCallbacks can be registered via a `Result`'s .notify method.\n\nAn incomplete `Result` can be told to call a function to compute its value;\nthe function return will be stored as the value unless the function raises an exception,\nin which case the exception information is recorded instead.\nIf an exception occurred, it will be reraised for any caller of the `Result`.\n\nTrite example:\n\n    R = Result(name=\"my demo\")\n\nThread 1:\n\n    # this blocks until the Result is ready\n    value = R()\n    print(value)\n    # prints 3 once Thread 2 (below) assigns to it\n\nThread 2:\n\n    R.result = 3\n\nThread 3:\n\n    value = R()\n    # returns immediately with 3\n\nYou can also collect multiple `Result`s in completion order using the `report()` function:\n\n    Rs = [ ... list of Results of whatever type ... ]\n    ...\n    for R in report(Rs):\n        x = R()     # collect result, will return immediately because\n                    # the Result is complete\n        print(x)    # print result\n\n## Function `after(Rs, R, func, *a, **kw)`\n\nAfter the completion of `Rs` call `func(*a,**kw)` and return\nits result via `R`; return the `Result` object.\n\nParameters:\n* `Rs`: an iterable of Results.\n* `R`: a `Result` to collect to result of calling `func`.\n  If `None`, one will be created.\n* `func`, `a`, `kw`: a callable and its arguments.\n\n## Function `bg(func, *a, **kw)`\n\nDispatch a `Thread` to run `func`, return a `Result` to collect its value.\n\nParameters:\n* `_name`: optional name for the `Result`, passed to the initialiser\n* `_extra`: optional extra data for the `Result`, passed to the initialiser\n\nOther parameters are passed to `func`.\n\n## Function `call_in_thread(func, *a, **kw)`\n\nRun `func(*a,**kw)` in a separate `Thread` via the `@in_thread` decorator.\nReturn or exception is as for the original function.\n\n## Class `CancellationError(builtins.Exception)`\n\nRaised when accessing `result` or `exc_info` after cancellation.\n\n*Method `CancellationError.__init__(self, message=None, **kw)`*:\nInitialise the `CancellationError`.\n\nThe optional `message` parameter (default `\"cancelled\"`)\nis set as the `message` attribute.\nOther keyword parameters set their matching attributes.\n\n## Function `in_thread(func)`\n\nDecorator to evaluate `func` in a separate `Thread`.\nReturn or exception is as for the original function.\n\nThis exists to step out of the current `Thread's` thread\nlocal context, such as a database transaction associated\nwith Django's implicit per-`Thread` database context.\n\n## Class `OnDemandFunction(Result)`\n\nWrap a callable, run it when required.\n\n## Class `OnDemandResult(Result)`\n\nWrap a callable, run it when required.\n\n## Function `report(LFs)`\n\nGenerator which yields completed `Result`s.\n\nThis is a generator that yields `Result`s as they complete,\nuseful for waiting for a sequence of `Result`s\nthat may complete in an arbitrary order.\n\n## Class `Result(cs.fsm.FSM)`\n\nBase class for asynchronous collection of a result.\nThis is used to make `Result`, `OnDemandFunction`s, `LateFunction`s\nand other objects with asynchronous termination.\n\nIn addition to the methods below, for each state value such\nas `self.PENDING` there is a corresponding attribute `is_pending`\ntesting whether the `Result` is in that state.\n\n*Method `Result.__init__(self, name=None, lock=None, result=None, state=None, extra=None)`*:\nBase initialiser for `Result` objects and subclasses.\n\nParameter:\n* `name`: optional parameter naming this object.\n* `lock`: optional locking object, defaults to a new `threading.Lock`.\n* `result`: if not `None`, prefill the `.result` property.\n* `extra`: an optional mapping of extra information to\n  associate with the `Result`, useful to provide context\n  when collecting the result; the `Result` has a public\n  attribute `.extra` which is an `AttrableMapping` to hold\n  this information.\n\n*Method `Result.__call__(self, *a, **kw)`*:\nCall the `Result`: wait for it to be ready and then return or raise.\n\nYou can optionally supply a callable and arguments,\nin which case `callable(*args,**kwargs)` will be called\nvia `Result.call` and the results applied to this `Result`.\n\nBasic example:\n\n    R = Result()\n    ... hand R to something which will fulfil it later ...\n    x = R() # wait for fulfilment - value lands in x\n\nDirect call:\n\n    R = Result()\n    ... pass R to something which wants the result ...\n    # call func(1,2,z=3), save result in R\n    # ready for collection by whatever received R\n    R(func,1,2,z=3)\n\n*Method `Result.bg(self, func, *a, **kw)`*:\nSubmit a function to compute the result in a separate `Thread`,\nreturning the `Thread`.\n\nKeyword arguments for `cs.threads.bg` may be supplied by\nprefixing their names with an underscore, for example:\n\n    T = R.bg(mainloop, _pre_enter_objects=(S, fs))\n\nThis dispatches a `Thread` to run `self.run_func(func,*a,**kw)`\nand as such the `Result` must be in \"pending\" state,\nand transitions to \"running\".\n\n*Method `Result.cancel(self)`*:\nCancel this function.\nIf `self.fsm_state` is `PENDING`` or `'CANCELLED'`, return `True`.\nOtherwise return `False` (too late to cancel).\n\n*Property `Result.cancelled`*:\nTest whether this `Result` has been cancelled.\nObsolete: use `.is_cancelled`.\n\n*Method `Result.empty(self)`*:\nAnalogue to `Queue.empty()`.\n\n*Property `Result.exc_info`*:\nThe exception information from a completed `Result`.\nThis is not available before completion.\n\n*Method `Result.get(self, default=None)`*:\nWait for readiness; return the result if `self.exc_info` is `None`,\notherwise `default`.\n\n*Method `Result.join(self)`*:\nCalling the `.join()` method waits for the function to run to\ncompletion and returns a tuple of `(result,exc_info)`.\n\nOn completion the sequence `(result,None)` is returned.\nIf an exception occurred computing the result the sequence\n`(None,exc_info)` is returned\nwhere `exc_info` is a tuple of `(exc_type,exc_value,exc_traceback)`.\nIf the function was cancelled the sequence `(None,None)`\nis returned.\n\n*Method `Result.notify(self, notifier: Callable[[ForwardRef('Result')], NoneType])`*:\nAfter the `Result` completes, call `notifier(self)`.\n\nIf the `Result` has already completed this will happen immediately.\nIf you'd rather `self` got put on some queue `Q`, supply `Q.put`.\n\n*Property `Result.pending`*:\nWhether the `Result` is pending.\nObsolete: use `.is_pending`.\n\n*Method `Result.post_notify(self, post_func) -> 'Result'`*:\nReturn a secondary `Result` which processes the result of `self`.\n\nAfter the `self` completes, call `post_func(retval)` where\n`retval` is the result of `self`, and use that to complete\nthe secondary `Result`.\n\nExample:\n\n    # submit packet to data stream\n    R = submit_packet()\n    # arrange that when the response is received, decode the response\n    R2 = R.post_notify(lambda response: decode(response))\n    # collect decoded response\n    decoded = R2()\n\nIf the `Result` has already completed this will happen immediately.\n\n*Method `Result.put(self, value)`*:\nStore the value. `Queue`-like idiom.\n\n*Method `Result.raise_(self, exc=None)`*:\nConvenience wrapper for `self.exc_info` to store an exception result `exc`.\nIf `exc` is omitted or `None`, uses `sys.exc_info()`.\n\n*Property `Result.ready`*:\nTrue if the `Result` state is `DONE` or `CANCELLED`..\n\n*Property `Result.result`*:\nThe result.\nThis property is not available before completion.\n\n*Method `Result.run_func(self, func, *a, **kw)`*:\nFulfil the `Result` by running `func(*a,**kw)`.\n\n*Method `Result.run_func_in_thread(self, func, *a, **kw)`*:\nFulfil the `Result` by running `func(*a,**kw)`\nin a separate `Thread`.\n\nThis exists to step out of the current `Thread's` thread\nlocal context, such as a database transaction associated\nwith Django's implicit per-`Thread` database context.\n\n*Property `Result.state`*:\nThe `FSM` state (obsolete).\nObsolete: use `.fsm_state`.\n\n## Class `ResultSet(builtins.set)`\n\nA `set` subclass containing `Result`s,\non which one may iterate as `Result`s complete.\n\n*Method `ResultSet.__iter__(self)`*:\nIterating on a `ResultSet` yields `Result`s as they complete.\n\n*Method `ResultSet.wait(self)`*:\nConvenience function to wait for all the `Result`s.\n\n# Release Log\n\n\n\n*Release 20240412*:\nResult.bg: plumb _foo arguments to cs.threads.bg as foo.\n\n*Release 20240316*:\nFixed release upload artifacts.\n\n*Release 20240305*:\nResult.__str__: handle early use where __dict__ lacks various entries.\n\n*Release 20231221*:\nDoc update.\n\n*Release 20231129*:\nResult.__del__: issue a warning about no collection instead of raising an exception.\n\n*Release 20230331*:\nResult.join: access self._result instead of the property.\n\n*Release 20230212*:\n* Result._complete: release self._get_lock before firing the event, as the event is what fires the notifiers.\n* Result.notify: when we make a direct notifier call, call the notifier outside the lock and remember to set self.collected=True.\n* Result: new post_notify() method to queue a function of the Result.result, returning a Result for the completion of the post function.\n\n*Release 20221207*:\nCancellationError: accept keyword arguments, apply as attributes.\n\n*Release 20221118*:\n* CancellationError: rename msg to message.\n* Result.run_func_in_thread: new method to run an arbitrary function in a separate Thread and return it via the Result.\n* New @in_thread decorator to cause a function to run in a separate Thread using Result.run_in_thread.\n* New call_in_thread to run an arbitrary function in a distinct Thread.\n* @in_thread: expose the original function as the decorated function's .direct attribute.\n\n*Release 20220918*:\nOnDemandResult: modern \"pending\" check.\n\n*Release 20220805*:\nResult now subclasses cs.fsm.FSM.\n\n*Release 20220311*:\n* Result: class local Seq instance.\n* Result.call: thread safe runtime check of self.state==pending.\n* New Task and @task decorator, prototype for rerunnable blocking chaining tasks scheme - very alpha.\n\n*Release 20210420*:\nUpdate dependencies, add docstring.\n\n*Release 20210407*:\nNew ResultSet(set) class, with context manager and wait methods, and whose __iter__ iterates completed Results.\n\n*Release 20210123*:\nbg: accept optional _extra parameter for use by the Result.\n\n*Release 20201102*:\nResult: now .extra attribute for associated data and a new optional \"extra\" parameter in the initialiser.\n\n*Release 20200521*:\n* OnDemandResult: bugfixes and improvements.\n* Result.bg: accept optional _name parameter to specify the Result.name.\n\n*Release 20191007*:\n* Simplify ResultState definition.\n* Result.bg: use cs.threads.bg to dispatch the Thread.\n\n*Release 20190522*:\n* Result.__call__ now accepts an optional callable and args.\n* Result.call: set the Result state to \"running\" before dispatching the function.\n* Rename OnDemandFunction to OnDemandResult, keep old name around for compatibility.\n* Result._complete: also permitted if state==cancelled.\n\n*Release 20190309*:\nSmall bugfix.\n\n*Release 20181231*:\n* Result.call: report baser exceptions than BaseException.\n* Drop _PendingFunction abstract class.\n\n*Release 20181109.1*:\nDISTINFO update.\n\n*Release 20181109*:\n* Derive CancellationError from Exception instead of RuntimeError, fix initialiser.\n* Rename AsynchState to ResultState and make it an Enum.\n* Make Results hashable and comparable for equality for use as mapping keys: equality is identity.\n* New Result.collected attribute, set true if .result or .exc_info are accessed, logs an error if Result.__del__ is called when false, may be set true externally if a Result is not required.\n* Drop `final` parameter; never used and supplanted by Result.notify.\n* Result.join: return the .result and .exc_info properties in order to mark the Result as collected.\n* Result: set .collected to True when a notifier has been called successfully.\n* Bugfix Result.cancel: apply the new cancelled state.\n\n*Release 20171231*:\n* Bugfix Result.call to catch BaseException instead of Exception.\n* New convenience function bg(func) to dispatch `func` in a separate Thread and return a Result to collect its value.\n\n*Release 20171030.1*:\nFix module requirements specification.\n\n*Release 20171030*:\nNew Result.bg(func, *a, **kw) method to dispatch function in separate Thread to compute the Result value.\n\n*Release 20170903*:\nrename cs.asynchron to cs.result\n\n",
    "bugtrack_url": null,
    "license": "GNU General Public License v3 or later (GPLv3+)",
    "summary": "Result and friends: various subclassable classes for deferred delivery of values.",
    "version": "20240412",
    "project_urls": {
        "URL": "https://bitbucket.org/cameron_simpson/css/commits/all"
    },
    "split_keywords": [
        "python2",
        " python3"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "11893b606facd42184cf0c4470057eedc5a60e721ebd261d235e5c05d1f4bbf0",
                "md5": "7a66b20cad3ddb37d73fc2cde072ea4f",
                "sha256": "7619541d6d770fad9abc4135de65080d02e308d67010c009403058f087346917"
            },
            "downloads": -1,
            "filename": "cs.result-20240412-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "7a66b20cad3ddb37d73fc2cde072ea4f",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 12239,
            "upload_time": "2024-04-12T04:38:15",
            "upload_time_iso_8601": "2024-04-12T04:38:15.057467Z",
            "url": "https://files.pythonhosted.org/packages/11/89/3b606facd42184cf0c4470057eedc5a60e721ebd261d235e5c05d1f4bbf0/cs.result-20240412-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "b09ac509bf0c3e41bf51cf952377fb4b4d12bc2bd159ebc27ad51c71cc65ae0a",
                "md5": "1146e46bed1d2332765fca1d5787083b",
                "sha256": "a10cd14329b89f7e46a7be3872efc8095099d79fb6b1ee52d2e3ea1d29c0b391"
            },
            "downloads": -1,
            "filename": "cs.result-20240412.tar.gz",
            "has_sig": false,
            "md5_digest": "1146e46bed1d2332765fca1d5787083b",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 13189,
            "upload_time": "2024-04-12T04:38:17",
            "upload_time_iso_8601": "2024-04-12T04:38:17.147139Z",
            "url": "https://files.pythonhosted.org/packages/b0/9a/c509bf0c3e41bf51cf952377fb4b4d12bc2bd159ebc27ad51c71cc65ae0a/cs.result-20240412.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-04-12 04:38:17",
    "github": false,
    "gitlab": false,
    "bitbucket": true,
    "codeberg": false,
    "bitbucket_user": "cameron_simpson",
    "bitbucket_project": "css",
    "lcname": "cs.result"
}
        
Elapsed time: 0.23560s