diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2020-01-18 04:04:07 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-18 04:04:07 -0800 |
commit | ef28caec6c276c76c771c0bad03aea80cd765866 (patch) | |
tree | cb778d524929e87ee9deb74363ad94610cc04832 | |
parent | 2e0952e939d6ab517449314876d8d3488ba5b98b (diff) | |
download | psutil-ef28caec6c276c76c771c0bad03aea80cd765866.tar.gz |
Add *new_only* parameter for process_iter() (#1667)
-rw-r--r-- | CREDITS | 4 | ||||
-rw-r--r-- | HISTORY.rst | 5 | ||||
-rw-r--r-- | docs/index.rst | 35 | ||||
-rw-r--r-- | psutil/__init__.py | 12 | ||||
-rwxr-xr-x | psutil/tests/test_system.py | 18 |
5 files changed, 48 insertions, 26 deletions
@@ -656,3 +656,7 @@ I: 1646 N: Javad Karabi W: https://github.com/karabijavad I: 1648 + +N: Mike Hommey +W: https://github.com/glandium +I: 1665 diff --git a/HISTORY.rst b/HISTORY.rst index 4841d26e..28a5ce13 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,6 +1,6 @@ *Bug tracker at https://github.com/giampaolo/psutil/issues* -5.6.8 (unreleased) +5.7.0 (unreleased) ================== XXXX-XX-XX @@ -12,6 +12,7 @@ XXXX-XX-XX directory for additional data. (patch by Javad Karabi) - 1652_: [Windows] dropped support for Windows XP and Windows Server 2003. Minimum supported Windows version now is Windows Vista. +- 1667_: added process_iter(new_only=True) parameter. **Bug fixes** @@ -22,6 +23,8 @@ XXXX-XX-XX current user and os.getpid(). - 1660_: [Windows] Process.open_files() complete rewrite + check of errors. - 1662_: [Windows] process exe() may raise WinError 0. +- 1665_: [Linux] disk_io_counters() does not take into account extra fields + added to recent kernels. (patch by Mike Hommey) 5.6.7 ===== diff --git a/docs/index.rst b/docs/index.rst index d69e1fac..b1c4ab74 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -855,7 +855,7 @@ Functions .. versionchanged:: 5.6.0 PIDs are returned in sorted order -.. function:: process_iter(attrs=None, ad_value=None) +.. function:: process_iter(attrs=None, ad_value=None, new_only=False) Return an iterator yielding a :class:`Process` class instance for all running processes on the local machine. @@ -871,25 +871,11 @@ Functions the resulting dict is stored as a ``info`` attribute which is attached to the returned :class:`Process` instances. If *attrs* is an empty list it will retrieve all process info (slow). + If *new_only* is true this function will yield only new processes which + appeared since the last time it was called. Example usage:: >>> import psutil - >>> for proc in psutil.process_iter(): - ... try: - ... pinfo = proc.as_dict(attrs=['pid', 'name', 'username']) - ... except psutil.NoSuchProcess: - ... pass - ... else: - ... print(pinfo) - ... - {'name': 'systemd', 'pid': 1, 'username': 'root'} - {'name': 'kthreadd', 'pid': 2, 'username': 'root'} - {'name': 'ksoftirqd/0', 'pid': 3, 'username': 'root'} - ... - - More compact version using *attrs* parameter:: - - >>> import psutil >>> for proc in psutil.process_iter(attrs=['pid', 'name', 'username']): ... print(proc.info) ... @@ -909,19 +895,28 @@ Functions 3: {'name': 'ksoftirqd/0', 'username': 'root'}, ...} - Example showing how to filter processes by name:: + Example showing how to filter processes by name (see also + `process filtering <#filtering-and-sorting-processes>`__ section for more + examples):: >>> import psutil >>> [p.info for p in psutil.process_iter(attrs=['pid', 'name']) if 'python' in p.info['name']] [{'name': 'python3', 'pid': 21947}, {'name': 'python', 'pid': 23835}] - See also `process filtering <#filtering-and-sorting-processes>`__ section for - more examples. + Get new processes only (since last call):: + + >>> import psutil + >>> for proc in psutil.process_iter(attrs=['pid', 'name'], new_only=True): + ... print(proc.info) + ... .. versionchanged:: 5.3.0 added "attrs" and "ad_value" parameters. + .. versionchanged:: + 5.7.0 added "new_only" parameter. + .. function:: pid_exists(pid) Check whether the given PID exists in the current process list. This is diff --git a/psutil/__init__.py b/psutil/__init__.py index ffeead87..e74bb109 100644 --- a/psutil/__init__.py +++ b/psutil/__init__.py @@ -227,7 +227,7 @@ __all__ = [ __all__.extend(_psplatform.__extra__all__) __author__ = "Giampaolo Rodola'" -__version__ = "5.6.8" +__version__ = "5.7.0" version_info = tuple([int(num) for num in __version__.split('.')]) _timer = getattr(time, 'monotonic', time.time) @@ -1407,7 +1407,7 @@ _pmap = {} _lock = threading.Lock() -def process_iter(attrs=None, ad_value=None): +def process_iter(attrs=None, ad_value=None, new_only=False): """Return a generator yielding a Process instance for all running processes. @@ -1427,6 +1427,8 @@ def process_iter(attrs=None, ad_value=None): to returned Process instance. If *attrs* is an empty list it will retrieve all process info (slow). + If *new_only* is true this function will yield only new processes + which appeared since the last time it was called. """ def add(pid): proc = Process(pid) @@ -1448,8 +1450,10 @@ def process_iter(attrs=None, ad_value=None): remove(pid) with _lock: - ls = sorted(list(_pmap.items()) + - list(dict.fromkeys(new_pids).items())) + ls = list(dict.fromkeys(new_pids).items()) + if not new_only: + ls += list(_pmap.items()) + ls.sort() for pid, proc in ls: try: diff --git a/psutil/tests/test_system.py b/psutil/tests/test_system.py index e04e120b..f2d07282 100755 --- a/psutil/tests/test_system.py +++ b/psutil/tests/test_system.py @@ -85,7 +85,7 @@ class TestSystemAPIs(unittest.TestCase): with self.assertRaises(psutil.AccessDenied): list(psutil.process_iter()) - def test_prcess_iter_w_params(self): + def test_prcess_iter_w_attrs(self): for p in psutil.process_iter(attrs=['pid']): self.assertEqual(list(p.info.keys()), ['pid']) with self.assertRaises(ValueError): @@ -105,6 +105,22 @@ class TestSystemAPIs(unittest.TestCase): self.assertGreaterEqual(p.info['pid'], 0) assert m.called + def test_process_iter_new_only(self): + ls1 = list(psutil.process_iter(attrs=['pid'])) + ls2 = list(psutil.process_iter(attrs=['pid'], new_only=True)) + self.assertGreater(len(ls1), len(ls2)) + # assume no more than 3 new processes were created in the meantime + self.assertIn(len(ls2), [0, 1, 2, 3, 4, 5]) + + sproc = get_test_subprocess() + ls = list(psutil.process_iter(attrs=['pid'], new_only=True)) + self.assertIn(len(ls2), [0, 1, 2, 3, 4, 5]) + for p in ls: + if p.pid == sproc.pid: + break + else: + self.fail("subprocess not found") + def test_wait_procs(self): def callback(p): pids.append(p.pid) |