bpo-5001: More-informative multiprocessing error messages (#3079) · python/cpython@bd73e72 (original) (raw)
`@@ -23,7 +23,7 @@
`
23
23
`from traceback import format_exc
`
24
24
``
25
25
`from . import connection
`
26
``
`-
from .context import reduction, get_spawning_popen
`
``
26
`+
from .context import reduction, get_spawning_popen, ProcessError
`
27
27
`from . import pool
`
28
28
`from . import process
`
29
29
`from . import util
`
`@@ -133,7 +133,10 @@ class Server(object):
`
133
133
`'debug_info', 'number_of_objects', 'dummy', 'incref', 'decref']
`
134
134
``
135
135
`def init(self, registry, address, authkey, serializer):
`
136
``
`-
assert isinstance(authkey, bytes)
`
``
136
`+
if not isinstance(authkey, bytes):
`
``
137
`+
raise TypeError(
`
``
138
`+
"Authkey {0!r} is type {1!s}, not bytes".format(
`
``
139
`+
authkey, type(authkey)))
`
137
140
`self.registry = registry
`
138
141
`self.authkey = process.AuthenticationString(authkey)
`
139
142
`Listener, Client = listener_client[serializer]
`
`@@ -163,7 +166,7 @@ def serve_forever(self):
`
163
166
`except (KeyboardInterrupt, SystemExit):
`
164
167
`pass
`
165
168
`finally:
`
166
``
`-
if sys.stdout != sys.stdout:
`
``
169
`+
if sys.stdout != sys.stdout: # what about stderr?
`
167
170
`util.debug('resetting stdout, stderr')
`
168
171
`sys.stdout = sys.stdout
`
169
172
`sys.stderr = sys.stderr
`
`@@ -316,6 +319,7 @@ def debug_info(self, c):
`
316
319
`'''
`
317
320
` Return some info --- useful to spot problems with refcounting
`
318
321
` '''
`
``
322
`+
Perhaps include debug info about 'c'?
`
319
323
`with self.mutex:
`
320
324
`result = []
`
321
325
`keys = list(self.id_to_refcount.keys())
`
`@@ -356,15 +360,20 @@ def create(self, c, typeid, *args, **kwds):
`
356
360
`self.registry[typeid]
`
357
361
``
358
362
`if callable is None:
`
359
``
`-
assert len(args) == 1 and not kwds
`
``
363
`+
if kwds or (len(args) != 1):
`
``
364
`+
raise ValueError(
`
``
365
`+
"Without callable, must have one non-keyword argument")
`
360
366
`obj = args[0]
`
361
367
`else:
`
362
368
`obj = callable(*args, **kwds)
`
363
369
``
364
370
`if exposed is None:
`
365
371
`exposed = public_methods(obj)
`
366
372
`if method_to_typeid is not None:
`
367
``
`-
assert type(method_to_typeid) is dict
`
``
373
`+
if not isinstance(method_to_typeid, dict):
`
``
374
`+
raise TypeError(
`
``
375
`+
"Method_to_typeid {0!r}: type {1!s}, not dict".format(
`
``
376
`+
method_to_typeid, type(method_to_typeid)))
`
368
377
`exposed = list(exposed) + list(method_to_typeid)
`
369
378
``
370
379
`ident = '%x' % id(obj) # convert to string because xmlrpclib
`
`@@ -417,7 +426,11 @@ def decref(self, c, ident):
`
417
426
`return
`
418
427
``
419
428
`with self.mutex:
`
420
``
`-
assert self.id_to_refcount[ident] >= 1
`
``
429
`+
if self.id_to_refcount[ident] <= 0:
`
``
430
`+
raise AssertionError(
`
``
431
`+
"Id {0!s} ({1!r}) has refcount {2:n}, not 1+".format(
`
``
432
`+
ident, self.id_to_obj[ident],
`
``
433
`+
self.id_to_refcount[ident]))
`
421
434
`self.id_to_refcount[ident] -= 1
`
422
435
`if self.id_to_refcount[ident] == 0:
`
423
436
`del self.id_to_refcount[ident]
`
`@@ -480,7 +493,14 @@ def get_server(self):
`
480
493
`'''
`
481
494
` Return server object with serve_forever() method and address attribute
`
482
495
` '''
`
483
``
`-
assert self._state.value == State.INITIAL
`
``
496
`+
if self._state.value != State.INITIAL:
`
``
497
`+
if self._state.value == State.STARTED:
`
``
498
`+
raise ProcessError("Already started server")
`
``
499
`+
elif self._state.value == State.SHUTDOWN:
`
``
500
`+
raise ProcessError("Manager has shut down")
`
``
501
`+
else:
`
``
502
`+
raise ProcessError(
`
``
503
`+
"Unknown state {!r}".format(self._state.value))
`
484
504
`return Server(self._registry, self._address,
`
485
505
`self._authkey, self._serializer)
`
486
506
``
`@@ -497,7 +517,14 @@ def start(self, initializer=None, initargs=()):
`
497
517
`'''
`
498
518
` Spawn a server process for this manager object
`
499
519
` '''
`
500
``
`-
assert self._state.value == State.INITIAL
`
``
520
`+
if self._state.value != State.INITIAL:
`
``
521
`+
if self._state.value == State.STARTED:
`
``
522
`+
raise ProcessError("Already started server")
`
``
523
`+
elif self._state.value == State.SHUTDOWN:
`
``
524
`+
raise ProcessError("Manager has shut down")
`
``
525
`+
else:
`
``
526
`+
raise ProcessError(
`
``
527
`+
"Unknown state {!r}".format(self._state.value))
`
501
528
``
502
529
`if initializer is not None and not callable(initializer):
`
503
530
`raise TypeError('initializer must be a callable')
`
`@@ -593,7 +620,14 @@ def _number_of_objects(self):
`
593
620
`def enter(self):
`
594
621
`if self._state.value == State.INITIAL:
`
595
622
`self.start()
`
596
``
`-
assert self._state.value == State.STARTED
`
``
623
`+
if self._state.value != State.STARTED:
`
``
624
`+
if self._state.value == State.INITIAL:
`
``
625
`+
raise ProcessError("Unable to start server")
`
``
626
`+
elif self._state.value == State.SHUTDOWN:
`
``
627
`+
raise ProcessError("Manager has shut down")
`
``
628
`+
else:
`
``
629
`+
raise ProcessError(
`
``
630
`+
"Unknown state {!r}".format(self._state.value))
`
597
631
`return self
`
598
632
``
599
633
`def exit(self, exc_type, exc_val, exc_tb):
`
`@@ -653,7 +687,7 @@ def register(cls, typeid, callable=None, proxytype=None, exposed=None,
`
653
687
`getattr(proxytype, 'method_to_typeid', None)
`
654
688
``
655
689
`if method_to_typeid:
`
656
``
`-
for key, value in list(method_to_typeid.items()):
`
``
690
`+
for key, value in list(method_to_typeid.items()): # isinstance?
`
657
691
`assert type(key) is str, '%r is not a string' % key
`
658
692
`assert type(value) is str, '%r is not a string' % value
`
659
693
``