diff -r 4c1d543135ef Include/methodobject.h --- a/Include/methodobject.h Thu Jul 31 23:58:27 2014 -0500 +++ b/Include/methodobject.h Sat Aug 02 20:41:03 2014 +0800 @@ -77,6 +77,7 @@ PyMethodDef *m_ml; /* Description of the C function to call */ PyObject *m_self; /* Passed as 'self' arg to the C func, can be NULL */ PyObject *m_module; /* The __module__ attribute, can be anything */ + PyObject *m_weakreflist; /* List of weak references */ } PyCFunctionObject; #endif diff -r 4c1d543135ef Lib/test/test_sys.py --- a/Lib/test/test_sys.py Thu Jul 31 23:58:27 2014 -0500 +++ b/Lib/test/test_sys.py Sat Aug 02 20:41:03 2014 +0800 @@ -784,7 +784,7 @@ # buffer # XXX # builtin_function_or_method - check(len, size('3P')) # XXX check layout + check(len, size('4P')) # XXX check layout # bytearray samples = [b'', b'u'*100000] for sample in samples: diff -r 4c1d543135ef Lib/test/test_weakref.py --- a/Lib/test/test_weakref.py Thu Jul 31 23:58:27 2014 -0500 +++ b/Lib/test/test_weakref.py Sat Aug 02 20:41:03 2014 +0800 @@ -92,6 +92,18 @@ self.check_basic_callback(create_function) self.check_basic_callback(create_bound_method) + @support.cpython_only + def test_cfunction(self): + import _testcapi + create_cfunction = _testcapi.create_cfunction + f = create_cfunction() + wr = weakref.ref(f) + self.assertIs(wr(), f) + del f + self.assertIsNone(wr()) + self.check_basic_ref(create_cfunction) + self.check_basic_callback(create_cfunction) + def test_multiple_callbacks(self): o = C() ref1 = weakref.ref(o, self.callback) diff -r 4c1d543135ef Modules/_testcapimodule.c --- a/Modules/_testcapimodule.c Thu Jul 31 23:58:27 2014 -0500 +++ b/Modules/_testcapimodule.c Sat Aug 02 20:41:03 2014 +0800 @@ -2653,6 +2653,21 @@ return obj; } +static PyMethodDef ml; + +static PyObject * +create_cfunction(PyObject *self, PyObject *args) +{ + return PyCFunction_NewEx(&ml, self, NULL); +} + +static PyMethodDef ml = { + "create_cfunction", + create_cfunction, + METH_NOARGS, + NULL +}; + static PyObject * _test_incref(PyObject *ob) { @@ -3186,6 +3201,7 @@ {"pytime_object_to_timeval", test_pytime_object_to_timeval, METH_VARARGS}, {"pytime_object_to_timespec", test_pytime_object_to_timespec, METH_VARARGS}, {"with_tp_del", with_tp_del, METH_VARARGS}, + {"create_cfunction", create_cfunction, METH_NOARGS}, {"test_pymem_alloc0", (PyCFunction)test_pymem_alloc0, METH_NOARGS}, {"test_pymem_setrawallocators", diff -r 4c1d543135ef Objects/methodobject.c --- a/Objects/methodobject.c Thu Jul 31 23:58:27 2014 -0500 +++ b/Objects/methodobject.c Sat Aug 02 20:41:03 2014 +0800 @@ -37,6 +37,7 @@ if (op == NULL) return NULL; } + op->m_weakreflist = NULL; op->m_ml = ml; Py_XINCREF(self); op->m_self = self; @@ -147,6 +148,9 @@ meth_dealloc(PyCFunctionObject *m) { _PyObject_GC_UNTRACK(m); + if (m->m_weakreflist != NULL) { + PyObject_ClearWeakRefs((PyObject*) m); + } Py_XDECREF(m->m_self); Py_XDECREF(m->m_module); if (numfree < PyCFunction_MAXFREELIST) { @@ -352,7 +356,7 @@ (traverseproc)meth_traverse, /* tp_traverse */ 0, /* tp_clear */ meth_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ + offsetof(PyCFunctionObject, m_weakreflist), /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ meth_methods, /* tp_methods */

AltStyle によって変換されたページ (->オリジナル) /