[Pythonmac-SIG] py2app standalone options (original) (raw)

Bob Ippolito bob at redivi.com
Thu Dec 23 21:39:45 CET 2004


On Dec 23, 2004, at 1:42 PM, has wrote:

Ronald Oussoren wrote:

To give a practical example, let's say I want to write a GUI interface to py2app. That's an application with different requirements than py2app, Not sure how: both are intended to build applications, and allow users to configure exactly how they're built. The only thing that differs is the workflow's order.

One of py2app's goals is to integrate seamlessly with distutils and to behave similarly to py2exe when it makes sense. That goal is counter to making it suitable for inclusion into a GUI workflow, unless that GUI's job is simply to piece together a setup.py script (which is completely orthogonal to what py2app does). Distutils isn't very good at pausing in the middle of a command, and py2app executes as a single distutils command, therefore what you specifically mentioned is not reasonable.

In svn trunk, I've broken up py2app._run into lots of other methods, so in theory if you cared you could now somewhat reasonably implement such functionality in a subclass, but that's as far as I'm going with it.

Right now, at 0.1.x, users that don't already have a pretty good idea of how this stuff works aren't of my concern. The goal for 0.2.0, which I think has already been achieved (sans documentation), was to make it better than the alternatives for any platform. Right now, for any given application, less magic is required in a py2app setup.py than anywhere else. It is NOT my goal to replace distutils or create a front-end to distutils at this point. py2applet is as far as I go in that regard, and it merely constructs the runtime equivalent of the 'obvious' setup.py for the given input files and uses no hooks not already available by distutils. py2applet's main script basically is a generic setup.py, in some grotesque way.

Look at all this another way: in an ideal world, developers and their applications wouldn't need to deal with any of this dependency crap at all. Each app would merely list its requirements and the system would magically conjour up suitable components upon request. That every single app has to lug around its own set of potentially obsolete/buggy/system-incompatible dependencies is no doubt partly due to this not being an ideal world, so compromises must sometimes be made. But then, it might also be partly due to a "well that's the way things have always been done" philosophy that's come from the traditional static-inflexible-early-bound-language-plus-compile-time-linking side of computer evolution; constraints Python isn't bound by. Dunno about you, but personally I'd want to hedge my bets before tying users down to any particular strategy.

In order for that to happen, either every user will have to have every version of every library already installed, or they would have to have the newest version of every library already installed (assuming that libraries would never be able to break backwards compatibility). The other way, of course, is to have all versions of all applications and libraries available on the internet for automatic download, and then you have a software distribution system. You can already have that if you want it, but none of them are perfect and none of them are suitable for the common user on Mac OS X.

Shipping a known version of all dependencies with your product guarantees that it will run the same way that it was built. That's a good thing. So what if it's "obsolete" or "buggy"? If it's obsolete, so if the application using it. If it's buggy, well, the person who developed the application should test and ship a new version that contains the newer library. At least you don't have to support the user (or another application's dependencies) doing god knows what and breaking your application (which of course, still happens, but really only by people who should know better so it's not as much of a problem). It doesn't matter when your language binds to symbols, all that matters is that when code changes, things can and probably will break.

"system-incompatible" isn't really a problem. Yes, it's easy to develop software that is not backwards compatible to an older version of OS X, but so what? Chances are you're taking advantage of functionality that is not and will never be available for a previous version.

Why should an application developer even have to bother listing its "requirements"? Maybe you like to do such busywork, but I sure don't.
The old modulefinder does a good job at determining this automatically, and modulegraph plus the special cases inked into py2app does a much better one. I have also been having some discussions on and off with PJE and Holger Kregel about how to do this in the more general case, so that the packages that need special casing (PIL, py, pypy, PEAK, docutils, etc.) have a way of presenting that information in a cross-platform cross-packager manner... but a typical application doesn't need such trickery, wxGlade is really the only one I've seen so far.

Here's another whacky idea: why not get rid of the one-way source-code->build->finished-application workflow, and treat [certain types of] applications as simply another editable format? This is what AppleScript does, for example: write a script and save it as an applet, run it, drop the applet onto Script Editor, edit it some more, run it, etc. If it errors, a dialog pops up with an error description and an 'Edit Script' button that, when clicked, opens the script in SE for you with the faulty line already highlighted. Emulate Smalltalk a bit more, C a bit less. The more open, flexible and neutral tools like py2app are, the easier this kind of lunacy is to indulge. After all an idea is only stupid until you've tried it and find you really quite like it. :)

That only works because everyone already has AppleScript and its IDE installed everywhere. We don't really even have an IDE worth using, and it's probably already possible to do this with emacs pdb integration, though I am not an emacs user (yet) so I can't say that with any authority.

BTW. the GUI I'd like to see is a GUI that allows me to grafically construct setup.py files. I think the biggest problem with setup.py files is that they're unnecessarily complicated. The best way to simplify the setup process would be to simplify setup.py itself: push all the descriptive stuff - name, version, author, description, etc, etc. - into its own plaintext file so the only thing setup.py then has to deal with is any custom build code. Make the system simple enough that it doesn't require a wizard in the first place; a drag-n-drop GUI shell is then merely a pleasant (and newbie-friendly) convenience, rather than an awkward band-aid for deeper inadequacies.

You can do that, with a setup.cfg file <http://docs.python.org/inst/config-syntax.html>.

Honestly I can't see how you can really complain about setup.py being "complicated":

from distutils.core import setup import py2app setup(app=['myscript.py'])

What the heck is the problem with that? Understandably, it does get ugly when you need to specify py2app-specific options with options=dict(py2app=dict( ... )), but that can be nicely expressed in a setup.cfg [py2app] section, if you were so inclined. Additionally, as I said, I am not looking to replace distutils or write a front-end to distutils at this point, so the options syntax is a necessary evil.

You can also do that with py2applet. It doesn't get much simpler than dragging your script plus resource files, optional icon and Info.plist onto py2applet and having an application bundle pop out in the same directory as the script. If the application can be packaged with a trivial setup.py (and most can), it just works.

-bob



More information about the Pythonmac-SIG mailing list