-
-
Notifications
You must be signed in to change notification settings - Fork 2k
Make UfuncHelpers thread-safe #11226
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
Conversation
|
I wouldn't merge this exactly as is, because I copied-and-pasted a fixture from #11224. Once that is merged it should probably go to a shared location - I'm not sure what that should be. |
This comment has been minimized.
This comment has been minimized.
mhvk
left a comment
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.
@bmerry - and thanks a third time! This looks good too. I was a bit hesitant about adding complexity, but in the end this is pretty deep in the bowels and central to quantities, so it seems well worth it. And the comments will help anyone looking in the future.
I'll approve now but will wait with merging until the other PRs have had a few more eyes, and we've decided on whether or not to backport.
|
|
||
| UFUNC_HELPERS = UfuncHelpers() | ||
| UNSUPPORTED_UFUNCS = UFUNC_HELPERS.UNSUPPORTED | ||
| UNSUPPORTED_UFUNCS = UFUNC_HELPERS.unsupported |
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.
Will replacing UNSUPPORTED with lowercase version break people's code? Do people use UNSUPPORTED from this class directly? Perhaps it is a smaller price to pay to break some PEP 8 and do a self.UNSUPPORTED |= ... and such. 💭
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.
You're right, I'd missed that users could directly access it as UFUNC_HELPERS.UNSUPPORTED or UfuncHelpers.UNSUPPORTED rather than through this alias, even though all the astropy code uses the alias. I'll change it back to the way it was before (uppercase, class attribute) and think up some way to isolate it in the test.
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.
Done.
| This makes it easier to provoke race conditions. | ||
| TODO: this is copied from another branch which adds it elsewhere. It |
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.
Well... Should we work to get that other PR merged first and then rebase this one on top of upstream master after that is merged? If so, please turn this PR into draft status and put a note on the top post to indicate that this PR is dependent on that other PR. (GitHub still has no proper linking like JIRA.)
But that said, is a new fixture really necessary? I can we use setup_class and teardown_class instead within TestUfuncHelpers?
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.
#11224 is merged, so this is moot now. Please rebase and use your fixture from conftest.py. Thanks! 😸
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've rebased - the only difference should be that the fast_thread_switching fixture is gone as it was added by #11224.
mhvk
left a comment
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.
Some small wonderings. Not essential, but let me know what you think.
| with concurrent.futures.ThreadPoolExecutor(max_workers=workers) as executor: | ||
| for p in range(10000): | ||
| helpers = UfuncHelpers() | ||
| # UNSUPPORTED is (for some reason) a class attribute rather than an |
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.
Hmm, what was this solved by your lower-case version? Sorry to only realize now, but it would seem to make sense to just initialize that in __init__ as well.
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.
Yes, that's why I moved it from class attribute to instance attribute. I moved it back due to concern that it would break code that uses UfuncHelpers.UNSUPPORTED, although I've just searched Github and not found any hits for "UfuncHelpers" outside of astropy source code so it may be an unwarranted concern.
Looking at it again, is the UfuncHelpers name considered to be public API? It doesn't have an underscore, but it's also not listed in __all__.
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'll defer to @mhvk here for a design decision. While you couldn't find usage on GitHub, doesn't mean people are not using it in their private code. But if we do decide to make break (pun?) for this, then we'll find out soon enough if people complain about it after the next release.
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.
My suggestion would be to leave it as upper case, but make it an instance property. Then, if anybody uses UFUNC_HELPERS.UNSUPPORTED, it will still work fine.
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.
p.s. So a bit in between - I don't think it is likely anybody would use the class, while I think it is quite possible they might have used the instance.
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.
Ok, I'll change it to an instance attribute tomorrow.
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.
Done.
This comment has been minimized.
This comment has been minimized.
It currently fails, because I haven't fixed the issue yet.
- Remove `modules` property that lazily creates the underlying `_modules` attribute, in favour of an `__init__` that creates `modules` as an attribute. - Add a lock that is held for all mutations of the object. Fixes astropy#11220.
It should be possible to test, but added the pragma to avoid codecov failure for code that I've merely re-indented. Co-authored-by: P. L. Lim <[email protected]>
I've rebased to fix that. Let me know what you want to do about UNSUPPORTED (class or instance attribute). |
This makes it a bit easier to test UfuncHelper without affecting the main singleton instance.
mhvk
left a comment
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.
Super, thanks so much!
Description
modulesproperty that lazily creates the underlying_modulesattribute, in favour of an__init__that createsmodulesas an attribute.for consistency. This is a singleton class and it's accessed via
the
UNSUPPORTED_UFUNCSglobal so this shouldn't make any differenceother than making it easier to isolate unit tests.
Fixes #11220.