[Python-checkins] r73085 - in python/branches/tk_and_idle_maintenance: Doc/c-api/buffer.rst Doc/library/ipaddr.rst Doc/library/select.rst Doc/library/unittest.rst Doc/whatsnew/2.7.rst Lib/lib-tk/Tkinter.py Lib/multiprocessing/synchronize.py Lib/test/regrtest.py Lib/test/test_cprofile.py Lib/test/test_epoll.py Lib/test/test_profile.py Lib/test/test_support.py Misc/ACKS Misc/NEWS Objects/object.c Python/ceval.c

guilherme.polo python-checkins at python.org
Sun May 31 23:36:16 CEST 2009


Author: guilherme.polo
Date: Sun May 31 23:36:15 2009
New Revision: 73085
Log:
Merged revisions 73060,73064-73065,73068-73069,73071-73074,73076-73077,73083 via svnmerge from 
svn+ssh://pythondev/python/trunk
........
 r73060 | gregory.p.smith | 2009年05月30日 16:58:11 -0300 (2009年5月30日) | 2 lines
 
 Add more examples to the ipaddr documentation.
........
 r73064 | antoine.pitrou | 2009年05月30日 18:27:00 -0300 (2009年5月30日) | 4 lines
 
 Issue #5330: C functions called with keyword arguments were not reported by
 the various profiling modules (profile, cProfile). Patch by Hagen Fürstenau.
........
 r73065 | antoine.pitrou | 2009年05月30日 18:39:25 -0300 (2009年5月30日) | 3 lines
 
 The test for #5330 wasn't correct.
........
 r73068 | antoine.pitrou | 2009年05月30日 18:45:40 -0300 (2009年5月30日) | 3 lines
 
 Update ACKS
........
 r73069 | benjamin.peterson | 2009年05月30日 21:42:42 -0300 (2009年5月30日) | 1 line
 
 fix signature
........
 r73071 | georg.brandl | 2009年05月31日 11:15:25 -0300 (2009年5月31日) | 1 line
 
 Fix markup.
........
 r73072 | antoine.pitrou | 2009年05月31日 11:20:14 -0300 (2009年5月31日) | 4 lines
 
 Issue #6152: New option '-j'/'--multiprocess' for regrtest allows running
 regression tests in parallel, shortening the total runtime.
........
 r73073 | benjamin.peterson | 2009年05月31日 11:43:00 -0300 (2009年5月31日) | 1 line
 
 remove function import
........
 r73074 | benjamin.peterson | 2009年05月31日 12:00:27 -0300 (2009年5月31日) | 1 line
 
 __enter__ and __exit__ must be on the class
........
 r73076 | antoine.pitrou | 2009年05月31日 15:05:51 -0300 (2009年5月31日) | 4 lines
 
 Uninitialized file type would lead to __exit__ lookup failure when site.py
 tries to read *.pth files on interpreter startup.
........
 r73077 | r.david.murray | 2009年05月31日 16:15:57 -0300 (2009年5月31日) | 4 lines
 
 Issue 3848: document the fact that epoll register raises an IOError if
 an fd is registered twice, and add some additional epoll tests. Patch
 by Christian Heimes.
........
 r73083 | guilherme.polo | 2009年05月31日 18:31:21 -0300 (2009年5月31日) | 1 line
 
 Improved PanedWindow.add's docstring. 'subcomand' is a Tcl term, and the possible options and values are the same accepted by paneconfigure (not configure).
........
Modified:
 python/branches/tk_and_idle_maintenance/ (props changed)
 python/branches/tk_and_idle_maintenance/Doc/c-api/buffer.rst
 python/branches/tk_and_idle_maintenance/Doc/library/ipaddr.rst
 python/branches/tk_and_idle_maintenance/Doc/library/select.rst
 python/branches/tk_and_idle_maintenance/Doc/library/unittest.rst
 python/branches/tk_and_idle_maintenance/Doc/whatsnew/2.7.rst
 python/branches/tk_and_idle_maintenance/Lib/lib-tk/Tkinter.py
 python/branches/tk_and_idle_maintenance/Lib/multiprocessing/synchronize.py
 python/branches/tk_and_idle_maintenance/Lib/test/regrtest.py
 python/branches/tk_and_idle_maintenance/Lib/test/test_cprofile.py
 python/branches/tk_and_idle_maintenance/Lib/test/test_epoll.py
 python/branches/tk_and_idle_maintenance/Lib/test/test_profile.py
 python/branches/tk_and_idle_maintenance/Lib/test/test_support.py
 python/branches/tk_and_idle_maintenance/Misc/ACKS
 python/branches/tk_and_idle_maintenance/Misc/NEWS
 python/branches/tk_and_idle_maintenance/Objects/object.c
 python/branches/tk_and_idle_maintenance/Python/ceval.c
Modified: python/branches/tk_and_idle_maintenance/Doc/c-api/buffer.rst
==============================================================================
--- python/branches/tk_and_idle_maintenance/Doc/c-api/buffer.rst	(original)
+++ python/branches/tk_and_idle_maintenance/Doc/c-api/buffer.rst	Sun May 31 23:36:15 2009
@@ -141,7 +141,7 @@
 Return 1 if *obj* supports the buffer interface otherwise 0.
 
 
-.. cfunction:: int PyObject_GetBuffer(PyObject *obj, PyObject *view, int flags)
+.. cfunction:: int PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)
 
 Export *obj* into a :ctype:`Py_buffer`, *view*. These arguments must
 never be *NULL*. The *flags* argument is a bit field indicating what
Modified: python/branches/tk_and_idle_maintenance/Doc/library/ipaddr.rst
==============================================================================
--- python/branches/tk_and_idle_maintenance/Doc/library/ipaddr.rst	(original)
+++ python/branches/tk_and_idle_maintenance/Doc/library/ipaddr.rst	Sun May 31 23:36:15 2009
@@ -16,6 +16,90 @@
 both IPv4 and IPv6.
 
 
+.. _ipaddr_examples:
+
+Examples
+--------
+
+Netmask.
+
+ >>> ipaddr.IP('1.1.1.1/255.255.255.0')
+ IPv4('1.1.1.1/24')
+ >>> ipaddr.IP('1080::200C:417B/96')
+ IPv6('1080::200c:417b/96')
+
+Hostmask.
+
+ >>> ipaddr.IPv4('1.1.1.1/0.0.0.255')
+ IPv4('1.1.1.1/24')
+
+Prefix length.
+
+ >>> addr = ipaddr.IPv4('1.1.1.1/24')
+ >>> addr.prefixlen
+ 24
+
+Individual addresses.
+
+ >>> ipaddr.IP('1.1.1.1')
+ IPv4('1.1.1.1/32')
+
+Many standard Python operations are also supported.
+
+Comparison.
+
+ >>> ipaddr.IPv4('1.1.1.1') == ipaddr.IPv4('1.1.1.2')
+ False
+ >>> ipaddr.IPv4('1.1.1.1') < ipaddr.IPv4('1.1.1.2')
+ True
+
+Inclusion.
+
+ >>> ipaddr.IPv4('1.1.1.1') in ipaddr.IPv4("1.0.0.0/8")
+ True
+
+Sorting.
+
+ >>> a = ipaddr.IPv4('1.1.1.10')
+ >>> b = ipaddr.IPv4('1.10.1.10')
+ >>> c = ipaddr.IPv4('1.1.10.10')
+ >>> d = ipaddr.IPv4('1.1.1.1')
+ >>> sorted([a, b, c, d])
+ [IPv4('1.1.1.1/32'), IPv4('1.1.1.10/32'), IPv4('1.1.10.10/32'), IPv4('1.10.1.10/32')]
+
+Conversion to string and integer forms.
+
+ >>> spam = ipaddr.IPv4('192.168.1.254'))
+ >>> str(spam)
+ '192.168.1.254/32'
+ >>> spam.ip_ext
+ '192.168.1.254'
+ >>> int(spam)
+ 3232236030
+ >>> eggs = ipaddr.IPv6('ffff::1/120')
+ >>> int(eggs)
+ 340277174624079928635746076935438991361
+
+Additionally, there are quite a few network-specific features available to
+ipaddr.
+
+ >>> ipaddr.IPv4('10.0.0.0/8').supernet()
+ IPv4('10.0.0.0/7')
+ >>> ipaddr.IPv4('10.0.0.0/8').subnet()
+ [IPv4('10.0.0.0/9'), IPv4('10.128.0.0/9')]
+ # This returns networks with a prefix length of /10
+ >>> ipaddr.IPv4('10.0.0.0/8').subnet(prefixlen_diff=2)
+ [IPv4('10.0.0.0/10'), IPv4('10.64.0.0/10'), IPv4('10.128.0.0/10'), IPv4('10.192.0.0/10')]
+ # Remove an address from a superblock.
+ >>> ipaddr.IP('10.0.0.0/24').address_exclude(ipaddr.IP('10.0.0.0/28'))
+ [IPv4('10.0.0.16/28'), IPv4('10.0.0.32/27'), IPv4('10.0.0.64/26'), IPv4('10.0.0.128/25')]
+
+
+.. _ipaddr_funcs_and_classes:
+
+Functions And Classes
+---------------------
+
 .. function:: IP(ipaddr)
 
 Take an IP string or int and return an object of the correct type. Returns
@@ -158,8 +242,7 @@
 >>> addr1 = IP('::1/32')
 >>> addr2 = IP('::1/128')
 >>> addr1.address_exclude(addr2)
- [IP('::0/128'), IP('::2/127'), IP('::4/126'), IP('::8/125'),
- ... IP('0:0:8000::/33')]
+ [IP('::0/128'), IP('::2/127'), IP('::4/126'), IP('::8/125'), IP('0:0:8000::/33')]
 
 Raises :exc:`ValueError` if *other* is not completely contained by *self*.
 
@@ -286,6 +369,11 @@
 2.5.2.
 
 
+.. _ipaddr_exceptions:
+
+Exceptions
+----------
+
 The following exceptions are defined by this module:
 
 .. exception:: Error
Modified: python/branches/tk_and_idle_maintenance/Doc/library/select.rst
==============================================================================
--- python/branches/tk_and_idle_maintenance/Doc/library/select.rst	(original)
+++ python/branches/tk_and_idle_maintenance/Doc/library/select.rst	Sun May 31 23:36:15 2009
@@ -160,6 +160,11 @@
 
 Register a fd descriptor with the epoll object.
 
+ .. note::
+
+ Registering a file descriptor that's already registered raises an
+ IOError -- contrary to :ref:`poll-objects`'s register.
+
 
 .. method:: epoll.modify(fd, eventmask)
 
Modified: python/branches/tk_and_idle_maintenance/Doc/library/unittest.rst
==============================================================================
--- python/branches/tk_and_idle_maintenance/Doc/library/unittest.rst	(original)
+++ python/branches/tk_and_idle_maintenance/Doc/library/unittest.rst	Sun May 31 23:36:15 2009
@@ -79,18 +79,15 @@
 Module :mod:`doctest`
 Another test-support module with a very different flavor.
 
- `Simple Smalltalk Testing: With Patterns
- <http://www.XProgramming.com/testfram.htm>`_
+ `Simple Smalltalk Testing: With Patterns <http://www.XProgramming.com/testfram.htm>`_
 Kent Beck's original paper on testing frameworks using the pattern shared
 by :mod:`unittest`.
 
- `Nose <http://code.google.com/p/python-nose/>`_ and `py.test
- <http://pytest.org>`_
+ `Nose <http://code.google.com/p/python-nose/>`_ and `py.test <http://pytest.org>`_
 Third-party unittest frameworks with a lighter-weight syntax for writing
 tests. For example, ``assert func(10) == 42``.
 
- `python-mock <http://python-mock.sourceforge.net/>`_ and
- `minimock <http://blog.ianbicking.org/minimock.html>`_
+ `python-mock <http://python-mock.sourceforge.net/>`_ and `minimock <http://blog.ianbicking.org/minimock.html>`_
 Tools for creating mock test objects (objects simulating external
 resources).
 
Modified: python/branches/tk_and_idle_maintenance/Doc/whatsnew/2.7.rst
==============================================================================
--- python/branches/tk_and_idle_maintenance/Doc/whatsnew/2.7.rst	(original)
+++ python/branches/tk_and_idle_maintenance/Doc/whatsnew/2.7.rst	Sun May 31 23:36:15 2009
@@ -654,6 +654,12 @@
 The :option:`-r` option also now reports the seed that was used
 (Added by Collin Winter.)
 
+* The :file:`regrtest.py` script now takes a :option:`-j` switch
+ that takes an integer specifying how many tests run in parallel. This
+ allows to shorten the total runtime on multi-core machines.
+ This option is compatible with several other options, including the
+ :option:`-R` switch which is known to produce long runtimes.
+ (Added by Antoine Pitrou, :issue:`6152`.)
 
 .. ======================================================================
 
Modified: python/branches/tk_and_idle_maintenance/Lib/lib-tk/Tkinter.py
==============================================================================
--- python/branches/tk_and_idle_maintenance/Lib/lib-tk/Tkinter.py	(original)
+++ python/branches/tk_and_idle_maintenance/Lib/lib-tk/Tkinter.py	Sun May 31 23:36:15 2009
@@ -3550,8 +3550,8 @@
 
 The child argument is the name of the child widget
 followed by pairs of arguments that specify how to
- manage the windows. Options may have any of the values
- accepted by the configure subcommand.
+ manage the windows. The possible options and values
+ are the ones accepted by the paneconfigure method.
 """
 self.tk.call((self._w, 'add', child) + self._options(kw))
 
Modified: python/branches/tk_and_idle_maintenance/Lib/multiprocessing/synchronize.py
==============================================================================
--- python/branches/tk_and_idle_maintenance/Lib/multiprocessing/synchronize.py	(original)
+++ python/branches/tk_and_idle_maintenance/Lib/multiprocessing/synchronize.py	Sun May 31 23:36:15 2009
@@ -58,8 +58,12 @@
 def _make_methods(self):
 self.acquire = self._semlock.acquire
 self.release = self._semlock.release
- self.__enter__ = self._semlock.__enter__
- self.__exit__ = self._semlock.__exit__
+
+ def __enter__(self):
+ return self._semlock.__enter__()
+
+ def __exit__(self, *args):
+ return self._semlock.__exit__(*args)
 
 def __getstate__(self):
 assert_spawning(self)
@@ -181,11 +185,15 @@
 self._woken_count, self._wait_semaphore) = state
 self._make_methods()
 
+ def __enter__(self):
+ return self._lock.__enter__()
+
+ def __exit__(self, *args):
+ return self._lock.__exit__(*args)
+
 def _make_methods(self):
 self.acquire = self._lock.acquire
 self.release = self._lock.release
- self.__enter__ = self._lock.__enter__
- self.__exit__ = self._lock.__exit__
 
 def __repr__(self):
 try:
Modified: python/branches/tk_and_idle_maintenance/Lib/test/regrtest.py
==============================================================================
--- python/branches/tk_and_idle_maintenance/Lib/test/regrtest.py	(original)
+++ python/branches/tk_and_idle_maintenance/Lib/test/regrtest.py	Sun May 31 23:36:15 2009
@@ -26,6 +26,7 @@
 -L: runleaks -- run the leaks(1) command just before exit
 -R: huntrleaks -- search for reference leaks (needs debug build, v. slow)
 -M: memlimit -- run very large memory-consuming tests
+-j: multiprocess -- run several processes at once
 
 If non-option arguments are present, they are names for tests to run,
 unless -x is given, in which case they are names for tests not to run.
@@ -133,6 +134,7 @@
 
 import cStringIO
 import getopt
+import json
 import os
 import random
 import re
@@ -193,7 +195,7 @@
 exclude=False, single=False, randomize=False, fromfile=None,
 findleaks=False, use_resources=None, trace=False, coverdir='coverage',
 runleaks=False, huntrleaks=False, verbose2=False, print_slow=False,
- random_seed=None):
+ random_seed=None, use_mp=None):
 """Execute a test suite.
 
 This also parses command-line options and modifies its behavior
@@ -218,13 +220,13 @@
 
 test_support.record_original_stdout(sys.stdout)
 try:
- opts, args = getopt.getopt(sys.argv[1:], 'hvgqxsSrf:lu:t:TD:NLR:wM:',
+ opts, args = getopt.getopt(sys.argv[1:], 'hvgqxsSrf:lu:t:TD:NLR:wM:j:',
 ['help', 'verbose', 'quiet', 'exclude',
 'single', 'slow', 'random', 'fromfile',
 'findleaks', 'use=', 'threshold=', 'trace',
 'coverdir=', 'nocoverdir', 'runleaks',
 'huntrleaks=', 'verbose2', 'memlimit=',
- 'randseed='
+ 'randseed=', 'multiprocess=', 'slaveargs=',
 ])
 except getopt.error, msg:
 usage(2, msg)
@@ -303,8 +305,23 @@
 use_resources.remove(r)
 elif r not in use_resources:
 use_resources.append(r)
+ elif o in ('-j', '--multiprocess'):
+ use_mp = int(a)
+ elif o == '--slaveargs':
+ args, kwargs = json.loads(a)
+ try:
+ result = runtest(*args, **kwargs)
+ except BaseException, e:
+ result = -3, e.__class__.__name__
+ print # Force a newline (just in case)
+ print json.dumps(result)
+ sys.exit(0)
 if single and fromfile:
 usage(2, "-s and -f don't go together!")
+ if use_mp and trace:
+ usage(2, "-T and -j don't go together!")
+ if use_mp and findleaks:
+ usage(2, "-l and -j don't go together!")
 
 good = []
 bad = []
@@ -370,50 +387,111 @@
 tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix],
 trace=False, count=True)
 test_times = []
- test_support.verbose = verbose # Tell tests to be moderately quiet
 test_support.use_resources = use_resources
 save_modules = sys.modules.keys()
- for test in tests:
- if not quiet:
- print test
- sys.stdout.flush()
- if trace:
- # If we're tracing code coverage, then we don't exit with status
- # if on a false return value from main.
- tracer.runctx('runtest(test, verbose, quiet,'
- ' test_times, testdir)',
- globals=globals(), locals=vars())
+
+ def accumulate_result(test, result):
+ ok, test_time = result
+ test_times.append((test_time, test))
+ if ok > 0:
+ good.append(test)
+ elif ok == 0:
+ bad.append(test)
 else:
+ skipped.append(test)
+ if ok == -2:
+ resource_denieds.append(test)
+
+ if use_mp:
+ from threading import Thread
+ from Queue import Queue, Empty
+ from subprocess import Popen, PIPE, STDOUT
+ from collections import deque
+ debug_output_pat = re.compile(r"\[\d+ refs\]$")
+ pending = deque()
+ output = Queue()
+ for test in tests:
+ args_tuple = (
+ (test, verbose, quiet, testdir),
+ dict(huntrleaks=huntrleaks, use_resources=use_resources)
+ )
+ pending.append((test, args_tuple))
+ def work():
+ # A worker thread.
 try:
- ok = runtest(test, verbose, quiet, test_times,
- testdir, huntrleaks)
- except KeyboardInterrupt:
- # print a newline separate from the ^C
- print
- break
- except:
+ while True:
+ try:
+ test, args_tuple = pending.popleft()
+ except IndexError:
+ output.put((None, None, None))
+ return
+ if not quiet:
+ print test
+ sys.stdout.flush()
+ popen = Popen([sys.executable, '-m', 'test.regrtest',
+ '--slaveargs', json.dumps(args_tuple)],
+ stdout=PIPE, stderr=STDOUT,
+ universal_newlines=True, close_fds=True)
+ out = popen.communicate()[0].strip()
+ out = debug_output_pat.sub("", out)
+ out, _, result = out.strip().rpartition("\n")
+ result = json.loads(result)
+ output.put((test, out.strip(), result))
+ except BaseException:
+ output.put((None, None, None))
 raise
- if ok > 0:
- good.append(test)
- elif ok == 0:
- bad.append(test)
+ workers = [Thread(target=work) for i in range(use_mp)]
+ for worker in workers:
+ worker.start()
+ finished = 0
+ while finished < use_mp:
+ test, out, result = output.get()
+ if test is None:
+ finished += 1
+ continue
+ if out:
+ print out
+ if result[0] == -3:
+ assert result[1] == 'KeyboardInterrupt'
+ pending.clear()
+ raise KeyboardInterrupt # What else?
+ accumulate_result(test, result)
+ for worker in workers:
+ worker.join()
+ else:
+ for test in tests:
+ if not quiet:
+ print test
+ sys.stdout.flush()
+ if trace:
+ # If we're tracing code coverage, then we don't exit with status
+ # if on a false return value from main.
+ tracer.runctx('runtest(test, verbose, quiet, testdir)',
+ globals=globals(), locals=vars())
 else:
- skipped.append(test)
- if ok == -2:
- resource_denieds.append(test)
- if findleaks:
- gc.collect()
- if gc.garbage:
- print "Warning: test created", len(gc.garbage),
- print "uncollectable object(s)."
- # move the uncollectable objects somewhere so we don't see
- # them again
- found_garbage.extend(gc.garbage)
- del gc.garbage[:]
- # Unload the newly imported modules (best effort finalization)
- for module in sys.modules.keys():
- if module not in save_modules and module.startswith("test."):
- test_support.unload(module)
+ try:
+ result = runtest(test, verbose, quiet,
+ testdir, huntrleaks)
+ accumulate_result(test, result)
+ except KeyboardInterrupt:
+ # print a newline separate from the ^C
+ print
+ break
+ except:
+ raise
+ if findleaks:
+ gc.collect()
+ if gc.garbage:
+ print "Warning: test created", len(gc.garbage),
+ print "uncollectable object(s)."
+ # move the uncollectable objects somewhere so we don't see
+ # them again
+ found_garbage.extend(gc.garbage)
+ del gc.garbage[:]
+ # Unload the newly imported modules (best effort finalization)
+ for module in sys.modules.keys():
+ if module not in save_modules and module.startswith("test."):
+ test_support.unload(module)
 
 # The lists won't be sorted if running with -r
 good.sort()
@@ -457,7 +535,7 @@
 sys.stdout.flush()
 try:
 test_support.verbose = True
- ok = runtest(test, True, quiet, test_times, testdir,
+ ok = runtest(test, True, quiet, testdir,
 huntrleaks)
 except KeyboardInterrupt:
 # print a newline separate from the ^C
@@ -521,8 +599,8 @@
 tests.sort()
 return stdtests + tests
 
-def runtest(test, verbose, quiet, test_times,
- testdir=None, huntrleaks=False):
+def runtest(test, verbose, quiet,
+ testdir=None, huntrleaks=False, use_resources=None):
 """Run a single test.
 
 test -- the name of the test
@@ -539,13 +617,16 @@
 1 test passed
 """
 
+ test_support.verbose = verbose # Tell tests to be moderately quiet
+ if use_resources is not None:
+ test_support.use_resources = use_resources
 try:
- return runtest_inner(test, verbose, quiet, test_times,
+ return runtest_inner(test, verbose, quiet,
 testdir, huntrleaks)
 finally:
 cleanup_test_droppings(test, verbose)
 
-def runtest_inner(test, verbose, quiet, test_times,
+def runtest_inner(test, verbose, quiet,
 testdir=None, huntrleaks=False):
 test_support.unload(test)
 if not testdir:
@@ -555,6 +636,7 @@
 else:
 capture_stdout = cStringIO.StringIO()
 
+ test_time = 0.0
 refleak = False # True if the test leaked references.
 try:
 save_stdout = sys.stdout
@@ -578,25 +660,24 @@
 if huntrleaks:
 refleak = dash_R(the_module, test, indirect_test, huntrleaks)
 test_time = time.time() - start_time
- test_times.append((test_time, test))
 finally:
 sys.stdout = save_stdout
 except test_support.ResourceDenied, msg:
 if not quiet:
 print test, "skipped --", msg
 sys.stdout.flush()
- return -2
+ return -2, test_time
 except unittest.SkipTest, msg:
 if not quiet:
 print test, "skipped --", msg
 sys.stdout.flush()
- return -1
+ return -1, test_time
 except KeyboardInterrupt:
 raise
 except test_support.TestFailed, msg:
 print "test", test, "failed --", msg
 sys.stdout.flush()
- return 0
+ return 0, test_time
 except:
 type, value = sys.exc_info()[:2]
 print "test", test, "crashed --", str(type) + ":", value
@@ -604,22 +685,22 @@
 if verbose:
 traceback.print_exc(file=sys.stdout)
 sys.stdout.flush()
- return 0
+ return 0, test_time
 else:
 if refleak:
- return 0
+ return 0, test_time
 # Except in verbose mode, tests should not print anything
 if verbose or huntrleaks:
- return 1
+ return 1, test_time
 output = capture_stdout.getvalue()
 if not output:
- return 1
+ return 1, test_time
 print "test", test, "produced unexpected output:"
 print "*" * 70
 print output
 print "*" * 70
 sys.stdout.flush()
- return 0
+ return 0, test_time
 
 def cleanup_test_droppings(testname, verbose):
 import shutil
@@ -707,9 +788,9 @@
 if any(deltas):
 msg = '%s leaked %s references, sum=%s' % (test, deltas, sum(deltas))
 print >> sys.stderr, msg
- refrep = open(fname, "a")
- print >> refrep, msg
- refrep.close()
+ with open(fname, "a") as refrep:
+ print >> refrep, msg
+ refrep.flush()
 return True
 return False
 
@@ -1227,6 +1308,6 @@
 i -= 1
 if os.path.abspath(os.path.normpath(sys.path[i])) == mydir:
 del sys.path[i]
- if len(sys.path) == pathlen:
+ if '--slaveargs' not in sys.argv and len(sys.path) == pathlen:
 print 'Could not find %r in sys.path to remove it' % mydir
 main()
Modified: python/branches/tk_and_idle_maintenance/Lib/test/test_cprofile.py
==============================================================================
--- python/branches/tk_and_idle_maintenance/Lib/test/test_cprofile.py	(original)
+++ python/branches/tk_and_idle_maintenance/Lib/test/test_cprofile.py	Sun May 31 23:36:15 2009
@@ -9,6 +9,7 @@
 
 class CProfileTest(ProfileTest):
 profilerclass = cProfile.Profile
+ expected_list_sort_output = "{method 'sort' of 'list' objects}"
 
 # Issue 3895.
 def test_bad_counter_during_dealloc(self):
Modified: python/branches/tk_and_idle_maintenance/Lib/test/test_epoll.py
==============================================================================
--- python/branches/tk_and_idle_maintenance/Lib/test/test_epoll.py	(original)
+++ python/branches/tk_and_idle_maintenance/Lib/test/test_epoll.py	Sun May 31 23:36:15 2009
@@ -95,6 +95,34 @@
 finally:
 ep.close()
 
+ # adding by object w/ fileno works, too.
+ ep = select.epoll(2)
+ try:
+ ep.register(server, select.EPOLLIN | select.EPOLLOUT)
+ ep.register(client, select.EPOLLIN | select.EPOLLOUT)
+ finally:
+ ep.close()
+
+ ep = select.epoll(2)
+ try:
+ # TypeError: argument must be an int, or have a fileno() method.
+ self.assertRaises(TypeError, ep.register, object(),
+ select.EPOLLIN | select.EPOLLOUT)
+ self.assertRaises(TypeError, ep.register, None,
+ select.EPOLLIN | select.EPOLLOUT)
+ # ValueError: file descriptor cannot be a negative integer (-1)
+ self.assertRaises(ValueError, ep.register, -1,
+ select.EPOLLIN | select.EPOLLOUT)
+ # IOError: [Errno 9] Bad file descriptor
+ self.assertRaises(IOError, ep.register, 10000,
+ select.EPOLLIN | select.EPOLLOUT)
+ # registering twice also raises an exception
+ ep.register(server, select.EPOLLIN | select.EPOLLOUT)
+ self.assertRaises(IOError, ep.register, server,
+ select.EPOLLIN | select.EPOLLOUT)
+ finally:
+ ep.close()
+
 def test_fromfd(self):
 server, client = self._connected_pair()
 
Modified: python/branches/tk_and_idle_maintenance/Lib/test/test_profile.py
==============================================================================
--- python/branches/tk_and_idle_maintenance/Lib/test/test_profile.py	(original)
+++ python/branches/tk_and_idle_maintenance/Lib/test/test_profile.py	Sun May 31 23:36:15 2009
@@ -16,6 +16,7 @@
 profilerclass = profile.Profile
 methodnames = ['print_stats', 'print_callers', 'print_callees']
 expected_output = {}
+ expected_list_sort_output = ':0(sort)'
 
 @classmethod
 def do_profiling(cls):
@@ -40,6 +41,25 @@
 "Stats.%s output for %s doesn't fit expectation!" %
 (method, self.profilerclass.__name__))
 
+ def test_calling_conventions(self):
+ # Issue #5330: profile and cProfile wouldn't report C functions called
+ # with keyword arguments. We test all calling conventions.
+ stmts = [
+ "[].sort()",
+ "[].sort(reverse=True)",
+ "[].sort(*(None, None, True))",
+ "[].sort(**dict(reverse=True))",
+ ]
+ for stmt in stmts:
+ s = StringIO()
+ prof = self.profilerclass(timer, 0.001)
+ prof.runctx(stmt, globals(), locals())
+ stats = pstats.Stats(prof, stream=s)
+ stats.print_stats()
+ res = s.getvalue()
+ self.assertTrue(self.expected_list_sort_output in res,
+ "Profiling {0!r} didn't report list.sort:\n{1}".format(stmt, res))
+
 
 def regenerate_expected_output(filename, cls):
 filename = filename.rstrip('co')
Modified: python/branches/tk_and_idle_maintenance/Lib/test/test_support.py
==============================================================================
--- python/branches/tk_and_idle_maintenance/Lib/test/test_support.py	(original)
+++ python/branches/tk_and_idle_maintenance/Lib/test/test_support.py	Sun May 31 23:36:15 2009
@@ -6,6 +6,7 @@
 import contextlib
 import errno
 import functools
+import gc
 import socket
 import sys
 import os
@@ -378,6 +379,10 @@
 'Unicode filename tests may not be effective' \
 % TESTFN_UNICODE_UNENCODEABLE
 
+# Disambiguate TESTFN for parallel testing, while letting it remain a valid
+# module name.
+TESTFN = "{0}_{1}_tmp".format(TESTFN, os.getpid())
+
 # Make sure we can write to TESTFN, try in /tmp if we can't
 fp = None
 try:
@@ -640,7 +645,6 @@
 longer than expected. This function tries its best to force all garbage
 objects to disappear.
 """
- import gc
 gc.collect()
 gc.collect()
 gc.collect()
Modified: python/branches/tk_and_idle_maintenance/Misc/ACKS
==============================================================================
--- python/branches/tk_and_idle_maintenance/Misc/ACKS	(original)
+++ python/branches/tk_and_idle_maintenance/Misc/ACKS	Sun May 31 23:36:15 2009
@@ -239,6 +239,7 @@
 Peter Funk
 Geoff Furnish
 Ulisses Furquim
+Hagen Fürstenau
 Achim Gaedke
 Martin von Gagern
 Lele Gaifax
Modified: python/branches/tk_and_idle_maintenance/Misc/NEWS
==============================================================================
--- python/branches/tk_and_idle_maintenance/Misc/NEWS	(original)
+++ python/branches/tk_and_idle_maintenance/Misc/NEWS	Sun May 31 23:36:15 2009
@@ -12,6 +12,9 @@
 Core and Builtins
 -----------------
 
+- Issue #5330: C functions called with keyword arguments were not reported by
+ the various profiling modules (profile, cProfile). Patch by Hagen Fürstenau.
+
 - Issue #5982: staticmethod and classmethod now expose the wrapped
 function with __func__.
 
@@ -1101,6 +1104,9 @@
 Tests
 -----
 
+- Issue #6152: New option '-j'/'--multiprocess' for regrtest allows running
+ regression tests in parallel, shortening the total runtime.
+
 - Issue #5354: New test support function import_fresh_module() makes
 it easy to import both normal and optimised versions of modules.
 test_heapq and test_warnings have been adjusted to use it, tests for
Modified: python/branches/tk_and_idle_maintenance/Objects/object.c
==============================================================================
--- python/branches/tk_and_idle_maintenance/Objects/object.c	(original)
+++ python/branches/tk_and_idle_maintenance/Objects/object.c	Sun May 31 23:36:15 2009
@@ -2156,6 +2156,9 @@
 
 	if (PyType_Ready(&PyMemberDescr_Type) < 0)
 		Py_FatalError("Can't initialize member descriptor type");
+
+	if (PyType_Ready(&PyFile_Type) < 0)
+		Py_FatalError("Can't initialize file type");
 }
 
 
Modified: python/branches/tk_and_idle_maintenance/Python/ceval.c
==============================================================================
--- python/branches/tk_and_idle_maintenance/Python/ceval.c	(original)
+++ python/branches/tk_and_idle_maintenance/Python/ceval.c	Sun May 31 23:36:15 2009
@@ -4160,10 +4160,17 @@
 		PCALL(PCALL_METHOD);
 	else if (PyType_Check(func))
 		PCALL(PCALL_TYPE);
+	else if (PyCFunction_Check(func))
+		PCALL(PCALL_CFUNCTION);
 	else
 		PCALL(PCALL_OTHER);
 #endif
-	result = PyObject_Call(func, callargs, kwdict);
+	if (PyCFunction_Check(func)) {
+		PyThreadState *tstate = PyThreadState_GET();
+		C_TRACE(result, PyCFunction_Call(func, callargs, kwdict));
+	}
+	else
+		result = PyObject_Call(func, callargs, kwdict);
 call_fail:
 	Py_XDECREF(callargs);
 	Py_XDECREF(kwdict);
@@ -4248,10 +4255,17 @@
 		PCALL(PCALL_METHOD);
 	else if (PyType_Check(func))
 		PCALL(PCALL_TYPE);
+	else if (PyCFunction_Check(func))
+		PCALL(PCALL_CFUNCTION);
 	else
 		PCALL(PCALL_OTHER);
 #endif
-	result = PyObject_Call(func, callargs, kwdict);
+	if (PyCFunction_Check(func)) {
+		PyThreadState *tstate = PyThreadState_GET();
+		C_TRACE(result, PyCFunction_Call(func, callargs, kwdict));
+	}
+	else
+		result = PyObject_Call(func, callargs, kwdict);
 ext_call_fail:
 	Py_XDECREF(callargs);
 	Py_XDECREF(kwdict);


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /