using py2exe , Panda3d and Python 2.4

I’ve created following python file using Panda module

import direct.directbase.DirectStart
run()

I’m using Panda3d 1.4.2 and Python 2.4.4

I’ve used py2exe for compiling python code given above.
Upon running the EXE i get following error:

Traceback (most recent call last):
File “Check.py”, line 1, in ?
File “direct_init_.pyc”, line 7, in ?
NameError: name ‘exit’ is not defined

Please help

It should be sys.exit
I thought it had been fixed…

1 Like

Thanks a lot.
Can I directly make any changes to .pyc file.
I mean can i simply open up the .pyc file in notepad and change exit to sys.exit.

Please confirm.

Actually i just discoved that its not possible to modify the init.pyc file like the way I thought it would be.

Please guide me what should I do to get rid of this error.

Thanks

I have not been able to successfully get py2exe to work on other computers, I have been stuck at the .libs not loading correctly…

It will work on a computer that has panda installed however :slight_smile:

What I have done: look in your panda install directory, under “direct”. Copy everything from the src folder in that directory up one (inside direct). Comment all of the lines in the init.py file. Use this setup script:

from distutils.core import setup
import py2exe
import os,sys
PANDA_DIR = 'C:\Panda3D-1.4.2/'

setup( console = [ {  'script' : 'test.py',
                     #'icon_resources' : [ ( 1, 'game.ico' ) ],
                     } ],
       #zipfile = None,
       options = { 'py2exe': { 'optimize' : 2,
                               'excludes' : [ 'Tkinter' ],
			       'dist_dir' : 'dist/'},
                 },
       data_files = [ ( 'etc', [ os.path.join(PANDA_DIR, 'etc/Config.prc'), ] ),
                      ],
       packages = [
        'direct',
        'direct.directbase',
        'direct.showbase',
        'direct.interval',
        'direct.actor',
        'direct.gui',
        'direct.task',
        'direct.controls',
        'direct.directnotify',
        'direct.directtools',
        'direct.directutil',
        'direct.fsm',
        'direct.cluster',
        'direct.particles',
        'direct.tkpanels',
        'direct.tkwidgets',
        'direct.directdevices',
        'direct.distributed',
        'pandac',
                   ],
      package_dir = {
        'direct' : os.path.join(PANDA_DIR, 'direct'),
        'direct.directbase' : os.path.join(PANDA_DIR, 'direct/directbase'),
        'direct.showbase' : os.path.join(PANDA_DIR, 'direct/showbase'),
        'direct.interval' : os.path.join(PANDA_DIR, 'direct/interval'),
        'direct.actor' : os.path.join(PANDA_DIR, 'direct/actor'),
        'direct.gui' : os.path.join(PANDA_DIR, 'direct/gui'),
        'direct.task' : os.path.join(PANDA_DIR, 'direct/task'),
        'direct.control' : os.path.join(PANDA_DIR, 'direct/control'),
        'direct.directnotify' : os.path.join(PANDA_DIR, 'direct/directnotify'),
        'direct.directtools' : os.path.join(PANDA_DIR, 'direct/directtools'),
        'direct.directutil' : os.path.join(PANDA_DIR, 'direct/directutil'),
        'direct.fsm' : os.path.join(PANDA_DIR, 'direct/fsm'),
        'direct.cluster' : os.path.join(PANDA_DIR, 'direct/cluster'),
        'direct.particles' : os.path.join(PANDA_DIR, 'direct/particles'),
        'direct.tkpanels' : os.path.join(PANDA_DIR, 'direct/tkpanels'),
        'direct.tkwidgets' : os.path.join(PANDA_DIR, 'direct/tkwidgets'),
        'direct.directdevices' : os.path.join(PANDA_DIR, 'direct/directdevices'),
        'direct.distributed' : os.path.join(PANDA_DIR, 'direct/distributed'),
        'pandac' : os.path.join(PANDA_DIR, 'pandac'),
                    },
)

This will get you to an error something like "failed to load the dll properly from pylibexpress.pyo…good luck! Please show us how you did it!

I did the following thing:

But when i run the exe file it gives following error:

Traceback (most recent call last):
File “Check.py”, line 1, in ?
File “direct_init_.pyc”, line 7, in ?
NameError: name ‘exit’ is not defined

Where is that from?

The “exit” should be sys.exit(), but that just means it encountered an error and is trying to exit anyways. It cannot find the direct.directbase folder because there isn’t one. It is direct.src.directbase, but the src folder does not have an init.py file so it is not a package…This is why you have to move the src folder contents into the direct folder and comment the lines in the init.py file. These lines make the direct folder work on this computer but do not work with py2exe…Don’t worry, everything will still work on your computer, too. I do not know why panda does not come this way to begin with. I think at one point Josh said it was supposed to, but it just didn’t. It is a simple fix, easy enough to do on your installation.

Your setup.py file must contain what I posted above because they are not in the regular python folders that py2exe checks, so it misses them and they have to be explicitely defined.

Does this help?

Rereading your post, it seems as though you are simply trying to make it run on your computer. In this case, py2exe is not necessary, all you have to do is type ppython yourfile.py and it will execute.

I did following :

and now I am getting following error on running the exe:

Traceback (most recent call last):
File “Check.py”, line 1, in ?
File “direct\directbase\DirectStart.pyo”, line 3, in ?
File “direct\showbase\ShowBase.pyo”, line 10, in ?
File “pandac\PandaModules.pyo”, line 1, in ?
File “pandac\libpandaexpressModules.pyo”, line 1, in ?
File “pandac\extension_native_helpers.pyo”, line 20, in ?
File “libpandaexpress.pyo”, line 12, in ?
File “libpandaexpress.pyo”, line 10, in __load
ImportError: DLL load failed: This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem.

Happy new year all :slight_smile:

Smriti Sharma, looks better now, though I don’t understand the additional “/” at the end of your PANDA_DIR path. Step 4 is not required too. Leave it away.

The “etc” folder should NOT be created next to “dist” and “build”. It should be there already BEFORE you run setup.py, because it is one of the data files you want to include in your distribution.

Open the dist folder and report which python .dll you find there.

enn0x

Thanks enn0x!!

Wishing a Prosperous New Year to you!!!

I think New Year is turning out to be great for me. I’ve started getting replies. Thanks a lot for your help.
I thought of shifting to PackPanda bacause of this problem with py2exe only.
But let me try your suggestion with py2exe as well.

I’ll try both packpanda and py2exe.
Whichever I succeed in…

The files inside the dist folder can be viewed as

But the Log still says

Not good. “etc”, “dist” and “build” do not belong into Panda3D’s python directory. This is because you build from inside Panda3D. Same advice as on the other thread: build from somewhere else to avoid having your Panda3D installation messed up.

Might be good to remove Panda3D and re-install first.

enn0x

Yeah i tried putting Check.py at E:\ALL
and doing all thosec things again. But I’m facing same error.

Can someone guide on which file(s) i should debug.
Any help is appreciated.

I think some of your problems might come from a messed up Panda3D directory (see your other thread about packpanda.py).

I suggest to first uninstall Panda3D, and if necessary remove any directories or modifications of environment variables (path, python path) by hand. Then reinstall Panda3D and see if something has changed.

enn0x

…passing through…
sorry for not helping, here is my setup.py, which is geared towards the nasty \direct structure and direct’s init.py, without moving \src* to \direct, without commenting init.py, and without hardcoding the packages by my hands.

I tried the setup.py in the place Ralph used to live.

# my PY2EXE setup.py, works with the nasty \direct\src structure and it's __init__.py
from distutils.core import setup
import os, glob, py2exe

##################################
PANDA_DIR = 'd:\Panda3D'
##################################

directInit = os.path.join(PANDA_DIR, 'direct/__init__.py')
tempDirectInit = os.path.join(PANDA_DIR, 'direct/__init__TEMP.py')
tempNameDirectInit = os.path.join(PANDA_DIR, 'direct/__init__TEMPNAME.py')
def swapFileNames():
    os.rename( directInit, tempNameDirectInit  )
    os.rename( tempDirectInit, directInit )
    os.rename( tempNameDirectInit, tempDirectInit )
# if empty __init__.py already exist, swap the names only (I'd like my HD clean),
# otherwise rename the original into "temp" and create new *EMPTY* __init__.py
if os.path.exists(tempDirectInit):  swapFileNames()
else:
   os.rename( directInit, tempDirectInit )
   emptyDirectInit = open(directInit,"w")
   emptyDirectInit.close()

try:
  P3Dpackage_dir={}
  directNpandac=['direct','pandac']
  for d in directNpandac:
      P3Dpackage_dir[d]=os.path.join(PANDA_DIR, d)
  directTree=[ 'direct.'+d for d in os.listdir('%s\direct\src' %PANDA_DIR) ]
  for d in directTree:
      P3Dpackage_dir[d]=os.path.join(PANDA_DIR, d.replace('.','/src/'))
  P3DmissingDLLs=glob.glob(os.path.join(PANDA_DIR, 'bin/*.dll'))
  # some C/C++ runtime libraries, machine without these .dlls will crash Panda3D
  runtimeLibraries=glob.glob(os.path.join(PANDA_DIR, 'bin/*.manifest'))+\
                   glob.glob(os.path.join(PANDA_DIR, 'bin/vcredist*.exe'))

  ############___INCLUDED DATA TREES___##########
  # dataTrees format : ( target distribution dir, source root, excluded dirs ),
  dataTrees=(
     # P3D's \models, without \audio and \icons
     [ 'models', os.path.join(PANDA_DIR, 'models'), ['audio','icons',] ],
     # local \models
     [ 'models', 'models' , [] ],
     )
  recursiveDataTrees=[]
  for destination, tree, excl in dataTrees:
      for root, dirs, files in os.walk(tree):
          if len(files):
             included=1
             for ex in excl:
                 if ('\\%s\\' %ex in root) or (root[-len(ex)-1:]=='\\'+ex):
                    included=0; break
             if included:
                destDir=os.path.join(destination,root[len(tree)+1:])
                recursiveDataTrees.append( ( destDir, [os.path.join(root,f) for f in files] ) )

  ############___PY2EXE CONVERSION___############
  setup(
     windows=[ {  'script' : 'Tut-Roaming-Ralph.py',
#                   'icon_resources' : [ ( 1, 'myLogo.ico' ) ],
               } ],
#      zipfile = None,
     options = {
        'py2exe': { 'optimize' : 2,
                    'excludes' : [ 'Tkinter' ],
                    'dist_dir' : 'dist/'},
                  },
     data_files = [
        ( 'etc', glob.glob(os.path.join(PANDA_DIR, 'etc/*.*')) ),
        ( '.', P3DmissingDLLs ),
        ( '.', runtimeLibraries ),
     ] + recursiveDataTrees,
     packages = directNpandac + directTree,
     package_dir = P3Dpackage_dir,
     )
  ########___end_of_PY2EXE CONVERSION___#########
finally:
  # restore direct\__init__.py name, leave the empty one there,
  # so in the future, only need to swap the names, instead of creating it over and over again
  swapFileNames()
  print '\direct\__init__.py filename restored :D\n'

Yes, enn0x, i did reinstalled the Panda3d(at same location after uninstalling it).
But it didn’t work either.

Finally, for the 1st time I tried the .exe on “other” computer and it didn’t work. Actually, I didn’t try it on other computer, I only simulated it, simply by renaming my P3D installation dir.
It said : No graphics pipe is available !
Damn, for a while it was driving me to the wrong direction. I thought it looked Config.prc in P3D install dir, but it was a false alarm.
I tracked it by renaming \etc instead, and then it worked. So locating the .prc wasn’t the problem. Then I renamed \bin, and it did NOT work. So there were still some needed .dlls which weren’t copied to \dist.
After some trials, they are the .dlls needed for rendering :

  1. Without libp3windisplay.dll (just like avformat-50-panda.dll and avutil-49-panda.dll) in \dist, it said the .dll wasn’t found. No problem, it can be easily copied.
  2. Without cgGL/DX, it said couldn’t locate entry point in cg.dll
  3. Without libpandagl/D3D, it said : No graphics pipe is available !, which is the 1st thing needed at runtime, so it made me mad for a moment.
    I fixed it by appending them to data_files :
P3DmissingDLLs=[ os.path.join(PANDA_DIR, 'bin',d) for d in (
'avformat-50-panda.dll', 'avutil-49-panda.dll',
'libp3windisplay.dll', 'libpandagl.dll', 'cgGL.dll',
'libpandadx8.dll', 'libpandadx9.dll', 'cgD3D8.dll', 'cgD3D9.dll',
)]

data_files = [
  ( 'etc', [ os.path.join(PANDA_DIR, 'etc/Config.prc'), ] ),
  ( '.', P3DmissingDLLs ),
#  ( '.', glob.glob('*.??g') ),
],

Great! I still have to give it a try, but looks very good. Thanks :slight_smile:

enn0x

I updated my setup.py with try…finally block to ensure that the renamed init.py will be restored, in case there is error after renaming process. Any error there would cause direct modules to be unavailable, like this :

I tried following:

Please see the attached Traceback image

:cry: Help!