mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	issue3352: clean up the multiprocessing API to remove many get_/set_ methods and convert them to properties. Update the docs and the examples included.
This commit is contained in:
		
							parent
							
								
									7c972f971c
								
							
						
					
					
						commit
						5bc9f4c09c
					
				
					 15 changed files with 81 additions and 87 deletions
				
			
		|  | @ -152,7 +152,7 @@ def _help_stuff_finish(inqueue, task_handler, size): | |||
| 
 | ||||
| def LocalProcess(**kwds): | ||||
|     p = Process(**kwds) | ||||
|     p.set_name('localhost/' + p.get_name()) | ||||
|     p.set_name('localhost/' + p.name) | ||||
|     return p | ||||
| 
 | ||||
| class Cluster(managers.SyncManager): | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ | |||
| def calculate(func, args): | ||||
|     result = func(*args) | ||||
|     return '%s says that %s%s = %s' % ( | ||||
|         multiprocessing.current_process().get_name(), | ||||
|         multiprocessing.current_process().name, | ||||
|         func.__name__, args, result | ||||
|         ) | ||||
| 
 | ||||
|  |  | |||
|  | @ -224,7 +224,7 @@ def test_sharedvalues(): | |||
|     p.start() | ||||
|     p.join() | ||||
| 
 | ||||
|     assert p.get_exitcode() == 0 | ||||
|     assert p.exitcode == 0 | ||||
| 
 | ||||
| 
 | ||||
| #### | ||||
|  |  | |||
|  | @ -21,7 +21,7 @@ | |||
| 
 | ||||
| 
 | ||||
| def note(format, *args): | ||||
|     sys.stderr.write('[%s]\t%s\n' % (current_process().get_name(),format%args)) | ||||
|     sys.stderr.write('[%s]\t%s\n' % (current_process().name, format%args)) | ||||
| 
 | ||||
| 
 | ||||
| class RequestHandler(SimpleHTTPRequestHandler): | ||||
|  |  | |||
|  | @ -29,7 +29,7 @@ def worker(input, output): | |||
| def calculate(func, args): | ||||
|     result = func(*args) | ||||
|     return '%s says that %s%s = %s' % \ | ||||
|         (current_process().get_name(), func.__name__, args, result) | ||||
|         (current_process().name, func.__name__, args, result) | ||||
| 
 | ||||
| # | ||||
| # Functions referenced by tasks | ||||
|  |  | |||
|  | @ -292,11 +292,11 @@ The :mod:`multiprocessing` package mostly replicates the API of the | |||
|       A process cannot join itself because this would cause a deadlock.  It is | ||||
|       an error to attempt to join a process before it has been started. | ||||
| 
 | ||||
|    .. method:: get_name() | ||||
|    .. attribute:: Process.name | ||||
| 
 | ||||
|       Return the process's name. | ||||
| 
 | ||||
|    .. method:: set_name(name) | ||||
|    .. attribute:: Process.name = name | ||||
| 
 | ||||
|       Set the process's name. | ||||
| 
 | ||||
|  | @ -311,11 +311,11 @@ The :mod:`multiprocessing` package mostly replicates the API of the | |||
|       Roughly, a process object is alive from the moment the :meth:`start` | ||||
|       method returns until the child process terminates. | ||||
| 
 | ||||
|    .. method:: is_daemon() | ||||
|    .. attribute:: Process.daemon | ||||
| 
 | ||||
|       Return the process's daemon flag. | ||||
|       Return the process's daemon flag., this is a boolean. | ||||
| 
 | ||||
|    .. method:: set_daemon(daemonic) | ||||
|    .. attribute:: Process.daemon = daemonic | ||||
| 
 | ||||
|       Set the process's daemon flag to the Boolean value *daemonic*.  This must | ||||
|       be called before :meth:`start` is called. | ||||
|  | @ -331,18 +331,18 @@ The :mod:`multiprocessing` package mostly replicates the API of the | |||
| 
 | ||||
|    In addition process objects also support the following methods: | ||||
| 
 | ||||
|    .. method:: get_pid() | ||||
|    .. attribute:: Process.pid | ||||
| 
 | ||||
|       Return the process ID.  Before the process is spawned, this will be | ||||
|       ``None``. | ||||
| 
 | ||||
|    .. method:: get_exit_code() | ||||
|    .. attribute:: Process.exitcode | ||||
| 
 | ||||
|       Return the child's exit code.  This will be ``None`` if the process has | ||||
|       not yet terminated.  A negative value *-N* indicates that the child was | ||||
|       terminated by signal *N*. | ||||
| 
 | ||||
|    .. method:: get_auth_key() | ||||
|    .. attribute:: Process.authkey | ||||
| 
 | ||||
|       Return the process's authentication key (a byte string). | ||||
| 
 | ||||
|  | @ -351,11 +351,11 @@ The :mod:`multiprocessing` package mostly replicates the API of the | |||
| 
 | ||||
|       When a :class:`Process` object is created, it will inherit the | ||||
|       authentication key of its parent process, although this may be changed | ||||
|       using :meth:`set_auth_key` below. | ||||
|       using :attr:`Process.authkey` below. | ||||
| 
 | ||||
|       See :ref:`multiprocessing-auth-keys`. | ||||
| 
 | ||||
|    .. method:: set_auth_key(authkey) | ||||
|    .. attribute:: Process.authkey = authkey | ||||
| 
 | ||||
|       Set the process's authentication key which must be a byte string. | ||||
| 
 | ||||
|  |  | |||
|  | @ -47,7 +47,8 @@ def start(self): | |||
|         self._parent._children[self] = None | ||||
|         threading.Thread.start(self) | ||||
| 
 | ||||
|     def get_exitcode(self): | ||||
|     @property | ||||
|     def exitcode(self): | ||||
|         if self._start_called and not self.is_alive(): | ||||
|             return 0 | ||||
|         else: | ||||
|  |  | |||
|  | @ -360,7 +360,7 @@ def get_preparation_data(name): | |||
|             sys_argv=sys.argv, | ||||
|             log_to_stderr=_log_to_stderr, | ||||
|             orig_dir=process.ORIGINAL_DIR, | ||||
|             authkey=process.current_process().get_authkey(), | ||||
|             authkey=process.current_process().authkey, | ||||
|             ) | ||||
| 
 | ||||
|         if _logger is not None: | ||||
|  | @ -407,7 +407,7 @@ def prepare(data): | |||
|     old_main_modules.append(sys.modules['__main__']) | ||||
| 
 | ||||
|     if 'name' in data: | ||||
|         process.current_process().set_name(data['name']) | ||||
|         process.current_process().name = data['name'] | ||||
| 
 | ||||
|     if 'authkey' in data: | ||||
|         process.current_process()._authkey = data['authkey'] | ||||
|  |  | |||
|  | @ -444,7 +444,7 @@ class BaseManager(object): | |||
| 
 | ||||
|     def __init__(self, address=None, authkey=None, serializer='pickle'): | ||||
|         if authkey is None: | ||||
|             authkey = current_process().get_authkey() | ||||
|             authkey = current_process().authkey | ||||
|         self._address = address     # XXX not final address if eg ('', 0) | ||||
|         self._authkey = AuthenticationString(authkey) | ||||
|         self._state = State() | ||||
|  | @ -489,7 +489,7 @@ def start(self): | |||
|                   self._serializer, writer), | ||||
|             ) | ||||
|         ident = ':'.join(str(i) for i in self._process._identity) | ||||
|         self._process.set_name(type(self).__name__  + '-' + ident) | ||||
|         self._process.name = type(self).__name__  + '-' + ident | ||||
|         self._process.start() | ||||
| 
 | ||||
|         # get address of server | ||||
|  | @ -690,7 +690,7 @@ def __init__(self, token, serializer, manager=None, | |||
|         elif self._manager is not None: | ||||
|             self._authkey = self._manager._authkey | ||||
|         else: | ||||
|             self._authkey = current_process().get_authkey() | ||||
|             self._authkey = current_process().authkey | ||||
| 
 | ||||
|         if incref: | ||||
|             self._incref() | ||||
|  | @ -699,7 +699,7 @@ def __init__(self, token, serializer, manager=None, | |||
| 
 | ||||
|     def _connect(self): | ||||
|         util.debug('making connection to manager') | ||||
|         name = current_process().get_name() | ||||
|         name = current_process().name | ||||
|         if threading.current_thread().name != 'MainThread': | ||||
|             name += '|' + threading.current_thread().name | ||||
|         conn = self._Client(self._token.address, authkey=self._authkey) | ||||
|  | @ -880,7 +880,7 @@ def AutoProxy(token, serializer, manager=None, authkey=None, | |||
|     if authkey is None and manager is not None: | ||||
|         authkey = manager._authkey | ||||
|     if authkey is None: | ||||
|         authkey = current_process().get_authkey() | ||||
|         authkey = current_process().authkey | ||||
| 
 | ||||
|     ProxyType = MakeProxyType('AutoProxy[%s]' % token.typeid, exposed) | ||||
|     proxy = ProxyType(token, serializer, manager=manager, authkey=authkey, | ||||
|  |  | |||
|  | @ -99,7 +99,7 @@ def __init__(self, processes=None, initializer=None, initargs=()): | |||
|                 args=(self._inqueue, self._outqueue, initializer, initargs) | ||||
|                 ) | ||||
|             self._pool.append(w) | ||||
|             w.name = w.get_name().replace('Process', 'PoolWorker') | ||||
|             w.name = w.name.replace('Process', 'PoolWorker') | ||||
|             w.daemon = True | ||||
|             w.start() | ||||
| 
 | ||||
|  |  | |||
|  | @ -132,45 +132,43 @@ def is_alive(self): | |||
|         self._popen.poll() | ||||
|         return self._popen.returncode is None | ||||
| 
 | ||||
|     def get_name(self): | ||||
|         ''' | ||||
|         Return name of process | ||||
|         ''' | ||||
|     @property | ||||
|     def name(self): | ||||
|         return self._name | ||||
| 
 | ||||
|     def set_name(self, name): | ||||
|         ''' | ||||
|         Set name of process | ||||
|         ''' | ||||
|     @name.setter | ||||
|     def name(self, name): | ||||
|         assert isinstance(name, str), 'name must be a string' | ||||
|         self._name = name | ||||
| 
 | ||||
|     def is_daemon(self): | ||||
|     @property | ||||
|     def daemon(self): | ||||
|         ''' | ||||
|         Return whether process is a daemon | ||||
|         ''' | ||||
|         return self._daemonic | ||||
| 
 | ||||
|     def set_daemon(self, daemonic): | ||||
|     @daemon.setter | ||||
|     def daemon(self, daemonic): | ||||
|         ''' | ||||
|         Set whether process is a daemon | ||||
|         ''' | ||||
|         assert self._popen is None, 'process has already started' | ||||
|         self._daemonic = daemonic | ||||
| 
 | ||||
|     def get_authkey(self): | ||||
|         ''' | ||||
|         Return authorization key of process | ||||
|         ''' | ||||
|     @property | ||||
|     def authkey(self): | ||||
|         return self._authkey | ||||
| 
 | ||||
|     def set_authkey(self, authkey): | ||||
|     @authkey.setter | ||||
|     def authkey(self, authkey): | ||||
|         ''' | ||||
|         Set authorization key of process | ||||
|         ''' | ||||
|         self._authkey = AuthenticationString(authkey) | ||||
| 
 | ||||
|     def get_exitcode(self): | ||||
|     @property | ||||
|     def exitcode(self): | ||||
|         ''' | ||||
|         Return exit code of process or `None` if it has yet to stop | ||||
|         ''' | ||||
|  | @ -178,7 +176,8 @@ def get_exitcode(self): | |||
|             return self._popen | ||||
|         return self._popen.poll() | ||||
| 
 | ||||
|     def get_ident(self): | ||||
|     @property | ||||
|     def ident(self): | ||||
|         ''' | ||||
|         Return indentifier (PID) of process or `None` if it has yet to start | ||||
|         ''' | ||||
|  | @ -187,7 +186,7 @@ def get_ident(self): | |||
|         else: | ||||
|             return self._popen and self._popen.pid | ||||
| 
 | ||||
|     pid = property(get_ident) | ||||
|     pid = ident | ||||
| 
 | ||||
|     def __repr__(self): | ||||
|         if self is _current_process: | ||||
|  | @ -198,7 +197,7 @@ def __repr__(self): | |||
|             status = 'initial' | ||||
|         else: | ||||
|             if self._popen.poll() is not None: | ||||
|                 status = self.get_exitcode() | ||||
|                 status = self.exitcode | ||||
|             else: | ||||
|                 status = 'started' | ||||
| 
 | ||||
|  | @ -245,7 +244,7 @@ def _bootstrap(self): | |||
|         except: | ||||
|             exitcode = 1 | ||||
|             import traceback | ||||
|             sys.stderr.write('Process %s:\n' % self.get_name()) | ||||
|             sys.stderr.write('Process %s:\n' % self.name) | ||||
|             sys.stderr.flush() | ||||
|             traceback.print_exc() | ||||
| 
 | ||||
|  |  | |||
|  | @ -81,9 +81,9 @@ def _get_listener(): | |||
|         try: | ||||
|             if _listener is None: | ||||
|                 debug('starting listener and thread for sending handles') | ||||
|                 _listener = Listener(authkey=current_process().get_authkey()) | ||||
|                 _listener = Listener(authkey=current_process().authkey) | ||||
|                 t = threading.Thread(target=_serve) | ||||
|                 t.set_daemon(True) | ||||
|                 t.daemon = True | ||||
|                 t.start() | ||||
|         finally: | ||||
|             _lock.release() | ||||
|  | @ -126,7 +126,7 @@ def rebuild_handle(pickled_data): | |||
|     if inherited: | ||||
|         return handle | ||||
|     sub_debug('rebuilding handle %d', handle) | ||||
|     conn = Client(address, authkey=current_process().get_authkey()) | ||||
|     conn = Client(address, authkey=current_process().authkey) | ||||
|     conn.send((handle, os.getpid())) | ||||
|     new_handle = recv_handle(conn) | ||||
|     conn.close() | ||||
|  |  | |||
|  | @ -108,9 +108,9 @@ def __init__(self): | |||
|     def __repr__(self): | ||||
|         try: | ||||
|             if self._semlock._is_mine(): | ||||
|                 name = current_process().get_name() | ||||
|                 if threading.current_thread().get_name() != 'MainThread': | ||||
|                     name += '|' + threading.current_thread().get_name() | ||||
|                 name = current_process().name | ||||
|                 if threading.current_thread().name != 'MainThread': | ||||
|                     name += '|' + threading.current_thread().name | ||||
|             elif self._semlock._get_value() == 1: | ||||
|                 name = 'None' | ||||
|             elif self._semlock._count() > 0: | ||||
|  | @ -133,9 +133,9 @@ def __init__(self): | |||
|     def __repr__(self): | ||||
|         try: | ||||
|             if self._semlock._is_mine(): | ||||
|                 name = current_process().get_name() | ||||
|                 if threading.current_thread().get_name() != 'MainThread': | ||||
|                     name += '|' + threading.current_thread().get_name() | ||||
|                 name = current_process().name | ||||
|                 if threading.current_thread().name != 'MainThread': | ||||
|                     name += '|' + threading.current_thread().name | ||||
|                 count = self._semlock._count() | ||||
|             elif self._semlock._get_value() == 1: | ||||
|                 name, count = 'None', 0 | ||||
|  |  | |||
|  | @ -273,11 +273,11 @@ def _exit_function(): | |||
| 
 | ||||
|     for p in active_children(): | ||||
|         if p._daemonic: | ||||
|             info('calling terminate() for daemon %s', p.get_name()) | ||||
|             info('calling terminate() for daemon %s', p.name) | ||||
|             p._popen.terminate() | ||||
| 
 | ||||
|     for p in active_children(): | ||||
|         info('calling join() for process %s', p.get_name()) | ||||
|         info('calling join() for process %s', p.name) | ||||
|         p.join() | ||||
| 
 | ||||
|     debug('running the remaining "atexit" finalizers') | ||||
|  |  | |||
|  | @ -119,22 +119,22 @@ def test_current(self): | |||
|             return | ||||
| 
 | ||||
|         current = self.current_process() | ||||
|         authkey = current.get_authkey() | ||||
|         authkey = current.authkey | ||||
| 
 | ||||
|         self.assertTrue(current.is_alive()) | ||||
|         self.assertTrue(not current.is_daemon()) | ||||
|         self.assertTrue(not current.daemon) | ||||
|         self.assertTrue(isinstance(authkey, bytes)) | ||||
|         self.assertTrue(len(authkey) > 0) | ||||
|         self.assertEqual(current.get_ident(), os.getpid()) | ||||
|         self.assertEqual(current.get_exitcode(), None) | ||||
|         self.assertEqual(current.ident, os.getpid()) | ||||
|         self.assertEqual(current.exitcode, None) | ||||
| 
 | ||||
|     def _test(self, q, *args, **kwds): | ||||
|         current = self.current_process() | ||||
|         q.put(args) | ||||
|         q.put(kwds) | ||||
|         q.put(current.get_name()) | ||||
|         q.put(current.name) | ||||
|         if self.TYPE != 'threads': | ||||
|             q.put(bytes(current.get_authkey())) | ||||
|             q.put(bytes(current.authkey)) | ||||
|             q.put(current.pid) | ||||
| 
 | ||||
|     def test_process(self): | ||||
|  | @ -146,33 +146,33 @@ def test_process(self): | |||
|         p = self.Process( | ||||
|             target=self._test, args=args, kwargs=kwargs, name=name | ||||
|             ) | ||||
|         p.set_daemon(True) | ||||
|         p.daemon = True | ||||
|         current = self.current_process() | ||||
| 
 | ||||
|         if self.TYPE != 'threads': | ||||
|             self.assertEquals(p.get_authkey(), current.get_authkey()) | ||||
|             self.assertEquals(p.authkey, current.authkey) | ||||
|         self.assertEquals(p.is_alive(), False) | ||||
|         self.assertEquals(p.is_daemon(), True) | ||||
|         self.assertEquals(p.daemon, True) | ||||
|         self.assertTrue(p not in self.active_children()) | ||||
|         self.assertTrue(type(self.active_children()) is list) | ||||
|         self.assertEqual(p.get_exitcode(), None) | ||||
|         self.assertEqual(p.exitcode, None) | ||||
| 
 | ||||
|         p.start() | ||||
| 
 | ||||
|         self.assertEquals(p.get_exitcode(), None) | ||||
|         self.assertEquals(p.exitcode, None) | ||||
|         self.assertEquals(p.is_alive(), True) | ||||
|         self.assertTrue(p in self.active_children()) | ||||
| 
 | ||||
|         self.assertEquals(q.get(), args[1:]) | ||||
|         self.assertEquals(q.get(), kwargs) | ||||
|         self.assertEquals(q.get(), p.get_name()) | ||||
|         self.assertEquals(q.get(), p.name) | ||||
|         if self.TYPE != 'threads': | ||||
|             self.assertEquals(q.get(), current.get_authkey()) | ||||
|             self.assertEquals(q.get(), current.authkey) | ||||
|             self.assertEquals(q.get(), p.pid) | ||||
| 
 | ||||
|         p.join() | ||||
| 
 | ||||
|         self.assertEquals(p.get_exitcode(), 0) | ||||
|         self.assertEquals(p.exitcode, 0) | ||||
|         self.assertEquals(p.is_alive(), False) | ||||
|         self.assertTrue(p not in self.active_children()) | ||||
| 
 | ||||
|  | @ -184,12 +184,12 @@ def test_terminate(self): | |||
|             return | ||||
| 
 | ||||
|         p = self.Process(target=self._test_terminate) | ||||
|         p.set_daemon(True) | ||||
|         p.daemon = True | ||||
|         p.start() | ||||
| 
 | ||||
|         self.assertEqual(p.is_alive(), True) | ||||
|         self.assertTrue(p in self.active_children()) | ||||
|         self.assertEqual(p.get_exitcode(), None) | ||||
|         self.assertEqual(p.exitcode, None) | ||||
| 
 | ||||
|         p.terminate() | ||||
| 
 | ||||
|  | @ -202,8 +202,8 @@ def test_terminate(self): | |||
| 
 | ||||
|         p.join() | ||||
| 
 | ||||
|         # XXX sometimes get p.get_exitcode() == 0 on Windows ... | ||||
|         #self.assertEqual(p.get_exitcode(), -signal.SIGTERM) | ||||
|         # XXX sometimes get p.exitcode == 0 on Windows ... | ||||
|         #self.assertEqual(p.exitcode, -signal.SIGTERM) | ||||
| 
 | ||||
|     def test_cpu_count(self): | ||||
|         try: | ||||
|  | @ -330,7 +330,7 @@ def test_put(self): | |||
|             target=self._test_put, | ||||
|             args=(queue, child_can_start, parent_can_continue) | ||||
|             ) | ||||
|         proc.set_daemon(True) | ||||
|         proc.daemon = True | ||||
|         proc.start() | ||||
| 
 | ||||
|         self.assertEqual(queue_empty(queue), True) | ||||
|  | @ -396,7 +396,7 @@ def test_get(self): | |||
|             target=self._test_get, | ||||
|             args=(queue, child_can_start, parent_can_continue) | ||||
|             ) | ||||
|         proc.set_daemon(True) | ||||
|         proc.daemon = True | ||||
|         proc.start() | ||||
| 
 | ||||
|         self.assertEqual(queue_empty(queue), True) | ||||
|  | @ -619,17 +619,11 @@ def test_notify(self): | |||
|         woken = self.Semaphore(0) | ||||
| 
 | ||||
|         p = self.Process(target=self.f, args=(cond, sleeping, woken)) | ||||
|         try: | ||||
|             p.set_daemon(True) | ||||
|         except AttributeError: | ||||
|             p.daemon = True | ||||
|         p.daemon = True | ||||
|         p.start() | ||||
| 
 | ||||
|         p = threading.Thread(target=self.f, args=(cond, sleeping, woken)) | ||||
|         try: | ||||
|             p.set_daemon(True) | ||||
|         except AttributeError: | ||||
|             p.daemon = True | ||||
|         p.daemon = True | ||||
|         p.start() | ||||
| 
 | ||||
|         # wait for both children to start sleeping | ||||
|  | @ -671,7 +665,7 @@ def test_notify_all(self): | |||
|         for i in range(3): | ||||
|             p = self.Process(target=self.f, | ||||
|                              args=(cond, sleeping, woken, TIMEOUT1)) | ||||
|             p.set_daemon(True) | ||||
|             p.daemon = True | ||||
|             p.start() | ||||
| 
 | ||||
|             t = threading.Thread(target=self.f, | ||||
|  | @ -694,7 +688,7 @@ def test_notify_all(self): | |||
|         # start some more threads/processes | ||||
|         for i in range(3): | ||||
|             p = self.Process(target=self.f, args=(cond, sleeping, woken)) | ||||
|             p.set_daemon(True) | ||||
|             p.daemon = True | ||||
|             p.start() | ||||
| 
 | ||||
|             t = threading.Thread(target=self.f, args=(cond, sleeping, woken)) | ||||
|  | @ -1191,7 +1185,7 @@ def test_connection(self): | |||
|         conn, child_conn = self.Pipe() | ||||
| 
 | ||||
|         p = self.Process(target=self._echo, args=(child_conn,)) | ||||
|         p.set_daemon(True) | ||||
|         p.daemon = True | ||||
|         p.start() | ||||
| 
 | ||||
|         seq = [1, 2.25, None] | ||||
|  | @ -1340,7 +1334,7 @@ def test_listener_client(self): | |||
|         for family in self.connection.families: | ||||
|             l = self.connection.Listener(family=family) | ||||
|             p = self.Process(target=self._test, args=(l.address,)) | ||||
|             p.set_daemon(True) | ||||
|             p.daemon = True | ||||
|             p.start() | ||||
|             conn = l.accept() | ||||
|             self.assertEqual(conn.recv(), 'hello') | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jesse Noller
						Jesse Noller