Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 517c7d4

Browse files
committed
PyNumber_CoerceEx: this took a shortcut (not doing anything) when the
left and right type were of the same type and not classic instances. This shortcut is dangerous for proxy types, because it means that coerce(Proxy(1), Proxy(2.1)) leaves Proxy(1) unchanged rather than turning it into Proxy(1.0). In an ever-so-slight change of semantics, I now only take the shortcut when the left and right types are of the same type and don't have the CHECKTYPES feature. It so happens that classic instances have this flag, so the shortcut is still skipped in this case (i.e. nothing changes for classic instances). Proxies also have this flag set (otherwise implementing numeric operations on proxies would become nightmarish) and this means that the shortcut is also skipped there, as desired. It so happens that int, long and float also have this flag set; that means that e.g. coerce(1, 1) will now invoke int_coerce(). This is fine: int_coerce() can deal with this, and I'm not worried about the performance; int_coerce() is only invoked when the user explicitly calls coerce(), which should be rarer than rare.
1 parent d451ec1 commit 517c7d4

2 files changed

Lines changed: 8 additions & 1 deletion

File tree

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,10 @@ Build
163163

164164
C API
165165

166+
- PyNumber_Coerce() and PyNumber_CoerceEx() now also invoke the type's
167+
coercion if both arguments have the same type but this type has the
168+
CHECKTYPES flag set. This is to better support proxies.
169+
166170
- The type of tp_free has been changed from "void (*)(PyObject *)" to
167171
"void (*)(void *)".
168172

Objects/object.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1427,7 +1427,10 @@ PyNumber_CoerceEx(PyObject **pv, PyObject **pw)
14271427
register PyObject *w = *pw;
14281428
int res;
14291429

1430-
if (v->ob_type == w->ob_type && !PyInstance_Check(v)) {
1430+
/* Shortcut only for old-style types */
1431+
if (v->ob_type == w->ob_type &&
1432+
!PyType_HasFeature(v->ob_type, Py_TPFLAGS_CHECKTYPES))
1433+
{
14311434
Py_INCREF(v);
14321435
Py_INCREF(w);
14331436
return 0;

0 commit comments

Comments
 (0)