From 2d32a26a257c7ce17806f0ec150bcbba5f39f914 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Fri, 12 May 2017 12:17:53 +0200 Subject: [PATCH] fix 1062: avoid TypeError on disk|net_io_counters() if no disks or NICs are installed on the system --- HISTORY.rst | 2 ++ psutil/__init__.py | 4 ++++ psutil/tests/test_system.py | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/HISTORY.rst b/HISTORY.rst index 3e5f0f475..ea4d1e5b8 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -43,6 +43,8 @@ - 1047_: [Windows] Process username(): memory leak in case exception is thrown. - 1048_: [Windows] users()'s host field report an invalid IP address. - 1058_: fixed Python warnings. +- 1062_: disk_io_counters() and net_io_counters() raise TypeError if no disks + or NICs are installed on the system. **Porting notes** diff --git a/psutil/__init__.py b/psutil/__init__.py index 509fcf823..88f7e158e 100644 --- a/psutil/__init__.py +++ b/psutil/__init__.py @@ -2083,6 +2083,8 @@ def disk_io_counters(perdisk=False, nowrap=True): executed first otherwise this function won't find any disk. """ rawdict = _psplatform.disk_io_counters() + if not rawdict: + return {} if perdisk else None if nowrap: rawdict = _wrap_numbers(rawdict, 'psutil.disk_io_counters') nt = getattr(_psplatform, "sdiskio", _common.sdiskio) @@ -2131,6 +2133,8 @@ def net_io_counters(pernic=False, nowrap=True): cache. """ rawdict = _psplatform.net_io_counters() + if not rawdict: + return {} if pernic else None if nowrap: rawdict = _wrap_numbers(rawdict, 'psutil.net_io_counters') if pernic: diff --git a/psutil/tests/test_system.py b/psutil/tests/test_system.py index 32f76f57c..fed7a222a 100755 --- a/psutil/tests/test_system.py +++ b/psutil/tests/test_system.py @@ -553,6 +553,15 @@ def check_ntuple(nt): self.assertIsInstance(key, str) check_ntuple(ret[key]) + def test_net_io_counters_no_nics(self): + # Emulate a case where no NICs are installed, see: + # https://github.com/giampaolo/psutil/issues/1062 + with mock.patch('psutil._psplatform.net_io_counters', + return_value={}) as m: + self.assertIsNone(psutil.net_io_counters(pernic=False)) + self.assertEqual(psutil.net_io_counters(pernic=True), {}) + assert m.called + def test_net_if_addrs(self): nics = psutil.net_if_addrs() assert nics, nics @@ -682,6 +691,15 @@ def check_ntuple(nt): key = key[:-1] self.assertNotIn(key, ret.keys()) + def test_disk_io_counters_no_disks(self): + # Emulate a case where no disks are installed, see: + # https://github.com/giampaolo/psutil/issues/1062 + with mock.patch('psutil._psplatform.disk_io_counters', + return_value={}) as m: + self.assertIsNone(psutil.disk_io_counters(perdisk=False)) + self.assertEqual(psutil.disk_io_counters(perdisk=True), {}) + assert m.called + # can't find users on APPVEYOR or TRAVIS @unittest.skipIf(APPVEYOR or TRAVIS and not psutil.users(), "unreliable on APPVEYOR or TRAVIS")