Skip to content

Commit

Permalink
Merge branch 'master' of github.com:giampaolo/psutil
Browse files Browse the repository at this point in the history
  • Loading branch information
giampaolo committed Jan 18, 2020
2 parents 5f16b3a + ef28cae commit e65cc95
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 26 deletions.
3 changes: 2 additions & 1 deletion HISTORY.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
*Bug tracker at https://github.com/giampaolo/psutil/issues*

5.6.8 (unreleased)
5.7.0 (unreleased)
==================

XXXX-XX-XX
Expand All @@ -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**

Expand Down
35 changes: 15 additions & 20 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -871,24 +871,10 @@ 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)
Expand All @@ -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
Expand Down
12 changes: 8 additions & 4 deletions psutil/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@

__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)
Expand Down Expand Up @@ -1407,7 +1407,7 @@ def pid_exists(pid):
_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.
Expand All @@ -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)
Expand All @@ -1448,8 +1450,10 @@ def remove(pid):
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:
Expand Down
18 changes: 17 additions & 1 deletion psutil/tests/test_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def test_process_iter(self):
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):
Expand All @@ -105,6 +105,22 @@ def test_prcess_iter_w_params(self):
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)
Expand Down

0 comments on commit e65cc95

Please sign in to comment.