Re: [PyInstaller] If PyInstaller EXEs modify PYTHONPATH, then using python via Popen might fail to find builtin modules. Does it?

635 views
Skip to first unread message

Hartmut Goebel

unread,
Nov 25, 2012, 11:42:25 AM11/25/12
to pyins...@googlegroups.com
Am 23.11.2012 18:03, schrieb Quentin Crain:

    cmd='python -S -c "import random; print random.randint(0,10)"'

If you require Python to be installed on the target machine, why do you need PyInstaller then?


--
Schönen Gruß
Hartmut Goebel
Dipl.-Informatiker (univ), CISSP, CSSLP

Goebel Consult
http://www.goebel-consult.de

Monatliche Kolumne: http://www.cissp-gefluester.de/2010-01-hinterturen-allen-ortes
Blog: http://www.goebel-consult.de/blog/200505010

Goebel Consult ist Mitglied bei http://www.7-it.de/

Steve Barnes

unread,
Nov 25, 2012, 11:04:16 AM11/25/12
to pyins...@googlegroups.com
> Date: Sun, 25 Nov 2012 17:42:25 +0100
> From: h.go...@goebel-consult.de
> To: pyins...@googlegroups.com
> Subject: Re: [PyInstaller] If PyInstaller EXEs modify PYTHONPATH, then
> using python via Popen might fail to find builtin modules. Does it?
Don't know if this is any help but on a project that I am involved we came up with a strategy of using py2exe to build executables for use on the end users machines but using python tasks for the development machines - all we do there is to have the command be dependant on the "Frozen" state - and for each of the external scripts that we need to be able to invoke we also build an executable for the end users machine.  By using the zipped library option, in py2exe but I am sure that pyInstaller has the equivalent option, each .exe is tiny as they all use the common code from the zipped library which includes any extensions that are needed.  For one or two of the extension that were only being called from code that was evaluated using eval or exe we did have to have a section doing something along the lines of:
if False:    import SomeModule    dummy = SomeModule.SomefunctionOrClass()
Just to make sure that the module got included in the library.
Gadget/Steve

Quentin Crain

unread,
Nov 25, 2012, 7:58:32 PM11/25/12
to pyins...@googlegroups.com
Hi!

Looks like I am going to have to force the addition of all the paths in sys.path into the spec file then build my EXEs.

Unfortunately, even this sucks as those python paths are specific to the system we build on, so what if the user has python in c:\program files\python27 instead of the default c:\python27, or of course any other path they may want? Uggh.

Hartmut: I apologize for giving the idea that python is required for our app. But, since our app uses Popen to run subcommands, it may be the case that some customer (and does, which is how we found it!) wants to use python within our app.

Steve: Thanks for the idea! I will ponder that.

-- Quentin

On Friday, November 23, 2012 9:03:45 AM UTC-8, Quentin Crain wrote:

Help please! How am I being dumb! grin!

This example python script runs python via Popen. It simply tries to print a random number. But the PYTHONPATH is redefined without the system's python <lib thus it is unable to find the random module.

Bonus: I assume once I can get past this, then I will not longer need the -S as the builtin site module will be found.

PROGRAM:

import subprocess
import shlex

def run_cmd(cmd):
    cmd=shlex.split(cmd)
    try:
        output=subprocess.check_output(cmd, stderr=subprocess.STDOUT)
    except Exception as exc:
        print ">>>", exc.output
    else:
        print output

def main():

    cmd='python -S -c "import sys; print sys.path"'
    run_cmd(cmd)

    print "\n\n"

    cmd='python -S -c "import random; print random.randint(0,10)"'
    run_cmd(cmd)

if __name__=="__main__":
    main()

SPEC:

# -*- mode: python -*-
a = Analysis(['test.py'],
             pathex=['C:\\Users\\???\\Desktop\\testing'],
             hiddenimports=[],
             hookspath=None)
pyz = PYZ(a.pure)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          name=os.path.join('dist', 'test.exe'),
          debug=False,
          strip=None,
          upx=True,
          console=True )


EXECUTION:

C:\Users\???\Desktop\testing>dist\test.exe
['', 'C:/Users/???/AppData/Local/Temp/_MEI92722', 'C:/Users/???/Desktop/testing/dist', 'C:\\Windows\\system32\\python27.zip', 'C:/User
s/???/AppData/Local/Temp/_MEI92722/\\DLLs', 'C:/Users/???/AppData/Local/Temp/_MEI92722/\\lib', 'C:/Users/???/AppData/Local/Temp/_ME
I92722/\\lib\\plat-win', 'C:/Users/???/AppData/Local/Temp/_MEI92722/\\lib\\lib-tk', 'C:\\PYTHON27']


>>> Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: No module named random

Steve Barnes

unread,
Nov 26, 2012, 1:06:21 AM11/26/12
to pyins...@googlegroups.com
________________________________
> Date: Sun, 25 Nov 2012 16:58:32 -0800
> From: czr...@gmail.com
> To: pyins...@googlegroups.com
> Subject: [PyInstaller] Re: If PyInstaller EXEs modify PYTHONPATH, then
> using python via Popen might fail to find builtin modules. Does it?
>
> Hi!
>
> Looks like I am going to have to force the addition of all the paths in
> sys.path into the spec file then build my EXEs.
>
> Unfortunately, even this sucks as those python paths are specific to
> the system we build on, so what if the user has python in c:\program
> files\python27 instead of the default c:\python27, or of course any
> other path they may want? Uggh.
>
> Hartmut: I apologize for giving the idea that python is required for
> our app. But, since our app uses Popen to run subcommands, it may be
> the case that some customer (and does, which is how we found it!) wants
> to use python within our app.
>
> Steve: Thanks for the idea! I will ponder that.
>
> -- Quentin
>
Quentin,
You shouldn't need to do this as if your python modules are being found using sys.path then, provided the user and you have accepted the default for installing extension modules of installing them to [PYTHONPATH]/lib/site-packages then your and their python should find them.  I would strongly suggest that any execute command that you provide in your app be in a try: except block so that you can pass on any errors such as failed import/failed to find python, etc., and if the user is expert enough to be calling python scripts, or has such expertise on hand, from within your app then they should be able to sort out things like missing dependencies _providing you let them see the error message_.
Gadget/Steve
Reply all
Reply to author
Forward
0 new messages