From 1994969c15a055d2f9479d3bc10fb6304b2979ed Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Sun, 25 Apr 2010 22:33:36 +0000 Subject: When DeprecationWarning was silenced by default, it also silenced any use of -Q by default as well. This change fixes that by treating -Q like -3 when it comes to DeprecationWarning; using it causes the silencing to not occur. Fixes issue #7319. --- Lib/subprocess.py | 53 ++++++++++++++++++++++++++++++++++++----------------- Lib/warnings.py | 3 ++- Misc/NEWS | 2 ++ Python/_warnings.c | 12 +++++++----- 4 files changed, 47 insertions(+), 23 deletions(-) diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 8c687c9..3cd2357 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -413,7 +413,6 @@ class CalledProcessError(Exception): if mswindows: - from _subprocess import CREATE_NEW_CONSOLE, CREATE_NEW_PROCESS_GROUP import threading import msvcrt import _subprocess @@ -442,6 +441,7 @@ __all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "check_output", "CalledProcessError"] if mswindows: + from _subprocess import CREATE_NEW_CONSOLE, CREATE_NEW_PROCESS_GROUP __all__.extend(["CREATE_NEW_CONSOLE", "CREATE_NEW_PROCESS_GROUP"]) try: MAXFD = os.sysconf("SC_OPEN_MAX") @@ -699,12 +699,12 @@ class Popen(object): return data - def __del__(self, sys=sys): + def __del__(self, _maxint=sys.maxint): if not self._child_created: # We didn't get to successfully create a child process. return # In case the child hasn't been waited on, check if it's done. - self._internal_poll(_deadstate=sys.maxint) + self._internal_poll(_deadstate=_maxint) if self.returncode is None and _active is not None: # Child is still running, keep us alive until we can wait on it. _active.append(self) @@ -907,13 +907,20 @@ class Popen(object): errwrite.Close() - def _internal_poll(self, _deadstate=None): + def _internal_poll(self, _deadstate=None, + _WaitForSingleObject=WaitForSingleObject, + _WAIT_OBJECT_0=WAIT_OBJECT_0, + _GetExitCodeProcess=GetExitCodeProcess): """Check if child process has terminated. Returns returncode - attribute.""" + attribute. + + This method is called by __del__, so it can only refer to objects + in its local scope. + + """ if self.returncode is None: - if(_subprocess.WaitForSingleObject(self._handle, 0) == - _subprocess.WAIT_OBJECT_0): - self.returncode = _subprocess.GetExitCodeProcess(self._handle) + if _WaitForSingleObject(self._handle, 0) == _WAIT_OBJECT_0: + self.returncode = _GetExitCodeProcess(self._handle) return self.returncode @@ -1194,25 +1201,37 @@ class Popen(object): raise child_exception - def _handle_exitstatus(self, sts): - if os.WIFSIGNALED(sts): - self.returncode = -os.WTERMSIG(sts) - elif os.WIFEXITED(sts): - self.returncode = os.WEXITSTATUS(sts) + def _handle_exitstatus(self, sts, _WIFSIGNALED=os.WIFSIGNALED, + _WTERMSIG=os.WTERMSIG, _WIFEXITED=os.WIFEXITED, + _WEXITSTATUS=os.WEXITSTATUS): + """ + + This method is called (indirectly) by __del__, so it cannot + refer to anything outside of its local scope.""" + if _WIFSIGNALED(sts): + self.returncode = -_WTERMSIG(sts) + elif _WIFEXITED(sts): + self.returncode = _WEXITSTATUS(sts) else: # Should never happen raise RuntimeError("Unknown child exit status!") - def _internal_poll(self, _deadstate=None): + def _internal_poll(self, _deadstate=None, _waitpid=os.waitpid, + _WNOHANG=os.WNOHANG, _os_error=os.error): """Check if child process has terminated. Returns returncode - attribute.""" + attribute. + + This method is called by __del__, so it cannot reference anything + outside of the local scope (nor can any methods it calls). + + """ if self.returncode is None: try: - pid, sts = os.waitpid(self.pid, os.WNOHANG) + pid, sts = _waitpid(self.pid, _WNOHANG) if pid == self.pid: self._handle_exitstatus(sts) - except os.error: + except _os_error: if _deadstate is not None: self.returncode = _deadstate return self.returncode diff --git a/Lib/warnings.py b/Lib/warnings.py index 134ba13..08b70af 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -384,7 +384,8 @@ except ImportError: _processoptions(sys.warnoptions) if not _warnings_defaults: silence = [ImportWarning, PendingDeprecationWarning] - if not sys.py3kwarning: # Don't silence DeprecationWarning if -3 was used. + # Don't silence DeprecationWarning if -3 or -Q was used. + if not sys.py3kwarning and not sys.flags.division_warning: silence.append(DeprecationWarning) for cls in silence: simplefilter("ignore", category=cls) diff --git a/Misc/NEWS b/Misc/NEWS index e1ba703..db6ca01 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -12,6 +12,8 @@ What's New in Python 2.7 beta 2? Core and Builtins ----------------- +- Issue #7319: When -Q is used, do not silence DeprecationWarning. + - Issue #7332: Remove the 16KB stack-based buffer in PyMarshal_ReadLastObjectFromFile, which doesn't bring any noticeable benefit compared to the dynamic memory allocation fallback. Patch by diff --git a/Python/_warnings.c b/Python/_warnings.c index bddd44c..1dc2512 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -280,7 +280,7 @@ show_warning(PyObject *filename, int lineno, PyObject *text, PyObject PyFile_WriteString("\n", f_stderr); } else - _Py_DisplaySourceLine(f_stderr, PyString_AS_STRING(filename), + _Py_DisplaySourceLine(f_stderr, PyString_AS_STRING(filename), lineno, 2); PyErr_Clear(); } @@ -294,7 +294,7 @@ warn_explicit(PyObject *category, PyObject *message, PyObject *item = Py_None; const char *action; int rc; - + if (registry && !PyDict_Check(registry) && (registry != Py_None)) { PyErr_SetString(PyExc_TypeError, "'registry' must be a dict"); return NULL; @@ -839,8 +839,9 @@ create_filter(PyObject *category, const char *action) static PyObject * init_filters(void) { - /* Don't silence DeprecationWarning if -3 was used. */ - PyObject *filters = PyList_New(Py_Py3kWarningFlag ? 3 : 4); + /* Don't silence DeprecationWarning if -3 or -Q were used. */ + PyObject *filters = PyList_New(Py_Py3kWarningFlag || + Py_DivisionWarningFlag ? 3 : 4); unsigned int pos = 0; /* Post-incremented in each use. */ unsigned int x; const char *bytes_action; @@ -848,7 +849,8 @@ init_filters(void) if (filters == NULL) return NULL; - if (!Py_Py3kWarningFlag) { + /* If guard changes, make sure to update 'filters' initialization above. */ + if (!Py_Py3kWarningFlag && !Py_DivisionWarningFlag) { PyList_SET_ITEM(filters, pos++, create_filter(PyExc_DeprecationWarning, "ignore")); } -- cgit v0.12