[FAQTS] Python Knowledge Base Update -- July 13th, 2000

Fiona Czuczman fiona at sitegnome.com
Thu Jul 13 17:40:19 EDT 2000


Hi guys,

I'm a little confused :-) yesterday I'm pretty sure I sent out a summary 
to the list, it doesn't seem to have made it though so this is a second 
attempt.  Apologies if it makes it twice now.

So, what's been entered into http://python.faqts.com:

- How can you check on the status of a file's "archive" bit, on DOS-type 
platforms
- What Python code can I use to find all the network ports that are in 
use on a server?
- Can I use python to access web (eg.yahoo) email account?
- Is there any way to find the mount point of a filesystem given the 
path to a file within the file system?
- How can I create a wxBitmap image from a Python Imaging Library (PIL) 
image?
- How can I compare two strings in a case-insensitive way?
- What is wxPython? How does it compare with Tkinter?
- Bidirectional communication through pipes: read/write popen()

cheers, Fiona


## Unanswered Questions ########################################


-------------------------------------------------------------
How can you check on the status of a file's "archive" bit, on DOS-type platforms
http://www.faqts.com/knowledge-base/view.phtml/aid/4706
-------------------------------------------------------------
Barry Pederson



## New Entries #################################################


-------------------------------------------------------------
What Python code can I use to find all the network ports that are in use on a server?
http://www.faqts.com/knowledge-base/view.phtml/aid/4684
-------------------------------------------------------------
Fiona Czuczman
Aaron Berg

to figure out what ports are used on a server you could use netstat -a 
-n

import os 
popen("netstat -a -n")


-------------------------------------------------------------
Can I use python to access web (eg.yahoo) email account?
http://www.faqts.com/knowledge-base/view.phtml/aid/4685
-------------------------------------------------------------
Fiona Czuczman
Steve Purcell

For web mail accounts that have POP access, such as Yahoo, check out
the 'poplib' standard library module:

  http://www.python.org/doc/current/lib/pop3-example.html


-------------------------------------------------------------
Is there any way to find the mount point of a filesystem given the path to a file within the file system?
http://www.faqts.com/knowledge-base/view.phtml/aid/4686
-------------------------------------------------------------
Fiona Czuczman
John Clonts

I didn't find anything already extant, so here's this:

def mountpoint(s):
    import os
    if (os.path.ismount(s) or len(s)==0): return s
    else: return mountpoint(os.path.split(s)[0])

def testit():
    print mountpoint("/home/john/scheme/cmucl")
    print mountpoint("/usr/local")
    print mountpoint("/lib/")
    print mountpoint("lib")


-------------------------------------------------------------
How can I create a wxBitmap image from a Python Imaging Library (PIL) image?
http://www.faqts.com/knowledge-base/view.phtml/aid/4687
-------------------------------------------------------------
Fiona Czuczman
Greg Landrum

Here's some sample code:
def PilImgToWxBmp(pilImg):
  wxImg = wxEmptyImage(pilImg.size[0],pilImg.size[1])
  wxImg.SetData(pilImg.tostring())
  bmp = wxImg.ConvertToBitmap()
  return bmp


-------------------------------------------------------------
How can I compare two strings in a case-insensitive way?
http://www.faqts.com/knowledge-base/view.phtml/aid/4688
-------------------------------------------------------------
Fiona Czuczman
Bjorn Pettersen

import string

if string.lower("FOO") == string.lower("Foo"):
   <do something useful>


## Edited Entries ##############################################


-------------------------------------------------------------
What is wxPython? How does it compare with Tkinter?
http://www.faqts.com/knowledge-base/view.phtml/aid/3565
-------------------------------------------------------------
Fiona Czuczman, Olivier Dagenais
Shae Erisson

wxPython [ http://www.wxpython.org ] is a set of Python bindings for 
the GUI toolkit wxWindows [ http://www.wxwindows.org ], that was 
written as a C++ library to provide a platform-independant way of 
implementing rich and fast user interfaces.

I chose wxPython over Tkinter (for my projects) because:
- wxWindows seems to have more widgets than Tk
- special widgets (like the TreeView) are implemented using the 
operating system's native implementations, not complete re-writes
- it's more than a "lowest common denominator" among platforms, 
wxWindows seeks to provide the same, advanced functionality on all 
platforms, even if it means they have to write a lot of code to 
complement a platform's native component
- wxWindows seems to cover more ground, in terms of functionality (it's 
more than a GUI toolkit, it also seeks to provide functions/classes for 
files, threads, printing, clipboard, networking, ODBC, etc...)
- I was *really* impressed with the wxPython demo


-------------------------------------------------------------
Bidirectional communication through pipes: read/write popen()
http://www.faqts.com/knowledge-base/view.phtml/aid/4448
-------------------------------------------------------------
Nathan Wallace, Fiona Czuczman
Hans Nowak, Snippet 259, Hrvoje Niksic

"""
Packages: files;miscellaneous
"""

'''
In all kinds of circumstances it would be very useful to call an
external filter to process some data, and read the results back in.
What I needed was something like popen(), only working for both
reading and writing.  However, such a thing is hard to write in a
simple-minded fashion because of deadlocks that occur when handling
more than several bytes of data.  Deadlocks can either be caused by
both programs waiting for not-yet-generated input, or (in my case) by
both their writes being blocked waiting for the other to read.

The usual choices are to:

a) Write a deadlock-free communication protocol and use it on both
   ends.  This is rarely a good solution, because the program that
   needs to be invoked is in most cases an external filter that knows
   nothing about our deadlock problems.

b) Use PTY's instead of pipes.  Many programmers prefer to avoid this
   path because of the added system resources that the PTY's require,
   and because of the increased complexity.

Given these choices, most people opt to use a temporary file and get
it over with.

However, discussing this problem with a colleague, he thought of a
third solution: break the circularity by using a process only for
reading and writing.  This can be done whenever reading and writing
are independent, i.e. when the data read from the subprocess does not
influence future writes to it.

The function below implements that idea.  Usage is something like:

rwpopen("""Some long string here...""", "sed", ["s/long/short/"])
  -> 'Some short string here...'

I've put the function to good use in a program I'm writing.  In
addition to getting rid of temporary files, the whole operation timed
faster than using a tmpfile (that was on a single-CPU machine).  The
function will, of course, work only under Unix and its lookalikes.
Additional information is embedded in the docstring and the comments.

I'd like to hear feedback.  Do other people find such a thing useful?
Is there a fundamental flaw or a possibility of a deadlock that I'm
missing?
'''

def rwpopen(input, command, args=[]):
    """Execute command with args, pipe input into it, and read it back.
    Return the result read from the command.

    Normally, when a process tries to write to a child process and
    read back its output, a deadlock condition can occur easily,
    either by both processes waiting for not-yet-generated input, or
    by both their writes() being blocked waiting for the other to
    read.

    This function prevents deadlocks by using separate processes for
    reading and writing, at the expense of an additional fork().  That
    way the process that writes to an exec'ed command and the process
    that reads from the command are fully independent, and no deadlock
    can occur.  The child process exits immediately after writing.

    More precisely: the current process (A) forks off a process B,
    which in turns forks off a process C.  While C does the usual
    dup,close,exec thing, B merely writes the data to the pipe and
    exits.  Independently of B, A reads C's response.  A deadlock
    cannot occur because A and B are independent of each other -- even
    if B's write() is stopped because it filled up the pipe buffer, A
    will happily keep reading C's output, and B's write() will be
    resumed shortly.
    """
    # XXX Redo this as a class, with overridable methods for reading
    # and writing.
    #
    # XXX Provide error-checking and propagating exceptions from child
    # to parent.  This would require either wait()ing on the child
    # (which is a bag of worms), or opening another pipe for
    # transmitting error messages or serialized exception objects.
    #
    # XXX This function expects the system to wait for the child upon
    # receiving SIGCHLD.  This should be the case on most systems as
    # long as SIGCHLD is handled by SIG_DFL.  If this is not the case,
    # zombies will remain.

    def safe_traceback():
        # Child processes catch exceptions so that they can exit using
        # os._exit() without fanfare.  They use this function to print
        # the traceback to stderr before dying.
        import traceback
        sys.stderr.write("Error in child process, pid %d.\n" %
                         os.getpid())
        sys.stderr.flush()
        traceback.print_exc()
        sys.stderr.flush()

    # It would be nice if Python provided a way to see if pipes are
    # bidirectional.  In that case, we could open only one pipe
    # instead of two, with p_readfd == p_writefd and c_readfd ==
    # c_writefd.
    p_readfd, c_writefd = os.pipe()
    c_readfd, p_writefd = os.pipe()
    if os.fork():
        # Parent
        for fd in (c_readfd, c_writefd, p_writefd):
            os.close(fd)
        # Convert the pipe fd to a file object, so we can use its
        # read() method to read all data.
        fp = os.fdopen(p_readfd, 'r')
        result = fp.read()
        fp.close()                      # Will close p_readfd.
        return result
    else:
        # Child
        try:
            if os.fork():
                # Still the same child
                os.write(p_writefd, input)
            else:
                # Grandchild
                try:
                    # Redirect the pipe to stdin.
                    os.close(0)
                    os.dup(c_readfd)
                    # Redirect stdout to the pipe.
                    os.close(1)
                    os.dup(c_writefd)
                    # Now close unneeded descriptors.
                    for fd in (c_readfd, c_writefd, p_readfd, p_writefd):
                        os.close(fd)
                    # Finally, execute the external command.
                    os.execvp(command, [command] + args)
                except:
                    safe_traceback()
                    os._exit(127)
        except:
            safe_traceback()
            os._exit(127)
        else:
            os._exit(0)







More information about the Python-list mailing list