Merged revisions 59666-59679 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r59666 | christian.heimes | 2008-01-02 19:28:32 +0100 (Wed, 02 Jan 2008) | 1 line
Made vs9to8 Unix compatible
........
r59669 | guido.van.rossum | 2008-01-02 20:00:46 +0100 (Wed, 02 Jan 2008) | 2 lines
Patch #1696. Don't attempt to close None in dry-run mode.
........
r59671 | jeffrey.yasskin | 2008-01-03 03:21:52 +0100 (Thu, 03 Jan 2008) | 6 lines
Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just
the complex_pow part), r56649, r56652, r56715, r57296, r57302, r57359, r57361,
r57372, r57738, r57739, r58017, r58039, r58040, and r59390, and new
documentation. The only significant difference is that round(x) returns a float
to preserve backward-compatibility. See http://bugs.python.org/issue1689.
........
r59672 | christian.heimes | 2008-01-03 16:41:30 +0100 (Thu, 03 Jan 2008) | 1 line
Issue #1726: Remove Python/atof.c from PCBuild/pythoncore.vcproj
........
r59675 | guido.van.rossum | 2008-01-03 20:12:44 +0100 (Thu, 03 Jan 2008) | 4 lines
Issue #1700, reported by Nguyen Quan Son, fix by Fredruk Lundh:
Regular Expression inline flags not handled correctly for some unicode
characters. (Forward port from 2.5.2.)
........
r59676 | christian.heimes | 2008-01-03 21:23:15 +0100 (Thu, 03 Jan 2008) | 1 line
Added math.isinf() and math.isnan()
........
r59677 | christian.heimes | 2008-01-03 22:14:48 +0100 (Thu, 03 Jan 2008) | 1 line
Some build bots don't compile mathmodule. There is an issue with the long definition of pi and euler
........
r59678 | christian.heimes | 2008-01-03 23:16:32 +0100 (Thu, 03 Jan 2008) | 2 lines
Modified PyImport_Import and PyImport_ImportModule to always use absolute imports by calling __import__ with an explicit level of 0
Added a new API function PyImport_ImportModuleNoBlock. It solves the problem with dead locks when mixing threads and imports
........
r59679 | christian.heimes | 2008-01-03 23:32:26 +0100 (Thu, 03 Jan 2008) | 1 line
Added copysign(x, y) function to the math module
........
diff --git a/Doc/c-api/utilities.rst b/Doc/c-api/utilities.rst
index 18e2733..b9eb390 100644
--- a/Doc/c-api/utilities.rst
+++ b/Doc/c-api/utilities.rst
@@ -184,7 +184,8 @@
single: modules (in module sys)
This is a simplified interface to :cfunc:`PyImport_ImportModuleEx` below,
- leaving the *globals* and *locals* arguments set to *NULL*. When the *name*
+ leaving the *globals* and *locals* arguments set to *NULL* and *level* set
+ to 0. When the *name*
argument contains a dot (when it specifies a submodule of a package), the
*fromlist* argument is set to the list ``['*']`` so that the return value is the
named module rather than the top-level package containing it as would otherwise
@@ -196,6 +197,27 @@
to find out. Starting with Python 2.4, a failing import of a module no longer
leaves the module in ``sys.modules``.
+ .. versionchanged:: 2.6
+ always use absolute imports
+
+ .. index:: single: modules (in module sys)
+
+
+.. cfunction:: PyObject* PyImport_ImportModuleNoBlock(const char *name)
+
+ .. index::
+ single: `cfunc:PyImport_ImportModule`
+
+ This version of `cfunc:PyImport_ImportModule` does not block. It's intended
+ to be used in C function which import other modules to execute a function.
+ The import may block if another thread holds the import lock. The function
+ `cfunc:PyImport_ImportModuleNoBlock` doesn't block. It first tries to fetch
+ the module from sys.modules and falls back to `cfunc:PyImport_ImportModule`
+ unless the the lock is hold. In the latter case the function raises an
+ ImportError.
+
+ .. versionadded:: 2.6
+
.. cfunction:: PyObject* PyImport_ImportModuleEx(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist)
@@ -214,6 +236,24 @@
Failing imports remove incomplete module objects, like with
:cfunc:`PyImport_ImportModule`.
+ .. versionchanged:: 2.6
+ The function is an alias for `cfunc:PyImport_ImportModuleLevel` with
+ -1 as level, meaning relative import.
+
+
+.. cfunction:: PyObject* PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level)
+
+ Import a module. This is best described by referring to the built-in Python
+ function :func:`__import__`, as the standard :func:`__import__` function calls
+ this function directly.
+
+ The return value is a new reference to the imported module or top-level package,
+ or *NULL* with an exception set on failure. Like for :func:`__import__`,
+ the return value when a submodule of a package was requested is normally the
+ top-level package, unless a non-empty *fromlist* was given.
+
+ ..versionadded:: 2.5
+
.. cfunction:: PyObject* PyImport_Import(PyObject *name)
@@ -222,6 +262,9 @@
current globals. This means that the import is done using whatever import hooks
are installed in the current environment.
+ .. versionchanged:: 2.6
+ always use absolute imports
+
.. cfunction:: PyObject* PyImport_ReloadModule(PyObject *m)
diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst
index 49fd77d..48efff5 100644
--- a/Doc/library/functions.rst
+++ b/Doc/library/functions.rst
@@ -915,10 +915,13 @@
.. function:: round(x[, n])
Return the floating point value *x* rounded to *n* digits after the decimal
- point. If *n* is omitted, it defaults to zero. The result is a floating point
- number. Values are rounded to the closest multiple of 10 to the power minus
- *n*; if two multiples are equally close, rounding is done away from 0 (so. for
- example, ``round(0.5)`` is ``1.0`` and ``round(-0.5)`` is ``-1.0``).
+ point. If *n* is omitted, it defaults to zero. Values are rounded to the
+ closest multiple of 10 to the power minus *n*; if two multiples are equally
+ close, rounding is done toward the even choice (so, for example, both
+ ``round(0.5)`` and ``round(-0.5)`` are ``0``, and ``round(1.5)`` is
+ ``2``). Delegates to ``x.__round__(n)``.
+
+ .. versionchanged:: 2.6
.. function:: set([iterable])
@@ -1064,6 +1067,14 @@
operators such as ``super(C, self)[name]``.
+.. function:: trunc(x)
+
+ Return the :class:`Real` value *x* truncated to an :class:`Integral` (usually
+ a long integer). Delegates to ``x.__trunc__()``.
+
+ .. versionadded:: 2.6
+
+
.. function:: tuple([iterable])
Return a tuple whose items are the same and in the same order as *iterable*'s
diff --git a/Doc/library/math.rst b/Doc/library/math.rst
index 7ea4aac..dc8c74a 100644
--- a/Doc/library/math.rst
+++ b/Doc/library/math.rst
@@ -26,8 +26,17 @@
.. function:: ceil(x)
- Return the ceiling of *x* as a float, the smallest integer value greater than or
- equal to *x*.
+ Return the ceiling of *x* as a float, the smallest integer value greater than
+ or equal to *x*. If *x* is not a float, delegates to ``x.__ceil__()``, which
+ should return an :class:`Integral` value.
+
+
+.. function:: copysign(x, y)
+
+ Return *x* with the sign of *y*. ``copysign`` copies the sign bit of an IEEE
+ 754 float, ``copysign(1, -0.0)`` returns *-1.0*.
+
+ ..versionadded:: 2.6
.. function:: fabs(x)
@@ -37,8 +46,9 @@
.. function:: floor(x)
- Return the floor of *x* as a float, the largest integer value less than or equal
- to *x*.
+ Return the floor of *x* as a float, the largest integer value less than or
+ equal to *x*. If *x* is not a float, delegates to ``x.__floor__()``, which
+ should return an :class:`Integral` value.
.. function:: fmod(x, y)
@@ -64,6 +74,23 @@
apart" the internal representation of a float in a portable way.
+.. function:: isinf(x)
+
+ Checks if the float *x* is positive or negative infinite.
+
+ ..versionadded:: 2.6
+
+
+.. function:: isnan(x)
+
+ Checks if the float *x* is a NaN (not a number). NaNs are part of the
+ IEEE 754 standards. Operation like but not limited to ``inf * 0``,
+ ``inf / inf`` or any operation involving a NaN, e.g. ``nan * 1``, return
+ a NaN.
+
+ ..versionadded:: 2.6
+
+
.. function:: ldexp(x, i)
Return ``x * (2**i)``. This is essentially the inverse of function
diff --git a/Doc/library/numbers.rst b/Doc/library/numbers.rst
new file mode 100644
index 0000000..d0f9c3b
--- /dev/null
+++ b/Doc/library/numbers.rst
@@ -0,0 +1,99 @@
+
+:mod:`numbers` --- Numeric abstract base classes
+================================================
+
+.. module:: numbers
+ :synopsis: Numeric abstract base classes (Complex, Real, Integral, etc.).
+
+The :mod:`numbers` module (:pep:`3141`) defines a hierarchy of numeric abstract
+base classes which progressively define more operations. These concepts also
+provide a way to distinguish exact from inexact types. None of the types defined
+in this module can be instantiated.
+
+
+.. class:: Number
+
+ The root of the numeric hierarchy. If you just want to check if an argument
+ *x* is a number, without caring what kind, use ``isinstance(x, Number)``.
+
+
+Exact and inexact operations
+----------------------------
+
+.. class:: Exact
+
+ Subclasses of this type have exact operations.
+
+ As long as the result of a homogenous operation is of the same type, you can
+ assume that it was computed exactly, and there are no round-off errors. Laws
+ like commutativity and associativity hold.
+
+
+.. class:: Inexact
+
+ Subclasses of this type have inexact operations.
+
+ Given X, an instance of :class:`Inexact`, it is possible that ``(X + -X) + 3
+ == 3``, but ``X + (-X + 3) == 0``. The exact form this error takes will vary
+ by type, but it's generally unsafe to compare this type for equality.
+
+
+The numeric tower
+-----------------
+
+.. class:: Complex
+
+ Subclasses of this type describe complex numbers and include the operations
+ that work on the builtin :class:`complex` type. These are: conversions to
+ :class:`complex` and :class:`bool`, :attr:`.real`, :attr:`.imag`, ``+``,
+ ``-``, ``*``, ``/``, :func:`abs`, :meth:`conjugate`, ``==``, and ``!=``. All
+ except ``-`` and ``!=`` are abstract.
+
+.. attribute:: Complex.real
+
+ Abstract. Retrieves the :class:`Real` component of this number.
+
+.. attribute:: Complex.imag
+
+ Abstract. Retrieves the :class:`Real` component of this number.
+
+.. method:: Complex.conjugate()
+
+ Abstract. Returns the complex conjugate. For example, ``(1+3j).conjugate() ==
+ (1-3j)``.
+
+.. class:: Real
+
+ To :class:`Complex`, :class:`Real` adds the operations that work on real
+ numbers.
+
+ In short, those are: a conversion to :class:`float`, :func:`trunc`,
+ :func:`round`, :func:`math.floor`, :func:`math.ceil`, :func:`divmod`, ``//``,
+ ``%``, ``<``, ``<=``, ``>``, and ``>=``.
+
+ Real also provides defaults for :func:`complex`, :attr:`Complex.real`,
+ :attr:`Complex.imag`, and :meth:`Complex.conjugate`.
+
+
+.. class:: Rational
+
+ Subtypes both :class:`Real` and :class:`Exact`, and adds
+ :attr:`Rational.numerator` and :attr:`Rational.denominator` properties, which
+ should be in lowest terms. With these, it provides a default for
+ :func:`float`.
+
+.. attribute:: Rational.numerator
+
+ Abstract.
+
+.. attribute:: Rational.denominator
+
+ Abstract.
+
+
+.. class:: Integral
+
+ Subtypes :class:`Rational` and adds a conversion to :class:`long`, the
+ 3-argument form of :func:`pow`, and the bit-string operations: ``<<``,
+ ``>>``, ``&``, ``^``, ``|``, ``~``. Provides defaults for :func:`float`,
+ :attr:`Rational.numerator`, and :attr:`Rational.denominator`.
diff --git a/Doc/library/numeric.rst b/Doc/library/numeric.rst
index 0d9d59f..d2b4d8b 100644
--- a/Doc/library/numeric.rst
+++ b/Doc/library/numeric.rst
@@ -6,16 +6,18 @@
********************************
The modules described in this chapter provide numeric and math-related functions
-and data types. The :mod:`math` and :mod:`cmath` contain various mathematical
-functions for floating-point and complex numbers. For users more interested in
-decimal accuracy than in speed, the :mod:`decimal` module supports exact
-representations of decimal numbers.
+and data types. The :mod:`numbers` module defines an abstract hierarchy of
+numeric types. The :mod:`math` and :mod:`cmath` modules contain various
+mathematical functions for floating-point and complex numbers. For users more
+interested in decimal accuracy than in speed, the :mod:`decimal` module supports
+exact representations of decimal numbers.
The following modules are documented in this chapter:
.. toctree::
+ numbers.rst
math.rst
cmath.rst
decimal.rst
diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst
index 0ec255f..3c7f8e6 100644
--- a/Doc/reference/datamodel.rst
+++ b/Doc/reference/datamodel.rst
@@ -152,7 +152,7 @@
object is accessed through the literal ``...`` or the built-in name
``Ellipsis``. Its truth value is true.
-Numbers
+:class:`numbers.Number`
.. index:: object: numeric
These are created by numeric literals and returned as results by arithmetic
@@ -164,7 +164,7 @@
Python distinguishes between integers, floating point numbers, and complex
numbers:
- Integers
+ :class:`numbers.Integral`
.. index:: object: integer
These represent elements from the mathematical set of integers (positive and
@@ -202,7 +202,7 @@
operation except left shift, if it yields a result in the plain integer domain
without causing overflow, will yield the same result when using mixed operands.
- Floating point numbers
+ :class:`numbers.Real` (:class:`float`)
.. index::
object: floating point
pair: floating point; number
@@ -217,7 +217,7 @@
overhead of using objects in Python, so there is no reason to complicate the
language with two kinds of floating point numbers.
- Complex numbers
+ :class:`numbers.Complex`
.. index::
object: complex
pair: complex; number
diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst
index 6e160ee..cf95636 100644
--- a/Doc/reference/expressions.rst
+++ b/Doc/reference/expressions.rst
@@ -768,7 +768,8 @@
``10**-2`` returns ``0.01``.
Raising ``0.0`` to a negative power results in a :exc:`ZeroDivisionError`.
-Raising a negative number to a fractional power results in a :exc:`ValueError`.
+Raising a negative number to a fractional power results in a :class:`complex`
+number. (Since Python 2.6. In earlier versions it raised a :exc:`ValueError`.)
.. _unary:
diff --git a/Include/import.h b/Include/import.h
index af9f339..05ad7f0 100644
--- a/Include/import.h
+++ b/Include/import.h
@@ -14,13 +14,10 @@
PyAPI_FUNC(PyObject *) PyImport_GetModuleDict(void);
PyAPI_FUNC(PyObject *) PyImport_AddModule(const char *name);
PyAPI_FUNC(PyObject *) PyImport_ImportModule(const char *name);
+PyAPI_FUNC(PyObject *) PyImport_ImportModuleNoBlock(const char *);
PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevel(char *name,
PyObject *globals, PyObject *locals, PyObject *fromlist, int level);
-/* For DLL compatibility */
-#undef PyImport_ImportModuleEx
-PyAPI_FUNC(PyObject *) PyImport_ImportModuleEx(
- char *name, PyObject *globals, PyObject *locals, PyObject *fromlist);
#define PyImport_ImportModuleEx(n, g, l, f) \
PyImport_ImportModuleLevel(n, g, l, f, -1)
diff --git a/Include/py_curses.h b/Include/py_curses.h
index 3cb23cc..c6cbdbd 100644
--- a/Include/py_curses.h
+++ b/Include/py_curses.h
@@ -90,7 +90,7 @@
#define import_curses() \
{ \
- PyObject *module = PyImport_ImportModule("_curses"); \
+ PyObject *module = PyImport_ImportModuleNoBlock("_curses"); \
if (module != NULL) { \
PyObject *module_dict = PyModule_GetDict(module); \
PyObject *c_api_object = PyDict_GetItemString(module_dict, "_C_API"); \
diff --git a/Include/pyport.h b/Include/pyport.h
index 82d305c..e4da8f4 100644
--- a/Include/pyport.h
+++ b/Include/pyport.h
@@ -335,12 +335,19 @@
/* High precision defintion of pi and e (Euler)
* The values are taken from libc6's math.h.
*/
+#ifndef Py_MATH_PIl
+#define Py_MATH_PIl 3.1415926535897932384626433832795029L
+#endif
#ifndef Py_MATH_PI
-#define Py_MATH_PI 3.1415926535897932384626433832795029L
+#define Py_MATH_PI 3.14159265358979323846
+#endif
+
+#ifndef Py_MATH_El
+#define Py_MATH_El 2.7182818284590452353602874713526625L
#endif
#ifndef Py_MATH_E
-#define Py_MATH_E 2.7182818284590452353602874713526625L
+#define Py_MATH_E 2.7182818284590452354
#endif
/* Py_IS_NAN(X)
diff --git a/Lib/distutils/command/build_scripts.py b/Lib/distutils/command/build_scripts.py
index 227bb9c..7b44264 100644
--- a/Lib/distutils/command/build_scripts.py
+++ b/Lib/distutils/command/build_scripts.py
@@ -110,7 +110,8 @@
if f:
f.close()
else:
- f.close()
+ if f:
+ f.close()
self.copy_file(script, outfile)
if os.name == 'posix':
diff --git a/Lib/sre_compile.py b/Lib/sre_compile.py
index f9f0736..f3b415d 100644
--- a/Lib/sre_compile.py
+++ b/Lib/sre_compile.py
@@ -516,7 +516,7 @@
indexgroup[i] = k
return _sre.compile(
- pattern, flags, code,
+ pattern, flags | p.pattern.flags, code,
p.pattern.groups-1,
groupindex, indexgroup
)
diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py
index 2d15f3a..8449794 100644
--- a/Lib/test/test_math.py
+++ b/Lib/test/test_math.py
@@ -231,6 +231,29 @@
self.ftest('tanh(0)', math.tanh(0), 0)
self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0)
+ def testCopysign(self):
+ self.assertEqual(math.copysign(1, 42), 1.0)
+ self.assertEqual(math.copysign(0., 42), 0.0)
+ self.assertEqual(math.copysign(1., -42), -1.0)
+ self.assertEqual(math.copysign(3, 0.), 3.0)
+ self.assertEqual(math.copysign(4., -0.), -4.0)
+
+ def testIsnan(self):
+ self.assert_(math.isnan(float("nan")))
+ self.assert_(math.isnan(float("inf")* 0.))
+ self.failIf(math.isnan(float("inf")))
+ self.failIf(math.isnan(0.))
+ self.failIf(math.isnan(1.))
+
+ def testIsinf(self):
+ self.assert_(math.isinf(float("inf")))
+ self.assert_(math.isinf(float("-inf")))
+ self.assert_(math.isinf(1E400))
+ self.assert_(math.isinf(-1E400))
+ self.failIf(math.isinf(float("nan")))
+ self.failIf(math.isinf(0.))
+ self.failIf(math.isinf(1.))
+
# RED_FLAG 16-Oct-2000 Tim
# While 2.0 is more consistent about exceptions than previous releases, it
# still fails this part of the test on some platforms. For now, we only
diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py
index 88fecbf..75c016e 100644
--- a/Lib/test/test_re.py
+++ b/Lib/test/test_re.py
@@ -632,6 +632,36 @@
self.assertEqual(re.compile("bla").match(a), None)
self.assertEqual(re.compile("").match(a).groups(), ())
+ def test_inline_flags(self):
+ # Bug #1700
+ upper_char = unichr(0x1ea0) # Latin Capital Letter A with Dot Bellow
+ lower_char = unichr(0x1ea1) # Latin Small Letter A with Dot Bellow
+
+ p = re.compile(upper_char, re.I | re.U)
+ q = p.match(lower_char)
+ self.assertNotEqual(q, None)
+
+ p = re.compile(lower_char, re.I | re.U)
+ q = p.match(upper_char)
+ self.assertNotEqual(q, None)
+
+ p = re.compile('(?i)' + upper_char, re.U)
+ q = p.match(lower_char)
+ self.assertNotEqual(q, None)
+
+ p = re.compile('(?i)' + lower_char, re.U)
+ q = p.match(upper_char)
+ self.assertNotEqual(q, None)
+
+ p = re.compile('(?iu)' + upper_char)
+ q = p.match(lower_char)
+ self.assertNotEqual(q, None)
+
+ p = re.compile('(?iu)' + lower_char)
+ q = p.match(upper_char)
+ self.assertNotEqual(q, None)
+
+
def run_re_tests():
from test.re_tests import benchmarks, tests, SUCCEED, FAIL, SYNTAX_ERROR
if verbose:
diff --git a/Mac/Modules/MacOS.c b/Mac/Modules/MacOS.c
index 7ba1dd6..4b86cf0 100644
--- a/Mac/Modules/MacOS.c
+++ b/Mac/Modules/MacOS.c
@@ -356,7 +356,7 @@
PyObject *m, *rv;
errors_loaded = 1;
- m = PyImport_ImportModule("macresource");
+ m = PyImport_ImportModuleNoBlock("macresource");
if (!m) {
if (Py_VerboseFlag)
PyErr_Print();
diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c
index 5e61938..050a5c1 100644
--- a/Modules/_ctypes/callbacks.c
+++ b/Modules/_ctypes/callbacks.c
@@ -367,7 +367,7 @@
if (context == NULL)
context = PyUnicode_FromString("_ctypes.DllGetClassObject");
- mod = PyImport_ImportModule("ctypes");
+ mod = PyImport_ImportModuleNoBlock("ctypes");
if (!mod) {
PyErr_WriteUnraisable(context ? context : Py_None);
/* There has been a warning before about this already */
@@ -446,7 +446,7 @@
if (context == NULL)
context = PyUnicode_FromString("_ctypes.DllCanUnloadNow");
- mod = PyImport_ImportModule("ctypes");
+ mod = PyImport_ImportModuleNoBlock("ctypes");
if (!mod) {
/* OutputDebugString("Could not import ctypes"); */
/* We assume that this error can only occur when shutting
diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c
index ea98d08..638b388 100644
--- a/Modules/_cursesmodule.c
+++ b/Modules/_cursesmodule.c
@@ -2316,7 +2316,7 @@
update_lines_cols(void)
{
PyObject *o;
- PyObject *m = PyImport_ImportModule("curses");
+ PyObject *m = PyImport_ImportModuleNoBlock("curses");
if (!m)
return 0;
diff --git a/Modules/cjkcodecs/cjkcodecs.h b/Modules/cjkcodecs/cjkcodecs.h
index 3ec24cb..fb6b5ce 100644
--- a/Modules/cjkcodecs/cjkcodecs.h
+++ b/Modules/cjkcodecs/cjkcodecs.h
@@ -245,7 +245,7 @@
static PyObject *cofunc = NULL;
if (cofunc == NULL) {
- PyObject *mod = PyImport_ImportModule("_multibytecodec");
+ PyObject *mod = PyImport_ImportModuleNoBlock("_multibytecodec");
if (mod == NULL)
return NULL;
cofunc = PyObject_GetAttrString(mod, "__create_codec");
diff --git a/Modules/datetimemodule.c b/Modules/datetimemodule.c
index 1e30f7e..b91a082 100644
--- a/Modules/datetimemodule.c
+++ b/Modules/datetimemodule.c
@@ -1329,7 +1329,7 @@
goto Done;
{
PyObject *format;
- PyObject *time = PyImport_ImportModule("time");
+ PyObject *time = PyImport_ImportModuleNoBlock("time");
if (time == NULL)
goto Done;
format = PyUnicode_FromString(PyString_AS_STRING(newfmt));
@@ -1357,7 +1357,7 @@
time_time(void)
{
PyObject *result = NULL;
- PyObject *time = PyImport_ImportModule("time");
+ PyObject *time = PyImport_ImportModuleNoBlock("time");
if (time != NULL) {
result = PyObject_CallMethod(time, "time", "()");
@@ -1375,7 +1375,7 @@
PyObject *time;
PyObject *result = NULL;
- time = PyImport_ImportModule("time");
+ time = PyImport_ImportModuleNoBlock("time");
if (time != NULL) {
result = PyObject_CallMethod(time, "struct_time",
"((iiiiiiiii))",
@@ -3821,7 +3821,7 @@
if (!PyArg_ParseTuple(args, "uu:strptime", &string, &format))
return NULL;
- if ((module = PyImport_ImportModule("time")) == NULL)
+ if ((module = PyImport_ImportModuleNoBlock("time")) == NULL)
return NULL;
obj = PyObject_CallMethod(module, "strptime", "uu", string, format);
Py_DECREF(module);
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 37fcc51..d449a2b 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -1199,7 +1199,7 @@
* the import and triggers an assertion.
*/
if (tmod == NULL) {
- tmod = PyImport_ImportModule("time");
+ tmod = PyImport_ImportModuleNoBlock("time");
if (tmod == NULL)
PyErr_Clear();
}
diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c
index edf5e9b..8992bae 100644
--- a/Modules/mathmodule.c
+++ b/Modules/mathmodule.c
@@ -133,6 +133,14 @@
"cos(x)\n\nReturn the cosine of x (measured in radians).")
FUNC1(cosh, cosh,
"cosh(x)\n\nReturn the hyperbolic cosine of x.")
+#if defined(MS_WINDOWS) || defined(HAVE_COPYSIGN)
+#ifdef MS_WINDOWS
+FUNC2(copysign, _copysign,
+#else
+FUNC2(copysign, copysign,
+#endif
+ "copysign(x,y)\n\nReturn x with the sign of y.");
+#endif
FUNC1(exp, exp,
"exp(x)\n\nReturn e raised to the power of x.")
FUNC1(fabs, fabs,
@@ -315,9 +323,8 @@
PyDoc_STRVAR(math_log10_doc,
"log10(x) -> the base 10 logarithm of x.");
-/* XXX(nnorwitz): Should we use the platform M_PI or something more accurate
- like: 3.14159265358979323846264338327950288 */
-static const double degToRad = 3.141592653589793238462643383 / 180.0;
+static const double degToRad = Py_MATH_PI / 180.0;
+static const double radToDeg = 180.0 / Py_MATH_PI;
static PyObject *
math_degrees(PyObject *self, PyObject *arg)
@@ -325,7 +332,7 @@
double x = PyFloat_AsDouble(arg);
if (x == -1.0 && PyErr_Occurred())
return NULL;
- return PyFloat_FromDouble(x / degToRad);
+ return PyFloat_FromDouble(x * radToDeg);
}
PyDoc_STRVAR(math_degrees_doc,
@@ -343,12 +350,42 @@
PyDoc_STRVAR(math_radians_doc,
"radians(x) -> converts angle x from degrees to radians");
+static PyObject *
+math_isnan(PyObject *self, PyObject *arg)
+{
+ double x = PyFloat_AsDouble(arg);
+ if (x == -1.0 && PyErr_Occurred())
+ return NULL;
+ return PyBool_FromLong((long)Py_IS_NAN(x));
+}
+
+PyDoc_STRVAR(math_isnan_doc,
+"isnan(x) -> bool\n\
+Checks if float x is not a number (NaN)");
+
+static PyObject *
+math_isinf(PyObject *self, PyObject *arg)
+{
+ double x = PyFloat_AsDouble(arg);
+ if (x == -1.0 && PyErr_Occurred())
+ return NULL;
+ return PyBool_FromLong((long)Py_IS_INFINITY(x));
+}
+
+PyDoc_STRVAR(math_isinf_doc,
+"isinf(x) -> bool\n\
+Checks if float x is infinite (positive or negative)");
+
+
static PyMethodDef math_methods[] = {
{"acos", math_acos, METH_O, math_acos_doc},
{"asin", math_asin, METH_O, math_asin_doc},
{"atan", math_atan, METH_O, math_atan_doc},
{"atan2", math_atan2, METH_VARARGS, math_atan2_doc},
{"ceil", math_ceil, METH_O, math_ceil_doc},
+#if defined(MS_WINDOWS) || defined(HAVE_COPYSIGN)
+ {"copysign", math_copysign, METH_VARARGS, math_copysign_doc},
+#endif
{"cos", math_cos, METH_O, math_cos_doc},
{"cosh", math_cosh, METH_O, math_cosh_doc},
{"degrees", math_degrees, METH_O, math_degrees_doc},
@@ -358,6 +395,8 @@
{"fmod", math_fmod, METH_VARARGS, math_fmod_doc},
{"frexp", math_frexp, METH_O, math_frexp_doc},
{"hypot", math_hypot, METH_VARARGS, math_hypot_doc},
+ {"isinf", math_isinf, METH_O, math_isinf_doc},
+ {"isnan", math_isnan, METH_O, math_isnan_doc},
{"ldexp", math_ldexp, METH_VARARGS, math_ldexp_doc},
{"log", math_log, METH_VARARGS, math_log_doc},
{"log10", math_log10, METH_O, math_log10_doc},
@@ -389,13 +428,13 @@
if (d == NULL)
goto finally;
- if (!(v = PyFloat_FromDouble(atan(1.0) * 4.0)))
+ if (!(v = PyFloat_FromDouble(Py_MATH_PI)))
goto finally;
if (PyDict_SetItemString(d, "pi", v) < 0)
goto finally;
Py_DECREF(v);
- if (!(v = PyFloat_FromDouble(exp(1.0))))
+ if (!(v = PyFloat_FromDouble(Py_MATH_E)))
goto finally;
if (PyDict_SetItemString(d, "e", v) < 0)
goto finally;
diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c
index 4c00203..9cc1227 100644
--- a/Modules/parsermodule.c
+++ b/Modules/parsermodule.c
@@ -3093,7 +3093,7 @@
* If this fails, the import of this module will fail because an
* exception will be raised here; should we clear the exception?
*/
- copyreg = PyImport_ImportModule("copy_reg");
+ copyreg = PyImport_ImportModuleNoBlock("copy_reg");
if (copyreg != NULL) {
PyObject *func, *pickler;
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 12bdde0..f3df9b7 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -4217,7 +4217,7 @@
return posix_error();
if (struct_rusage == NULL) {
- PyObject *m = PyImport_ImportModule("resource");
+ PyObject *m = PyImport_ImportModuleNoBlock("resource");
if (m == NULL)
return NULL;
struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h
index b41a040..135b716 100644
--- a/Modules/socketmodule.h
+++ b/Modules/socketmodule.h
@@ -222,7 +222,7 @@
void *api;
DPRINTF("Importing the %s C API...\n", apimodule);
- mod = PyImport_ImportModule(apimodule);
+ mod = PyImport_ImportModuleNoBlock(apimodule);
if (mod == NULL)
goto onError;
DPRINTF(" %s package found\n", apimodule);
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index 8854d0d..de8c99c 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -556,7 +556,7 @@
static PyObject *
time_strptime(PyObject *self, PyObject *args)
{
- PyObject *strptime_module = PyImport_ImportModule("_strptime");
+ PyObject *strptime_module = PyImport_ImportModuleNoBlock("_strptime");
PyObject *strptime_result;
if (!strptime_module)
@@ -668,7 +668,7 @@
{
PyObject* m;
- m = PyImport_ImportModule("time");
+ m = PyImport_ImportModuleNoBlock("time");
if (m == NULL) {
return NULL;
}
diff --git a/Modules/zipimport.c b/Modules/zipimport.c
index 08322b6..84985a8 100644
--- a/Modules/zipimport.c
+++ b/Modules/zipimport.c
@@ -766,7 +766,7 @@
let's avoid a stack overflow. */
return NULL;
importing_zlib = 1;
- zlib = PyImport_ImportModule("zlib"); /* import zlib */
+ zlib = PyImport_ImportModuleNoBlock("zlib");
importing_zlib = 0;
if (zlib != NULL) {
decompress = PyObject_GetAttrString(zlib,
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 5b94b0f..694f3b0 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -2800,7 +2800,7 @@
if (ucnhash_CAPI == NULL) {
/* load the unicode data module */
PyObject *m, *api;
- m = PyImport_ImportModule("unicodedata");
+ m = PyImport_ImportModuleNoBlock("unicodedata");
if (m == NULL)
goto ucnhashError;
api = PyObject_GetAttrString(m, "ucnhash_CAPI");
diff --git a/PC/VS8.0/pythoncore.vcproj b/PC/VS8.0/pythoncore.vcproj
index 6a16cd9..2a5392e 100644
--- a/PC/VS8.0/pythoncore.vcproj
+++ b/PC/VS8.0/pythoncore.vcproj
@@ -1599,10 +1599,6 @@
>
</File>
<File
- RelativePath="..\..\Python\atof.c"
- >
- </File>
- <File
RelativePath="..\..\Python\bltinmodule.c"
>
</File>
diff --git a/PCbuild/pythoncore.vcproj b/PCbuild/pythoncore.vcproj
index 413e407..930ee5f 100644
--- a/PCbuild/pythoncore.vcproj
+++ b/PCbuild/pythoncore.vcproj
@@ -1599,10 +1599,6 @@
>
</File>
<File
- RelativePath="..\Python\atof.c"
- >
- </File>
- <File
RelativePath="..\Python\bltinmodule.c"
>
</File>
diff --git a/Python/errors.c b/Python/errors.c
index 79f711d..cbc6f15 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -711,7 +711,7 @@
{
PyObject *mod, *dict, *func = NULL;
- mod = PyImport_ImportModule("warnings");
+ mod = PyImport_ImportModuleNoBlock("warnings");
if (mod != NULL) {
dict = PyModule_GetDict(mod);
func = PyDict_GetItemString(dict, "warn_explicit");
diff --git a/Python/import.c b/Python/import.c
index a7f6a48..658cc70 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -1896,6 +1896,53 @@
return result;
}
+/* Import a module without blocking
+ *
+ * At first it tries to fetch the module from sys.modules. If the module was
+ * never loaded before it loads it with PyImport_ImportModule() unless another
+ * thread holds the import lock. In the latter case the function raises an
+ * ImportError instead of blocking.
+ *
+ * Returns the module object with incremented ref count.
+ */
+PyObject *
+PyImport_ImportModuleNoBlock(const char *name)
+{
+ PyObject *result;
+ PyObject *modules;
+ long me;
+
+ /* Try to get the module from sys.modules[name] */
+ modules = PyImport_GetModuleDict();
+ if (modules == NULL)
+ return NULL;
+
+ result = PyDict_GetItemString(modules, name);
+ if (result != NULL) {
+ Py_INCREF(result);
+ return result;
+ }
+ else {
+ PyErr_Clear();
+ }
+
+ /* check the import lock
+ * me might be -1 but I ignore the error here, the lock function
+ * takes care of the problem */
+ me = PyThread_get_thread_ident();
+ if (import_lock_thread == -1 || import_lock_thread == me) {
+ /* no thread or me is holding the lock */
+ return PyImport_ImportModule(name);
+ }
+ else {
+ PyErr_Format(PyExc_ImportError,
+ "Failed to import %.200s because the import lock"
+ "is held by another thread.",
+ name);
+ return NULL;
+ }
+}
+
/* Forward declarations for helper routines */
static PyObject *get_parent(PyObject *globals, char *buf,
Py_ssize_t *p_buflen, int level);
@@ -1965,26 +2012,6 @@
return tail;
}
-/* For DLL compatibility */
-#undef PyImport_ImportModuleEx
-PyObject *
-PyImport_ImportModuleEx(char *name, PyObject *globals, PyObject *locals,
- PyObject *fromlist)
-{
- PyObject *result;
- lock_import();
- result = import_module_level(name, globals, locals, fromlist, -1);
- if (unlock_import() < 0) {
- Py_XDECREF(result);
- PyErr_SetString(PyExc_RuntimeError,
- "not holding the import lock");
- return NULL;
- }
- return result;
-}
-#define PyImport_ImportModuleEx(n, g, l, f) \
- PyImport_ImportModuleLevel(n, g, l, f, -1);
-
PyObject *
PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals,
PyObject *fromlist, int level)
@@ -2572,9 +2599,10 @@
if (import == NULL)
goto err;
- /* Call the __import__ function with the proper argument list */
- r = PyObject_CallFunctionObjArgs(import, module_name, globals,
- globals, silly_list, NULL);
+ /* Call the __import__ function with the proper argument list
+ * Always use absolute import here. */
+ r = PyObject_CallFunction(import, "OOOOi", module_name, globals,
+ globals, silly_list, 0, NULL);
err:
Py_XDECREF(globals);
diff --git a/Python/mactoolboxglue.c b/Python/mactoolboxglue.c
index 6688b02..bb1ebb1 100644
--- a/Python/mactoolboxglue.c
+++ b/Python/mactoolboxglue.c
@@ -36,7 +36,7 @@
PyObject *m;
PyObject *rv;
- m = PyImport_ImportModule("MacOS");
+ m = PyImport_ImportModuleNoBlock("MacOS");
if (!m) {
if (Py_VerboseFlag)
PyErr_Print();