should accept a single parameter, which will be the weak reference object
itself. *callback* may also be ``None`` or ``NULL``. If *ob* is not a
weakly referenceable object, or if *callback* is not callable, ``None``, or
- ``NULL``, this will return ``NULL`` and raise :exc:`TypeError`.
+ ``NULL``, this will raise :exc:`TypeError` and return ``NULL``.
+
+ .. versionchanged:: next
+ Raise :exc:`!TypeError` if *callback* is not callable, ``None``, or
+ ``NULL``.
.. seealso::
:c:func:`PyType_SUPPORTS_WEAKREFS` for checking if *ob* is weakly
collected; it should accept a single parameter, which will be the weak
reference object itself. *callback* may also be ``None`` or ``NULL``. If *ob*
is not a weakly referenceable object, or if *callback* is not callable,
- ``None``, or ``NULL``, this will return ``NULL`` and raise :exc:`TypeError`.
+ ``NULL``, this will raise :exc:`TypeError` and return ``NULL``.
+
+ .. versionchanged:: next
+ Raise :exc:`!TypeError` if *callback* is not callable, ``None``, or
+ ``NULL``.
.. seealso::
:c:func:`PyType_SUPPORTS_WEAKREFS` for checking if *ob* is weakly
.. versionchanged:: 3.4
Added the :attr:`__callback__` attribute.
+ .. versionchanged:: next
+ Raise :exc:`!TypeError` if *callback* is not callable or ``None``.
+
.. function:: proxy(object[, callback])
Extended the operator support on proxy objects to include the matrix
multiplication operators ``@`` and ``@=``.
+ .. versionchanged:: next
+ Raise :exc:`!TypeError` if *callback* is not callable or ``None``.
+
.. function:: getweakrefcount(object)
# PyWeakref_NewRef() handles None callback as NULL callback
wr = newref(obj, None)
self.assertIs(type(wr), weakref.ReferenceType)
+ self.assertRaises(TypeError, newref, obj, 42)
log = []
wr = newref(obj, log.append)
self.assertIs(type(wr), weakref.ReferenceType)
# PyWeakref_NewProxy() handles None callback as NULL callback
wp = newproxy(obj, None)
self.assertIs(type(wp), weakref.ProxyType)
+ self.assertRaises(TypeError, newproxy, obj, 42)
log = []
wp = newproxy(obj, log.append)
self.assertIs(type(wp), weakref.ProxyType)
sys.setrecursionlimit(15)
def f():
- ref(lambda: 0, [])
+ ref(lambda: 0, ord)
f()
try:
self.check_basic_callback(create_function)
self.check_basic_callback(create_bound_method)
+ def test_non_callable_callback(self):
+ c = C()
+ self.assertRaises(TypeError, weakref.ref, c, 42)
+ self.assertRaises(TypeError, weakref.proxy, c, 42)
+
@support.cpython_only
def test_cfunction(self):
_testcapi = import_helper.import_module("_testcapi")
--- /dev/null
+:c:func:`PyWeakref_NewRef` and :c:func:`PyWeakref_NewProxy` now raise
+:exc:`TypeError` if the *callback* argument is not callable, ``None``, or
+``NULL``.
--- /dev/null
+:func:`weakref.ref` and :func:`weakref.proxy` now raise :exc:`TypeError` if
+the *callback* argument is not callable or ``None``.
Py_TYPE(obj)->tp_name);
return NULL;
}
- if (callback == Py_None)
+ if (callback == Py_None) {
callback = NULL;
+ }
+ if (callback != NULL && !PyCallable_Check(callback)) {
+ PyErr_Format(PyExc_TypeError,
+ "callback must be callable or None, not '%T'",
+ callback);
+ return NULL;
+ }
PyWeakReference **list = GET_WEAKREFS_LISTPTR(obj);
if ((type == &_PyWeakref_RefType) ||