chiark / gitweb /
algorithms.c: Add missing `copy' methods on hash and Keccak objects.
[catacomb-python] / algorithms.c
index 7eab3ae4571c9cb1fe543b7a591621808d9b4180..50ae06859541304b3340b6f554f969b74e570667 100644 (file)
@@ -83,11 +83,11 @@ PyObject *keysz_pywrap(const octet *k)
 static PyObject *keyszany_pynew(PyTypeObject *ty,
                                PyObject *arg, PyObject *kw)
 {
 static PyObject *keyszany_pynew(PyTypeObject *ty,
                                PyObject *arg, PyObject *kw)
 {
-  char *kwlist[] = { "default", 0 };
+  static const char *const kwlist[] = { "default", 0 };
   int dfl;
   keysz_pyobj *o;
 
   int dfl;
   keysz_pyobj *o;
 
-  if (!PyArg_ParseTupleAndKeywords(arg, kw, "i:new", kwlist, &dfl))
+  if (!PyArg_ParseTupleAndKeywords(arg, kw, "i:new", KWLIST, &dfl))
     goto end;
   if (dfl < 0) VALERR("key size cannot be negative");
   o = (keysz_pyobj *)ty->tp_alloc(ty, 0);
     goto end;
   if (dfl < 0) VALERR("key size cannot be negative");
   o = (keysz_pyobj *)ty->tp_alloc(ty, 0);
@@ -100,11 +100,11 @@ end:
 static PyObject *keyszrange_pynew(PyTypeObject *ty,
                                  PyObject *arg, PyObject *kw)
 {
 static PyObject *keyszrange_pynew(PyTypeObject *ty,
                                  PyObject *arg, PyObject *kw)
 {
-  char *kwlist[] = { "default", "min", "max", "mod", 0 };
+  static const char *const kwlist[] = { "default", "min", "max", "mod", 0 };
   int dfl, min = 0, max = 0, mod = 1;
   keyszrange_pyobj *o;
 
   int dfl, min = 0, max = 0, mod = 1;
   keyszrange_pyobj *o;
 
-  if (!PyArg_ParseTupleAndKeywords(arg, kw, "i|iii:new", kwlist,
+  if (!PyArg_ParseTupleAndKeywords(arg, kw, "i|iii:new", KWLIST,
                                   &dfl, &min, &max, &mod))
     goto end;
   if (dfl < 0 || min < 0) VALERR("key size cannot be negative");
                                   &dfl, &min, &max, &mod))
     goto end;
   if (dfl < 0 || min < 0) VALERR("key size cannot be negative");
@@ -124,13 +124,13 @@ end:
 static PyObject *keyszset_pynew(PyTypeObject *ty,
                                PyObject *arg, PyObject *kw)
 {
 static PyObject *keyszset_pynew(PyTypeObject *ty,
                                PyObject *arg, PyObject *kw)
 {
-  char *kwlist[] = { "default", "set", 0 };
+  static const char *const kwlist[] = { "default", "set", 0 };
   int dfl, i, n, xx;
   PyObject *set = 0;
   PyObject *x = 0, *l = 0;
   keyszset_pyobj *o = 0;
 
   int dfl, i, n, xx;
   PyObject *set = 0;
   PyObject *x = 0, *l = 0;
   keyszset_pyobj *o = 0;
 
-  if (!PyArg_ParseTupleAndKeywords(arg, kw, "i|O:new", kwlist, &dfl, &set))
+  if (!PyArg_ParseTupleAndKeywords(arg, kw, "i|O:new", KWLIST, &dfl, &set))
     goto end;
   if (!set) set = PyTuple_New(0);
   else Py_INCREF(set);
     goto end;
   if (!set) set = PyTuple_New(0);
   else Py_INCREF(set);
@@ -457,29 +457,27 @@ PyTypeObject *gccipher_pytype, *gcipher_pytype;
 CONVFUNC(gccipher, gccipher *, GCCIPHER_CC)
 CONVFUNC(gcipher, gcipher *, GCIPHER_C)
 
 CONVFUNC(gccipher, gccipher *, GCCIPHER_CC)
 CONVFUNC(gcipher, gcipher *, GCIPHER_C)
 
-PyObject *gcipher_pywrap(PyObject *cobj, gcipher *c, unsigned f)
+PyObject *gcipher_pywrap(PyObject *cobj, gcipher *c)
 {
   gcipher_pyobj *g;
   if (!cobj) cobj = gccipher_pywrap((/*unconst*/ gccipher *)GC_CLASS(c));
   else Py_INCREF(cobj);
   g = PyObject_NEW(gcipher_pyobj, (PyTypeObject *)cobj);
   g->c = c;
 {
   gcipher_pyobj *g;
   if (!cobj) cobj = gccipher_pywrap((/*unconst*/ gccipher *)GC_CLASS(c));
   else Py_INCREF(cobj);
   g = PyObject_NEW(gcipher_pyobj, (PyTypeObject *)cobj);
   g->c = c;
-  g->f = f;
   return ((PyObject *)g);
 }
 
 static PyObject *gcipher_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
 {
   return ((PyObject *)g);
 }
 
 static PyObject *gcipher_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
 {
-  char *kwlist[] = { "k", 0 };
+  static const char *const kwlist[] = { "k", 0 };
   char *k;
   Py_ssize_t sz;
 
   char *k;
   Py_ssize_t sz;
 
-  if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#:new", kwlist, &k, &sz))
+  if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#:new", KWLIST, &k, &sz))
     goto end;
   if (keysz(sz, GCCIPHER_CC(ty)->keysz) != sz) VALERR("bad key length");
   return (gcipher_pywrap((PyObject *)ty,
     goto end;
   if (keysz(sz, GCCIPHER_CC(ty)->keysz) != sz) VALERR("bad key length");
   return (gcipher_pywrap((PyObject *)ty,
-                        GC_INIT(GCCIPHER_CC(ty), k, sz),
-                        f_freeme));
+                        GC_INIT(GCCIPHER_CC(ty), k, sz)));
 end:
   return (0);
 }
 end:
   return (0);
 }
@@ -503,8 +501,7 @@ PyObject *gccipher_pywrap(gccipher *cc)
 
 static void gcipher_pydealloc(PyObject *me)
 {
 
 static void gcipher_pydealloc(PyObject *me)
 {
-  if (GCIPHER_F(me) & f_freeme)
-    GC_DESTROY(GCIPHER_C(me));
+  GC_DESTROY(GCIPHER_C(me));
   Py_DECREF(me->ob_type);
   FREEOBJ(me);
 }
   Py_DECREF(me->ob_type);
   FREEOBJ(me);
 }
@@ -722,10 +719,10 @@ CONVFUNC(ghash, ghash *, GHASH_H)
 
 static PyObject *ghash_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
 {
 
 static PyObject *ghash_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
 {
-  char *kwlist[] = { 0 };
-  if (!PyArg_ParseTupleAndKeywords(arg, kw, ":new", kwlist))
+  static const char *const kwlist[] = { 0 };
+  if (!PyArg_ParseTupleAndKeywords(arg, kw, ":new", KWLIST))
     goto end;
     goto end;
-  return (ghash_pywrap((PyObject *)ty, GH_INIT(GCHASH_CH(ty)), f_freeme));
+  return (ghash_pywrap((PyObject *)ty, GH_INIT(GCHASH_CH(ty))));
 end:
   return (0);
 }
 end:
   return (0);
 }
@@ -747,21 +744,19 @@ PyObject *gchash_pywrap(gchash *ch)
   return ((PyObject *)g);
 }
 
   return ((PyObject *)g);
 }
 
-PyObject *ghash_pywrap(PyObject *cobj, ghash *h, unsigned f)
+PyObject *ghash_pywrap(PyObject *cobj, ghash *h)
 {
   ghash_pyobj *g;
   if (!cobj) cobj = gchash_pywrap((/*unconst*/ gchash *)GH_CLASS(h));
   else Py_INCREF(cobj);
   g = PyObject_NEW(ghash_pyobj, (PyTypeObject *)cobj);
   g->h = h;
 {
   ghash_pyobj *g;
   if (!cobj) cobj = gchash_pywrap((/*unconst*/ gchash *)GH_CLASS(h));
   else Py_INCREF(cobj);
   g = PyObject_NEW(ghash_pyobj, (PyTypeObject *)cobj);
   g->h = h;
-  g->f = f;
   return ((PyObject *)g);
 }
 
 static void ghash_pydealloc(PyObject *me)
 {
   return ((PyObject *)g);
 }
 
 static void ghash_pydealloc(PyObject *me)
 {
-  if (GHASH_F(me) & f_freeme)
-    GH_DESTROY(GHASH_H(me));
+  GH_DESTROY(GHASH_H(me));
   Py_DECREF(me->ob_type);
   FREEOBJ(me);
 }
   Py_DECREF(me->ob_type);
   FREEOBJ(me);
 }
@@ -775,6 +770,12 @@ static PyObject *gchget_hashsz(PyObject *me, void *hunoz)
 static PyObject *gchget_bufsz(PyObject *me, void *hunoz)
   { return (PyInt_FromLong(GCHASH_CH(me)->bufsz)); }
 
 static PyObject *gchget_bufsz(PyObject *me, void *hunoz)
   { return (PyInt_FromLong(GCHASH_CH(me)->bufsz)); }
 
+static PyObject *ghmeth_copy(PyObject *me, PyObject *arg)
+{
+  if (!PyArg_ParseTuple(arg, ":copy")) return (0);
+  return (ghash_pywrap((PyObject *)me->ob_type, GH_COPY(GHASH_H(me))));
+}
+
 static PyObject *ghmeth_hash(PyObject *me, PyObject *arg)
 {
   char *p;
 static PyObject *ghmeth_hash(PyObject *me, PyObject *arg)
 {
   char *p;
@@ -788,11 +789,9 @@ static PyObject *ghmeth_hash(PyObject *me, PyObject *arg)
   static PyObject *ghmeth_hashu##w(PyObject *me, PyObject *arg)                \
   {                                                                    \
     uint##n x;                                                         \
   static PyObject *ghmeth_hashu##w(PyObject *me, PyObject *arg)                \
   {                                                                    \
     uint##n x;                                                         \
-    if (!PyArg_ParseTuple(arg, "O&:hashu" #w, convu##n, &x)) goto end; \
+    if (!PyArg_ParseTuple(arg, "O&:hashu" #w, convu##n, &x)) return (0); \
     GH_HASHU##W(GHASH_H(me), x);                                       \
     RETURN_ME;                                                         \
     GH_HASHU##W(GHASH_H(me), x);                                       \
     RETURN_ME;                                                         \
-  end:                                                                 \
-    return (0);                                                                \
   }
 DOUINTCONV(GHMETH_HASHU_)
 
   }
 DOUINTCONV(GHMETH_HASHU_)
 
@@ -841,6 +840,7 @@ static PyGetSetDef gchash_pygetset[] = {
 
 static PyMethodDef ghash_pymethods[] = {
 #define METHNAME(name) ghmeth_##name
 
 static PyMethodDef ghash_pymethods[] = {
 #define METHNAME(name) ghmeth_##name
+  METH (copy,                  "H.copy() -> HH")
   METH (hash,                  "H.hash(M)")
 #define METHU_(n, W, w) METH(hashu##w, "H.hashu" #w "(WORD)")
   DOUINTCONV(METHU_)
   METH (hash,                  "H.hash(M)")
 #define METHU_(n, W, w) METH(hashu##w, "H.hashu" #w "(WORD)")
   DOUINTCONV(METHU_)
@@ -960,29 +960,27 @@ CONVFUNC(gmhash, ghash *, GHASH_H)
 
 static PyObject *gmac_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
 {
 
 static PyObject *gmac_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
 {
-  char *kwlist[] = { "k", 0 };
+  static const char *const kwlist[] = { "k", 0 };
   char *k;
   Py_ssize_t sz;
 
   char *k;
   Py_ssize_t sz;
 
-  if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#:new", kwlist, &k, &sz))
+  if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#:new", KWLIST, &k, &sz))
     goto end;
   if (keysz(sz, GCMAC_CM(ty)->keysz) != sz) VALERR("bad key length");
   return (gmac_pywrap((PyObject *)ty,
     goto end;
   if (keysz(sz, GCMAC_CM(ty)->keysz) != sz) VALERR("bad key length");
   return (gmac_pywrap((PyObject *)ty,
-                     GM_KEY(GCMAC_CM(ty), k, sz),
-                     f_freeme));
+                     GM_KEY(GCMAC_CM(ty), k, sz)));
 end:
   return (0);
 }
 
 static PyObject *gmhash_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
 {
 end:
   return (0);
 }
 
 static PyObject *gmhash_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
 {
-  char *kwlist[] = { 0 };
+  static const char *const kwlist[] = { 0 };
   ghash_pyobj *g;
 
   ghash_pyobj *g;
 
-  if (!PyArg_ParseTupleAndKeywords(arg, kw, ":new", kwlist)) return (0);
+  if (!PyArg_ParseTupleAndKeywords(arg, kw, ":new", KWLIST)) return (0);
   g = PyObject_NEW(ghash_pyobj, ty);
   g->h = GM_INIT(GMAC_M(ty));
   g = PyObject_NEW(ghash_pyobj, ty);
   g->h = GM_INIT(GMAC_M(ty));
-  g->f = f_freeme;
   Py_INCREF(ty);
   return ((PyObject *)g);
 }
   Py_INCREF(ty);
   return ((PyObject *)g);
 }
@@ -1004,7 +1002,7 @@ PyObject *gcmac_pywrap(gcmac *cm)
   return ((PyObject *)g);
 }
 
   return ((PyObject *)g);
 }
 
-PyObject *gmac_pywrap(PyObject *cobj, gmac *m, unsigned f)
+PyObject *gmac_pywrap(PyObject *cobj, gmac *m)
 {
   gmac_pyobj *g;
   if (!cobj) cobj = gcmac_pywrap((/*unconst*/ gcmac *)GM_CLASS(m));
 {
   gmac_pyobj *g;
   if (!cobj) cobj = gcmac_pywrap((/*unconst*/ gcmac *)GM_CLASS(m));
@@ -1023,14 +1021,12 @@ PyObject *gmac_pywrap(PyObject *cobj, gmac *m, unsigned f)
   g->ty.ht_type.tp_new = gmhash_pynew;
   typeready(&g->ty.ht_type);
   g->m = m;
   g->ty.ht_type.tp_new = gmhash_pynew;
   typeready(&g->ty.ht_type);
   g->m = m;
-  g->f = f;
   return ((PyObject *)g);
 }
 
 static void gmac_pydealloc(PyObject *me)
 {
   return ((PyObject *)g);
 }
 
 static void gmac_pydealloc(PyObject *me)
 {
-  if (GMAC_F(me) & f_freeme)
-    GM_DESTROY(GMAC_M(me));
+  GM_DESTROY(GMAC_M(me));
   Py_DECREF(me->ob_type);
   PyType_Type.tp_dealloc(me);
 }
   Py_DECREF(me->ob_type);
   PyType_Type.tp_dealloc(me);
 }
@@ -1220,13 +1216,13 @@ CONVFUNC(poly1305hash, poly1305_ctx *, P1305_CTX)
 static PyObject *poly1305hash_pynew(PyTypeObject *ty,
                                    PyObject *arg, PyObject *kw)
 {
 static PyObject *poly1305hash_pynew(PyTypeObject *ty,
                                    PyObject *arg, PyObject *kw)
 {
-  char *kwlist[] = { "mask", 0 };
+  static const char *const kwlist[] = { "mask", 0 };
   poly1305key_pyobj *pk = (poly1305key_pyobj *)ty;
   poly1305hash_pyobj *ph;
   char *m = 0;
   Py_ssize_t sz;
 
   poly1305key_pyobj *pk = (poly1305key_pyobj *)ty;
   poly1305hash_pyobj *ph;
   char *m = 0;
   Py_ssize_t sz;
 
-  if (!PyArg_ParseTupleAndKeywords(arg, kw, "|s#:new", kwlist, &m, &sz))
+  if (!PyArg_ParseTupleAndKeywords(arg, kw, "|s#:new", KWLIST, &m, &sz))
     return (0);
   if (m && sz != POLY1305_MASKSZ) VALERR("bad mask length");
   ph = PyObject_NEW(poly1305hash_pyobj, ty);
     return (0);
   if (m && sz != POLY1305_MASKSZ) VALERR("bad mask length");
   ph = PyObject_NEW(poly1305hash_pyobj, ty);
@@ -1242,12 +1238,12 @@ end:
 static PyObject *poly1305key_pynew(PyTypeObject *ty,
                                   PyObject *arg, PyObject *kw)
 {
 static PyObject *poly1305key_pynew(PyTypeObject *ty,
                                   PyObject *arg, PyObject *kw)
 {
-  char *kwlist[] = { "k", 0 };
+  static const char *const kwlist[] = { "k", 0 };
   poly1305key_pyobj *pk;
   char *k;
   Py_ssize_t sz;
 
   poly1305key_pyobj *pk;
   char *k;
   Py_ssize_t sz;
 
-  if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#:new", kwlist, &k, &sz))
+  if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#:new", KWLIST, &k, &sz))
     goto end;
   if (keysz(sz, poly1305_keysz) != sz) VALERR("bad key length");
 
     goto end;
   if (keysz(sz, poly1305_keysz) != sz) VALERR("bad key length");
 
@@ -1308,11 +1304,9 @@ static PyObject *polymeth_hash(PyObject *me, PyObject *arg)
   {                                                                    \
     uint##n x;                                                         \
     octet b[SZ_##W];                                                   \
   {                                                                    \
     uint##n x;                                                         \
     octet b[SZ_##W];                                                   \
-    if (!PyArg_ParseTuple(arg, "O&:hashu" #w, convu##n, &x)) goto end; \
+    if (!PyArg_ParseTuple(arg, "O&:hashu" #w, convu##n, &x)) return (0); \
     STORE##W(b, x); poly1305_hash(P1305_CTX(me), b, sizeof(b));                \
     RETURN_ME;                                                         \
     STORE##W(b, x); poly1305_hash(P1305_CTX(me), b, sizeof(b));                \
     RETURN_ME;                                                         \
-  end:                                                                 \
-    return (0);                                                                \
   }
 DOUINTCONV(POLYMETH_HASHU_)
 
   }
 DOUINTCONV(POLYMETH_HASHU_)
 
@@ -1600,8 +1594,8 @@ static PyObject *kxvik_pynew(PyTypeObject *ty,
 {
   unsigned n = 24;
   kxvik_pyobj *rc = 0;
 {
   unsigned n = 24;
   kxvik_pyobj *rc = 0;
-  char *kwlist[] = { "nround", 0 };
-  if (!PyArg_ParseTupleAndKeywords(arg, kw, "|O&:new", kwlist,
+  static const char *const kwlist[] = { "nround", 0 };
+  if (!PyArg_ParseTupleAndKeywords(arg, kw, "|O&:new", KWLIST,
                                   convuint, &n))
     goto end;
   rc = (kxvik_pyobj *)ty->tp_alloc(ty, 0);
                                   convuint, &n))
     goto end;
   rc = (kxvik_pyobj *)ty->tp_alloc(ty, 0);
@@ -1611,6 +1605,16 @@ end:
   return ((PyObject *)rc);
 }
 
   return ((PyObject *)rc);
 }
 
+static PyObject *kxvikmeth_copy(PyObject *me, PyObject *arg)
+{
+  kxvik_pyobj *k = (kxvik_pyobj *)me, *rc = 0;
+  if (!PyArg_ParseTuple(arg, ":copy")) goto end;
+  rc = (kxvik_pyobj *)k->ob_type->tp_alloc(k->ob_type, 0);
+  rc->s = k->s; rc->n = k->n;
+end:
+  return ((PyObject *)rc);
+}
+
 static PyObject *kxvikmeth_mix(PyObject *me, PyObject *arg)
 {
   kxvik_pyobj *k = (kxvik_pyobj *)me;
 static PyObject *kxvikmeth_mix(PyObject *me, PyObject *arg)
 {
   kxvik_pyobj *k = (kxvik_pyobj *)me;
@@ -1689,6 +1693,7 @@ static PyGetSetDef kxvik_pygetset[] = {
 
 static PyMethodDef kxvik_pymethods[] = {
 #define METHNAME(func) kxvikmeth_##func
 
 static PyMethodDef kxvik_pymethods[] = {
 #define METHNAME(func) kxvikmeth_##func
+  METH (copy,                  "KECCAK.copy() -> KECCAK'")
   METH (mix,                   "KECCAK.mix(DATA)")
   METH (extract,               "KECCAK.extract(NOCTETS)")
   METH (step,                  "KECCAK.step()")
   METH (mix,                   "KECCAK.mix(DATA)")
   METH (extract,               "KECCAK.extract(NOCTETS)")
   METH (step,                  "KECCAK.step()")
@@ -1764,9 +1769,9 @@ static PyObject *shake_dopynew(void (*initfn)(shake_ctx *,
   shake_pyobj *rc = 0;
   char *p = 0, *f = 0;
   Py_ssize_t psz = 0, fsz = 0;
   shake_pyobj *rc = 0;
   char *p = 0, *f = 0;
   Py_ssize_t psz = 0, fsz = 0;
-  char *kwlist[] = { "perso", "func", 0 };
+  static const char *const kwlist[] = { "perso", "func", 0 };
 
 
-  if (!PyArg_ParseTupleAndKeywords(arg, kw, "|s#s#:new", kwlist,
+  if (!PyArg_ParseTupleAndKeywords(arg, kw, "|s#s#:new", KWLIST,
                                   &p, &psz, &f, &fsz))
     goto end;
   rc = (shake_pyobj *)ty->tp_alloc(ty, 0);
                                   &p, &psz, &f, &fsz))
     goto end;
   rc = (shake_pyobj *)ty->tp_alloc(ty, 0);
@@ -1807,12 +1812,10 @@ static PyObject *shakemeth_hash(PyObject *me, PyObject *arg)
   {                                                                    \
     uint##n x;                                                         \
     octet b[SZ_##W];                                                   \
   {                                                                    \
     uint##n x;                                                         \
     octet b[SZ_##W];                                                   \
-    if (!PyArg_ParseTuple(arg, "O&:hashu" #w, convu##n, &x)) goto end; \
-    if (shake_check(me, 0)) goto end;                                  \
+    if (!PyArg_ParseTuple(arg, "O&:hashu" #w, convu##n, &x)) return (0); \
+    if (shake_check(me, 0)) return (0);                                        \
     STORE##W(b, x); shake_hash(SHAKE_H(me), b, sizeof(b));             \
     RETURN_ME;                                                         \
     STORE##W(b, x); shake_hash(SHAKE_H(me), b, sizeof(b));             \
     RETURN_ME;                                                         \
-  end:                                                                 \
-    return (0);                                                                \
   }
 DOUINTCONV(SHAKEMETH_HASHU_)
 
   }
 DOUINTCONV(SHAKEMETH_HASHU_)
 
@@ -2148,13 +2151,13 @@ typedef struct prp {
 
 static PyObject *gprp_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
 {
 
 static PyObject *gprp_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
 {
-  char *kwlist[] = { "key", 0 };
+  static const char *const kwlist[] = { "key", 0 };
   char *k;
   Py_ssize_t sz;
   const prpinfo *prp = GCPRP_PRP(ty);
   PyObject *me;
 
   char *k;
   Py_ssize_t sz;
   const prpinfo *prp = GCPRP_PRP(ty);
   PyObject *me;
 
-  if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#:new", kwlist, &k, &sz))
+  if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#:new", KWLIST, &k, &sz))
     goto end;
   if (keysz(sz, prp->keysz) != sz) VALERR("bad key length");
   me = (PyObject *)ty->tp_alloc(ty, 0);
     goto end;
   if (keysz(sz, prp->keysz) != sz) VALERR("bad key length");
   me = (PyObject *)ty->tp_alloc(ty, 0);