I think it's too late to change the cancellation logic. Cancellation is tricky. On Sun, Dec 3, 2017 at 1:53 PM, Chris Jerdonek <chris.jerdonek@gmail.com> wrote:
On Sun, Dec 3, 2017 at 9:04 AM, Guido van Rossum <guido@python.org> wrote:
Sounds like an implementation issue. The Future class has a boolean flag indicating whether it's been cancelled, and everything then raises CancelledError when that flag is set. I suppose we could replace that flag with an instance of CancelledError, and when we *catch* CancelledError we set it to that. But it seems messy and I'm not sure that you should attempt this. IMO you should define an exception that does *not* derive from CancelledError and raise that -- it will properly be transmitted. What's your reason for not doing that? IOW why are you trying to pump more than a bit through the narrow "cancelled" channel?
My use case is mostly for diagnostic / logging purposes. I want to log all exceptions bubbling out of a task, and I want to do so from within the coroutine itself rather than when I call task.result(). I also want to be able to detect if something wasn't logged when I call task.result() (to avoid double logging and errors passing silently, etc), and I'd also prefer that task.cancelled(), etc. still return the correct values.
My first idea was to define LoggedError(Exception) and LoggedCancelledError(CancelledError) subclasses, and raise a new exception from within the task after logging. If LoggedCancelledError doesn't derive from CancelledError, then task.cancelled() won't reflect that the task was cancelled.
Could it simplify things on the asyncio side if the CancelledError and non-CancelledError code paths shared more logic (e.g. by both setting an exception instead of only the generic case setting an exception)?
--Chris
On Sun, Dec 3, 2017 at 2:11 AM, Andrew Svetlov <andrew.svetlov@gmail.com
wrote:
IIRC at very early stages Guido van Rossum decided to *freeze* `CancelledError`: user code should not derive from the exception. Like
you
never derive from StopIteration.
On Sun, Dec 3, 2017 at 8:00 AM Chris Jerdonek <chris.jerdonek@gmail.com
wrote:
Hi, I want to ask how people feel about the following.
If you raise a subclass of CancelledError from within a task and then call task.result(), CancelledError is raised rather than the subclass.
Here is some code to illustrate:
class MyCancelledError(CancelledError): pass
async def raise_my_cancel(): raise MyCancelledError()
task = asyncio.ensure_future(raise_my_cancel()) try: await task except Exception: pass assert task.cancelled() # Raises CancelledError and not MyCancelledError. task.result()
Does this seem right to people? Is there a justification for this?
If it would help for the discussion, I could provide a use case.
Thanks a lot, --Chris _______________________________________________ Async-sig mailing list Async-sig@python.org https://mail.python.org/mailman/listinfo/async-sig Code of Conduct: https://www.python.org/psf/codeofconduct/
-- Thanks, Andrew Svetlov
_______________________________________________ Async-sig mailing list Async-sig@python.org https://mail.python.org/mailman/listinfo/async-sig Code of Conduct: https://www.python.org/psf/codeofconduct/
-- --Guido van Rossum (python.org/~guido)
-- --Guido van Rossum (python.org/~guido)