
I'm wondering how scripts should be handled by easyinstall -- right now they pretty much get ignored. But I'm not sure how they should be handled at all. Distutils has a couple rules, with --install-scripts, and --home (which uses ~/bin), and the normal rules... and then some translation of those options to Windows. But none of those seems to translate very well to easyinstall. Or eggs. I don't have any ideas myself on this. Except that the scripts themselves are usually pretty dumb anyway, just thin wrappers that fix up sys.path, import a module, and call a function; so the status quo could probably be improved upon anyway. -- Ian Bicking / ianb@colorstudy.com / http://blog.ianbicking.org

At 03:56 PM 5/29/2005 -0500, Ian Bicking wrote:
Yep. Like you, however, I'm not sure what to do about 'em. Take a look at the Unix versions of easy_install -- they're actually the regular .egg files, with a shell script cat'ted on at the front! (Somebody could probably pull the same trick with an .exe on Windows.) However, such "eggsecutables" aren't really a solution for packages with multiple scripts. I'm thinking maybe bdist_egg should include an EGG-SCRIPTS directory for the scripts, so that EasyInstall could pull them out and install them whenever you do a non --multi-version install. It would, however, also need to *uninstall* them when deactivating a current version, because otherwise they'd be for the wrong version. I had previously thought that we would move towards using "python -m" to run scripts in eggs; unfortunately this only works for unpacked eggs, not egg files. Of course, this all just overlaps the fact that distutils script installation is really only good for command-line utilities anyway, and even for those, Windows requires a fair bit of tweaking in order to be able to use them effectively at a non-Cygwin command line. It might help if there were some kind of metadata for scripts, like to indicate whether something is a command-line utility, a graphical application, etc. Then distutils could tweak the file extension and/or build a custom launcher for it (like Fredrik Lundh's exemaker for Windows) as appropriate for the platform. That information could then be added to EGG-INFO and/or EGG-SCRIPTS, and used by EasyInstall to do script installation and uninstallation.

On May 29, 2005, at 3:46 PM, Phillip J. Eby wrote:
Couldn't you change build_scripts and install_scripts when using bdist_egg to instead put the script inside the egg somewhere, and the installer would put scripts in the usual places that simply require and then exec the real script? -bob

At 04:43 PM 5/29/2005 -0700, Bob Ippolito wrote:
That's more or less what I was proposing, except that I wouldn't use build_scripts or install_scripts, just pack the original source scripts into the egg, and then let the installer do its thing at the other end. That way, a cross-platform egg wouldn't have any platform-specific stuff baked into the scripts accidentally. It's not as if build_scripts or install_scripts do anything of consequence at the moment anyway; they just munge the #! line and copy the files (as of Python 2.3 anyway). My main thought is distinguishing console vs. GUI start scripts. I don't believe there's a Mac equivalent to '.pyw', for example. Also, at some point EasyInstall really could support adding desktop shortcuts (or Start menu entries or whatever you call them on a given platform) for applications bundled in eggs. Sort of an end-user py2exe/py2app thing. On the other hand, it does seem a little silly to use a command-line tool to install a graphical application. :) However, it probably makes sense to create platform-specific GUI wrappers around EasyInstall to do this sort of thing.

On May 29, 2005, at 5:01 PM, Phillip J. Eby wrote:
I guess, I don't think it really matters. If platform specific stuff gets baked into the scripts somehow, then they probably won't work without it. The #! line is of course of no consequence in-egg.
There is a Mac equivalent to '.pyw', it's the same thing (except .py files don't normally launch with a terminal attached, so really all Python scripts are treated as .pyw .. which is probably a bug). Mac OS X doesn't condone applications touching the user's dock, so the "start menu" thing is out. As for putting the applications in a reasonable place, the "reasonable place" depends on the user. The best solution might be to just pop open the dist folder and let the user drag it to where they want it, or to put it in a disk image and mount it. Anyway, "GUI scripts" is mostly a non-starter on OS X, it's generally not the right thing to do. Things should either be applications or not. Python doesn't currently participate in the "script" infrastructure on Mac OS X.
Well, on Mac OS X, you don't install graphical applications, they're self-contained application bundles that you just put wherever you want and run. Installers, on Mac OS X, are for crappy applications that don't do things the right way. -bob

At 05:13 PM 5/29/2005 -0700, Bob Ippolito wrote:
Okay, sure.
Um, yeah. I'm trying to say that I want a way to create a crappy cross-platform application. :) Let's say I write a wx app (yes, it'll be nasty-looking on the Mac, I get it), and just want to distribute it as a cross-platform egg (because only its dependencies are impure). I would want there to be a Mac version of EasyInstall that takes this script and makes it into a Python application. You're probably going to tell me that I'm talking about py2app, except for the part where I don't have a Mac myself, so I can't run it. But the application is something useful that people would like to use, even on the Mac, despite its crappy wx-based user interface. Why can't Mac users just download the egg and double-click it or drop it on EasyInstall or whatever the idiomatic thing to do is, to get back an application that they can then drag to wherever they're going to keep it?
Python doesn't currently participate in the "script" infrastructure on Mac OS X.
Unfortunately, I don't even know what this means. I was talking about command-line scripts, in a generic Unix-y sense.
Right, so when EasyInstall is eventually bundled with Python, perhaps there'll be some kind of association such that trying to invoke an egg does the right thing to turn it into an application or something. The idea here is that if you bundle your application as an .egg, then a platform-specific tool should be available to: * Do whatever wrapping or installing is customary for making "an application" available on the platform * Download and install the application's dependencies, perhaps after prompting for optional features (using the "optional dependencies" facility of Eggs) Now, in the case of the Mac, once this is done, you presumably have a valid "application" that you can then distribute any way you see fit. But, if you'd like to have access to cross-platform apps that non-Mac people are writing, it would be a lot more convenient if there were an EasyInstall+py2app tool.

Phillip J. Eby wrote:
That's what I'd be inclined towards. Like, this is what one script I have looks like: #!/usr/bin/env python import os import sys try: here = __file__ except NameError: # Python 2.2 here = sys.argv[0] # For when running directly out of the svn checkout: relative_paste = os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(here))), 'paste') if os.path.exists(relative_paste): sys.path.insert(0, os.path.dirname(relative_paste)) from paste import app_setup sys.exit(app_setup.run(sys.argv)) I think this could be better expressed as: 'script_modules': {'paster': 'paste.app_setup.run'} And that whole script I give above is just a platform (Unixy) way of building that script. Of course command-line scripts don't translate as well to other operating systems and environments. Really these "scripts" should be one instance of an executable, that has a fairly minimal interface (__call__(args)). A richer interface might make the arguments introspectable, with possible platform-specific GUIs built around them, or even richer interfaces. I don't know what those would look like, but it would be nice to leave room for those. I know for a lot of developers, myself included, I could support multiple platforms *if* it's easy to build for these from the platform I use. But if I have to use a Mac to build a Mac distribution (ditto Windows) then (being realistic) I don't distribute things built for the Mac. For the most part this doesn't matter -- the libraries are still quite usable on other platforms -- but this does cause problems for scripts. -- Ian Bicking / ianb@colorstudy.com / http://blog.ianbicking.org

On 5/30/05, Ian Bicking <ianb@colorstudy.com> wrote:
Scripts are a *pain*, basically because so much of the peripheral issues are OS-specific. On Unix, the general preference seems to be a script with no extension, and a #! line, written in Python, for most cases (Unix is nice and uniform like that :-)) On Windows, the file extension determines executability. Opinion seems divided (probably not evenly) between people who prefer a .py extension (along with appropriate PATHEXT/file association magic, which the default install does *not* do) and people who prefer a .bat (or even .exe) wrapper. On Windows, GUI and console applications need to be run with different Python executables, adding another level of complexity. I'd like to see the basic "wrap up a script" functionality tidied up - leave start menu changes, shortcuts, aliases, PATH changes, etc etc, as OS-specific enhancements. Experienced users can do this for themselves, and packagers can write platform-specific "installer" scripts where appropriate. (Personally, I dislike most installers' choices for start menu items anyway :-)) The python -m option solves 90% of the script issue in my view. Simply write your driver script as a Python module, and install it as such. Then it can be invoked via python -m (or pythonw -m if it's a GUI application). Most of the remaining 10% would be covered by extending -m to packages. There is a Cookbook recipe which demonstrates a module which can do this (so we have "python -m execpackage my.package.script arg1 arg2...") but it would be nice if this were built in. This is mainly a namespace issue, though. For eggs, we're 90% of the way to executable eggs. All that's needed is a way of adding a particular egg to sys.path, then using the -m machinery (with a standard module name, such as main, or maybe requiring the user to specify a module, effectively an egg "subcommand", or possibly reading egg metadata). This could be implemented as an egg.py module, so you'd have python -m egg path/to/my/sample.egg arg... (invokes the main module, or one from egg metadata). python -m egg -m subcmd path/to/my/sample.egg arg... (invokes the subcmd module - maybe -m for the subcmd option name isn't an ideal choice...) Of course, on Unix, this can be handled by temporary environment variable setting, like PYTHONPATH=path/to/my/sample.egg python -m main arg... but the point here is to make it cross-platform. As I say, the command lines can look a bit clumsy, but wrapping that up in an alias, or desktop shortcut, or whatever, is something I explicitly defer to platform-specific installers. You'll notice that I've completely sidestepped the idea that distutils build "appropriate" wrappers or launchers, or tweak extensions. Past experience has shown that it's incredibly hard to get any consensus on this sort of thing. But it *is* possible (IMHO) to get 90% of the way there, just by getting people to use -m compatible modules. Of course, that isn't 2.3 compatible. But I'd rather move forward than keep trying to work around the same issues - -m was added to address something that people had tried, and failed, to solve in pure Python 2.3, so why reopen that again? Paul.

At 04:16 PM 6/5/2005 +0100, Paul Moore wrote:
I like these ideas, but for the moment, I think we need to make existing packages' scripts work, or there's not going to be enough initial adoption. My current plan is to simply tack an extra line between the #! line and the rest of the script, assuming it has either a .py extension or a #! line containing "python". The line would read something like: import pkg_resources; pkg_resources.require("OwningPackage==exactversion"); del pkg_resources This would work as long as there were no 'from __future__' import lines in the script. (Which we could check for, and move the line after, but I'm not sure I want to get that complicated, certainly not in the first version of the feature.) The script would then be installed according to normal distutils practices in all other respects. Of course, to support this, bdist_egg will need to add the scripts to an 'EGG-INFO/scripts' subdirectory. That way, you get them even when installing from an egg, and when you switch active library versions using EasyInstall, it can remove the old scripts and install the new ones.
I'd definitely like to encourage people to do that, and build up assistive infrastructure for it. But, EasyInstall has to have a strategy for dealing with today's scripts, or it's not very useful today.

Paul Moore wrote:
I agree that Windows scripts are messy and poorly understood. I for one don't have any opinion or knowledge about how to make a well-behaved Windows script...
... however, I know how to make a good script on Unix and Mac machines, and I'm hardly going to give that up for Windows. I'd have a hard time replacing: paster serve with: python -m execpackage paste.app_setup serve Or even: /path/to/svn/checkout/scripts/paster serve With: PYTHONPATH=/path/to/svn/checkout python -m execpackage paste.app_setup serve And I don't even know how to do that on Windows. So, right now the status quo is perfectly fine on Unixy machines, and we can't make that worse.
I would be fine with that too, but I think installers need to take up the cause before this will work. And anyway, easy_install is an installer, so this is within its scope. I think I'd like these semantics: setup(... script_packages=[{'paster': 'paste.app_setup:main'}]) Then a script is generated by that name (with some extension on Windows, I don't care what), and it does: import paste.app_setup sys.exit(main(sys.argv) or 0) Well... somewhere in there it would be nice to make the distinction between console and GUI applications, to make that script use pythonw on Windows. One issue, though, is how to run the script differently. For instance, how to use a different installation/version of Python, or how to best setup or change sys.path. For instance, I always try to detect if the script is being run out of a checkout, and fix up the path when doing so (not only does this avoid PYTHONPATH setup, it means that you won't accidentally run a script with a perhaps older installed version of a package if you forget to fix PYTHONPATH).
I don't see why this should be so difficult to come to consensus on. So far consensus hasn't been very useful, because consensus would just turn into ad hoc scripts and installation processes. Recipes can't build consensus; but setuptools is actual code, not a recipe. And how strongly can people feel about .bat vs. .py vs. .exe? These aren't interesting enough problems to deserve fanaticism ;) -- Ian Bicking / ianb@colorstudy.com / http://blog.ianbicking.org

On 6/5/05, Ian Bicking <ianb@colorstudy.com> wrote:
I do :-) Or at least, I think I do... :-)
... however, I know how to make a good script on Unix and Mac machines, and I'm hardly going to give that up for Windows.
But if you make your code work via -m, then at least you haven't left us poor Windows users without any driver script at all!
I didn't intend for one moment to suggest that we should. But I do feel, quite strongly, that it's platform-specific. People keep trying to make wrapper scripts "just work" cross-platform, and that's what I see as the mistake. OTOH, python -m execpackage paste.app_setup serve *can* be cross-platform. So writing a Unix wrapper round that, and a different Windows-specific wrapper, etc, is not an unreasonable approach. (Nor is writing a more capable Unix-specific implementation). Why do you need your "paster" script to be more complex than #!/bin/sh exec python -m execpackage paste.app_setup $* (excuse my pidgin Unix - assume I knew enough to write this properly :-))? What *I* am trying to move away from is having non-trivial cross-platform code in .py files installed as scripts. An example is with Twisted, twistd.py is installed as a script, but it has some non-trivial platform detection logic in it. It wouldn't take much to move that logic to the twisted.scripts.twistd module (or somewhere similar) so the twistd daemon could be run directly from a python -m invocation. Keep a trivial wrapper by all means, but don't make the wrapper the only way of getting the functionality.
Welcome to Windows :-) Seriously, some issues: 1. .exe is binary, so not customisable. Also, you need two versions of any wrapper exe, one a console app and one a GUI one. But this is not a bad option. Fredrik Lundh has implemented something along these likes (exemaker). It's not a popular option though - maybe because the binaries must be built on Windows, maybe because of virus concerns, I don't know. 2. The default Python installer doesn't do all of the necessary magicto make .py files "executable". That's a deliberate policy decision, and not likely to change. It's my preference, though (I make the necessary changes manually). 3. .bat files are mildly, but annoyingly, non-cross-platform. As Windows 9x and command.com die, this is becoming less of an issue, but it's still there. Also, if you hit Ctrl-C to interrupt a .bat wrapper, the OS generates a horribly unfriendly "Abort batch job (Yes/No/Cancel)?" prompt. Oh, and there is no way to use .bat files to create a GUI wrapper - you *always* get a console window. As I say, my preference is (2), and I can argue that it's the only good one. But it ain't going to happen, so we're left with irritating workarounds. As long as I can get all I need by just ignoring the Python scripts directory, that's fine - but while some scripts include nontrivial logic, I can't do that. Paul.

At 03:56 PM 5/29/2005 -0500, Ian Bicking wrote:
Yep. Like you, however, I'm not sure what to do about 'em. Take a look at the Unix versions of easy_install -- they're actually the regular .egg files, with a shell script cat'ted on at the front! (Somebody could probably pull the same trick with an .exe on Windows.) However, such "eggsecutables" aren't really a solution for packages with multiple scripts. I'm thinking maybe bdist_egg should include an EGG-SCRIPTS directory for the scripts, so that EasyInstall could pull them out and install them whenever you do a non --multi-version install. It would, however, also need to *uninstall* them when deactivating a current version, because otherwise they'd be for the wrong version. I had previously thought that we would move towards using "python -m" to run scripts in eggs; unfortunately this only works for unpacked eggs, not egg files. Of course, this all just overlaps the fact that distutils script installation is really only good for command-line utilities anyway, and even for those, Windows requires a fair bit of tweaking in order to be able to use them effectively at a non-Cygwin command line. It might help if there were some kind of metadata for scripts, like to indicate whether something is a command-line utility, a graphical application, etc. Then distutils could tweak the file extension and/or build a custom launcher for it (like Fredrik Lundh's exemaker for Windows) as appropriate for the platform. That information could then be added to EGG-INFO and/or EGG-SCRIPTS, and used by EasyInstall to do script installation and uninstallation.

On May 29, 2005, at 3:46 PM, Phillip J. Eby wrote:
Couldn't you change build_scripts and install_scripts when using bdist_egg to instead put the script inside the egg somewhere, and the installer would put scripts in the usual places that simply require and then exec the real script? -bob

At 04:43 PM 5/29/2005 -0700, Bob Ippolito wrote:
That's more or less what I was proposing, except that I wouldn't use build_scripts or install_scripts, just pack the original source scripts into the egg, and then let the installer do its thing at the other end. That way, a cross-platform egg wouldn't have any platform-specific stuff baked into the scripts accidentally. It's not as if build_scripts or install_scripts do anything of consequence at the moment anyway; they just munge the #! line and copy the files (as of Python 2.3 anyway). My main thought is distinguishing console vs. GUI start scripts. I don't believe there's a Mac equivalent to '.pyw', for example. Also, at some point EasyInstall really could support adding desktop shortcuts (or Start menu entries or whatever you call them on a given platform) for applications bundled in eggs. Sort of an end-user py2exe/py2app thing. On the other hand, it does seem a little silly to use a command-line tool to install a graphical application. :) However, it probably makes sense to create platform-specific GUI wrappers around EasyInstall to do this sort of thing.

On May 29, 2005, at 5:01 PM, Phillip J. Eby wrote:
I guess, I don't think it really matters. If platform specific stuff gets baked into the scripts somehow, then they probably won't work without it. The #! line is of course of no consequence in-egg.
There is a Mac equivalent to '.pyw', it's the same thing (except .py files don't normally launch with a terminal attached, so really all Python scripts are treated as .pyw .. which is probably a bug). Mac OS X doesn't condone applications touching the user's dock, so the "start menu" thing is out. As for putting the applications in a reasonable place, the "reasonable place" depends on the user. The best solution might be to just pop open the dist folder and let the user drag it to where they want it, or to put it in a disk image and mount it. Anyway, "GUI scripts" is mostly a non-starter on OS X, it's generally not the right thing to do. Things should either be applications or not. Python doesn't currently participate in the "script" infrastructure on Mac OS X.
Well, on Mac OS X, you don't install graphical applications, they're self-contained application bundles that you just put wherever you want and run. Installers, on Mac OS X, are for crappy applications that don't do things the right way. -bob

At 05:13 PM 5/29/2005 -0700, Bob Ippolito wrote:
Okay, sure.
Um, yeah. I'm trying to say that I want a way to create a crappy cross-platform application. :) Let's say I write a wx app (yes, it'll be nasty-looking on the Mac, I get it), and just want to distribute it as a cross-platform egg (because only its dependencies are impure). I would want there to be a Mac version of EasyInstall that takes this script and makes it into a Python application. You're probably going to tell me that I'm talking about py2app, except for the part where I don't have a Mac myself, so I can't run it. But the application is something useful that people would like to use, even on the Mac, despite its crappy wx-based user interface. Why can't Mac users just download the egg and double-click it or drop it on EasyInstall or whatever the idiomatic thing to do is, to get back an application that they can then drag to wherever they're going to keep it?
Python doesn't currently participate in the "script" infrastructure on Mac OS X.
Unfortunately, I don't even know what this means. I was talking about command-line scripts, in a generic Unix-y sense.
Right, so when EasyInstall is eventually bundled with Python, perhaps there'll be some kind of association such that trying to invoke an egg does the right thing to turn it into an application or something. The idea here is that if you bundle your application as an .egg, then a platform-specific tool should be available to: * Do whatever wrapping or installing is customary for making "an application" available on the platform * Download and install the application's dependencies, perhaps after prompting for optional features (using the "optional dependencies" facility of Eggs) Now, in the case of the Mac, once this is done, you presumably have a valid "application" that you can then distribute any way you see fit. But, if you'd like to have access to cross-platform apps that non-Mac people are writing, it would be a lot more convenient if there were an EasyInstall+py2app tool.

Phillip J. Eby wrote:
That's what I'd be inclined towards. Like, this is what one script I have looks like: #!/usr/bin/env python import os import sys try: here = __file__ except NameError: # Python 2.2 here = sys.argv[0] # For when running directly out of the svn checkout: relative_paste = os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(here))), 'paste') if os.path.exists(relative_paste): sys.path.insert(0, os.path.dirname(relative_paste)) from paste import app_setup sys.exit(app_setup.run(sys.argv)) I think this could be better expressed as: 'script_modules': {'paster': 'paste.app_setup.run'} And that whole script I give above is just a platform (Unixy) way of building that script. Of course command-line scripts don't translate as well to other operating systems and environments. Really these "scripts" should be one instance of an executable, that has a fairly minimal interface (__call__(args)). A richer interface might make the arguments introspectable, with possible platform-specific GUIs built around them, or even richer interfaces. I don't know what those would look like, but it would be nice to leave room for those. I know for a lot of developers, myself included, I could support multiple platforms *if* it's easy to build for these from the platform I use. But if I have to use a Mac to build a Mac distribution (ditto Windows) then (being realistic) I don't distribute things built for the Mac. For the most part this doesn't matter -- the libraries are still quite usable on other platforms -- but this does cause problems for scripts. -- Ian Bicking / ianb@colorstudy.com / http://blog.ianbicking.org

On 5/30/05, Ian Bicking <ianb@colorstudy.com> wrote:
Scripts are a *pain*, basically because so much of the peripheral issues are OS-specific. On Unix, the general preference seems to be a script with no extension, and a #! line, written in Python, for most cases (Unix is nice and uniform like that :-)) On Windows, the file extension determines executability. Opinion seems divided (probably not evenly) between people who prefer a .py extension (along with appropriate PATHEXT/file association magic, which the default install does *not* do) and people who prefer a .bat (or even .exe) wrapper. On Windows, GUI and console applications need to be run with different Python executables, adding another level of complexity. I'd like to see the basic "wrap up a script" functionality tidied up - leave start menu changes, shortcuts, aliases, PATH changes, etc etc, as OS-specific enhancements. Experienced users can do this for themselves, and packagers can write platform-specific "installer" scripts where appropriate. (Personally, I dislike most installers' choices for start menu items anyway :-)) The python -m option solves 90% of the script issue in my view. Simply write your driver script as a Python module, and install it as such. Then it can be invoked via python -m (or pythonw -m if it's a GUI application). Most of the remaining 10% would be covered by extending -m to packages. There is a Cookbook recipe which demonstrates a module which can do this (so we have "python -m execpackage my.package.script arg1 arg2...") but it would be nice if this were built in. This is mainly a namespace issue, though. For eggs, we're 90% of the way to executable eggs. All that's needed is a way of adding a particular egg to sys.path, then using the -m machinery (with a standard module name, such as main, or maybe requiring the user to specify a module, effectively an egg "subcommand", or possibly reading egg metadata). This could be implemented as an egg.py module, so you'd have python -m egg path/to/my/sample.egg arg... (invokes the main module, or one from egg metadata). python -m egg -m subcmd path/to/my/sample.egg arg... (invokes the subcmd module - maybe -m for the subcmd option name isn't an ideal choice...) Of course, on Unix, this can be handled by temporary environment variable setting, like PYTHONPATH=path/to/my/sample.egg python -m main arg... but the point here is to make it cross-platform. As I say, the command lines can look a bit clumsy, but wrapping that up in an alias, or desktop shortcut, or whatever, is something I explicitly defer to platform-specific installers. You'll notice that I've completely sidestepped the idea that distutils build "appropriate" wrappers or launchers, or tweak extensions. Past experience has shown that it's incredibly hard to get any consensus on this sort of thing. But it *is* possible (IMHO) to get 90% of the way there, just by getting people to use -m compatible modules. Of course, that isn't 2.3 compatible. But I'd rather move forward than keep trying to work around the same issues - -m was added to address something that people had tried, and failed, to solve in pure Python 2.3, so why reopen that again? Paul.

At 04:16 PM 6/5/2005 +0100, Paul Moore wrote:
I like these ideas, but for the moment, I think we need to make existing packages' scripts work, or there's not going to be enough initial adoption. My current plan is to simply tack an extra line between the #! line and the rest of the script, assuming it has either a .py extension or a #! line containing "python". The line would read something like: import pkg_resources; pkg_resources.require("OwningPackage==exactversion"); del pkg_resources This would work as long as there were no 'from __future__' import lines in the script. (Which we could check for, and move the line after, but I'm not sure I want to get that complicated, certainly not in the first version of the feature.) The script would then be installed according to normal distutils practices in all other respects. Of course, to support this, bdist_egg will need to add the scripts to an 'EGG-INFO/scripts' subdirectory. That way, you get them even when installing from an egg, and when you switch active library versions using EasyInstall, it can remove the old scripts and install the new ones.
I'd definitely like to encourage people to do that, and build up assistive infrastructure for it. But, EasyInstall has to have a strategy for dealing with today's scripts, or it's not very useful today.

Paul Moore wrote:
I agree that Windows scripts are messy and poorly understood. I for one don't have any opinion or knowledge about how to make a well-behaved Windows script...
... however, I know how to make a good script on Unix and Mac machines, and I'm hardly going to give that up for Windows. I'd have a hard time replacing: paster serve with: python -m execpackage paste.app_setup serve Or even: /path/to/svn/checkout/scripts/paster serve With: PYTHONPATH=/path/to/svn/checkout python -m execpackage paste.app_setup serve And I don't even know how to do that on Windows. So, right now the status quo is perfectly fine on Unixy machines, and we can't make that worse.
I would be fine with that too, but I think installers need to take up the cause before this will work. And anyway, easy_install is an installer, so this is within its scope. I think I'd like these semantics: setup(... script_packages=[{'paster': 'paste.app_setup:main'}]) Then a script is generated by that name (with some extension on Windows, I don't care what), and it does: import paste.app_setup sys.exit(main(sys.argv) or 0) Well... somewhere in there it would be nice to make the distinction between console and GUI applications, to make that script use pythonw on Windows. One issue, though, is how to run the script differently. For instance, how to use a different installation/version of Python, or how to best setup or change sys.path. For instance, I always try to detect if the script is being run out of a checkout, and fix up the path when doing so (not only does this avoid PYTHONPATH setup, it means that you won't accidentally run a script with a perhaps older installed version of a package if you forget to fix PYTHONPATH).
I don't see why this should be so difficult to come to consensus on. So far consensus hasn't been very useful, because consensus would just turn into ad hoc scripts and installation processes. Recipes can't build consensus; but setuptools is actual code, not a recipe. And how strongly can people feel about .bat vs. .py vs. .exe? These aren't interesting enough problems to deserve fanaticism ;) -- Ian Bicking / ianb@colorstudy.com / http://blog.ianbicking.org

On 6/5/05, Ian Bicking <ianb@colorstudy.com> wrote:
I do :-) Or at least, I think I do... :-)
... however, I know how to make a good script on Unix and Mac machines, and I'm hardly going to give that up for Windows.
But if you make your code work via -m, then at least you haven't left us poor Windows users without any driver script at all!
I didn't intend for one moment to suggest that we should. But I do feel, quite strongly, that it's platform-specific. People keep trying to make wrapper scripts "just work" cross-platform, and that's what I see as the mistake. OTOH, python -m execpackage paste.app_setup serve *can* be cross-platform. So writing a Unix wrapper round that, and a different Windows-specific wrapper, etc, is not an unreasonable approach. (Nor is writing a more capable Unix-specific implementation). Why do you need your "paster" script to be more complex than #!/bin/sh exec python -m execpackage paste.app_setup $* (excuse my pidgin Unix - assume I knew enough to write this properly :-))? What *I* am trying to move away from is having non-trivial cross-platform code in .py files installed as scripts. An example is with Twisted, twistd.py is installed as a script, but it has some non-trivial platform detection logic in it. It wouldn't take much to move that logic to the twisted.scripts.twistd module (or somewhere similar) so the twistd daemon could be run directly from a python -m invocation. Keep a trivial wrapper by all means, but don't make the wrapper the only way of getting the functionality.
Welcome to Windows :-) Seriously, some issues: 1. .exe is binary, so not customisable. Also, you need two versions of any wrapper exe, one a console app and one a GUI one. But this is not a bad option. Fredrik Lundh has implemented something along these likes (exemaker). It's not a popular option though - maybe because the binaries must be built on Windows, maybe because of virus concerns, I don't know. 2. The default Python installer doesn't do all of the necessary magicto make .py files "executable". That's a deliberate policy decision, and not likely to change. It's my preference, though (I make the necessary changes manually). 3. .bat files are mildly, but annoyingly, non-cross-platform. As Windows 9x and command.com die, this is becoming less of an issue, but it's still there. Also, if you hit Ctrl-C to interrupt a .bat wrapper, the OS generates a horribly unfriendly "Abort batch job (Yes/No/Cancel)?" prompt. Oh, and there is no way to use .bat files to create a GUI wrapper - you *always* get a console window. As I say, my preference is (2), and I can argue that it's the only good one. But it ain't going to happen, so we're left with irritating workarounds. As long as I can get all I need by just ignoring the Python scripts directory, that's fine - but while some scripts include nontrivial logic, I can't do that. Paul.
participants (4)
-
Bob Ippolito
-
Ian Bicking
-
Paul Moore
-
Phillip J. Eby