-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
bpo-33521: Add 1.32x faster C implementation of asyncio.isfuture(). #6876
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Add 1.32x faster C implementation of asyncio.isfuture(). |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -193,6 +193,51 @@ is_coroutine(PyObject *coro) | |||||
return has_it; | ||||||
} | ||||||
|
||||||
/*[clinic input] | ||||||
_asyncio.isfuture | ||||||
|
||||||
obj: object | ||||||
/ | ||||||
|
||||||
Return True if obj is a Future instance. | ||||||
|
||||||
This returns True when obj is a Future instance or is advertising | ||||||
itself as duck-type compatible by setting _asyncio_future_blocking. | ||||||
See comment in Future for more details. | ||||||
|
||||||
[clinic start generated code]*/ | ||||||
|
||||||
static PyObject * | ||||||
_asyncio_isfuture(PyObject *module, PyObject *obj) | ||||||
/*[clinic end generated code: output=3c79d083f507d4fa input=a71fdef4d9b354b4]*/ | ||||||
{ | ||||||
_Py_IDENTIFIER(__class__); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good idea. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @asvetlov @1st1 isfuture check if _asyncio_future_blocking exists and is not None because mock object has _asyncio_future_blocking as None and we want to return isfuture() as False in this case. cpython/Lib/test/test_asyncio/test_futures.py Lines 123 to 124 in 8425de4
Do we really want to use Future_CheckExact to return fast? |
||||||
PyObject* class = _PyObject_GetAttrId(obj, &PyId___class__); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is better to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggested to @jimmylai to get the class attribute to make sure that the C implementation behaves as the Python implementation: see PEP 399. If someone wants to use type(), I would prefer to see the same change in the Python implementation as well. @1st1, @asvetlov: Do you know the rationale for checking class here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggested to use I think it was I who used There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So the Python version can be updated to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @1st1 @serhiy-storchaka Use type: Unit tests fail when use type()
|
||||||
if (class == NULL) { | ||||||
return NULL; | ||||||
} | ||||||
_Py_IDENTIFIER(_asyncio_future_blocking); | ||||||
int class_has_attr = _PyObject_HasAttrId( | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it needed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. class may not have attr _asyncio_future_blocking |
||||||
class, &PyId__asyncio_future_blocking); | ||||||
Py_DECREF(class); | ||||||
if (class_has_attr < 0) { | ||||||
return NULL; | ||||||
} | ||||||
if (!class_has_attr) { | ||||||
Py_RETURN_FALSE; | ||||||
} | ||||||
PyObject* obj_attr = _PyObject_GetAttrId(obj, &PyId__asyncio_future_blocking); | ||||||
if (obj_attr == NULL) { | ||||||
return NULL; | ||||||
} | ||||||
if (obj_attr != Py_None) { | ||||||
Py_DECREF(obj_attr); | ||||||
Py_RETURN_TRUE; | ||||||
} | ||||||
Py_DECREF(obj_attr); | ||||||
Py_RETURN_FALSE; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. obj_attr is leaked here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added Py_DECREF(obj_attr); |
||||||
} | ||||||
|
||||||
|
||||||
static PyObject * | ||||||
get_future_loop(PyObject *fut) | ||||||
|
@@ -3276,6 +3321,7 @@ PyDoc_STRVAR(module_doc, "Accelerator module for asyncio"); | |||||
|
||||||
static PyMethodDef asyncio_methods[] = { | ||||||
_ASYNCIO_GET_EVENT_LOOP_METHODDEF | ||||||
_ASYNCIO_ISFUTURE_METHODDEF | ||||||
_ASYNCIO_GET_RUNNING_LOOP_METHODDEF | ||||||
_ASYNCIO__GET_RUNNING_LOOP_METHODDEF | ||||||
_ASYNCIO__SET_RUNNING_LOOP_METHODDEF | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make the argument positional-only.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In pratice, it means adding "/" on a new line, aligned with "obj", and run "make clinic" again.