-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
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__); | ||||||
|
||||||
| # As `isinstance(Mock(), Future)` returns `False` | |
| self.assertFalse(asyncio.isfuture(mock.Mock())) |
Do we really want to use Future_CheckExact to return fast?
Outdated
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.
It is better to use Py_TYPE() for convenience and speed . There is a subtle difference between the type and the __class__ attribute, but it is usually ignored when write C accelerations.
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.
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 comment
The reason will be displayed to describe this comment to others. Learn more.
I suggested to use Py_TYPE as well.
I think it was I who used __class__ there, and there's no rationale behind that :)
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.
So the Python version can be updated to use type() too.
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.
@1st1 @serhiy-storchaka
use type() won't work.
Original isfuture: return (hasattr(obj.__class__, '_asyncio_future_blocking') and obj._asyncio_future_blocking is not None)
Use type: return (hasattr(type(obj), '_asyncio_future_blocking') and obj._asyncio_future_blocking is not None)
Unit tests fail when use type()
Did I use type() wrong?
======================================================================
FAIL: test_isfuture (test.test_asyncio.test_futures.CFutureTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/jimmylai/workspace/cpython/Lib/test/test_asyncio/test_futures.py", line 131, in test_isfuture
self.assertTrue(asyncio.isfuture(mock.Mock(type(f))))
AssertionError: False is not true
======================================================================
FAIL: test_isfuture (test.test_asyncio.test_futures.CSubFutureTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/jimmylai/workspace/cpython/Lib/test/test_asyncio/test_futures.py", line 131, in test_isfuture
self.assertTrue(asyncio.isfuture(mock.Mock(type(f))))
AssertionError: False is not true
======================================================================
FAIL: test_isfuture (test.test_asyncio.test_futures.PyFutureTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/jimmylai/workspace/cpython/Lib/test/test_asyncio/test_futures.py", line 131, in test_isfuture
self.assertTrue(asyncio.isfuture(mock.Mock(type(f))))
AssertionError: False is not true
Outdated
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.
Is it needed?
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.
class may not have attr _asyncio_future_blocking
It's needed.
Outdated
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.
obj_attr is leaked here.
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.
added Py_DECREF(obj_attr);
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.