catching errors in embedded Python on Windows

David Bolen db3l at fitlinxx.com
Thu Aug 23 22:47:05 EDT 2001


Howard Lightstone <howard at eegsoftware.com> writes:

> OK, I made up a Python class/methods to take over stderr/stdout when
> running Pythonw applications and display them in a Tkinter window.
> Works slick.
> 
> However, this DOESN'T work when embedding Python since pythonrun.c still
> refers to stdout/stderr directly...which Windows doesn't have set to
> anything useful.

I don't see many direct references to stdout/stderr in pythonrun.c (at
least current source) except in some specific low level error
conditions or system exit scenarios.  It seems to be using the
sys.stdout and sys.stderr objects pretty consistently, so if they're
redirected you should be fine.  Certainly anything your prior
class/methods did in your pythonw applications should be doable in an
embedded environment.

I think there was a recent thread here on some manner to handle this
with actual internal API calls (probably PySys_SetObject to point
stdout/stderr in the sys module to your internal object), but in an
early embedded application I had, I didn't yet grok Python that well,
so instead took a more straight forward approach that more closely
matched how I had done it in pure Python code - by executing actual
Python code to perform the redirection.

That is, I did the following:

* Created an embedded Python interpreter, and then declared my own code
  as a module to extend that embedded interpreter (see the recent extending
  and embedding thread for further info).  The extension was also for other
  purposes in addition to redirection.

* Wrote internal stdout and stderr functions that routed the messages
  to an internal display window.  I then declared them as functions in
  my module I extended the interpreter with.

* Before executing any scripts with the newly created embedded interpreter,
  I used PyRun_SimpleFile to execute a fixed initialization file that
  re-routed stdout/stderr, as in ("ecna" is my extension module name):

      import sys

      class StdoutCatcher:
	  def write(self, stuff):
	      ecna.stdout(stuff)

      class StderrCatcher:
	  def write(self, stuff):
	      ecna.stderr(stuff)

      sys.stdout = StdoutCatcher()
      sys.stderr = StderrCatcher()

  I expect you could also use PyRun_SimpleString instead if you didn't
  want to depend on an external file.

> How does one reroute/catch these errors?  Unfortunately, the only thing
> I can think of  involves changing pythonrun.c to use the 'objects'
> attached to sys.stdout and sys.stderr so they COULD be rerouted.

Could you point at the section of pythonrun.c you think won't follow a
sys.{stdout,stderr} redirection?

--
-- David
-- 
/-----------------------------------------------------------------------\
 \               David Bolen            \   E-mail: db3l at fitlinxx.com  /
  |             FitLinxx, Inc.            \  Phone: (203) 708-5192    |
 /  860 Canal Street, Stamford, CT  06902   \  Fax: (203) 316-5150     \
\-----------------------------------------------------------------------/



More information about the Python-list mailing list