Added tests for slice deletion and fixed bugs.
diff --git a/python/minimal_test.py b/python/minimal_test.py
index 32b8333..0c73a4b 100644
--- a/python/minimal_test.py
+++ b/python/minimal_test.py
@@ -30,6 +30,7 @@
 import unittest
 from google.protobuf.pyext import _message
 from google.protobuf.internal import api_implementation
+from google.protobuf import unittest_pb2
 
 class TestMessageExtension(unittest.TestCase):
 
@@ -53,6 +54,21 @@
         self.assertTrue(_message._IS_UPB)
         self.assertEqual(api_implementation.Type(), "cpp")
 
+    def test_repeated_field_slice_delete(self):
+        def test_slice(start, end, step):
+            vals = list(range(20))
+            message = unittest_pb2.TestAllTypes(repeated_int32=vals)
+            del vals[start:end:step]
+            del message.repeated_int32[start:end:step]
+            self.assertEqual(vals, list(message.repeated_int32))
+        test_slice(3, 11, 1)
+        test_slice(3, 11, 2)
+        test_slice(3, 11, 3)
+        test_slice(11, 3, -1)
+        test_slice(11, 3, -2)
+        test_slice(11, 3, -3)
+        test_slice(10, 25, 4)
+
 #TestMessageExtension.test_descriptor_pool.__unittest_expecting_failure__ = True
 
 
diff --git a/python/repeated.c b/python/repeated.c
index 6e96ccf..7d797f2 100644
--- a/python/repeated.c
+++ b/python/repeated.c
@@ -79,8 +79,8 @@
   //   - low bit clear: repeated field is reified (points to upb_array).
   uintptr_t field;
   union {
-    upb_array* arr;    // stub: the data for this array.
-    PyObject* parent;  // reified: owning pointer to parent message.
+    PyObject* parent;  // stub: owning pointer to parent message.
+    upb_array* arr;    // reified: the data for this array.
   } ptr;
 } PyUpb_RepeatedContainer;
 
@@ -371,19 +371,31 @@
     start = end;
     step = -step;
   }
+
   size_t dst = start;
-  size_t src = step > 1 ? start + 1 : start + count;
+  size_t src;
   if (step > 1) {
-    // Move elements between steps.
-    for (Py_ssize_t i = 0; i < count; i++, dst += step, src += step + 1) {
+    // Move elements between steps:
+    //
+    //        src
+    //         |
+    // |------X---X---X---X------------------------------|
+    //        |
+    //       dst           <-------- tail -------------->
+    src = start + 1;
+    for (Py_ssize_t i = 1; i < count; i++, dst += step - 1, src += step) {
       upb_array_move(arr, dst, src, step);
     }
+  } else {
+    src = start + count;
   }
+
   // Move tail.
   size_t tail = upb_array_size(arr) - src;
-  assert(dst + tail == upb_array_size(arr) - count);
-  upb_array_move(arr, dst, src, upb_array_size(arr) - src);
-  upb_array_resize(arr, dst + tail, NULL);
+  size_t new_size = dst + tail;
+  assert(new_size == upb_array_size(arr) - count);
+  upb_array_move(arr, dst, src, tail);
+  upb_array_resize(arr, new_size, NULL);
   return 0;
 }