From 4118174315f4cba03208886af868fe31f1cd5b9d Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 2 Jul 2008 20:22:54 +0000 Subject: Merged revisions 64475,64544-64545,64550,64557-64558,64565,64570,64577,64582-64583,64585,64590,64592-64593,64625,64630,64638,64647,64655-64656,64663-64664 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r64475 | raymond.hettinger | 2008-06-22 22:29:28 -0500 (Sun, 22 Jun 2008) | 1 line Issue 3161: Missing import and test. ........ r64544 | georg.brandl | 2008-06-26 16:12:55 -0500 (Thu, 26 Jun 2008) | 2 lines Use newer versions of externals. ........ r64545 | benjamin.peterson | 2008-06-26 16:23:30 -0500 (Thu, 26 Jun 2008) | 1 line add a htmlview directive ........ r64550 | brett.cannon | 2008-06-26 19:32:16 -0500 (Thu, 26 Jun 2008) | 2 lines Ignore .pyc and .pyo files. ........ r64557 | mark.dickinson | 2008-06-27 05:11:52 -0500 (Fri, 27 Jun 2008) | 3 lines Remove trailing 'L's from numerator and denominator in the repr() of a Fraction instance. ........ r64558 | mark.dickinson | 2008-06-27 06:03:21 -0500 (Fri, 27 Jun 2008) | 2 lines Add Jean Brouwers for his work on math.sum ........ r64565 | raymond.hettinger | 2008-06-27 16:34:24 -0500 (Fri, 27 Jun 2008) | 1 line Fix whitespace in example code. ........ r64570 | hyeshik.chang | 2008-06-27 20:04:31 -0500 (Fri, 27 Jun 2008) | 8 lines Give information for compililation of _multiprocessing.SemLock on FreeBSD: FreeBSD's P1003.1b semaphore support is highly experimental and it's disabled by default. Even if a user loads the experimental kernel module manually, _multiprocessing doesn't work correctly due to several known incompatibilities around sem_unlink and sem_getvalue, yet. ........ r64577 | raymond.hettinger | 2008-06-28 17:16:53 -0500 (Sat, 28 Jun 2008) | 1 line Issue 3230: Do not the set specific size macro. ........ r64582 | benjamin.peterson | 2008-06-28 18:06:05 -0500 (Sat, 28 Jun 2008) | 2 lines convert test_audioop to unittest. Thanks to Giampaolo Rodola. ........ r64583 | benjamin.peterson | 2008-06-28 18:06:49 -0500 (Sat, 28 Jun 2008) | 1 line rewrap ........ r64585 | benjamin.peterson | 2008-06-28 18:35:31 -0500 (Sat, 28 Jun 2008) | 1 line fix typo ........ r64590 | benjamin.peterson | 2008-06-29 08:43:07 -0500 (Sun, 29 Jun 2008) | 1 line reinstate the ending backtick. thanks Nick :) ........ r64592 | vinay.sajip | 2008-06-29 16:25:28 -0500 (Sun, 29 Jun 2008) | 2 lines Removed out-of-date comment in _install_handlers and used issubclass in place of equality comparison of classes. ........ r64593 | vinay.sajip | 2008-06-29 16:27:15 -0500 (Sun, 29 Jun 2008) | 1 line Updated to reflect change in logging.config to remove out-of-date comment in _install_handlers and the use of issubclass in place of equality comparison of classes. ........ r64625 | georg.brandl | 2008-07-01 14:59:00 -0500 (Tue, 01 Jul 2008) | 2 lines Add a link to PEP 324. ........ r64630 | georg.brandl | 2008-07-01 15:18:10 -0500 (Tue, 01 Jul 2008) | 2 lines #3216: fix Execute's parameter description. ........ r64638 | georg.brandl | 2008-07-01 15:50:02 -0500 (Tue, 01 Jul 2008) | 2 lines #1410739: add a footnote about "is" and "unusual" behavior. ........ r64647 | benjamin.peterson | 2008-07-01 18:33:06 -0500 (Tue, 01 Jul 2008) | 1 line add ABC to the glossary ........ r64655 | mark.dickinson | 2008-07-02 04:37:01 -0500 (Wed, 02 Jul 2008) | 7 lines Replace occurrences of '\d' with '[0-9]' in Decimal regex, to make sure that the behaviour of Decimal doesn't change if/when re.UNICODE becomes assumed in Python 3.0. Also add a check that alternative Unicode digits (e.g. u'\N{FULLWIDTH DIGIT ONE}') are *not* accepted in a numeric string. ........ r64656 | nick.coghlan | 2008-07-02 08:09:19 -0500 (Wed, 02 Jul 2008) | 1 line Issue 3190: pydoc now hides module __package__ attributes ........ r64663 | jesse.noller | 2008-07-02 11:44:09 -0500 (Wed, 02 Jul 2008) | 1 line Reenable the manager tests with Amaury's threading fix ........ r64664 | facundo.batista | 2008-07-02 11:52:55 -0500 (Wed, 02 Jul 2008) | 4 lines Issue #449227: Now with the rlcompleter module, callable objects are added a '(' when completed. ........ --- Doc/Makefile | 8 +- Doc/glossary.rst | 15 +- Doc/library/abc.rst | 8 +- Doc/library/collections.rst | 4 +- Doc/library/msilib.rst | 9 +- Doc/library/rlcompleter.rst | 6 +- Doc/library/subprocess.rst | 4 + Doc/reference/compound_stmts.rst | 8 +- Doc/reference/expressions.rst | 6 +- Lib/_abcoll.py | 1 + Lib/decimal.py | 20 +- Lib/fractions.py | 2 +- Lib/logging/config.py | 3 +- Lib/pydoc.py | 5 +- Lib/rlcompleter.py | 22 ++- Lib/test/test_audioop.py | 415 ++++++++++++++------------------------- Lib/test/test_collections.py | 15 ++ Lib/test/test_decimal.py | 3 + Lib/test/test_fractions.py | 4 + Lib/test/test_multiprocessing.py | 30 ++- Lib/test/test_pydoc.py | 2 - Misc/ACKS | 1 + Objects/dictobject.c | 2 +- setup.py | 11 ++ 24 files changed, 271 insertions(+), 333 deletions(-) diff --git a/Doc/Makefile b/Doc/Makefile index c1abe11..470337b 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -33,15 +33,15 @@ checkout: fi @if [ ! -d tools/docutils ]; then \ echo "Checking out Docutils..."; \ - svn checkout $(SVNROOT)/external/docutils-0.4/docutils tools/docutils; \ + svn checkout $(SVNROOT)/external/docutils-0.5/docutils tools/docutils; \ fi @if [ ! -d tools/jinja ]; then \ echo "Checking out Jinja..."; \ - svn checkout $(SVNROOT)/external/Jinja-1.1/jinja tools/jinja; \ + svn checkout $(SVNROOT)/external/Jinja-1.2/jinja tools/jinja; \ fi @if [ ! -d tools/pygments ]; then \ echo "Checking out Pygments..."; \ - svn checkout $(SVNROOT)/external/Pygments-0.9/pygments tools/pygments; \ + svn checkout $(SVNROOT)/external/Pygments-0.10/pygments tools/pygments; \ fi update: checkout @@ -103,6 +103,8 @@ pydoc-topics: build @echo "Building finished; now copy build/pydoc-topics/pydoc_topics.py " \ "into the Lib/ directory" +htmlview: html + $(PYTHON) -c "import webbrowser; webbrowser.open('build/html/index.html')" clean: -rm -rf build/* -rm -rf tools/sphinx diff --git a/Doc/glossary.rst b/Doc/glossary.rst index cd8b7ac..3caa36e 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -16,6 +16,14 @@ Glossary The typical Python prompt of the interactive shell when entering code for an indented code block. + Abstract Base Class + Abstract Base Classes (abbreviated ABCs) complement :term:`duck-typing` by + providing a way to define interfaces when other techniques like :func:`hasattr` + would be clumsy. Python comes with many builtin ABCs for data structures + (in the :mod:`collections` module), numbers (in the :mod:`numbers` + module), and streams (in the :mod:`io` module). You can create your own + ABC with the :mod:`abc` module. + argument A value passed to a function or method, assigned to a name local to the body. A function or method may have both positional arguments and @@ -93,15 +101,16 @@ Glossary be any object with a :meth:`__hash__` function, not just integers starting from zero. Called a hash in Perl. - duck-typing + duck-typing Pythonic programming style that determines an object's type by inspection of its method or attribute signature rather than by explicit relationship to some type object ("If it looks like a duck and quacks like a duck, it must be a duck.") By emphasizing interfaces rather than specific types, well-designed code improves its flexibility by allowing polymorphic substitution. Duck-typing avoids tests using :func:`type` or - :func:`isinstance`. Instead, it typically employs :func:`hasattr` tests or - :term:`EAFP` programming. + :func:`isinstance`. (Note, however, that duck-typing can be complemented + with abstract base classes.) Instead, it typically employs :func:`hasattr` + tests or :term:`EAFP` programming. EAFP Easier to ask for forgiveness than permission. This common Python coding diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst index f1a6c06..21d3018 100644 --- a/Doc/library/abc.rst +++ b/Doc/library/abc.rst @@ -8,10 +8,10 @@ .. sectionauthor:: Georg Brandl .. much of the content adapted from docstrings -This module provides the infrastructure for defining abstract base classes -(ABCs) in Python, as outlined in :pep:`3119`; see the PEP for why this was added -to Python. (See also :pep:`3141` and the :mod:`numbers` module regarding a type -hierarchy for numbers based on ABCs.) +This module provides the infrastructure for defining :term:`abstract base +classes` (ABCs) in Python, as outlined in :pep:`3119`; see the PEP for why this +was added to Python. (See also :pep:`3141` and the :mod:`numbers` module +regarding a type hierarchy for numbers based on ABCs.) The :mod:`collections` module has some concrete classes that derive from ABCs; these can, of course, be further derived. In addition the diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index 3203ca5..7718c51 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -520,8 +520,8 @@ Example: raise ValueError('Got unexpected field names: %r' % kwds.keys()) return result - def __getnewargs__(self): - return tuple(self) + def __getnewargs__(self): + return tuple(self) x = property(itemgetter(0)) y = property(itemgetter(1)) diff --git a/Doc/library/msilib.rst b/Doc/library/msilib.rst index eb58d44..d0a53d7 100644 --- a/Doc/library/msilib.rst +++ b/Doc/library/msilib.rst @@ -1,4 +1,3 @@ - :mod:`msilib` --- Read and write Microsoft Installer files ========================================================== @@ -163,11 +162,11 @@ View Objects ------------ -.. method:: View.Execute([params=None]) +.. method:: View.Execute(params) - Execute the SQL query of the view, through :cfunc:`MSIViewExecute`. *params* is - an optional record describing actual values of the parameter tokens in the - query. + Execute the SQL query of the view, through :cfunc:`MSIViewExecute`. If + *params* is not ``None``, it is a record describing actual values of the + parameter tokens in the query. .. method:: View.GetColumnInfo(kind) diff --git a/Doc/library/rlcompleter.rst b/Doc/library/rlcompleter.rst index 01efb03..b09df54 100644 --- a/Doc/library/rlcompleter.rst +++ b/Doc/library/rlcompleter.rst @@ -20,9 +20,9 @@ Example:: >>> import readline >>> readline.parse_and_bind("tab: complete") >>> readline. - readline.__doc__ readline.get_line_buffer readline.read_init_file - readline.__file__ readline.insert_text readline.set_completer - readline.__name__ readline.parse_and_bind + readline.__doc__ readline.get_line_buffer( readline.read_init_file( + readline.__file__ readline.insert_text( readline.set_completer( + readline.__name__ readline.parse_and_bind( >>> readline. The :mod:`rlcompleter` module is designed for use with Python's interactive diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index ba2a5a1..daa88b3 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -18,6 +18,10 @@ replace several other, older modules and functions, such as:: Information about how the :mod:`subprocess` module can be used to replace these modules and functions can be found in the following sections. +.. seealso:: + + :pep:`324` -- PEP proposing the subprocess module + Using the subprocess Module --------------------------- diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index c5b949e..a3665e7 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -583,10 +583,10 @@ variables with different implementation details. :pep:`3129` - Class Decorators -Class definitions, like function definitions, may be wrapped by one or -more :term:`decorator` expressions. The evaluation rules for the -decorator expressions are the same as for functions. The result must -be a class object, which is then bound to the class name. +Class definitions, like function definitions, may be wrapped by one or more +:term:`decorator` expressions. The evaluation rules for the decorator +expressions are the same as for functions. The result must be a class object, +which is then bound to the class name. .. rubric:: Footnotes diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index af79e53..e205e42 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -1082,7 +1082,7 @@ The operator :keyword:`not in` is defined to have the inverse true value of The operators :keyword:`is` and :keyword:`is not` test for object identity: ``x is y`` is true if and only if *x* and *y* are the same object. ``x is not y`` -yields the inverse truth value. +yields the inverse truth value. [#]_ .. _booleans: @@ -1314,3 +1314,7 @@ groups from right to left). identity only, but this caused surprises because people expected to be able to test a dictionary for emptiness by comparing it to ``{}``. +.. [#] Due to automatic garbage-collection, free lists, and the dynamic nature of + descriptors, you may notice seemingly unusual behaviour in certain uses of + the :keyword:`is` operator, like those involving comparisons between instance + methods, or constants. Check their documentation for more info. diff --git a/Lib/_abcoll.py b/Lib/_abcoll.py index 8a8c0ee..72f1397 100644 --- a/Lib/_abcoll.py +++ b/Lib/_abcoll.py @@ -9,6 +9,7 @@ bootstrapping issues. Unit tests are in test_collections. """ from abc import ABCMeta, abstractmethod +import sys __all__ = ["Hashable", "Iterable", "Iterator", "Sized", "Container", "Callable", diff --git a/Lib/decimal.py b/Lib/decimal.py index e1d69fd..180b177 100644 --- a/Lib/decimal.py +++ b/Lib/decimal.py @@ -5423,20 +5423,20 @@ ExtendedContext = Context( # other meaning for \d than the numbers [0-9]. import re -_parser = re.compile(r""" # A numeric string consists of: +_parser = re.compile(r""" # A numeric string consists of: # \s* - (?P[-+])? # an optional sign, followed by either... + (?P[-+])? # an optional sign, followed by either... ( - (?=\d|\.\d) # ...a number (with at least one digit) - (?P\d*) # consisting of a (possibly empty) integer part - (\.(?P\d*))? # followed by an optional fractional part - (E(?P[-+]?\d+))? # followed by an optional exponent, or... + (?=[0-9]|\.[0-9]) # ...a number (with at least one digit) + (?P[0-9]*) # having a (possibly empty) integer part + (\.(?P[0-9]*))? # followed by an optional fractional part + (E(?P[-+]?[0-9]+))? # followed by an optional exponent, or... | - Inf(inity)? # ...an infinity, or... + Inf(inity)? # ...an infinity, or... | - (?Ps)? # ...an (optionally signaling) - NaN # NaN - (?P\d*) # with (possibly empty) diagnostic information. + (?Ps)? # ...an (optionally signaling) + NaN # NaN + (?P[0-9]*) # with (possibly empty) diagnostic info. ) # \s* \Z diff --git a/Lib/fractions.py b/Lib/fractions.py index d3fd920..329a16f 100755 --- a/Lib/fractions.py +++ b/Lib/fractions.py @@ -201,7 +201,7 @@ class Fraction(numbers.Rational): def __repr__(self): """repr(self)""" - return ('Fraction(%r, %r)' % (self._numerator, self._denominator)) + return ('Fraction(%s, %s)' % (self._numerator, self._denominator)) def __str__(self): """str(self)""" diff --git a/Lib/logging/config.py b/Lib/logging/config.py index 645a7ba..4123506 100644 --- a/Lib/logging/config.py +++ b/Lib/logging/config.py @@ -152,8 +152,7 @@ def _install_handlers(cp, formatters): h.setLevel(logging._levelNames[level]) if len(fmt): h.setFormatter(formatters[fmt]) - #temporary hack for FileHandler and MemoryHandler. - if klass == logging.handlers.MemoryHandler: + if issubclass(klass, logging.handlers.MemoryHandler): if "target" in opts: target = cp.get(sectname,"target") else: diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 2c559bd..cd9490e 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -159,8 +159,9 @@ def _split_list(s, predicate): def visiblename(name, all=None): """Decide whether to show documentation on a variable.""" # Certain special names are redundant. - if name in ('__builtins__', '__doc__', '__file__', '__path__', - '__module__', '__name__', '__slots__'): return 0 + _hidden_names = ('__builtins__', '__doc__', '__file__', '__path__', + '__module__', '__name__', '__slots__', '__package__') + if name in _hidden_names: return 0 # Private names are hidden, but special names are displayed. if name.startswith('__') and name.endswith('__'): return 1 if all is not None: diff --git a/Lib/rlcompleter.py b/Lib/rlcompleter.py index 10a53dc..2739fed 100644 --- a/Lib/rlcompleter.py +++ b/Lib/rlcompleter.py @@ -86,6 +86,11 @@ class Completer: except IndexError: return None + def _callable_postfix(self, val, word): + if callable(val): + word = word + "(" + return word + def global_matches(self, text): """Compute matches when text is a simple name. @@ -96,12 +101,13 @@ class Completer: import keyword matches = [] n = len(text) - for list in [keyword.kwlist, - builtins.__dict__, - self.namespace]: - for word in list: - if word[:n] == text and word != "__builtins__": - matches.append(word) + for word in keyword.kwlist: + if word[:n] == text: + matches.append(word) + for nspace in [builtins.__dict__, self.namespace]: + for word, val in nspace.items(): + if word[:n] == text and word != "builtins": + matches.append(self._callable_postfix(val, word)) return matches def attr_matches(self, text): @@ -133,7 +139,9 @@ class Completer: n = len(attr) for word in words: if word[:n] == attr and word != "__builtins__": - matches.append("%s.%s" % (expr, word)) + val = getattr(object, word) + word = self._callable_postfix(val, "%s.%s" % (expr, word)) + matches.append(word) return matches def get_class_members(klass): diff --git a/Lib/test/test_audioop.py b/Lib/test/test_audioop.py index ae796ba..d43159a 100644 --- a/Lib/test/test_audioop.py +++ b/Lib/test/test_audioop.py @@ -1,288 +1,171 @@ -# Test audioop. import audioop -from test.support import verbose +import unittest +from test.support import run_unittest + def gendata1(): return b'\0\1\2' def gendata2(): - if verbose: - print('getsample') if audioop.getsample(b'\0\1', 2, 0) == 1: return b'\0\0\0\1\0\2' else: return b'\0\0\1\0\2\0' def gendata4(): - if verbose: - print('getsample') if audioop.getsample(b'\0\0\0\1', 4, 0) == 1: return b'\0\0\0\0\0\0\0\1\0\0\0\2' else: return b'\0\0\0\0\1\0\0\0\2\0\0\0' -def testmax(data): - if verbose: - print('max') - if audioop.max(data[0], 1) != 2 or \ - audioop.max(data[1], 2) != 2 or \ - audioop.max(data[2], 4) != 2: - return 0 - return 1 - -def testminmax(data): - if verbose: - print('minmax') - if audioop.minmax(data[0], 1) != (0, 2) or \ - audioop.minmax(data[1], 2) != (0, 2) or \ - audioop.minmax(data[2], 4) != (0, 2): - return 0 - return 1 - -def testmaxpp(data): - if verbose: - print('maxpp') - if audioop.maxpp(data[0], 1) != 0 or \ - audioop.maxpp(data[1], 2) != 0 or \ - audioop.maxpp(data[2], 4) != 0: - return 0 - return 1 - -def testavg(data): - if verbose: - print('avg') - if audioop.avg(data[0], 1) != 1 or \ - audioop.avg(data[1], 2) != 1 or \ - audioop.avg(data[2], 4) != 1: - return 0 - return 1 - -def testavgpp(data): - if verbose: - print('avgpp') - if audioop.avgpp(data[0], 1) != 0 or \ - audioop.avgpp(data[1], 2) != 0 or \ - audioop.avgpp(data[2], 4) != 0: - return 0 - return 1 - -def testrms(data): - if audioop.rms(data[0], 1) != 1 or \ - audioop.rms(data[1], 2) != 1 or \ - audioop.rms(data[2], 4) != 1: - return 0 - return 1 - -def testcross(data): - if verbose: - print('cross') - if audioop.cross(data[0], 1) != 0 or \ - audioop.cross(data[1], 2) != 0 or \ - audioop.cross(data[2], 4) != 0: - return 0 - return 1 - -def testadd(data): - if verbose: - print('add') - data2 = [] - for d in data: - str = bytearray(len(d)) - for i,b in enumerate(d): - str[i] = 2*b - data2.append(str) - if audioop.add(data[0], data[0], 1) != data2[0] or \ - audioop.add(data[1], data[1], 2) != data2[1] or \ - audioop.add(data[2], data[2], 4) != data2[2]: - return 0 - return 1 - -def testbias(data): - if verbose: - print('bias') - # Note: this test assumes that avg() works - d1 = audioop.bias(data[0], 1, 100) - d2 = audioop.bias(data[1], 2, 100) - d4 = audioop.bias(data[2], 4, 100) - if audioop.avg(d1, 1) != 101 or \ - audioop.avg(d2, 2) != 101 or \ - audioop.avg(d4, 4) != 101: - return 0 - return 1 - -def testlin2lin(data): - if verbose: - print('lin2lin') - # too simple: we test only the size - for d1 in data: - for d2 in data: - got = len(d1)//3 - wtd = len(d2)//3 - if len(audioop.lin2lin(d1, got, wtd)) != len(d2): - return 0 - return 1 - -def testadpcm2lin(data): - # Very cursory test - if audioop.adpcm2lin(b'\0\0', 1, None) != (b'\0\0\0\0', (0,0)): - return 0 - return 1 - -def testlin2adpcm(data): - if verbose: - print('lin2adpcm') - # Very cursory test - if audioop.lin2adpcm(b'\0\0\0\0', 1, None) != (b'\0\0', (0,0)): - return 0 - return 1 - -def testlin2alaw(data): - if verbose: - print('lin2alaw') - if audioop.lin2alaw(data[0], 1) != b'\xd5\xc5\xf5' or \ - audioop.lin2alaw(data[1], 2) != b'\xd5\xd5\xd5' or \ - audioop.lin2alaw(data[2], 4) != b'\xd5\xd5\xd5': - return 0 - return 1 - -def testalaw2lin(data): - if verbose: - print('alaw2lin') - # Cursory - d = audioop.lin2alaw(data[0], 1) - if audioop.alaw2lin(d, 1) != data[0]: - return 0 - return 1 - -def testlin2ulaw(data): - if verbose: - print('lin2ulaw') - if audioop.lin2ulaw(data[0], 1) != b'\xff\xe7\xdb' or \ - audioop.lin2ulaw(data[1], 2) != b'\xff\xff\xff' or \ - audioop.lin2ulaw(data[2], 4) != b'\xff\xff\xff': - return 0 - return 1 - -def testulaw2lin(data): - if verbose: - print('ulaw2lin') - # Cursory - d = audioop.lin2ulaw(data[0], 1) - if audioop.ulaw2lin(d, 1) != data[0]: - return 0 - return 1 - -def testmul(data): - if verbose: - print('mul') - data2 = [] - for d in data: - str = bytearray(len(d)) - for i,b in enumerate(d): - str[i] = 2*b - data2.append(str) - if audioop.mul(data[0], 1, 2) != data2[0] or \ - audioop.mul(data[1],2, 2) != data2[1] or \ - audioop.mul(data[2], 4, 2) != data2[2]: - return 0 - return 1 - -def testratecv(data): - if verbose: - print('ratecv') - state = None - d1, state = audioop.ratecv(data[0], 1, 1, 8000, 16000, state) - d2, state = audioop.ratecv(data[0], 1, 1, 8000, 16000, state) - if d1 + d2 != b'\000\000\001\001\002\001\000\000\001\001\002': - return 0 - return 1 - -def testreverse(data): - if verbose: - print('reverse') - if audioop.reverse(data[0], 1) != b'\2\1\0': - return 0 - return 1 - -def testtomono(data): - if verbose: - print('tomono') - data2 = bytearray() - for d in data[0]: - data2.append(d) - data2.append(d) - if audioop.tomono(data2, 1, 0.5, 0.5) != data[0]: - return 0 - return 1 - -def testtostereo(data): - if verbose: - print('tostereo') - data2 = bytearray() - for d in data[0]: - data2.append(d) - data2.append(d) - if audioop.tostereo(data[0], 1, 1, 1) != data2: - return 0 - return 1 - -def testfindfactor(data): - if verbose: - print('findfactor') - if audioop.findfactor(data[1], data[1]) != 1.0: - return 0 - return 1 - -def testfindfit(data): - if verbose: - print('findfit') - if audioop.findfit(data[1], data[1]) != (0, 1.0): - return 0 - return 1 - -def testfindmax(data): - if verbose: - print('findmax') - if audioop.findmax(data[1], 1) != 2: - return 0 - return 1 - -def testgetsample(data): - if verbose: - print('getsample') - for i in range(3): - if audioop.getsample(data[0], 1, i) != i or \ - audioop.getsample(data[1], 2, i) != i or \ - audioop.getsample(data[2], 4, i) != i: - return 0 - return 1 - -def testone(name, data): - try: - func = eval('test'+name) - except NameError: - print('No test found for audioop.'+name+'()') - return - try: - rv = func(data) - except Exception as e: - print('Test FAILED for audioop.'+name+'() (with %s)' % repr(e)) - return - if not rv: - print('Test FAILED for audioop.'+name+'()') - -def test_main(): - data = [gendata1(), gendata2(), gendata4()] - names = dir(audioop) - # We know there is a routine 'add' - routines = [] - for n in names: - if type(eval('audioop.'+n)) == type(audioop.add): - routines.append(n) - for n in routines: - testone(n, data) +data = [gendata1(), gendata2(), gendata4()] + + +class TestAudioop(unittest.TestCase): + + def test_max(self): + self.assertEqual(audioop.max(data[0], 1), 2) + self.assertEqual(audioop.max(data[1], 2), 2) + self.assertEqual(audioop.max(data[2], 4), 2) + + def test_minmax(self): + self.assertEqual(audioop.minmax(data[0], 1), (0, 2)) + self.assertEqual(audioop.minmax(data[1], 2), (0, 2)) + self.assertEqual(audioop.minmax(data[2], 4), (0, 2)) + + def test_maxpp(self): + self.assertEqual(audioop.maxpp(data[0], 1), 0) + self.assertEqual(audioop.maxpp(data[1], 2), 0) + self.assertEqual(audioop.maxpp(data[2], 4), 0) + + def test_avg(self): + self.assertEqual(audioop.avg(data[0], 1), 1) + self.assertEqual(audioop.avg(data[1], 2), 1) + self.assertEqual(audioop.avg(data[2], 4), 1) + + def test_avgpp(self): + self.assertEqual(audioop.avgpp(data[0], 1), 0) + self.assertEqual(audioop.avgpp(data[1], 2), 0) + self.assertEqual(audioop.avgpp(data[2], 4), 0) + + def test_rms(self): + self.assertEqual(audioop.rms(data[0], 1), 1) + self.assertEqual(audioop.rms(data[1], 2), 1) + self.assertEqual(audioop.rms(data[2], 4), 1) + + def test_cross(self): + self.assertEqual(audioop.cross(data[0], 1), 0) + self.assertEqual(audioop.cross(data[1], 2), 0) + self.assertEqual(audioop.cross(data[2], 4), 0) + + def test_add(self): + data2 = [] + for d in data: + str = bytearray(len(d)) + for i,b in enumerate(d): + str[i] = 2*b + data2.append(str) + self.assertEqual(audioop.add(data[0], data[0], 1), data2[0]) + self.assertEqual(audioop.add(data[1], data[1], 2), data2[1]) + self.assertEqual(audioop.add(data[2], data[2], 4), data2[2]) + + def test_bias(self): + # Note: this test assumes that avg() works + d1 = audioop.bias(data[0], 1, 100) + d2 = audioop.bias(data[1], 2, 100) + d4 = audioop.bias(data[2], 4, 100) + self.assertEqual(audioop.avg(d1, 1), 101) + self.assertEqual(audioop.avg(d2, 2), 101) + self.assertEqual(audioop.avg(d4, 4), 101) + + def test_lin2lin(self): + # too simple: we test only the size + for d1 in data: + for d2 in data: + got = len(d1)//3 + wtd = len(d2)//3 + self.assertEqual(len(audioop.lin2lin(d1, got, wtd)), len(d2)) + + def test_adpcm2lin(self): + # Very cursory test + self.assertEqual(audioop.adpcm2lin(b'\0\0', 1, None), (b'\0\0\0\0', (0,0))) + + def test_lin2adpcm(self): + # Very cursory test + self.assertEqual(audioop.lin2adpcm(b'\0\0\0\0', 1, None), (b'\0\0', (0,0))) + + def test_lin2alaw(self): + self.assertEqual(audioop.lin2alaw(data[0], 1), b'\xd5\xc5\xf5') + self.assertEqual(audioop.lin2alaw(data[1], 2), b'\xd5\xd5\xd5') + self.assertEqual(audioop.lin2alaw(data[2], 4), b'\xd5\xd5\xd5') + + def test_alaw2lin(self): + # Cursory + d = audioop.lin2alaw(data[0], 1) + self.assertEqual(audioop.alaw2lin(d, 1), data[0]) + + def test_lin2ulaw(self): + self.assertEqual(audioop.lin2ulaw(data[0], 1), b'\xff\xe7\xdb') + self.assertEqual(audioop.lin2ulaw(data[1], 2), b'\xff\xff\xff') + self.assertEqual(audioop.lin2ulaw(data[2], 4), b'\xff\xff\xff') + + def test_ulaw2lin(self): + # Cursory + d = audioop.lin2ulaw(data[0], 1) + self.assertEqual(audioop.ulaw2lin(d, 1), data[0]) + + def test_mul(self): + data2 = [] + for d in data: + str = bytearray(len(d)) + for i,b in enumerate(d): + str[i] = 2*b + data2.append(str) + self.assertEqual(audioop.mul(data[0], 1, 2), data2[0]) + self.assertEqual(audioop.mul(data[1],2, 2), data2[1]) + self.assertEqual(audioop.mul(data[2], 4, 2), data2[2]) + + def test_ratecv(self): + state = None + d1, state = audioop.ratecv(data[0], 1, 1, 8000, 16000, state) + d2, state = audioop.ratecv(data[0], 1, 1, 8000, 16000, state) + self.assertEqual(d1 + d2, b'\000\000\001\001\002\001\000\000\001\001\002') + + def test_reverse(self): + self.assertEqual(audioop.reverse(data[0], 1), b'\2\1\0') + + def test_tomono(self): + data2 = bytearray() + for d in data[0]: + data2.append(d) + data2.append(d) + self.assertEqual(audioop.tomono(data2, 1, 0.5, 0.5), data[0]) + + def test_tostereo(self): + data2 = bytearray() + for d in data[0]: + data2.append(d) + data2.append(d) + self.assertEqual(audioop.tostereo(data[0], 1, 1, 1), data2) + + def test_findfactor(self): + self.assertEqual(audioop.findfactor(data[1], data[1]), 1.0) + + def test_findfit(self): + self.assertEqual(audioop.findfit(data[1], data[1]), (0, 1.0)) + + def test_findmax(self): + self.assertEqual(audioop.findmax(data[1], 1), 2) + + def test_getsample(self): + for i in range(3): + self.assertEqual(audioop.getsample(data[0], 1, i), i) + self.assertEqual(audioop.getsample(data[1], 2, i), i) + self.assertEqual(audioop.getsample(data[2], 4, i), i) +def test_main(): + run_unittest(TestAudioop) if __name__ == '__main__': test_main() diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index 9289afe..ec0aa80 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -296,6 +296,21 @@ class TestCollectionABCs(unittest.TestCase): self.failUnless(isinstance(sample(), Set)) self.failUnless(issubclass(sample, Set)) + def test_hash_Set(self): + class OneTwoThreeSet(Set): + def __init__(self): + self.contents = [1, 2, 3] + def __contains__(self, x): + return x in self.contents + def __len__(self): + return len(self.contents) + def __iter__(self): + return iter(self.contents) + def __hash__(self): + return self._hash() + a, b = OneTwoThreeSet(), OneTwoThreeSet() + self.failUnless(hash(a) == hash(b)) + def test_MutableSet(self): self.failUnless(isinstance(set(), MutableSet)) self.failUnless(issubclass(set, MutableSet)) diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 617f4d9..d0de64d 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -426,6 +426,9 @@ class DecimalExplicitConstructionTest(unittest.TestCase): self.assertEqual(str(Decimal('1.3E4 \n')), '1.3E+4') self.assertEqual(str(Decimal(' -7.89')), '-7.89') + #but alternate unicode digits should not + self.assertEqual(str(Decimal('\uff11')), 'NaN') + def test_explicit_from_tuples(self): #zero diff --git a/Lib/test/test_fractions.py b/Lib/test/test_fractions.py index 97e91ce..3c8da77 100644 --- a/Lib/test/test_fractions.py +++ b/Lib/test/test_fractions.py @@ -364,6 +364,10 @@ class FractionTest(unittest.TestCase): def testStringification(self): self.assertEquals("Fraction(7, 3)", repr(F(7, 3))) + self.assertEquals("Fraction(6283185307, 2000000000)", + repr(F('3.1415926535'))) + self.assertEquals("Fraction(-1, 100000000000000000000)", + repr(F(1, -10**20))) self.assertEquals("7/3", str(F(7, 3))) self.assertEquals("7", str(F(7, 1))) diff --git a/Lib/test/test_multiprocessing.py b/Lib/test/test_multiprocessing.py index 5522c07..5966060 100644 --- a/Lib/test/test_multiprocessing.py +++ b/Lib/test/test_multiprocessing.py @@ -960,7 +960,6 @@ class _TestContainers(BaseTestCase): def sqr(x, wait=0.0): time.sleep(wait) return x*x -""" class _TestPool(BaseTestCase): def test_apply(self): @@ -1030,7 +1029,6 @@ class _TestPool(BaseTestCase): join = TimingWrapper(self.pool.join) join() self.assertTrue(join.elapsed < 0.2) -""" # # Test that manager has expected number of shared objects left # @@ -1333,7 +1331,6 @@ class _TestConnection(BaseTestCase): self.assertRaises(ValueError, a.send_bytes, msg, 4, -1) -""" class _TestListenerClient(BaseTestCase): ALLOWED_TYPES = ('processes', 'threads') @@ -1353,7 +1350,6 @@ class _TestListenerClient(BaseTestCase): self.assertEqual(conn.recv(), 'hello') p.join() l.close() -""" # # Test of sending connection and socket objects between processes # @@ -1769,28 +1765,28 @@ def test_main(run=None): multiprocessing.get_logger().setLevel(LOG_LEVEL) - #ProcessesMixin.pool = multiprocessing.Pool(4) - #ThreadsMixin.pool = multiprocessing.dummy.Pool(4) - #ManagerMixin.manager.__init__() - #ManagerMixin.manager.start() - #ManagerMixin.pool = ManagerMixin.manager.Pool(4) + ProcessesMixin.pool = multiprocessing.Pool(4) + ThreadsMixin.pool = multiprocessing.dummy.Pool(4) + ManagerMixin.manager.__init__() + ManagerMixin.manager.start() + ManagerMixin.pool = ManagerMixin.manager.Pool(4) testcases = ( - sorted(testcases_processes.values(), key=lambda tc:tc.__name__) #+ - #sorted(testcases_threads.values(), key=lambda tc:tc.__name__) + - #sorted(testcases_manager.values(), key=lambda tc:tc.__name__) + sorted(testcases_processes.values(), key=lambda tc:tc.__name__) + + sorted(testcases_threads.values(), key=lambda tc:tc.__name__) + + sorted(testcases_manager.values(), key=lambda tc:tc.__name__) ) loadTestsFromTestCase = unittest.defaultTestLoader.loadTestsFromTestCase suite = unittest.TestSuite(loadTestsFromTestCase(tc) for tc in testcases) run(suite) - #ThreadsMixin.pool.terminate() - #ProcessesMixin.pool.terminate() - #ManagerMixin.pool.terminate() - #ManagerMixin.manager.shutdown() + ThreadsMixin.pool.terminate() + ProcessesMixin.pool.terminate() + ManagerMixin.pool.terminate() + ManagerMixin.manager.shutdown() - #del ProcessesMixin.pool, ThreadsMixin.pool, ManagerMixin.pool + del ProcessesMixin.pool, ThreadsMixin.pool, ManagerMixin.pool def main(): test_main(unittest.TextTestRunner(verbosity=2).run) diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index 8b30e26..95a11af 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -66,7 +66,6 @@ FUNCTIONS DATA __author__ = 'Benjamin Peterson' __credits__ = 'Nobody' - __package__ = None __version__ = '1.2.3.4' VERSION @@ -163,7 +162,6 @@ war         __author__ = 'Benjamin Peterson'
__credits__ = 'Nobody'
-__package__ = None
__version__ = '1.2.3.4'

diff --git a/Misc/ACKS b/Misc/ACKS index 31fd5d3..ce010d5 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -87,6 +87,7 @@ Dave Brennan Tom Bridgman Richard Brodie Daniel Brotsky +Jean Brouwers Gary S. Brown Oleg Broytmann Dave Brueck diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 4d06318..eb57666 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -1226,7 +1226,7 @@ dict_fromkeys(PyObject *cls, PyObject *args) PyObject *key; long hash; - if (dictresize(mp, PySet_GET_SIZE(seq))) + if (dictresize(mp, Py_SIZE(seq))) return NULL; while (_PyDict_Next(seq, &pos, &key, &oldvalue, &hash)) { diff --git a/setup.py b/setup.py index c947bdc..d73e765 100644 --- a/setup.py +++ b/setup.py @@ -1136,6 +1136,17 @@ class PyBuildExt(build_ext): HAVE_BROKEN_SEM_UNLINK=1 ) libraries = [] + + elif platform in ('freebsd5', 'freebsd6', 'freebsd7', 'freebsd8'): + # FreeBSD's P1003.1b semaphore support is very experimental + # and has many known problems. (as of June 2008) + macros = dict( # FreeBSD + HAVE_SEM_OPEN=0, + HAVE_SEM_TIMEDWAIT=0, + HAVE_FD_TRANSFER=1, + ) + libraries = [] + else: # Linux and other unices macros = dict( HAVE_SEM_OPEN=1, -- cgit v0.12