summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2017-05-03 01:21:19 +0200
committerGiampaolo Rodola <g.rodola@gmail.com>2017-05-03 01:21:19 +0200
commit13b68a54de2fdc3b77d62412b9723cf44b3ad926 (patch)
tree297257a86a860f17bdab0e14e73de7883c815b8d
parent743fc935a325370d5cb86e64c18317800276f4ae (diff)
parentb4b3892f42bfaed40d99a729456a560bb69f2600 (diff)
downloadpsutil-13b68a54de2fdc3b77d62412b9723cf44b3ad926.tar.gz
fix conflicts
-rw-r--r--HISTORY.rst1
-rw-r--r--psutil/_psutil_windows.c7
-rw-r--r--psutil/tests/__init__.py118
-rw-r--r--psutil/tests/test_unicode.py18
4 files changed, 61 insertions, 83 deletions
diff --git a/HISTORY.rst b/HISTORY.rst
index 85092fa6..94126cd3 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -35,6 +35,7 @@
None
- OpenBSD: connections('unix'): laddr and raddr are now set to "" instead of
None
+- 1046_: [Windows] disk_partitions() on Windows overrides user's SetErrorMode.
*2017-04-10*
diff --git a/psutil/_psutil_windows.c b/psutil/_psutil_windows.c
index b1a62977..1c742afb 100644
--- a/psutil/_psutil_windows.c
+++ b/psutil/_psutil_windows.c
@@ -2447,6 +2447,7 @@ psutil_disk_partitions(PyObject *self, PyObject *args) {
int all;
int type;
int ret;
+ unsigned int old_mode = 0;
char opts[20];
LPTSTR fs_type[MAX_PATH + 1] = { 0 };
DWORD pflags = 0;
@@ -2460,7 +2461,7 @@ psutil_disk_partitions(PyObject *self, PyObject *args) {
// avoid to visualize a message box in case something goes wrong
// see https://github.com/giampaolo/psutil/issues/264
- SetErrorMode(SEM_FAILCRITICALERRORS);
+ old_mode = SetErrorMode(SEM_FAILCRITICALERRORS);
if (! PyArg_ParseTuple(args, "O", &py_all))
goto error;
@@ -2541,11 +2542,11 @@ next:
drive_letter = strchr(drive_letter, 0) + 1;
}
- SetErrorMode(0);
+ SetErrorMode(old_mode);
return py_retlist;
error:
- SetErrorMode(0);
+ SetErrorMode(old_mode);
Py_XDECREF(py_tuple);
Py_DECREF(py_retlist);
return NULL;
diff --git a/psutil/tests/__init__.py b/psutil/tests/__init__.py
index e7e6f543..987907e5 100644
--- a/psutil/tests/__init__.py
+++ b/psutil/tests/__init__.py
@@ -27,7 +27,6 @@ import tempfile
import textwrap
import threading
import time
-import traceback
import warnings
from socket import AF_INET
from socket import AF_INET6
@@ -146,7 +145,6 @@ ASCII_FS = sys.getfilesystemencoding().lower() in ('ascii', 'us-ascii')
ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
SCRIPTS_DIR = os.path.join(ROOT_DIR, 'scripts')
-_HERE = os.path.abspath(os.path.dirname(__file__))
# --- support
@@ -175,26 +173,7 @@ SOCK_SEQPACKET = getattr(socket, "SOCK_SEQPACKET", object())
_subprocesses_started = set()
_pids_started = set()
-_testfiles = set()
-
-
-@atexit.register
-def _cleanup_files():
- DEVNULL.close()
- for name in os.listdir(_HERE):
- if name.startswith(TESTFILE_PREFIX):
- _testfiles.add(name)
- for name in _testfiles:
- try:
- safe_rmpath(name)
- except Exception:
- traceback.print_exc()
-
-
-# this is executed first
-@atexit.register
-def _cleanup_procs():
- reap_children(recursive=True)
+_testfiles_created = set()
# ===================================================================
@@ -244,18 +223,18 @@ class ThreadTask(threading.Thread):
def get_test_subprocess(cmd=None, **kwds):
- """Create a python subprocess which does nothing for 60 secs and
+ """Creates a python subprocess which does nothing for 60 secs and
return it as subprocess.Popen instance.
-
If "cmd" is specified that is used instead of python.
- By default sdtin and stdout are redirected to /dev/null.
+ By default stdout and stderr are redirected to /dev/null.
It also attemps to make sure the process is in a reasonably
initialized state.
-
- The caller is supposed to clean this up with reap_children().
"""
kwds.setdefault("stdin", DEVNULL)
kwds.setdefault("stdout", DEVNULL)
+ if WINDOWS:
+ # avoid creating error boxes
+ kwds.setdefault("creationflags", 0x8000000) # CREATE_NO_WINDOW
if cmd is None:
safe_rmpath(_TESTFN)
pyline = "from time import sleep;"
@@ -281,11 +260,8 @@ def create_proc_children_pair():
A (us) -> B (child) -> C (grandchild).
Return a (child, grandchild) tuple.
The 2 processes are fully initialized and will live for 60 secs.
-
- The caller is supposed to clean them up with reap_children().
"""
_TESTFN2 = os.path.basename(_TESTFN) + '2' # need to be relative
- _testfiles.add(_TESTFN2)
s = textwrap.dedent("""\
import subprocess, os, sys, time
PYTHON = os.path.realpath(sys.executable)
@@ -308,19 +284,16 @@ def create_proc_children_pair():
return (child1, child2)
except Exception:
reap_children()
- safe_rmpath(_TESTFN2)
raise
def pyrun(src):
- """Run python 'src' code (a string) in a separate interpreter
- and return it as a subprocess.Popen instance.
-
- The caller is supposed to clean this up with reap_children().
+ """Run python 'src' code in a separate interpreter.
+ Returns a subprocess.Popen instance.
"""
with tempfile.NamedTemporaryFile(
prefix=TESTFILE_PREFIX, mode="wt", delete=False) as f:
- _testfiles.add(f.name)
+ _testfiles_created.add(f.name)
f.write(src)
f.flush()
subp = get_test_subprocess([PYTHON, f.name], stdout=None,
@@ -329,37 +302,32 @@ def pyrun(src):
return subp
-def sh(cmd, **kwargs):
- """run cmd as subprocess.Popen and return its output.
+def sh(cmd):
+ """run cmd in a subprocess and return its output.
raises RuntimeError on error.
"""
- kwargs.setdefault("stdout", subprocess.PIPE)
- kwargs.setdefault("stderr", subprocess.PIPE)
- kwargs.setdefault(
- "shell", True if isinstance(cmd, (str, unicode)) else False)
- kwargs.setdefault("universal_newlines", True)
- p = subprocess.Popen(cmd, **kwargs)
- _subprocesses_started.add(p)
- try:
- stdout, stderr = p.communicate()
- if p.returncode != 0:
- raise RuntimeError(stderr)
- if stderr:
- warn(stderr)
- if stdout.endswith('\n'):
- stdout = stdout[:-1]
- return stdout
- except Exception:
- reap_children()
- raise
+ shell = True if isinstance(cmd, (str, unicode)) else False
+ # avoid creating error boxes on windows
+ creationflags = 0x8000000 if WINDOWS else 0
+ p = subprocess.Popen(cmd, shell=shell, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, universal_newlines=True,
+ creationflags=creationflags)
+ stdout, stderr = p.communicate()
+ if p.returncode != 0:
+ raise RuntimeError(stderr)
+ if stderr:
+ warn(stderr)
+ if stdout.endswith('\n'):
+ stdout = stdout[:-1]
+ return stdout
def reap_children(recursive=False):
- """Terminate and wait() ANY subprocess which was started by this
- test suite and ensure that no zombies stick around to hog resources
- and create problems when looking for refleaks.
+ """Terminate and wait() any subprocess started by this test suite
+ and ensure that no zombies stick around to hog resources and
+ create problems when looking for refleaks.
- If "esursive" is True it also tries hard to terminate and wait()
+ If resursive is True it also tries to terminate and wait()
all grandchildren started by this process.
"""
# Get the children here, before terminating the children sub
@@ -611,13 +579,13 @@ def chdir(dirname):
os.chdir(curdir)
-def create_exe(outpath, use_gcc=False, c_code=""):
+def create_exe(outpath, c_code=None):
"""Creates an executable file in the given location."""
assert not os.path.exists(outpath), outpath
- if use_gcc or c_code:
+ if c_code:
if not which("gcc"):
raise ValueError("gcc is not installed")
- if not c_code:
+ if c_code is None:
c_code = textwrap.dedent(
"""
#include <unistd.h>
@@ -642,9 +610,8 @@ def create_exe(outpath, use_gcc=False, c_code=""):
def unique_filename(prefix=TESTFILE_PREFIX, suffix=""):
- ret = tempfile.mktemp(prefix=prefix, suffix=suffix)
- _testfiles.add(ret)
- return ret
+ return tempfile.mktemp(prefix=prefix, suffix=suffix)
+
# ===================================================================
# --- testing
@@ -724,6 +691,21 @@ def skip_on_not_implemented(only_if=None):
return decorator
+def cleanup():
+ for name in os.listdir('.'):
+ if name.startswith(TESTFILE_PREFIX):
+ try:
+ safe_rmpath(name)
+ except UnicodeEncodeError as exc:
+ warn(exc)
+ for path in _testfiles_created:
+ safe_rmpath(path)
+
+
+atexit.register(cleanup)
+atexit.register(lambda: DEVNULL.close())
+
+
# ===================================================================
# --- network
# ===================================================================
@@ -991,6 +973,8 @@ def copyload_shared_lib(dst_prefix=TESTFILE_PREFIX):
dst = tempfile.mktemp(prefix=dst_prefix, suffix=ext)
libs = [x.path for x in psutil.Process().memory_maps()
if os.path.normcase(os.path.splitext(x.path)[1]) == ext]
+ if WINDOWS:
+ libs = [x for x in libs if 'wow64' not in x.lower()]
src = random.choice(libs)
cfile = None
try:
diff --git a/psutil/tests/test_unicode.py b/psutil/tests/test_unicode.py
index f67e14c2..ce881eac 100644
--- a/psutil/tests/test_unicode.py
+++ b/psutil/tests/test_unicode.py
@@ -110,16 +110,6 @@ def subprocess_supports_unicode(name):
return True
-def ctypes_supports_unicode(name):
- if PY3:
- return True
- try:
- with copyload_shared_lib():
- pass
- except UnicodeEncodeError:
- return False
-
-
# An invalid unicode string.
if PY3:
INVALID_NAME = (TESTFN.encode('utf8') + b"f\xc0\x80").decode(
@@ -252,15 +242,17 @@ class _BaseFSAPIsTests(object):
psutil.disk_usage(self.funky_name)
@unittest.skipIf(not HAS_MEMORY_MAPS, "not supported")
+ @unittest.skipIf(not PY3, "ctypes opens err msg box on Python 2")
def test_memory_maps(self):
- if not ctypes_supports_unicode(self.funky_name):
- raise unittest.SkipTest("ctypes can't handle unicode")
-
+ # XXX: on Python 2, using ctypes.CDLL with a unicode path
+ # opens a message box which blocks the test run.
with copyload_shared_lib(dst_prefix=self.funky_name) as funky_path:
def normpath(p):
return os.path.realpath(os.path.normcase(p))
libpaths = [normpath(x.path)
for x in psutil.Process().memory_maps()]
+ # ...just to have a clearer msg in case of failure
+ libpaths = [x for x in libpaths if TESTFILE_PREFIX in x]
self.assertIn(normpath(funky_path), libpaths)
for path in libpaths:
self.assertIsInstance(path, str)