summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2020-01-18 04:04:07 -0800
committerGitHub <noreply@github.com>2020-01-18 04:04:07 -0800
commitef28caec6c276c76c771c0bad03aea80cd765866 (patch)
treecb778d524929e87ee9deb74363ad94610cc04832
parent2e0952e939d6ab517449314876d8d3488ba5b98b (diff)
downloadpsutil-ef28caec6c276c76c771c0bad03aea80cd765866.tar.gz
Add *new_only* parameter for process_iter() (#1667)
-rw-r--r--CREDITS4
-rw-r--r--HISTORY.rst5
-rw-r--r--docs/index.rst35
-rw-r--r--psutil/__init__.py12
-rwxr-xr-xpsutil/tests/test_system.py18
5 files changed, 48 insertions, 26 deletions
diff --git a/CREDITS b/CREDITS
index 988af1fe..b2234ce3 100644
--- a/CREDITS
+++ b/CREDITS
@@ -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)