Skip to content
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

Fix #17354: Preserve class binding in classmethod flows when using #17647

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

vilhenad
Copy link

@vilhenad vilhenad commented Mar 30, 2025

Classmethod flows were losing their cls inheritance structure when copied with .with_options(), causing them to default to the base class implementation. This was particularly evident when subclassing (e.g., ChildProcessor.process would incorrectly use BaseProcessor.get_multiplier).

The fix ensures proper context preservation by:

  1. Creating deep copies of the function for each bound flow
  2. Maintaining independent prefect_self references
  3. Preserving all function attributes during copying

Added test cases verify:

  • Classmethod inheritance is maintained after .with_options()
  • Instance methods retain their proper self context
  • Multiple bound flows don't interfere with each other

Closes #17354

Checklist

  • This pull request references any related issue by including "closes <link to issue>"
    • If no issue exists and your change is not a small fix, please create an issue first.
  • If this pull request adds new functionality, it includes unit tests that cover the changes
  • If this pull request removes docs files, it includes redirect settings in mint.json.
  • If this pull request adds functions or classes, it includes helpful docstrings.

@github-actions github-actions bot added the bug Something isn't working label Mar 30, 2025
Copy link

codspeed-hq bot commented Mar 30, 2025

CodSpeed Performance Report

Merging #17647 will not alter performance

Comparing vilhenad:fix-classmethod-flow-bug-17354 (518f246) with main (de45c87)

Summary

✅ 2 untouched benchmarks

Copy link
Member

@desertaxle desertaxle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @vilhenad! I think it makes more sense to move the copying logic into .with_options, since copying the function shouldn't be necessary during normal execution. Copying it on every call could increase memory usage for instance method flows.

@vilhenad
Copy link
Author

Thank you for the quick review @desertaxle! I completely understand your point on increasing memory usage. However, if you don't mind clarifying, I've got a question. As you can see by my second unit test, this fix also addresses instance methods not preserving context when using a flow (without .with_options). Should I just carry through with only making changes to the .with_options (consequently discarding this other fix)?

@desertaxle
Copy link
Member

@vilhenad I made some changes in #17660 that address the issue covered by your second unit test, so I think you should focus on only the issue with .with_options in this PR.

… using

.with_options()

Classmethod flows were losing their cls inheritance structure when
copied with .with_options(), causing them to default to the base class
implementation.

The fix ensures proper context preservation by:
1. Creating deep copies of the function for each bound flow
2. Preserving all function attributes during copying

Added test cases verify:
- Classmethod inheritance is maintained after .with_options()

Closes PrefectHQ#17354
@vilhenad vilhenad force-pushed the fix-classmethod-flow-bug-17354 branch from 19d765a to aeeb09a Compare April 7, 2025 04:34
…s__ and __prefect_self__) so that instance methods don't lose context and don't fail parameter binding.
@vilhenad
Copy link
Author

vilhenad commented Apr 8, 2025

@desertaxle I've pushed the changes you requested. One thing is confusing me: my unit test is passing fine locally, but consistently failing in the GitHub CI. The test code appears identical to the example from the issue page and works in isolation locally.
Wondering if you have any insights into why the CI environment might be behaving differently?

@desertaxle
Copy link
Member

Thanks for making those updates @vilhenad!

I think it's failing on 3.13 because of changes in 3.13 that made @classmethod no longer chainable. I added the _isclassmethod and _isstaticmethod attributes in #17660 to handle that change, and I think that they'll need to be copied over in .with_options for the functionality in this PR to work with 3.13.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Classmethod flows lose class binding after .with_options()
2 participants