Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1ce6b58

Browse files
committed
Merged revisions 80439 via svnmerge from
svn+ssh://[email protected]/python/trunk ........ r80439 | brian.curtin | 2010-04-24 10:40:11 -0500 (Sat, 24 Apr 2010) | 6 lines Fix #7838. Add docstrings and privatize _subprocess implementation details. Since CREATE_NEW_* are used for the creation flags of a subprocess, they were added to __all__. The rest of the previously exposed attributes are now qualified by _subprocess.ATTR rather than importing *. ........
1 parent e322024 commit 1ce6b58

2 files changed

Lines changed: 132 additions & 57 deletions

File tree

Lib/subprocess.py

Lines changed: 39 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -356,31 +356,18 @@ def __str__(self):
356356

357357

358358
if mswindows:
359+
from _subprocess import CREATE_NEW_CONSOLE, CREATE_NEW_PROCESS_GROUP
359360
import threading
360361
import msvcrt
361-
if 0: # <-- change this to use pywin32 instead of the _subprocess driver
362-
import pywintypes
363-
from win32api import GetStdHandle, STD_INPUT_HANDLE, \
364-
STD_OUTPUT_HANDLE, STD_ERROR_HANDLE
365-
from win32api import GetCurrentProcess, DuplicateHandle, \
366-
GetModuleFileName, GetVersion
367-
from win32con import DUPLICATE_SAME_ACCESS, SW_HIDE
368-
from win32pipe import CreatePipe
369-
from win32process import CreateProcess, STARTUPINFO, \
370-
GetExitCodeProcess, STARTF_USESTDHANDLES, \
371-
STARTF_USESHOWWINDOW, CREATE_NEW_CONSOLE
372-
from win32process import TerminateProcess
373-
from win32event import WaitForSingleObject, INFINITE, WAIT_OBJECT_0
374-
else:
375-
from _subprocess import *
376-
class STARTUPINFO:
377-
dwFlags = 0
378-
hStdInput = None
379-
hStdOutput = None
380-
hStdError = None
381-
wShowWindow = 0
382-
class pywintypes:
383-
error = IOError
362+
import _subprocess
363+
class STARTUPINFO:
364+
dwFlags = 0
365+
hStdInput = None
366+
hStdOutput = None
367+
hStdError = None
368+
wShowWindow = 0
369+
class pywintypes:
370+
error = IOError
384371
else:
385372
import select
386373
_has_poll = hasattr(select, 'poll')
@@ -406,6 +393,8 @@ class pywintypes:
406393
__all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "getstatusoutput",
407394
"getoutput", "check_output", "CalledProcessError"]
408395

396+
if mswindows:
397+
__all__.extend(["CREATE_NEW_CONSOLE", "CREATE_NEW_PROCESS_GROUP"])
409398
try:
410399
MAXFD = os.sysconf("SC_OPEN_MAX")
411400
except:
@@ -770,11 +759,11 @@ def _get_handles(self, stdin, stdout, stderr):
770759
errread, errwrite = -1, -1
771760

772761
if stdin is None:
773-
p2cread = GetStdHandle(STD_INPUT_HANDLE)
762+
p2cread = _subprocess.GetStdHandle(_subprocess.STD_INPUT_HANDLE)
774763
if p2cread is None:
775-
p2cread, _ = CreatePipe(None, 0)
764+
p2cread, _ = _subprocess.CreatePipe(None, 0)
776765
elif stdin == PIPE:
777-
p2cread, p2cwrite = CreatePipe(None, 0)
766+
p2cread, p2cwrite = _subprocess.CreatePipe(None, 0)
778767
elif isinstance(stdin, int):
779768
p2cread = msvcrt.get_osfhandle(stdin)
780769
else:
@@ -783,11 +772,11 @@ def _get_handles(self, stdin, stdout, stderr):
783772
p2cread = self._make_inheritable(p2cread)
784773

785774
if stdout is None:
786-
c2pwrite = GetStdHandle(STD_OUTPUT_HANDLE)
775+
c2pwrite = _subprocess.GetStdHandle(_subprocess.STD_OUTPUT_HANDLE)
787776
if c2pwrite is None:
788-
_, c2pwrite = CreatePipe(None, 0)
777+
_, c2pwrite = _subprocess.CreatePipe(None, 0)
789778
elif stdout == PIPE:
790-
c2pread, c2pwrite = CreatePipe(None, 0)
779+
c2pread, c2pwrite = _subprocess.CreatePipe(None, 0)
791780
elif isinstance(stdout, int):
792781
c2pwrite = msvcrt.get_osfhandle(stdout)
793782
else:
@@ -796,11 +785,11 @@ def _get_handles(self, stdin, stdout, stderr):
796785
c2pwrite = self._make_inheritable(c2pwrite)
797786

798787
if stderr is None:
799-
errwrite = GetStdHandle(STD_ERROR_HANDLE)
788+
errwrite = _subprocess.GetStdHandle(_subprocess.STD_ERROR_HANDLE)
800789
if errwrite is None:
801-
_, errwrite = CreatePipe(None, 0)
790+
_, errwrite = _subprocess.CreatePipe(None, 0)
802791
elif stderr == PIPE:
803-
errread, errwrite = CreatePipe(None, 0)
792+
errread, errwrite = _subprocess.CreatePipe(None, 0)
804793
elif stderr == STDOUT:
805794
errwrite = c2pwrite
806795
elif isinstance(stderr, int):
@@ -817,14 +806,15 @@ def _get_handles(self, stdin, stdout, stderr):
817806

818807
def _make_inheritable(self, handle):
819808
"""Return a duplicate of handle, which is inheritable"""
820-
return DuplicateHandle(GetCurrentProcess(), handle,
821-
GetCurrentProcess(), 0, 1,
822-
DUPLICATE_SAME_ACCESS)
809+
return _subprocess.DuplicateHandle(_subprocess.GetCurrentProcess(),
810+
handle, _subprocess.GetCurrentProcess(), 0, 1,
811+
_subprocess.DUPLICATE_SAME_ACCESS)
823812

824813

825814
def _find_w9xpopen(self):
826815
"""Find and return absolut path to w9xpopen.exe"""
827-
w9xpopen = os.path.join(os.path.dirname(GetModuleFileName(0)),
816+
w9xpopen = os.path.join(
817+
os.path.dirname(_subprocess.GetModuleFileName(0)),
828818
"w9xpopen.exe")
829819
if not os.path.exists(w9xpopen):
830820
# Eeek - file-not-found - possibly an embedding
@@ -854,17 +844,17 @@ def _execute_child(self, args, executable, preexec_fn, close_fds,
854844
if startupinfo is None:
855845
startupinfo = STARTUPINFO()
856846
if None not in (p2cread, c2pwrite, errwrite):
857-
startupinfo.dwFlags |= STARTF_USESTDHANDLES
847+
startupinfo.dwFlags |= _subprocess.STARTF_USESTDHANDLES
858848
startupinfo.hStdInput = p2cread
859849
startupinfo.hStdOutput = c2pwrite
860850
startupinfo.hStdError = errwrite
861851

862852
if shell:
863-
startupinfo.dwFlags |= STARTF_USESHOWWINDOW
864-
startupinfo.wShowWindow = SW_HIDE
853+
startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW
854+
startupinfo.wShowWindow = _subprocess.SW_HIDE
865855
comspec = os.environ.get("COMSPEC", "cmd.exe")
866856
args = comspec + " /c " + args
867-
if (GetVersion() >= 0x80000000 or
857+
if (_subprocess.GetVersion() >= 0x80000000 or
868858
os.path.basename(comspec).lower() == "command.com"):
869859
# Win9x, or using command.com on NT. We need to
870860
# use the w9xpopen intermediate program. For more
@@ -878,11 +868,11 @@ def _execute_child(self, args, executable, preexec_fn, close_fds,
878868
# use at xxx" and a hopeful warning about the
879869
# stability of your system. Cost is Ctrl+C won't
880870
# kill children.
881-
creationflags |= CREATE_NEW_CONSOLE
871+
creationflags |= _subprocess.CREATE_NEW_CONSOLE
882872

883873
# Start the process
884874
try:
885-
hp, ht, pid, tid = CreateProcess(executable, args,
875+
hp, ht, pid, tid = _subprocess.CreateProcess(executable, args,
886876
# no special security
887877
None, None,
888878
int(not close_fds),
@@ -921,17 +911,19 @@ def _internal_poll(self, _deadstate=None):
921911
"""Check if child process has terminated. Returns returncode
922912
attribute."""
923913
if self.returncode is None:
924-
if WaitForSingleObject(self._handle, 0) == WAIT_OBJECT_0:
925-
self.returncode = GetExitCodeProcess(self._handle)
914+
if(_subprocess.WaitForSingleObject(self._handle, 0) ==
915+
_subprocess.WAIT_OBJECT_0):
916+
self.returncode = _subprocess.GetExitCodeProcess(self._handle)
926917
return self.returncode
927918

928919

929920
def wait(self):
930921
"""Wait for child process to terminate. Returns returncode
931922
attribute."""
932923
if self.returncode is None:
933-
WaitForSingleObject(self._handle, INFINITE)
934-
self.returncode = GetExitCodeProcess(self._handle)
924+
_subprocess.WaitForSingleObject(self._handle,
925+
_subprocess.INFINITE)
926+
self.returncode = _subprocess.GetExitCodeProcess(self._handle)
935927
return self.returncode
936928

937929

@@ -990,7 +982,7 @@ def send_signal(self, sig):
990982
def terminate(self):
991983
"""Terminates the process
992984
"""
993-
TerminateProcess(self._handle, 1)
985+
_subprocess.TerminateProcess(self._handle, 1)
994986

995987
kill = terminate
996988

PC/_subprocess.c

Lines changed: 93 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,13 @@ static PyTypeObject sp_handle_type = {
158158
/* -------------------------------------------------------------------- */
159159
/* windows API functions */
160160

161+
PyDoc_STRVAR(GetStdHandle_doc,
162+
"GetStdHandle(handle) -> integer\n\
163+
\n\
164+
Return a handle to the specified standard device\n\
165+
(STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE).\n\
166+
The integer associated with the handle object is returned.");
167+
161168
static PyObject *
162169
sp_GetStdHandle(PyObject* self, PyObject* args)
163170
{
@@ -183,6 +190,11 @@ sp_GetStdHandle(PyObject* self, PyObject* args)
183190
return HANDLE_TO_PYNUM(handle);
184191
}
185192

193+
PyDoc_STRVAR(GetCurrentProcess_doc,
194+
"GetCurrentProcess() -> handle\n\
195+
\n\
196+
Return a handle object for the current process.");
197+
186198
static PyObject *
187199
sp_GetCurrentProcess(PyObject* self, PyObject* args)
188200
{
@@ -192,6 +204,17 @@ sp_GetCurrentProcess(PyObject* self, PyObject* args)
192204
return sp_handle_new(GetCurrentProcess());
193205
}
194206

207+
PyDoc_STRVAR(DuplicateHandle_doc,
208+
"DuplicateHandle(source_proc_handle, source_handle,\n\
209+
target_proc_handle, target_handle, access,\n\
210+
inherit[, options]) -> handle\n\
211+
\n\
212+
Return a duplicate handle object.\n\
213+
\n\
214+
The duplicate handle refers to the same object as the original\n\
215+
handle. Therefore, any changes to the object are reflected\n\
216+
through both handles.");
217+
195218
static PyObject *
196219
sp_DuplicateHandle(PyObject* self, PyObject* args)
197220
{
@@ -234,6 +257,14 @@ sp_DuplicateHandle(PyObject* self, PyObject* args)
234257
return sp_handle_new(target_handle);
235258
}
236259

260+
PyDoc_STRVAR(CreatePipe_doc,
261+
"CreatePipe(pipe_attrs, size) -> (read_handle, write_handle)\n\
262+
\n\
263+
Create an anonymous pipe, and return handles to the read and\n\
264+
write ends of the pipe.\n\
265+
\n\
266+
pipe_attrs is ignored internally and can be None.");
267+
237268
static PyObject *
238269
sp_CreatePipe(PyObject* self, PyObject* args)
239270
{
@@ -369,6 +400,18 @@ getenvironment(PyObject* environment)
369400
return NULL;
370401
}
371402

403+
PyDoc_STRVAR(CreateProcess_doc,
404+
"CreateProcess(app_name, cmd_line, proc_attrs, thread_attrs,\n\
405+
inherit, flags, env_mapping, curdir,\n\
406+
startup_info) -> (proc_handle, thread_handle,\n\
407+
pid, tid)\n\
408+
\n\
409+
Create a new process and its primary thread. The return\n\
410+
value is a tuple of the process handle, thread handle,\n\
411+
process ID, and thread ID.\n\
412+
\n\
413+
proc_attrs and thread_attrs are ignored internally and can be None.");
414+
372415
static PyObject *
373416
sp_CreateProcess(PyObject* self, PyObject* args)
374417
{
@@ -445,6 +488,11 @@ sp_CreateProcess(PyObject* self, PyObject* args)
445488
pi.dwThreadId);
446489
}
447490

491+
PyDoc_STRVAR(TerminateProcess_doc,
492+
"TerminateProcess(handle, exit_code) -> None\n\
493+
\n\
494+
Terminate the specified process and all of its threads.");
495+
448496
static PyObject *
449497
sp_TerminateProcess(PyObject* self, PyObject* args)
450498
{
@@ -465,6 +513,11 @@ sp_TerminateProcess(PyObject* self, PyObject* args)
465513
return Py_None;
466514
}
467515

516+
PyDoc_STRVAR(GetExitCodeProcess_doc,
517+
"GetExitCodeProcess(handle) -> Exit code\n\
518+
\n\
519+
Return the termination status of the specified process.");
520+
468521
static PyObject *
469522
sp_GetExitCodeProcess(PyObject* self, PyObject* args)
470523
{
@@ -483,6 +536,13 @@ sp_GetExitCodeProcess(PyObject* self, PyObject* args)
483536
return PyLong_FromLong(exit_code);
484537
}
485538

539+
PyDoc_STRVAR(WaitForSingleObject_doc,
540+
"WaitForSingleObject(handle, timeout) -> result\n\
541+
\n\
542+
Wait until the specified object is in the signaled state or\n\
543+
the time-out interval elapses. The timeout value is specified\n\
544+
in milliseconds.");
545+
486546
static PyObject *
487547
sp_WaitForSingleObject(PyObject* self, PyObject* args)
488548
{
@@ -505,6 +565,11 @@ sp_WaitForSingleObject(PyObject* self, PyObject* args)
505565
return PyLong_FromLong((int) result);
506566
}
507567

568+
PyDoc_STRVAR(GetVersion_doc,
569+
"GetVersion() -> version\n\
570+
\n\
571+
Return the version number of the current operating system.");
572+
508573
static PyObject *
509574
sp_GetVersion(PyObject* self, PyObject* args)
510575
{
@@ -514,6 +579,18 @@ sp_GetVersion(PyObject* self, PyObject* args)
514579
return PyLong_FromLong((int) GetVersion());
515580
}
516581

582+
PyDoc_STRVAR(GetModuleFileName_doc,
583+
"GetModuleFileName(module) -> path\n\
584+
\n\
585+
Return the fully-qualified path for the file that contains\n\
586+
the specified module. The module must have been loaded by the\n\
587+
current process.\n\
588+
\n\
589+
The module parameter should be a handle to the loaded module\n\
590+
whose path is being requested. If this parameter is 0, \n\
591+
GetModuleFileName retrieves the path of the executable file\n\
592+
of the current process.");
593+
517594
static PyObject *
518595
sp_GetModuleFileName(PyObject* self, PyObject* args)
519596
{
@@ -535,16 +612,22 @@ sp_GetModuleFileName(PyObject* self, PyObject* args)
535612
}
536613

537614
static PyMethodDef sp_functions[] = {
538-
{"GetStdHandle", sp_GetStdHandle, METH_VARARGS},
539-
{"GetCurrentProcess", sp_GetCurrentProcess, METH_VARARGS},
540-
{"DuplicateHandle", sp_DuplicateHandle, METH_VARARGS},
541-
{"CreatePipe", sp_CreatePipe, METH_VARARGS},
542-
{"CreateProcess", sp_CreateProcess, METH_VARARGS},
543-
{"TerminateProcess", sp_TerminateProcess, METH_VARARGS},
544-
{"GetExitCodeProcess", sp_GetExitCodeProcess, METH_VARARGS},
545-
{"WaitForSingleObject", sp_WaitForSingleObject, METH_VARARGS},
546-
{"GetVersion", sp_GetVersion, METH_VARARGS},
547-
{"GetModuleFileName", sp_GetModuleFileName, METH_VARARGS},
615+
{"GetStdHandle", sp_GetStdHandle, METH_VARARGS, GetStdHandle_doc},
616+
{"GetCurrentProcess", sp_GetCurrentProcess, METH_VARARGS,
617+
GetCurrentProcess_doc},
618+
{"DuplicateHandle", sp_DuplicateHandle, METH_VARARGS,
619+
DuplicateHandle_doc},
620+
{"CreatePipe", sp_CreatePipe, METH_VARARGS, CreatePipe_doc},
621+
{"CreateProcess", sp_CreateProcess, METH_VARARGS, CreateProcess_doc},
622+
{"TerminateProcess", sp_TerminateProcess, METH_VARARGS,
623+
TerminateProcess_doc},
624+
{"GetExitCodeProcess", sp_GetExitCodeProcess, METH_VARARGS,
625+
GetExitCodeProcess_doc},
626+
{"WaitForSingleObject", sp_WaitForSingleObject, METH_VARARGS,
627+
WaitForSingleObject_doc},
628+
{"GetVersion", sp_GetVersion, METH_VARARGS, GetVersion_doc},
629+
{"GetModuleFileName", sp_GetModuleFileName, METH_VARARGS,
630+
GetModuleFileName_doc},
548631
{NULL, NULL}
549632
};
550633

0 commit comments

Comments
 (0)