Commit a342c013 authored by Christian Heimes's avatar Christian Heimes

Merged revisions...

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
........
parent 58f9e4f3
...@@ -75,9 +75,6 @@ html_last_updated_fmt = '%b %d, %Y' ...@@ -75,9 +75,6 @@ html_last_updated_fmt = '%b %d, %Y'
# typographically correct entities. # typographically correct entities.
html_use_smartypants = True 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. # Custom sidebar templates, filenames relative to this file.
html_sidebars = { html_sidebars = {
'index': 'indexsidebar.html', 'index': 'indexsidebar.html',
...@@ -86,6 +83,7 @@ html_sidebars = { ...@@ -86,6 +83,7 @@ html_sidebars = {
# Additional templates that should be rendered to pages. # Additional templates that should be rendered to pages.
html_additional_pages = { html_additional_pages = {
'download': 'download.html', 'download': 'download.html',
'index': 'indexcontent.html',
} }
# Output file base name for HTML help builder. # Output file base name for HTML help builder.
......
...@@ -319,8 +319,8 @@ a matching identifier is found: ...@@ -319,8 +319,8 @@ a matching identifier is found:
.. describe:: func .. describe:: func
The name of a Python function; dotted names may be used. The role text The name of a Python function; dotted names may be used. The role text
should include trailing parentheses to enhance readability. The parentheses should not include trailing parentheses to enhance readability. The
are stripped when searching for identifiers. parentheses are stripped when searching for identifiers.
.. describe:: data .. describe:: data
...@@ -338,7 +338,7 @@ a matching identifier is found: ...@@ -338,7 +338,7 @@ a matching identifier is found:
.. describe:: meth .. describe:: meth
The name of a method of an object. The role text should include the type 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 .. describe:: attr
......
...@@ -528,9 +528,11 @@ the more significant byte last. ...@@ -528,9 +528,11 @@ the more significant byte last.
.. opcode:: IMPORT_NAME (namei) .. opcode:: IMPORT_NAME (namei)
Imports the module ``co_names[namei]``. The module object is pushed onto the Imports the module ``co_names[namei]``. TOS and TOS1 are popped and provide
stack. The current namespace is not affected: for a proper import statement, a the *fromlist* and *level* arguments of :func:`__import__`. The module
subsequent ``STORE_FAST`` instruction modifies the namespace. 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) .. opcode:: IMPORT_FROM (namei)
......
...@@ -101,13 +101,15 @@ Module Interface ...@@ -101,13 +101,15 @@ Module Interface
:mod:`codecs` module for the list of supported encodings. :mod:`codecs` module for the list of supported encodings.
*errors* is an optional string that specifies how encoding and decoding *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. errors are to be handled. Pass ``'strict'`` to raise a :exc:`ValueError`
Pass ``'strict'`` to raise a :exc:`ValueError` exception if there is an exception if there is an encoding error (the default of ``None`` has the same
encoding error (the default of ``None`` has the same effect), or pass effect), or pass ``'ignore'`` to ignore errors. (Note that ignoring encoding
``'ignore'`` to ignore errors. (Note that ignoring encoding errors can lead errors can lead to data loss.) ``'replace'`` causes a replacement marker
to data loss.) ``'replace'`` causes a replacement marker (such as ``'?'``) (such as ``'?'``) to be inserted where there is malformed data. When
to be inserted where there is malformed data. For all possible values, see writing, ``'xmlcharrefreplace'`` (replace with the appropriate XML character
:func:`codecs.register`. 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 *newline* controls how universal newlines works (it only applies to text
mode). It can be ``None``, ``''``, ``'\n'``, ``'\r'``, and ``'\r\n'``. It mode). It can be ``None``, ``''``, ``'\n'``, ``'\r'``, and ``'\r\n'``. It
...@@ -581,8 +583,11 @@ Text I/O ...@@ -581,8 +583,11 @@ Text I/O
exception if there is an encoding error (the default of ``None`` has the same 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 effect), or pass ``'ignore'`` to ignore errors. (Note that ignoring encoding
errors can lead to data loss.) ``'replace'`` causes a replacement marker errors can lead to data loss.) ``'replace'`` causes a replacement marker
(such as ``'?'``) to be inserted where there is malformed data. For all (such as ``'?'``) to be inserted where there is malformed data. When
possible values see :func:`codecs.register`. 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 *newline* can be ``None``, ``''``, ``'\n'``, ``'\r'``, or ``'\r\n'``. It
controls the handling of line endings. If it is ``None``, universal newlines controls the handling of line endings. If it is ``None``, universal newlines
......
...@@ -143,11 +143,15 @@ Power and logarithmic functions: ...@@ -143,11 +143,15 @@ Power and logarithmic functions:
.. function:: pow(x, y) .. function:: pow(x, y)
Return ``x**y``. ``1.0**y`` returns *1.0*, even for ``1.0**nan``. ``0**y`` Return ``x`` raised to the power ``y``. Exceptional cases follow
returns *0.* for all positive *y*, *0* and *NAN*. 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 .. 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) .. function:: sqrt(x)
...@@ -198,13 +202,6 @@ Trigonometric functions: ...@@ -198,13 +202,6 @@ Trigonometric functions:
Return the sine of *x* radians. Return the sine of *x* radians.
.. function:: asinh(x)
Return the inverse hyperbolic sine of *x*, in radians.
.. versionadded:: 2.6
.. function:: tan(x) .. function:: tan(x)
Return the tangent of *x* radians. Return the tangent of *x* radians.
...@@ -224,18 +221,32 @@ Angular conversion: ...@@ -224,18 +221,32 @@ Angular conversion:
Hyperbolic functions: Hyperbolic functions:
.. function:: cosh(x) .. function:: acosh(x)
Return the hyperbolic cosine of *x*. Return the inverse hyperbolic cosine of *x*.
.. versionadded:: 2.6
.. function:: acosh(x)
Return the inverse hyperbolic cosine of *x*, in radians. .. function:: asinh(x)
Return the inverse hyperbolic sine of *x*.
.. versionadded:: 2.6 .. 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:: sinh(x) .. function:: sinh(x)
Return the hyperbolic sine of *x*. Return the hyperbolic sine of *x*.
...@@ -246,12 +257,6 @@ Hyperbolic functions: ...@@ -246,12 +257,6 @@ Hyperbolic functions:
Return the hyperbolic tangent of *x*. 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: The module also defines two mathematical constants:
...@@ -279,7 +284,7 @@ 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` isn't defined, and in cases where ``math.log(0)`` raises
:exc:`OverflowError`, ``math.log(0L)`` may raise :exc:`ValueError` instead. :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 Signaling *NaN*s raise an exception. The exception type still depends on the
platform and libm implementation. It's usually :exc:`ValueError` for *EDOM* platform and libm implementation. It's usually :exc:`ValueError` for *EDOM*
and :exc:`OverflowError` for errno *ERANGE*. and :exc:`OverflowError` for errno *ERANGE*.
......
...@@ -1254,7 +1254,8 @@ to be ignored. ...@@ -1254,7 +1254,8 @@ to be ignored.
For :func:`execle`, :func:`execlpe`, :func:`execve`, and :func:`execvpe` (note 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 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 :func:`execlp`, :func:`execv`, and :func:`execvp` all cause the new process to
inherit the environment of the current process. Availability: Macintosh, Unix, inherit the environment of the current process. Availability: Macintosh, Unix,
Windows. Windows.
...@@ -1484,7 +1485,8 @@ written in Python, such as a mail server's external command delivery program. ...@@ -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` For :func:`spawnle`, :func:`spawnlpe`, :func:`spawnve`, and :func:`spawnvpe`
(note that these all end in "e"), the *env* parameter must be a mapping (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 :func:`spawnl`, :func:`spawnlp`, :func:`spawnv`, and :func:`spawnvp` all cause
the new process to inherit the environment of the current process. the new process to inherit the environment of the current process.
......
...@@ -28,15 +28,6 @@ copying and removal. For operations on individual files, see also the ...@@ -28,15 +28,6 @@ copying and removal. For operations on individual files, see also the
are not copied. 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]) .. function:: copyfileobj(fsrc, fdst[, length])
Copy the contents of the file-like object *fsrc* to the file-like object *fdst*. 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 ...@@ -48,6 +39,17 @@ copying and removal. For operations on individual files, see also the
be copied. 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) .. function:: copymode(src, dst)
Copy the permission bits from *src* to *dst*. The file contents, owner, and Copy the permission bits from *src* to *dst*. The file contents, owner, and
......
...@@ -89,8 +89,9 @@ This module defines one class called :class:`Popen`: ...@@ -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 searching the executable, so you can't specify the program's path relative to
*cwd*. *cwd*.
If *env* is not ``None``, it defines the environment variables for the new If *env* is not ``None``, it must be a mapping that defines the environment
process. 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 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 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: ...@@ -202,6 +203,35 @@ Instances of the :class:`Popen` class have the following methods:
size is large or unlimited. 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: The following attributes are also available:
.. attribute:: Popen.stdin .. attribute:: Popen.stdin
......
{% extends "defindex.html" %}
{% block tables %}
<p><strong>Parts of the documentation:</strong></p> <p><strong>Parts of the documentation:</strong></p>
<table class="contentstable" align="center"><tr> <table class="contentstable" align="center"><tr>
<td width="50%"> <td width="50%">
...@@ -54,3 +56,4 @@ ...@@ -54,3 +56,4 @@
<p class="biglink"><a class="biglink" href="{{ pathto("copyright") }}">Copyright</a></p> <p class="biglink"><a class="biglink" href="{{ pathto("copyright") }}">Copyright</a></p>
</td></tr> </td></tr>
</table> </table>
{% endblock %}
...@@ -1292,11 +1292,42 @@ Here are all of the changes that Python 2.6 makes to the core Python language. ...@@ -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 :func:`isnan`, return true if their floating-point argument is
infinite or Not A Number. (:issue:`1640`) infinite or Not A Number. (:issue:`1640`)
The ``math.copysign(x, y)`` function * The :mod:`math` module has seven new functions, and the existing
copies the sign bit of an IEEE 754 number, returning the absolute functions have been improved to give more consistent behaviour
value of *x* combined with the sign bit of *y*. For example, across platforms, especially with respect to handling of
``math.copysign(1, -0.0)`` returns -1.0. (Contributed by Christian floating-point exceptions and IEEE 754 special values.
Heimes.) 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 * Changes to the :class:`Exception` interface
as dictated by :pep:`352` continue to be made. For 2.6, 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. ...@@ -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. available, instead of restricting itself to protocol 1.
(Contributed by W. Barnes; :issue:`1551443`.) (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, * A new data type in the :mod:`collections` module: :class:`namedtuple(typename,
fieldnames)` is a factory function that creates subclasses of the standard tuple fieldnames)` is a factory function that creates subclasses of the standard tuple
whose fields are accessible by name as well as index. For example:: whose fields are accessible by name as well as index. For example::
......
...@@ -290,6 +290,7 @@ import io ...@@ -290,6 +290,7 @@ import io
import os import os
import traceback import traceback
import gc import gc
import signal
# Exception classes used by this module. # Exception classes used by this module.
class CalledProcessError(Exception): class CalledProcessError(Exception):
...@@ -317,6 +318,7 @@ if mswindows: ...@@ -317,6 +318,7 @@ if mswindows:
from win32process import CreateProcess, STARTUPINFO, \ from win32process import CreateProcess, STARTUPINFO, \
GetExitCodeProcess, STARTF_USESTDHANDLES, \ GetExitCodeProcess, STARTF_USESTDHANDLES, \
STARTF_USESHOWWINDOW, CREATE_NEW_CONSOLE STARTF_USESHOWWINDOW, CREATE_NEW_CONSOLE
from win32process import TerminateProcess
from win32event import WaitForSingleObject, INFINITE, WAIT_OBJECT_0 from win32event import WaitForSingleObject, INFINITE, WAIT_OBJECT_0
else: else:
from _subprocess import * from _subprocess import *
...@@ -828,6 +830,21 @@ class Popen(object): ...@@ -828,6 +830,21 @@ class Popen(object):
self.wait() self.wait()
return (stdout, stderr) 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: else:
# #
# POSIX methods # POSIX methods
...@@ -1115,6 +1132,21 @@ class Popen(object): ...@@ -1115,6 +1132,21 @@ class Popen(object):
self.wait() self.wait()
return (stdout, stderr) 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(): def _demo_posix():
# #
......
...@@ -102,7 +102,7 @@ class MathTests(unittest.TestCase): ...@@ -102,7 +102,7 @@ class MathTests(unittest.TestCase):
self.ftest('atan(0)', math.atan(0), 0) self.ftest('atan(0)', math.atan(0), 0)
self.ftest('atan(1)', math.atan(1), math.pi/4) 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(-INF), -math.pi/2) self.ftest('atan(-inf)', math.atan(NINF), -math.pi/2)
self.assert_(math.isnan(math.atan(NAN))) self.assert_(math.isnan(math.atan(NAN)))
def testAtanh(self): def testAtanh(self):
...@@ -383,14 +383,140 @@ class MathTests(unittest.TestCase): ...@@ -383,14 +383,140 @@ class MathTests(unittest.TestCase):
self.assert_(math.isnan(math.pow(2, NAN))) self.assert_(math.isnan(math.pow(2, NAN)))
self.assert_(math.isnan(math.pow(0, NAN))) self.assert_(math.isnan(math.pow(0, NAN)))
self.assertEqual(math.pow(1, NAN), 1) self.assertEqual(math.pow(1, NAN), 1)
self.assertEqual(1**NAN, 1)
self.assertEqual(1**INF, 1) # pow(0., x)
self.assertEqual(1**NINF, 1) self.assertEqual(math.pow(0., INF), 0.)
self.assertEqual(1**0, 1) self.assertEqual(math.pow(0., 3.), 0.)
self.assertEqual(1.**NAN, 1) self.assertEqual(math.pow(0., 2.3), 0.)
self.assertEqual(1.**INF, 1) self.assertEqual(math.pow(0., 2.), 0.)
self.assertEqual(1.**NINF, 1) self.assertEqual(math.pow(0., 0.), 1.)
self.assertEqual(1.**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): def testRadians(self):
self.assertRaises(TypeError, math.radians) self.assertRaises(TypeError, math.radians)
...@@ -417,7 +543,7 @@ class MathTests(unittest.TestCase): ...@@ -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)**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.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(-INF), -INF) self.assertEquals(math.sinh(NINF), NINF)
self.assert_(math.isnan(math.sinh(NAN))) self.assert_(math.isnan(math.sinh(NAN)))
def testSqrt(self): def testSqrt(self):
...@@ -555,7 +681,12 @@ class MathTests(unittest.TestCase): ...@@ -555,7 +681,12 @@ class MathTests(unittest.TestCase):
# no real versions of rect, polar # no real versions of rect, polar
continue continue
func = getattr(math, fn) 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) self.ftest("%s:%s(%r)" % (id, fn, ar), result, er)
def test_main(): def test_main():
......
...@@ -584,6 +584,29 @@ class ProcessTestCase(unittest.TestCase): ...@@ -584,6 +584,29 @@ class ProcessTestCase(unittest.TestCase):
os.remove(fname) os.remove(fname)
self.assertEqual(rc, 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.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 # Windows tests
...@@ -655,6 +678,29 @@ class ProcessTestCase(unittest.TestCase): ...@@ -655,6 +678,29 @@ class ProcessTestCase(unittest.TestCase):
' -c "import sys; sys.exit(47)"') ' -c "import sys; sys.exit(47)"')
self.assertEqual(rc, 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(): def test_main():
test_support.run_unittest(ProcessTestCase) test_support.run_unittest(ProcessTestCase)
......
...@@ -107,16 +107,8 @@ special_type(double d) ...@@ -107,16 +107,8 @@ special_type(double d)
#define P14 0.25*Py_MATH_PI #define P14 0.25*Py_MATH_PI
#define P12 0.5*Py_MATH_PI #define P12 0.5*Py_MATH_PI
#define P34 0.75*Py_MATH_PI #define P34 0.75*Py_MATH_PI
#ifdef MS_WINDOWS #define INF Py_HUGE_VAL
/* On Windows HUGE_VAL is an extern variable and not a constant. Since the #define N Py_NAN
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 U -9.5426319407711027e33 /* unlikely value, used as placeholder */ #define U -9.5426319407711027e33 /* unlikely value, used as placeholder */
/* First, the C functions that do the real work. Each of the c_* /* First, the C functions that do the real work. Each of the c_*
...@@ -128,15 +120,7 @@ special_type(double d) ...@@ -128,15 +120,7 @@ special_type(double d)
raised. raised.
*/ */
static Py_complex acos_special_values[7][7] = { 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 static Py_complex
c_acos(Py_complex z) c_acos(Py_complex z)
...@@ -177,15 +161,7 @@ PyDoc_STRVAR(c_acos_doc, ...@@ -177,15 +161,7 @@ PyDoc_STRVAR(c_acos_doc,
"Return the arc cosine of x."); "Return the arc cosine of x.");
static Py_complex acosh_special_values[7][7] = { 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 static Py_complex
c_acosh(Py_complex z) c_acosh(Py_complex z)
...@@ -237,15 +213,7 @@ PyDoc_STRVAR(c_asin_doc, ...@@ -237,15 +213,7 @@ PyDoc_STRVAR(c_asin_doc,
"Return the arc sine of x."); "Return the arc sine of x.");
static Py_complex asinh_special_values[7][7] = { 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 static Py_complex
c_asinh(Py_complex z) c_asinh(Py_complex z)
...@@ -323,15 +291,7 @@ PyDoc_STRVAR(c_atan_doc, ...@@ -323,15 +291,7 @@ PyDoc_STRVAR(c_atan_doc,
"Return the arc tangent of x."); "Return the arc tangent of x.");
static Py_complex atanh_special_values[7][7] = { 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 static Py_complex
c_atanh(Py_complex z) c_atanh(Py_complex z)
...@@ -404,15 +364,7 @@ PyDoc_STRVAR(c_cos_doc, ...@@ -404,15 +364,7 @@ PyDoc_STRVAR(c_cos_doc,
/* cosh(infinity + i*y) needs to be dealt with specially */ /* cosh(infinity + i*y) needs to be dealt with specially */
static Py_complex cosh_special_values[7][7] = { 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 static Py_complex
c_cosh(Py_complex z) c_cosh(Py_complex z)
...@@ -472,15 +424,7 @@ PyDoc_STRVAR(c_cosh_doc, ...@@ -472,15 +424,7 @@ PyDoc_STRVAR(c_cosh_doc,
/* exp(infinity + i*y) and exp(-infinity + i*y) need special treatment for /* exp(infinity + i*y) and exp(-infinity + i*y) need special treatment for
finite y */ finite y */
static Py_complex exp_special_values[7][7] = { 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 static Py_complex
c_exp(Py_complex z) c_exp(Py_complex z)
...@@ -538,15 +482,7 @@ PyDoc_STRVAR(c_exp_doc, ...@@ -538,15 +482,7 @@ PyDoc_STRVAR(c_exp_doc,
"Return the exponential value e**x."); "Return the exponential value e**x.");
static Py_complex log_special_values[7][7] = { 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 static Py_complex
c_log(Py_complex z) c_log(Py_complex z)
...@@ -658,15 +594,7 @@ PyDoc_STRVAR(c_sin_doc, ...@@ -658,15 +594,7 @@ PyDoc_STRVAR(c_sin_doc,
/* sinh(infinity + i*y) needs to be dealt with specially */ /* sinh(infinity + i*y) needs to be dealt with specially */
static Py_complex sinh_special_values[7][7] = { 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 static Py_complex
c_sinh(Py_complex z) c_sinh(Py_complex z)
...@@ -723,15 +651,7 @@ PyDoc_STRVAR(c_sinh_doc, ...@@ -723,15 +651,7 @@ PyDoc_STRVAR(c_sinh_doc,
"Return the hyperbolic sine of x."); "Return the hyperbolic sine of x.");
static Py_complex sqrt_special_values[7][7] = { 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 static Py_complex
c_sqrt(Py_complex z) c_sqrt(Py_complex z)
...@@ -826,15 +746,7 @@ PyDoc_STRVAR(c_tan_doc, ...@@ -826,15 +746,7 @@ PyDoc_STRVAR(c_tan_doc,
/* tanh(infinity + i*y) needs to be dealt with specially */ /* tanh(infinity + i*y) needs to be dealt with specially */
static Py_complex tanh_special_values[7][7] = { 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 static Py_complex
c_tanh(Py_complex z) c_tanh(Py_complex z)
...@@ -1043,15 +955,7 @@ the distance from 0 and phi the phase angle."); ...@@ -1043,15 +955,7 @@ the distance from 0 and phi the phase angle.");
*/ */
static Py_complex rect_special_values[7][7] = { 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 PyObject * static PyObject *
cmath_rect(PyObject *self, PyObject *args) cmath_rect(PyObject *self, PyObject *args)
...@@ -1176,4 +1080,119 @@ initcmath(void) ...@@ -1176,4 +1080,119 @@ initcmath(void)
PyModule_AddObject(m, "pi", PyModule_AddObject(m, "pi",
PyFloat_FromDouble(Py_MATH_PI)); PyFloat_FromDouble(Py_MATH_PI));
PyModule_AddObject(m, "e", PyFloat_FromDouble(Py_MATH_E)); 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)
})
} }
...@@ -414,6 +414,15 @@ math_modf(PyObject *self, PyObject *arg) ...@@ -414,6 +414,15 @@ math_modf(PyObject *self, PyObject *arg)
double y, x = PyFloat_AsDouble(arg); double y, x = PyFloat_AsDouble(arg);
if (x == -1.0 && PyErr_Occurred()) if (x == -1.0 && PyErr_Occurred())
return NULL; 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; errno = 0;
PyFPE_START_PROTECT("in math_modf", return 0); PyFPE_START_PROTECT("in math_modf", return 0);
x = modf(x, &y); x = modf(x, &y);
...@@ -586,6 +595,7 @@ math_pow(PyObject *self, PyObject *args) ...@@ -586,6 +595,7 @@ math_pow(PyObject *self, PyObject *args)
{ {
PyObject *ox, *oy; PyObject *ox, *oy;
double r, x, y; double r, x, y;
int odd_y;
if (! PyArg_UnpackTuple(args, "pow", 2, 2, &ox, &oy)) if (! PyArg_UnpackTuple(args, "pow", 2, 2, &ox, &oy))
return NULL; return NULL;
...@@ -593,37 +603,62 @@ math_pow(PyObject *self, PyObject *args) ...@@ -593,37 +603,62 @@ math_pow(PyObject *self, PyObject *args)
y = PyFloat_AsDouble(oy); y = PyFloat_AsDouble(oy);
if ((x == -1.0 || y == -1.0) && PyErr_Occurred()) if ((x == -1.0 || y == -1.0) && PyErr_Occurred())
return NULL; 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;
}
/* an infinite result arises either from:
(A) (+/-0.)**negative, /* deal directly with IEEE specials, to cope with problems on various
(B) overflow of x**y with both x and y finite (and x nonzero) platforms whose semantics don't exactly match C99 */
(C) (+/-inf)**positive, or if (!Py_IS_FINITE(x) || !Py_IS_FINITE(y)) {
(D) x**inf with |x| > 1, or x**-inf with |x| < 1. errno = 0;
if (Py_IS_NAN(x))
In case (A) we want ValueError to be raised. In case (B) r = y == 0. ? 1. : x; /* NaN**0 = 1 */
OverflowError should be raised. In cases (C) and (D) the infinite else if (Py_IS_NAN(y))
result should be returned. r = x == 1. ? 1. : y; /* 1**NaN = 1 */
*/ else if (Py_IS_INFINITY(x)) {
else if (Py_IS_INFINITY(r)) { odd_y = Py_IS_FINITE(y) && fmod(fabs(y), 2.0) == 1.0;
if (x == 0.) if (y > 0.)
errno = EDOM; r = odd_y ? x : fabs(x);
else if (Py_IS_FINITE(x) && Py_IS_FINITE(y)) else if (y == 0.)
errno = ERANGE; r = 1.;
else else /* y < 0. */
errno = 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.;
}
}
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)) if (errno && is_error(r))
......
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