diff -r f23533fa6afa Lib/test/test_coroutines.py --- a/Lib/test/test_coroutines.py Thu May 21 20:54:48 2015 +0300 +++ b/Lib/test/test_coroutines.py Thu May 21 15:32:22 2015 -0400 @@ -244,6 +244,21 @@ foo() support.gc_collect() + def test_func_10(self): + async def foo(): pass + self.assertIn("(coroutine)", repr(foo)) + + async def bar(): return foo() + self.assertIn("(closure,coroutine)", repr(bar)) + + @types.coroutine + def baz(): yield + self.assertIn("(generator,coroutine)", repr(baz)) + + @types.coroutine + def bletch(): yield foo() + self.assertIn("(closure,generator,coroutine)", repr(bletch)) + def test_await_1(self): async def foo(): diff -r f23533fa6afa Lib/test/test_generators.py --- a/Lib/test/test_generators.py Thu May 21 20:54:48 2015 +0300 +++ b/Lib/test/test_generators.py Thu May 21 15:32:22 2015 -0400 @@ -108,6 +108,27 @@ self.assertEqual(gen.__qualname__, "GeneratorTest.test_name..") + def test_repr(self): + def func(): + yield 1 + self.assertIn('(generator)', repr(func)) + + def func2(f): + def function(x): + return f(x) + return function + + def func3(i): + yield i + + def func4(f): + def function(x): + yield f(x) + return function + self.assertIn('(closure)', repr(func2(func3))) + self.assertIsNotNone(func2(func3)) + self.assertIn('(closure,generator)', repr(func4(func3))) + class ExceptionTest(unittest.TestCase): # Tests for the issue #23353: check that the currently handled exception diff -r f23533fa6afa Objects/funcobject.c --- a/Objects/funcobject.c Thu May 21 20:54:48 2015 +0300 +++ b/Objects/funcobject.c Thu May 21 15:32:22 2015 -0400 @@ -566,11 +566,50 @@ PyObject_GC_Del(op); } +static char* +func_get_status(PyFunctionObject *op) +{ + static char result[31]; /* len(" (closure,generator,coroutine)") + 1 == 31 */ + PyCodeObject *co; + int init = 0; + + co = (PyCodeObject *)func_get_code(op); + if (op->func_closure != NULL) { + strcpy(result, " (closure"); + init = 1; + } + if (co->co_flags & CO_GENERATOR && !(co->co_flags & CO_COROUTINE)) { + if (init) { + strcat(result, ","); + } + else { + init = 1; + strcpy(result, " ("); + } + strcat(result, "generator"); + } + if (co->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE)) { + if (init) { + strcat(result, ","); + } + else { + init = 1; + strcpy(result, " ("); + } + strcat(result, "coroutine"); + } + if (init) { + strcat(result, ")"); + } + Py_DECREF(co); + return result; +} + static PyObject* func_repr(PyFunctionObject *op) { - return PyUnicode_FromFormat("", - op->func_qualname, op); + return PyUnicode_FromFormat("", + op->func_qualname, op, func_get_status(op)); } static int