-
Notifications
You must be signed in to change notification settings - Fork 59
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
Retag wheels automatically when fusing #215
Conversation
This adds the ability to "retag" a universal2 fused wheel. When running delocate-fuse with this flag, it will update the filename and the dist-info file of the fused wheel to reflect that it is a universal2 wheel.
I feel that anything updating the wheel tags should reuse the |
Are you okay with raising the errors like I did when the two wheels are not correct/have too many tags? |
I completely missed those functions. It would be good to update the code to use them.
Since you're updating the tag already then it would be a good idea to verify that the minimum platform tag is correct. I mostly want tag renaming to behave similarly to the I doubt that I'd like retagging to be the default behavior rather than an optional flag. Not verifying the tags has left a lot of mis-tagged wheels around.
I'm not sure. I like the verification and the error massage but not that it's hardcoded to I'd prefer a generic extendable solution to expected tags: _FUSEABLE_TAGS = {
frozenset(("x86_64", "arm64")): "universal2",
} |
👍
I agree with this. Wasn't sure that was what the maintainers wanted, but if it is, then sounds good to me.
That approach seems interesting. When I started doing this I was unsure what scope to make this "retagging" functionality. On the one had like you point out, it does seem like it could (should?) be generalized to support various situations. But on the other hand, I was unsure how many different variety of wheels (not binaries, because I think lipo can fuse more than are actually relevant for Python wheels) actually can be fused together. And in particular, what wheels can and are being fused together today. If you look at the project's
When I looked at that it gave me the impression this is essentially why To be clear, I'm not opposed to your sentiment of wanting a general and clean solution. But I'm not sure that the extra flexibility is worth the extra complexity. If there is a very clear set of what conditions to support with retagging, then that might be workable. But if we are trying to support unknown fusing conditions, which either don't currently exist or at the very least are not reasons people use I'll update the parts we have discussed and see where that takes me. |
This updates '_get_archs_and_version_from_wheel_name' to check if both arm64 and x86_64 platform tags are in the wheel's filename. If they are both present, it changes the returned arch to be universal2 with the appropriate version.
This is now much simpler and more generalized. It first updates the name to contain platform tags from both from_wheel and to_wheel. Next it calls '_check_and_update_wheel_name' which fixes any issues with the name AND will convert it to universal2 if necessary. And finally, it calls '_update_wheelfile' to update the info in the WHEEL file to match the new name.
Just pushed some new commits and I think I may have been wrong about it being overly difficult! With a slight tweak to I left it as a flag as I wanted to double check about making it the default behavior. Since that would be a breaking change, I just wanted to confirm that thats not a problem. |
I'd like the default behavior changed for the reasons I mentioned above. Added or changed features must be clearly marked in the changelog and anyone relying on old behavior can pin their version of Delocate. It would be nice to have @matthew-brett's opinion as well but I'm not sure if they'll be available. |
This also updates the fuse function to support pathlib paths and updates the retagging function to use pathlib paths.
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 sure to note the changed behavior in the changelog.
Am I right in thinkng this is going to break anyone's automated workflow that is using I suspect use of If so - is there anything we can do not to have a torrent of 'you broke my CI' complaints? How about (sorry if I missed it), a |
Keep in mind that this situation is a result of
If they follow Semantic Versioning then they're fine. Anyone using the typical dependency specifiers to keep things stable, such as It's possible for those still using the workaround from the readme's "Making dual-architecture binaries" section to rename the wrong wheel after an update if they decided to not use the
Not nearly as common as In my experience my wheels already have universal platform tags and universal dependencies before I even run Delocate on them so anything involving
These complaints have simple answers. Either they pin version 0.11.0 or they modify their scripts to handle the updated output. If they read the changelog then they'll know everything they need without having to raise an issue. I think that sorting out complaints would take less time and effort then dealing with the technical debt of keeping the old behavior in the current code. There were CI complaints for 0.11.0 as well and those weren't hard to deal with.
They can pin It's mainly you who wants to keep the old behavior as an option. The main issue solved is that the old behavior is unintuitive especially due to how |
This also required some typing changes to functions called by fused_trees.
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #215 +/- ##
=======================================
Coverage 96.95% 96.95%
=======================================
Files 15 16 +1
Lines 1282 1315 +33
=======================================
+ Hits 1243 1275 +32
- Misses 39 40 +1 ☔ View full report in Codecov by Sentry. |
I've considered replacing the syntax of Something that would work for most cases would be to make |
Anything that raises an informative error would be fine I think. |
What if we add a flag So as an example: delocate-fuse wheel1.whl wheel2.whl # Raises error where we inform the need for `--no-overwrite`
delocate-fuse --no-overwrite wheel1.whl wheel2.whl # Runs without error In this case, we probably would not need to raise any error if |
I just fixed the last test I added. Total user error, forgot to add the right hand side of that assert 😅 sorry about that. |
This would sound perfectly reasonable, but the issue with this is that no matter how loudly you try to announce the change, devs won't notice it until the change is finalized and their scripts break. The reason I suggest requiring For announcing the changes to the user, I think the most reasonable thing you can do is simply print where wheel was outputted to stdout. By adding the following to the end of the print(f"Fused wheel written to {out_wheel}") If the user doesn't notice this then they're not going to notice anything else less than an error. |
I'm suggesting we don't just print something out, but raise an error and print something out. I thought based on @matthew-brett's comments:
And what I believe your position is, which is we should retag by default, not because it is a good idea, but because doing anything else is incorrect and leads to bad wheels out in the wild, when they could have easily been made correct. That this satisfies both of those interests. So what I was suggesting would only work if the user specifically adds But if/when this upgrade is made, and those who have disregarded semantic versioning run their CI the same as before, we can now raise an error explicitly stating they now need to use the Perhaps I was unclear because I included the So I think this is a reasonable middle ground where we force the user to change, let them know how they can do that, but don't really add any substantial extra code thats going to lay around in the library and be hard to remove in the future. |
Just to clarify - that was my intention with |
That's correct. This is why I insist on the new behavior being default and removing even the option (other when pinning an old version of delocate) for the previous behavior. I couldn't come up with anything better than making
I insist on pinning Although I feel strongly about this, I'll go with whatever solution Matthew asserts. |
I'm happy with whatever name for the new command - and it's perfectly reasonable to not want to keep the old pathway around. As long as the error message is clear, and there is no possibility of unexpected behavior without the error, anything is fine with me. |
@HexDecimal I don't understand why you feel a new command is better than requiring a new flag on # delocate_fuse.py
...
parser.add_argument(
"--no-overwrite",
action="store_true"
)
def main() -> None: # noqa: D103
args = parser.parse_args()
if not (args.no_overwrite or args.wheel_dir):
raise RuntimeError("Useful error message telling user to use '--no-overwrite' or '--wheel-dir'") # This returns 1 as an exit code
... This causes the same kind of exposure to the new change as setting up a new command like
parser.add_argument(
"--no-overwrite",
action="store_true",
default=True
) This way its no longer necessary to use and we can go back to telling people to do Another more subjective benefit is we don't have to permanently change the name and lose Again if you feel |
It's a good attempt, but I see downsides to this approach.
Once Rationally I should be okay with leaving For names, the original name of
Those using
Yeah, I got used to the name too, but its API has made it difficult to fix in a graceful way. I'll let you pick the new name if you want.
|
Depending on the version of each wheel being fused, the universal2 wheel's version can be either the x86_64 or the arm64 wheel's version. The first test for this is testing the scenario where the x86_64 wheel's version should be used. This new test is tesing the scenario where the arm64 wheel's version should be used.
This moves the old 'delocate-fuse' functionality into the new 'delocate-merge' command. Running 'delocate-fuse' will now print a message notifying the user of this change and then exit with an exit code of 1. This also updates relevant tests, the changelog, and the README.
Sorry I wasn't able to respond to this sooner. I wanted to say I very much appreciate that response @HexDecimal and completely agree with all of your critiques. With that, I've put together the changes necessary to move all the functionality of fusing into Let me know what you think. |
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.
Lots of progress made so far, I think anything left is polish and cleanup. I like the warning added to the readme.
No need to rush. I'd prefer this to be done correctly rather than quickly.
Just a heads up, I'm not going to have much time to work on this for the next week. So I'll do what I can, but probably will get to the remaining things towards the end of next week. |
Any thoughts on what's left for this to be ready to merge? |
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.
As far as I can tell. Everything is resolved.
This PR can be squashed and merged.
Great! Thanks for working with me through this. |
Awesome to have this fixed! I will have to look at fixing Encrust to make sure I'm not expecting the old name :) |
And, done: https://pypi.org/project/encrust/2024.9.3/ |
This is my attempt at a PR for #174.
This adds the ability to "retag" a universal2 fused wheel. When running delocate-fuse with this flag, it will update the filename and the dist-info file of the fused wheel to reflect that it is a universal2 wheel.
I didn't update the readme or add any tests yet. I wanted to first get feedback on whether or not this is the "retag" you had in mind.
Let me know what you think/if there is anything you would like changed!