From 9d455a5e431921be1a25f2fee6e4a47dac9de995 Mon Sep 17 00:00:00 2001 From: David Goodger Date: Tue, 3 Aug 2004 13:13:43 +0000 Subject: [PATCH] update from Peter Astrand --- pep-0000.txt | 4 +- pep-0324.txt | 242 +++++++++++++++++++++++++++++++++------------------ 2 files changed, 157 insertions(+), 89 deletions(-) diff --git a/pep-0000.txt b/pep-0000.txt index 78d72bcc0..aacbb8049 100644 --- a/pep-0000.txt +++ b/pep-0000.txt @@ -119,7 +119,7 @@ Index by Category S 319 Python Synchronize/Asynchronize Block Pelletier S 321 Date/Time Parsing and Formatting Kuchling S 323 Copyable Iterators Martelli - S 324 popen5 - New POSIX process module Astrand + S 324 process - New POSIX process module Astrand S 325 Resource-Release Support for Generators Pedroni S 330 Python Bytecode Verification Pelletier S 331 Locale-Independent Float/String conversions Reis @@ -347,7 +347,7 @@ Numerical Index S 321 Date/Time Parsing and Formatting Kuchling SF 322 Reverse Iteration Hettinger S 323 Copyable Iterators Martelli - S 324 popen5 - New POSIX process module Astrand + S 324 process - New POSIX process module Astrand S 325 Resource-Release Support for Generators Pedroni SR 326 A Case for Top and Bottom Values Carlson, Reedy SF 327 Decimal Data Type Batista diff --git a/pep-0324.txt b/pep-0324.txt index 5774f9b3e..8a98ee029 100644 --- a/pep-0324.txt +++ b/pep-0324.txt @@ -1,5 +1,5 @@ PEP: 324 -Title: popen5 - New POSIX process module +Title: process - New POSIX process module Version: $Revision$ Last-Modified: $Date$ Author: Peter Astrand @@ -33,7 +33,7 @@ Motivation Currently, Python has a large number of different functions for process creation. This makes it hard for developers to choose. - The popen5 modules provides the following enhancements over + The process module provides the following enhancements over previous functions: - One "unified" module provides all functionality from previous @@ -56,8 +56,8 @@ Motivation and redirect stderr, but not stdout. This is not possible with current functions, without using temporary files. - - With popen5, it's possible to control if all open file - descriptors should be closed before the new program is + - With the process module, it's possible to control if all open + file descriptors should be closed before the new program is executed. - Support for connecting several subprocesses (shell "pipe"). @@ -78,23 +78,23 @@ Rationale The following points summarizes the design: - - popen5 was based on popen2, which is tried-and-tested. + - process was based on popen2, which is tried-and-tested. - The factory functions in popen2 have been removed, because I consider the class constructor equally easy to work with. - popen2 contains several factory functions and classes for - different combinations of redirection. popen5, however, - contains one single class. Since popen5 supports 12 different - combinations of redirection, providing a class or function for - each of them would be cumbersome and not very intuitive. Even - with popen2, this is a readability problem. For example, many - people cannot tell the difference between popen2.popen2 and - popen2.popen4 without using the documentation. + different combinations of redirection. process, however, + contains one single class. Since the process module supports 12 + different combinations of redirection, providing a class or + function for each of them would be cumbersome and not very + intuitive. Even with popen2, this is a readability problem. + For example, many people cannot tell the difference between + popen2.popen2 and popen2.popen4 without using the documentation. - - One small utility function is provided: popen5.run(). It aims - to be an enhancement over os.system(), while still very easy to - use: + - Two small utility functions are provided: process.call() and + process.callv(). These aims to be an enhancement over + os.system(), while still very easy to use: - It does not use the Standard C function system(), which has limitations. @@ -105,6 +105,43 @@ Rationale - The return value is easier to work with. + The call() utility function accepts an 'args' argument, just + like the Popen class constructor. It waits for the command to + complete, then returns the returncode attribute. The + implementation is very simple: + + def call(*args, **kwargs): + return Popen(*args, **kwargs).wait() + + The motivation behind the call() function is simple: Starting a + process and wait for it to finish is a common task. + + The callv() function is identical to call(), except that each + non-keyword argument is treated as a program argument. This + gives a slightly nicer syntax. The drawback is that callv() does + not allow specifying the program and it's arguments as a + whitespace-separated string: The entire (first) string would be + intepreted as the executable. The implementation of callv() is + also very simple: + + def callv(*args, **kwargs): + return Popen(args, **kwargs).wait() + + While Popen supports a wide range of options, many users have + simple needs. Many people are using os.system() today, mainly + because it provides a simple interface. Consider this example: + + os.system("stty sane -F " + device) + + With process.call(), this would look like: + + process.call(["stty", "sane", "-F", device]) + + Some people feel that the list brackets are clumsy. With + callv(), they are not needed: + + process.callv("stty", "sane", "-F", device) + - The "preexec" functionality makes it possible to run arbitrary code between fork and exec. One might ask why there are special arguments for setting the environment and current directory, but @@ -119,27 +156,39 @@ Rationale - env and cwd are considered quite cross-platform: They make sense even on Windows. - - No MS Windows support is available, currently. To be able to - provide more functionality than what is already available from - the popen2 module, help from C modules is required. - Specification This module defines one class called Popen: - class Popen(args, bufsize=0, argv0=None, + class Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, - preexec_fn=None, preexec_args=(), close_fds=0, - cwd=None, env=None, universal_newlines=0) - - Arguments are: - + preexec_fn=None, close_fds=False, + cwd=None, env=None, universal_newlines=False, + startupinfo=None, creationflags=0): + + + Arguments are: + - args should be a sequence of program arguments. The program to execute is normally the first item in the args sequence, but can - be explicitly set by using the argv0 argument. The Popen class - uses os.execvp() to execute the child program. - + be explicitly set by using the executable argument. + + - On UNIX: the Popen class uses os.execvp() to execute the child + program, which operates on sequences. If args is a string, it + will be converted to a sequence using the cmdline2list method. + Please note that syntax for quoting arguments is different from + a typical UNIX shell. See the documentation of the cmdline2list + method for more information. + + - On Windows: the Popen class uses CreateProcess() to execute the + child program, which operates on strings. If args is a + sequence, it will be converted to a string using the + list2cmdline method. Please note that not all MS Windows + applications interpret the command line the same way: The + list2cmdline is designed for applications using the same rules + as the MS C runtime. + - bufsize, if given, has the same meaning as the corresponding argument to the built-in open() function: 0 means unbuffered, 1 means line buffered, any other positive value means use a buffer @@ -159,8 +208,7 @@ Specification stdout. - If preexec_fn is set to a callable object, this object will be - called in the child process just before the child is executed, - with arguments preexec_args. + called in the child process just before the child is executed. - If close_fds is true, all file descriptors except 0, 1 and 2 will be closed before the child process is executed. @@ -171,65 +219,80 @@ Specification - If env is not None, it defines the environment variables for the new process. - - If universal_newlines is true, the file objects fromchild and - childerr are opened as a text files, but lines may be terminated + - If universal_newlines is true, the file objects stdout and + stderr are opened as a text files, but lines may be terminated by any of '\n', the Unix end-of-line convention, '\r', the Macintosh convention or '\r\n', the Windows convention. All of these external representations are seen as '\n' by the Python program. Note: This feature is only available if Python is built with universal newline support (the default). Also, the - newlines attribute of the file objects fromchild, tochild and - childerr are not updated by the communicate() method. - - The module also defines one shortcut function: - - run(*args): - Run command with arguments. Wait for command to complete, - then return the returncode attribute. Example: - - retcode = popen5.run("stty", "sane") - + newlines attribute of the file objects stdout, stdin and stderr + are not updated by the communicate() method. + - The startupinfo and creationflags, if given, will be passed to + the underlying CreateProcess() function. They can specify + things such as appearance of the main window and priority for + the new process. (Windows only) + + + This module also defines two shortcut functions: + + - call(*args, **kwargs): + Run command with arguments. Wait for command to complete, then + return the returncode attribute. + + The arguments are the same as for the Popen constructor. Example: + + retcode = call(["ls", "-l"]) + + + - callv(*args, **kwargs): + Run command with arguments. Wait for command to complete, then + return the returncode attribute. + + This function is identical to call(), except that each non-keyword + argument is treated as a program argument. Example: + + retcode = callv("ls", "-l") + + This is equivalent to: + + retcode = call(["ls", "-l"]) + + Exceptions ---------- Exceptions raised in the child process, before the new program has - started to execute, will be re-raised in the parent. Additionally, - the exception object will have one extra attribute called - 'child_traceback', which is a string containing traceback - information from the child's point of view. - + started to execute, will be re-raised in the parent. + Additionally, the exception object will have one extra attribute + called 'child_traceback', which is a string containing traceback + information from the childs point of view. + The most common exception raised is OSError. This occurs, for example, when trying to execute a non-existent file. Applications should prepare for OSErrors. - - A PopenException will also be raised if Popen is called with - invalid arguments. - - + + A ValueError will be raised if Popen is called with invalid arguments. + + Security -------- - popen5 will never call /bin/sh implicitly. This means that all - characters, including shell metacharacters, can safely be passed - to child processes. - - + Unlike some other popen functions, this implementation will never call + /bin/sh implicitly. This means that all characters, including shell + metacharacters, can safely be passed to child processes. + + Popen objects ------------- Instances of the Popen class have the following methods: poll() - Returns -1 if child process hasn't completed yet, or its exit - status otherwise. See below for a description of how the exit - status is encoded. - + Check if child process has terminated. Returns returncode + attribute. + wait() - Waits for and returns the exit status of the child process. - The exit status encodes both the return code of the process - and information about whether it exited using the exit() - system call or died due to a signal. Functions to help - interpret the status code are defined in the os module (the - W*() family of functions). - + Wait for child process to terminate. Returns returncode attribute. + communicate(input=None) Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for @@ -243,31 +306,36 @@ Specification method if the data size is large or unlimited. The following attributes are also available: - - fromchild - A file object that provides output from the child process. - - tochild - A file object that provides input to the child process. - - childerr - A file object that provides error output from the child - process. - + + stdin + If the stdin argument is PIPE, this attribute is a file object + that provides input to the child process. Otherwise, it is None. + + stdout + If the stdout argument is PIPE, this attribute is a file object + that provides output from the child process. Otherwise, it is + None. + + stderr + If the stderr argument is PIPE, this attribute is file object that + provides error output from the child process. Otherwise, it is + None. + pid The process ID of the child process. returncode The child return code. A None value indicates that the - process hasn't terminated yet. A negative value means that - the process was terminated by a signal with number - -returncode. - - + process hasn't terminated yet. A negative value -N indicates + that the child was terminated by signal N (UNIX only). + + Open Issues - Perhaps the module should be called something like "process", - instead of "popen5". + Currently, the reference implementation requires the "win32all" + extensions when running on the Windows platform. This dependency + could probably be eliminated by providing a small "glue" module + written in C, just like the _winreg module. Reference Implementation