diff --git a/src/core/surface/server.c b/src/core/surface/server.c
index f9172d9850ca9d23574c5113c93bd56ae6c7246a..d0974c04cfabb21274273671abfba69676bd7672 100644
--- a/src/core/surface/server.c
+++ b/src/core/surface/server.c
@@ -979,7 +979,7 @@ void grpc_server_destroy(grpc_server *server) {
   call_data *calld;
 
   gpr_mu_lock(&server->mu);
-  GPR_ASSERT(server->shutdown);
+  GPR_ASSERT(server->shutdown || !server->listeners);
   GPR_ASSERT(server->listeners_destroyed == num_listeners(server));
 
   while (server->listeners) {
diff --git a/src/python/src/grpc/_adapter/_c/types/server.c b/src/python/src/grpc/_adapter/_c/types/server.c
index 65d84b58fe8e3539f39f2124d2dfbaf6755fa26e..26b38da8f1a0e08d9d78e4dd6d9fa9b59ae7d69a 100644
--- a/src/python/src/grpc/_adapter/_c/types/server.c
+++ b/src/python/src/grpc/_adapter/_c/types/server.c
@@ -167,17 +167,13 @@ PyObject *pygrpc_Server_start(Server *self, PyObject *ignored) {
 
 PyObject *pygrpc_Server_shutdown(
     Server *self, PyObject *args, PyObject *kwargs) {
-  PyObject *user_tag = NULL;
+  PyObject *user_tag;
   pygrpc_tag *tag;
   static char *keywords[] = {"tag", NULL};
-  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", keywords, &user_tag)) {
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", keywords, &user_tag)) {
     return NULL;
   }
-  if (user_tag) {
-    tag = pygrpc_produce_server_shutdown_tag(user_tag);
-    grpc_server_shutdown_and_notify(self->c_serv, tag);
-  } else {
-    grpc_server_shutdown(self->c_serv);
-  }
+  tag = pygrpc_produce_server_shutdown_tag(user_tag);
+  grpc_server_shutdown_and_notify(self->c_serv, self->cq->c_cq, tag);
   Py_RETURN_NONE;
 }
diff --git a/src/python/src/grpc/_adapter/_c/utility.c b/src/python/src/grpc/_adapter/_c/utility.c
index 6722b53f840e3e5f50c6e5d41c118f4200502294..6ad3955986c3f2ef0218d4708440607f2ef87d78 100644
--- a/src/python/src/grpc/_adapter/_c/utility.c
+++ b/src/python/src/grpc/_adapter/_c/utility.c
@@ -40,6 +40,7 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/slice.h>
 #include <grpc/support/time.h>
+#include <grpc/support/log.h>
 
 #include "grpc/_adapter/_c/types.h"
 
@@ -122,7 +123,8 @@ PyObject *pygrpc_consume_event(grpc_event event) {
           event.success ? Py_True : Py_False);
     } else {
       result = Py_BuildValue("iOOONO", GRPC_OP_COMPLETE, tag->user_tag,
-          tag->call, Py_None, pygrpc_consume_ops(tag->ops, tag->nops),
+          tag->call ? tag->call : Py_None, Py_None,
+          pygrpc_consume_ops(tag->ops, tag->nops),
           event.success ? Py_True : Py_False);
     }
     break;
diff --git a/src/python/src/grpc/_adapter/_intermediary_low.py b/src/python/src/grpc/_adapter/_intermediary_low.py
index a6e325c4e5b63e62b029ea53c8b50057647cd6ba..6b96aef1d34e0a99c309b50dc17bfd98060b1645 100644
--- a/src/python/src/grpc/_adapter/_intermediary_low.py
+++ b/src/python/src/grpc/_adapter/_intermediary_low.py
@@ -100,7 +100,7 @@ class _TagAdapter(collections.namedtuple('_TagAdapter', [
 
 class Call(object):
   """Adapter from old _low.Call interface to new _low.Call."""
-  
+
   def __init__(self, channel, completion_queue, method, host, deadline):
     self._internal = channel._internal.create_call(
         completion_queue._internal, method, host, deadline)
@@ -207,7 +207,7 @@ class CompletionQueue(object):
       complete_accepted = ev.success if kind == Event.Kind.COMPLETE_ACCEPTED else None
       service_acceptance = ServiceAcceptance(Call._from_internal(ev.call), ev.call_details.method, ev.call_details.host, ev.call_details.deadline) if kind == Event.Kind.SERVICE_ACCEPTED else None
       message_bytes = ev.results[0].message if kind == Event.Kind.READ_ACCEPTED else None
-      status = Status(ev.results[0].status.code, ev.results[0].status.details) if (kind == Event.Kind.FINISH and ev.results[0].status) else Status(_types.StatusCode.CANCELLED if ev.results[0].cancelled else _types.StatusCode.OK, '') if ev.results[0].cancelled is not None else None
+      status = Status(ev.results[0].status.code, ev.results[0].status.details) if (kind == Event.Kind.FINISH and ev.results[0].status) else Status(_types.StatusCode.CANCELLED if ev.results[0].cancelled else _types.StatusCode.OK, '') if len(ev.results) > 0 and ev.results[0].cancelled is not None else None
       metadata = ev.results[0].initial_metadata if (kind in [Event.Kind.SERVICE_ACCEPTED, Event.Kind.METADATA_ACCEPTED]) else (ev.results[0].trailing_metadata if kind == Event.Kind.FINISH else None)
     else:
       raise RuntimeError('unknown event')
@@ -241,7 +241,7 @@ class Server(object):
     return self._internal.request_call(self._internal_cq, _TagAdapter(tag, Event.Kind.SERVICE_ACCEPTED))
 
   def stop(self):
-    return self._internal.shutdown()
+    return self._internal.shutdown(_TagAdapter(None, Event.Kind.STOP))
 
 
 class ClientCredentials(object):
@@ -253,6 +253,6 @@ class ClientCredentials(object):
 
 class ServerCredentials(object):
   """Adapter from old _low.ServerCredentials interface to new _low.ServerCredentials."""
-  
+
   def __init__(self, root_credentials, pair_sequence):
     self._internal = _low.ServerCredentials.ssl(root_credentials, list(pair_sequence))
diff --git a/src/python/src/grpc/_adapter/_intermediary_low_test.py b/src/python/src/grpc/_adapter/_intermediary_low_test.py
index 6ff51c43a69ae02ade3de7c6aac228beef6fed65..478346341b08d62a70dffb82bea474f037bcf249 100644
--- a/src/python/src/grpc/_adapter/_intermediary_low_test.py
+++ b/src/python/src/grpc/_adapter/_intermediary_low_test.py
@@ -94,14 +94,6 @@ class EchoTest(unittest.TestCase):
 
   def tearDown(self):
     self.server.stop()
-    # NOTE(nathaniel): Yep, this is weird; it's a consequence of
-    # grpc_server_destroy's being what has the effect of telling the server's
-    # completion queue to pump out all pending events/tags immediately rather
-    # than gracefully completing all outstanding RPCs while accepting no new
-    # ones.
-    # TODO(nathaniel): Deallocation of a Python object shouldn't have this kind
-    # of observable side effect let alone such an important one.
-    del self.server
     self.server_completion_queue.stop()
     self.client_completion_queue.stop()
     while True:
@@ -114,6 +106,7 @@ class EchoTest(unittest.TestCase):
         break
     self.server_completion_queue = None
     self.client_completion_queue = None
+    del self.server
 
   def _perform_echo_test(self, test_data):
     method = 'test method'
@@ -316,7 +309,6 @@ class CancellationTest(unittest.TestCase):
 
   def tearDown(self):
     self.server.stop()
-    del self.server
     self.server_completion_queue.stop()
     self.client_completion_queue.stop()
     while True:
@@ -327,6 +319,7 @@ class CancellationTest(unittest.TestCase):
       event = self.client_completion_queue.get(0)
       if event is not None and event.kind is _low.Event.Kind.STOP:
         break
+    del self.server
 
   def testCancellation(self):
     method = 'test method'
diff --git a/src/python/src/grpc/_adapter/_low.py b/src/python/src/grpc/_adapter/_low.py
index 0c1d3b40a5b2df1f8e8f6c8e36e59bde0849b2c8..dcf67dbc11732f5abc9dd7ea31b14ccc042b6ed2 100644
--- a/src/python/src/grpc/_adapter/_low.py
+++ b/src/python/src/grpc/_adapter/_low.py
@@ -101,11 +101,8 @@ class Server(_types.Server):
   def start(self):
     return self.server.start()
 
-  def shutdown(self, tag=_NO_TAG):
-    if tag is _NO_TAG:
-      return self.server.shutdown()
-    else:
-      return self.server.shutdown(tag)
+  def shutdown(self, tag=None):
+    return self.server.shutdown(tag)
 
   def request_call(self, completion_queue, tag):
     return self.server.request_call(completion_queue.completion_queue, tag)
diff --git a/src/python/src/grpc/_adapter/_low_test.py b/src/python/src/grpc/_adapter/_low_test.py
index e53b176caf95562d69379a128cd4a74c0a082d11..8a9f1a0c4983e4bc0c6e985db69802c282cb3b87 100644
--- a/src/python/src/grpc/_adapter/_low_test.py
+++ b/src/python/src/grpc/_adapter/_low_test.py
@@ -48,7 +48,6 @@ class InsecureServerInsecureClient(unittest.TestCase):
   def tearDown(self):
     self.server.shutdown()
     del self.client_channel
-    del self.server
 
     self.client_completion_queue.shutdown()
     while self.client_completion_queue.next().type != _types.EventType.QUEUE_SHUTDOWN:
@@ -59,6 +58,7 @@ class InsecureServerInsecureClient(unittest.TestCase):
 
     del self.client_completion_queue
     del self.server_completion_queue
+    del self.server
 
   def testEcho(self):
     DEADLINE = time.time()+5