From: Jimmy R. <ji...@re...> - 2005-02-22 20:36:55
|
Harald Armin Massa wrote: > the shardlib.zip is just a zip-file, and Python is able to read and > update zips. So maybe ... you could just download your updates, and > really update that library-file on site? My Python code handles the download but then exits and runs the downloaded installer so that Python itself can be updated when necessary. The patch idea is interesting. The last time I dealt with patching was using RTPatch which was very expensive and very slow. Today I found bsdiff/bspatch which are free and extremely fast. I can add one pyo to my uncompressed zip file and bsdiff produces a patch file that is smaller than the pyo itself (it uses bz2 compression). The patch applies in a fraction of a second. I'm a little afraid of things going wrong in the middle (user canceling, power failure, etc.) - sync/patch failures cost time/money for everyone involved. Perhaps a transaction-like cycle, as you suggest, is in order if I take this approach. Thanks, Jimmy |
From: Jimmy R. <ji...@re...> - 2005-02-22 20:47:26
|
Michael Foord wrote: > Jimmy Retzlaff wrote: >=20 > >There have been several requests for single file executables on this > >list, but now I'm looking for almost the opposite... > > > >My first go at the problem has been to derive a class from > >build_exe.py2exe to generate multiple zip files (leaving all Python > >standard library files in library.zip for bootstrapping). I then add > >code to the top of my main Python file to add all zip files in the > >application directory to sys.path. This seems to be working OK in my > >initial testing. >=20 > What do you mean by 'avoid modifying' - do mean finding a solution that > doesn't change anything ? Or do you mean find a solution that leaves > your main application as a '.py' file ? As it stands now I have to manually insert a block of code at the top of my main Python file to look for zip files and add them to sys.path. I actually distribute a number of applications this way so this isn't ideal from a maintenance standpoint. It might not be so bad if I automated it. > Why do you need the apps files (modules) in a zip file ? Why not simply > tell py2exe to exclude them and include them manually as '.py' files > somewhere on sys.path ? That might be a good solution. I still have to have a block of codein my main Python file, but it's more like "if hasattr(sys, 'frozen'): sys.path.append(sys.prefix)" which is much simpler than what I have now. > One way or the other you are going to have to *manually* tell py2exe > which modules to *exclude* from the main zip. You could use some of the > code from Movable Python to build a list of the whole standard library > though.... and use membership in that as the test for which zip to put > files in. It sounds like you've already got something like that working > though. Yep, I do have something. It's pretty simple - if something comes from somewhere under sys.prefix (c:\Python24 on my machine) then it's "system," otherwise it's "app." This bundles everything in site-packages under "system" which is good for my purposes. All this raises another question. Can I skip the zip file(s) altogether? Is there a way to tell py2exe to use the exe's folder (or some subfolder) as sys.path rather than the archive? If I can get things bootstrapped then I could skip zip files altogether. I'm guessing I'd have to modify/rebuild the C stub to do this. Thanks, Jimmy |
From: Jimmy R. <ji...@re...> - 2005-02-23 01:21:25
|
Jimmy Retzlaff wrote: >=20 > Jimmy Retzlaff wrote: > > > > All this raises another question. Can I skip the zip file(s) altogether? > > Is there a way to tell py2exe to use the exe's folder (or some > > subfolder) as sys.path rather than the archive? If I can get things > > bootstrapped then I could skip zip files altogether. I'm guessing I'd > > have to modify/rebuild the C stub to do this. >=20 > I'm talking to myself here, hopefully someone else will benefit from my > ramblings. :) It appears that the only thing that needs to appear in > the zip file is __future__.pyo (or pyc is not optimizing), and the zip > can be a 0 byte file if nothing is imported from __future__ in the main > Python file. Since sys is built-in, it can be imported in the main file > and something like this can be done: >=20 > import sys > if hasattr(sys, 'frozen'): > sys.path.insert(0, sys.prefix + r'\library') >=20 > Then all modules & packages can appear in a "library" folder that sits > next to the exe. >=20 Uggh, it looks like I accidentally sent the last part of my conversation with myself to the ctypes list instead of the py2exe list... Anyway, I finally have something I'm pretty happy with. There is nothing extra in any of my python files except setup.py and a distribution is produced which includes all the pyo files and no zip files. Here is setup.py: import os from distutils.core import setup import py2exe.build_exe class py2exeSansZip(py2exe.build_exe.py2exe): def make_lib_archive(self, zip_filename, base_dir, verbose=3D0, dry_run=3D0): # Don't really produce an archive, just copy the files. from distutils.dir_util import copy_tree copy_tree(base_dir, os.path.dirname(zip_filename), verbose=3Dverbose, dry_run=3Ddry_run) return '.' setup(windows=3D['test.py'], cmdclass=3D{'py2exe' : py2exeSansZip}) One thing I noticed while testing all this is that py2exe'd apps can't run from a shortcut if the "Start in" entry in the shortcut is not also the exe's directory (regardless of whether zips are used or not). Things don't seem to get far enough to produce an error log. I'm assuming the absolute part of the path used to build the lone entry in sys.path is the equivalent of Python's os.getcwd() rather than os.path.dirname(sys.argv[0]). Thanks for the ideas. Jimmy |
From: Michael F. <mi...@pc...> - 2005-02-23 08:44:33
|
Jimmy Retzlaff wrote: > [snip..] > >One thing I noticed while testing all this is that py2exe'd apps can't >run from a shortcut if the "Start in" entry in the shortcut is not also >the exe's directory (regardless of whether zips are used or not). Things >don't seem to get far enough to produce an error log. I'm assuming the >absolute part of the path used to build the lone entry in sys.path is >the equivalent of Python's os.getcwd() rather than >os.path.dirname(sys.argv[0]). > >Thanks for the ideas. > > > A couple of functions I use in my apps : import imp, os, sys def main_is_frozen(): return (hasattr(sys, "frozen") or # new py2exe hasattr(sys, "importers") # old py2exe or imp.is_frozen("__main__")) # tools/freeze def get_main_dir(): if main_is_frozen(): return os.path.abspath(os.path.dirname(sys.executable)) return os.path.abspath(os.path.dirname(sys.argv[0])) get_main_dir() will return the directory the script is in - whether a frozen app or not (and however it is frozen). Regards, Fuzzy http://www.voidspace.org.uk/python/index.shtml >Jimmy > > >------------------------------------------------------- >SF email is sponsored by - The IT Product Guide >Read honest & candid reviews on hundreds of IT Products from real users. >Discover which products truly live up to the hype. Start reading now. >http://ads.osdn.com/?ad_ide95&alloc_id396&op=click >_______________________________________________ >Py2exe-users mailing list >Py2...@li... >https://lists.sourceforge.net/lists/listinfo/py2exe-users > > > > > |
From: Jimmy R. <ji...@re...> - 2005-02-23 01:40:17
|
Jimmy Retzlaff wrote: > > One thing I noticed while testing all this is that py2exe'd apps can't > run from a shortcut if the "Start in" entry in the shortcut is not also > the exe's directory (regardless of whether zips are used or not). Things > don't seem to get far enough to produce an error log. I'm assuming the > absolute part of the path used to build the lone entry in sys.path is > the equivalent of Python's os.getcwd() rather than > os.path.dirname(sys.argv[0]). Get your facts straight Jimmy! The problem you mention above is in your own application code, not Thomas' py2exe code. Jimmy p.s. - my code may not be the only thing I need help with :) |
From: Thomas J. <pre...@pr...> - 2005-02-23 05:43:17
|
My suggestion: Create a small patcher that merges the diffs, like it has been suggested before; But instead of doing this on individual files and shooting them into the zip, just diff the full zip file. Error Handling: When the 'installer' is patching, have it first move files to .old, then apply the patches into the original filename, followed by deleting the .old file. If the .old files exist on next app startup, you can reverse the patching and start over. I'd recommend making the main app (that is, the exe + the main py script) the patcher itself; Have it check for updates on startup, download & patch if an update is available, and then launch your actual script. A different solution is having the main app be a version checker and downloader, that does all of the above except the actual patching, which is managed by a patcher script downloaded with each version - that would allow flexibility in your patching system. - Thomas |