diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2017-05-03 01:21:19 +0200 |
---|---|---|
committer | Giampaolo Rodola <g.rodola@gmail.com> | 2017-05-03 01:21:19 +0200 |
commit | 13b68a54de2fdc3b77d62412b9723cf44b3ad926 (patch) | |
tree | 297257a86a860f17bdab0e14e73de7883c815b8d | |
parent | 743fc935a325370d5cb86e64c18317800276f4ae (diff) | |
parent | b4b3892f42bfaed40d99a729456a560bb69f2600 (diff) | |
download | psutil-13b68a54de2fdc3b77d62412b9723cf44b3ad926.tar.gz |
fix conflicts
-rw-r--r-- | HISTORY.rst | 1 | ||||
-rw-r--r-- | psutil/_psutil_windows.c | 7 | ||||
-rw-r--r-- | psutil/tests/__init__.py | 118 | ||||
-rw-r--r-- | psutil/tests/test_unicode.py | 18 |
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) |