mirror of https://github.com/python/cpython
Merged revisions 59921-59932 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r59923 | raymond.hettinger | 2008-01-11 19:04:55 +0100 (Fri, 11 Jan 2008) | 1 line Speed-up and simplify code urlparse's result objects. ........ r59924 | andrew.kuchling | 2008-01-11 20:33:24 +0100 (Fri, 11 Jan 2008) | 1 line Bug #1790: update link; remove outdated paragraph ........ r59925 | thomas.heller | 2008-01-11 20:34:06 +0100 (Fri, 11 Jan 2008) | 5 lines Raise an error instead of crashing with a segfault when a NULL function pointer is called. Will backport to release25-maint. ........ r59927 | thomas.heller | 2008-01-11 21:29:19 +0100 (Fri, 11 Jan 2008) | 4 lines Fix a potential 'SystemError: NULL result without error'. NULL may be a valid return value from PyLong_AsVoidPtr. Will backport to release25-maint. ........ r59928 | raymond.hettinger | 2008-01-12 00:25:18 +0100 (Sat, 12 Jan 2008) | 1 line Update the opcode docs for STORE_MAP and BUILD_MAP ........ r59929 | mark.dickinson | 2008-01-12 02:56:00 +0100 (Sat, 12 Jan 2008) | 4 lines Issue 1780: Allow leading and trailing whitespace in Decimal constructor, when constructing from a string. Disallow trailing newlines in Context.create_decimal. ........ r59930 | georg.brandl | 2008-01-12 11:53:29 +0100 (Sat, 12 Jan 2008) | 3 lines Move OSError docs to exceptions doc, remove obsolete descriptions from os docs, rework posix docs. ........ r59931 | georg.brandl | 2008-01-12 14:47:57 +0100 (Sat, 12 Jan 2008) | 3 lines Patch #1700288: Method cache optimization, by Armin Rigo, ported to 2.6 by Kevin Jacobs. ........ r59932 | georg.brandl | 2008-01-12 17:11:09 +0100 (Sat, 12 Jan 2008) | 2 lines Fix editing glitch. ........
This commit is contained in:
parent
25bb783c03
commit
a62da1daaf
|
@ -276,9 +276,10 @@ Decimal objects
|
||||||
|
|
||||||
Construct a new :class:`Decimal` object based from *value*.
|
Construct a new :class:`Decimal` object based from *value*.
|
||||||
|
|
||||||
*value* can be an integer, string, tuple, or another :class:`Decimal` object. If
|
*value* can be an integer, string, tuple, or another :class:`Decimal`
|
||||||
no *value* is given, returns ``Decimal("0")``. If *value* is a string, it
|
object. If no *value* is given, returns ``Decimal("0")``. If *value* is a
|
||||||
should conform to the decimal numeric string syntax::
|
string, it should conform to the decimal numeric string syntax after leading
|
||||||
|
and trailing whitespace characters are removed::
|
||||||
|
|
||||||
sign ::= '+' | '-'
|
sign ::= '+' | '-'
|
||||||
digit ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
|
digit ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
|
||||||
|
@ -308,6 +309,10 @@ Decimal objects
|
||||||
|
|
||||||
Once constructed, :class:`Decimal` objects are immutable.
|
Once constructed, :class:`Decimal` objects are immutable.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.6
|
||||||
|
leading and trailing whitespace characters are permitted when
|
||||||
|
creating a Decimal instance from a string.
|
||||||
|
|
||||||
Decimal floating point objects share many properties with the other built-in
|
Decimal floating point objects share many properties with the other built-in
|
||||||
numeric types such as :class:`float` and :class:`int`. All of the usual math
|
numeric types such as :class:`float` and :class:`int`. All of the usual math
|
||||||
operations and special methods apply. Likewise, decimal objects can be copied,
|
operations and special methods apply. Likewise, decimal objects can be copied,
|
||||||
|
@ -925,6 +930,9 @@ method. For example, ``C.exp(x)`` is equivalent to
|
||||||
>>> Decimal("3.4445") + Decimal(0) + Decimal("1.0023")
|
>>> Decimal("3.4445") + Decimal(0) + Decimal("1.0023")
|
||||||
Decimal("4.44")
|
Decimal("4.44")
|
||||||
|
|
||||||
|
This method implements the to-number operation of the IBM
|
||||||
|
specification. If the argument is a string, no leading or trailing
|
||||||
|
whitespace is permitted.
|
||||||
|
|
||||||
.. method:: Context.Etiny()
|
.. method:: Context.Etiny()
|
||||||
|
|
||||||
|
|
|
@ -506,10 +506,10 @@ the more significant byte last.
|
||||||
Works as ``BUILD_TUPLE``, but creates a set.
|
Works as ``BUILD_TUPLE``, but creates a set.
|
||||||
|
|
||||||
|
|
||||||
.. opcode:: BUILD_MAP (zero)
|
.. opcode:: BUILD_MAP (count)
|
||||||
|
|
||||||
Pushes a new empty dictionary object onto the stack. The argument is ignored
|
Pushes a new dictionary object onto the stack. The dictionary is pre-sized
|
||||||
and set to zero by the compiler.
|
to hold *count* entries.
|
||||||
|
|
||||||
|
|
||||||
.. opcode:: LOAD_ATTR (namei)
|
.. opcode:: LOAD_ATTR (namei)
|
||||||
|
@ -589,6 +589,10 @@ the more significant byte last.
|
||||||
Pushes a try block from a try-except clause onto the block stack. *delta* points
|
Pushes a try block from a try-except clause onto the block stack. *delta* points
|
||||||
to the finally block.
|
to the finally block.
|
||||||
|
|
||||||
|
.. opcode:: STORE_MAP ()
|
||||||
|
|
||||||
|
Store a key and value pair in a dictionary. Pops the key and value while leaving
|
||||||
|
the dictionary on the stack.
|
||||||
|
|
||||||
.. opcode:: LOAD_FAST (var_num)
|
.. opcode:: LOAD_FAST (var_num)
|
||||||
|
|
||||||
|
|
|
@ -207,9 +207,19 @@ The following exceptions are the exceptions that are actually raised.
|
||||||
|
|
||||||
.. exception:: OSError
|
.. exception:: OSError
|
||||||
|
|
||||||
This class is derived from :exc:`EnvironmentError` and is used primarily as the
|
.. index:: module: errno
|
||||||
:mod:`os` module's ``os.error`` exception. See :exc:`EnvironmentError` above for
|
|
||||||
a description of the possible associated values.
|
This exception is derived from :exc:`EnvironmentError`. It is raised when a
|
||||||
|
function returns a system-related error (not for illegal argument types or
|
||||||
|
other incidental errors). The :attr:`errno` attribute is a numeric error
|
||||||
|
code from :cdata:`errno`, and the :attr:`strerror` attribute is the
|
||||||
|
corresponding string, as would be printed by the C function :cfunc:`perror`.
|
||||||
|
See the module :mod:`errno`, which contains names for the error codes defined
|
||||||
|
by the underlying operating system.
|
||||||
|
|
||||||
|
For exceptions that involve a file system path (such as :func:`chdir` or
|
||||||
|
:func:`unlink`), the exception instance will contain a third attribute,
|
||||||
|
:attr:`filename`, which is the file name passed to the function.
|
||||||
|
|
||||||
|
|
||||||
.. exception:: OverflowError
|
.. exception:: OverflowError
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
:mod:`os` --- Miscellaneous operating system interfaces
|
:mod:`os` --- Miscellaneous operating system interfaces
|
||||||
=======================================================
|
=======================================================
|
||||||
|
|
||||||
|
@ -6,53 +5,32 @@
|
||||||
:synopsis: Miscellaneous operating system interfaces.
|
:synopsis: Miscellaneous operating system interfaces.
|
||||||
|
|
||||||
|
|
||||||
This module provides a more portable way of using operating system dependent
|
This module provides a portable way of using operating system dependent
|
||||||
functionality than importing an operating system dependent built-in module like
|
functionality. If you just want to read or write a file see :func:`open`, if
|
||||||
:mod:`posix` or :mod:`nt`. If you just want to read or write a file see
|
you want to manipulate paths, see the :mod:`os.path` module, and if you want to
|
||||||
:func:`open`, if you want to manipulate paths, see the :mod:`os.path`
|
read all the lines in all the files on the command line see the :mod:`fileinput`
|
||||||
module, and if you want to read all the lines in all the files on the
|
module. For creating temporary files and directories see the :mod:`tempfile`
|
||||||
command line see the :mod:`fileinput` module. For creating temporary
|
module, and for high-level file and directory handling see the :mod:`shutil`
|
||||||
files and directories see the :mod:`tempfile` module, and for high-level
|
module.
|
||||||
file and directory handling see the :mod:`shutil` module.
|
|
||||||
|
|
||||||
This module searches for an operating system dependent built-in module like
|
The design of all built-in operating system dependent modules of Python is such
|
||||||
:mod:`mac` or :mod:`posix` and exports the same functions and data as found
|
that as long as the same functionality is available, it uses the same interface;
|
||||||
there. The design of all built-in operating system dependent modules of Python
|
for example, the function ``os.stat(path)`` returns stat information about
|
||||||
is such that as long as the same functionality is available, it uses the same
|
*path* in the same format (which happens to have originated with the POSIX
|
||||||
interface; for example, the function ``os.stat(path)`` returns stat information
|
|
||||||
about *path* in the same format (which happens to have originated with the POSIX
|
|
||||||
interface).
|
interface).
|
||||||
|
|
||||||
Extensions peculiar to a particular operating system are also available through
|
Extensions peculiar to a particular operating system are also available through
|
||||||
the :mod:`os` module, but using them is of course a threat to portability!
|
the :mod:`os` module, but using them is of course a threat to portability!
|
||||||
|
|
||||||
Note that after the first time :mod:`os` is imported, there is *no* performance
|
.. note::
|
||||||
penalty in using functions from :mod:`os` instead of directly from the operating
|
|
||||||
system dependent built-in module, so there should be *no* reason not to use
|
|
||||||
:mod:`os`!
|
|
||||||
|
|
||||||
The :mod:`os` module contains many functions and data values. The items below
|
All functions in this module raise :exc:`OSError` in the case of invalid or
|
||||||
and in the following sub-sections are all available directly from the :mod:`os`
|
inaccessible file names and paths, or other arguments that have the correct
|
||||||
module.
|
type, but are not accepted by the operating system.
|
||||||
|
|
||||||
.. exception:: error
|
.. exception:: error
|
||||||
|
|
||||||
.. index:: module: errno
|
An alias for the built-in :exc:`OSError` exception.
|
||||||
|
|
||||||
This exception is raised when a function returns a system-related error (not for
|
|
||||||
illegal argument types or other incidental errors). This is also known as the
|
|
||||||
built-in exception :exc:`OSError`. The accompanying value is a pair containing
|
|
||||||
the numeric error code from :cdata:`errno` and the corresponding string, as
|
|
||||||
would be printed by the C function :cfunc:`perror`. See the module
|
|
||||||
:mod:`errno`, which contains names for the error codes defined by the underlying
|
|
||||||
operating system.
|
|
||||||
|
|
||||||
When exceptions are classes, this exception carries two attributes,
|
|
||||||
:attr:`errno` and :attr:`strerror`. The first holds the value of the C
|
|
||||||
:cdata:`errno` variable, and the latter holds the corresponding error message
|
|
||||||
from :cfunc:`strerror`. For exceptions that involve a file system path (such as
|
|
||||||
:func:`chdir` or :func:`unlink`), the exception instance will contain a third
|
|
||||||
attribute, :attr:`filename`, which is the file name passed to the function.
|
|
||||||
|
|
||||||
|
|
||||||
.. data:: name
|
.. data:: name
|
||||||
|
@ -645,7 +623,6 @@ platforms. For descriptions of their availability and use, consult
|
||||||
Files and Directories
|
Files and Directories
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
|
|
||||||
.. function:: access(path, mode)
|
.. function:: access(path, mode)
|
||||||
|
|
||||||
Use the real uid/gid to test for access to *path*. Note that most operations
|
Use the real uid/gid to test for access to *path*. Note that most operations
|
||||||
|
@ -1760,8 +1737,8 @@ Miscellaneous System Information
|
||||||
|
|
||||||
.. function:: getloadavg()
|
.. function:: getloadavg()
|
||||||
|
|
||||||
Return the number of processes in the system run queue averaged over the last 1,
|
Return the number of processes in the system run queue averaged over the last
|
||||||
5, and 15 minutes or raises :exc:`OSError` if the load average was
|
1, 5, and 15 minutes or raises :exc:`OSError` if the load average was
|
||||||
unobtainable.
|
unobtainable.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
:mod:`posix` --- The most common POSIX system calls
|
:mod:`posix` --- The most common POSIX system calls
|
||||||
===================================================
|
===================================================
|
||||||
|
|
||||||
|
@ -22,13 +21,8 @@ available through the :mod:`os` interface. Once :mod:`os` is imported, there is
|
||||||
:mod:`os` provides some additional functionality, such as automatically calling
|
:mod:`os` provides some additional functionality, such as automatically calling
|
||||||
:func:`putenv` when an entry in ``os.environ`` is changed.
|
:func:`putenv` when an entry in ``os.environ`` is changed.
|
||||||
|
|
||||||
The descriptions below are very terse; refer to the corresponding Unix manual
|
|
||||||
(or POSIX documentation) entry for more information. Arguments called *path*
|
|
||||||
refer to a pathname given as a string.
|
|
||||||
|
|
||||||
Errors are reported as exceptions; the usual exceptions are given for type
|
Errors are reported as exceptions; the usual exceptions are given for type
|
||||||
errors, while errors reported by the system calls raise :exc:`error` (a synonym
|
errors, while errors reported by the system calls raise :exc:`OSError`.
|
||||||
for the standard exception :exc:`OSError`), described below.
|
|
||||||
|
|
||||||
|
|
||||||
.. _posix-large-files:
|
.. _posix-large-files:
|
||||||
|
@ -42,9 +36,8 @@ Large File Support
|
||||||
|
|
||||||
.. sectionauthor:: Steve Clift <clift@mail.anacapa.net>
|
.. sectionauthor:: Steve Clift <clift@mail.anacapa.net>
|
||||||
|
|
||||||
|
Several operating systems (including AIX, HP-UX, Irix and Solaris) provide
|
||||||
Several operating systems (including AIX, HPUX, Irix and Solaris) provide
|
support for files that are larger than 2 GB from a C programming model where
|
||||||
support for files that are larger than 2 Gb from a C programming model where
|
|
||||||
:ctype:`int` and :ctype:`long` are 32-bit values. This is typically accomplished
|
:ctype:`int` and :ctype:`long` are 32-bit values. This is typically accomplished
|
||||||
by defining the relevant size and offset types as 64-bit values. Such files are
|
by defining the relevant size and offset types as 64-bit values. Such files are
|
||||||
sometimes referred to as :dfn:`large files`.
|
sometimes referred to as :dfn:`large files`.
|
||||||
|
@ -67,16 +60,16 @@ On large-file-capable Linux systems, this might work::
|
||||||
|
|
||||||
.. _posix-contents:
|
.. _posix-contents:
|
||||||
|
|
||||||
Module Contents
|
Notable Module Contents
|
||||||
---------------
|
-----------------------
|
||||||
|
|
||||||
Module :mod:`posix` defines the following data item:
|
|
||||||
|
|
||||||
|
In addition to many functions described in the :mod:`os` module documentation,
|
||||||
|
:mod:`posix` defines the following data item:
|
||||||
|
|
||||||
.. data:: environ
|
.. data:: environ
|
||||||
|
|
||||||
A dictionary representing the string environment at the time the interpreter was
|
A dictionary representing the string environment at the time the interpreter
|
||||||
started. For example, ``environ['HOME']`` is the pathname of your home
|
was started. For example, ``environ['HOME']`` is the pathname of your home
|
||||||
directory, equivalent to ``getenv("HOME")`` in C.
|
directory, equivalent to ``getenv("HOME")`` in C.
|
||||||
|
|
||||||
Modifying this dictionary does not affect the string environment passed on by
|
Modifying this dictionary does not affect the string environment passed on by
|
||||||
|
@ -90,7 +83,3 @@ Module :mod:`posix` defines the following data item:
|
||||||
updates the environment on modification. Note also that updating ``os.environ``
|
updates the environment on modification. Note also that updating ``os.environ``
|
||||||
will render this dictionary obsolete. Use of the :mod:`os` module version of
|
will render this dictionary obsolete. Use of the :mod:`os` module version of
|
||||||
this is recommended over direct access to the :mod:`posix` module.
|
this is recommended over direct access to the :mod:`posix` module.
|
||||||
|
|
||||||
Additional contents of this module should only be accessed via the :mod:`os`
|
|
||||||
module; refer to the documentation for that module for further information.
|
|
||||||
|
|
||||||
|
|
|
@ -110,12 +110,11 @@ between conformable Python objects and XML on the wire.
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
`XML-RPC HOWTO <http://www.tldp.org/HOWTO/XML-RPC-HOWTO/index.html>`_
|
`XML-RPC HOWTO <http://www.tldp.org/HOWTO/XML-RPC-HOWTO/index.html>`_
|
||||||
A good description of XML operation and client software in several languages.
|
A good description of XML-RPC operation and client software in several languages.
|
||||||
Contains pretty much everything an XML-RPC client developer needs to know.
|
Contains pretty much everything an XML-RPC client developer needs to know.
|
||||||
|
|
||||||
`XML-RPC Hacks page <http://xmlrpc-c.sourceforge.net/hacks.php>`_
|
`XML-RPC Introspection <http://xmlrpc-c.sourceforge.net/introspection.html>`_
|
||||||
Extensions for various open-source libraries to support introspection and
|
Describes the XML-RPC protocol extension for introspection.
|
||||||
multicall.
|
|
||||||
|
|
||||||
|
|
||||||
.. _serverproxy-objects:
|
.. _serverproxy-objects:
|
||||||
|
@ -167,11 +166,6 @@ grouped under the reserved :attr:`system` member:
|
||||||
no such string is available, an empty string is returned. The documentation
|
no such string is available, an empty string is returned. The documentation
|
||||||
string may contain HTML markup.
|
string may contain HTML markup.
|
||||||
|
|
||||||
Introspection methods are currently supported by servers written in PHP, C and
|
|
||||||
Microsoft .NET. Partial introspection support is included in recent updates to
|
|
||||||
UserLand Frontier. Introspection support for Perl, Python and Java is available
|
|
||||||
at the `XML-RPC Hacks <http://xmlrpc-c.sourceforge.net/hacks.php>`_ page.
|
|
||||||
|
|
||||||
|
|
||||||
.. _boolean-objects:
|
.. _boolean-objects:
|
||||||
|
|
||||||
|
|
|
@ -374,6 +374,9 @@ typedef struct _typeobject {
|
||||||
PyObject *tp_weaklist;
|
PyObject *tp_weaklist;
|
||||||
destructor tp_del;
|
destructor tp_del;
|
||||||
|
|
||||||
|
/* Type attribute cache version tag. Added in version 2.6 */
|
||||||
|
unsigned int tp_version_tag;
|
||||||
|
|
||||||
#ifdef COUNT_ALLOCS
|
#ifdef COUNT_ALLOCS
|
||||||
/* these must be last and never explicitly initialized */
|
/* these must be last and never explicitly initialized */
|
||||||
Py_ssize_t tp_allocs;
|
Py_ssize_t tp_allocs;
|
||||||
|
@ -525,6 +528,10 @@ given type object has a specified feature.
|
||||||
#define Py_TPFLAGS_HAVE_STACKLESS_EXTENSION 0
|
#define Py_TPFLAGS_HAVE_STACKLESS_EXTENSION 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Objects support type attribute cache */
|
||||||
|
#define Py_TPFLAGS_HAVE_VERSION_TAG (1L<<18)
|
||||||
|
#define Py_TPFLAGS_VALID_VERSION_TAG (1L<<19)
|
||||||
|
|
||||||
/* These flags are used to determine if a type is a subclass. */
|
/* These flags are used to determine if a type is a subclass. */
|
||||||
#define Py_TPFLAGS_INT_SUBCLASS (1L<<23)
|
#define Py_TPFLAGS_INT_SUBCLASS (1L<<23)
|
||||||
#define Py_TPFLAGS_LONG_SUBCLASS (1L<<24)
|
#define Py_TPFLAGS_LONG_SUBCLASS (1L<<24)
|
||||||
|
@ -538,6 +545,7 @@ given type object has a specified feature.
|
||||||
|
|
||||||
#define Py_TPFLAGS_DEFAULT ( \
|
#define Py_TPFLAGS_DEFAULT ( \
|
||||||
Py_TPFLAGS_HAVE_STACKLESS_EXTENSION | \
|
Py_TPFLAGS_HAVE_STACKLESS_EXTENSION | \
|
||||||
|
Py_TPFLAGS_HAVE_VERSION_TAG | \
|
||||||
0)
|
0)
|
||||||
|
|
||||||
#define PyType_HasFeature(t,f) (((t)->tp_flags & (f)) != 0)
|
#define PyType_HasFeature(t,f) (((t)->tp_flags & (f)) != 0)
|
||||||
|
|
|
@ -123,5 +123,11 @@ class CFuncPtrTestCase(unittest.TestCase):
|
||||||
self.failUnlessEqual(strtok(None, b"\n"), "c")
|
self.failUnlessEqual(strtok(None, b"\n"), "c")
|
||||||
self.failUnlessEqual(strtok(None, b"\n"), None)
|
self.failUnlessEqual(strtok(None, b"\n"), None)
|
||||||
|
|
||||||
|
def test_NULL_funcptr(self):
|
||||||
|
tp = CFUNCTYPE(c_int)
|
||||||
|
func = tp() # NULL function pointer
|
||||||
|
# raise a ValueError when we try to call it
|
||||||
|
self.assertRaises(ValueError, func)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -524,6 +524,8 @@ class Decimal(_numbers.Real, _numbers.Inexact):
|
||||||
Decimal("314")
|
Decimal("314")
|
||||||
>>> Decimal(Decimal(314)) # another decimal instance
|
>>> Decimal(Decimal(314)) # another decimal instance
|
||||||
Decimal("314")
|
Decimal("314")
|
||||||
|
>>> Decimal(' 3.14 \\n') # leading and trailing whitespace okay
|
||||||
|
Decimal("3.14")
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Note that the coefficient, self._int, is actually stored as
|
# Note that the coefficient, self._int, is actually stored as
|
||||||
|
@ -539,7 +541,7 @@ class Decimal(_numbers.Real, _numbers.Inexact):
|
||||||
# From a string
|
# From a string
|
||||||
# REs insist on real strings, so we can too.
|
# REs insist on real strings, so we can too.
|
||||||
if isinstance(value, str):
|
if isinstance(value, str):
|
||||||
m = _parser(value)
|
m = _parser(value.strip())
|
||||||
if m is None:
|
if m is None:
|
||||||
if context is None:
|
if context is None:
|
||||||
context = getcontext()
|
context = getcontext()
|
||||||
|
@ -3542,7 +3544,16 @@ class Context(object):
|
||||||
return rounding
|
return rounding
|
||||||
|
|
||||||
def create_decimal(self, num='0'):
|
def create_decimal(self, num='0'):
|
||||||
"""Creates a new Decimal instance but using self as context."""
|
"""Creates a new Decimal instance but using self as context.
|
||||||
|
|
||||||
|
This method implements the to-number operation of the
|
||||||
|
IBM Decimal specification."""
|
||||||
|
|
||||||
|
if isinstance(num, str) and num != num.strip():
|
||||||
|
return self._raise_error(ConversionSyntax,
|
||||||
|
"no trailing or leading whitespace is "
|
||||||
|
"permitted.")
|
||||||
|
|
||||||
d = Decimal(num, context=self)
|
d = Decimal(num, context=self)
|
||||||
if d._isnan() and len(d._int) > self.prec - self._clamp:
|
if d._isnan() and len(d._int) > self.prec - self._clamp:
|
||||||
return self._raise_error(ConversionSyntax,
|
return self._raise_error(ConversionSyntax,
|
||||||
|
@ -5157,7 +5168,7 @@ _parser = re.compile(r""" # A numeric string consists of:
|
||||||
(?P<diag>\d*) # with (possibly empty) diagnostic information.
|
(?P<diag>\d*) # with (possibly empty) diagnostic information.
|
||||||
)
|
)
|
||||||
# \s*
|
# \s*
|
||||||
$
|
\Z
|
||||||
""", re.VERBOSE | re.IGNORECASE).match
|
""", re.VERBOSE | re.IGNORECASE).match
|
||||||
|
|
||||||
_all_zeros = re.compile('0*$').match
|
_all_zeros = re.compile('0*$').match
|
||||||
|
|
|
@ -429,6 +429,10 @@ class DecimalExplicitConstructionTest(unittest.TestCase):
|
||||||
#just not a number
|
#just not a number
|
||||||
self.assertEqual(str(Decimal('ugly')), 'NaN')
|
self.assertEqual(str(Decimal('ugly')), 'NaN')
|
||||||
|
|
||||||
|
#leading and trailing whitespace permitted
|
||||||
|
self.assertEqual(str(Decimal('1.3E4 \n')), '1.3E+4')
|
||||||
|
self.assertEqual(str(Decimal(' -7.89')), '-7.89')
|
||||||
|
|
||||||
def test_explicit_from_tuples(self):
|
def test_explicit_from_tuples(self):
|
||||||
|
|
||||||
#zero
|
#zero
|
||||||
|
@ -517,6 +521,10 @@ class DecimalExplicitConstructionTest(unittest.TestCase):
|
||||||
self.assertEqual(str(d), '456789')
|
self.assertEqual(str(d), '456789')
|
||||||
d = nc.create_decimal('456789')
|
d = nc.create_decimal('456789')
|
||||||
self.assertEqual(str(d), '4.57E+5')
|
self.assertEqual(str(d), '4.57E+5')
|
||||||
|
# leading and trailing whitespace should result in a NaN;
|
||||||
|
# spaces are already checked in Cowlishaw's test-suite, so
|
||||||
|
# here we just check that a trailing newline results in a NaN
|
||||||
|
self.assertEqual(str(nc.create_decimal('3.14\n')), 'NaN')
|
||||||
|
|
||||||
# from tuples
|
# from tuples
|
||||||
d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
|
d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
|
||||||
|
|
|
@ -37,46 +37,11 @@ _parse_cache = {}
|
||||||
|
|
||||||
def clear_cache():
|
def clear_cache():
|
||||||
"""Clear the parse cache."""
|
"""Clear the parse cache."""
|
||||||
global _parse_cache
|
_parse_cache.clear()
|
||||||
_parse_cache = {}
|
|
||||||
|
|
||||||
|
|
||||||
class BaseResult(tuple):
|
class ResultMixin(object):
|
||||||
"""Base class for the parsed result objects.
|
"""Shared methods for the parsed result objects."""
|
||||||
|
|
||||||
This provides the attributes shared by the two derived result
|
|
||||||
objects as read-only properties. The derived classes are
|
|
||||||
responsible for checking the right number of arguments were
|
|
||||||
supplied to the constructor.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__slots__ = ()
|
|
||||||
|
|
||||||
# Attributes that access the basic components of the URL:
|
|
||||||
|
|
||||||
@property
|
|
||||||
def scheme(self):
|
|
||||||
return self[0]
|
|
||||||
|
|
||||||
@property
|
|
||||||
def netloc(self):
|
|
||||||
return self[1]
|
|
||||||
|
|
||||||
@property
|
|
||||||
def path(self):
|
|
||||||
return self[2]
|
|
||||||
|
|
||||||
@property
|
|
||||||
def query(self):
|
|
||||||
return self[-2]
|
|
||||||
|
|
||||||
@property
|
|
||||||
def fragment(self):
|
|
||||||
return self[-1]
|
|
||||||
|
|
||||||
# Additional attributes that provide access to parsed-out portions
|
|
||||||
# of the netloc:
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def username(self):
|
def username(self):
|
||||||
|
@ -116,31 +81,20 @@ class BaseResult(tuple):
|
||||||
return int(port, 10)
|
return int(port, 10)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
from collections import namedtuple
|
||||||
|
|
||||||
class SplitResult(BaseResult):
|
class SplitResult(namedtuple('SplitResult', 'scheme netloc path query fragment'), ResultMixin):
|
||||||
|
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
def __new__(cls, scheme, netloc, path, query, fragment):
|
|
||||||
return BaseResult.__new__(
|
|
||||||
cls, (scheme, netloc, path, query, fragment))
|
|
||||||
|
|
||||||
def geturl(self):
|
def geturl(self):
|
||||||
return urlunsplit(self)
|
return urlunsplit(self)
|
||||||
|
|
||||||
|
|
||||||
class ParseResult(BaseResult):
|
class ParseResult(namedtuple('ParseResult', 'scheme netloc path params query fragment'), ResultMixin):
|
||||||
|
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
def __new__(cls, scheme, netloc, path, params, query, fragment):
|
|
||||||
return BaseResult.__new__(
|
|
||||||
cls, (scheme, netloc, path, params, query, fragment))
|
|
||||||
|
|
||||||
@property
|
|
||||||
def params(self):
|
|
||||||
return self[3]
|
|
||||||
|
|
||||||
def geturl(self):
|
def geturl(self):
|
||||||
return urlunparse(self)
|
return urlunparse(self)
|
||||||
|
|
||||||
|
|
|
@ -2882,7 +2882,7 @@ CFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
&& (PyLong_Check(PyTuple_GET_ITEM(args, 0)))) {
|
&& (PyLong_Check(PyTuple_GET_ITEM(args, 0)))) {
|
||||||
CDataObject *ob;
|
CDataObject *ob;
|
||||||
void *ptr = PyLong_AsVoidPtr(PyTuple_GET_ITEM(args, 0));
|
void *ptr = PyLong_AsVoidPtr(PyTuple_GET_ITEM(args, 0));
|
||||||
if (ptr == NULL)
|
if (ptr == NULL && PyErr_Occurred())
|
||||||
return NULL;
|
return NULL;
|
||||||
ob = (CDataObject *)GenericCData_new(type, args, kwds);
|
ob = (CDataObject *)GenericCData_new(type, args, kwds);
|
||||||
if (ob == NULL)
|
if (ob == NULL)
|
||||||
|
@ -3291,6 +3291,11 @@ CFuncPtr_call(CFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
|
||||||
|
|
||||||
|
|
||||||
pProc = *(void **)self->b_ptr;
|
pProc = *(void **)self->b_ptr;
|
||||||
|
if (pProc == NULL) {
|
||||||
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
"attempt to call NULL function pointer");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
#ifdef MS_WIN32
|
#ifdef MS_WIN32
|
||||||
if (self->index) {
|
if (self->index) {
|
||||||
/* It's a COM method */
|
/* It's a COM method */
|
||||||
|
|
|
@ -947,6 +947,7 @@ PyObject_GenericGetAttr(PyObject *obj, PyObject *name)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 /* XXX this is not quite _PyType_Lookup anymore */
|
||||||
/* Inline _PyType_Lookup */
|
/* Inline _PyType_Lookup */
|
||||||
{
|
{
|
||||||
Py_ssize_t i, n;
|
Py_ssize_t i, n;
|
||||||
|
@ -967,6 +968,9 @@ PyObject_GenericGetAttr(PyObject *obj, PyObject *name)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
descr = _PyType_Lookup(tp, name);
|
||||||
|
#endif
|
||||||
|
|
||||||
Py_XINCREF(descr);
|
Py_XINCREF(descr);
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,171 @@
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Support type attribute cache */
|
||||||
|
|
||||||
|
/* The cache can keep references to the names alive for longer than
|
||||||
|
they normally would. This is why the maximum size is limited to
|
||||||
|
MCACHE_MAX_ATTR_SIZE, since it might be a problem if very large
|
||||||
|
strings are used as attribute names. */
|
||||||
|
#define MCACHE_MAX_ATTR_SIZE 100
|
||||||
|
#define MCACHE_SIZE_EXP 10
|
||||||
|
#define MCACHE_HASH(version, name_hash) \
|
||||||
|
(((unsigned int)(version) * (unsigned int)(name_hash)) \
|
||||||
|
>> (8*sizeof(unsigned int) - MCACHE_SIZE_EXP))
|
||||||
|
#define MCACHE_HASH_METHOD(type, name) \
|
||||||
|
MCACHE_HASH((type)->tp_version_tag, \
|
||||||
|
((PyStringObject *)(name))->ob_shash)
|
||||||
|
#define MCACHE_CACHEABLE_NAME(name) \
|
||||||
|
PyString_CheckExact(name) && \
|
||||||
|
PyString_GET_SIZE(name) <= MCACHE_MAX_ATTR_SIZE
|
||||||
|
|
||||||
|
struct method_cache_entry {
|
||||||
|
unsigned int version;
|
||||||
|
PyObject *name; /* reference to exactly a str or None */
|
||||||
|
PyObject *value; /* borrowed */
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct method_cache_entry method_cache[1 << MCACHE_SIZE_EXP];
|
||||||
|
static unsigned int next_version_tag = 0;
|
||||||
|
|
||||||
|
static void
|
||||||
|
type_modified(PyTypeObject *type)
|
||||||
|
{
|
||||||
|
/* Invalidate any cached data for the specified type and all
|
||||||
|
subclasses. This function is called after the base
|
||||||
|
classes, mro, or attributes of the type are altered.
|
||||||
|
|
||||||
|
Invariants:
|
||||||
|
|
||||||
|
- Py_TPFLAGS_VALID_VERSION_TAG is never set if
|
||||||
|
Py_TPFLAGS_HAVE_VERSION_TAG is not set (e.g. on type
|
||||||
|
objects coming from non-recompiled extension modules)
|
||||||
|
|
||||||
|
- before Py_TPFLAGS_VALID_VERSION_TAG can be set on a type,
|
||||||
|
it must first be set on all super types.
|
||||||
|
|
||||||
|
This function clears the Py_TPFLAGS_VALID_VERSION_TAG of a
|
||||||
|
type (so it must first clear it on all subclasses). The
|
||||||
|
tp_version_tag value is meaningless unless this flag is set.
|
||||||
|
We don't assign new version tags eagerly, but only as
|
||||||
|
needed.
|
||||||
|
*/
|
||||||
|
PyObject *raw, *ref;
|
||||||
|
Py_ssize_t i, n;
|
||||||
|
|
||||||
|
if(!PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG))
|
||||||
|
return;
|
||||||
|
|
||||||
|
raw = type->tp_subclasses;
|
||||||
|
if (raw != NULL) {
|
||||||
|
n = PyList_GET_SIZE(raw);
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
ref = PyList_GET_ITEM(raw, i);
|
||||||
|
ref = PyWeakref_GET_OBJECT(ref);
|
||||||
|
if (ref != Py_None) {
|
||||||
|
type_modified((PyTypeObject *)ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
type_mro_modified(PyTypeObject *type, PyObject *bases) {
|
||||||
|
/*
|
||||||
|
Check that all base classes or elements of the mro of type are
|
||||||
|
able to be cached. This function is called after the base
|
||||||
|
classes or mro of the type are altered.
|
||||||
|
|
||||||
|
Unset HAVE_VERSION_TAG and VALID_VERSION_TAG if the type
|
||||||
|
inherits from an old-style class, either directly or if it
|
||||||
|
appears in the MRO of a new-style class. No support either for
|
||||||
|
custom MROs that include types that are not officially super
|
||||||
|
types.
|
||||||
|
|
||||||
|
Called from mro_internal, which will subsequently be called on
|
||||||
|
each subclass when their mro is recursively updated.
|
||||||
|
*/
|
||||||
|
Py_ssize_t i, n;
|
||||||
|
int clear = 0;
|
||||||
|
|
||||||
|
if(!PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG))
|
||||||
|
return;
|
||||||
|
|
||||||
|
n = PyTuple_GET_SIZE(bases);
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
PyObject *b = PyTuple_GET_ITEM(bases, i);
|
||||||
|
PyTypeObject *cls;
|
||||||
|
|
||||||
|
if (!PyType_Check(b) ) {
|
||||||
|
clear = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cls = (PyTypeObject *)b;
|
||||||
|
|
||||||
|
if (!PyType_HasFeature(cls, Py_TPFLAGS_HAVE_VERSION_TAG) ||
|
||||||
|
!PyType_IsSubtype(type, cls)) {
|
||||||
|
clear = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clear)
|
||||||
|
type->tp_flags &= ~(Py_TPFLAGS_HAVE_VERSION_TAG|
|
||||||
|
Py_TPFLAGS_VALID_VERSION_TAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
assign_version_tag(PyTypeObject *type)
|
||||||
|
{
|
||||||
|
/* Ensure that the tp_version_tag is valid and set
|
||||||
|
Py_TPFLAGS_VALID_VERSION_TAG. To respect the invariant, this
|
||||||
|
must first be done on all super classes. Return 0 if this
|
||||||
|
cannot be done, 1 if Py_TPFLAGS_VALID_VERSION_TAG.
|
||||||
|
*/
|
||||||
|
Py_ssize_t i, n;
|
||||||
|
PyObject *bases;
|
||||||
|
|
||||||
|
if (PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG))
|
||||||
|
return 1;
|
||||||
|
if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG))
|
||||||
|
return 0;
|
||||||
|
if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
type->tp_version_tag = next_version_tag++;
|
||||||
|
/* for stress-testing: next_version_tag &= 0xFF; */
|
||||||
|
|
||||||
|
if (type->tp_version_tag == 0) {
|
||||||
|
/* wrap-around or just starting Python - clear the whole
|
||||||
|
cache by filling names with references to Py_None.
|
||||||
|
Values are also set to NULL for added protection, as they
|
||||||
|
are borrowed reference */
|
||||||
|
for (i = 0; i < (1 << MCACHE_SIZE_EXP); i++) {
|
||||||
|
method_cache[i].value = NULL;
|
||||||
|
Py_XDECREF(method_cache[i].name);
|
||||||
|
method_cache[i].name = Py_None;
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
}
|
||||||
|
/* mark all version tags as invalid */
|
||||||
|
type_modified(&PyBaseObject_Type);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
bases = type->tp_bases;
|
||||||
|
n = PyTuple_GET_SIZE(bases);
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
PyObject *b = PyTuple_GET_ITEM(bases, i);
|
||||||
|
assert(PyType_Check(b));
|
||||||
|
if (!assign_version_tag((PyTypeObject *)b))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
type->tp_flags |= Py_TPFLAGS_VALID_VERSION_TAG;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyMemberDef type_members[] = {
|
static PyMemberDef type_members[] = {
|
||||||
{"__basicsize__", T_INT, offsetof(PyTypeObject,tp_basicsize),READONLY},
|
{"__basicsize__", T_INT, offsetof(PyTypeObject,tp_basicsize),READONLY},
|
||||||
{"__itemsize__", T_INT, offsetof(PyTypeObject, tp_itemsize), READONLY},
|
{"__itemsize__", T_INT, offsetof(PyTypeObject, tp_itemsize), READONLY},
|
||||||
|
@ -130,6 +295,8 @@ type_set_module(PyTypeObject *type, PyObject *value, void *context)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type_modified(type);
|
||||||
|
|
||||||
return PyDict_SetItemString(type->tp_dict, "__module__", value);
|
return PyDict_SetItemString(type->tp_dict, "__module__", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1299,6 +1466,14 @@ mro_internal(PyTypeObject *type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
type->tp_mro = tuple;
|
type->tp_mro = tuple;
|
||||||
|
|
||||||
|
type_mro_modified(type, type->tp_mro);
|
||||||
|
/* corner case: the old-style super class might have been hidden
|
||||||
|
from the custom MRO */
|
||||||
|
type_mro_modified(type, type->tp_bases);
|
||||||
|
|
||||||
|
type_modified(type);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2026,6 +2201,16 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
|
||||||
{
|
{
|
||||||
Py_ssize_t i, n;
|
Py_ssize_t i, n;
|
||||||
PyObject *mro, *res, *base, *dict;
|
PyObject *mro, *res, *base, *dict;
|
||||||
|
unsigned int h;
|
||||||
|
|
||||||
|
if (MCACHE_CACHEABLE_NAME(name) &&
|
||||||
|
PyType_HasFeature(type,Py_TPFLAGS_VALID_VERSION_TAG)) {
|
||||||
|
/* fast path */
|
||||||
|
h = MCACHE_HASH_METHOD(type, name);
|
||||||
|
if (method_cache[h].version == type->tp_version_tag &&
|
||||||
|
method_cache[h].name == name)
|
||||||
|
return method_cache[h].value;
|
||||||
|
}
|
||||||
|
|
||||||
/* Look in tp_dict of types in MRO */
|
/* Look in tp_dict of types in MRO */
|
||||||
mro = type->tp_mro;
|
mro = type->tp_mro;
|
||||||
|
@ -2036,6 +2221,7 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
|
||||||
if (mro == NULL)
|
if (mro == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
res = NULL;
|
||||||
assert(PyTuple_Check(mro));
|
assert(PyTuple_Check(mro));
|
||||||
n = PyTuple_GET_SIZE(mro);
|
n = PyTuple_GET_SIZE(mro);
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
|
@ -2045,9 +2231,18 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
|
||||||
assert(dict && PyDict_Check(dict));
|
assert(dict && PyDict_Check(dict));
|
||||||
res = PyDict_GetItem(dict, name);
|
res = PyDict_GetItem(dict, name);
|
||||||
if (res != NULL)
|
if (res != NULL)
|
||||||
return res;
|
break;
|
||||||
}
|
}
|
||||||
return NULL;
|
|
||||||
|
if (MCACHE_CACHEABLE_NAME(name) && assign_version_tag(type)) {
|
||||||
|
h = MCACHE_HASH_METHOD(type, name);
|
||||||
|
method_cache[h].version = type->tp_version_tag;
|
||||||
|
method_cache[h].value = res; /* borrowed */
|
||||||
|
Py_INCREF(name);
|
||||||
|
Py_DECREF(method_cache[h].name);
|
||||||
|
method_cache[h].name = name;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is similar to PyObject_GenericGetAttr(),
|
/* This is similar to PyObject_GenericGetAttr(),
|
||||||
|
@ -2137,10 +2332,6 @@ type_setattro(PyTypeObject *type, PyObject *name, PyObject *value)
|
||||||
type->tp_name);
|
type->tp_name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* XXX Example of how I expect this to be used...
|
|
||||||
if (update_subclasses(type, name, invalidate_cache, NULL) < 0)
|
|
||||||
return -1;
|
|
||||||
*/
|
|
||||||
if (PyObject_GenericSetAttr((PyObject *)type, name, value) < 0)
|
if (PyObject_GenericSetAttr((PyObject *)type, name, value) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
return update_slot(type, name);
|
return update_slot(type, name);
|
||||||
|
@ -5421,6 +5612,13 @@ update_slot(PyTypeObject *type, PyObject *name)
|
||||||
slotdef **pp;
|
slotdef **pp;
|
||||||
int offset;
|
int offset;
|
||||||
|
|
||||||
|
/* Clear the VALID_VERSION flag of 'type' and all its
|
||||||
|
subclasses. This could possibly be unified with the
|
||||||
|
update_subclasses() recursion below, but carefully:
|
||||||
|
they each have their own conditions on which to stop
|
||||||
|
recursing into subclasses. */
|
||||||
|
type_modified(type);
|
||||||
|
|
||||||
init_slotdefs();
|
init_slotdefs();
|
||||||
pp = ptrs;
|
pp = ptrs;
|
||||||
for (p = slotdefs; p->name; p++) {
|
for (p = slotdefs; p->name; p++) {
|
||||||
|
|
Loading…
Reference in New Issue