Redirecting stdout from a C extension

After exploring a bunch of options, this problem turns out to have a preposterously simple solution!!!

Instead of
         printf("hello from C extension");
Simply using
         PyRun_String("print \"hello from C extension\"")

magically prints to the Python app's stdout.

-mike

···

At 02:59 PM 1/10/2006, you wrote:

On 2006-01-10, mike cantor <mcantor@stanford.edu> wrote:

> Thanks for the ideas. Can you flush out in a little more detail how I
> would use a pipe to accomplish this?

#!/usr/bin/python

import sys,os,threading,time

done = False

def reader(fd):
    sys.stdout.write("starting reader on fd %d\n" % fd)
    while not done:
        data = os.read(fd,1024)
        sys.stdout.write("reader got %s\n" % repr(data))
        sys.stdout.flush()

r,w = os.pipe()

threading.Thread(target=reader,args=(r,)).start()

os.write(2,"hi there to stderr file descriptor\n")
time.sleep(0.1)

os.dup2(w,2) # fd 2 is now the "write" end of the pipe
time.sleep(0.1)

os.write(2,"hello again to stderr file descriptor\n")
time.sleep(0.1)

# generate something else on stderr file descriptor
os.system("dd if=/dev/null of=/dev/null")
time.sleep(0.1)

done = True
os.write(2,"good bye\n")
time.sleep(0.1)

sys.exit()

> One thing that occured to me after reading your suggestions:
> is it possible to pass he stdout and stderr file handles into
> the C extension (as an argument to the module function) and
> then assign them there?

I don't know what you mean by "the module function", but I'd
bet the answer is "no".

--
Grant Edwards grante Yow! All right, you
                                  at degenerates! I want this
                               visi.com place evacuated in 20
                                                   seconds!

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help@lists.wxwidgets.org

        PyRun_String("print \"hello from C extension\"")

Sorry make that
         PyRun_SimpleString("print \"hello from C extension\"");

···

magically prints to the Python app's stdout.

-mike

At 02:59 PM 1/10/2006, you wrote:

On 2006-01-10, mike cantor <mcantor@stanford.edu> wrote:

> Thanks for the ideas. Can you flush out in a little more detail how I
> would use a pipe to accomplish this?

#!/usr/bin/python

import sys,os,threading,time

done = False

def reader(fd):
    sys.stdout.write("starting reader on fd %d\n" % fd)
    while not done:
        data = os.read(fd,1024)
        sys.stdout.write("reader got %s\n" % repr(data))
        sys.stdout.flush()

r,w = os.pipe()

threading.Thread(target=reader,args=(r,)).start()

os.write(2,"hi there to stderr file descriptor\n")
time.sleep(0.1)

os.dup2(w,2) # fd 2 is now the "write" end of the pipe
time.sleep(0.1)

os.write(2,"hello again to stderr file descriptor\n")
time.sleep(0.1)

# generate something else on stderr file descriptor
os.system("dd if=/dev/null of=/dev/null")
time.sleep(0.1)

done = True
os.write(2,"good bye\n")
time.sleep(0.1)

sys.exit()

> One thing that occured to me after reading your suggestions:
> is it possible to pass he stdout and stderr file handles into
> the C extension (as an argument to the module function) and
> then assign them there?

I don't know what you mean by "the module function", but I'd
bet the answer is "no".

--
Grant Edwards grante Yow! All right, you
                                  at degenerates! I want this
                               visi.com place evacuated in 20
                                                   seconds!

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help@lists.wxwidgets.org

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help@lists.wxwidgets.org

Hi all,

I have a wxPython application which reads information from a bunch of controls and, upon, pressing of a button, runs a method from a C extension that uses this information. One part of the interface allows the user to run scripts which SetValue() a bunch of the controls to pre-set combinations and then call the C method, possibly multiple times. For example:

def RepT100Script(UI):
     UI.SetSimParamFilename("PGParams-pulse.txt")
     UI.SetFitCircuitCheckboxes(["pRepT"])

     for i in range(5):
         UI.SetFitLogFilename("FitLog_SimRepT100_" + str(i+1))
         UI.SetFitResultsFilename = ("FitRes_SimRepT100_" + str(i+1))
         UI.DoFit() #The C extension

UI is the main wx.frame object of the app and the "Set" methods above get passed into UI's child panels where they eventually call SetValue(...) on the various controls.

Now to the wierd part: If I comment out UI.DoFit(), the controls are all updated correctly. But with UI.DoFit() included, The control updates don't happen and the C extension method starts firing off! I have tried shots in the dark, like placing combinations of sleep(5), wx.WakeUpIdle, and UI.Layout() before the DoFit line, but nothing seems to work.

Any ideas?

Thanks,
-mike

def RepT100Script(UI, i=1):
    UI.SetSimParamFilename("PGParams-pulse.txt")
    UI.SetFitCircuitCheckboxes(["pRepT"])
    UI.SetFitLogFilename("FitLog_SimRepT100_%i"%i)
    UI.SetFitResultsFilename = ("FitRes_SimRepT100_%i"%i)

    wx.CallAfter(UI.DoFit)
    if i < 5:
        wx.CallAfter(RepT100Script, UI, i+1)

That's my suggestion.

- Josiah

···

mike cantor <mcantor@stanford.edu> wrote:

Hi all,

I have a wxPython application which reads information from a bunch of
controls and, upon, pressing of a button, runs a method from a C extension
that uses this information. One part of the interface allows the user to
run scripts which SetValue() a bunch of the controls to pre-set
combinations and then call the C method, possibly multiple times. For example:

def RepT100Script(UI):
     UI.SetSimParamFilename("PGParams-pulse.txt")
     UI.SetFitCircuitCheckboxes(["pRepT"])

     for i in range(5):
         UI.SetFitLogFilename("FitLog_SimRepT100_" + str(i+1))
         UI.SetFitResultsFilename = ("FitRes_SimRepT100_" + str(i+1))
         UI.DoFit() #The C extension

UI is the main wx.frame object of the app and the "Set" methods above get
passed into UI's child panels where they eventually call SetValue(...) on
the various controls.

Now to the wierd part: If I comment out UI.DoFit(), the controls are all
updated correctly. But with UI.DoFit() included, The control updates
don't happen and the C extension method starts firing off! I have tried
shots in the dark, like placing combinations of sleep(5), wx.WakeUpIdle,
and UI.Layout() before the DoFit line, but nothing seems to work.

Any ideas?

Thanks,
-mike

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help@lists.wxwidgets.org

mike cantor wrote:

Hi all,

I have a wxPython application which reads information from a bunch of controls and, upon, pressing of a button, runs a method from a C extension that uses this information. One part of the interface allows the user to run scripts which SetValue() a bunch of the controls to pre-set combinations and then call the C method, possibly multiple times. For example:

def RepT100Script(UI):
    UI.SetSimParamFilename("PGParams-pulse.txt")
    UI.SetFitCircuitCheckboxes(["pRepT"])

    for i in range(5):
        UI.SetFitLogFilename("FitLog_SimRepT100_" + str(i+1))
        UI.SetFitResultsFilename = ("FitRes_SimRepT100_" + str(i+1))
        UI.DoFit() #The C extension

UI is the main wx.frame object of the app and the "Set" methods above get passed into UI's child panels where they eventually call SetValue(...) on the various controls.

Now to the wierd part: If I comment out UI.DoFit(), the controls are all updated correctly. But with UI.DoFit() included, The control updates don't happen and the C extension method starts firing off! I have tried shots in the dark, like placing combinations of sleep(5), wx.WakeUpIdle, and UI.Layout() before the DoFit line, but nothing seems to work.

While you are executing the loop and the UI.DoFit function control is not returning to the app's MainLoop, and so no more events can be dispatched until it is done. If events are not dispatched then things like refreshing the display of a control can't happen. See
http://wiki.wxpython.org/index.cgi/LongRunningTasks for more info.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!