From 023611f34ead5bdfbeec73b1598df0023090106a Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Sun, 23 Oct 2011 22:40:37 +0200 Subject: Issue 13141: Demonstrate recommended style for socketserver examples. --- Doc/library/socketserver.rst | 64 +++++++++++++++++++++++--------------------- Misc/NEWS | 6 +++++ 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/Doc/library/socketserver.rst b/Doc/library/socketserver.rst index 1d151a7..177c0b1 100644 --- a/Doc/library/socketserver.rst +++ b/Doc/library/socketserver.rst @@ -348,7 +348,7 @@ This is the server side:: def handle(self): # self.request is the TCP socket connected to the client self.data = self.request.recv(1024).strip() - print("%s wrote:" % self.client_address[0]) + print("{} wrote:".format(self.client_address[0])) print(self.data) # just send back the same data, but upper-cased self.request.send(self.data.upper()) @@ -372,7 +372,7 @@ objects that simplify communication by providing the standard file interface):: # self.rfile is a file-like object created by the handler; # we can now use e.g. readline() instead of raw recv() calls self.data = self.rfile.readline().strip() - print("%s wrote:" % self.client_address[0]) + print("{} wrote:".format(self.client_address[0])) print(self.data) # Likewise, self.wfile is a file-like object used to write back # to the client @@ -395,16 +395,18 @@ This is the client side:: # Create a socket (SOCK_STREAM means a TCP socket) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - # Connect to server and send data - sock.connect((HOST, PORT)) - sock.send(bytes(data + "\n","utf8")) + try: + # Connect to server and send data + sock.connect((HOST, PORT)) + sock.send(bytes(data + "\n", "utf-8")) - # Receive data from the server and shut down - received = sock.recv(1024) - sock.close() + # Receive data from the server and shut down + received = str(sock.recv(1024), "utf-8") + finally: + sock.close() - print("Sent: %s" % data) - print("Received: %s" % received) + print("Sent: {}".format(data)) + print("Received: {}".format(received)) The output of the example should look something like this: @@ -421,10 +423,10 @@ Client:: $ python TCPClient.py hello world with TCP Sent: hello world with TCP - Received: b'HELLO WORLD WITH TCP' + Received: HELLO WORLD WITH TCP $ python TCPClient.py python is nice Sent: python is nice - Received: b'PYTHON IS NICE' + Received: PYTHON IS NICE :class:`socketserver.UDPServer` Example @@ -445,7 +447,7 @@ This is the server side:: def handle(self): data = self.request[0].strip() socket = self.request[1] - print("%s wrote:" % self.client_address[0]) + print("{} wrote:".format(self.client_address[0])) print(data) socket.sendto(data.upper(), self.client_address) @@ -467,11 +469,11 @@ This is the client side:: # As you can see, there is no connect() call; UDP has no connections. # Instead, data is directly sent to the recipient via sendto(). - sock.sendto(bytes(data + "\n","utf8"), (HOST, PORT)) - received = sock.recv(1024) + sock.sendto(bytes(data + "\n", "utf-8"), (HOST, PORT)) + received = str(sock.recv(1024), "utf-8") - print("Sent: %s" % data) - print("Received: %s" % received) + print("Sent: {}".format(data)) + print("Received: {}".format(received)) The output of the example should look exactly like for the TCP server example. @@ -491,9 +493,9 @@ An example for the :class:`ThreadingMixIn` class:: class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler): def handle(self): - data = self.request.recv(1024) + data = str(self.request.recv(1024), 'ascii') cur_thread = threading.current_thread() - response = bytes("%s: %s" % (cur_thread.getName(), data),'ascii') + response = bytes("{}: {}".format(cur_thread.name, data), 'ascii') self.request.send(response) class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): @@ -502,10 +504,12 @@ An example for the :class:`ThreadingMixIn` class:: def client(ip, port, message): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((ip, port)) - sock.send(message) - response = sock.recv(1024) - print("Received: %s" % response) - sock.close() + try: + sock.send(bytes(message, 'ascii')) + response = str(sock.recv(1024), 'ascii') + print("Received: {}".format(response)) + finally: + sock.close() if __name__ == "__main__": # Port 0 means to select an arbitrary unused port @@ -518,13 +522,13 @@ An example for the :class:`ThreadingMixIn` class:: # more thread for each request server_thread = threading.Thread(target=server.serve_forever) # Exit the server thread when the main thread terminates - server_thread.setDaemon(True) + server_thread.daemon = True server_thread.start() print("Server loop running in thread:", server_thread.name) - client(ip, port, b"Hello World 1") - client(ip, port, b"Hello World 2") - client(ip, port, b"Hello World 3") + client(ip, port, "Hello World 1") + client(ip, port, "Hello World 2") + client(ip, port, "Hello World 3") server.shutdown() @@ -533,9 +537,9 @@ The output of the example should look something like this:: $ python ThreadedTCPServer.py Server loop running in thread: Thread-1 - Received: b"Thread-2: b'Hello World 1'" - Received: b"Thread-3: b'Hello World 2'" - Received: b"Thread-4: b'Hello World 3'" + Received: Thread-2: Hello World 1 + Received: Thread-3: Hello World 2 + Received: Thread-4: Hello World 3 The :class:`ForkingMixIn` class is used in the same way, except that the server diff --git a/Misc/NEWS b/Misc/NEWS index c078623..100fcec 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -190,6 +190,12 @@ Extension Modules - Issue #12950: Fix passing file descriptors in multiprocessing, under OpenIndiana/Illumos. +Documentation +------------- + +- Issue #13141: Demonstrate recommended style for socketserver examples. + + What's New in Python 3.2.2? =========================== -- cgit v0.12 From c45fb25fba9ef8a1d322099db86be98775d37bec Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Mon, 24 Oct 2011 13:14:55 +0200 Subject: Issue #13255: wrong docstrings in array module. --- Misc/NEWS | 2 ++ Modules/arraymodule.c | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index 100fcec..3909420 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -58,6 +58,8 @@ Core and Builtins Library ------- +- Issue #13255: wrong docstrings in array module. + - Issue #9168: now smtpd is able to bind privileged port. - Issue #12529: fix cgi.parse_header issue on strings with double-quotes and diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index fe6106c..31c4f39 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -1484,7 +1484,7 @@ PyDoc_STRVAR(fromunicode_doc, \n\ Extends this array with data from the unicode string ustr.\n\ The array must be a unicode type array; otherwise a ValueError\n\ -is raised. Use array.frombytes(ustr.decode(...)) to\n\ +is raised. Use array.frombytes(ustr.encode(...)) to\n\ append Unicode data to an array of some other type."); @@ -1506,7 +1506,7 @@ PyDoc_STRVAR(tounicode_doc, \n\ Convert the array to a unicode string. The array must be\n\ a unicode type array; otherwise a ValueError is raised. Use\n\ -array.tostring().decode() to obtain a unicode string from\n\ +array.tobytes().decode() to obtain a unicode string from\n\ an array of some other type."); @@ -2557,7 +2557,7 @@ count() -- return number of occurrences of an object\n\ extend() -- extend array by appending multiple elements from an iterable\n\ fromfile() -- read items from a file object\n\ fromlist() -- append items from the list\n\ -fromstring() -- append items from the string\n\ +frombytes() -- append items from the string\n\ index() -- return index of first occurrence of an object\n\ insert() -- insert a new item into the array at a provided position\n\ pop() -- remove and return item (default last)\n\ @@ -2565,7 +2565,7 @@ remove() -- remove first occurrence of an object\n\ reverse() -- reverse the order of the items in the array\n\ tofile() -- write all items to a file object\n\ tolist() -- return the array converted to an ordinary list\n\ -tostring() -- return the array converted to a string\n\ +tobytes() -- return the array converted to a string\n\ \n\ Attributes:\n\ \n\ -- cgit v0.12 From d6ca6c2b32118fec10d28b1a23d97f8e6b536d04 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 24 Oct 2011 08:51:15 -0400 Subject: note callable is back in 3.2 --- Doc/library/2to3.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Doc/library/2to3.rst b/Doc/library/2to3.rst index b3efeab..fe1c2be 100644 --- a/Doc/library/2to3.rst +++ b/Doc/library/2to3.rst @@ -123,7 +123,9 @@ and off individually. They are described here in more detail. .. 2to3fixer:: callable Converts ``callable(x)`` to ``isinstance(x, collections.Callable)``, adding - an import to :mod:`collections` if needed. + an import to :mod:`collections` if needed. Note ``callable(x)`` has returned + in Python 3.2, so if you do not intend to support Python 3.1, you can disable + this fixer. .. 2to3fixer:: dict -- cgit v0.12 From f8859e1808eff603b727d1adbeb38f745c9fedb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Fran=C3=A7ois=20Natali?= Date: Mon, 24 Oct 2011 18:45:29 +0200 Subject: Issue #10332: multiprocessing: fix a race condition when a Pool is closed before all tasks have completed. --- Lib/multiprocessing/pool.py | 6 +++++- Lib/test/test_multiprocessing.py | 14 ++++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/Lib/multiprocessing/pool.py b/Lib/multiprocessing/pool.py index e450319..04e7c44 100644 --- a/Lib/multiprocessing/pool.py +++ b/Lib/multiprocessing/pool.py @@ -321,7 +321,11 @@ class Pool(object): @staticmethod def _handle_workers(pool): - while pool._worker_handler._state == RUN and pool._state == RUN: + thread = threading.current_thread() + + # Keep maintaining workers until the cache gets drained, unless the pool + # is terminated. + while thread._state == RUN or (pool._cache and thread._state != TERMINATE): pool._maintain_pool() time.sleep(0.1) # send sentinel to stop workers diff --git a/Lib/test/test_multiprocessing.py b/Lib/test/test_multiprocessing.py index 6940d0e..45bf454 100644 --- a/Lib/test/test_multiprocessing.py +++ b/Lib/test/test_multiprocessing.py @@ -1217,6 +1217,20 @@ class _TestPoolWorkerLifetime(BaseTestCase): p.close() p.join() + def test_pool_worker_lifetime_early_close(self): + # Issue #10332: closing a pool whose workers have limited lifetimes + # before all the tasks completed would make join() hang. + p = multiprocessing.Pool(3, maxtasksperchild=1) + results = [] + for i in range(6): + results.append(p.apply_async(sqr, (i, 0.3))) + p.close() + p.join() + # check the results + for (j, res) in enumerate(results): + self.assertEqual(res.get(), sqr(j)) + + # # Test that manager has expected number of shared objects left # diff --git a/Misc/NEWS b/Misc/NEWS index 3909420..f7a741a 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -58,6 +58,9 @@ Core and Builtins Library ------- +- Issue #10332: multiprocessing: fix a race condition when a Pool is closed + before all tasks have completed. + - Issue #13255: wrong docstrings in array module. - Issue #9168: now smtpd is able to bind privileged port. -- cgit v0.12