bpo-30508: Don't log exceptions if Task/Future "cancel()" method was called. (#2109)

diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
index 75327fa..492b983 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -305,6 +305,8 @@
 static PyObject *
 future_cancel(FutureObj *fut)
 {
+    fut->fut_log_tb = 0;
+
     if (fut->fut_state != STATE_PENDING) {
         Py_RETURN_FALSE;
     }
@@ -638,6 +640,17 @@
     }
 }
 
+static int
+FutureObj_set_log_traceback(FutureObj *fut, PyObject *val)
+{
+    int is_true = PyObject_IsTrue(val);
+    if (is_true < 0) {
+        return -1;
+    }
+    fut->fut_log_tb = is_true;
+    return 0;
+}
+
 static PyObject *
 FutureObj_get_loop(FutureObj *fut)
 {
@@ -882,7 +895,8 @@
     {"_callbacks", (getter)FutureObj_get_callbacks, NULL, NULL},              \
     {"_result", (getter)FutureObj_get_result, NULL, NULL},                    \
     {"_exception", (getter)FutureObj_get_exception, NULL, NULL},              \
-    {"_log_traceback", (getter)FutureObj_get_log_traceback, NULL, NULL},      \
+    {"_log_traceback", (getter)FutureObj_get_log_traceback,                   \
+                       (setter)FutureObj_set_log_traceback, NULL},            \
     {"_source_traceback", (getter)FutureObj_get_source_traceback, NULL, NULL},
 
 static PyGetSetDef FutureType_getsetlist[] = {
@@ -1568,6 +1582,8 @@
 _asyncio_Task_cancel_impl(TaskObj *self)
 /*[clinic end generated code: output=6bfc0479da9d5757 input=13f9bf496695cb52]*/
 {
+    self->task_log_tb = 0;
+
     if (self->task_state != STATE_PENDING) {
         Py_RETURN_FALSE;
     }