Commit 5fb7c2ad authored by Christian Heimes's avatar Christian Heimes

Merged revisions 59565-59594 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r59568 | facundo.batista | 2007-12-19 13:53:01 +0100 (Wed, 19 Dec 2007) | 3 lines


  Some minor cleanups.  Thanks Mark Dickinson.
........
  r59573 | raymond.hettinger | 2007-12-19 19:13:31 +0100 (Wed, 19 Dec 2007) | 1 line

  Fix issue 1661: Flags argument silently ignored in re functions with compiled regexes.
........
  r59574 | guido.van.rossum | 2007-12-19 20:41:06 +0100 (Wed, 19 Dec 2007) | 7 lines

  Patch #1583 by Adam Olsen.

  This adds signal.set_wakeup_fd(fd) which sets a file descriptor to
  which a zero byte will be written whenever a C exception handler runs.

  I added a simple C API as well, PySignal_SetWakeupFd(fd).
........
  r59575 | raymond.hettinger | 2007-12-19 23:14:34 +0100 (Wed, 19 Dec 2007) | 1 line

  Bigger range for non-extended opargs.
........
  r59576 | guido.van.rossum | 2007-12-19 23:51:13 +0100 (Wed, 19 Dec 2007) | 5 lines

  Patch #1549 by Thomas Herve.
  This changes the rules for when __hash__ is inherited slightly,
  by allowing it to be inherited when one or more of __lt__, __le__,
  __gt__, __ge__ are overridden, as long as __eq__ and __ne__ aren't.
........
  r59577 | raymond.hettinger | 2007-12-20 02:25:05 +0100 (Thu, 20 Dec 2007) | 1 line

  Add comments
........
  r59578 | brett.cannon | 2007-12-20 11:09:52 +0100 (Thu, 20 Dec 2007) | 3 lines

  Add tests for the warnings module; specifically formatwarning and showwarning.
  Still need tests for warn_explicit and simplefilter.
........
  r59582 | guido.van.rossum | 2007-12-20 18:28:10 +0100 (Thu, 20 Dec 2007) | 2 lines

  Patch #1672 by Joseph Armbruster.  Use tempdir() to get a temporary directory.
........
  r59584 | georg.brandl | 2007-12-20 22:03:02 +0100 (Thu, 20 Dec 2007) | 2 lines

  Fix refleak introduced in r59576.
........
  r59586 | guido.van.rossum | 2007-12-21 00:48:28 +0100 (Fri, 21 Dec 2007) | 4 lines

  Improve performance of built-in any()/all() by avoiding PyIter_Next() --
  using a trick found in ifilter().
  Feel free to backport to 2.5.
........
  r59591 | andrew.kuchling | 2007-12-22 18:27:02 +0100 (Sat, 22 Dec 2007) | 1 line

  Add item
........
parent 81f11309
...@@ -355,6 +355,16 @@ in various ways. There is a separate error indicator for each thread. ...@@ -355,6 +355,16 @@ in various ways. There is a separate error indicator for each thread.
.. % thread.interrupt_main() (used from IDLE), so it's still needed. .. % thread.interrupt_main() (used from IDLE), so it's still needed.
.. cfunction:: int PySignal_SetWakeupFd(int fd)
This utility function specifies a file descriptor to which a ``'\0'`` byte will
be written whenever a signal is received. It returns the previous such file
descriptor. The value ``-1`` disables the feature; this is the initial state.
This is equivalent to :func:`signal.set_wakeup_fd` in Python, but without any
error checking. *fd* should be a valid file descriptor. The function should
only be called from the main thread.
.. cfunction:: PyObject* PyErr_NewException(char *name, PyObject *base, PyObject *dict) .. cfunction:: PyObject* PyErr_NewException(char *name, PyObject *base, PyObject *dict)
This utility function creates and returns a new exception object. The *name* This utility function creates and returns a new exception object. The *name*
......
...@@ -110,6 +110,20 @@ The :mod:`signal` module defines the following functions: ...@@ -110,6 +110,20 @@ The :mod:`signal` module defines the following functions:
:manpage:`signal(2)`.) :manpage:`signal(2)`.)
.. function:: set_wakeup_fd(fd)
Set the wakeup fd to *fd*. When a signal is received, a ``'\0'`` byte is
written to the fd. This can be used by a library to wakeup a poll or select
call, allowing the signal to be fully processed.
The old wakeup fd is returned. *fd* must be non-blocking. It is up to the
library to remove any bytes before calling poll or select again.
When threads are enabled, this function can only be called from the main thread;
attempting to call it from other threads will cause a :exc:`ValueError`
exception to be raised.
.. function:: signal(signalnum, handler) .. function:: signal(signalnum, handler)
Set the handler for signal *signalnum* to the function *handler*. *handler* can Set the handler for signal *signalnum* to the function *handler*. *handler* can
......
...@@ -147,15 +147,16 @@ for processing the documentation. ...@@ -147,15 +147,16 @@ for processing the documentation.
The input format is reStructured Text, The input format is reStructured Text,
a markup commonly used in the Python community that supports a markup commonly used in the Python community that supports
custom extensions and directives. Sphinx concentrates custom extensions and directives. Sphinx concentrates
on its HTML output, producing attractively styled on HTML output, producing attractively styled
and modern HTML. (XXX finish this -- mention new search feature) and modern HTML, but printed output is still supported through
conversion to LaTeX as an output format.
.. seealso:: .. seealso::
`Docutils <http://docutils.sf.net>`__: The fundamental `Docutils <http://docutils.sf.net>`__: The fundamental
reStructured Text parser and toolset. reStructured Text parser and toolset.
`Documenting Python <XXX>`__: Describes how to write for `Documenting Python <http://docs.python.org/dev/documenting/>`__: Describes how to write for
Python's documentation. Python's documentation.
...@@ -839,6 +840,27 @@ complete list of changes, or look through the CVS logs for all the details. ...@@ -839,6 +840,27 @@ complete list of changes, or look through the CVS logs for all the details.
* The :mod:`sets` module has been deprecated; it's better to * The :mod:`sets` module has been deprecated; it's better to
use the built-in :class:`set` and :class:`frozenset` types. use the built-in :class:`set` and :class:`frozenset` types.
* Integrating signal handling with GUI handling event loops
like those used by Tkinter or GTk+ has long been a problem; most
software ends up polling, waking up every fraction of a second. Thi
The :mod:`signal` module can now make this more efficient.
Calling ``signal.set_wakeup_fd(fd)`` sets a file descriptor
to be used; when a signal is received, a byte is written to that
file descriptor. There's also a C-level function,
:cfunc:`PySignal_SetWakeupFd`, for setting the descriptor.
Event loops will use this by opening a pipe to create two descriptors,
one for reading and one for writing. The writeable descriptor
will be passed to :func:`set_wakeup_fd`, and the readable descriptor
will be added to the list of descriptors monitored by the event loop via
:cfunc:`select` or :cfunc:`poll`.
On receiving a signal, a byte will be written and the main event loop
will be woken up, without the need to poll.
Contributed by Adam Olsen.
.. % Patch 1583
* The :mod:`smtplib` module now supports SMTP over SSL thanks to the * The :mod:`smtplib` module now supports SMTP over SSL thanks to the
addition of the :class:`SMTP_SSL` class. This class supports an addition of the :class:`SMTP_SSL` class. This class supports an
interface identical to the existing :class:`SMTP` class. Both interface identical to the existing :class:`SMTP` class. Both
......
...@@ -227,6 +227,9 @@ PyAPI_FUNC(int) PyErr_WarnExplicit(PyObject *, const char *, ...@@ -227,6 +227,9 @@ PyAPI_FUNC(int) PyErr_WarnExplicit(PyObject *, const char *,
PyAPI_FUNC(int) PyErr_CheckSignals(void); PyAPI_FUNC(int) PyErr_CheckSignals(void);
PyAPI_FUNC(void) PyErr_SetInterrupt(void); PyAPI_FUNC(void) PyErr_SetInterrupt(void);
/* In signalmodule.c */
int PySignal_SetWakeupFd(int fd);
/* Support for adding program text to SyntaxErrors */ /* Support for adding program text to SyntaxErrors */
PyAPI_FUNC(void) PyErr_SyntaxLocation(const char *, int); PyAPI_FUNC(void) PyErr_SyntaxLocation(const char *, int);
PyAPI_FUNC(PyObject *) PyErr_ProgramText(const char *, int); PyAPI_FUNC(PyObject *) PyErr_ProgramText(const char *, int);
......
...@@ -184,7 +184,6 @@ class Clamped(DecimalException): ...@@ -184,7 +184,6 @@ class Clamped(DecimalException):
number of zero digits are appended to the coefficient ("fold-down"). number of zero digits are appended to the coefficient ("fold-down").
""" """
class InvalidOperation(DecimalException): class InvalidOperation(DecimalException):
"""An invalid operation was performed. """An invalid operation was performed.
...@@ -210,14 +209,10 @@ class InvalidOperation(DecimalException): ...@@ -210,14 +209,10 @@ class InvalidOperation(DecimalException):
""" """
def handle(self, context, *args): def handle(self, context, *args):
if args: if args:
if args[0] == 1: # sNaN, must drop 's' but keep diagnostics ans = _dec_from_triple(args[0]._sign, args[0]._int, 'n', True)
ans = _dec_from_triple(args[1]._sign, args[1]._int, 'n', True)
return ans._fix_nan(context) return ans._fix_nan(context)
elif args[0] == 2:
return _dec_from_triple(args[1], args[2], 'n', True)
return NaN return NaN
class ConversionSyntax(InvalidOperation): class ConversionSyntax(InvalidOperation):
"""Trying to convert badly formed string. """Trying to convert badly formed string.
...@@ -277,7 +272,6 @@ class Inexact(DecimalException): ...@@ -277,7 +272,6 @@ class Inexact(DecimalException):
The inexact signal may be tested (or trapped) to determine if a given The inexact signal may be tested (or trapped) to determine if a given
operation (or sequence of operations) was inexact. operation (or sequence of operations) was inexact.
""" """
pass
class InvalidContext(InvalidOperation): class InvalidContext(InvalidOperation):
"""Invalid context. Unknown rounding, for example. """Invalid context. Unknown rounding, for example.
...@@ -304,7 +298,6 @@ class Rounded(DecimalException): ...@@ -304,7 +298,6 @@ class Rounded(DecimalException):
The rounded signal may be tested (or trapped) to determine if a given The rounded signal may be tested (or trapped) to determine if a given
operation (or sequence of operations) caused a loss of precision. operation (or sequence of operations) caused a loss of precision.
""" """
pass
class Subnormal(DecimalException): class Subnormal(DecimalException):
"""Exponent < Emin before rounding. """Exponent < Emin before rounding.
...@@ -316,7 +309,6 @@ class Subnormal(DecimalException): ...@@ -316,7 +309,6 @@ class Subnormal(DecimalException):
The subnormal signal may be tested (or trapped) to determine if a given The subnormal signal may be tested (or trapped) to determine if a given
or operation (or sequence of operations) yielded a subnormal result. or operation (or sequence of operations) yielded a subnormal result.
""" """
pass
class Overflow(Inexact, Rounded): class Overflow(Inexact, Rounded):
"""Numerical overflow. """Numerical overflow.
...@@ -662,7 +654,7 @@ class Decimal(_numbers.Real, _numbers.Inexact): ...@@ -662,7 +654,7 @@ class Decimal(_numbers.Real, _numbers.Inexact):
"""Returns whether the number is not actually one. """Returns whether the number is not actually one.
0 if a number 0 if a number
1 if NaN (it could be a normal quiet NaN or a phantom one) 1 if NaN
2 if sNaN 2 if sNaN
""" """
if self._is_special: if self._is_special:
...@@ -708,10 +700,10 @@ class Decimal(_numbers.Real, _numbers.Inexact): ...@@ -708,10 +700,10 @@ class Decimal(_numbers.Real, _numbers.Inexact):
if self_is_nan == 2: if self_is_nan == 2:
return context._raise_error(InvalidOperation, 'sNaN', return context._raise_error(InvalidOperation, 'sNaN',
1, self) self)
if other_is_nan == 2: if other_is_nan == 2:
return context._raise_error(InvalidOperation, 'sNaN', return context._raise_error(InvalidOperation, 'sNaN',
1, other) other)
if self_is_nan: if self_is_nan:
return self._fix_nan(context) return self._fix_nan(context)
...@@ -922,7 +914,7 @@ class Decimal(_numbers.Real, _numbers.Inexact): ...@@ -922,7 +914,7 @@ class Decimal(_numbers.Real, _numbers.Inexact):
if not self: if not self:
# -Decimal('0') is Decimal('0'), not Decimal('-0') # -Decimal('0') is Decimal('0'), not Decimal('-0')
ans = self.copy_sign(Dec_0) ans = self.copy_abs()
else: else:
ans = self.copy_negate() ans = self.copy_negate()
...@@ -942,7 +934,7 @@ class Decimal(_numbers.Real, _numbers.Inexact): ...@@ -942,7 +934,7 @@ class Decimal(_numbers.Real, _numbers.Inexact):
if not self: if not self:
# + (-0) = 0 # + (-0) = 0
ans = self.copy_sign(Dec_0) ans = self.copy_abs()
else: else:
ans = Decimal(self) ans = Decimal(self)
...@@ -1465,9 +1457,6 @@ class Decimal(_numbers.Real, _numbers.Inexact): ...@@ -1465,9 +1457,6 @@ class Decimal(_numbers.Real, _numbers.Inexact):
context - context used. context - context used.
""" """
if context is None:
context = getcontext()
if self._is_special: if self._is_special:
if self._isnan(): if self._isnan():
# decapitate payload if necessary # decapitate payload if necessary
...@@ -1631,11 +1620,9 @@ class Decimal(_numbers.Real, _numbers.Inexact): ...@@ -1631,11 +1620,9 @@ class Decimal(_numbers.Real, _numbers.Inexact):
if context is None: if context is None:
context = getcontext() context = getcontext()
if self._exp == 'N': if self._exp == 'N':
return context._raise_error(InvalidOperation, 'sNaN', return context._raise_error(InvalidOperation, 'sNaN', self)
1, self)
if other._exp == 'N': if other._exp == 'N':
return context._raise_error(InvalidOperation, 'sNaN', return context._raise_error(InvalidOperation, 'sNaN', other)
1, other)
if self._exp == 'n': if self._exp == 'n':
product = self product = self
elif other._exp == 'n': elif other._exp == 'n':
...@@ -1678,13 +1665,13 @@ class Decimal(_numbers.Real, _numbers.Inexact): ...@@ -1678,13 +1665,13 @@ class Decimal(_numbers.Real, _numbers.Inexact):
if self_is_nan or other_is_nan or modulo_is_nan: if self_is_nan or other_is_nan or modulo_is_nan:
if self_is_nan == 2: if self_is_nan == 2:
return context._raise_error(InvalidOperation, 'sNaN', return context._raise_error(InvalidOperation, 'sNaN',
1, self) self)
if other_is_nan == 2: if other_is_nan == 2:
return context._raise_error(InvalidOperation, 'sNaN', return context._raise_error(InvalidOperation, 'sNaN',
1, other) other)
if modulo_is_nan == 2: if modulo_is_nan == 2:
return context._raise_error(InvalidOperation, 'sNaN', return context._raise_error(InvalidOperation, 'sNaN',
1, modulo) modulo)
if self_is_nan: if self_is_nan:
return self._fix_nan(context) return self._fix_nan(context)
if other_is_nan: if other_is_nan:
...@@ -2555,16 +2542,16 @@ class Decimal(_numbers.Real, _numbers.Inexact): ...@@ -2555,16 +2542,16 @@ class Decimal(_numbers.Real, _numbers.Inexact):
other_is_nan = other._isnan() other_is_nan = other._isnan()
if self_is_nan == 2: if self_is_nan == 2:
return context._raise_error(InvalidOperation, 'sNaN', return context._raise_error(InvalidOperation, 'sNaN',
1, self) self)
if other_is_nan == 2: if other_is_nan == 2:
return context._raise_error(InvalidOperation, 'sNaN', return context._raise_error(InvalidOperation, 'sNaN',
1, other) other)
if self_is_nan: if self_is_nan:
return context._raise_error(InvalidOperation, 'NaN in compare_signal', return context._raise_error(InvalidOperation, 'NaN in compare_signal',
1, self) self)
if other_is_nan: if other_is_nan:
return context._raise_error(InvalidOperation, 'NaN in compare_signal', return context._raise_error(InvalidOperation, 'NaN in compare_signal',
1, other) other)
return self.compare(other, context=context) return self.compare(other, context=context)
def compare_total(self, other): def compare_total(self, other):
...@@ -3208,8 +3195,8 @@ class Decimal(_numbers.Real, _numbers.Inexact): ...@@ -3208,8 +3195,8 @@ class Decimal(_numbers.Real, _numbers.Inexact):
"""Returns an indication of the class of self. """Returns an indication of the class of self.
The class is one of the following strings: The class is one of the following strings:
-sNaN sNaN
-NaN NaN
-Infinity -Infinity
-Normal -Normal
-Subnormal -Subnormal
...@@ -5173,8 +5160,6 @@ NaN = Decimal('NaN') ...@@ -5173,8 +5160,6 @@ NaN = Decimal('NaN')
Dec_0 = Decimal(0) Dec_0 = Decimal(0)
Dec_p1 = Decimal(1) Dec_p1 = Decimal(1)
Dec_n1 = Decimal(-1) Dec_n1 = Decimal(-1)
Dec_p2 = Decimal(2)
Dec_n2 = Decimal(-2)
# Infsign[sign] is infinity w/ that sign # Infsign[sign] is infinity w/ that sign
Infsign = (Inf, negInf) Infsign = (Inf, negInf)
......
...@@ -224,6 +224,8 @@ def _compile(*key): ...@@ -224,6 +224,8 @@ def _compile(*key):
return p return p
pattern, flags = key pattern, flags = key
if isinstance(pattern, _pattern_type): if isinstance(pattern, _pattern_type):
if flags:
raise ValueError('Cannot process flags argument with a compiled pattern')
return pattern return pattern
if not sre_compile.isstring(pattern): if not sre_compile.isstring(pattern):
raise TypeError("first argument must be string or compiled pattern") raise TypeError("first argument must be string or compiled pattern")
......
...@@ -111,6 +111,14 @@ class ReTests(unittest.TestCase): ...@@ -111,6 +111,14 @@ class ReTests(unittest.TestCase):
# self.assertEqual(z, y) # self.assertEqual(z, y)
# self.assertEqual(type(z), type(y)) # self.assertEqual(type(z), type(y))
def test_bug_1661(self):
# Verify that flags do not get silently ignored with compiled patterns
pattern = re.compile('.')
self.assertRaises(ValueError, re.match, pattern, 'A', re.I)
self.assertRaises(ValueError, re.search, pattern, 'A', re.I)
self.assertRaises(ValueError, re.findall, pattern, 'A', re.I)
self.assertRaises(ValueError, re.compile, pattern, re.I)
def test_sub_template_numeric_escape(self): def test_sub_template_numeric_escape(self):
# bug 776311 and friends # bug 776311 and friends
self.assertEqual(re.sub('x', r'\0', 'x'), '\0') self.assertEqual(re.sub('x', r'\0', 'x'), '\0')
......
...@@ -85,6 +85,35 @@ class Vector: ...@@ -85,6 +85,35 @@ class Vector:
raise ValueError("Cannot compare vectors of different length") raise ValueError("Cannot compare vectors of different length")
return other return other
class SimpleOrder(object):
"""
A simple class that defines order but not full comparison.
"""
def __init__(self, value):
self.value = value
def __lt__(self, other):
if not isinstance(other, SimpleOrder):
return True
return self.value < other.value
def __gt__(self, other):
if not isinstance(other, SimpleOrder):
return False
return self.value > other.value
class DumbEqualityWithoutHash(object):
"""
A class that define __eq__, but no __hash__: it shouldn't be hashable.
"""
def __eq__(self, other):
return False
opmap = { opmap = {
"lt": (lambda a,b: a< b, operator.lt, operator.__lt__), "lt": (lambda a,b: a< b, operator.lt, operator.__lt__),
"le": (lambda a,b: a<=b, operator.le, operator.__le__), "le": (lambda a,b: a<=b, operator.le, operator.__le__),
...@@ -330,8 +359,39 @@ class ListTest(unittest.TestCase): ...@@ -330,8 +359,39 @@ class ListTest(unittest.TestCase):
for op in opmap["lt"]: for op in opmap["lt"]:
self.assertIs(op(x, y), True) self.assertIs(op(x, y), True)
class HashableTest(unittest.TestCase):
"""
Test hashability of classes with rich operators defined.
"""
def test_simpleOrderHashable(self):
"""
A class that only defines __gt__ and/or __lt__ should be hashable.
"""
a = SimpleOrder(1)
b = SimpleOrder(2)
self.assert_(a < b)
self.assert_(b > a)
self.assert_(a.__hash__ is not None)
def test_notHashableException(self):
"""
If a class is not hashable, it should raise a TypeError with an
understandable message.
"""
a = DumbEqualityWithoutHash()
try:
hash(a)
except TypeError as e:
self.assertEquals(str(e),
"unhashable type: 'DumbEqualityWithoutHash'")
else:
raise test_support.TestFailed("Should not be here")
def test_main(): def test_main():
test_support.run_unittest(VectorTest, NumberTest, MiscTest, DictTest, ListTest) test_support.run_unittest(VectorTest, NumberTest, MiscTest, DictTest, ListTest, HashableTest)
if __name__ == "__main__": if __name__ == "__main__":
test_main() test_main()
...@@ -166,12 +166,59 @@ class BasicSignalTests(unittest.TestCase): ...@@ -166,12 +166,59 @@ class BasicSignalTests(unittest.TestCase):
self.assertRaises(TypeError, signal.signal, self.assertRaises(TypeError, signal.signal,
signal.SIGUSR1, None) signal.SIGUSR1, None)
class WakeupSignalTests(unittest.TestCase):
TIMEOUT_FULL = 10
TIMEOUT_HALF = 5
def test_wakeup_fd_early(self):
import select
signal.alarm(1)
before_time = time.time()
# We attempt to get a signal during the sleep,
# before select is called
time.sleep(self.TIMEOUT_FULL)
mid_time = time.time()
self.assert_(mid_time - before_time < self.TIMEOUT_HALF)
select.select([self.read], [], [], self.TIMEOUT_FULL)
after_time = time.time()
self.assert_(after_time - mid_time < self.TIMEOUT_HALF)
def test_wakeup_fd_during(self):
import select
signal.alarm(1)
before_time = time.time()
# We attempt to get a signal during the select call
self.assertRaises(select.error, select.select,
[self.read], [], [], self.TIMEOUT_FULL)
after_time = time.time()
self.assert_(after_time - before_time < self.TIMEOUT_HALF)
def setUp(self):
import fcntl
self.alrm = signal.signal(signal.SIGALRM, lambda x,y:None)
self.read, self.write = os.pipe()
flags = fcntl.fcntl(self.write, fcntl.F_GETFL, 0)
flags = flags | os.O_NONBLOCK
fcntl.fcntl(self.write, fcntl.F_SETFL, flags)
self.old_wakeup = signal.set_wakeup_fd(self.write)
def tearDown(self):
signal.set_wakeup_fd(self.old_wakeup)
os.close(self.read)
os.close(self.write)
signal.signal(signal.SIGALRM, self.alrm)
def test_main(): def test_main():
if sys.platform[:3] in ('win', 'os2'): if sys.platform[:3] in ('win', 'os2'):
raise test_support.TestSkipped("Can't test signal on %s" % \ raise test_support.TestSkipped("Can't test signal on %s" % \
sys.platform) sys.platform)
test_support.run_unittest(BasicSignalTests, InterProcessSignalTests) test_support.run_unittest(BasicSignalTests, InterProcessSignalTests,
WakeupSignalTests)
if __name__ == "__main__": if __name__ == "__main__":
......
...@@ -242,7 +242,7 @@ class ProcessTestCase(unittest.TestCase): ...@@ -242,7 +242,7 @@ class ProcessTestCase(unittest.TestCase):
self.assertEquals(rc, 2) self.assertEquals(rc, 2)
def test_cwd(self): def test_cwd(self):
tmpdir = os.getenv("TEMP", "/tmp") tmpdir = tempfile.gettempdir()
# We cannot use os.path.realpath to canonicalize the path, # We cannot use os.path.realpath to canonicalize the path,
# since it doesn't expand Tru64 {memb} strings. See bug 1063571. # since it doesn't expand Tru64 {memb} strings. See bug 1063571.
cwd = os.getcwd() cwd = os.getcwd()
......
import warnings import warnings
import linecache
import os import os
from io import StringIO
import sys import sys
import unittest import unittest
from test import test_support from test import test_support
...@@ -36,6 +38,8 @@ class TestModule(unittest.TestCase): ...@@ -36,6 +38,8 @@ class TestModule(unittest.TestCase):
self.assert_(w.category is category) self.assert_(w.category is category)
def test_filtering(self): def test_filtering(self):
# Test filterwarnings().
# Implicitly also tests resetwarnings().
with test_support.catch_warning() as w: with test_support.catch_warning() as w:
warnings.filterwarnings("error", "", Warning, "", 0) warnings.filterwarnings("error", "", Warning, "", 0)
self.assertRaises(UserWarning, warnings.warn, 'convert to error') self.assertRaises(UserWarning, warnings.warn, 'convert to error')
...@@ -97,6 +101,33 @@ class TestModule(unittest.TestCase): ...@@ -97,6 +101,33 @@ class TestModule(unittest.TestCase):
self.assertEqual(os.path.basename(w.filename), "sys") self.assertEqual(os.path.basename(w.filename), "sys")
class WarningsDisplayTests(unittest.TestCase):
def test_formatwarning(self):
message = "msg"
category = Warning
file_name = os.path.splitext(warning_tests.__file__)[0] + '.py'
line_num = 3
file_line = linecache.getline(file_name, line_num).strip()
expect = "%s:%s: %s: %s\n %s\n" % (file_name, line_num, category.__name__,
message, file_line)
self.failUnlessEqual(warnings.formatwarning(message, category,
file_name, line_num),
expect)
def test_showwarning(self):
file_name = os.path.splitext(warning_tests.__file__)[0] + '.py'
line_num = 3
expected_file_line = linecache.getline(file_name, line_num).strip()
message = 'msg'
category = Warning
file_object = StringIO()
expect = warnings.formatwarning(message, category, file_name, line_num)
warnings.showwarning(message, category, file_name, line_num,
file_object)
self.failUnlessEqual(file_object.getvalue(), expect)
def test_main(verbose=None): def test_main(verbose=None):
# Obscure hack so that this test passes after reloads or repeated calls # Obscure hack so that this test passes after reloads or repeated calls
# to test_main (regrtest -R). # to test_main (regrtest -R).
...@@ -106,7 +137,7 @@ def test_main(verbose=None): ...@@ -106,7 +137,7 @@ def test_main(verbose=None):
del warning_tests.__warningregistry__ del warning_tests.__warningregistry__
if hasattr(sys, '__warningregistry__'): if hasattr(sys, '__warningregistry__'):
del sys.__warningregistry__ del sys.__warningregistry__
test_support.run_unittest(TestModule) test_support.run_unittest(TestModule, WarningsDisplayTests)
if __name__ == "__main__": if __name__ == "__main__":
test_main(verbose=True) test_main(verbose=True)
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
#include <signal.h> #include <signal.h>
#include <sys/stat.h>
#ifndef SIG_ERR #ifndef SIG_ERR
#define SIG_ERR ((PyOS_sighandler_t)(-1)) #define SIG_ERR ((PyOS_sighandler_t)(-1))
#endif #endif
...@@ -75,6 +77,8 @@ static struct { ...@@ -75,6 +77,8 @@ static struct {
PyObject *func; PyObject *func;
} Handlers[NSIG]; } Handlers[NSIG];
static sig_atomic_t wakeup_fd = -1;
/* Speed up sigcheck() when none tripped */ /* Speed up sigcheck() when none tripped */
static volatile sig_atomic_t is_tripped = 0; static volatile sig_atomic_t is_tripped = 0;
...@@ -128,6 +132,8 @@ signal_handler(int sig_num) ...@@ -128,6 +132,8 @@ signal_handler(int sig_num)
cleared in PyErr_CheckSignals() before .tripped. */ cleared in PyErr_CheckSignals() before .tripped. */
is_tripped = 1; is_tripped = 1;
Py_AddPendingCall(checksignals_witharg, NULL); Py_AddPendingCall(checksignals_witharg, NULL);
if (wakeup_fd != -1)
write(wakeup_fd, "\0", 1);
#ifdef WITH_THREAD #ifdef WITH_THREAD
} }
#endif #endif
...@@ -267,6 +273,50 @@ None -- if an unknown handler is in effect\n\ ...@@ -267,6 +273,50 @@ None -- if an unknown handler is in effect\n\
anything else -- the callable Python object used as a handler"); anything else -- the callable Python object used as a handler");
static PyObject *
signal_set_wakeup_fd(PyObject *self, PyObject *args)
{
struct stat buf;
int fd, old_fd;
if (!PyArg_ParseTuple(args, "i:set_wakeup_fd", &fd))
return NULL;
#ifdef WITH_THREAD
if (PyThread_get_thread_ident() != main_thread) {
PyErr_SetString(PyExc_ValueError,
"set_wakeup_fd only works in main thread");
return NULL;
}
#endif
if (fd != -1 && fstat(fd, &buf) != 0) {
PyErr_SetString(PyExc_ValueError, "invalid fd");
return NULL;
}
old_fd = wakeup_fd;
wakeup_fd = fd;
return PyLong_FromLong(old_fd);
}
PyDoc_STRVAR(set_wakeup_fd_doc,
"set_wakeup_fd(fd) -> fd\n\
\n\
Sets the fd to be written to (with '\\0') when a signal\n\
comes in. A library can use this to wakeup select or poll.\n\
The previous fd is returned.\n\
\n\
The fd must be non-blocking.");
/* C API for the same, without all the error checking */
int
PySignal_SetWakeupFd(int fd)
{
int old_fd = wakeup_fd;
if (fd < 0)
fd = -1;
wakeup_fd = fd;
return old_fd;
}
/* List of functions defined in the module */ /* List of functions defined in the module */
static PyMethodDef signal_methods[] = { static PyMethodDef signal_methods[] = {
#ifdef HAVE_ALARM #ifdef HAVE_ALARM
...@@ -274,6 +324,7 @@ static PyMethodDef signal_methods[] = { ...@@ -274,6 +324,7 @@ static PyMethodDef signal_methods[] = {
#endif #endif
{"signal", signal_signal, METH_VARARGS, signal_doc}, {"signal", signal_signal, METH_VARARGS, signal_doc},
{"getsignal", signal_getsignal, METH_VARARGS, getsignal_doc}, {"getsignal", signal_getsignal, METH_VARARGS, getsignal_doc},
{"set_wakeup_fd", signal_set_wakeup_fd, METH_VARARGS, set_wakeup_fd_doc},
#ifdef HAVE_PAUSE #ifdef HAVE_PAUSE
{"pause", (PyCFunction)signal_pause, {"pause", (PyCFunction)signal_pause,
METH_NOARGS,pause_doc}, METH_NOARGS,pause_doc},
......
...@@ -184,13 +184,19 @@ static PyObject * ...@@ -184,13 +184,19 @@ static PyObject *
builtin_all(PyObject *self, PyObject *v) builtin_all(PyObject *self, PyObject *v)
{ {
PyObject *it, *item; PyObject *it, *item;
PyObject *(*iternext)(PyObject *);
int cmp;
it = PyObject_GetIter(v); it = PyObject_GetIter(v);
if (it == NULL) if (it == NULL)
return NULL; return NULL;
iternext = *Py_TYPE(it)->tp_iternext;
while ((item = PyIter_Next(it)) != NULL) { for (;;) {
int cmp = PyObject_IsTrue(item); item = iternext(it);
if (item == NULL)
break;
cmp = PyObject_IsTrue(item);
Py_DECREF(item); Py_DECREF(item);
if (cmp < 0) { if (cmp < 0) {
Py_DECREF(it); Py_DECREF(it);
...@@ -202,8 +208,12 @@ builtin_all(PyObject *self, PyObject *v) ...@@ -202,8 +208,12 @@ builtin_all(PyObject *self, PyObject *v)
} }
} }
Py_DECREF(it); Py_DECREF(it);
if (PyErr_Occurred()) if (PyErr_Occurred()) {
if (PyErr_ExceptionMatches(PyExc_StopIteration))
PyErr_Clear();
else
return NULL; return NULL;
}
Py_RETURN_TRUE; Py_RETURN_TRUE;
} }
...@@ -216,13 +226,19 @@ static PyObject * ...@@ -216,13 +226,19 @@ static PyObject *
builtin_any(PyObject *self, PyObject *v) builtin_any(PyObject *self, PyObject *v)
{ {
PyObject *it, *item; PyObject *it, *item;
PyObject *(*iternext)(PyObject *);
int cmp;
it = PyObject_GetIter(v); it = PyObject_GetIter(v);
if (it == NULL) if (it == NULL)
return NULL; return NULL;
iternext = *Py_TYPE(it)->tp_iternext;
while ((item = PyIter_Next(it)) != NULL) { for (;;) {
int cmp = PyObject_IsTrue(item); item = iternext(it);
if (item == NULL)
break;
cmp = PyObject_IsTrue(item);
Py_DECREF(item); Py_DECREF(item);
if (cmp < 0) { if (cmp < 0) {
Py_DECREF(it); Py_DECREF(it);
...@@ -234,8 +250,12 @@ builtin_any(PyObject *self, PyObject *v) ...@@ -234,8 +250,12 @@ builtin_any(PyObject *self, PyObject *v)
} }
} }
Py_DECREF(it); Py_DECREF(it);
if (PyErr_Occurred()) if (PyErr_Occurred()) {
if (PyErr_ExceptionMatches(PyExc_StopIteration))
PyErr_Clear();
else
return NULL; return NULL;
}
Py_RETURN_FALSE; Py_RETURN_FALSE;
} }
......
...@@ -3172,7 +3172,7 @@ compiler_visit_expr(struct compiler *c, expr_ty e) ...@@ -3172,7 +3172,7 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
return compiler_ifexp(c, e); return compiler_ifexp(c, e);
case Dict_kind: case Dict_kind:
n = asdl_seq_LEN(e->v.Dict.values); n = asdl_seq_LEN(e->v.Dict.values);
ADDOP_I(c, BUILD_MAP, (n>255 ? 255 : n)); ADDOP_I(c, BUILD_MAP, (n>0xFFFF ? 0xFFFF : n));
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
VISIT(c, expr, VISIT(c, expr,
(expr_ty)asdl_seq_GET(e->v.Dict.values, i)); (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
...@@ -3648,10 +3648,10 @@ static int ...@@ -3648,10 +3648,10 @@ static int
instrsize(struct instr *instr) instrsize(struct instr *instr)
{ {
if (!instr->i_hasarg) if (!instr->i_hasarg)
return 1; return 1; /* 1 byte for the opcode*/
if (instr->i_oparg > 0xffff) if (instr->i_oparg > 0xffff)
return 6; return 6; /* 1 (opcode) + 1 (EXTENDED_ARG opcode) + 2 (oparg) + 2(oparg extended) */
return 3; return 3; /* 1 (opcode) + 2 (oparg) */
} }
static int static int
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment