crossplatform py2exe - would it be useful?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Thomas Heller

    crossplatform py2exe - would it be useful?

    I'm currently working on a new version of py2exe, which will require
    Python 2.3 and later, because it uses the zipimport mechanism.

    Since py2exe is a distutils extension, and since C compilers are
    commonly available on most platforms except Windows, it would be fairly
    easy to let py2exe generate a C source file installing this import hook,
    and let distutils' C compiler build an executable file from this.

    Would this be useful, or would I be wasting my time, since McMillan
    installer, cx_freeze, and tools/freeze already do it?

    At the end of this post you'll find excerpts from the readme file, which
    is currently the only documentation available.

    Thomas

    The readme file:

    A new and improved py2exe for Python 2.3
    =============== =============== ==========

    Uses the zipimport mechanism, so it requires Python 2.3 or later. The
    zipimport mechanism is able to handle the early imports of the
    warnings and also the encodings module which is done by Python.

    Creates a single directory, which must be deployed completely.

    (Most of this is based on ideas of Mark Hammond:) Can create any
    number of console and gui executables in this directory, plus
    optionally a windows service exe, plus optionally an exe and dll com
    server. The com servers can expose one or more com object classes.

    All pure Python files are contained in a single zip archive, which is
    shared by all the executables. The zip archive may also be used by
    programs embedding Python. Since extension modules cannot be imported
    from zipfiles, a simple pure Python loader is included in the zipfile
    which loads the extension from the file system (without requiring that
    the directory is in sys.path).

    It would be nice if the executables could be run with only a single
    sys.path entry containing the absolute filename of the zipfile, but it
    seems for dll com servers the executable's directory is also
    needed. The absolute filenames are constructed at runtime from the
    directory containing the executable, and the zipfile name specified at
    build time.

    The way has changed how build targets are specified in the setup
    script. py2exe installs it own Distribution subclass, which enables
    additional keyword arguments to the setup function:

    console = [...] # list of scripts to convert into console executables
    windows = [...] # list of scripts to convert into gui executables
    com_servers = [...] # list of fully qualified class names to build into the exe com server
    service = [...] # list of fully qualified class names to build into a service executable
    zipfile = "xxx.zip" # filename of the zipfile containing the pure Python modules

    All of the above arguments are optional. The zipfile name defaults to
    'library.zip'.
  • Kevin Cazabon

    #2
    Re: crossplatform py2exe - would it be useful?

    Hi Thomas;

    I've tried Freeze before, but I'm hooked on py2exe because it's so
    SIMPLE and flexible, and handles all the weird cases automatically.. .
    For those of us that aren't C gurus, anything that makes the process
    easier is welcome.

    To clarify your proposal, would you simply build the executable using
    the same setup.py script on other platforms too, or would you have to
    do more manual steps?

    Thanks for the great work so far... py2exe ROCKS! q:]

    Kevin.


    Thomas Heller <theller@python .net> wrote in message news:<ptji8wgr. fsf@python.net> ...[color=blue]
    > I'm currently working on a new version of py2exe, which will require
    > Python 2.3 and later, because it uses the zipimport mechanism.
    >
    > Since py2exe is a distutils extension, and since C compilers are
    > commonly available on most platforms except Windows, it would be fairly
    > easy to let py2exe generate a C source file installing this import hook,
    > and let distutils' C compiler build an executable file from this.
    >
    > Would this be useful, or would I be wasting my time, since McMillan
    > installer, cx_freeze, and tools/freeze already do it?
    >
    > At the end of this post you'll find excerpts from the readme file, which
    > is currently the only documentation available.
    >
    > Thomas
    >
    > The readme file:
    >
    > A new and improved py2exe for Python 2.3
    > =============== =============== ==========
    >
    > Uses the zipimport mechanism, so it requires Python 2.3 or later. The
    > zipimport mechanism is able to handle the early imports of the
    > warnings and also the encodings module which is done by Python.
    >
    > Creates a single directory, which must be deployed completely.
    >
    > (Most of this is based on ideas of Mark Hammond:) Can create any
    > number of console and gui executables in this directory, plus
    > optionally a windows service exe, plus optionally an exe and dll com
    > server. The com servers can expose one or more com object classes.
    >
    > All pure Python files are contained in a single zip archive, which is
    > shared by all the executables. The zip archive may also be used by
    > programs embedding Python. Since extension modules cannot be imported
    > from zipfiles, a simple pure Python loader is included in the zipfile
    > which loads the extension from the file system (without requiring that
    > the directory is in sys.path).
    >
    > It would be nice if the executables could be run with only a single
    > sys.path entry containing the absolute filename of the zipfile, but it
    > seems for dll com servers the executable's directory is also
    > needed. The absolute filenames are constructed at runtime from the
    > directory containing the executable, and the zipfile name specified at
    > build time.
    >
    > The way has changed how build targets are specified in the setup
    > script. py2exe installs it own Distribution subclass, which enables
    > additional keyword arguments to the setup function:
    >
    > console = [...] # list of scripts to convert into console executables
    > windows = [...] # list of scripts to convert into gui executables
    > com_servers = [...] # list of fully qualified class names to build into the exe com server
    > service = [...] # list of fully qualified class names to build into a service executable
    > zipfile = "xxx.zip" # filename of the zipfile containing the pure Python modules
    >
    > All of the above arguments are optional. The zipfile name defaults to
    > 'library.zip'.[/color]

    Comment

    • Alex Martelli

      #3
      Re: crossplatform py2exe - would it be useful?

      Thomas Heller wrote:
      [color=blue]
      > I'm currently working on a new version of py2exe, which will require
      > Python 2.3 and later, because it uses the zipimport mechanism.
      >
      > Since py2exe is a distutils extension, and since C compilers are
      > commonly available on most platforms except Windows, it would be fairly
      > easy to let py2exe generate a C source file installing this import hook,
      > and let distutils' C compiler build an executable file from this.
      >
      > Would this be useful, or would I be wasting my time, since McMillan
      > installer, cx_freeze, and tools/freeze already do it?[/color]

      I think it would be a WONDERFUL idea: py2exe is the simplest to use
      of all the tools you mention, and it would save a lot of ink^H^H^H pixels,
      each time I point people to it, to be able to omit the blurb about "if
      you're interested in deploying to Windows platform only, then"...:-).


      Alex

      Comment

      • Oren Tirosh

        #4
        Re: crossplatform py2exe - would it be useful?

        On Wed, Aug 06, 2003 at 08:36:20PM +0200, Thomas Heller wrote:[color=blue]
        > I'm currently working on a new version of py2exe, which will require
        > Python 2.3 and later, because it uses the zipimport mechanism.[/color]

        Now that zipimport is part of Python the code required for bootstrapping
        a py2exe runtime is just:

        myscript -c "import sys; sys.path.insert (0, sys.executable) ; import foo"

        This reduces the difference between the custom interpreter supplied with
        py2exe and the standard interpreter to just a few lines of C.

        The obvious question is - why not go all the way and put this little
        hook into the standard Python distribution? This way py2exe could be a
        platform-independent pure Python application. In fact, py2exe wouldn't
        actually be necessary because anyone could create a zip file manually and
        append it to the executable but it's more convenient to have a tool that
        automates the process and finds the required dependencies.

        Oren

        Comment

        • Alex Martelli

          #5
          Re: crossplatform py2exe - would it be useful?

          Oren Tirosh wrote:
          [color=blue]
          > On Wed, Aug 06, 2003 at 08:36:20PM +0200, Thomas Heller wrote:[color=green]
          >> I'm currently working on a new version of py2exe, which will require
          >> Python 2.3 and later, because it uses the zipimport mechanism.[/color]
          >
          > Now that zipimport is part of Python the code required for bootstrapping
          > a py2exe runtime is just:
          >
          > myscript -c "import sys; sys.path.insert (0, sys.executable) ; import foo"
          >
          > This reduces the difference between the custom interpreter supplied with
          > py2exe and the standard interpreter to just a few lines of C.
          >
          > The obvious question is - why not go all the way and put this little
          > hook into the standard Python distribution? This way py2exe could be a
          > platform-independent pure Python application. In fact, py2exe wouldn't
          > actually be necessary because anyone could create a zip file manually and
          > append it to the executable but it's more convenient to have a tool that
          > automates the process and finds the required dependencies.[/color]

          Sounds like a good idea to me, if a sensible name is chosen for the
          "main module" (I propose 'main':-). Take it to Python-Dev...? I even
          wonder if it's unobtrusive enough to be considered (as a "bugfix"... :-)
          for 2.3.1, rather than having to get into 2.4 and thus wait a LONG time...


          Alex


          Comment

          • Thomas Heller

            #6
            Re: crossplatform py2exe - would it be useful?

            Oren Tirosh <oren-py-l@hishome.net> writes:
            [color=blue]
            > On Wed, Aug 06, 2003 at 08:36:20PM +0200, Thomas Heller wrote:[color=green]
            >> I'm currently working on a new version of py2exe, which will require
            >> Python 2.3 and later, because it uses the zipimport mechanism.[/color]
            >
            > Now that zipimport is part of Python the code required for bootstrapping
            > a py2exe runtime is just:
            >
            > myscript -c "import sys; sys.path.insert (0, sys.executable) ; import foo"
            >[/color]

            Yes, something like this is also what I am thinking now. And 'myscript'
            is just a copy of the standard interpreter. Although the sys.path entry
            must be present *before* Py_Initialize is called.
            [color=blue]
            > This reduces the difference between the custom interpreter supplied with
            > py2exe and the standard interpreter to just a few lines of C.
            >
            > The obvious question is - why not go all the way and put this little
            > hook into the standard Python distribution? This way py2exe could be a
            > platform-independent pure Python application. In fact, py2exe wouldn't
            > actually be necessary because anyone could create a zip file manually and
            > append it to the executable but it's more convenient to have a tool that
            > automates the process and finds the required dependencies.[/color]

            Yes, and modulefinder is now in the standard library.

            OTOH, py2exe does a little bit more: It has a mechanism to supply
            modules to include which modulefinder doesn't find, exclude modules
            which are unneeded although found, can detect whether Tkinter is used
            and copy it, scan (on Windows) extensions for dlls they need (wxPython
            needs the wxWindows dll, for example), handle hidden imports from C code
            in Python itself and extensions, and so on.

            And it works around the fact that extension modules cannot be loaded
            from zipfiles, it creates a pure Python loader included in the zip for
            them.

            Having said that, I would have nothing against py2exe included in the
            standard distribution, and the hooks in place.

            Thanks,

            Thomas

            Comment

            • Thomas Heller

              #7
              Re: crossplatform py2exe - would it be useful?

              Alex Martelli <aleax@aleax.it > writes:
              [color=blue]
              > Oren Tirosh wrote:
              >[color=green]
              >> On Wed, Aug 06, 2003 at 08:36:20PM +0200, Thomas Heller wrote:[color=darkred]
              >>> I'm currently working on a new version of py2exe, which will require
              >>> Python 2.3 and later, because it uses the zipimport mechanism.[/color]
              >>
              >> Now that zipimport is part of Python the code required for bootstrapping
              >> a py2exe runtime is just:
              >>
              >> myscript -c "import sys; sys.path.insert (0, sys.executable) ; import foo"
              >>
              >> This reduces the difference between the custom interpreter supplied with
              >> py2exe and the standard interpreter to just a few lines of C.
              >>
              >> The obvious question is - why not go all the way and put this little
              >> hook into the standard Python distribution? This way py2exe could be a
              >> platform-independent pure Python application. In fact, py2exe wouldn't
              >> actually be necessary because anyone could create a zip file manually and
              >> append it to the executable but it's more convenient to have a tool that
              >> automates the process and finds the required dependencies.[/color]
              >
              > Sounds like a good idea to me, if a sensible name is chosen for the
              > "main module" (I propose 'main':-).[/color]

              My choice would have been __main__ :-) Is it really the correct way to
              'import __main__' instead of 'running' it?
              [color=blue]
              > Take it to Python-Dev...? I even wonder if it's unobtrusive enough to
              > be considered (as a "bugfix"... :-) for 2.3.1, rather than having to
              > get into 2.4 and thus wait a LONG time...
              >
              >
              > Alex[/color]

              Thomas

              Comment

              • Alex Martelli

                #8
                Re: crossplatform py2exe - would it be useful?

                Thomas Heller wrote:
                ...[color=blue][color=green][color=darkred]
                >>> myscript -c "import sys; sys.path.insert (0, sys.executable) ; import foo"[/color][/color][/color]
                ...[color=blue][color=green]
                >> Sounds like a good idea to me, if a sensible name is chosen for the
                >> "main module" (I propose 'main':-).[/color]
                >
                > My choice would have been __main__ :-) Is it really the correct way to
                > 'import __main__' instead of 'running' it?[/color]

                Well, most main scripts ARE coded with the "if __name__=='__ma in__':"
                convention, after all, so an "import __main__" can be seen as a way
                to just piggyback on that existing convention rather than inventing a
                new one in addition. So, I concede it's better than "import main".


                Alex

                Comment

                • Thomas Heller

                  #9
                  Re: crossplatform py2exe - would it be useful?

                  Alex Martelli <aleax@aleax.it > writes:
                  [color=blue]
                  > Thomas Heller wrote:
                  > ...[color=green][color=darkred]
                  >>>> myscript -c "import sys; sys.path.insert (0, sys.executable) ; import foo"[/color][/color]
                  > ...[color=green][color=darkred]
                  >>> Sounds like a good idea to me, if a sensible name is chosen for the
                  >>> "main module" (I propose 'main':-).[/color]
                  >>
                  >> My choice would have been __main__ :-) Is it really the correct way to
                  >> 'import __main__' instead of 'running' it?[/color]
                  >
                  > Well, most main scripts ARE coded with the "if __name__=='__ma in__':"
                  > convention, after all, so an "import __main__" can be seen as a way
                  > to just piggyback on that existing convention rather than inventing a
                  > new one in addition. So, I concede it's better than "import main".
                  >[/color]

                  How would the hook be triggered? The zipimporter code would probably add
                  argv[0] to sys.path, and then try to 'import __main__' or something like
                  this. The problem is that a standalone executable python would have to
                  disable the standard Python command line flags and environment
                  variables, but they are parse *before* Py_Initialize() is called.

                  And I hope that the options set by the command line flags and env vars
                  should now come from the __main__ script itself.

                  Thomas

                  Comment

                  • Alex Martelli

                    #10
                    Re: crossplatform py2exe - would it be useful?

                    Thomas Heller wrote:
                    [color=blue]
                    > Alex Martelli <aleax@aleax.it > writes:
                    >[color=green]
                    >> Thomas Heller wrote:
                    >> ...[color=darkred]
                    >>>>> myscript -c "import sys; sys.path.insert (0, sys.executable) ; import
                    >>>>> foo"[/color]
                    >> ...[color=darkred]
                    >>>> Sounds like a good idea to me, if a sensible name is chosen for the
                    >>>> "main module" (I propose 'main':-).
                    >>>
                    >>> My choice would have been __main__ :-) Is it really the correct way to
                    >>> 'import __main__' instead of 'running' it?[/color]
                    >>
                    >> Well, most main scripts ARE coded with the "if __name__=='__ma in__':"
                    >> convention, after all, so an "import __main__" can be seen as a way
                    >> to just piggyback on that existing convention rather than inventing a
                    >> new one in addition. So, I concede it's better than "import main".
                    >>[/color]
                    >
                    > How would the hook be triggered? The zipimporter code would probably add
                    > argv[0] to sys.path, and then try to 'import __main__' or something like
                    > this. The problem is that a standalone executable python would have to
                    > disable the standard Python command line flags and environment
                    > variables, but they are parse *before* Py_Initialize() is called.[/color]

                    Ah, yes, good point. So, the executable needs to know whether to do
                    the usual commandline and environment processing, or not, _before_
                    calling Py_Inizialize. One approach might be to trigger this based
                    on the executable's own *name* -- do the full commandline and environment
                    processing if and only if the executable's name starts with (case-
                    insensitive, probably, to be safe...) the six letters 'python', but
                    not otherwise. There are, no doubt, other alternative ways, too, but
                    this one seems dirt-simple and practically sufficient.

                    [color=blue]
                    > And I hope that the options set by the command line flags and env vars
                    > should now come from the __main__ script itself.[/color]

                    I'm not sure I understand what you mean. Anyway, I do see that if
                    my 'foobar.exe' is a python.exe + appended zipfile, then running
                    'foobar -i' should just put '-i' in sys.argv[1], and NOT gobble it up
                    to mean "enter interactive mode", for example.


                    Alex

                    Comment

                    • Thomas Heller

                      #11
                      Re: crossplatform py2exe - would it be useful?

                      Alex Martelli <aleax@aleax.it > writes:
                      [color=blue]
                      > Thomas Heller wrote:
                      >[color=green]
                      >> Alex Martelli <aleax@aleax.it > writes:
                      >>[color=darkred]
                      >>> Thomas Heller wrote:
                      >>> ...
                      >>>>>> myscript -c "import sys; sys.path.insert (0, sys.executable) ; import
                      >>>>>> foo"
                      >>> ...
                      >>>>> Sounds like a good idea to me, if a sensible name is chosen for the
                      >>>>> "main module" (I propose 'main':-).
                      >>>>
                      >>>> My choice would have been __main__ :-) Is it really the correct way to
                      >>>> 'import __main__' instead of 'running' it?
                      >>>
                      >>> Well, most main scripts ARE coded with the "if __name__=='__ma in__':"
                      >>> convention, after all, so an "import __main__" can be seen as a way
                      >>> to just piggyback on that existing convention rather than inventing a
                      >>> new one in addition. So, I concede it's better than "import main".
                      >>>[/color]
                      >>
                      >> How would the hook be triggered? The zipimporter code would probably add
                      >> argv[0] to sys.path, and then try to 'import __main__' or something like
                      >> this. The problem is that a standalone executable python would have to
                      >> disable the standard Python command line flags and environment
                      >> variables, but they are parse *before* Py_Initialize() is called.[/color]
                      >
                      > Ah, yes, good point. So, the executable needs to know whether to do
                      > the usual commandline and environment processing, or not, _before_
                      > calling Py_Inizialize.[/color]

                      Exactly. And it may even be useful to do specail command line
                      processing, an PY2EXEVERBOSE flag might be useful.
                      [color=blue]
                      > One approach might be to trigger this based
                      > on the executable's own *name* -- do the full commandline and environment
                      > processing if and only if the executable's name starts with (case-
                      > insensitive, probably, to be safe...) the six letters 'python', but
                      > not otherwise. There are, no doubt, other alternative ways, too, but
                      > this one seems dirt-simple and practically sufficient.[/color]

                      On windows, where the interpreter is in a dll, providing a custom
                      equivalent to python.exe (as py2exe currently does) is pretty simple.
                      On systems where the interpreter is staically linked, there's no other
                      choice than to recompile and relink the whole pythonm if I understand
                      correctly.
                      [color=blue][color=green]
                      >> And I hope that the options set by the command line flags and env vars
                      >> should now come from the __main__ script itself.[/color]
                      >
                      > I'm not sure I understand what you mean. Anyway, I do see that if
                      > my 'foobar.exe' is a python.exe + appended zipfile, then running
                      > 'foobar -i' should just put '-i' in sys.argv[1], and NOT gobble it up
                      > to mean "enter interactive mode", for example.[/color]

                      You understood. Yes, the command line flags must be passed into
                      sys.argv. But I still want to set the optimize flag and the unbuffered
                      flag at *build* time. I'm quite sure all this cannot be encoded into the
                      filename.

                      Right now, py2exe embeds a struct containing a magic value plus these
                      flags into the exe, just before the zip-archive, but all this unpacking
                      has to be done from C code (because these flags are not writable from
                      Python code), so all this has to be part of the hook.

                      Thomas

                      PS: Since py2exe, even on Linux, doesn't really create a single file
                      executable, there are always some shared libs needed, maybe the first
                      step would be to create a directory containing the interpreter
                      executable with an appended ziparchive, the shared libs needed (zlib.so,
                      maybe more), and a bash script containing something like this (you'll
                      probably see how rusty my *nix skills are nowadays):

                      #!/bin/sh
                      exec python_with_zip -c "<<EOF
                      the script itself
                      "
                      EOF


                      What are the disadvantages of a shell-script against an (elf) executable?

                      Comment

                      • Oren Tirosh

                        #12
                        Re: crossplatform py2exe - would it be useful?

                        On Thu, Aug 07, 2003 at 02:46:24PM +0200, Thomas Heller wrote:[color=blue]
                        > Alex Martelli <aleax@aleax.it > writes:
                        >[color=green]
                        > > Oren Tirosh wrote:
                        > >[color=darkred]
                        > >> On Wed, Aug 06, 2003 at 08:36:20PM +0200, Thomas Heller wrote:
                        > >>> I'm currently working on a new version of py2exe, which will require
                        > >>> Python 2.3 and later, because it uses the zipimport mechanism.
                        > >>
                        > >> Now that zipimport is part of Python the code required for bootstrapping
                        > >> a py2exe runtime is just:
                        > >>
                        > >> myscript -c "import sys; sys.path.insert (0, sys.executable) ; import foo"
                        > >>
                        > >> This reduces the difference between the custom interpreter supplied with
                        > >> py2exe and the standard interpreter to just a few lines of C.
                        > >>
                        > >> The obvious question is - why not go all the way and put this little
                        > >> hook into the standard Python distribution? This way py2exe could be a
                        > >> platform-independent pure Python application. In fact, py2exe wouldn't
                        > >> actually be necessary because anyone could create a zip file manually and
                        > >> append it to the executable but it's more convenient to have a tool that
                        > >> automates the process and finds the required dependencies.[/color]
                        > >
                        > > Sounds like a good idea to me, if a sensible name is chosen for the
                        > > "main module" (I propose 'main':-).[/color]
                        >
                        > My choice would have been __main__ :-) Is it really the correct way to
                        > 'import __main__' instead of 'running' it?[/color]

                        You can't import __main__ - you'll get the one already in sys.modules.
                        The code for the main script needs to be executed in __main__'s dict.

                        Guido might not like it if the interpreter always attempted to open
                        its executable image file to check for an appended zip. It could cause
                        problems on some obscure environments. A possible alternative would be
                        to have a configuration area inside the executable that can be modified
                        by an external program (e.g. py2exe). The program would search for a
                        signature string and modify the section after it. The configuration
                        area can be as simple as a string that overrides the command line
                        arguments.

                        Oren

                        Comment

                        • Alex Martelli

                          #13
                          Re: crossplatform py2exe - would it be useful?

                          Oren Tirosh wrote:
                          ...[color=blue][color=green][color=darkred]
                          >> > Sounds like a good idea to me, if a sensible name is chosen for the
                          >> > "main module" (I propose 'main':-).[/color]
                          >>
                          >> My choice would have been __main__ :-) Is it really the correct way to
                          >> 'import __main__' instead of 'running' it?[/color]
                          >
                          > You can't import __main__ - you'll get the one already in sys.modules.[/color]

                          If there's a __main__ in the zip, we could remove (even assuming it's
                          already there) the yet-empty sys.modules['__main__'].
                          [color=blue]
                          > The code for the main script needs to be executed in __main__'s dict.
                          >
                          > Guido might not like it if the interpreter always attempted to open
                          > its executable image file to check for an appended zip. It could cause[/color]

                          So, I reiterate an idea I've already expressed: key on the executable
                          file's name. If it's at least six characters long and the first six
                          characters are (case-insensitive) 'p', 'y', 't', 'h', 'o', 'n' in this
                          order, forget the whole thing and proceed like now; in other words,
                          use whatever new tricks we insert *if and only if* the executable file's
                          name does NOT start with (case-insensitive) 'python'.
                          [color=blue]
                          > problems on some obscure environments. A possible alternative would be
                          > to have a configuration area inside the executable that can be modified
                          > by an external program (e.g. py2exe). The program would search for a
                          > signature string and modify the section after it. The configuration
                          > area can be as simple as a string that overrides the command line
                          > arguments.[/color]

                          I suspect "obscure environments" may make it hard for py2exe to find
                          the needed signature and get at the 'configuration area' (depending on
                          how executable files are stored when seen as stream of bytes). Still,
                          such an area would also be useful for other purposes, as you mention
                          (e.g., supplying the -O switch "at compile time", and the like). So,
                          perhaps, we could simply test the executable's name FIRST, and if the
                          name starts with "python" just do nothing, otherwise look at the
                          configuration area (string) and so on. On any "obscure environment"
                          where the set of tricks doesn't work, one would simply have to avoid
                          renaming or copying the python interpreter to weird names, and otherwise
                          would be just about as well or badly off as today.


                          Alex

                          Comment

                          • Alex Martelli

                            #14
                            Re: crossplatform py2exe - would it be useful?

                            Thomas Heller wrote:
                            ...[color=blue][color=green]
                            >> Ah, yes, good point. So, the executable needs to know whether to do
                            >> the usual commandline and environment processing, or not, _before_
                            >> calling Py_Inizialize.[/color]
                            >
                            > Exactly. And it may even be useful to do specail command line
                            > processing, an PY2EXEVERBOSE flag might be useful.[/color]

                            I guess it might, yes.

                            [color=blue][color=green]
                            >> One approach might be to trigger this based
                            >> on the executable's own *name* -- do the full commandline and environment
                            >> processing if and only if the executable's name starts with (case-
                            >> insensitive, probably, to be safe...) the six letters 'python', but
                            >> not otherwise. There are, no doubt, other alternative ways, too, but
                            >> this one seems dirt-simple and practically sufficient.[/color]
                            >
                            > On windows, where the interpreter is in a dll, providing a custom
                            > equivalent to python.exe (as py2exe currently does) is pretty simple.
                            > On systems where the interpreter is staically linked, there's no other
                            > choice than to recompile and relink the whole pythonm if I understand
                            > correctly.[/color]

                            Python 2.3 now supports building a .so (or whatever) on many systems,
                            needing just a switch on ./configure. If one chooses to go for a
                            static build anyway, sure, one will have to link statically. But
                            no recompile and relink would be needed (unless 'pythonm' is something
                            I don't know about rather than just a typo for 'python'...?). E.g.,
                            on Linux:

                            $ cat main.py
                            print "Hello world"
                            $ python -c 'import main'
                            Hello world
                            $ zip main main.pyc
                            adding: main.pyc (deflated 31%)
                            $ cp /usr/local/bin/python2.3 ./myapp
                            $ cat main.zip >>myapp
                            $ ./myapp -c 'import sys; sys.path.insert (0,"myapp"); import main'
                            Hello world
                            $

                            So, if I could just insert that "-c string" into myapp in some
                            way -- and have myapp, which is just a copy of the python 2.3
                            interpreter, execute it in some way instead of the arguments
                            [leaving the arguments to use for sys.argv] -- I'd be in clover,
                            quite indifferently as to whether myapp is statically OR
                            dynamically linked. Admittedly at this level it doesn't work
                            with __main__, as Oren suggested ('import __main__' is a noop
                            unless one deletes sys.modules['__main__'], and if one does it's
                            "ImportErro r: Cannot re-init internal module __main__"). Which
                            is why I've reverted to 'main' without underscores;-).

                            Anyway, the zipfile would of course be prepared in much more
                            sophisticated (but presumably platform independent?) ways, and
                            the suitable string (including e.g. a -O or whatever) could be
                            inserted (by a py2exe tool or the like) into a suitable config
                            area in the executable, as Oren suggested.


                            [color=blue][color=green][color=darkred]
                            >>> And I hope that the options set by the command line flags and env vars
                            >>> should now come from the __main__ script itself.[/color]
                            >>
                            >> I'm not sure I understand what you mean. Anyway, I do see that if
                            >> my 'foobar.exe' is a python.exe + appended zipfile, then running
                            >> 'foobar -i' should just put '-i' in sys.argv[1], and NOT gobble it up
                            >> to mean "enter interactive mode", for example.[/color]
                            >
                            > You understood. Yes, the command line flags must be passed into
                            > sys.argv. But I still want to set the optimize flag and the unbuffered
                            > flag at *build* time. I'm quite sure all this cannot be encoded into the
                            > filename.[/color]

                            Right. But it COULD easily be encoded in a "configurat ion area".
                            [color=blue]
                            > Right now, py2exe embeds a struct containing a magic value plus these
                            > flags into the exe, just before the zip-archive, but all this unpacking
                            > has to be done from C code (because these flags are not writable from
                            > Python code), so all this has to be part of the hook.[/color]

                            Oh yes, it surely would need to be part of the hook.

                            [color=blue]
                            > Thomas
                            >
                            > PS: Since py2exe, even on Linux, doesn't really create a single file
                            > executable, there are always some shared libs needed, maybe the first
                            > step would be to create a directory containing the interpreter
                            > executable with an appended ziparchive, the shared libs needed (zlib.so,[/color]

                            Perhaps this step could be left to a separate tool (basically we're talking
                            about a self-unpackaging zipfile, it seems to me).
                            [color=blue]
                            > maybe more), and a bash script containing something like this (you'll
                            > probably see how rusty my *nix skills are nowadays):
                            >
                            > #!/bin/sh
                            > exec python_with_zip -c "<<EOF
                            > the script itself
                            > "
                            > EOF
                            >
                            >
                            > What are the disadvantages of a shell-script against an (elf) executable?[/color]

                            For example, a shell script cannot be set-userid (it wouldn't be secure).


                            Alex

                            Comment

                            • Thomas Heller

                              #15
                              Re: crossplatform py2exe - would it be useful?

                              Alex Martelli <aleax@aleax.it > writes:
                              [color=blue]
                              > Oren Tirosh wrote:
                              > ...[color=green][color=darkred]
                              >>> > Sounds like a good idea to me, if a sensible name is chosen for the
                              >>> > "main module" (I propose 'main':-).
                              >>>
                              >>> My choice would have been __main__ :-) Is it really the correct way to
                              >>> 'import __main__' instead of 'running' it?[/color]
                              >>
                              >> You can't import __main__ - you'll get the one already in sys.modules.[/color]
                              >
                              > If there's a __main__ in the zip, we could remove (even assuming it's
                              > already there) the yet-empty sys.modules['__main__'].
                              >[color=green]
                              >> The code for the main script needs to be executed in __main__'s dict.[/color][/color]

                              Then we name the boot module __boot__ and import this from the zip.
                              This could then execute the script in the __main__ module's namespace.
                              [color=blue]
                              > So, I reiterate an idea I've already expressed: key on the executable
                              > file's name. If it's at least six characters long and the first six
                              > characters are (case-insensitive) 'p', 'y', 't', 'h', 'o', 'n' in this
                              > order, forget the whole thing and proceed like now; in other words,
                              > use whatever new tricks we insert *if and only if* the executable file's
                              > name does NOT start with (case-insensitive) 'python'.
                              >[color=green]
                              >> problems on some obscure environments. A possible alternative would be
                              >> to have a configuration area inside the executable that can be modified
                              >> by an external program (e.g. py2exe). The program would search for a
                              >> signature string and modify the section after it. The configuration
                              >> area can be as simple as a string that overrides the command line
                              >> arguments.[/color]
                              >
                              > I suspect "obscure environments" may make it hard for py2exe to find
                              > the needed signature and get at the 'configuration area' (depending on
                              > how executable files are stored when seen as stream of bytes). Still,
                              > such an area would also be useful for other purposes, as you mention
                              > (e.g., supplying the -O switch "at compile time", and the like). So,
                              > perhaps, we could simply test the executable's name FIRST, and if the
                              > name starts with "python" just do nothing, otherwise look at the
                              > configuration area (string) and so on.[/color]

                              Sounds much like the way py2exe already works now. It locates the
                              appended zip-file by searching the exefile from the end, then finds the
                              beginning of the zipfile, and looks for a magic number there, which is
                              used to verify that the next n bytes before this position is a C
                              structure containing the required flags.

                              I don't like the idea to scan the executable for a magic signature
                              without further hints where this should be.
                              [color=blue]
                              > On any "obscure environment"
                              > where the set of tricks doesn't work, one would simply have to avoid
                              > renaming or copying the python interpreter to weird names, and otherwise
                              > would be just about as well or badly off as today.[/color]

                              From reading the McMillan installer sources some time ago, I have the
                              impression that on some obscure platforms it's not possible to append
                              the structure and the zipfile to the executable, and on other obscure
                              platforms (or maybe runtime environments, maybe a cgi executable started
                              from apache) it may be difficult to the pathname if the exefile.

                              But, all in all, it sounds like a plan. Although I have the impression
                              that it may be difficult to convince the python-dev crowd to include
                              this in 2.3.1. (Is anyone of them reading this thread?)

                              Thomas

                              Comment

                              Working...