Closed mboisson closed 3 years ago
Hi!
This is one of the features I would really like to implement, but it isn't yet there, at least not in any "supported" manner. Simply put, Python's zipfile
, which handles PKZIP for wheelfile
, doesn't really allow arbitrary modifications to an existing archive. From what I understand, one has to rebuild the archive in memory to do that.
I was going to add a mode='a'
switch so that this is handled internally by WheelFile
, and afterwards you'd be able to just wf.version = new_version
, but it will take a lot head scratching to do it properly. I don't think I will be able to make it happen in any timeframe that could be helpful to your case.
What I can offer instead, is this snippet. It generates a new version of a wheel based on an already existing one. It might not be better than your current approach, but that is the best I can muster with current version.
I tested it on the latest Django wheel, and it seems to work properly, modulo the fact that wheel unpack
will not work because of normalization issues (see #10) - WheelFile
does it as described by the spec, but the rest of the ecosystem - not necessarily.
Please test it extensively before committing anything to your indexes :).
Also, before using this I would advise you to wait until next Monday. This weekend I'm going to make a release that fixes few bugs, including one nasty oversight of mine wrt. RECORD
files spec. The wheels do work right now, but there is a minute chance that after a repacked, misformatted wheel may nuke site-packages
on removal / update :grin:. See pypa/pip#10118 or #11.
I will update the gist accordingly afterwards.
Please beware that this implementation is in very early stage of development. There may be minute mistakes and oversights that can result in a wheel that, while installable, might not be 100% up to spec.
@mboisson wheelfile==0.0.7
is out, I updated the gist accordingly.
I also decided that this usecase will become a separate WheelFile
method, so if you're willing to wait ~a week, this snippet will become:
foo1 = WheelFile(...)
foo2 = WheelFile.clone(foo1, version=foo1.version + 'computecanada')
(Actual method signature TBD.)
@mboisson
wheelfile==0.0.7
is out, I updated the gist accordingly.I also decided that this usecase will become a separate
WheelFile
method, so if you're willing to wait ~a week, this snippet will become:foo1 = WheelFile(...) foo2 = WheelFile.clone(foo1, version=foo1.version + 'computecanada')
(Actual method signature TBD.)
That would be nice! Thanks!
@mboisson
Sorry this took longer than I said it would, it turned out that this would be a bit more hairy if implemented with the same API style as the rest of the library.
For your usecase, you can use it as follows:
with WheelFile(path_to_wheel) as wf:
WheelFile.from_wheelfile(wf, version=str(wf.version) + '+computecanada')
I tested it on django
and it seems to work as intended.
A working version is now on master
. It requires implementing one more check (it should raise ValueError
when the new WheelFile
would result in overwriting the old one), but for your usage it should suffice.
I released it as 0.0.8.dev0
. Feel free to use it:
pip install wheelfile==0.0.8.dev0
Please test extensively before bulk changing files. All bug reports greatly appreciated.
Hi @MrMino, I just tested. It seems to work very well!
Thank you!
Hi, We have a use case (https://github.com/ComputeCanada/software-stack/issues/80) to patch a wheel file to update the Version of a wheel to include a local version tag.
I could not figure out how to do this with your package. I need to: 1) read an existing wheel 2) update the metadata info to change the version 3) rewrite a new wheel under a new name
Any guidance on how to do that would be appreciated.
For now, we have https://github.com/ComputeCanada/wheels_builder/pull/29 but this does not handle the RECORD file