ec.c (ecptxl_1): Accept any iterable of coordinates.
[catacomb-python] / ec.c
diff --git a/ec.c b/ec.c
index 2ab20a6..40d73e7 100644 (file)
--- a/ec.c
+++ b/ec.c
@@ -513,9 +513,8 @@ end:
 static int ecptxl_1(ec_curve *c, ec *p, PyObject *x)
 {
   int rc = -1;
-  PyObject *y = 0, *z = 0, *t = 0;
+  PyObject *y = 0, *z = 0, *t = 0, *u = 0;
   mp *xx = 0;
-  Py_ssize_t n;
   qd_parse qd;
   int paren;
 
@@ -536,27 +535,33 @@ static int ecptxl_1(ec_curve *c, ec *p, PyObject *x)
   } else if (c && (xx = tomp(x)) != 0) {
     xx = F_IN(c->f, xx, xx);
     if (!EC_FIND(c, p, xx)) VALERR("not on the curve");
-  } else if (PySequence_Check(x)) {
-    t = x; x = 0;
-    n = PySequence_Size(t); if (n < 0) goto end;
-    if (n != 2 && n != 3)
-      TYERR("want sequence of two or three items");
-    if ((x = PySequence_GetItem(t, 0)) == 0 ||
-       (y = PySequence_GetItem(t, 1)) == 0 ||
-       (n == 3 && (z = PySequence_GetItem(t, 2)) == 0))
-      goto end;
-    rc = (n == 2) ? ecptxl_2(c, p, x, y) : ecptxl_3(c, p, x, y, z);
+  } else if ((t = PyObject_GetIter(x)) != 0) {
+    Py_DECREF(x);
+    x = PyIter_Next(t); if (!x) goto enditer;
+    y = PyIter_Next(t); if (!y) goto enditer;
+    z = PyIter_Next(t); if (!z && PyErr_Occurred()) goto end;
+    if (z) {
+      u = PyIter_Next(t);
+      if (u) goto enditer;
+      else if (PyErr_Occurred()) goto end;
+    }
+    rc = !z ? ecptxl_2(c, p, x, y) : ecptxl_3(c, p, x, y, z);
     goto end;
-  } else
+  } else {
+    PyErr_Clear();
     TYERR("can't convert to curve point");
+  }
   goto ok;
 
+enditer:
+  if (PyErr_Occurred()) goto end;
+  TYERR("expected sequence of 2 or 3 items");
 fix:
   if (c) EC_IN(c, p, p);
 ok:
   rc = 0;
 end:
-  Py_XDECREF(x); Py_XDECREF(y); Py_XDECREF(z); Py_XDECREF(t);
+  Py_XDECREF(x); Py_XDECREF(y); Py_XDECREF(z); Py_XDECREF(t); Py_XDECREF(u);
   mp_drop(xx);
   return (rc);
 }