Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from

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

........
  r62386 | christian.heimes | 2008-04-19 04:23:57 +0200 (Sat, 19 Apr 2008) | 2 lines

  Added kill, terminate and send_signal to subprocess.Popen
  The bits and pieces for the Windows side were already in place. The POSIX side is trivial (as usual) and uses os.kill().
........
  r62387 | georg.brandl | 2008-04-19 10:23:59 +0200 (Sat, 19 Apr 2008) | 2 lines

  Fix-up docs for revision 62386.
........
  r62389 | georg.brandl | 2008-04-19 18:57:43 +0200 (Sat, 19 Apr 2008) | 2 lines

  #2369: clarify that copyfile() doesn't take a target directory.
........
  r62390 | georg.brandl | 2008-04-19 18:58:28 +0200 (Sat, 19 Apr 2008) | 2 lines

  #2634: clarify meaning of env parameter to spawn/exec*e.
........
  r62391 | georg.brandl | 2008-04-19 18:58:49 +0200 (Sat, 19 Apr 2008) | 2 lines

  #2633: clarify meaning of env parameter.
........
  r62392 | georg.brandl | 2008-04-19 18:59:16 +0200 (Sat, 19 Apr 2008) | 2 lines

  #2631: clarify IMPORT_NAME semantics.
........
  r62393 | georg.brandl | 2008-04-19 19:00:14 +0200 (Sat, 19 Apr 2008) | 2 lines

  :func: et al. should *not* include the parens.
........
  r62396 | mark.dickinson | 2008-04-19 20:51:48 +0200 (Sat, 19 Apr 2008) | 5 lines

  Additional tests for math.pow, and extra special-case
  handling code in math.pow, in the hope of making all
  tests pass on the alpha Tru64 buildbot.
........
  r62400 | mark.dickinson | 2008-04-19 21:41:52 +0200 (Sat, 19 Apr 2008) | 3 lines

  Additional special-case handling for math.pow.
  Windows/VS2008 doesn't like (-1)**(+-inf).
........
  r62401 | benjamin.peterson | 2008-04-19 21:47:34 +0200 (Sat, 19 Apr 2008) | 2 lines

  Complete documentation for errors argument of io's open and TextIOWrapper
........
  r62402 | mark.dickinson | 2008-04-19 22:31:16 +0200 (Sat, 19 Apr 2008) | 2 lines

  Document updates to math and cmath modules.
........
  r62407 | georg.brandl | 2008-04-19 23:28:38 +0200 (Sat, 19 Apr 2008) | 2 lines

  Update template for newest Sphinx.
........
  r62409 | mark.dickinson | 2008-04-19 23:35:35 +0200 (Sat, 19 Apr 2008) | 5 lines

  Correct documentation for math.pow;
  0**nan is nan, not 0.  (But nan**0 and 1**nan are 1.)

  Also fix minor typo: 'quite NaN' -> 'quiet NaN'
........
  r62410 | mark.dickinson | 2008-04-19 23:49:22 +0200 (Sat, 19 Apr 2008) | 4 lines

  Move asinh documentation to the proper place.
  Remove meaningless 'in radians' from inverse
  hyperbolic functions.
........
  r62412 | mark.dickinson | 2008-04-20 03:22:30 +0200 (Sun, 20 Apr 2008) | 5 lines

  Report additional diagnostic information in
  test_math, to help track down debian-alpha
  buildbot failure.
........
  r62413 | mark.dickinson | 2008-04-20 03:39:24 +0200 (Sun, 20 Apr 2008) | 3 lines

  FreeBSD doesn't follow C99 for modf(inf); so add explicit
  special-value handling to math.modf code.
........
  r62414 | mark.dickinson | 2008-04-20 06:13:13 +0200 (Sun, 20 Apr 2008) | 5 lines

  Yet more explicit special case handling to make
  math.pow behave on alpha Tru64.  All IEEE 754
  special values are now handled directly; only
  the finite**finite case is handled by libm.
........
  r62418 | mark.dickinson | 2008-04-20 18:13:17 +0200 (Sun, 20 Apr 2008) | 7 lines

  Issue 2662: Initialize special value tables dynamically (i.e. when
  cmath module is loaded) instead of statically. This fixes compile-time
  problems on platforms where HUGE_VAL is an extern variable rather than
  a constant.

  Thanks Hirokazu Yamamoto for the patch.
........
  r62419 | andrew.kuchling | 2008-04-20 18:54:02 +0200 (Sun, 20 Apr 2008) | 1 line

  Move description of math module changes; various edits to description of cmath changes
........
This commit is contained in:
Christian Heimes 2008-04-20 21:01:16 +00:00
parent 58f9e4f347
commit a342c013fc
15 changed files with 585 additions and 210 deletions

View File

@ -75,9 +75,6 @@ html_last_updated_fmt = '%b %d, %Y'
# typographically correct entities.
html_use_smartypants = True
# Content template for the index page, filename relative to this file.
html_index = 'indexcontent.html'
# Custom sidebar templates, filenames relative to this file.
html_sidebars = {
'index': 'indexsidebar.html',
@ -86,6 +83,7 @@ html_sidebars = {
# Additional templates that should be rendered to pages.
html_additional_pages = {
'download': 'download.html',
'index': 'indexcontent.html',
}
# Output file base name for HTML help builder.

View File

@ -319,8 +319,8 @@ a matching identifier is found:
.. describe:: func
The name of a Python function; dotted names may be used. The role text
should include trailing parentheses to enhance readability. The parentheses
are stripped when searching for identifiers.
should not include trailing parentheses to enhance readability. The
parentheses are stripped when searching for identifiers.
.. describe:: data
@ -338,7 +338,7 @@ a matching identifier is found:
.. describe:: meth
The name of a method of an object. The role text should include the type
name, method name and the trailing parentheses. A dotted name may be used.
name and the method name. A dotted name may be used.
.. describe:: attr

View File

@ -528,9 +528,11 @@ the more significant byte last.
.. opcode:: IMPORT_NAME (namei)
Imports the module ``co_names[namei]``. The module object is pushed onto the
stack. The current namespace is not affected: for a proper import statement, a
subsequent ``STORE_FAST`` instruction modifies the namespace.
Imports the module ``co_names[namei]``. TOS and TOS1 are popped and provide
the *fromlist* and *level* arguments of :func:`__import__`. The module
object is pushed onto the stack. The current namespace is not affected:
for a proper import statement, a subsequent ``STORE_FAST`` instruction
modifies the namespace.
.. opcode:: IMPORT_FROM (namei)

View File

@ -101,13 +101,15 @@ Module Interface
:mod:`codecs` module for the list of supported encodings.
*errors* is an optional string that specifies how encoding and decoding
errors are to be handled---this argument should not be used in binary mode.
Pass ``'strict'`` to raise a :exc:`ValueError` exception if there is an
encoding error (the default of ``None`` has the same effect), or pass
``'ignore'`` to ignore errors. (Note that ignoring encoding errors can lead
to data loss.) ``'replace'`` causes a replacement marker (such as ``'?'``)
to be inserted where there is malformed data. For all possible values, see
:func:`codecs.register`.
errors are to be handled. Pass ``'strict'`` to raise a :exc:`ValueError`
exception if there is an encoding error (the default of ``None`` has the same
effect), or pass ``'ignore'`` to ignore errors. (Note that ignoring encoding
errors can lead to data loss.) ``'replace'`` causes a replacement marker
(such as ``'?'``) to be inserted where there is malformed data. When
writing, ``'xmlcharrefreplace'`` (replace with the appropriate XML character
reference) or ``'backslashreplace'`` (replace with backslashed escape
sequences) can be used. Any other error handling name that has been
registered with :func:`codecs.register_error` is also valid.
*newline* controls how universal newlines works (it only applies to text
mode). It can be ``None``, ``''``, ``'\n'``, ``'\r'``, and ``'\r\n'``. It
@ -581,8 +583,11 @@ Text I/O
exception if there is an encoding error (the default of ``None`` has the same
effect), or pass ``'ignore'`` to ignore errors. (Note that ignoring encoding
errors can lead to data loss.) ``'replace'`` causes a replacement marker
(such as ``'?'``) to be inserted where there is malformed data. For all
possible values see :func:`codecs.register`.
(such as ``'?'``) to be inserted where there is malformed data. When
writing, ``'xmlcharrefreplace'`` (replace with the appropriate XML character
reference) or ``'backslashreplace'`` (replace with backslashed escape
sequences) can be used. Any other error handling name that has been
registered with :func:`codecs.register_error` is also valid.
*newline* can be ``None``, ``''``, ``'\n'``, ``'\r'``, or ``'\r\n'``. It
controls the handling of line endings. If it is ``None``, universal newlines

View File

@ -143,11 +143,15 @@ Power and logarithmic functions:
.. function:: pow(x, y)
Return ``x**y``. ``1.0**y`` returns *1.0*, even for ``1.0**nan``. ``0**y``
returns *0.* for all positive *y*, *0* and *NAN*.
Return ``x`` raised to the power ``y``. Exceptional cases follow
Annex 'F' of the C99 standard as far as possible. In particular,
``pow(1.0, x)`` and ``pow(x, 0.0)`` always return ``1.0``, even
when ``x`` is a zero or a NaN. If both ``x`` and ``y`` are finite,
``x`` is negative, and ``y`` is not an integer then ``pow(x, y)``
is undefined, and raises :exc:`ValueError`.
.. versionchanged:: 2.6
The outcome of ``1**nan`` and ``0**nan`` was undefined.
The outcome of ``1**nan`` and ``nan**0`` was undefined.
.. function:: sqrt(x)
@ -198,13 +202,6 @@ Trigonometric functions:
Return the sine of *x* radians.
.. function:: asinh(x)
Return the inverse hyperbolic sine of *x*, in radians.
.. versionadded:: 2.6
.. function:: tan(x)
Return the tangent of *x* radians.
@ -224,18 +221,32 @@ Angular conversion:
Hyperbolic functions:
.. function:: acosh(x)
Return the inverse hyperbolic cosine of *x*.
.. versionadded:: 2.6
.. function:: asinh(x)
Return the inverse hyperbolic sine of *x*.
.. versionadded:: 2.6
.. function:: atanh(x)
Return the inverse hyperbolic tangent of *x*.
.. versionadded:: 2.6
.. function:: cosh(x)
Return the hyperbolic cosine of *x*.
.. function:: acosh(x)
Return the inverse hyperbolic cosine of *x*, in radians.
.. versionadded:: 2.6
.. function:: sinh(x)
Return the hyperbolic sine of *x*.
@ -246,12 +257,6 @@ Hyperbolic functions:
Return the hyperbolic tangent of *x*.
.. function:: atanh(x)
Return the inverse hyperbolic tangent of *x*, in radians.
.. versionadded:: 2.6
The module also defines two mathematical constants:
@ -279,7 +284,7 @@ The module also defines two mathematical constants:
:exc:`OverflowError` isn't defined, and in cases where ``math.log(0)`` raises
:exc:`OverflowError`, ``math.log(0L)`` may raise :exc:`ValueError` instead.
All functions return a quite *NaN* if at least one of the args is *NaN*.
All functions return a quiet *NaN* if at least one of the args is *NaN*.
Signaling *NaN*s raise an exception. The exception type still depends on the
platform and libm implementation. It's usually :exc:`ValueError` for *EDOM*
and :exc:`OverflowError` for errno *ERANGE*.

View File

@ -1254,7 +1254,8 @@ to be ignored.
For :func:`execle`, :func:`execlpe`, :func:`execve`, and :func:`execvpe` (note
that these all end in "e"), the *env* parameter must be a mapping which is
used to define the environment variables for the new process; the :func:`execl`,
used to define the environment variables for the new process (these are used
instead of the current process' environment); the functions :func:`execl`,
:func:`execlp`, :func:`execv`, and :func:`execvp` all cause the new process to
inherit the environment of the current process. Availability: Macintosh, Unix,
Windows.
@ -1484,7 +1485,8 @@ written in Python, such as a mail server's external command delivery program.
For :func:`spawnle`, :func:`spawnlpe`, :func:`spawnve`, and :func:`spawnvpe`
(note that these all end in "e"), the *env* parameter must be a mapping
which is used to define the environment variables for the new process; the
which is used to define the environment variables for the new process (they are
used instead of the current process' environment); the functions
:func:`spawnl`, :func:`spawnlp`, :func:`spawnv`, and :func:`spawnvp` all cause
the new process to inherit the environment of the current process.

View File

@ -28,15 +28,6 @@ copying and removal. For operations on individual files, see also the
are not copied.
.. function:: copyfile(src, dst)
Copy the contents (no metadata) of the file named *src* to a file named *dst*.
The destination location must be writable; otherwise, an :exc:`IOError` exception
will be raised. If *dst* already exists, it will be replaced. Special files
such as character or block devices and pipes cannot be copied with this
function. *src* and *dst* are path names given as strings.
.. function:: copyfileobj(fsrc, fdst[, length])
Copy the contents of the file-like object *fsrc* to the file-like object *fdst*.
@ -48,6 +39,17 @@ copying and removal. For operations on individual files, see also the
be copied.
.. function:: copyfile(src, dst)
Copy the contents (no metadata) of the file named *src* to a file named *dst*.
*dst* must be the complete target file name; look at :func:`copy` for a copy that
accepts a target directory path.
The destination location must be writable; otherwise, an :exc:`IOError` exception
will be raised. If *dst* already exists, it will be replaced. Special files
such as character or block devices and pipes cannot be copied with this
function. *src* and *dst* are path names given as strings.
.. function:: copymode(src, dst)
Copy the permission bits from *src* to *dst*. The file contents, owner, and

View File

@ -89,8 +89,9 @@ This module defines one class called :class:`Popen`:
searching the executable, so you can't specify the program's path relative to
*cwd*.
If *env* is not ``None``, it defines the environment variables for the new
process.
If *env* is not ``None``, it must be a mapping that defines the environment
variables for the new process; these are used instead of inheriting the current
process' environment, which is the default behavior.
If *universal_newlines* is :const:`True`, the file objects stdout and stderr are
opened as text files, but lines may be terminated by any of ``'\n'``, the Unix
@ -202,6 +203,35 @@ Instances of the :class:`Popen` class have the following methods:
size is large or unlimited.
.. method:: Popen.send_signal(signal)
Sends the signal *signal* to the child.
.. note::
On Windows only SIGTERM is supported so far. It's an alias for
:meth:`terminate`.
.. versionadded:: 2.6
.. method:: Popen.terminate()
Stop the child. On Posix OSs the method sends SIGTERM to the
child. On Windows the Win32 API function TerminateProcess is called
to stop the child.
.. versionadded:: 2.6
.. method:: Popen.kill()
Kills the child. On Posix OSs the function sends SIGKILL to the child.
On Windows :meth:`kill` is an alias for :meth:`terminate`.
.. versionadded:: 2.6
The following attributes are also available:
.. attribute:: Popen.stdin

View File

@ -1,3 +1,5 @@
{% extends "defindex.html" %}
{% block tables %}
<p><strong>Parts of the documentation:</strong></p>
<table class="contentstable" align="center"><tr>
<td width="50%">
@ -54,3 +56,4 @@
<p class="biglink"><a class="biglink" href="{{ pathto("copyright") }}">Copyright</a></p>
</td></tr>
</table>
{% endblock %}

View File

@ -1292,11 +1292,42 @@ Here are all of the changes that Python 2.6 makes to the core Python language.
:func:`isnan`, return true if their floating-point argument is
infinite or Not A Number. (:issue:`1640`)
The ``math.copysign(x, y)`` function
copies the sign bit of an IEEE 754 number, returning the absolute
value of *x* combined with the sign bit of *y*. For example,
``math.copysign(1, -0.0)`` returns -1.0. (Contributed by Christian
Heimes.)
* The :mod:`math` module has seven new functions, and the existing
functions have been improved to give more consistent behaviour
across platforms, especially with respect to handling of
floating-point exceptions and IEEE 754 special values.
The new functions are:
* :func:`isinf` and :func:`isnan` determine whether a given float is
a (positive or negative) infinity or a NaN (Not a Number),
respectively.
* ``copysign(x, y)`` copies the sign bit of an IEEE 754 number,
returning the absolute value of *x* combined with the sign bit of
*y*. For example, ``math.copysign(1, -0.0)`` returns -1.0.
(Contributed by Christian Heimes.)
* The inverse hyperbolic functions :func:`acosh`, :func:`asinh` and
:func:`atanh`.
* The function :func:`log1p`, returning the natural logarithm of
*1+x* (base *e*).
There's also a new :func:`trunc` function as a result of the
backport of `PEP 3141's type hierarchy for numbers <#pep-3141>`__.
The existing math functions have been modified to follow the
recommendations of the C99 standard with respect to special values
whenever possible. For example, ``sqrt(-1.)`` should now give a
:exc:`ValueError` across (nearly) all platforms, while
``sqrt(float('NaN'))`` should return a NaN on all IEEE 754
platforms. Where Annex 'F' of the C99 standard recommends signaling
'divide-by-zero' or 'invalid', Python will raise :exc:`ValueError`.
Where Annex 'F' of the C99 standard recommends signaling 'overflow',
Python will raise :exc:`OverflowError`. (See :issue:`711019`,
:issue:`1640`.)
(Contributed by Christian Heimes and Mark Dickinson.)
* Changes to the :class:`Exception` interface
as dictated by :pep:`352` continue to be made. For 2.6,
@ -1415,6 +1446,40 @@ complete list of changes, or look through the CVS logs for all the details.
available, instead of restricting itself to protocol 1.
(Contributed by W. Barnes; :issue:`1551443`.)
* The :mod:`cmath` module underwent an extensive set of revisions,
thanks to Mark Dickinson and Christian Heimes, that added some new
features and greatly improved the accuracy of the computations.
Five new functions were added:
* :func:`polar` converts a complex number to polar form, returning
the modulus and argument of that complex number.
* :func:`rect` does the opposite, turning a (modulus, argument) pair
back into the corresponding complex number.
* :func:`phase` returns the phase or argument of a complex number.
* :func:`isnan` returns True if either
the real or imaginary part of its argument is a NaN.
* :func:`isinf` returns True if either the real or imaginary part of
its argument is infinite.
The revisions also improved the numerical soundness of the
:mod:`cmath` module. For all functions, the real and imaginary
parts of the results are accurate to within a few units of least
precision (ulps) whenever possible. See :issue:`1381` for the
details. The branch cuts for :func:`asinh`, :func:`atanh`: and
:func:`atan` have also been corrected.
The tests for the module have been greatly expanded; nearly 2000 new
test cases exercise the algebraic functions.
On IEEE 754 platforms, the :mod:`cmath` module now handles IEEE 754
special values and floating-point exceptions in a manner consistent
with Annex 'G' of the C99 standard.
* A new data type in the :mod:`collections` module: :class:`namedtuple(typename,
fieldnames)` is a factory function that creates subclasses of the standard tuple
whose fields are accessible by name as well as index. For example::

View File

@ -290,6 +290,7 @@ import io
import os
import traceback
import gc
import signal
# Exception classes used by this module.
class CalledProcessError(Exception):
@ -317,6 +318,7 @@ if mswindows:
from win32process import CreateProcess, STARTUPINFO, \
GetExitCodeProcess, STARTF_USESTDHANDLES, \
STARTF_USESHOWWINDOW, CREATE_NEW_CONSOLE
from win32process import TerminateProcess
from win32event import WaitForSingleObject, INFINITE, WAIT_OBJECT_0
else:
from _subprocess import *
@ -828,6 +830,21 @@ class Popen(object):
self.wait()
return (stdout, stderr)
def send_signal(self, sig):
"""Send a signal to the process
"""
if sig == signal.SIGTERM:
self.terminate()
else:
raise ValueError("Only SIGTERM is supported on Windows")
def terminate(self):
"""Terminates the process
"""
TerminateProcess(self._handle, 1)
kill = terminate
else:
#
# POSIX methods
@ -1115,6 +1132,21 @@ class Popen(object):
self.wait()
return (stdout, stderr)
def send_signal(self, sig):
"""Send a signal to the process
"""
os.kill(self.pid, sig)
def terminate(self):
"""Terminate the process with SIGTERM
"""
self.send_signal(signal.SIGTERM)
def kill(self):
"""Kill the process with SIGKILL
"""
self.send_signal(signal.SIGKILL)
def _demo_posix():
#

View File

@ -102,7 +102,7 @@ class MathTests(unittest.TestCase):
self.ftest('atan(0)', math.atan(0), 0)
self.ftest('atan(1)', math.atan(1), math.pi/4)
self.ftest('atan(inf)', math.atan(INF), math.pi/2)
self.ftest('atan(-inf)', math.atan(-INF), -math.pi/2)
self.ftest('atan(-inf)', math.atan(NINF), -math.pi/2)
self.assert_(math.isnan(math.atan(NAN)))
def testAtanh(self):
@ -383,14 +383,140 @@ class MathTests(unittest.TestCase):
self.assert_(math.isnan(math.pow(2, NAN)))
self.assert_(math.isnan(math.pow(0, NAN)))
self.assertEqual(math.pow(1, NAN), 1)
self.assertEqual(1**NAN, 1)
self.assertEqual(1**INF, 1)
self.assertEqual(1**NINF, 1)
self.assertEqual(1**0, 1)
self.assertEqual(1.**NAN, 1)
self.assertEqual(1.**INF, 1)
self.assertEqual(1.**NINF, 1)
self.assertEqual(1.**0, 1)
# pow(0., x)
self.assertEqual(math.pow(0., INF), 0.)
self.assertEqual(math.pow(0., 3.), 0.)
self.assertEqual(math.pow(0., 2.3), 0.)
self.assertEqual(math.pow(0., 2.), 0.)
self.assertEqual(math.pow(0., 0.), 1.)
self.assertEqual(math.pow(0., -0.), 1.)
self.assertRaises(ValueError, math.pow, 0., -2.)
self.assertRaises(ValueError, math.pow, 0., -2.3)
self.assertRaises(ValueError, math.pow, 0., -3.)
self.assertRaises(ValueError, math.pow, 0., NINF)
self.assert_(math.isnan(math.pow(0., NAN)))
# pow(INF, x)
self.assertEqual(math.pow(INF, INF), INF)
self.assertEqual(math.pow(INF, 3.), INF)
self.assertEqual(math.pow(INF, 2.3), INF)
self.assertEqual(math.pow(INF, 2.), INF)
self.assertEqual(math.pow(INF, 0.), 1.)
self.assertEqual(math.pow(INF, -0.), 1.)
self.assertEqual(math.pow(INF, -2.), 0.)
self.assertEqual(math.pow(INF, -2.3), 0.)
self.assertEqual(math.pow(INF, -3.), 0.)
self.assertEqual(math.pow(INF, NINF), 0.)
self.assert_(math.isnan(math.pow(INF, NAN)))
# pow(-0., x)
self.assertEqual(math.pow(-0., INF), 0.)
self.assertEqual(math.pow(-0., 3.), -0.)
self.assertEqual(math.pow(-0., 2.3), 0.)
self.assertEqual(math.pow(-0., 2.), 0.)
self.assertEqual(math.pow(-0., 0.), 1.)
self.assertEqual(math.pow(-0., -0.), 1.)
self.assertRaises(ValueError, math.pow, -0., -2.)
self.assertRaises(ValueError, math.pow, -0., -2.3)
self.assertRaises(ValueError, math.pow, -0., -3.)
self.assertRaises(ValueError, math.pow, -0., NINF)
self.assert_(math.isnan(math.pow(-0., NAN)))
# pow(NINF, x)
self.assertEqual(math.pow(NINF, INF), INF)
self.assertEqual(math.pow(NINF, 3.), NINF)
self.assertEqual(math.pow(NINF, 2.3), INF)
self.assertEqual(math.pow(NINF, 2.), INF)
self.assertEqual(math.pow(NINF, 0.), 1.)
self.assertEqual(math.pow(NINF, -0.), 1.)
self.assertEqual(math.pow(NINF, -2.), 0.)
self.assertEqual(math.pow(NINF, -2.3), 0.)
self.assertEqual(math.pow(NINF, -3.), -0.)
self.assertEqual(math.pow(NINF, NINF), 0.)
self.assert_(math.isnan(math.pow(NINF, NAN)))
# pow(-1, x)
self.assertEqual(math.pow(-1., INF), 1.)
self.assertEqual(math.pow(-1., 3.), -1.)
self.assertRaises(ValueError, math.pow, -1., 2.3)
self.assertEqual(math.pow(-1., 2.), 1.)
self.assertEqual(math.pow(-1., 0.), 1.)
self.assertEqual(math.pow(-1., -0.), 1.)
self.assertEqual(math.pow(-1., -2.), 1.)
self.assertRaises(ValueError, math.pow, -1., -2.3)
self.assertEqual(math.pow(-1., -3.), -1.)
self.assertEqual(math.pow(-1., NINF), 1.)
self.assert_(math.isnan(math.pow(-1., NAN)))
# pow(1, x)
self.assertEqual(math.pow(1., INF), 1.)
self.assertEqual(math.pow(1., 3.), 1.)
self.assertEqual(math.pow(1., 2.3), 1.)
self.assertEqual(math.pow(1., 2.), 1.)
self.assertEqual(math.pow(1., 0.), 1.)
self.assertEqual(math.pow(1., -0.), 1.)
self.assertEqual(math.pow(1., -2.), 1.)
self.assertEqual(math.pow(1., -2.3), 1.)
self.assertEqual(math.pow(1., -3.), 1.)
self.assertEqual(math.pow(1., NINF), 1.)
self.assertEqual(math.pow(1., NAN), 1.)
# pow(x, 0) should be 1 for any x
self.assertEqual(math.pow(2.3, 0.), 1.)
self.assertEqual(math.pow(-2.3, 0.), 1.)
self.assertEqual(math.pow(NAN, 0.), 1.)
self.assertEqual(math.pow(2.3, -0.), 1.)
self.assertEqual(math.pow(-2.3, -0.), 1.)
self.assertEqual(math.pow(NAN, -0.), 1.)
# pow(x, y) is invalid if x is negative and y is not integral
self.assertRaises(ValueError, math.pow, -1., 2.3)
self.assertRaises(ValueError, math.pow, -15., -3.1)
# pow(x, NINF)
self.assertEqual(math.pow(1.9, NINF), 0.)
self.assertEqual(math.pow(1.1, NINF), 0.)
self.assertEqual(math.pow(0.9, NINF), INF)
self.assertEqual(math.pow(0.1, NINF), INF)
self.assertEqual(math.pow(-0.1, NINF), INF)
self.assertEqual(math.pow(-0.9, NINF), INF)
self.assertEqual(math.pow(-1.1, NINF), 0.)
self.assertEqual(math.pow(-1.9, NINF), 0.)
# pow(x, INF)
self.assertEqual(math.pow(1.9, INF), INF)
self.assertEqual(math.pow(1.1, INF), INF)
self.assertEqual(math.pow(0.9, INF), 0.)
self.assertEqual(math.pow(0.1, INF), 0.)
self.assertEqual(math.pow(-0.1, INF), 0.)
self.assertEqual(math.pow(-0.9, INF), 0.)
self.assertEqual(math.pow(-1.1, INF), INF)
self.assertEqual(math.pow(-1.9, INF), INF)
# pow(x, y) should work for x negative, y an integer
self.ftest('(-2.)**3.', math.pow(-2.0, 3.0), -8.0)
self.ftest('(-2.)**2.', math.pow(-2.0, 2.0), 4.0)
self.ftest('(-2.)**1.', math.pow(-2.0, 1.0), -2.0)
self.ftest('(-2.)**0.', math.pow(-2.0, 0.0), 1.0)
self.ftest('(-2.)**-0.', math.pow(-2.0, -0.0), 1.0)
self.ftest('(-2.)**-1.', math.pow(-2.0, -1.0), -0.5)
self.ftest('(-2.)**-2.', math.pow(-2.0, -2.0), 0.25)
self.ftest('(-2.)**-3.', math.pow(-2.0, -3.0), -0.125)
self.assertRaises(ValueError, math.pow, -2.0, -0.5)
self.assertRaises(ValueError, math.pow, -2.0, 0.5)
# the following tests have been commented out since they don't
# really belong here: the implementation of ** for floats is
# independent of the implemention of math.pow
#self.assertEqual(1**NAN, 1)
#self.assertEqual(1**INF, 1)
#self.assertEqual(1**NINF, 1)
#self.assertEqual(1**0, 1)
#self.assertEqual(1.**NAN, 1)
#self.assertEqual(1.**INF, 1)
#self.assertEqual(1.**NINF, 1)
#self.assertEqual(1.**0, 1)
def testRadians(self):
self.assertRaises(TypeError, math.radians)
@ -417,7 +543,7 @@ class MathTests(unittest.TestCase):
self.ftest('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1)
self.ftest('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0)
self.assertEquals(math.sinh(INF), INF)
self.assertEquals(math.sinh(-INF), -INF)
self.assertEquals(math.sinh(NINF), NINF)
self.assert_(math.isnan(math.sinh(NAN)))
def testSqrt(self):
@ -555,7 +681,12 @@ class MathTests(unittest.TestCase):
# no real versions of rect, polar
continue
func = getattr(math, fn)
result = func(ar)
try:
result = func(ar)
except ValueError:
message = ("Unexpected ValueError in " +
"test %s:%s(%r)\n" % (id, fn, ar))
self.fail(message)
self.ftest("%s:%s(%r)" % (id, fn, ar), result, er)
def test_main():

View File

@ -584,6 +584,29 @@ class ProcessTestCase(unittest.TestCase):
os.remove(fname)
self.assertEqual(rc, 47)
def test_send_signal(self):
p = subprocess.Popen([sys.executable,
"-c", "input()"])
self.assert_(p.poll() is None, p.poll())
p.send_signal(signal.SIGINT)
self.assertNotEqual(p.wait(), 0)
def test_kill(self):
p = subprocess.Popen([sys.executable,
"-c", "input()"])
self.assert_(p.poll() is None, p.poll())
p.kill()
self.assertEqual(p.wait(), -signal.SIGKILL)
def test_terminate(self):
p = subprocess.Popen([sys.executable,
"-c", "input()"])
self.assert_(p.poll() is None, p.poll())
p.terminate()
self.assertEqual(p.wait(), -signal.SIGTERM)
#
# Windows tests
@ -655,6 +678,29 @@ class ProcessTestCase(unittest.TestCase):
' -c "import sys; sys.exit(47)"')
self.assertEqual(rc, 47)
def test_send_signal(self):
p = subprocess.Popen([sys.executable,
"-c", "input()"])
self.assert_(p.poll() is None, p.poll())
p.send_signal(signal.SIGTERM)
self.assertNotEqual(p.wait(), 0)
def test_kill(self):
p = subprocess.Popen([sys.executable,
"-c", "input()"])
self.assert_(p.poll() is None, p.poll())
p.kill()
self.assertNotEqual(p.wait(), 0)
def test_terminate(self):
p = subprocess.Popen([sys.executable,
"-c", "input()"])
self.assert_(p.poll() is None, p.poll())
p.terminate()
self.assertNotEqual(p.wait(), 0)
def test_main():
test_support.run_unittest(ProcessTestCase)

View File

@ -107,16 +107,8 @@ special_type(double d)
#define P14 0.25*Py_MATH_PI
#define P12 0.5*Py_MATH_PI
#define P34 0.75*Py_MATH_PI
#ifdef MS_WINDOWS
/* On Windows HUGE_VAL is an extern variable and not a constant. Since the
special value arrays need a constant we have to roll our own infinity
and nan. */
# define INF (DBL_MAX*DBL_MAX)
# define N (INF*0.)
#else
# define INF Py_HUGE_VAL
# define N Py_NAN
#endif /* MS_WINDOWS */
#define INF Py_HUGE_VAL
#define N Py_NAN
#define U -9.5426319407711027e33 /* unlikely value, used as placeholder */
/* First, the C functions that do the real work. Each of the c_*
@ -128,15 +120,7 @@ special_type(double d)
raised.
*/
static Py_complex acos_special_values[7][7] = {
{{P34,INF},{P,INF}, {P,INF}, {P,-INF}, {P,-INF}, {P34,-INF},{N,INF}},
{{P12,INF},{U,U}, {U,U}, {U,U}, {U,U}, {P12,-INF},{N,N}},
{{P12,INF},{U,U}, {P12,0.},{P12,-0.},{U,U}, {P12,-INF},{P12,N}},
{{P12,INF},{U,U}, {P12,0.},{P12,-0.},{U,U}, {P12,-INF},{P12,N}},
{{P12,INF},{U,U}, {U,U}, {U,U}, {U,U}, {P12,-INF},{N,N}},
{{P14,INF},{0.,INF},{0.,INF},{0.,-INF},{0.,-INF},{P14,-INF},{N,INF}},
{{N,INF}, {N,N}, {N,N}, {N,N}, {N,N}, {N,-INF}, {N,N}}
};
static Py_complex acos_special_values[7][7];
static Py_complex
c_acos(Py_complex z)
@ -177,15 +161,7 @@ PyDoc_STRVAR(c_acos_doc,
"Return the arc cosine of x.");
static Py_complex acosh_special_values[7][7] = {
{{INF,-P34},{INF,-P}, {INF,-P}, {INF,P}, {INF,P}, {INF,P34},{INF,N}},
{{INF,-P12},{U,U}, {U,U}, {U,U}, {U,U}, {INF,P12},{N,N}},
{{INF,-P12},{U,U}, {0.,-P12},{0.,P12},{U,U}, {INF,P12},{N,N}},
{{INF,-P12},{U,U}, {0.,-P12},{0.,P12},{U,U}, {INF,P12},{N,N}},
{{INF,-P12},{U,U}, {U,U}, {U,U}, {U,U}, {INF,P12},{N,N}},
{{INF,-P14},{INF,-0.},{INF,-0.},{INF,0.},{INF,0.},{INF,P14},{INF,N}},
{{INF,N}, {N,N}, {N,N}, {N,N}, {N,N}, {INF,N}, {N,N}}
};
static Py_complex acosh_special_values[7][7];
static Py_complex
c_acosh(Py_complex z)
@ -237,15 +213,7 @@ PyDoc_STRVAR(c_asin_doc,
"Return the arc sine of x.");
static Py_complex asinh_special_values[7][7] = {
{{-INF,-P14},{-INF,-0.},{-INF,-0.},{-INF,0.},{-INF,0.},{-INF,P14},{-INF,N}},
{{-INF,-P12},{U,U}, {U,U}, {U,U}, {U,U}, {-INF,P12},{N,N}},
{{-INF,-P12},{U,U}, {-0.,-0.}, {-0.,0.}, {U,U}, {-INF,P12},{N,N}},
{{INF,-P12}, {U,U}, {0.,-0.}, {0.,0.}, {U,U}, {INF,P12}, {N,N}},
{{INF,-P12}, {U,U}, {U,U}, {U,U}, {U,U}, {INF,P12}, {N,N}},
{{INF,-P14}, {INF,-0.}, {INF,-0.}, {INF,0.}, {INF,0.}, {INF,P14}, {INF,N}},
{{INF,N}, {N,N}, {N,-0.}, {N,0.}, {N,N}, {INF,N}, {N,N}}
};
static Py_complex asinh_special_values[7][7];
static Py_complex
c_asinh(Py_complex z)
@ -323,15 +291,7 @@ PyDoc_STRVAR(c_atan_doc,
"Return the arc tangent of x.");
static Py_complex atanh_special_values[7][7] = {
{{-0.,-P12},{-0.,-P12},{-0.,-P12},{-0.,P12},{-0.,P12},{-0.,P12},{-0.,N}},
{{-0.,-P12},{U,U}, {U,U}, {U,U}, {U,U}, {-0.,P12},{N,N}},
{{-0.,-P12},{U,U}, {-0.,-0.}, {-0.,0.}, {U,U}, {-0.,P12},{-0.,N}},
{{0.,-P12}, {U,U}, {0.,-0.}, {0.,0.}, {U,U}, {0.,P12}, {0.,N}},
{{0.,-P12}, {U,U}, {U,U}, {U,U}, {U,U}, {0.,P12}, {N,N}},
{{0.,-P12}, {0.,-P12}, {0.,-P12}, {0.,P12}, {0.,P12}, {0.,P12}, {0.,N}},
{{0.,-P12}, {N,N}, {N,N}, {N,N}, {N,N}, {0.,P12}, {N,N}}
};
static Py_complex atanh_special_values[7][7];
static Py_complex
c_atanh(Py_complex z)
@ -404,15 +364,7 @@ PyDoc_STRVAR(c_cos_doc,
/* cosh(infinity + i*y) needs to be dealt with specially */
static Py_complex cosh_special_values[7][7] = {
{{INF,N},{U,U},{INF,0.}, {INF,-0.},{U,U},{INF,N},{INF,N}},
{{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
{{N,0.}, {U,U},{1.,0.}, {1.,-0.}, {U,U},{N,0.}, {N,0.}},
{{N,0.}, {U,U},{1.,-0.}, {1.,0.}, {U,U},{N,0.}, {N,0.}},
{{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
{{INF,N},{U,U},{INF,-0.},{INF,0.}, {U,U},{INF,N},{INF,N}},
{{N,N}, {N,N},{N,0.}, {N,0.}, {N,N},{N,N}, {N,N}}
};
static Py_complex cosh_special_values[7][7];
static Py_complex
c_cosh(Py_complex z)
@ -472,15 +424,7 @@ PyDoc_STRVAR(c_cosh_doc,
/* exp(infinity + i*y) and exp(-infinity + i*y) need special treatment for
finite y */
static Py_complex exp_special_values[7][7] = {
{{0.,0.},{U,U},{0.,-0.}, {0.,0.}, {U,U},{0.,0.},{0.,0.}},
{{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
{{N,N}, {U,U},{1.,-0.}, {1.,0.}, {U,U},{N,N}, {N,N}},
{{N,N}, {U,U},{1.,-0.}, {1.,0.}, {U,U},{N,N}, {N,N}},
{{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
{{INF,N},{U,U},{INF,-0.},{INF,0.},{U,U},{INF,N},{INF,N}},
{{N,N}, {N,N},{N,-0.}, {N,0.}, {N,N},{N,N}, {N,N}}
};
static Py_complex exp_special_values[7][7];
static Py_complex
c_exp(Py_complex z)
@ -538,15 +482,7 @@ PyDoc_STRVAR(c_exp_doc,
"Return the exponential value e**x.");
static Py_complex log_special_values[7][7] = {
{{INF,-P34},{INF,-P}, {INF,-P}, {INF,P}, {INF,P}, {INF,P34}, {INF,N}},
{{INF,-P12},{U,U}, {U,U}, {U,U}, {U,U}, {INF,P12}, {N,N}},
{{INF,-P12},{U,U}, {-INF,-P}, {-INF,P}, {U,U}, {INF,P12}, {N,N}},
{{INF,-P12},{U,U}, {-INF,-0.},{-INF,0.},{U,U}, {INF,P12}, {N,N}},
{{INF,-P12},{U,U}, {U,U}, {U,U}, {U,U}, {INF,P12}, {N,N}},
{{INF,-P14},{INF,-0.},{INF,-0.}, {INF,0.}, {INF,0.},{INF,P14}, {INF,N}},
{{INF,N}, {N,N}, {N,N}, {N,N}, {N,N}, {INF,N}, {N,N}}
};
static Py_complex log_special_values[7][7];
static Py_complex
c_log(Py_complex z)
@ -658,15 +594,7 @@ PyDoc_STRVAR(c_sin_doc,
/* sinh(infinity + i*y) needs to be dealt with specially */
static Py_complex sinh_special_values[7][7] = {
{{INF,N},{U,U},{-INF,-0.},{-INF,0.},{U,U},{INF,N},{INF,N}},
{{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
{{0.,N}, {U,U},{-0.,-0.}, {-0.,0.}, {U,U},{0.,N}, {0.,N}},
{{0.,N}, {U,U},{0.,-0.}, {0.,0.}, {U,U},{0.,N}, {0.,N}},
{{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
{{INF,N},{U,U},{INF,-0.}, {INF,0.}, {U,U},{INF,N},{INF,N}},
{{N,N}, {N,N},{N,-0.}, {N,0.}, {N,N},{N,N}, {N,N}}
};
static Py_complex sinh_special_values[7][7];
static Py_complex
c_sinh(Py_complex z)
@ -723,15 +651,7 @@ PyDoc_STRVAR(c_sinh_doc,
"Return the hyperbolic sine of x.");
static Py_complex sqrt_special_values[7][7] = {
{{INF,-INF},{0.,-INF},{0.,-INF},{0.,INF},{0.,INF},{INF,INF},{N,INF}},
{{INF,-INF},{U,U}, {U,U}, {U,U}, {U,U}, {INF,INF},{N,N}},
{{INF,-INF},{U,U}, {0.,-0.}, {0.,0.}, {U,U}, {INF,INF},{N,N}},
{{INF,-INF},{U,U}, {0.,-0.}, {0.,0.}, {U,U}, {INF,INF},{N,N}},
{{INF,-INF},{U,U}, {U,U}, {U,U}, {U,U}, {INF,INF},{N,N}},
{{INF,-INF},{INF,-0.},{INF,-0.},{INF,0.},{INF,0.},{INF,INF},{INF,N}},
{{INF,-INF},{N,N}, {N,N}, {N,N}, {N,N}, {INF,INF},{N,N}}
};
static Py_complex sqrt_special_values[7][7];
static Py_complex
c_sqrt(Py_complex z)
@ -826,15 +746,7 @@ PyDoc_STRVAR(c_tan_doc,
/* tanh(infinity + i*y) needs to be dealt with specially */
static Py_complex tanh_special_values[7][7] = {
{{-1.,0.},{U,U},{-1.,-0.},{-1.,0.},{U,U},{-1.,0.},{-1.,0.}},
{{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
{{N,N}, {U,U},{-0.,-0.},{-0.,0.},{U,U},{N,N}, {N,N}},
{{N,N}, {U,U},{0.,-0.}, {0.,0.}, {U,U},{N,N}, {N,N}},
{{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
{{1.,0.}, {U,U},{1.,-0.}, {1.,0.}, {U,U},{1.,0.}, {1.,0.}},
{{N,N}, {N,N},{N,-0.}, {N,0.}, {N,N},{N,N}, {N,N}}
};
static Py_complex tanh_special_values[7][7];
static Py_complex
c_tanh(Py_complex z)
@ -1043,15 +955,7 @@ the distance from 0 and phi the phase angle.");
*/
static Py_complex rect_special_values[7][7] = {
{{INF,N},{U,U},{-INF,0.},{-INF,-0.},{U,U},{INF,N},{INF,N}},
{{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
{{0.,0.},{U,U},{-0.,0.}, {-0.,-0.}, {U,U},{0.,0.},{0.,0.}},
{{0.,0.},{U,U},{0.,-0.}, {0.,0.}, {U,U},{0.,0.},{0.,0.}},
{{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
{{INF,N},{U,U},{INF,-0.},{INF,0.}, {U,U},{INF,N},{INF,N}},
{{N,N}, {N,N},{N,0.}, {N,0.}, {N,N},{N,N}, {N,N}}
};
static Py_complex rect_special_values[7][7];
static PyObject *
cmath_rect(PyObject *self, PyObject *args)
@ -1176,4 +1080,119 @@ initcmath(void)
PyModule_AddObject(m, "pi",
PyFloat_FromDouble(Py_MATH_PI));
PyModule_AddObject(m, "e", PyFloat_FromDouble(Py_MATH_E));
/* initialize special value tables */
#define INIT_SPECIAL_VALUES(NAME, BODY) { Py_complex* p = (Py_complex*)NAME; BODY }
#define C(REAL, IMAG) p->real = REAL; p->imag = IMAG; ++p;
INIT_SPECIAL_VALUES(acos_special_values, {
C(P34,INF) C(P,INF) C(P,INF) C(P,-INF) C(P,-INF) C(P34,-INF) C(N,INF)
C(P12,INF) C(U,U) C(U,U) C(U,U) C(U,U) C(P12,-INF) C(N,N)
C(P12,INF) C(U,U) C(P12,0.) C(P12,-0.) C(U,U) C(P12,-INF) C(P12,N)
C(P12,INF) C(U,U) C(P12,0.) C(P12,-0.) C(U,U) C(P12,-INF) C(P12,N)
C(P12,INF) C(U,U) C(U,U) C(U,U) C(U,U) C(P12,-INF) C(N,N)
C(P14,INF) C(0.,INF) C(0.,INF) C(0.,-INF) C(0.,-INF) C(P14,-INF) C(N,INF)
C(N,INF) C(N,N) C(N,N) C(N,N) C(N,N) C(N,-INF) C(N,N)
})
INIT_SPECIAL_VALUES(acosh_special_values, {
C(INF,-P34) C(INF,-P) C(INF,-P) C(INF,P) C(INF,P) C(INF,P34) C(INF,N)
C(INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,P12) C(N,N)
C(INF,-P12) C(U,U) C(0.,-P12) C(0.,P12) C(U,U) C(INF,P12) C(N,N)
C(INF,-P12) C(U,U) C(0.,-P12) C(0.,P12) C(U,U) C(INF,P12) C(N,N)
C(INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,P12) C(N,N)
C(INF,-P14) C(INF,-0.) C(INF,-0.) C(INF,0.) C(INF,0.) C(INF,P14) C(INF,N)
C(INF,N) C(N,N) C(N,N) C(N,N) C(N,N) C(INF,N) C(N,N)
})
INIT_SPECIAL_VALUES(asinh_special_values, {
C(-INF,-P14) C(-INF,-0.) C(-INF,-0.) C(-INF,0.) C(-INF,0.) C(-INF,P14) C(-INF,N)
C(-INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(-INF,P12) C(N,N)
C(-INF,-P12) C(U,U) C(-0.,-0.) C(-0.,0.) C(U,U) C(-INF,P12) C(N,N)
C(INF,-P12) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(INF,P12) C(N,N)
C(INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,P12) C(N,N)
C(INF,-P14) C(INF,-0.) C(INF,-0.) C(INF,0.) C(INF,0.) C(INF,P14) C(INF,N)
C(INF,N) C(N,N) C(N,-0.) C(N,0.) C(N,N) C(INF,N) C(N,N)
})
INIT_SPECIAL_VALUES(atanh_special_values, {
C(-0.,-P12) C(-0.,-P12) C(-0.,-P12) C(-0.,P12) C(-0.,P12) C(-0.,P12) C(-0.,N)
C(-0.,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(-0.,P12) C(N,N)
C(-0.,-P12) C(U,U) C(-0.,-0.) C(-0.,0.) C(U,U) C(-0.,P12) C(-0.,N)
C(0.,-P12) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(0.,P12) C(0.,N)
C(0.,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(0.,P12) C(N,N)
C(0.,-P12) C(0.,-P12) C(0.,-P12) C(0.,P12) C(0.,P12) C(0.,P12) C(0.,N)
C(0.,-P12) C(N,N) C(N,N) C(N,N) C(N,N) C(0.,P12) C(N,N)
})
INIT_SPECIAL_VALUES(cosh_special_values, {
C(INF,N) C(U,U) C(INF,0.) C(INF,-0.) C(U,U) C(INF,N) C(INF,N)
C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N)
C(N,0.) C(U,U) C(1.,0.) C(1.,-0.) C(U,U) C(N,0.) C(N,0.)
C(N,0.) C(U,U) C(1.,-0.) C(1.,0.) C(U,U) C(N,0.) C(N,0.)
C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N)
C(INF,N) C(U,U) C(INF,-0.) C(INF,0.) C(U,U) C(INF,N) C(INF,N)
C(N,N) C(N,N) C(N,0.) C(N,0.) C(N,N) C(N,N) C(N,N)
})
INIT_SPECIAL_VALUES(exp_special_values, {
C(0.,0.) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(0.,0.) C(0.,0.)
C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N)
C(N,N) C(U,U) C(1.,-0.) C(1.,0.) C(U,U) C(N,N) C(N,N)
C(N,N) C(U,U) C(1.,-0.) C(1.,0.) C(U,U) C(N,N) C(N,N)
C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N)
C(INF,N) C(U,U) C(INF,-0.) C(INF,0.) C(U,U) C(INF,N) C(INF,N)
C(N,N) C(N,N) C(N,-0.) C(N,0.) C(N,N) C(N,N) C(N,N)
})
INIT_SPECIAL_VALUES(log_special_values, {
C(INF,-P34) C(INF,-P) C(INF,-P) C(INF,P) C(INF,P) C(INF,P34) C(INF,N)
C(INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,P12) C(N,N)
C(INF,-P12) C(U,U) C(-INF,-P) C(-INF,P) C(U,U) C(INF,P12) C(N,N)
C(INF,-P12) C(U,U) C(-INF,-0.) C(-INF,0.) C(U,U) C(INF,P12) C(N,N)
C(INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,P12) C(N,N)
C(INF,-P14) C(INF,-0.) C(INF,-0.) C(INF,0.) C(INF,0.) C(INF,P14) C(INF,N)
C(INF,N) C(N,N) C(N,N) C(N,N) C(N,N) C(INF,N) C(N,N)
})
INIT_SPECIAL_VALUES(sinh_special_values, {
C(INF,N) C(U,U) C(-INF,-0.) C(-INF,0.) C(U,U) C(INF,N) C(INF,N)
C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N)
C(0.,N) C(U,U) C(-0.,-0.) C(-0.,0.) C(U,U) C(0.,N) C(0.,N)
C(0.,N) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(0.,N) C(0.,N)
C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N)
C(INF,N) C(U,U) C(INF,-0.) C(INF,0.) C(U,U) C(INF,N) C(INF,N)
C(N,N) C(N,N) C(N,-0.) C(N,0.) C(N,N) C(N,N) C(N,N)
})
INIT_SPECIAL_VALUES(sqrt_special_values, {
C(INF,-INF) C(0.,-INF) C(0.,-INF) C(0.,INF) C(0.,INF) C(INF,INF) C(N,INF)
C(INF,-INF) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,INF) C(N,N)
C(INF,-INF) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(INF,INF) C(N,N)
C(INF,-INF) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(INF,INF) C(N,N)
C(INF,-INF) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,INF) C(N,N)
C(INF,-INF) C(INF,-0.) C(INF,-0.) C(INF,0.) C(INF,0.) C(INF,INF) C(INF,N)
C(INF,-INF) C(N,N) C(N,N) C(N,N) C(N,N) C(INF,INF) C(N,N)
})
INIT_SPECIAL_VALUES(tanh_special_values, {
C(-1.,0.) C(U,U) C(-1.,-0.) C(-1.,0.) C(U,U) C(-1.,0.) C(-1.,0.)
C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N)
C(N,N) C(U,U) C(-0.,-0.) C(-0.,0.) C(U,U) C(N,N) C(N,N)
C(N,N) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(N,N) C(N,N)
C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N)
C(1.,0.) C(U,U) C(1.,-0.) C(1.,0.) C(U,U) C(1.,0.) C(1.,0.)
C(N,N) C(N,N) C(N,-0.) C(N,0.) C(N,N) C(N,N) C(N,N)
})
INIT_SPECIAL_VALUES(rect_special_values, {
C(INF,N) C(U,U) C(-INF,0.) C(-INF,-0.) C(U,U) C(INF,N) C(INF,N)
C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N)
C(0.,0.) C(U,U) C(-0.,0.) C(-0.,-0.) C(U,U) C(0.,0.) C(0.,0.)
C(0.,0.) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(0.,0.) C(0.,0.)
C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N)
C(INF,N) C(U,U) C(INF,-0.) C(INF,0.) C(U,U) C(INF,N) C(INF,N)
C(N,N) C(N,N) C(N,0.) C(N,0.) C(N,N) C(N,N) C(N,N)
})
}

View File

@ -414,6 +414,15 @@ math_modf(PyObject *self, PyObject *arg)
double y, x = PyFloat_AsDouble(arg);
if (x == -1.0 && PyErr_Occurred())
return NULL;
/* some platforms don't do the right thing for NaNs and
infinities, so we take care of special cases directly. */
if (!Py_IS_FINITE(x)) {
if (Py_IS_INFINITY(x))
return Py_BuildValue("(dd)", copysign(0., x), x);
else if (Py_IS_NAN(x))
return Py_BuildValue("(dd)", x, x);
}
errno = 0;
PyFPE_START_PROTECT("in math_modf", return 0);
x = modf(x, &y);
@ -586,6 +595,7 @@ math_pow(PyObject *self, PyObject *args)
{
PyObject *ox, *oy;
double r, x, y;
int odd_y;
if (! PyArg_UnpackTuple(args, "pow", 2, 2, &ox, &oy))
return NULL;
@ -593,37 +603,62 @@ math_pow(PyObject *self, PyObject *args)
y = PyFloat_AsDouble(oy);
if ((x == -1.0 || y == -1.0) && PyErr_Occurred())
return NULL;
/* 1**x and x**0 return 1., even if x is a NaN or infinity. */
if (x == 1.0 || y == 0.0)
return PyFloat_FromDouble(1.);
errno = 0;
PyFPE_START_PROTECT("in math_pow", return 0);
r = pow(x, y);
PyFPE_END_PROTECT(r);
if (Py_IS_NAN(r)) {
if (!Py_IS_NAN(x) && !Py_IS_NAN(y))
errno = EDOM;
else
errno = 0;
/* deal directly with IEEE specials, to cope with problems on various
platforms whose semantics don't exactly match C99 */
if (!Py_IS_FINITE(x) || !Py_IS_FINITE(y)) {
errno = 0;
if (Py_IS_NAN(x))
r = y == 0. ? 1. : x; /* NaN**0 = 1 */
else if (Py_IS_NAN(y))
r = x == 1. ? 1. : y; /* 1**NaN = 1 */
else if (Py_IS_INFINITY(x)) {
odd_y = Py_IS_FINITE(y) && fmod(fabs(y), 2.0) == 1.0;
if (y > 0.)
r = odd_y ? x : fabs(x);
else if (y == 0.)
r = 1.;
else /* y < 0. */
r = odd_y ? copysign(0., x) : 0.;
}
else if (Py_IS_INFINITY(y)) {
if (fabs(x) == 1.0)
r = 1.;
else if (y > 0. && fabs(x) > 1.0)
r = y;
else if (y < 0. && fabs(x) < 1.0) {
r = -y; /* result is +inf */
if (x == 0.) /* 0**-inf: divide-by-zero */
errno = EDOM;
}
else
r = 0.;
}
}
/* an infinite result arises either from:
(A) (+/-0.)**negative,
(B) overflow of x**y with both x and y finite (and x nonzero)
(C) (+/-inf)**positive, or
(D) x**inf with |x| > 1, or x**-inf with |x| < 1.
In case (A) we want ValueError to be raised. In case (B)
OverflowError should be raised. In cases (C) and (D) the infinite
result should be returned.
*/
else if (Py_IS_INFINITY(r)) {
if (x == 0.)
errno = EDOM;
else if (Py_IS_FINITE(x) && Py_IS_FINITE(y))
errno = ERANGE;
else
errno = 0;
else {
/* let libm handle finite**finite */
errno = 0;
PyFPE_START_PROTECT("in math_pow", return 0);
r = pow(x, y);
PyFPE_END_PROTECT(r);
/* a NaN result should arise only from (-ve)**(finite
non-integer); in this case we want to raise ValueError. */
if (!Py_IS_FINITE(r)) {
if (Py_IS_NAN(r)) {
errno = EDOM;
}
/*
an infinite result here arises either from:
(A) (+/-0.)**negative (-> divide-by-zero)
(B) overflow of x**y with x and y finite
*/
else if (Py_IS_INFINITY(r)) {
if (x == 0.)
errno = EDOM;
else
errno = ERANGE;
}
}
}
if (errno && is_error(r))