Added repeated fields.
diff --git a/python/message.c b/python/message.c
index 728b116..3012b0a 100644
--- a/python/message.c
+++ b/python/message.c
@@ -29,6 +29,7 @@
 
 #include "python/convert.h"
 #include "python/descriptor.h"
+#include "python/repeated.h"
 #include "upb/def.h"
 #include "upb/reflection.h"
 #include "upb/text_encode.h"
@@ -332,14 +333,14 @@
   return ok >= 0;
 }
 
-static bool PyUpb_CMessage_InitRepeatedAttribute() {
-  // TODO(haberman): disabled until repeated container is in.
-  // PyObject* repeated = PyUpb_CMessage_GetAttr(_self, name);
-  // PyObject* tmp = PyUpb_RepeatedContainer_Extend(repeated, value);
-  // if (!tmp) return -1;
-  // Py_DECREF(tmp);
-  PyErr_SetString(PyExc_NotImplementedError, "repeated init");
-  return false;
+static bool PyUpb_CMessage_InitRepeatedAttribute(PyObject* _self,
+                                                 PyObject* name,
+                                                 PyObject* value) {
+  PyObject* repeated = PyUpb_CMessage_GetAttr(_self, name);
+  PyObject* tmp = PyUpb_RepeatedContainer_Extend(repeated, value);
+  if (!tmp) return false;
+  Py_DECREF(tmp);
+  return true;
 }
 
 static bool PyUpb_CMessage_InitMessageAttribute(PyObject* _self, PyObject* name,
@@ -410,7 +411,7 @@
     if (upb_fielddef_ismap(f)) {
       if (!PyUpb_CMessage_InitMapAttribute(_self, name, f, value)) return -1;
     } else if (upb_fielddef_isseq(f)) {
-      if (!PyUpb_CMessage_InitRepeatedAttribute()) return -1;
+      if (!PyUpb_CMessage_InitRepeatedAttribute(_self, name, value)) return -1;
     } else if (upb_fielddef_issubmsg(f)) {
       if (!PyUpb_CMessage_InitMessageAttribute(_self, name, value)) return -1;
     } else {
@@ -598,8 +599,7 @@
       // PyUpb_MapContainer_SwitchToSet(obj, (upb_map*)msgval.map_val);
     } else if (upb_fielddef_isseq(f)) {
       if (!msgval.array_val) continue;
-      // TODO(haberman): re-enable when repeated fields are checked in.
-      // PyUpb_RepeatedContainer_SwitchToSet(obj, (upb_array*)msgval.array_val);
+      PyUpb_RepeatedContainer_SwitchToSet(obj, (upb_array*)msgval.array_val);
     } else {
       PyUpb_CMessage* sub = (void*)obj;
       assert(self == sub->ptr.parent);
@@ -715,6 +715,7 @@
 
 PyObject* PyUpb_CMessage_GetUnsetWrapper(PyUpb_CMessage* self,
                                          const upb_fielddef* field) {
+  PyObject* _self = (void*)self;
   // Non-present messages return magical "empty" messages that point to their
   // parent, but will materialize into real messages if any fields are
   // assigned.
@@ -731,10 +732,7 @@
     PyErr_SetString(PyExc_NotImplementedError, "unset map");
     return NULL;
   } else if (upb_fielddef_isseq(field)) {
-    // TODO(haberman): re-enable when repeated fields are checked in.
-    // subobj = PyUpb_RepeatedContainer_NewUnset(_self, field, self->arena);
-    PyErr_SetString(PyExc_NotImplementedError, "unset repeated");
-    return NULL;
+    subobj = PyUpb_RepeatedContainer_NewUnset(_self, field, self->arena);
   } else {
     subobj = PyUpb_CMessage_NewUnset(&self->ob_base, field, self->arena);
   }
@@ -757,11 +755,8 @@
     PyErr_SetString(PyExc_NotImplementedError, "access map");
     return NULL;
   } else {
-    // TODO(haberman): re-enable when repeated fields are checked in.
-    // return PyUpb_RepeatedContainer_GetOrCreateWrapper(mutval.array, _self,
-    //                                                   field, self->arena);
-    PyErr_SetString(PyExc_NotImplementedError, "access repeated");
-    return NULL;
+    return PyUpb_RepeatedContainer_GetOrCreateWrapper(mutval.array, field,
+                                                      self->arena);
   }
 }