diff -r 8efb09a13529 -r adfab67acffa Grammar/Grammar
--- a/Grammar/Grammar	Sat Aug 07 16:01:53 2010 +1200
+++ b/Grammar/Grammar	Wed Oct 26 20:29:15 2011 +1300
@@ -21,8 +21,9 @@
 
 decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
 decorators: decorator+
-decorated: decorators (classdef | funcdef)
+decorated: decorators (classdef | funcdef | cofuncdef)
 funcdef: 'def' NAME parameters ['->' test] ':' suite
+cofuncdef: 'codef' NAME parameters ['->' test] ':' suite
 parameters: '(' [typedargslist] ')'
 typedargslist: ((tfpdef ['=' test] ',')*
                 ('*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef)
@@ -64,7 +65,7 @@
 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
 assert_stmt: 'assert' test [',' test]
 
-compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated
+compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | cofuncdef | classdef | decorated
 if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
 while_stmt: 'while' test ':' suite ['else' ':' suite]
 for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
diff -r 8efb09a13529 -r adfab67acffa Include/code.h
--- a/Include/code.h	Sat Aug 07 16:01:53 2010 +1200
+++ b/Include/code.h	Wed Oct 26 20:29:15 2011 +1300
@@ -41,6 +41,7 @@
    call frame it setup.
 */
 #define CO_NOFREE       0x0040
+#define CO_COFUNCTION	0x0080
 
 /* These are no longer used. */
 #if 0
diff -r 8efb09a13529 -r adfab67acffa Include/funcobject.h
--- a/Include/funcobject.h	Sat Aug 07 16:01:53 2010 +1200
+++ b/Include/funcobject.h	Wed Oct 26 20:29:15 2011 +1300
@@ -72,6 +72,8 @@
 	(((PyFunctionObject *)func) -> func_closure)
 #define PyFunction_GET_ANNOTATIONS(func) \
 	(((PyFunctionObject *)func) -> func_annotations)
+#define PyFunction_IS_COFUNCTION(func) \
+	(((PyCodeObject *)PyFunction_GET_CODE(func))->co_flags & CO_COFUNCTION)
 
 /* The classmethod and staticmethod types lives here, too */
 PyAPI_DATA(PyTypeObject) PyClassMethod_Type;
diff -r 8efb09a13529 -r adfab67acffa Include/object.h
--- a/Include/object.h	Sat Aug 07 16:01:53 2010 +1200
+++ b/Include/object.h	Wed Oct 26 20:29:15 2011 +1300
@@ -296,7 +296,7 @@
 	printfunc tp_print;
 	getattrfunc tp_getattr;
 	setattrfunc tp_setattr;
-	void *tp_reserved; /* formerly known as tp_compare */
+	ternaryfunc tp_cocall; /* formerly known as tp_compare */
 	reprfunc tp_repr;
 
 	/* Method suites for standard classes */
@@ -445,6 +445,7 @@
 PyAPI_FUNC(int) PyObject_IsTrue(PyObject *);
 PyAPI_FUNC(int) PyObject_Not(PyObject *);
 PyAPI_FUNC(int) PyCallable_Check(PyObject *);
+PyAPI_FUNC(PyObject *) PyObject_CoCall(PyObject *, PyObject *args, PyObject *kw);
 
 PyAPI_FUNC(void) PyObject_ClearWeakRefs(PyObject *);
 
@@ -494,6 +495,9 @@
 given type object has a specified feature.
 */
 
+/* The tp_reserved slot is now used for tp_cocall */
+#define Py_TPFLAGS_COCALL (1L<<8)
+
 /* Set if the type object is dynamically allocated */
 #define Py_TPFLAGS_HEAPTYPE (1L<<9)
 
@@ -537,6 +541,7 @@
 #define Py_TPFLAGS_DEFAULT  ( \
                              Py_TPFLAGS_HAVE_STACKLESS_EXTENSION | \
                              Py_TPFLAGS_HAVE_VERSION_TAG | \
+                             Py_TPFLAGS_COCALL | \
                             0)
 
 #define PyType_HasFeature(t,f)  (((t)->tp_flags & (f)) != 0)
diff -r 8efb09a13529 -r adfab67acffa Include/opcode.h
--- a/Include/opcode.h	Sat Aug 07 16:01:53 2010 +1200
+++ b/Include/opcode.h	Wed Oct 26 20:29:15 2011 +1300
@@ -115,7 +115,11 @@
 #define DELETE_FAST	126	/* Local variable number */
 
 #define RAISE_VARARGS	130	/* Number of raise arguments (1, 2 or 3) */
-/* CALL_FUNCTION_XXX opcodes defined below depend on this definition */
+/* The CALL_FUNCTION family of opcodes encode the following values in the
+   last 3 bits of the offset of the opcode from CALL_FUNCTION. */
+	#define CALL_FLAG_VAR     1
+	#define CALL_FLAG_KW      2
+	#define CALL_FLAG_COCALL  4
 #define CALL_FUNCTION	131	/* #args + (#kwargs<<8) */
 #define MAKE_FUNCTION	132	/* #defaults + #kwdefaults<<8 + #annotations<<16 */
 #define BUILD_SLICE 	133	/* Number of items */
@@ -125,8 +129,7 @@
 #define LOAD_DEREF      136     /* Load and dereference from closure cell */ 
 #define STORE_DEREF     137     /* Store into cell */ 
 
-/* The next 3 opcodes must be contiguous and satisfy
-   (CALL_FUNCTION_VAR - CALL_FUNCTION) & 3 == 1  */
+/* The next 3 opcodes are constrained, see CALL_FUNCTION */
 #define CALL_FUNCTION_VAR          140	/* #args + (#kwargs<<8) */
 #define CALL_FUNCTION_KW           141	/* #args + (#kwargs<<8) */
 #define CALL_FUNCTION_VAR_KW       142	/* #args + (#kwargs<<8) */
@@ -138,7 +141,6 @@
 #define SET_ADD         146
 #define MAP_ADD         147
 
-
 /* EXCEPT_HANDLER is a special, implicit block type which is created when
    entering an except handler. It is not an opcode but we define it here
    as we want it to be available to both frameobject.c and ceval.c, while
diff -r 8efb09a13529 -r adfab67acffa Include/symtable.h
--- a/Include/symtable.h	Sat Aug 07 16:01:53 2010 +1200
+++ b/Include/symtable.h	Wed Oct 26 20:29:15 2011 +1300
@@ -41,6 +41,7 @@
 	unsigned ste_child_free : 1;  /* true if a child block has free vars,
 				         including free refs to globals */
 	unsigned ste_generator : 1;   /* true if namespace is a generator */
+	unsigned ste_cofunction : 1;   /* true if namespace is a cofunction */
 	unsigned ste_varargs : 1;     /* true if block has varargs */
 	unsigned ste_varkeywords : 1; /* true if block has varkeywords */
 	unsigned ste_returns_value : 1;  /* true if namespace uses return with
diff -r 8efb09a13529 -r adfab67acffa Lib/opcode.py
--- a/Lib/opcode.py	Sat Aug 07 16:01:53 2010 +1200
+++ b/Lib/opcode.py	Wed Oct 26 20:29:15 2011 +1300
@@ -174,5 +174,4 @@
 def_op('SET_ADD', 146)
 def_op('MAP_ADD', 147)
 
-
 del def_op, name_op, jrel_op, jabs_op
diff -r 8efb09a13529 -r adfab67acffa Lib/site.py
--- a/Lib/site.py	Sat Aug 07 16:01:53 2010 +1200
+++ b/Lib/site.py	Wed Oct 26 20:29:15 2011 +1300
@@ -105,12 +105,22 @@
 def addbuilddir():
     """Append ./build/lib.<platform> in case we're running in the build dir
     (especially for Guido :-)"""
-    from distutils.util import get_platform
-    s = "build/lib.%s-%.3s" % (get_platform(), sys.version)
+#    from distutils.util import get_platform
+#    s = "build/lib.%s-%.3s" % (get_platform(), sys.version)
+#    if hasattr(sys, 'gettotalrefcount'):
+#        s += '-pydebug'
+#    s = os.path.join(os.path.dirname(sys.path[-1]), s)
+#    sys.path.append(s)
+    d = os.path.dirname(sys.path[-1])
+    pat = os.path.join(d, "build", "lib.*-%.3s" % sys.version)
     if hasattr(sys, 'gettotalrefcount'):
-        s += '-pydebug'
-    s = os.path.join(os.path.dirname(sys.path[-1]), s)
-    sys.path.append(s)
+        pat += '-pydebug'
+    import glob
+    #print("Looking for", pat) ###
+    l = glob.glob(pat)
+    #print("Found", l)
+    if l:
+        sys.path.append(l[0])
 
 
 def _init_pathinfo():
diff -r 8efb09a13529 -r adfab67acffa Lib/symbol.py
--- a/Lib/symbol.py	Sat Aug 07 16:01:53 2010 +1200
+++ b/Lib/symbol.py	Wed Oct 26 20:29:15 2011 +1300
@@ -17,80 +17,85 @@
 decorators = 260
 decorated = 261
 funcdef = 262
-parameters = 263
-typedargslist = 264
-tfpdef = 265
-varargslist = 266
-vfpdef = 267
-stmt = 268
-simple_stmt = 269
-small_stmt = 270
-expr_stmt = 271
-augassign = 272
-del_stmt = 273
-pass_stmt = 274
-flow_stmt = 275
-break_stmt = 276
-continue_stmt = 277
-return_stmt = 278
-yield_stmt = 279
-raise_stmt = 280
-import_stmt = 281
-import_name = 282
-import_from = 283
-import_as_name = 284
-dotted_as_name = 285
-import_as_names = 286
-dotted_as_names = 287
-dotted_name = 288
-global_stmt = 289
-nonlocal_stmt = 290
-assert_stmt = 291
-compound_stmt = 292
-if_stmt = 293
-while_stmt = 294
-for_stmt = 295
-try_stmt = 296
-with_stmt = 297
-with_item = 298
-except_clause = 299
-suite = 300
-test = 301
-test_nocond = 302
-lambdef = 303
-lambdef_nocond = 304
-or_test = 305
-and_test = 306
-not_test = 307
-comparison = 308
-comp_op = 309
-star_expr = 310
-expr = 311
-xor_expr = 312
-and_expr = 313
-shift_expr = 314
-arith_expr = 315
-term = 316
-factor = 317
-power = 318
-atom = 319
-testlist_comp = 320
-trailer = 321
-subscriptlist = 322
-subscript = 323
-sliceop = 324
-exprlist = 325
-testlist = 326
-dictorsetmaker = 327
-classdef = 328
-arglist = 329
-argument = 330
-comp_iter = 331
-comp_for = 332
-comp_if = 333
-testlist1 = 334
-encoding_decl = 335
-yield_expr = 336
+cofuncdef = 263
+parameters = 264
+typedargslist = 265
+tfpdef = 266
+varargslist = 267
+vfpdef = 268
+stmt = 269
+simple_stmt = 270
+small_stmt = 271
+expr_stmt = 272
+augassign = 273
+del_stmt = 274
+pass_stmt = 275
+flow_stmt = 276
+break_stmt = 277
+continue_stmt = 278
+return_stmt = 279
+yield_stmt = 280
+raise_stmt = 281
+import_stmt = 282
+import_name = 283
+import_from = 284
+import_as_name = 285
+dotted_as_name = 286
+import_as_names = 287
+dotted_as_names = 288
+dotted_name = 289
+global_stmt = 290
+nonlocal_stmt = 291
+assert_stmt = 292
+compound_stmt = 293
+if_stmt = 294
+while_stmt = 295
+for_stmt = 296
+try_stmt = 297
+with_stmt = 298
+with_item = 299
+except_clause = 300
+suite = 301
+test = 302
+test_nocond = 303
+lambdef = 304
+lambdef_nocond = 305
+or_test = 306
+and_test = 307
+not_test = 308
+comparison = 309
+comp_op = 310
+star_expr = 311
+expr = 312
+xor_expr = 313
+and_expr = 314
+shift_expr = 315
+arith_expr = 316
+term = 317
+factor = 318
+power = 319
+atom = 320
+cocall = 321
+cotrailer = 322
+testlist_comp = 323
+trailer = 324
+subscriptlist = 325
+subscript = 326
+sliceop = 327
+exprlist = 328
+testlist = 329
+dictorsetmaker = 330
+classdef = 331
+arglist = 332
+argument = 333
+comp_iter = 334
+comp_for = 335
+comp_if = 336
+testlist1 = 337
+encoding_decl = 338
+yield_expr = 339
+yield_arg = 340
+yield_from = 341
 #--end constants--
 
 sym_name = {}
diff -r 8efb09a13529 -r adfab67acffa Modules/xxmodule.c
--- a/Modules/xxmodule.c	Sat Aug 07 16:01:53 2010 +1200
+++ b/Modules/xxmodule.c	Wed Oct 26 20:29:15 2011 +1300
@@ -106,7 +106,7 @@
 	0,			/*tp_print*/
 	(getattrfunc)0,         /*tp_getattr*/
 	(setattrfunc)Xxo_setattr, /*tp_setattr*/
-	0,			/*tp_reserved*/
+	0,			/*tp_cocall*/
 	0,			/*tp_repr*/
 	0,			/*tp_as_number*/
 	0,			/*tp_as_sequence*/
diff -r 8efb09a13529 -r adfab67acffa Objects/classobject.c
--- a/Objects/classobject.c	Sat Aug 07 16:01:53 2010 +1200
+++ b/Objects/classobject.c	Wed Oct 26 20:29:15 2011 +1300
@@ -291,7 +291,7 @@
 }
 
 static PyObject *
-method_call(PyObject *func, PyObject *arg, PyObject *kw)
+method_call_or_cocall(PyObject *func, PyObject *arg, PyObject *kw, int is_cocall)
 {
 	PyObject *self = PyMethod_GET_SELF(func);
 	PyObject *result;
@@ -316,12 +316,27 @@
 		}
 		arg = newarg;
 	}
-	result = PyObject_Call((PyObject *)func, arg, kw);
+	if (is_cocall)
+		result = PyObject_CoCall((PyObject *)func, arg, kw);
+	else
+		result = PyObject_Call((PyObject *)func, arg, kw);
 	Py_DECREF(arg);
 	return result;
 }
 
 static PyObject *
+method_call(PyObject *func, PyObject *arg, PyObject *kw)
+{
+	return method_call_or_cocall(func, arg, kw, 0);
+}
+
+static PyObject *
+method_cocall(PyObject *func, PyObject *arg, PyObject *kw)
+{
+	return method_call_or_cocall(func, arg, kw, 1);
+}
+
+static PyObject *
 method_descr_get(PyObject *meth, PyObject *obj, PyObject *cls)
 {
 	/* Don't rebind an already bound method of a class that's not a base
@@ -344,7 +359,7 @@
 	0,					/* tp_print */
 	0,					/* tp_getattr */
 	0,					/* tp_setattr */
-	0,					/* tp_reserved */
+	method_cocall,				/* tp_cocall */
 	(reprfunc)method_repr,			/* tp_repr */
 	0,					/* tp_as_number */
 	0,					/* tp_as_sequence */
diff -r 8efb09a13529 -r adfab67acffa Objects/funcobject.c
--- a/Objects/funcobject.c	Sat Aug 07 16:01:53 2010 +1200
+++ b/Objects/funcobject.c	Wed Oct 26 20:29:15 2011 +1300
@@ -1,6 +1,7 @@
 
 /* Function object implementation */
 
+#include <stdio.h> /***/
 #include "Python.h"
 #include "code.h"
 #include "eval.h"
@@ -432,6 +433,13 @@
 	return 0;
 }
 
+static PyObject *
+func_get_iscofunction(PyFunctionObject *op)
+{
+	PyCodeObject *code = (PyCodeObject *)op->func_code;
+	return PyBool_FromLong(code->co_flags & CO_COFUNCTION);
+}
+
 static PyGetSetDef func_getsetlist[] = {
         {"__code__", (getter)func_get_code, (setter)func_set_code},
         {"__defaults__", (getter)func_get_defaults,
@@ -442,6 +450,7 @@
 	 (setter)func_set_annotations},
 	{"__dict__", (getter)func_get_dict, (setter)func_set_dict},
 	{"__name__", (getter)func_get_name, (setter)func_set_name},
+	{"__iscofunction__", (getter)func_get_iscofunction},
 	{NULL} /* Sentinel */
 };
 
@@ -568,7 +577,9 @@
 static PyObject*
 func_repr(PyFunctionObject *op)
 {
-	return PyUnicode_FromFormat("<function %U at %p>",
+	PyCodeObject *code = (PyCodeObject*)op->func_code;
+	const char *co = (code->co_flags & CO_COFUNCTION) ? "co" : "";
+	return PyUnicode_FromFormat("<%sfunction %U at %p>", co,
 				   op->func_name, op);
 }
 
@@ -589,13 +600,26 @@
 }
 
 static PyObject *
-function_call(PyObject *func, PyObject *arg, PyObject *kw)
+function_call_or_cocall(PyObject *func, PyObject *arg, PyObject *kw, int is_cocall)
 {
+	PyCodeObject *code = (PyCodeObject *)PyFunction_GET_CODE(func);
 	PyObject *result;
 	PyObject *argdefs;
 	PyObject *kwtuple = NULL;
 	PyObject **d, **k;
 	Py_ssize_t nk, nd;
+	
+	if (((code->co_flags & CO_COFUNCTION) != 0) != is_cocall) {
+		if (is_cocall) {
+			Py_INCREF(Py_NotImplemented);
+			return Py_NotImplemented;
+		}
+		else {
+			PyErr_SetString(PyExc_TypeError,
+				"Cofunction can only be called from another cofunction or using costart");
+			return 0;
+		}
+	}
 
 	argdefs = PyFunction_GET_DEFAULTS(func);
 	if (argdefs != NULL && PyTuple_Check(argdefs)) {
@@ -628,7 +652,7 @@
 	}
 
 	result = PyEval_EvalCodeEx(
-		(PyCodeObject *)PyFunction_GET_CODE(func),
+		code,
 		PyFunction_GET_GLOBALS(func), (PyObject *)NULL,
 		&PyTuple_GET_ITEM(arg, 0), PyTuple_GET_SIZE(arg),
 		k, nk, d, nd,
@@ -640,6 +664,18 @@
 	return result;
 }
 
+static PyObject *
+function_call(PyObject *func, PyObject *arg, PyObject *kw)
+{
+	return function_call_or_cocall(func, arg, kw, 0);
+}
+
+static PyObject *
+function_cocall(PyObject *func, PyObject *arg, PyObject *kw)
+{
+	return function_call_or_cocall(func, arg, kw, 1);
+}
+
 /* Bind a function to an object */
 static PyObject *
 func_descr_get(PyObject *func, PyObject *obj, PyObject *type)
@@ -660,7 +696,7 @@
 	0,					/* tp_print */
 	0,					/* tp_getattr */
 	0,					/* tp_setattr */
-	0,					/* tp_reserved */
+	function_cocall,			/* tp_cocall */
 	(reprfunc)func_repr,			/* tp_repr */
 	0,					/* tp_as_number */
 	0,					/* tp_as_sequence */
diff -r 8efb09a13529 -r adfab67acffa Objects/object.c
--- a/Objects/object.c	Sat Aug 07 16:01:53 2010 +1200
+++ b/Objects/object.c	Wed Oct 26 20:29:15 2011 +1300
@@ -1150,6 +1150,24 @@
 	return x->ob_type->tp_call != NULL;
 }
 
+/* Call a cofunction, returning a generator */
+
+PyObject *
+PyObject_CoCall(PyObject *func, PyObject *args, PyObject *kw) {
+	PyTypeObject *type = Py_TYPE(func);
+	PyObject *result = NULL;
+	if (type->tp_cocall) {
+		result = type->tp_cocall(func, args, kw);
+		if (result != Py_NotImplemented)
+			return result;
+	}
+	Py_XDECREF(result);
+	PyErr_Format(PyExc_TypeError,
+		"Object of type '%s' does not support cocall",
+		type->tp_name);
+	return NULL;
+}
+
 /* ------------------------- PyObject_Dir() helpers ------------------------- */
 
 /* Helper for PyObject_Dir.
diff -r 8efb09a13529 -r adfab67acffa Objects/typeobject.c
--- a/Objects/typeobject.c	Sat Aug 07 16:01:53 2010 +1200
+++ b/Objects/typeobject.c	Wed Oct 26 20:29:15 2011 +1300
@@ -3659,7 +3659,7 @@
 		type->tp_setattr = base->tp_setattr;
 		type->tp_setattro = base->tp_setattro;
 	}
-	/* tp_reserved is ignored */
+	COPYSLOT(tp_cocall);
 	COPYSLOT(tp_repr);
 	/* tp_hash see tp_richcompare */
 	COPYSLOT(tp_call);
@@ -3883,9 +3883,9 @@
 			goto error;
 	}
 
-	/* Warn for a type that implements tp_compare (now known as
-	   tp_reserved) but not tp_richcompare. */
-	if (type->tp_reserved && !type->tp_richcompare) {
+	/* Warn for a type that implements tp_compare (now used for
+	   tp_cocall) but not tp_richcompare. */
+	if (!(type->tp_flags & Py_TPFLAGS_COCALL) && type->tp_cocall && !type->tp_richcompare) {
 		int error;
 		char msg[240];
 		PyOS_snprintf(msg, sizeof(msg),
@@ -4948,6 +4948,22 @@
 	return res;
 }
 
+static PyObject *
+slot_tp_cocall(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	static PyObject *call_str;
+	PyObject *meth = lookup_method(self, "__cocall__", &call_str);
+	PyObject *res;
+
+	if (meth == NULL)
+		return NULL;
+
+	res = PyObject_Call(meth, args, kwds);
+
+	Py_DECREF(meth);
+	return res;
+}
+
 /* There are two slot dispatch functions for tp_getattro.
 
    - slot_tp_getattro() is used when __getattribute__ is overridden
@@ -5492,6 +5508,8 @@
 	       "x.__hash__() <==> hash(x)"),
 	FLSLOT("__call__", tp_call, slot_tp_call, (wrapperfunc)wrap_call,
 	       "x.__call__(...) <==> x(...)", PyWrapperFlag_KEYWORDS),
+	FLSLOT("__cocall__", tp_cocall, slot_tp_cocall, (wrapperfunc)wrap_call,
+	       "x.__cocall__(...) <==> costart(x, ...)", PyWrapperFlag_KEYWORDS),
 	TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook,
 	       wrap_binaryfunc, "x.__getattribute__('name') <==> x.name"),
 	TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""),
diff -r 8efb09a13529 -r adfab67acffa Parser/Python.asdl
--- a/Parser/Python.asdl	Sat Aug 07 16:01:53 2010 +1200
+++ b/Parser/Python.asdl	Wed Oct 26 20:29:15 2011 +1300
@@ -9,7 +9,7 @@
 	    -- not really an actual node but useful in Jython's typesystem.
 	    | Suite(stmt* body)
 
-	stmt = FunctionDef(identifier name, arguments args, 
+	stmt = FunctionDef(int is_cofunction, identifier name, arguments args, 
                            stmt* body, expr* decorator_list, expr? returns)
 	      | ClassDef(identifier name, 
 			 expr* bases,
@@ -65,7 +65,7 @@
 	     -- x < 4 < 3 and (x < 4) < 3
 	     | Compare(expr left, cmpop* ops, expr* comparators)
 	     | Call(expr func, expr* args, keyword* keywords,
-			 expr? starargs, expr? kwargs)
+		expr? starargs, expr? kwargs)
 	     | Num(object n) -- a number as a PyObject.
 	     | Str(string s) -- need to specify raw, unicode, etc?
 	     | Bytes(string s)
diff -r 8efb09a13529 -r adfab67acffa Python/ast.c
--- a/Python/ast.c	Sat Aug 07 16:01:53 2010 +1200
+++ b/Python/ast.c	Wed Oct 26 20:29:15 2011 +1300
@@ -984,7 +984,7 @@
 }
 
 static stmt_ty
-ast_for_funcdef(struct compiling *c, const node *n, asdl_seq *decorator_seq)
+ast_for_funcdef(struct compiling *c, const node *n, asdl_seq *decorator_seq, int is_cofunction)
 {
     /* funcdef: 'def' NAME parameters ['->' test] ':' suite */
     identifier name;
@@ -993,7 +993,7 @@
     expr_ty returns = NULL;
     int name_i = 1;
 
-    REQ(n, funcdef);
+    REQ(n, is_cofunction ? cofuncdef : funcdef);
 
     name = NEW_IDENTIFIER(CHILD(n, name_i));
     if (!name)
@@ -1011,7 +1011,7 @@
     if (!body)
         return NULL;
 
-    return FunctionDef(name, args, body, decorator_seq, returns, LINENO(n),
+    return FunctionDef(is_cofunction, name, args, body, decorator_seq, returns, LINENO(n),
                        n->n_col_offset, c->c_arena);
 }
 
@@ -1032,7 +1032,9 @@
 	   TYPE(CHILD(n, 1)) == classdef);
 
     if (TYPE(CHILD(n, 1)) == funcdef) {
-      thing = ast_for_funcdef(c, CHILD(n, 1), decorator_seq);
+      thing = ast_for_funcdef(c, CHILD(n, 1), decorator_seq, 0);
+    } else if (TYPE(CHILD(n, 1)) == cofuncdef) {
+      thing = ast_for_funcdef(c, CHILD(n, 1), decorator_seq, 1);
     } else if (TYPE(CHILD(n, 1)) == classdef) {
       thing = ast_for_classdef(c, CHILD(n, 1), decorator_seq);
     }
@@ -3137,7 +3139,9 @@
             case with_stmt:
                 return ast_for_with_stmt(c, ch);
             case funcdef:
-                return ast_for_funcdef(c, ch, NULL);
+                return ast_for_funcdef(c, ch, NULL, 0);
+            case cofuncdef:
+                return ast_for_funcdef(c, ch, NULL, 1);
             case classdef:
                 return ast_for_classdef(c, ch, NULL);
 	    case decorated:
diff -r 8efb09a13529 -r adfab67acffa Python/bltinmodule.c
--- a/Python/bltinmodule.c	Sat Aug 07 16:01:53 2010 +1200
+++ b/Python/bltinmodule.c	Wed Oct 26 20:29:15 2011 +1300
@@ -2032,6 +2032,37 @@
 is a shortcut for issubclass(X, A) or issubclass(X, B) or ... (etc.).");
 
 
+static PyObject *
+builtin_costart(PyObject *self, PyObject *args, PyObject *kw)
+{
+	int n = PyTuple_GET_SIZE(args);
+	PyObject *cofunc; /* borrowed from args */
+	PyObject *coargs = 0;
+	PyObject *result = 0;
+	
+	if (n < 1) {
+		PyErr_SetString(PyExc_TypeError, "Too few arguments to 'costart'");
+		goto bad;
+	}
+	cofunc = PyTuple_GET_ITEM(args, 0);
+	coargs = PyTuple_GetSlice(args, 1, n);
+	if (!coargs)
+		goto bad;
+	result = PyObject_CoCall(cofunc, coargs, kw);
+bad:
+	Py_XDECREF(coargs);
+	return result;
+}
+
+PyDoc_STRVAR(costart_doc,
+"costart(cofunc, ...) -> generator\n\
+\n\
+Starts a cofunction by calling its __cocall__ method and passing along any\n\
+other supplied arguments. If cofunc is a function defined using the 'codef'\n\
+keyword, the result is a generator object. Other objects implementing\n\
+__cocall__ are expected to return an object obeying the iterator protocol.");
+
+
 typedef struct {
 	PyObject_HEAD
 	Py_ssize_t	tuplesize;
@@ -2220,6 +2251,7 @@
 	{"bin",		builtin_bin,	    METH_O, bin_doc},
  	{"chr",		builtin_chr,        METH_VARARGS, chr_doc},
  	{"compile",	(PyCFunction)builtin_compile,    METH_VARARGS | METH_KEYWORDS, compile_doc},
+	{"costart",	(PyCFunction)builtin_costart,    METH_VARARGS | METH_KEYWORDS, costart_doc},
  	{"delattr",	builtin_delattr,    METH_VARARGS, delattr_doc},
  	{"dir",		builtin_dir,        METH_VARARGS, dir_doc},
  	{"divmod",	builtin_divmod,     METH_VARARGS, divmod_doc},
diff -r 8efb09a13529 -r adfab67acffa Python/ceval.c
--- a/Python/ceval.c	Sat Aug 07 16:01:53 2010 +1200
+++ b/Python/ceval.c	Wed Oct 26 20:29:15 2011 +1300
@@ -111,13 +111,11 @@
 #endif
 static PyObject * fast_function(PyObject *, PyObject ***, int, int, int);
 static PyObject * do_call(PyObject *, PyObject ***, int, int);
-static PyObject * ext_do_call(PyObject *, PyObject ***, int, int, int);
+static PyObject * ext_do_call(PyObject *, PyObject ***, int, int, int, int *);
 static PyObject * update_keyword_args(PyObject *, int, PyObject ***,
 				      PyObject *);
 static PyObject * update_star_args(int, int, PyObject *, PyObject ***);
 static PyObject * load_args(PyObject ***, int);
-#define CALL_FLAG_VAR 1
-#define CALL_FLAG_KW 2
 
 #ifdef LLTRACE
 static int lltrace;
@@ -1799,6 +1797,7 @@
 			u = POP();
 			x = PyObject_GetIter(u);
 			Py_DECREF(u);
+		yield_from_x:
 			if (!x)
 				break;
 			/* x is now the iterator, make the first next() call */
@@ -2579,6 +2578,11 @@
 		TARGET(CALL_FUNCTION)
 		{
 			PyObject **sp;
+			
+			/* Skip fast path in cofunction for now */
+			if (co->co_flags & CO_COFUNCTION)
+				goto _call_function_var_kw;
+				
 			PCALL(PCALL_ALL);
 			sp = stack_pointer;
 #ifdef WITH_TSC
@@ -2603,6 +2607,8 @@
 		    int flags = (opcode - CALL_FUNCTION) & 3;
 		    int n = na + 2 * nk;
 		    PyObject **pfunc, *func, **sp;
+		    int cocall = co->co_flags & CO_COFUNCTION;
+		    
 		    PCALL(PCALL_ALL);
 		    if (flags & CALL_FLAG_VAR)
 			    n++;
@@ -2625,7 +2631,7 @@
 			    Py_INCREF(func);
 		    sp = stack_pointer;
 		    READ_TIMESTAMP(intr0);
-		    x = ext_do_call(func, &sp, flags, na, nk);
+		    x = ext_do_call(func, &sp, flags, na, nk, &cocall);
 		    READ_TIMESTAMP(intr1);
 		    stack_pointer = sp;
 		    Py_DECREF(func);
@@ -2634,6 +2640,10 @@
 			    w = POP();
 			    Py_DECREF(w);
 		    }
+		    if (cocall) {
+		    	f->f_lasti = INSTR_OFFSET() - 1;
+		    	goto yield_from_x;
+		    }
 		    PUSH(x);
 		    if (x != NULL)
 			    DISPATCH();
@@ -3818,7 +3828,7 @@
 		} else
 			Py_INCREF(func);
 		READ_TIMESTAMP(*pintr0);
-		if (PyFunction_Check(func))
+		if (PyFunction_Check(func) && !PyFunction_IS_COFUNCTION(func))
 			x = fast_function(func, pp_stack, n, na, nk);
 		else
 			x = do_call(func, pp_stack, na, nk);
@@ -4025,8 +4035,26 @@
 	return result;
 }
 
+/* If object implements __cocall__, perform cocall, otherwise normal call.
+   Returns a boolean in 'cocall' indicating whether a cocall was made. */
+
 static PyObject *
-ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk)
+do_call_or_cocall(PyObject *func, PyObject *args, PyObject *kw, int *cocall) {
+	PyTypeObject *type = Py_TYPE(func);
+	PyObject *result;
+	if (type->tp_cocall) {
+		result = type->tp_cocall(func, args, kw);
+		if (result != Py_NotImplemented) {
+			*cocall = 1;
+			return result;
+		}
+	}
+	*cocall = 0;
+	return PyObject_Call(func, args, kw);
+}
+
+static PyObject *
+ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk, int *cocall)
 {
 	int nstar = 0;
 	PyObject *callargs = NULL;
@@ -4108,7 +4136,9 @@
 	else
 		PCALL(PCALL_OTHER);
 #endif
-	if (PyCFunction_Check(func)) {
+	if (*cocall)
+		result = do_call_or_cocall(func, callargs, kwdict, cocall);
+	else if (PyCFunction_Check(func)) {
 		PyThreadState *tstate = PyThreadState_GET();
 		C_TRACE(result, PyCFunction_Call(func, callargs, kwdict));
 	}
diff -r 8efb09a13529 -r adfab67acffa Python/compile.c
--- a/Python/compile.c	Sat Aug 07 16:01:53 2010 +1200
+++ b/Python/compile.c	Wed Oct 26 20:29:15 2011 +1300
@@ -1478,6 +1478,10 @@
 				  s->lineno))
 		return 0;
 
+	if (s->v.FunctionDef.is_cofunction) {
+		c->u->u_ste->ste_generator = 1;
+		c->u->u_ste->ste_cofunction = 1;
+	}
 	st = (stmt_ty)asdl_seq_GET(s->v.FunctionDef.body, 0);
 	docstring = compiler_isdocstring(st);
 	if (docstring && Py_OptimizeFlag < 2)
@@ -2738,6 +2742,13 @@
 				    e->v.Call.kwargs);
 }
 
+static int call_ops[8] = {
+	CALL_FUNCTION,
+	CALL_FUNCTION_VAR,
+	CALL_FUNCTION_KW,
+	CALL_FUNCTION_VAR_KW,
+};
+
 /* shared code between compiler_call and compiler_class */
 static int
 compiler_call_helper(struct compiler *c,
@@ -2757,26 +2768,13 @@
 	}
 	if (starargs) {
 		VISIT(c, expr, starargs);
-		code |= 1;
+		code |= CALL_FLAG_VAR;
 	}
 	if (kwargs) {
 		VISIT(c, expr, kwargs);
-		code |= 2;
+		code |= CALL_FLAG_KW;
 	}
-	switch (code) {
-	case 0:
-		ADDOP_I(c, CALL_FUNCTION, n);
-		break;
-	case 1:
-		ADDOP_I(c, CALL_FUNCTION_VAR, n);
-		break;
-	case 2:
-		ADDOP_I(c, CALL_FUNCTION_KW, n);
-		break;
-	case 3:
-		ADDOP_I(c, CALL_FUNCTION_VAR_KW, n);
-		break;
-	}
+	ADDOP_I(c, call_ops[code], n);
 	return 1;
 }
 
@@ -3996,6 +3994,8 @@
 			flags |= CO_NESTED;
 		if (ste->ste_generator)
 			flags |= CO_GENERATOR;
+		if (ste->ste_cofunction)
+			flags |= CO_COFUNCTION;
 		if (ste->ste_varargs)
 			flags |= CO_VARARGS;
 		if (ste->ste_varkeywords)
diff -r 8efb09a13529 -r adfab67acffa Python/symtable.c
--- a/Python/symtable.c	Sat Aug 07 16:01:53 2010 +1200
+++ b/Python/symtable.c	Wed Oct 26 20:29:15 2011 +1300
@@ -75,6 +75,7 @@
 		ste->ste_nested = 1;
 	ste->ste_child_free = 0;
 	ste->ste_generator = 0;
+	ste->ste_cofunction = 0;
 	ste->ste_returns_value = 0;
 
 	if (PyDict_SetItem(st->st_blocks, ste->ste_id, (PyObject *)ste) < 0)
