Issue with py2exe 0.5.0 and sys.path

Hi all,

win98, py2.3.3, wxPy2.4.2.4

As a preamble, thanks to Thomas Heller, Mark Hammond for the
new py2exe and to the guy(s) who wrote the wiki pages (sorry
I do no find the name(s)).

I have a problem with this new release of py2exe, 0.5.0. I
came to this when I built an executable for my "psi baby",
http://www.chez.com/spinecho/pypsi/pagpypsi.htm
psi is Python shell (à la PyShell) where the user can import
modules on the fly, like

import mymodule

I had not this problem with the previous py2exe releases.

Generally if a Python script is launched, the home directory of this
script belongs to the sys.path, even if this is not explicitly
defined somewhere in the script code. When creating an exe, this
is no more valid.

I wrote a wxPy app, wxappli.py, to test this. The application
has two buttons and a textcrl as output display. In the wxappli
dir, I have a module, called mylib.py containing the
function sub.
Button1 displays the sys.path of the application. Button2 calls
the module mylib on the fly and run the def sub().

def OnClick1(self, event):
    r = sys.path
    s = '\n'.join(r)
    self.txt.SetValue(s)

def OnClick2(self, event):
    import mylib
    r = mylib.sub()
    self.txt.SetValue(r)

If I run, the script, I get this

From Button1:

C:\jm\jmpy\makexe\wxapp
C:\PYTHON23\PYTHON23.zip
C:\PYTHON23\lib\site-packages\win32
...
The first line corresponds to the application dir.

From Button2:

sub in mylib.py
a string as a response to my function sub()

Seems to be ok.

Now, if I build an exe, I get this:

From Button1:

C:\JM\JMPY\MAKEXE\WXAPP\DIST\library.zip

Button2:
This fails
A log file is created with:
Traceback (most recent call last):
  File "wxappli.py", line 33, in OnClick2
ImportError: No module named mylib

From that I conclude, the application path - home dir -

is not in the sys.path.

I can repeat the same test, with a pure Python script,
a script not using wxPython.

I think the problem is more visible in a pure python script
like this.

def main():
    print 'hello'
    print __file__

if __name__ == '__main__':
    main()

Running the script is ok, understand the __file__ variable is
desplayed correctly. But if I create an exe from this,
the application is no more working. __file__ can not be found.

Any idea, comments.

Jean-Michel Fauth, Switzerland

"Jean-Michel Fauth" <jmfauth@bluewin.ch> writes:

Hi all,

win98, py2.3.3, wxPy2.4.2.4

As a preamble, thanks to Thomas Heller, Mark Hammond for the
new py2exe and to the guy(s) who wrote the wiki pages (sorry
I do no find the name(s)).

You're welcome! Most of the stuff in the wiki was added by Harald Armin
Massa (I hope I got his name correct), but there are also contributions
from other people.

I have a problem with this new release of py2exe, 0.5.0. I
came to this when I built an executable for my "psi baby",
http://www.chez.com/spinecho/pypsi/pagpypsi.htm
psi is Python shell (à la PyShell) where the user can import
modules on the fly, like

import mymodule

I had not this problem with the previous py2exe releases.

Generally if a Python script is launched, the home directory of this
script belongs to the sys.path, even if this is not explicitly
defined somewhere in the script code. When creating an exe, this
is no more valid.

This is by intent. The py2exe'd exe-file runs with the minimal sys.path
possible, and that is the one where only the 'library.zip' archive is
in.

If another directory were also on sys.path, it would be easy to break
the exe by copying some *.py, *.pyc, *.pyo, or *.dll or *.pyd file into
this directory.

I wrote a wxPy app, wxappli.py, to test this. The application
has two buttons and a textcrl as output display. In the wxappli
dir, I have a module, called mylib.py containing the
function sub.
Button1 displays the sys.path of the application. Button2 calls
the module mylib on the fly and run the def sub().

def OnClick1(self, event):
    r = sys.path
    s = '\n'.join(r)
    self.txt.SetValue(s)

def OnClick2(self, event):
    import mylib
    r = mylib.sub()
    self.txt.SetValue(r)

If I run, the script, I get this
From Button1:
C:\jm\jmpy\makexe\wxapp
C:\PYTHON23\PYTHON23.zip
C:\PYTHON23\lib\site-packages\win32
...
The first line corresponds to the application dir.

From Button2:
sub in mylib.py
a string as a response to my function sub()

Seems to be ok.

Now, if I build an exe, I get this:
From Button1:
C:\JM\JMPY\MAKEXE\WXAPP\DIST\library.zip

Button2:
This fails
A log file is created with:
Traceback (most recent call last):
  File "wxappli.py", line 33, in OnClick2
ImportError: No module named mylib

From that I conclude, the application path - home dir -
is not in the sys.path.

I can repeat the same test, with a pure Python script,
a script not using wxPython.

Right. This behaviour is in all py2exe'd files, not only in gui exes.
And in the samples directory is a trivial sample hello.py, which
demonstrates this and also other things, and allows easy
experimentation.

I think the problem is more visible in a pure python script
like this.

def main():
    print 'hello'
    print __file__

if __name__ == '__main__':
    main()

Running the script is ok, understand the __file__ variable is
desplayed correctly. But if I create an exe from this,
the application is no more working. __file__ can not be found.

This is a different thing. IIRC, __file__ in the __main__ module is new
in Python 2.3, it wasn't defined in Python 2.2.
And in the py2exe'd file it is not set because the main script is not
even loaded from a file, not even one in the zip archive - it is
contained in the exe itself as windows resource.

Thomas