diff --git a/Doc/c-api/concrete.rst b/Doc/c-api/concrete.rst index 1e1fa0dccf1..d2bedc2e300 100644 --- a/Doc/c-api/concrete.rst +++ b/Doc/c-api/concrete.rst @@ -2223,8 +2223,8 @@ Dictionary Objects .. cfunction:: int PyDict_SetItem(PyObject *p, PyObject *key, PyObject *val) Insert *value* into the dictionary *p* with a key of *key*. *key* must be - hashable; if it isn't, :exc:`TypeError` will be raised. Return ``0`` on success - or ``-1`` on failure. + :term:`hashable`; if it isn't, :exc:`TypeError` will be raised. Return ``0`` + on success or ``-1`` on failure. .. cfunction:: int PyDict_SetItemString(PyObject *p, const char *key, PyObject *val) diff --git a/Doc/glossary.rst b/Doc/glossary.rst index dfcbee803ee..aa698674512 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -140,6 +140,20 @@ Glossary in the past to create a "free-threaded" interpreter (one which locks shared data at a much finer granularity), but performance suffered in the common single-processor case. + + hashable + An object is *hashable* if it has a hash value that never changes during + its lifetime (it needs a :meth:`__hash__` method), and can be compared to + other objects (it needs an :meth:`__eq__` or :meth:`__cmp__` method). + Hashable objects that compare equal must have the same hash value. + + Hashability makes an object usable as a dictionary key and a set member, + because these data structures use the hash value internally. + + All of Python's immutable built-in objects are hashable, while all mutable + containers (such as lists or dictionaries) are not. Objects that are + instances of user-defined classes are hashable by default; they all + compare unequal, and their hash value is their :func:`id`. IDLE An Integrated Development Environment for Python. IDLE is a basic editor diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index 87cccf63a75..e67c9eb17b5 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -260,7 +260,7 @@ compared to an object of a different type, :exc:`TypeError` is raised unless the comparison is ``==`` or ``!=``. The latter cases return :const:`False` or :const:`True`, respectively. -:class:`timedelta` objects are hashable (usable as dictionary keys), support +:class:`timedelta` objects are :term:`hashable` (usable as dictionary keys), support efficient pickling, and in Boolean contexts, a :class:`timedelta` object is considered to be true if and only if it isn't equal to ``timedelta(0)``. diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index d3724ddc777..fe956b29e3d 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -18,7 +18,7 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. .. class:: SequenceMatcher This is a flexible class for comparing pairs of sequences of any type, so long - as the sequence elements are hashable. The basic algorithm predates, and is a + as the sequence elements are :term:`hashable`. The basic algorithm predates, and is a little fancier than, an algorithm published in the late 1980's by Ratcliff and Obershelp under the hyperbolic name "gestalt pattern matching." The idea is to find the longest contiguous matching subsequence that contains no "junk" @@ -305,7 +305,7 @@ The :class:`SequenceMatcher` class has this constructor: on blanks or hard tabs. The optional arguments *a* and *b* are sequences to be compared; both default to - empty strings. The elements of both sequences must be hashable. + empty strings. The elements of both sequences must be :term:`hashable`. :class:`SequenceMatcher` objects have the following methods: diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index c7e689d953b..63f2c33e7de 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -747,9 +747,9 @@ available. They are listed here in alphabetical order. value of ``None`` (if no newlines have been seen yet), ``'\n'``, ``'\r'``, ``'\r\n'``, or a tuple containing all the newline types seen. - See also the :mod:`fileinput` module, the file-related functions in the - :mod:`os` module, and the :mod:`os.path` module. - + Python provides many file handling modules including + :mod:`fileinput`, :mod:`os`, :mod:`os.path`, :mod:`tempfile`, and + :mod:`shutil`. .. function:: ord(c) diff --git a/Doc/library/os.rst b/Doc/library/os.rst index e627498f480..a5507391644 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -11,7 +11,9 @@ functionality than importing a operating system dependent built-in module like :mod:`posix` or :mod:`nt`. If you just want to read or write a file see :func:`open`, if you want to manipulate paths, see the :mod:`os.path` module, and if you want to read all the lines in all the files on the -command line see the :mod:`fileinput` module. +command line see the :mod:`fileinput` module. For creating temporary +files and directories see the :mod:`tempfile` module, and for high-level +file and directory handling see the :mod:`shutil` module. This module searches for an operating system dependent built-in module like :mod:`mac` or :mod:`posix` and exports the same functions and data as found @@ -800,8 +802,9 @@ Files and Directories .. function:: lstat(path) - Like :func:`stat`, but do not follow symbolic links. Availability: Macintosh, - Unix. + Like :func:`stat`, but do not follow symbolic links. This is an alias for + :func:`stat` on platforms that do not support symbolic links, such as + Windows. .. function:: mkfifo(path[, mode]) @@ -852,6 +855,9 @@ Files and Directories ``0777`` (octal). On some systems, *mode* is ignored. Where it is used, the current umask value is first masked out. Availability: Macintosh, Unix, Windows. + It is also possible to create temporary directories; see the + :mod:`tempfile` module's :func:`tempfile.mkdtemp` function. + .. function:: makedirs(path[, mode]) diff --git a/Doc/library/random.rst b/Doc/library/random.rst index 4d58e13f241..f0d5d1214af 100644 --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -54,7 +54,7 @@ Bookkeeping functions: .. function:: seed([x]) Initialize the basic random number generator. Optional argument *x* can be any - hashable object. If *x* is omitted or ``None``, current system time is used; + :term:`hashable` object. If *x* is omitted or ``None``, current system time is used; current system time is also used to initialize the generator when the module is first imported. If randomness sources are provided by the operating system, they are used instead of the system time (see the :func:`os.urandom` function @@ -140,7 +140,7 @@ Functions for sequences: (the sample) to be partitioned into grand prize and second place winners (the subslices). - Members of the population need not be hashable or unique. If the population + Members of the population need not be :term:`hashable` or unique. If the population contains repeats, then each occurrence is a possible selection in the sample. To choose a sample from a range of integers, use an :func:`range` object as an diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 927ddb0c1a6..3fdaa1f4d69 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -15,7 +15,8 @@ The :mod:`shutil` module offers a number of high-level operations on files and collections of files. In particular, functions are provided which support file -copying and removal. +copying and removal. For operations on individual files, see also the +:mod:`os` module. .. warning:: diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index fb278fa7798..f557b1f8c87 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -874,7 +874,7 @@ functions based on regular expressions. specified, then there is no limit on the number of splits (all possible splits are made). - If *sep is given, consecutive delimiters are not grouped together and are + If *sep* is given, consecutive delimiters are not grouped together and are deemed to delimit empty strings (for example, ``'1,,2'.split(',')`` returns ``['1', '', '2']``). The *sep* argument may consist of multiple characters (for example, ``'1<>2<>3'.split('<>')`` returns ``['1', '2', '3']``). @@ -1371,7 +1371,7 @@ Set Types --- :class:`set`, :class:`frozenset` .. index:: object: set -A :dfn:`set` object is an unordered collection of distinct hashable objects. +A :dfn:`set` object is an unordered collection of distinct :term:`hashable` objects. Common uses include membership testing, removing duplicates from a sequence, and computing mathematical operations such as intersection, union, difference, and symmetric difference. @@ -1387,7 +1387,7 @@ There are currently two builtin set types, :class:`set` and :class:`frozenset`. The :class:`set` type is mutable --- the contents can be changed using methods like :meth:`add` and :meth:`remove`. Since it is mutable, it has no hash value and cannot be used as either a dictionary key or as an element of another set. -The :class:`frozenset` type is immutable and hashable --- its contents cannot be +The :class:`frozenset` type is immutable and :term:`hashable` --- its contents cannot be altered after it is created; it can therefore be used as a dictionary key or as an element of another set. @@ -1487,8 +1487,7 @@ or ``a>b``. Accordingly, sets do not implement the :meth:`__cmp__` method. Since sets only define partial ordering (subset relationships), the output of the :meth:`list.sort` method is undefined for lists of sets. -Set elements are like dictionary keys; they need to define both :meth:`__hash__` -and :meth:`__eq__` methods. +Set elements, like dictionary keys, must be :term:`hashable`. Binary operations that mix :class:`set` instances with :class:`frozenset` return the type of the first operand. For example: ``frozenset('ab') | set('bc')`` @@ -1559,20 +1558,20 @@ Mapping Types --- :class:`dict` statement: del builtin: len -A :dfn:`mapping` object maps immutable values to arbitrary objects. Mappings -are mutable objects. There is currently only one standard mapping type, the -:dfn:`dictionary`. -(For other containers see the built in :class:`list`, -:class:`set`, and :class:`tuple` classes, and the :mod:`collections` -module.) +A :dfn:`mapping` object maps :term:`hashable` values to arbitrary objects. +Mappings are mutable objects. There is currently only one standard mapping +type, the :dfn:`dictionary`. (For other containers see the built in +:class:`list`, :class:`set`, and :class:`tuple` classes, and the +:mod:`collections` module.) -A dictionary's keys are *almost* arbitrary values. Only values containing -lists, dictionaries or other mutable types (that are compared by value rather -than by object identity) may not be used as keys. Numeric types used for keys -obey the normal rules for numeric comparison: if two numbers compare equal (such -as ``1`` and ``1.0``) then they can be used interchangeably to index the same -dictionary entry. (Note however, that since computers store floating-point -numbers as approximations it is usually unwise to use them as dictionary keys.) +A dictionary's keys are *almost* arbitrary values. Values that are not +:term:`hashable`, that is, values containing lists, dictionaries or other +mutable types (that are compared by value rather than by object identity) may +not be used as keys. Numeric types used for keys obey the normal rules for +numeric comparison: if two numbers compare equal (such as ``1`` and ``1.0``) +then they can be used interchangeably to index the same dictionary entry. (Note +however, that since computers store floating-point numbers as approximations it +is usually unwise to use them as dictionary keys.) Dictionaries can be created by placing a comma-separated list of ``key: value`` pairs within braces, for example: ``{'jack': 4098, 'sjoerd': 4127}`` or ``{4098: @@ -1821,7 +1820,10 @@ created with the built-in :func:`file` and (more usually) :func:`open` constructors described in the :ref:`built-in-funcs` section. [#]_ File objects are also returned by some other built-in functions and methods, such as :func:`os.popen` and :func:`os.fdopen` and the :meth:`makefile` -method of socket objects. +method of socket objects. Temporary files can be created using the +:mod:`tempfile` module, and high-level file operations such as copying, +moving, and deleting files and directories can be achieved with the +:mod:`shutil` module. When a file operation fails for an I/O-related reason, the exception :exc:`IOError` is raised. This includes situations where the operation is not diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst index 6c7c919f9d6..3adf3182bd1 100644 --- a/Doc/library/weakref.rst +++ b/Doc/library/weakref.rst @@ -85,7 +85,7 @@ Extension types can easily be made to support weak references; see but cannot be propagated; they are handled in exactly the same way as exceptions raised from an object's :meth:`__del__` method. - Weak references are hashable if the *object* is hashable. They will maintain + Weak references are :term:`hashable` if the *object* is hashable. They will maintain their hash value even after the *object* was deleted. If :func:`hash` is called the first time only after the *object* was deleted, the call will raise :exc:`TypeError`. @@ -104,7 +104,7 @@ Extension types can easily be made to support weak references; see the proxy in most contexts instead of requiring the explicit dereferencing used with weak reference objects. The returned object will have a type of either ``ProxyType`` or ``CallableProxyType``, depending on whether *object* is - callable. Proxy objects are not hashable regardless of the referent; this + callable. Proxy objects are not :term:`hashable` regardless of the referent; this avoids a number of problems related to their fundamentally mutable nature, and prevent their use as dictionary keys. *callback* is the same as the parameter of the same name to the :func:`ref` function. diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 3ebc973d096..69ac9dc80da 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -388,9 +388,10 @@ Set types Frozen sets .. index:: object: frozenset - These represent an immutable set. They are created by the built-in - :func:`frozenset` constructor. As a frozenset is immutable and hashable, it can - be used again as an element of another set, or as a dictionary key. + These represent an immutable set. They are created by the built-in + :func:`frozenset` constructor. As a frozenset is immutable and + :term:`hashable`, it can be used again as an element of another set, or as + a dictionary key. .. % Set types @@ -1242,6 +1243,9 @@ Basic customization object.__gt__(self, other) object.__ge__(self, other) + .. index:: + single: comparisons + These are the so-called "rich comparison" methods, and are called for comparison operators in preference to :meth:`__cmp__` below. The correspondence between operator symbols and method names is as follows: ``x other``. If no :meth:`__cmp__`, :meth:`__eq__` - or :meth:`__ne__` operation is defined, class instances are compared by object - identity ("address"). See also the description of :meth:`__hash__` for some - important notes on creating objects which support custom comparison operations - and are usable as dictionary keys. (Note: the restriction that exceptions are - not propagated by :meth:`__cmp__` has been removed since Python 1.5.) + Called by comparison operations if rich comparison (see above) is not + defined. Should return a negative integer if ``self < other``, zero if + ``self == other``, a positive integer if ``self > other``. If no + :meth:`__cmp__`, :meth:`__eq__` or :meth:`__ne__` operation is defined, class + instances are compared by object identity ("address"). See also the + description of :meth:`__hash__` for some important notes on creating + :term:`hashable` objects which support custom comparison operations and are + usable as dictionary keys. (Note: the restriction that exceptions are not + propagated by :meth:`__cmp__` has been removed since Python 1.5.) .. method:: object.__hash__(self) @@ -1293,19 +1300,12 @@ Basic customization builtin: hash single: __cmp__() (object method) - Called for the key object for dictionary operations, and by the built-in - function :func:`hash`. Should return a 32-bit integer usable as a hash value + Called for the key object for dictionary operations, and by the built-in + function :func:`hash`. Should return an integer usable as a hash value for dictionary operations. The only required property is that objects which compare equal have the same hash value; it is advised to somehow mix together (e.g., using exclusive or) the hash values for the components of the object that - also play a part in comparison of objects. If a class does not define a - :meth:`__cmp__` method it should not define a :meth:`__hash__` operation either; - if it defines :meth:`__cmp__` or :meth:`__eq__` but not :meth:`__hash__`, its - instances will not be usable as dictionary keys. If a class defines mutable - objects and implements a :meth:`__cmp__` or :meth:`__eq__` method, it should not - implement :meth:`__hash__`, since the dictionary implementation requires that a - key's hash value is immutable (if the object's hash value changes, it will be in - the wrong hash bucket). + also play a part in comparison of objects. :meth:`__hash__` may also return a long integer object; the 32-bit integer is then derived from the hash of that object. diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 16170522f80..64f620b74db 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -267,7 +267,7 @@ in the new dictionary in the order they are produced. hashable Restrictions on the types of the key values are listed earlier in section -:ref:`types`. (To summarize, the key type should be hashable, which excludes +:ref:`types`. (To summarize, the key type should be :term:`hashable`, which excludes all mutable objects.) Clashes between duplicate keys are not detected; the last datum (textually rightmost in the display) stored for a given key value prevails. diff --git a/Lib/bsddb/dbtables.py b/Lib/bsddb/dbtables.py index 06fcf8aacf4..56b4e3a01d1 100644 --- a/Lib/bsddb/dbtables.py +++ b/Lib/bsddb/dbtables.py @@ -362,7 +362,7 @@ def __new_rowid(self, table, txn) : unique = 0 while not unique: # Generate a random 64-bit row ID string - # (note: might have <64 bits of randomness + # (note: might have <64 bits of true randomness # but it's plenty for our database id needs!) blist = [] for x in range(_rowid_str_len): diff --git a/Lib/contextlib.py b/Lib/contextlib.py index fba4889002b..aeec40e1e32 100644 --- a/Lib/contextlib.py +++ b/Lib/contextlib.py @@ -25,6 +25,10 @@ def __exit__(self, type, value, traceback): else: raise RuntimeError("generator didn't stop") else: + if value is None: + # Need to force instantiation so we can reliably + # tell if we get the same exception back + value = type() try: self.gen.throw(type, value, traceback) raise RuntimeError("generator didn't stop after throw()") diff --git a/Lib/ctypes/test/test_cfuncs.py b/Lib/ctypes/test/test_cfuncs.py index e939bc1be85..8f97fc46a1e 100644 --- a/Lib/ctypes/test/test_cfuncs.py +++ b/Lib/ctypes/test/test_cfuncs.py @@ -158,17 +158,17 @@ def test_double_plus(self): self.failUnlessEqual(self._dll.tf_bd(0, 42.), 14.) self.failUnlessEqual(self.S(), 42) -## def test_longdouble(self): -## self._dll.tf_D.restype = c_longdouble -## self._dll.tf_D.argtypes = (c_longdouble,) -## self.failUnlessEqual(self._dll.tf_D(42.), 14.) -## self.failUnlessEqual(self.S(), 42) + def test_longdouble(self): + self._dll.tf_D.restype = c_longdouble + self._dll.tf_D.argtypes = (c_longdouble,) + self.failUnlessEqual(self._dll.tf_D(42.), 14.) + self.failUnlessEqual(self.S(), 42) -## def test_longdouble_plus(self): -## self._dll.tf_bD.restype = c_longdouble -## self._dll.tf_bD.argtypes = (c_byte, c_longdouble) -## self.failUnlessEqual(self._dll.tf_bD(0, 42.), 14.) -## self.failUnlessEqual(self.S(), 42) + def test_longdouble_plus(self): + self._dll.tf_bD.restype = c_longdouble + self._dll.tf_bD.argtypes = (c_byte, c_longdouble) + self.failUnlessEqual(self._dll.tf_bD(0, 42.), 14.) + self.failUnlessEqual(self.S(), 42) def test_callwithresult(self): def process_result(result): diff --git a/Lib/ctypes/test/test_functions.py b/Lib/ctypes/test/test_functions.py index 626af948c99..3af11cc5deb 100644 --- a/Lib/ctypes/test/test_functions.py +++ b/Lib/ctypes/test/test_functions.py @@ -143,17 +143,17 @@ def test_doubleresult(self): self.failUnlessEqual(result, -21) self.failUnlessEqual(type(result), float) -## def test_longdoubleresult(self): -## f = dll._testfunc_D_bhilfD -## f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_longdouble] -## f.restype = c_longdouble -## result = f(1, 2, 3, 4, 5.0, 6.0) -## self.failUnlessEqual(result, 21) -## self.failUnlessEqual(type(result), float) + def test_longdoubleresult(self): + f = dll._testfunc_D_bhilfD + f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_longdouble] + f.restype = c_longdouble + result = f(1, 2, 3, 4, 5.0, 6.0) + self.failUnlessEqual(result, 21) + self.failUnlessEqual(type(result), float) -## result = f(-1, -2, -3, -4, -5.0, -6.0) -## self.failUnlessEqual(result, -21) -## self.failUnlessEqual(type(result), float) + result = f(-1, -2, -3, -4, -5.0, -6.0) + self.failUnlessEqual(result, -21) + self.failUnlessEqual(type(result), float) def test_longlongresult(self): try: diff --git a/Lib/test/test_with.py b/Lib/test/test_with.py index a7bc2068b4c..e77846399d7 100644 --- a/Lib/test/test_with.py +++ b/Lib/test/test_with.py @@ -442,6 +442,7 @@ def shouldThrow(): self.assertAfterWithGeneratorInvariantsNoError(self.bar) def testRaisedStopIteration1(self): + # From bug 1462485 @contextmanager def cm(): yield @@ -453,6 +454,7 @@ def shouldThrow(): self.assertRaises(StopIteration, shouldThrow) def testRaisedStopIteration2(self): + # From bug 1462485 class cm(object): def __enter__(self): pass @@ -465,7 +467,21 @@ def shouldThrow(): self.assertRaises(StopIteration, shouldThrow) + def testRaisedStopIteration3(self): + # Another variant where the exception hasn't been instantiated + # From bug 1705170 + @contextmanager + def cm(): + yield + + def shouldThrow(): + with cm(): + raise next(iter([])) + + self.assertRaises(StopIteration, shouldThrow) + def testRaisedGeneratorExit1(self): + # From bug 1462485 @contextmanager def cm(): yield @@ -477,6 +493,7 @@ def shouldThrow(): self.assertRaises(GeneratorExit, shouldThrow) def testRaisedGeneratorExit2(self): + # From bug 1462485 class cm (object): def __enter__(self): pass diff --git a/Modules/_bsddb.c b/Modules/_bsddb.c index 874b7f7e7ba..8414618085a 100644 --- a/Modules/_bsddb.c +++ b/Modules/_bsddb.c @@ -5920,6 +5920,10 @@ PyMODINIT_FUNC init_bsddb(void) ADD_INT(d, DB_NOPANIC); #endif +#ifdef DB_REGISTER + ADD_INT(d, DB_REGISTER); +#endif + #if (DBVER >= 42) ADD_INT(d, DB_TIME_NOTGRANTED); ADD_INT(d, DB_TXN_NOT_DURABLE); diff --git a/configure b/configure index b43c2f940c9..53c1ec56cac 100755 --- a/configure +++ b/configure @@ -13315,7 +13315,10 @@ fi if test -z "$with_system_ffi" && test "$ac_cv_header_ffi_h" = yes; then case "$ac_sys_system/`uname -m`" in + Linux/alpha*) with_system_ffi="yes"; CONFIG_ARGS="$CONFIG_ARGS --with-system-ffi";; Linux/arm*) with_system_ffi="yes"; CONFIG_ARGS="$CONFIG_ARGS --with-system-ffi";; + Linux/ppc*) with_system_ffi="yes"; CONFIG_ARGS="$CONFIG_ARGS --with-system-ffi";; + Linux/s390*) with_system_ffi="yes"; CONFIG_ARGS="$CONFIG_ARGS --with-system-ffi";; *) with_system_ffi="no" esac fi diff --git a/configure.in b/configure.in index cd02cc92b5f..059d184749e 100644 --- a/configure.in +++ b/configure.in @@ -1731,7 +1731,10 @@ AC_ARG_WITH(system_ffi, if test -z "$with_system_ffi" && test "$ac_cv_header_ffi_h" = yes; then case "$ac_sys_system/`uname -m`" in + Linux/alpha*) with_system_ffi="yes"; CONFIG_ARGS="$CONFIG_ARGS --with-system-ffi";; Linux/arm*) with_system_ffi="yes"; CONFIG_ARGS="$CONFIG_ARGS --with-system-ffi";; + Linux/ppc*) with_system_ffi="yes"; CONFIG_ARGS="$CONFIG_ARGS --with-system-ffi";; + Linux/s390*) with_system_ffi="yes"; CONFIG_ARGS="$CONFIG_ARGS --with-system-ffi";; *) with_system_ffi="no" esac fi