diff -r 7356f71fb0a4 Lib/test/test_types.py --- a/Lib/test/test_types.py Fri May 29 09:06:05 2015 -0400 +++ b/Lib/test/test_types.py Fri May 29 12:20:40 2015 -0400 @@ -1233,9 +1233,6 @@ def gen(): yield - self.assertFalse(isinstance(gen(), collections.abc.Coroutine)) - self.assertFalse(isinstance(gen(), collections.abc.Awaitable)) - self.assertIs(types.coroutine(gen), gen) self.assertTrue(gen.__code__.co_flags & inspect.CO_ITERABLE_COROUTINE) diff -r 7356f71fb0a4 Lib/types.py --- a/Lib/types.py Fri May 29 09:06:05 2015 -0400 +++ b/Lib/types.py Fri May 29 12:20:40 2015 -0400 @@ -160,33 +160,21 @@ import functools as _functools import collections.abc as _collections_abc +import _types def coroutine(func): """Convert regular generator function to a coroutine.""" - # We don't want to import 'dis' or 'inspect' just for - # these constants. - _CO_GENERATOR = 0x20 - _CO_ITERABLE_COROUTINE = 0x100 - if not callable(func): raise TypeError('types.coroutine() expects a callable') - if (isinstance(func, FunctionType) and - isinstance(getattr(func, '__code__', None), CodeType) and - (func.__code__.co_flags & _CO_GENERATOR)): - - # TODO: Implement this in C. - co = func.__code__ - func.__code__ = CodeType( - co.co_argcount, co.co_kwonlyargcount, co.co_nlocals, - co.co_stacksize, - co.co_flags | _CO_ITERABLE_COROUTINE, - co.co_code, - co.co_consts, co.co_names, co.co_varnames, co.co_filename, - co.co_name, co.co_firstlineno, co.co_lnotab, co.co_freevars, - co.co_cellvars) - return func + if func.__class__ is FunctionType: + try: + _types._coroutine(func) + except TypeError: + pass + else: + return func @_functools.wraps(func) def wrapped(*args, **kwargs): diff -r 7356f71fb0a4 Modules/Setup.dist --- a/Modules/Setup.dist Fri May 29 09:06:05 2015 -0400 +++ b/Modules/Setup.dist Fri May 29 12:20:40 2015 -0400 @@ -119,6 +119,7 @@ atexit atexitmodule.c # Register functions to be run at interpreter-shutdown _stat _stat.c # stat.h interface time timemodule.c # -lm # time operations and variables +_types _typesmodule.c # Types module speedups # access to ISO C locale support _locale _localemodule.c # -lintl diff -r 7356f71fb0a4 Modules/_typesmodule.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modules/_typesmodule.c Fri May 29 12:20:40 2015 -0400 @@ -0,0 +1,59 @@ +/* Helpers for types module. */ + +#include "Python.h" + +static PyObject * +types_coroutine(PyObject *self, PyObject *func) +{ + PyCodeObject *func_code; + + if (!PyFunction_Check(func)) { + PyErr_Format(PyExc_TypeError, + "callable expected, got %.50s", + Py_TYPE(func)->tp_name); + return NULL; + } + + func_code = (PyCodeObject *)PyFunction_GET_CODE(func); + + if (!(func_code->co_flags & CO_GENERATOR)) { + PyErr_SetString(PyExc_TypeError, + "generator function expected"); + return NULL; + } + + func_code->co_flags |= CO_ITERABLE_COROUTINE; + Py_RETURN_NONE; +} + +PyDoc_STRVAR(types_coroutine_doc, +"_coroutine(func) -> None\n\ +\n\ +Applies CO_ITERABLE_COROUTINE to generator functions code object.\n\ +This is an internal helper for types.coroutine(), do not use this \n\ +function directly.\n"); + +static PyMethodDef types_methods[] = { + {"_coroutine", types_coroutine, METH_O, types_coroutine_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyDoc_STRVAR(module_doc, "Helpers for types module.\n"); + +static struct PyModuleDef _typesmodule = { + PyModuleDef_HEAD_INIT, + "_types", + module_doc, + -1, + types_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__types(void) +{ + return PyModule_Create(&_typesmodule); +} diff -r 7356f71fb0a4 PC/config.c --- a/PC/config.c Fri May 29 09:06:05 2015 -0400 +++ b/PC/config.c Fri May 29 12:20:40 2015 -0400 @@ -38,6 +38,7 @@ extern PyObject* PyInit__collections(void); extern PyObject* PyInit__heapq(void); extern PyObject* PyInit__bisect(void); +extern PyObject* PyInit__types(void); extern PyObject* PyInit__symtable(void); extern PyObject* PyInit_mmap(void); extern PyObject* PyInit__csv(void); @@ -117,6 +118,7 @@ {"itertools", PyInit_itertools}, {"_collections", PyInit__collections}, {"_symtable", PyInit__symtable}, + {"_types", PyInit__types}, {"mmap", PyInit_mmap}, {"_csv", PyInit__csv}, {"_sre", PyInit__sre}, diff -r 7356f71fb0a4 PCbuild/pythoncore.vcxproj --- a/PCbuild/pythoncore.vcxproj Fri May 29 09:06:05 2015 -0400 +++ b/PCbuild/pythoncore.vcxproj Fri May 29 12:20:40 2015 -0400 @@ -227,6 +227,7 @@ + @@ -415,4 +416,4 @@ - \ No newline at end of file + diff -r 7356f71fb0a4 PCbuild/pythoncore.vcxproj.filters --- a/PCbuild/pythoncore.vcxproj.filters Fri May 29 09:06:05 2015 -0400 +++ b/PCbuild/pythoncore.vcxproj.filters Fri May 29 12:20:40 2015 -0400 @@ -473,6 +473,9 @@ Modules + + Modules + Modules @@ -974,4 +977,4 @@ Resource Files - \ No newline at end of file +