Improve argument checking speed.
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 545dba6..6403103 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -3320,6 +3320,22 @@
 	}
 }
 
+static int
+check_num_args(PyObject *ob, int n)
+{
+	if (!PyTuple_CheckExact(ob)) {
+		PyErr_SetString(PyExc_SystemError,
+		    "PyArg_UnpackTuple() argument list is not a tuple");
+		return 0;
+	}
+	if (n == PyTuple_GET_SIZE(ob))
+		return 1;
+	PyErr_Format(
+	    PyExc_TypeError, 
+	    "expected %d arguments, got %d", n, PyTuple_GET_SIZE(ob));
+	return 0;
+}
+
 /* Generic wrappers for overloadable 'operators' such as __getitem__ */
 
 /* There's a wrapper *function* for each distinct function typedef used
@@ -3334,7 +3350,7 @@
 	inquiry func = (inquiry)wrapped;
 	int res;
 
-	if (!PyArg_UnpackTuple(args, "", 0, 0))
+	if (!check_num_args(args, 0))
 		return NULL;
 	res = (*func)(self);
 	if (res == -1 && PyErr_Occurred())
@@ -3348,7 +3364,7 @@
 	inquiry func = (inquiry)wrapped;
 	int res;
 
-	if (!PyArg_UnpackTuple(args, "", 0, 0))
+	if (!check_num_args(args, 0))
 		return NULL;
 	res = (*func)(self);
 	if (res == -1 && PyErr_Occurred())
@@ -3362,8 +3378,9 @@
 	binaryfunc func = (binaryfunc)wrapped;
 	PyObject *other;
 
-	if (!PyArg_UnpackTuple(args, "", 1, 1, &other))
+	if (!check_num_args(args, 1))
 		return NULL;
+	other = PyTuple_GET_ITEM(args, 0);
 	return (*func)(self, other);
 }
 
@@ -3373,8 +3390,9 @@
 	binaryfunc func = (binaryfunc)wrapped;
 	PyObject *other;
 
-	if (!PyArg_UnpackTuple(args, "", 1, 1, &other))
+	if (!check_num_args(args, 1))
 		return NULL;
+	other = PyTuple_GET_ITEM(args, 0);
 	if (!(self->ob_type->tp_flags & Py_TPFLAGS_CHECKTYPES) &&
 	    !PyType_IsSubtype(other->ob_type, self->ob_type)) {
 		Py_INCREF(Py_NotImplemented);
@@ -3389,8 +3407,9 @@
 	binaryfunc func = (binaryfunc)wrapped;
 	PyObject *other;
 
-	if (!PyArg_UnpackTuple(args, "", 1, 1, &other))
+	if (!check_num_args(args, 1))
 		return NULL;
+	other = PyTuple_GET_ITEM(args, 0);
 	if (!(self->ob_type->tp_flags & Py_TPFLAGS_CHECKTYPES) &&
 	    !PyType_IsSubtype(other->ob_type, self->ob_type)) {
 		Py_INCREF(Py_NotImplemented);
@@ -3406,8 +3425,9 @@
 	PyObject *other, *res;
 	int ok;
 
-	if (!PyArg_UnpackTuple(args, "", 1, 1, &other))
+	if (!check_num_args(args, 1))
 		return NULL;
+	other = PyTuple_GET_ITEM(args, 0);
 	ok = func(&self, &other);
 	if (ok < 0)
 		return NULL;
@@ -3459,7 +3479,7 @@
 {
 	unaryfunc func = (unaryfunc)wrapped;
 
-	if (!PyArg_UnpackTuple(args, "", 0, 0))
+	if (!check_num_args(args, 0))
 		return NULL;
 	return (*func)(self);
 }
@@ -3509,7 +3529,7 @@
 			return NULL;
 		return (*func)(self, i);
 	}
-	PyArg_UnpackTuple(args, "", 1, 1, &arg);
+	check_num_args(args, 1);
 	assert(PyErr_Occurred());
 	return NULL;
 }
@@ -3551,8 +3571,9 @@
 	int i, res;
 	PyObject *arg;
 
-	if (!PyArg_UnpackTuple(args, "", 1, 1, &arg))
+	if (!check_num_args(args, 1))
 		return NULL;
+	arg = PyTuple_GET_ITEM(args, 0);
 	i = getindex(self, arg);
 	if (i == -1 && PyErr_Occurred())
 		return NULL;
@@ -3602,8 +3623,9 @@
 	int res;
 	PyObject *value;
 
-	if (!PyArg_UnpackTuple(args, "", 1, 1, &value))
+	if (!check_num_args(args, 1))
 		return NULL;
+	value = PyTuple_GET_ITEM(args, 0);
 	res = (*func)(self, value);
 	if (res == -1 && PyErr_Occurred())
 		return NULL;
@@ -3634,8 +3656,9 @@
 	int res;
 	PyObject *key;
 
-	if (!PyArg_UnpackTuple(args, "", 1, 1, &key))
+	if (!check_num_args(args, 1))
 		return NULL;
+	key = PyTuple_GET_ITEM(args, 0);
 	res = (*func)(self, key, NULL);
 	if (res == -1 && PyErr_Occurred())
 		return NULL;
@@ -3650,8 +3673,9 @@
 	int res;
 	PyObject *other;
 
-	if (!PyArg_UnpackTuple(args, "", 1, 1, &other))
+	if (!check_num_args(args, 1))
 		return NULL;
+	other = PyTuple_GET_ITEM(args, 0);
 	if (other->ob_type->tp_compare != func &&
 	    !PyType_IsSubtype(other->ob_type, self->ob_type)) {
 		PyErr_Format(
@@ -3711,8 +3735,9 @@
 	int res;
 	PyObject *name;
 
-	if (!PyArg_UnpackTuple(args, "", 1, 1, &name))
+	if (!check_num_args(args, 1))
 		return NULL;
+	name = PyTuple_GET_ITEM(args, 0);
 	if (!hackcheck(self, func, "__delattr__"))
 		return NULL;
 	res = (*func)(self, name, NULL);
@@ -3728,7 +3753,7 @@
 	hashfunc func = (hashfunc)wrapped;
 	long res;
 
-	if (!PyArg_UnpackTuple(args, "", 0, 0))
+	if (!check_num_args(args, 0))
 		return NULL;
 	res = (*func)(self);
 	if (res == -1 && PyErr_Occurred())
@@ -3750,8 +3775,9 @@
 	richcmpfunc func = (richcmpfunc)wrapped;
 	PyObject *other;
 
-	if (!PyArg_UnpackTuple(args, "", 1, 1, &other))
+	if (!check_num_args(args, 1))
 		return NULL;
+	other = PyTuple_GET_ITEM(args, 0);
 	return (*func)(self, other, op);
 }
 
@@ -3776,7 +3802,7 @@
 	unaryfunc func = (unaryfunc)wrapped;
 	PyObject *res;
 
-	if (!PyArg_UnpackTuple(args, "", 0, 0))
+	if (!check_num_args(args, 0))
 		return NULL;
 	res = (*func)(self);
 	if (res == NULL && !PyErr_Occurred())
@@ -3828,8 +3854,9 @@
 	PyObject *obj;
 	int ret;
 
-	if (!PyArg_UnpackTuple(args, "", 1, 1, &obj))
+	if (!check_num_args(args, 1))
 		return NULL;
+	obj = PyTuple_GET_ITEM(args, 0);
 	ret = (*func)(self, obj, NULL);
 	if (ret < 0)
 		return NULL;