New submission from Kyle Stanley <aeros...@gmail.com>:

Based on the following python-ideas thread: 
https://mail.python.org/archives/list/python-id...@python.org/thread/LMTQ2AI6A7UXEFVHRGHKWD33H24FGM6G/#ICJKHZ4BPIUMOPIT2TDTBIW2EH4CPNCP.

In the above ML thread, the author proposed adding a new cf.SerialExecutor 
class, which seems to be not a great fit for the standard library (based on the 
current state of the discussion, as of writing this). But, Guido mentioned the 
following:

> IOW I'm rather lukewarm about this -- even if you (Jonathan) have found use 
> for it, I'm not sure how many other people would use it, so I doubt it's 
> worth adding it to the stdlib. (The only thing the stdlib might grow could be 
> a public API that makes implementing this feasible without overriding private 
> methods.)

Specifically, the OPs proposal should be reasonably possible to implement 
(either just locally for themselves or a potential PyPI package) with a few 
minor additions to cf.Future's public API:

1) Add a means of *publicly* accessing the future's state (future._state) 
without going through the internal condition's RLock.

This would allow the developer to implement their own condition or other 
synchronization primitive to access the state of the future. IMO, this would 
best be implemented as a separate ``future.state()`` and 
``future.set_state()``. 

2) Add a means of *publicly* accessing the future's result (future._result) 
without going through the internal condition's RLock.

This would be similar to the above, but since there's already a 
``future.result()`` and ``future.set_result()``, I think it would be best 
implemented as an optional *sync* parameter that defaults to True. When set to 
False, it directly accesses future._result without the condition; when set to 
True, it has the current behavior. 

3) Add public global constants for the different possible future states: 
PENDING, RUNNING, CANCELLED, CANCELLED_AND_NOTIFIED, and FINISHED. 

This would be useful to serve as a template of possible future states for 
custom implementations. I also find that ``fut.set_state(cf.RUNNING)`` looks 
better than ``fut.state("running")`` from an API design perspective. 

Optional addition: To make ``fut.state()`` and ``fut.set_state()`` more useful 
for general purposes, it could have a single *sync* boolean parameter (feel 
free to bikeshed over the name), which changes whether it directly accesses 
future._state or does so safely through the condition. Presumably, the 
documentation would explicitly state that with sync=False, the future's state 
will not be synchronized across separate threads or processes. This would also 
allow it to have the same API as ``future.result()`` and 
``future.set_result()``.

Also, as for my own personal motivation in expanding upon the public API for 
cf.Future, I've found that directly accessing the state of the future can be 
incredibly useful for debugging purposes. I made significant use of it while 
implementing the new *cancel_futures* parameter for executor.shutdown(). But, 
since future._state is a private member, there's no guarantee that it will 
continue to behave the same or that it can be relied upon in the long-term. 
This may not be a huge concern for quick debugging sessions, but could easily 
result in breakage when used in logging or unit tests.

----------
assignee: aeros
components: Library (Lib)
messages: 362047
nosy: aeros, bquinlan, gvanrossum, pitrou
priority: normal
severity: normal
status: open
title: Expand concurrent.futures.Future's public API
type: enhancement
versions: Python 3.9

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue39645>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to