Using pythonw.exe

Hi. I’m planning on using pythonw.exe to run my Panda3D programs because using it does not summon up a console while the game is running. The problem is, some of the programs crashes while using pythonw.exe. I’ve tried switching back to using ppython.exe and the programs no longer crashes. Is there a problem on using pythonw.exe?

I had the same experience when I tried pythonw. I think that the problem must be that Panda3D is trying to print stuff on the console, and it’s failing and getting upset about it. Or at least, that’s my theory. We really ought to try to debug that, but it just never became a priority.

How bad do you need it?

It’s possible to disable Panda’s output to console. One easy thing to do is to put in your Config.prc file:

notify-output panda.log

which causes it to write all output to the file named “panda.log” instead.

David

It’s a very urgent matter for us. We have a client update system that works on ppython.exe but crashes on pythonw.exe. But since we can’t release a public version of our game that has a console, we can’t update the client to the latest version, resulting in the game closing. (We require the player to update first before playing.) And we’re nearing our deadline, which is always a bummer… :smiley:

To package my game on Windows, I used pyinstaller to pack it into an exe, and used the Windows subsystem instead of Console without any problems. Ran fine everywhere, without an annoying console popping up. I don’t know why pythonw.exe would fail that… Does renaming your python file to .pyw, then running it through normal python help?

I don’t know why I didn’t think of this before: It’s not a problem with Panda3D at all. It’s python. When you use pythonw, any attempt to use a print-statement will crash. You probably have a print-statement in your program somewhere.

I was able to solve the problem by saying:

sys.stdout = open(“logfile.log”,“w”)
sys.stderr = sys.stdout

If I do that, the print-statements get directed into a file.

Update: here’s a little hack I just found that works. Put this at the top of your program:

try:
    sys.stdout.flush()
except:
    sys.stdout = open("logfile.out","w")
    sys.stderr = sys.stdout

If you do that, then pythonw will write its output to a logfile, whereas regular python will write its output to the console, as usual.

wow thanks Josh that is indeed helpful

I’ve never had any problem printing something to the console using pythonw, so I assume it only breaks on Linux ?

there is no pythonw on linux

Really ?
So, how come 2 people experience the same thing while I don’t ?

Pythonw is very weird. If you print more than 4k bytes, it crashes. The reason for this appears to be that it buffers stdout up to 4k bytes, then tries to flush the output. It doesn’t notice that it can’t flush the output until after printing 4k.

Wouldn’t it better like this then :

  1. no disk hit at all
  2. catches the unhandled exception and maybe send it (not the whole log) back to you
try:
    sys.stdout.flush()
except:
    class Silence:
      def write(self,s):
          pass
      def exc(self,typ,val,tb):
          import traceback
          errLog = '%s%s: %s' %(''.join(traceback.format_tb(tb)),typ.__name__, str(val))
          # SENDS THE errLog STRING TO YOU
          # _____( do it yourself )______
          # If you want to keep it on the disc
#           f=open('err.log','w')
#           f.write(errLog)
#           f.close()
          sys.exit()

    sys.stdout = Silence()
    sys.stderr = sys.stdout
    # for unhandled exception (without try... block)
    sys.excepthook = sys.stdout.exc