summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2020-01-18 13:04:20 +0100
committerGiampaolo Rodola <g.rodola@gmail.com>2020-01-18 13:04:20 +0100
commite65cc95de72828caed74c7916530dd74fca351e3 (patch)
treecb778d524929e87ee9deb74363ad94610cc04832
parent5f16b3a3c498c89dd11d03b3db1592b2332b5cbf (diff)
parentef28caec6c276c76c771c0bad03aea80cd765866 (diff)
downloadpsutil-e65cc95de72828caed74c7916530dd74fca351e3.tar.gz
Merge branch 'master' of github.com:giampaolo/psutil
-rw-r--r--HISTORY.rst3
-rw-r--r--docs/index.rst35
-rw-r--r--psutil/__init__.py12
-rwxr-xr-xpsutil/tests/test_system.py18
4 files changed, 42 insertions, 26 deletions
diff --git a/HISTORY.rst b/HISTORY.rst
index 96268d98..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**
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)