Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 70e7ea2

Browse files
committed
Merged revisions 61038,61042-61045,61047,61050,61053,61055-61056,61061-61062,61066,61068,61070,61083,61085,61092-61097,61103-61108 via svnmerge from
svn+ssh://[email protected]/python/trunk ........ r61105 | andrew.kuchling | 2008-02-28 15:03:03 +0100 (Thu, 28 Feb 2008) | 1 line #2169: make generated HTML more valid ........ r61106 | jeffrey.yasskin | 2008-02-28 19:03:15 +0100 (Thu, 28 Feb 2008) | 4 lines Prevent SocketServer.ForkingMixIn from waiting on child processes that it didn't create, in most cases. When there are max_children handlers running, it will still wait for any child process, not just handler processes. ........ r61107 | raymond.hettinger | 2008-02-28 20:41:24 +0100 (Thu, 28 Feb 2008) | 1 line Document impending updates to itertools. ........ r61108 | martin.v.loewis | 2008-02-28 20:44:22 +0100 (Thu, 28 Feb 2008) | 1 line Add 2.6aN uuids. ........
1 parent 9e7f1d2 commit 70e7ea2

5 files changed

Lines changed: 99 additions & 33 deletions

File tree

Doc/library/itertools.rst

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,30 @@ loops that truncate the stream.
7474
yield element
7575

7676

77+
.. function:: itertools.chain.from_iterable(iterable)
78+
79+
Alternate constructor for :func:`chain`. Gets chained inputs from a
80+
single iterable argument that is evaluated lazily. Equivalent to::
81+
82+
@classmethod
83+
def from_iterable(iterables):
84+
for it in iterables:
85+
for element in it:
86+
yield element
87+
88+
.. versionadded:: 2.6
89+
7790
.. function:: combinations(iterable, r)
7891

7992
Return successive *r* length combinations of elements in the *iterable*.
8093

81-
Combinations are emitted in a lexicographic sort order. So, if the
94+
Combinations are emitted in lexicographic sort order. So, if the
8295
input *iterable* is sorted, the combination tuples will be produced
8396
in sorted order.
8497

8598
Elements are treated as unique based on their position, not on their
8699
value. So if the input elements are unique, there will be no repeat
87-
values within a single combination.
100+
values in each combination.
88101

89102
Each result tuple is ordered to match the input order. So, every
90103
combination is a subsequence of the input *iterable*.
@@ -327,6 +340,26 @@ loops that truncate the stream.
327340
example :func:`islice` or :func:`takewhile`).
328341

329342

343+
.. function:: permutations(iterable[, r])
344+
345+
Return successive *r* length permutations of elements in the *iterable*.
346+
347+
If *r* is not specified or is ``None``, then *r* defaults to the length
348+
of the *iterable* and all possible full-length permutations
349+
are generated.
350+
351+
Permutations are emitted in lexicographic sort order. So, if the
352+
input *iterable* is sorted, the permutation tuples will be produced
353+
in sorted order.
354+
355+
Elements are treated as unique based on their position, not on their
356+
value. So if the input elements are unique, there will be no repeat
357+
values in each permutation.
358+
359+
Example: ``permutations(range(3),2) --> (1,2) (1,3) (2,1) (2,3) (3,1) (3,2)``
360+
361+
.. versionadded:: 2.6
362+
330363
.. function:: product(*iterables[, repeat])
331364

332365
Cartesian product of input iterables.
@@ -553,13 +586,13 @@ which incur interpreter overhead. ::
553586

554587
def ncycles(seq, n):
555588
"Returns the sequence elements n times"
556-
return chain(*repeat(seq, n))
589+
return chain.from_iterable(repeat(seq, n))
557590

558591
def dotproduct(vec1, vec2):
559592
return sum(imap(operator.mul, vec1, vec2))
560593

561594
def flatten(listOfLists):
562-
return list(chain(*listOfLists))
595+
return list(chain.from_iterable(listOfLists))
563596

564597
def repeatfunc(func, times=None, *args):
565598
"""Repeat calls to func with specified arguments.
@@ -568,8 +601,7 @@ which incur interpreter overhead. ::
568601
"""
569602
if times is None:
570603
return starmap(func, repeat(args))
571-
else:
572-
return starmap(func, repeat(args, times))
604+
return starmap(func, repeat(args, times))
573605

574606
def pairwise(iterable):
575607
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
@@ -583,7 +615,7 @@ which incur interpreter overhead. ::
583615

584616
def roundrobin(*iterables):
585617
"roundrobin('abc', 'd', 'ef') --> 'a', 'd', 'e', 'b', 'f', 'c'"
586-
# Recipe contributed by George Sakkis
618+
# Recipe credited to George Sakkis
587619
pending = len(iterables)
588620
nexts = cycle(iter(it).next for it in iterables)
589621
while pending:
@@ -595,8 +627,9 @@ which incur interpreter overhead. ::
595627
nexts = cycle(islice(nexts, pending))
596628

597629
def powerset(iterable):
598-
"powerset('ab') --> set([]), set(['b']), set(['a']), set(['a', 'b'])"
599-
skip = object()
600-
for t in product(*izip(repeat(skip), iterable)):
601-
yield set(e for e in t if e is not skip)
630+
"powerset('ab') --> set([]), set(['a']), set(['b']), set(['a', 'b'])"
631+
# Recipe credited to Eric Raymond
632+
pairs = [(2**i, x) for i, x in enumerate(iterable)]
633+
for n in xrange(2**len(pairs)):
634+
yield set(x for m, x in pairs if m&n)
602635

Lib/SimpleHTTPServer.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,9 @@ def list_directory(self, path):
109109
list.sort(key=lambda a: a.lower())
110110
f = StringIO()
111111
displaypath = cgi.escape(urllib.unquote(self.path))
112-
f.write("<title>Directory listing for %s</title>\n" % displaypath)
113-
f.write("<h2>Directory listing for %s</h2>\n" % displaypath)
112+
f.write('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">')
113+
f.write("<html>\n<title>Directory listing for %s</title>\n" % displaypath)
114+
f.write("<body>\n<h2>Directory listing for %s</h2>\n" % displaypath)
114115
f.write("<hr>\n<ul>\n")
115116
for name in list:
116117
fullname = os.path.join(path, name)
@@ -124,7 +125,7 @@ def list_directory(self, path):
124125
# Note: a link to a directory displays with @ and links with /
125126
f.write('<li><a href="%s">%s</a>\n'
126127
% (urllib.quote(linkname), cgi.escape(displayname)))
127-
f.write("</ul>\n<hr>\n")
128+
f.write("</ul>\n<hr>\n</body>\n</html>\n")
128129
length = f.tell()
129130
f.seek(0)
130131
self.send_response(200)

Lib/SocketServer.py

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -440,18 +440,30 @@ class ForkingMixIn:
440440

441441
def collect_children(self):
442442
"""Internal routine to wait for children that have exited."""
443-
while self.active_children:
444-
if len(self.active_children) < self.max_children:
445-
options = os.WNOHANG
446-
else:
447-
# If the maximum number of children are already
448-
# running, block while waiting for a child to exit
449-
options = 0
443+
if self.active_children is None: return
444+
while len(self.active_children) >= self.max_children:
445+
# XXX: This will wait for any child process, not just ones
446+
# spawned by this library. This could confuse other
447+
# libraries that expect to be able to wait for their own
448+
# children.
450449
try:
451-
pid, status = os.waitpid(0, options)
450+
pid, status = os.waitpid(0, options=0)
452451
except os.error:
453452
pid = None
454-
if not pid: break
453+
if pid not in self.active_children: continue
454+
self.active_children.remove(pid)
455+
456+
# XXX: This loop runs more system calls than it ought
457+
# to. There should be a way to put the active_children into a
458+
# process group and then use os.waitpid(-pgid) to wait for any
459+
# of that set, but I couldn't find a way to allocate pgids
460+
# that couldn't collide.
461+
for child in self.active_children:
462+
try:
463+
pid, status = os.waitpid(child, os.WNOHANG)
464+
except os.error:
465+
pid = None
466+
if not pid: continue
455467
try:
456468
self.active_children.remove(pid)
457469
except ValueError as e:

Lib/test/test_socketserver.py

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
Test suite for SocketServer.py.
33
"""
44

5+
import contextlib
56
import errno
67
import imp
78
import os
@@ -109,6 +110,18 @@ class svrcls(MyMixinServer, self.__svrcls):
109110
if verbose: print("thread: done")
110111

111112

113+
@contextlib.contextmanager
114+
def simple_subprocess(testcase):
115+
pid = os.fork()
116+
if pid == 0:
117+
# Don't throw an exception; it would be caught by the test harness.
118+
os._exit(72)
119+
yield None
120+
pid2, status = os.waitpid(pid, 0)
121+
testcase.assertEquals(pid2, pid)
122+
testcase.assertEquals(72 << 8, status)
123+
124+
112125
class SocketServerTest(unittest.TestCase):
113126
"""Test all socket servers."""
114127

@@ -211,10 +224,11 @@ def test_ThreadingTCPServer(self):
211224
self.stream_examine)
212225

213226
if HAVE_FORKING:
214-
def test_ThreadingTCPServer(self):
215-
self.run_server(SocketServer.ForkingTCPServer,
216-
SocketServer.StreamRequestHandler,
217-
self.stream_examine)
227+
def test_ForkingTCPServer(self):
228+
with simple_subprocess(self):
229+
self.run_server(SocketServer.ForkingTCPServer,
230+
SocketServer.StreamRequestHandler,
231+
self.stream_examine)
218232

219233
if HAVE_UNIX_SOCKETS:
220234
def test_UnixStreamServer(self):
@@ -229,9 +243,10 @@ def test_ThreadingUnixStreamServer(self):
229243

230244
if HAVE_FORKING:
231245
def test_ForkingUnixStreamServer(self):
232-
self.run_server(ForkingUnixStreamServer,
233-
SocketServer.StreamRequestHandler,
234-
self.stream_examine)
246+
with simple_subprocess(self):
247+
self.run_server(ForkingUnixStreamServer,
248+
SocketServer.StreamRequestHandler,
249+
self.stream_examine)
235250

236251
def test_UDPServer(self):
237252
self.run_server(SocketServer.UDPServer,
@@ -245,9 +260,10 @@ def test_ThreadingUDPServer(self):
245260

246261
if HAVE_FORKING:
247262
def test_ForkingUDPServer(self):
248-
self.run_server(SocketServer.ForkingUDPServer,
249-
SocketServer.DatagramRequestHandler,
250-
self.dgram_examine)
263+
with simple_subprocess(self):
264+
self.run_server(SocketServer.ForkingUDPServer,
265+
SocketServer.DatagramRequestHandler,
266+
self.dgram_examine)
251267

252268
# Alas, on Linux (at least) recvfrom() doesn't return a meaningful
253269
# client address so this cannot work:

Tools/msi/uuids.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@
3737
'2.5.1150':'{31800004-6386-4999-a519-518f2d78d8f0}', # 2.5.1
3838
'2.5.2150':'{6304a7da-1132-4e91-a343-a296269eab8a}', # 2.5.2c1
3939
'2.5.2150':'{6b976adf-8ae8-434e-b282-a06c7f624d2f}', # 2.5.2
40+
'2.6.101': '{0ba82e1b-52fd-4e03-8610-a6c76238e8a8}', # 2.6a1
41+
'2.6.102': '{3b27e16c-56db-4570-a2d3-e9a26180c60b}', # 2.6a2
42+
'2.6.103': '{cd06a9c5-bde5-4bd7-9874-48933997122a}', # 2.6a3
43+
'2.6.104': '{dc6ed634-474a-4a50-a547-8de4b7491e53}', # 2.6a4
4044
'3.0.101': '{8554263a-3242-4857-9359-aa87bc2c58c2}', # 3.0a1
4145
'3.0.102': '{692d6e2c-f0ac-40b8-a133-7191aeeb67f9}', # 3.0a2
4246
'3.0.103': '{49cb2995-751a-4753-be7a-d0b1bb585e06}', # 3.0a3

0 commit comments

Comments
 (0)