Title: `inspect.iscoroutinefunction()` does not detect marked partial objects · Issue #142418 · python/cpython · GitHub
Open Graph Title: `inspect.iscoroutinefunction()` does not detect marked partial objects · Issue #142418 · python/cpython
X Title: `inspect.iscoroutinefunction()` does not detect marked partial objects · Issue #142418 · python/cpython
Description: Bug report Bug description: inspect.markcoroutinefunction() is applied directly to the passed function, except for methods (which is correct behavior). However, inspect.iscoroutinefunction() checks the passed function only after unwrappi...
Open Graph Description: Bug report Bug description: inspect.markcoroutinefunction() is applied directly to the passed function, except for methods (which is correct behavior). However, inspect.iscoroutinefunction() checks...
X Description: Bug report Bug description: inspect.markcoroutinefunction() is applied directly to the passed function, except for methods (which is correct behavior). However, inspect.iscoroutinefunction() checks...
Opengraph URL: https://github.com/python/cpython/issues/142418
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"`inspect.iscoroutinefunction()` does not detect marked partial objects","articleBody":"# Bug report\n\n### Bug description:\n\n`inspect.markcoroutinefunction()` is applied directly to the passed function, except for methods (which is correct behavior). However, `inspect.iscoroutinefunction()` checks the passed function only after unwrapping (a function that is not wrapped in either `functools.partial` or ~~`functools.partialmethod`~~ (currently, `_has_coroutine_mark()` does not handle these objects; [why?](https://github.com/python/cpython/pull/16600))), and thus cannot detect the marker that is not at the end of the unwrapping chain, which results in false negative in cases where a `functools.partial`/~~`functools.partialmethod`~~ object is marked.\n\n```python\n\u003e\u003e\u003e from functools import partial\n\u003e\u003e\u003e from inspect import iscoroutinefunction, markcoroutinefunction\n\u003e\u003e\u003e async def wedonotlikesnakecase():\n... return \"the_funniest_joke_in_the_world\"\n\u003e\u003e\u003e def manufacturer_of_jokes(somefunc):\n... global manufacturer_of_jokes\n... del manufacturer_of_jokes\n... return somefunc()\n\u003e\u003e\u003e joke = partial(manufacturer_of_jokes, wedonotlikesnakecase)\n\u003e\u003e\u003e joke = markcoroutinefunction(joke)\n\u003e\u003e\u003e iscoroutinefunction(joke)\nFalse\n```\n\nI discovered this problem while theoretically considering backporting `inspect.iscoroutinefunction()` to older versions of Python. The problem has not yet been caused by any use case, so it is okay if the issue is closed due to lack of demand. But just in case, I am attaching part of how `iscoroutinefunction()` is implemented in my code.\n\n```python\ndef iscoroutinefunction(obj):\n marker_name, marker_value = _get_coroutinefunction_marker()\n\n while True: # unwrap \u0026 check\n if ismethod(obj):\n obj = obj.__func__\n continue\n\n if marker_value is not MISSING:\n if getattr(obj, marker_name, MISSING) is marker_value:\n return True\n\n if isinstance(obj, partial):\n obj = obj.func\n continue\n\n impl = getattr(obj, _partialmethod_attribute_name, MISSING)\n\n if isinstance(impl, partialmethod):\n obj = impl.func\n continue\n\n # unlike its namesake in the `inspect` module, it does not unwrap\n return _has_code_flag(obj, CO_COROUTINE)\n```\n\n### CPython versions tested on:\n\n3.12, 3.13, 3.14\n\n### Operating systems tested on:\n\nLinux\n\n\u003c!-- gh-linked-prs --\u003e\n### Linked PRs\n* gh-142503\n* gh-142505\n\u003c!-- /gh-linked-prs --\u003e\n","author":{"url":"https://github.com/x42005e1f","@type":"Person","name":"x42005e1f"},"datePublished":"2025-12-08T13:48:48.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":4},"url":"https://github.com/142418/cpython/issues/142418"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:69deb94b-736f-27e8-6937-4bf15676330a |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | 8AD4:29DBA8:EB6DB9:1422773:69693EAC |
| html-safe-nonce | 1f4894c18d7f7c9757e6bc93473af11de8532410d2fa77b0ef1ad25f2c312981 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI4QUQ0OjI5REJBODpFQjZEQjk6MTQyMjc3Mzo2OTY5M0VBQyIsInZpc2l0b3JfaWQiOiI1ODQ2NTMzNDMzMjY4NDUzMDM3IiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | 495417e6fa723c5385223c02b19157cfad179f9851948b8279253846644a3dc0 |
| hovercard-subject-tag | issue:3706484357 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/python/cpython/142418/issue_layout |
| twitter:image | https://opengraph.githubassets.com/98aaf9985c98cc65f091fe3dc0bb7bc04d0b5eff8713abb1e3c719594ba2c91f/python/cpython/issues/142418 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/98aaf9985c98cc65f091fe3dc0bb7bc04d0b5eff8713abb1e3c719594ba2c91f/python/cpython/issues/142418 |
| og:image:alt | Bug report Bug description: inspect.markcoroutinefunction() is applied directly to the passed function, except for methods (which is correct behavior). However, inspect.iscoroutinefunction() checks... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | x42005e1f |
| hostname | github.com |
| expected-hostname | github.com |
| None | 54182691a21263b584d2e600b758e081b0ff1d10ffc0d2eefa51cf754b43b51d |
| turbo-cache-control | no-preview |
| go-import | github.com/python/cpython git https://github.com/python/cpython.git |
| octolytics-dimension-user_id | 1525981 |
| octolytics-dimension-user_login | python |
| octolytics-dimension-repository_id | 81598961 |
| octolytics-dimension-repository_nwo | python/cpython |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 81598961 |
| octolytics-dimension-repository_network_root_nwo | python/cpython |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | d69ac0477df0f87da03b8b06cebd187012d7a930 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width