Skip to content

Implement types._GeneratorWrapper in C #133372

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

Closed
efimov-mikhail opened this issue May 4, 2025 · 14 comments · Fixed by #134563
Closed

Implement types._GeneratorWrapper in C #133372

efimov-mikhail opened this issue May 4, 2025 · 14 comments · Fixed by #134563
Labels
extension-modules C modules in the Modules dir pending The issue will be closed if no feedback is provided topic-asyncio type-feature A feature request or enhancement

Comments

@efimov-mikhail
Copy link
Contributor

efimov-mikhail commented May 4, 2025

Feature or enhancement

Proposal:

I've found an old TODO line in types module and decided to give it a try:
https://github.com/python/cpython/blob/main/Lib/types.py#L253

My PR with this change will be linked soon.

Has this already been discussed elsewhere?

No response given

Links to previous discussion of this feature:

No response

Linked PRs

@efimov-mikhail efimov-mikhail added the type-feature A feature request or enhancement label May 4, 2025
@sobolevn
Copy link
Member

sobolevn commented May 4, 2025

Please, before diving to deep into it: explain what we will achieve by doing so. For example: performance (and in what cases). Also: take extra care about potential compatibility changes.

@efimov-mikhail
Copy link
Contributor Author

efimov-mikhail commented May 4, 2025

Please, before diving to deep into it: explain what we will achieve by doing so. For example: performance (and in what cases). Also: take extra care about potential compatibility changes.

Actually, base PR is already present, I've linked it.
In my opinion, this change is kinda similar to two things that we already have in codebase.
First is basic collections that have implementations both in Python and C, OrderedDict for example.
Pure Python implementation will not be removed but faster C implementation is added and it will be used if possible.

Second is PyCoroWrapper in genobject.c which wraps generator object.
IMO, _GeneratorWrapper is very similar to this class and can be implemented in C for performance.

I don't think that performance gain is big, mainly because _GeneratorWrapper is only used in types.coroutine decorator.
And that decorator is kinda old-style and not used much.
But this is still an improvement in very basic class for async programming.

I also slightly improve pure Python implementation of _GeneratorWrapper: gi_suspended and cr_suspended properties are added.
IMO, they were missed by mistake.

Speaking about compatibility, I can see no problems, because C version is very close to pure Python version.
Only exception texts aren't equal and setting arbitrary values to __name__ / __qualname__ is prohibited as with general functions and generators.

@efimov-mikhail
Copy link
Contributor Author

Moreover, there is another "TODO: Implement this in C." line in this file:

# TODO: Implement this in C.

It seems that types.coroutine also should be implemented both in C and in Python.
I can make this change in separate PR if this one will be accepted.

@picnixz picnixz added extension-modules C modules in the Modules dir and removed stdlib Python modules in the Lib dir labels May 4, 2025
@ZeroIntensity
Copy link
Member

I tried this a few months ago on my own, and from that experience, I'm really concerned about this change.

  • For one, _GeneratorWrapper isn't something that needs to be all that fast. In coroutines, the bottleneck is always the IO. I think any speedup we get will be negated by IO operations.
  • The linked PR seemed incorrect at a quick glance, so the complexity will likely only get worse (for example, the PR is missing thread-safety).

@picnixz
Copy link
Member

picnixz commented May 4, 2025

How fast are we in terms of import time however? Here it's interesting to see if we can improve the import time of types.

@sobolevn
Copy link
Member

sobolevn commented May 4, 2025

The linked PR seemed incorrect at a quick glance, so the complexity will likely only get worse (for example, the PR is missing thread-safety)

I also fear that we might introduce some bugs with the rewrite. Since @types.coroutine is very outdated, I don't think that we should really touch it :(

Unless we see a really good reasoning.

@AA-Turner
Copy link
Member

Since @types.coroutine is very outdated, I don't think that we should really touch it :(

Would it be worth considering deprecating @types.coroutine?

In the top 10,000 PyPI projects, it's only used in 91: amazon-ion, aspidites, async-generator, esphome, langgraph, nuitka, pycapnp, telnetlib3, and trio.

Of these, the uses in aspidites, nuitka, and pycapnp are test-only.

A

Footnotes

  1. excluding asyncio and taskgroup, which are stdlib backports

@sobolevn
Copy link
Member

sobolevn commented May 4, 2025

I think we can do that for 3.15, it would mark 10 versions of async def addition.
But, asyncio team should decide on it :)

@AA-Turner
Copy link
Member

cc @kumaraditya303

@kumaraditya303
Copy link
Contributor

asyncio doesn't support generator based coroutines anymore so optimizing this isn't worth it. I think the comment should be removed as it is not relevant nowadays.

@efimov-mikhail
Copy link
Contributor Author

efimov-mikhail commented May 5, 2025

Since @types.coroutine is very outdated, I don't think that we should really touch it :(

Would it be worth considering deprecating @types.coroutine?

IMO, this is very good question, and we could consider it in the details.
FYI, 4 years ago there were reasons why not to deprecate it:

#81102 (comment)

I should learn these code snippets deeply to better understand the current situation.

@AA-Turner
Copy link
Member

also cc @njsmith. Both the examples cited by Nathaniel are 'simple' cases where all types.coroutine does is add a flag to co_flags, so another alternative would be to consider deprecating wrapping generator-like functions & _GeneratorWrapper, but keep the flag-mutation code.

A

@efimov-mikhail
Copy link
Contributor Author

@kumaraditya303
Copy link
Contributor

I don't there is any benefit of changing or deprecating it, there are valid use cases for it and I think it's best to just remove the comment of implementing it in C and close this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
extension-modules C modules in the Modules dir pending The issue will be closed if no feedback is provided topic-asyncio type-feature A feature request or enhancement
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

6 participants