Commit 7acd50ad authored by Victor Stinner's avatar Victor Stinner Committed by GitHub

bpo-35491: Enhance multiprocessing.BaseProcess.__repr__() (GH-11138)

* Add the pid and parent pid to multiprocessing.BaseProcess.__repr__().
* Add negative sign (ex: "-SIGTERM") to exitcode (process killed
  by a signal)
* Only call _popen.poll() once.

Example:
  <ForkProcess(ForkPoolWorker-1, started daemon)>
becomes:
  <ForkProcess name='ForkPoolWorker-1' pid=12449 parent=12448 started daemon>

Example:
  <ForkProcess(ForkPoolWorker-1, stopped[SIGTERM] daemon)>
becomes:
  <ForkProcess name='ForkPoolWorker-1' pid=12960 parent=12959 stopped exitcode=-SIGTERM daemon>
parent cb0f5e29
...@@ -626,14 +626,14 @@ The :mod:`multiprocessing` package mostly replicates the API of the ...@@ -626,14 +626,14 @@ The :mod:`multiprocessing` package mostly replicates the API of the
>>> import multiprocessing, time, signal >>> import multiprocessing, time, signal
>>> p = multiprocessing.Process(target=time.sleep, args=(1000,)) >>> p = multiprocessing.Process(target=time.sleep, args=(1000,))
>>> print(p, p.is_alive()) >>> print(p, p.is_alive())
<Process(..., initial)> False <Process ... initial> False
>>> p.start() >>> p.start()
>>> print(p, p.is_alive()) >>> print(p, p.is_alive())
<Process(..., started)> True <Process ... started> True
>>> p.terminate() >>> p.terminate()
>>> time.sleep(0.1) >>> time.sleep(0.1)
>>> print(p, p.is_alive()) >>> print(p, p.is_alive())
<Process(..., stopped[SIGTERM])> False <Process ... stopped exitcode=-SIGTERM> False
>>> p.exitcode == -signal.SIGTERM >>> p.exitcode == -signal.SIGTERM
True True
......
...@@ -248,6 +248,7 @@ class BaseProcess(object): ...@@ -248,6 +248,7 @@ class BaseProcess(object):
raise ValueError("process not started") from None raise ValueError("process not started") from None
def __repr__(self): def __repr__(self):
exitcode = None
if self is _current_process: if self is _current_process:
status = 'started' status = 'started'
elif self._closed: elif self._closed:
...@@ -257,19 +258,23 @@ class BaseProcess(object): ...@@ -257,19 +258,23 @@ class BaseProcess(object):
elif self._popen is None: elif self._popen is None:
status = 'initial' status = 'initial'
else: else:
if self._popen.poll() is not None: exitcode = self._popen.poll()
status = self.exitcode if exitcode is not None:
else:
status = 'started'
if type(status) is int:
if status == 0:
status = 'stopped' status = 'stopped'
else: else:
status = 'stopped[%s]' % _exitcode_to_name.get(status, status) status = 'started'
return '<%s(%s, %s%s)>' % (type(self).__name__, self._name, info = [type(self).__name__, 'name=%r' % self._name]
status, self.daemon and ' daemon' or '') if self._popen is not None:
info.append('pid=%s' % self._popen.pid)
info.append('parent=%s' % self._parent_pid)
info.append(status)
if exitcode is not None:
exitcode = _exitcode_to_name.get(exitcode, exitcode)
info.append('exitcode=%s' % exitcode)
if self.daemon:
info.append('daemon')
return '<%s>' % ' '.join(info)
## ##
...@@ -373,7 +378,7 @@ _exitcode_to_name = {} ...@@ -373,7 +378,7 @@ _exitcode_to_name = {}
for name, signum in list(signal.__dict__.items()): for name, signum in list(signal.__dict__.items()):
if name[:3]=='SIG' and '_' not in name: if name[:3]=='SIG' and '_' not in name:
_exitcode_to_name[-signum] = name _exitcode_to_name[-signum] = f'-{name}'
# For debug and leak testing # For debug and leak testing
_dangling = WeakSet() _dangling = WeakSet()
:mod:`multiprocessing`: Add ``Pool.__repr__()`` and enhance
``BaseProcess.__repr__()`` (add pid and parent pid) to ease debugging. Pool
state constant values are now strings instead of integers, for example ``RUN``
value becomes ``'RUN'`` instead of ``0``.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment