[Python-3000-checkins] r60725 - in python/branches/py3k: Demo/classes/README Doc/README.txt Doc/conf.py Doc/extending/windows.rst Doc/library/decimal.rst Doc/library/fractions.rst Doc/library/numbers.rst Doc/library/pickletools.rst Doc/library/rational.rst Doc/whatsnew/2.6.rst Lib/decimal.py Lib/fractions.py Lib/pickletools.py Lib/rational.py Lib/test/test_builtin.py Lib/test/test_fractions.py Lib/test/test_rational.py Modules/_collectionsmodule.c

christian.heimes python-3000-checkins at python.org
Mon Feb 11 07:19:19 CET 2008


Author: christian.heimes
Date: Mon Feb 11 07:19:17 2008
New Revision: 60725

Added:
   python/branches/py3k/Doc/library/fractions.rst
      - copied, changed from r60724, python/branches/py3k/Doc/library/rational.rst
   python/branches/py3k/Lib/fractions.py
      - copied, changed from r60724, python/branches/py3k/Lib/rational.py
   python/branches/py3k/Lib/test/test_fractions.py
      - copied, changed from r60724, python/branches/py3k/Lib/test/test_rational.py
Removed:
   python/branches/py3k/Doc/library/rational.rst
   python/branches/py3k/Lib/rational.py
   python/branches/py3k/Lib/test/test_rational.py
Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Demo/classes/README
   python/branches/py3k/Doc/README.txt
   python/branches/py3k/Doc/conf.py
   python/branches/py3k/Doc/extending/windows.rst
   python/branches/py3k/Doc/library/decimal.rst
   python/branches/py3k/Doc/library/numbers.rst
   python/branches/py3k/Doc/library/pickletools.rst
   python/branches/py3k/Doc/whatsnew/2.6.rst
   python/branches/py3k/Lib/decimal.py
   python/branches/py3k/Lib/pickletools.py
   python/branches/py3k/Lib/test/test_builtin.py
   python/branches/py3k/Modules/_collectionsmodule.c
Log:
Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,60505-60506,60508-60509,60523-60524,60532,60543,60545,60547-60548,60552,60554,60556-60559,60561-60562,60569,60571-60572,60574,60576-60583,60585-60586,60589,60591,60594-60595,60597-60598,60600-60601,60606-60612,60615,60617,60619-60621,60623-60625,60627-60629,60631,60633,60635,60647,60650,60652,60654,60656,60658-60659,60664-60666,60668-60670,60672,60676,60678,60680-60683,60685-60686,60688,60690,60692-60694,60697-60706,60708-60712,60714-60724 via svnmerge from 
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r60701 | georg.brandl | 2008-02-09 22:36:15 +0100 (Sat, 09 Feb 2008) | 2 lines
  
  Needs only 2.4 now.
........
  r60702 | georg.brandl | 2008-02-09 22:38:54 +0100 (Sat, 09 Feb 2008) | 2 lines
  
  Docs are rst now.
........
  r60703 | georg.brandl | 2008-02-09 23:00:00 +0100 (Sat, 09 Feb 2008) | 2 lines
  
  Fix link.
........
  r60704 | georg.brandl | 2008-02-10 00:09:25 +0100 (Sun, 10 Feb 2008) | 2 lines
  
  Fix for newest doctools.
........
  r60709 | raymond.hettinger | 2008-02-10 08:21:09 +0100 (Sun, 10 Feb 2008) | 1 line
  
  Clarify that decimal also supports fixed-point arithmetic.
........
  r60710 | nick.coghlan | 2008-02-10 08:32:52 +0100 (Sun, 10 Feb 2008) | 1 line
  
  Add missing NEWS entry for r60695
........
  r60712 | mark.dickinson | 2008-02-10 15:58:38 +0100 (Sun, 10 Feb 2008) | 3 lines
  
  Turn classmethods into staticmethods, and avoid calling the constructor
  of subclasses of Rational.  (See discussion in issue #1682.)
........
  r60715 | mark.dickinson | 2008-02-10 16:19:58 +0100 (Sun, 10 Feb 2008) | 2 lines
  
  Typos in decimal comment and documentation
........
  r60716 | skip.montanaro | 2008-02-10 16:31:54 +0100 (Sun, 10 Feb 2008) | 2 lines
  
  Get the saying right. ;-)
........
  r60717 | skip.montanaro | 2008-02-10 16:32:16 +0100 (Sun, 10 Feb 2008) | 2 lines
  
  whoops - revert
........
  r60718 | mark.dickinson | 2008-02-10 20:23:36 +0100 (Sun, 10 Feb 2008) | 2 lines
  
  Remove reference to Rational
........
  r60719 | raymond.hettinger | 2008-02-10 21:35:16 +0100 (Sun, 10 Feb 2008) | 1 line
  
  Complete an open todo on pickletools -- add a pickle optimizer.
........
  r60721 | mark.dickinson | 2008-02-10 22:29:51 +0100 (Sun, 10 Feb 2008) | 3 lines
  
  Rename rational.Rational to fractions.Fraction, to avoid name clash
  with numbers.Rational.  See issue #1682 for related discussion.
........
  r60722 | christian.heimes | 2008-02-11 03:26:22 +0100 (Mon, 11 Feb 2008) | 1 line
  
  The test requires the network resource
........
  r60723 | mark.dickinson | 2008-02-11 04:11:55 +0100 (Mon, 11 Feb 2008) | 3 lines
  
  Put an extra space into the repr of a Fraction:
  Fraction(1, 2) instead of Fraction(1,2).
........


Modified: python/branches/py3k/Demo/classes/README
==============================================================================
--- python/branches/py3k/Demo/classes/README	(original)
+++ python/branches/py3k/Demo/classes/README	Mon Feb 11 07:19:17 2008
@@ -4,7 +4,6 @@
 Dates.py	Date manipulation package by Tim Peters
 Dbm.py		Wrapper around built-in dbm, supporting	arbitrary values
 Range.py	Example of a generator: re-implement built-in range()
-Rat.py		Rational numbers
 Rev.py		Yield the reverse of a sequence
 Vec.py		A simple vector class
 bitvec.py	A bit-vector class by Jan-Hein B\"uhrman

Modified: python/branches/py3k/Doc/README.txt
==============================================================================
--- python/branches/py3k/Doc/README.txt	(original)
+++ python/branches/py3k/Doc/README.txt	Mon Feb 11 07:19:17 2008
@@ -14,7 +14,7 @@
 Building the docs
 =================
 
-You need to install Python 2.5.1 or higher (but Python 3.0 is not supported yet);
+You need to install Python 2.4 or higher (but Python 3.0 is not supported yet);
 the toolset used to build the docs are written in Python.  The toolset used
 to build the documentation is called *Sphinx*, it is not included in this
 tree, but maintained separately in the Python Subversion repository.  Also
@@ -55,7 +55,7 @@
 
  * "latex", which builds LaTeX source files that can be run with "pdflatex"
    to produce PDF documents.
- 
+
  * "linkcheck", which checks all external references to see whether they are
    broken, redirected or malformed, and outputs this information to stdout
    as well as a plain-text (.txt) file.

Modified: python/branches/py3k/Doc/conf.py
==============================================================================
--- python/branches/py3k/Doc/conf.py	(original)
+++ python/branches/py3k/Doc/conf.py	Mon Feb 11 07:19:17 2008
@@ -38,17 +38,17 @@
 today_fmt = '%B %d, %Y'
 
 # List of files that shouldn't be included in the build.
-unused_files = [
-    'whatsnew/2.0.rst',
-    'whatsnew/2.1.rst',
-    'whatsnew/2.2.rst',
-    'whatsnew/2.3.rst',
-    'whatsnew/2.4.rst',
-    'whatsnew/2.5.rst',
-    'whatsnew/2.6.rst',
-    'maclib/scrap.rst',
-    'library/xmllib.rst',
-    'library/xml.etree.rst',
+unused_docs = [
+    'whatsnew/2.0',
+    'whatsnew/2.1',
+    'whatsnew/2.2',
+    'whatsnew/2.3',
+    'whatsnew/2.4',
+    'whatsnew/2.5',
+    'whatsnew/2.6',
+    'maclib/scrap',
+    'library/xmllib',
+    'library/xml.etree',
 ]
 
 # Relative filename of the reference count data file.

Modified: python/branches/py3k/Doc/extending/windows.rst
==============================================================================
--- python/branches/py3k/Doc/extending/windows.rst	(original)
+++ python/branches/py3k/Doc/extending/windows.rst	Mon Feb 11 07:19:17 2008
@@ -179,7 +179,7 @@
 
    MyObject_Type.ob_type = &PyType_Type;
 
-Refer to section 3 of the `Python FAQ <http://www.python.org/doc/FAQ.html>`_ for
+Refer to section 3 of the `Python FAQ <http://www.python.org/doc/faq>`_ for
 details on why you must do this.
 
 

Modified: python/branches/py3k/Doc/library/decimal.rst
==============================================================================
--- python/branches/py3k/Doc/library/decimal.rst	(original)
+++ python/branches/py3k/Doc/library/decimal.rst	Mon Feb 11 07:19:17 2008
@@ -1,6 +1,6 @@
 
-:mod:`decimal` --- Decimal floating point arithmetic
-====================================================
+:mod:`decimal` --- Decimal fixed point and floating point arithmetic
+====================================================================
 
 .. module:: decimal
    :synopsis: Implementation of the General Decimal Arithmetic  Specification.
@@ -16,6 +16,11 @@
 The :mod:`decimal` module provides support for decimal floating point
 arithmetic.  It offers several advantages over the :class:`float` datatype:
 
+* Decimal "is based on a floating-point model which was designed with people
+  in mind, and necessarily has a paramount guiding principle -- computers must
+  provide an arithmetic that works in the same way as the arithmetic that
+  people learn at school." -- excerpt from the decimal arithmetic specification.
+
 * Decimal numbers can be represented exactly.  In contrast, numbers like
   :const:`1.1` do not have an exact representation in binary floating point. End
   users typically would not expect :const:`1.1` to display as
@@ -25,7 +30,7 @@
   + 0.1 + 0.1 - 0.3`` is exactly equal to zero.  In binary floating point, the result
   is :const:`5.5511151231257827e-017`.  While near to zero, the differences
   prevent reliable equality testing and differences can accumulate. For this
-  reason, decimal would be preferred in accounting applications which have strict
+  reason, decimal is preferred in accounting applications which have strict
   equality invariants.
 
 * The decimal module incorporates a notion of significant places so that ``1.30
@@ -50,6 +55,13 @@
   standards.  While the built-in float type exposes only a modest portion of its
   capabilities, the decimal module exposes all required parts of the standard.
   When needed, the programmer has full control over rounding and signal handling.
+  This includes an option to enforce exact arithmetic by using exceptions
+  to block any inexact operations.
+
+* The decimal module was designed to support "without prejudice, both exact
+  unrounded decimal arithmetic (sometimes called fixed-point arithmetic)
+  and rounded floating-point arithmetic."  -- excerpt from the decimal
+  arithmetic specification.
 
 The module design is centered around three concepts:  the decimal number, the
 context for arithmetic, and signals.
@@ -832,7 +844,7 @@
    :const:`ROUND_HALF_EVEN`.  All flags are cleared.  No traps are enabled (so that
    exceptions are not raised during computations).
 
-   Because the trapped are disabled, this context is useful for applications that
+   Because the traps are disabled, this context is useful for applications that
    prefer to have result value of :const:`NaN` or :const:`Infinity` instead of
    raising exceptions.  This allows an application to complete a run in the
    presence of conditions that would otherwise halt the program.
@@ -1245,7 +1257,7 @@
 :const:`True`.  An attempt to compare two Decimals using any of the ``<``,
 ``<=``, ``>`` or ``>=`` operators will raise the :exc:`InvalidOperation` signal
 if either operand is a :const:`NaN`, and return :const:`False` if this signal is
-trapped.  Note that the General Decimal Arithmetic specification does not
+not trapped.  Note that the General Decimal Arithmetic specification does not
 specify the behavior of direct comparisons; these rules for comparisons
 involving a :const:`NaN` were taken from the IEEE 854 standard (see Table 3 in
 section 5.7).  To ensure strict standards-compliance, use the :meth:`compare`

Copied: python/branches/py3k/Doc/library/fractions.rst (from r60724, python/branches/py3k/Doc/library/rational.rst)
==============================================================================
--- python/branches/py3k/Doc/library/rational.rst	(original)
+++ python/branches/py3k/Doc/library/fractions.rst	Mon Feb 11 07:19:17 2008
@@ -1,28 +1,28 @@
 
-:mod:`rational` --- Rational numbers
+:mod:`fractions` --- Rational numbers
 ====================================
 
-.. module:: rational
+.. module:: fractions
    :synopsis: Rational numbers.
 .. moduleauthor:: Jeffrey Yasskin <jyasskin at gmail.com>
 .. sectionauthor:: Jeffrey Yasskin <jyasskin at gmail.com>
 .. versionadded:: 2.6
 
 
-The :mod:`rational` module defines an immutable, infinite-precision
+The :mod:`fractions` module defines an immutable, infinite-precision
 Rational number class.
 
 
-.. class:: Rational(numerator=0, denominator=1)
-           Rational(other_rational)
-           Rational(string)
+.. class:: Fraction(numerator=0, denominator=1)
+           Fraction(other_fraction)
+           Fraction(string)
 
    The first version requires that *numerator* and *denominator* are
    instances of :class:`numbers.Integral` and returns a new
-   ``Rational`` representing ``numerator/denominator``. If
+   ``Fraction`` representing ``numerator/denominator``. If
    *denominator* is :const:`0`, raises a :exc:`ZeroDivisionError`. The
-   second version requires that *other_rational* is an instance of
-   :class:`numbers.Rational` and returns an instance of
+   second version requires that *other_fraction* is an instance of
+   :class:`numbers.Fraction` and returns an instance of
    :class:`Rational` with the same value. The third version expects a
    string of the form ``[-+]?[0-9]+(/[0-9]+)?``, optionally surrounded
    by spaces.
@@ -31,39 +31,39 @@
    :class:`numbers.Rational` and is immutable and hashable.
 
 
-.. method:: Rational.from_float(flt)
+.. method:: Fraction.from_float(flt)
 
-   This classmethod constructs a :class:`Rational` representing the
+   This classmethod constructs a :class:`Fraction` representing the
    exact value of *flt*, which must be a :class:`float`. Beware that
-   ``Rational.from_float(0.3)`` is not the same value as ``Rational(3,
+   ``Fraction.from_float(0.3)`` is not the same value as ``Rational(3,
    10)``
 
 
-.. method:: Rational.from_decimal(dec)
+.. method:: Fraction.from_decimal(dec)
 
-   This classmethod constructs a :class:`Rational` representing the
+   This classmethod constructs a :class:`Fraction` representing the
    exact value of *dec*, which must be a
    :class:`decimal.Decimal`.
 
 
-.. method:: Rational.__floor__()
+.. method:: Fraction.__floor__()
 
    Returns the greatest :class:`int` ``<= self``. Will be accessible
    through :func:`math.floor` in Py3k.
 
 
-.. method:: Rational.__ceil__()
+.. method:: Fraction.__ceil__()
 
    Returns the least :class:`int` ``>= self``. Will be accessible
    through :func:`math.ceil` in Py3k.
 
 
-.. method:: Rational.__round__()
-            Rational.__round__(ndigits)
+.. method:: Fraction.__round__()
+            Fraction.__round__(ndigits)
 
    The first version returns the nearest :class:`int` to ``self``,
    rounding half to even. The second version rounds ``self`` to the
-   nearest multiple of ``Rational(1, 10**ndigits)`` (logically, if
+   nearest multiple of ``Fraction(1, 10**ndigits)`` (logically, if
    ``ndigits`` is negative), again rounding half toward even. Will be
    accessible through :func:`round` in Py3k.
 

Modified: python/branches/py3k/Doc/library/numbers.rst
==============================================================================
--- python/branches/py3k/Doc/library/numbers.rst	(original)
+++ python/branches/py3k/Doc/library/numbers.rst	Mon Feb 11 07:19:17 2008
@@ -104,7 +104,7 @@
 
 Implementors should be careful to make equal numbers equal and hash
 them to the same values. This may be subtle if there are two different
-extensions of the real numbers. For example, :class:`rational.Rational`
+extensions of the real numbers. For example, :class:`fractions.Fraction`
 implements :func:`hash` as follows::
 
     def __hash__(self):
@@ -199,11 +199,11 @@
 Because most of the operations on any given type will be very similar,
 it can be useful to define a helper function which generates the
 forward and reverse instances of any given operator. For example,
-:class:`rational.Rational` uses::
+:class:`fractions.Fraction` uses::
 
     def _operator_fallbacks(monomorphic_operator, fallback_operator):
         def forward(a, b):
-            if isinstance(b, (int, long, Rational)):
+            if isinstance(b, (int, long, Fraction)):
                 return monomorphic_operator(a, b)
             elif isinstance(b, float):
                 return fallback_operator(float(a), b)
@@ -215,7 +215,7 @@
         forward.__doc__ = monomorphic_operator.__doc__
 
         def reverse(b, a):
-            if isinstance(a, RationalAbc):
+            if isinstance(a, Rational):
                 # Includes ints.
                 return monomorphic_operator(a, b)
             elif isinstance(a, numbers.Real):
@@ -231,7 +231,7 @@
 
     def _add(a, b):
         """a + b"""
-        return Rational(a.numerator * b.denominator +
+        return Fraction(a.numerator * b.denominator +
                         b.numerator * a.denominator,
                         a.denominator * b.denominator)
 

Modified: python/branches/py3k/Doc/library/pickletools.rst
==============================================================================
--- python/branches/py3k/Doc/library/pickletools.rst	(original)
+++ python/branches/py3k/Doc/library/pickletools.rst	Mon Feb 11 07:19:17 2008
@@ -33,3 +33,10 @@
    the opcode's argument; *pos* is the position at which this opcode is located.
    *pickle* can be a string or a file-like object.
 
+.. function:: optimize(picklestring)
+
+   Returns a new equivalent pickle string after eliminating unused ``PUT``
+   opcodes. The optimized pickle is shorter, takes less transmission time,
+   requires less storage space, and unpickles more efficiently.
+
+   .. versionadded:: 2.6

Deleted: /python/branches/py3k/Doc/library/rational.rst
==============================================================================
--- /python/branches/py3k/Doc/library/rational.rst	Mon Feb 11 07:19:17 2008
+++ (empty file)
@@ -1,75 +0,0 @@
-
-:mod:`rational` --- Rational numbers
-====================================
-
-.. module:: rational
-   :synopsis: Rational numbers.
-.. moduleauthor:: Jeffrey Yasskin <jyasskin at gmail.com>
-.. sectionauthor:: Jeffrey Yasskin <jyasskin at gmail.com>
-.. versionadded:: 2.6
-
-
-The :mod:`rational` module defines an immutable, infinite-precision
-Rational number class.
-
-
-.. class:: Rational(numerator=0, denominator=1)
-           Rational(other_rational)
-           Rational(string)
-
-   The first version requires that *numerator* and *denominator* are
-   instances of :class:`numbers.Integral` and returns a new
-   ``Rational`` representing ``numerator/denominator``. If
-   *denominator* is :const:`0`, raises a :exc:`ZeroDivisionError`. The
-   second version requires that *other_rational* is an instance of
-   :class:`numbers.Rational` and returns an instance of
-   :class:`Rational` with the same value. The third version expects a
-   string of the form ``[-+]?[0-9]+(/[0-9]+)?``, optionally surrounded
-   by spaces.
-
-   Implements all of the methods and operations from
-   :class:`numbers.Rational` and is immutable and hashable.
-
-
-.. method:: Rational.from_float(flt)
-
-   This classmethod constructs a :class:`Rational` representing the
-   exact value of *flt*, which must be a :class:`float`. Beware that
-   ``Rational.from_float(0.3)`` is not the same value as ``Rational(3,
-   10)``
-
-
-.. method:: Rational.from_decimal(dec)
-
-   This classmethod constructs a :class:`Rational` representing the
-   exact value of *dec*, which must be a
-   :class:`decimal.Decimal`.
-
-
-.. method:: Rational.__floor__()
-
-   Returns the greatest :class:`int` ``<= self``. Will be accessible
-   through :func:`math.floor` in Py3k.
-
-
-.. method:: Rational.__ceil__()
-
-   Returns the least :class:`int` ``>= self``. Will be accessible
-   through :func:`math.ceil` in Py3k.
-
-
-.. method:: Rational.__round__()
-            Rational.__round__(ndigits)
-
-   The first version returns the nearest :class:`int` to ``self``,
-   rounding half to even. The second version rounds ``self`` to the
-   nearest multiple of ``Rational(1, 10**ndigits)`` (logically, if
-   ``ndigits`` is negative), again rounding half toward even. Will be
-   accessible through :func:`round` in Py3k.
-
-
-.. seealso::
-
-   Module :mod:`numbers`
-      The abstract base classes making up the numeric tower.
-

Modified: python/branches/py3k/Doc/whatsnew/2.6.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/2.6.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/2.6.rst	Mon Feb 11 07:19:17 2008
@@ -578,8 +578,8 @@
 
 :class:`Rational` numbers derive from :class:`Real`, have
 :attr:`numerator` and :attr:`denominator` properties, and can be
-converted to floats.  Python 2.6 adds a simple rational-number class
-in the :mod:`rational` module.
+converted to floats.  Python 2.6 adds a simple rational-number class,
+:class:`Fraction`, in the :mod:`fractions` module.
 
 :class:`Integral` numbers derive from :class:`Rational`, and
 can be shifted left and right with ``<<`` and ``>>``, 
@@ -598,29 +598,29 @@
 
   
 
-The Rational Module
+The Fraction Module
 --------------------------------------------------
 
 To fill out the hierarchy of numeric types, a rational-number class
-has been added as the :mod:`rational` module.  Rational numbers are
+has been added as the :mod:`fractions` module.  Rational numbers are
 represented as a fraction; rational numbers can exactly represent
 numbers such as two-thirds that floating-point numbers can only
 approximate.
 
-The :class:`Rational` constructor takes two :class:`Integral` values
+The :class:`Fraction` constructor takes two :class:`Integral` values
 that will be the numerator and denominator of the resulting fraction. ::
 
-    >>> from rational import Rational
-    >>> a = Rational(2, 3)
-    >>> b = Rational(2, 5)
+    >>> from fractions import Fraction
+    >>> a = Fraction(2, 3)
+    >>> b = Fraction(2, 5)
     >>> float(a), float(b)
     (0.66666666666666663, 0.40000000000000002)
     >>> a+b
-    rational.Rational(16,15)
+    Fraction(16, 15)
     >>> a/b
-    rational.Rational(5,3)
+    Fraction(5, 3)
 
-The :mod:`rational` module is based upon an implementation by Sjoerd
+The :mod:`fractions` module is based upon an implementation by Sjoerd
 Mullender that was in Python's :file:`Demo/classes/` directory for a
 long time.  This implementation was significantly updated by Jeffrey
 Yaskin.

Modified: python/branches/py3k/Lib/decimal.py
==============================================================================
--- python/branches/py3k/Lib/decimal.py	(original)
+++ python/branches/py3k/Lib/decimal.py	Mon Feb 11 07:19:17 2008
@@ -802,7 +802,7 @@
     #   != comparisons involving a NaN always return True
     #   <, >, <= and >= comparisons involving a (quiet or signaling)
     #      NaN signal InvalidOperation, and return False if the
-    #      InvalidOperation is trapped.
+    #      InvalidOperation is not trapped.
     #
     # This behavior is designed to conform as closely as possible to
     # that specified by IEEE 754.

Copied: python/branches/py3k/Lib/fractions.py (from r60724, python/branches/py3k/Lib/rational.py)
==============================================================================
--- python/branches/py3k/Lib/rational.py	(original)
+++ python/branches/py3k/Lib/fractions.py	Mon Feb 11 07:19:17 2008
@@ -1,16 +1,15 @@
 # Originally contributed by Sjoerd Mullender.
 # Significantly modified by Jeffrey Yasskin <jyasskin at gmail.com>.
 
-"""Rational, infinite-precision, real numbers."""
+"""Fraction, infinite-precision, real numbers."""
 
 import math
 import numbers
 import operator
 import re
 
-__all__ = ["Rational"]
+__all__ = ["Fraction"]
 
-RationalAbc = numbers.Rational
 
 
 def gcd(a, b):
@@ -38,15 +37,15 @@
 """, re.VERBOSE)
 
 
-class Rational(RationalAbc):
+class Fraction(numbers.Rational):
     """This class implements rational numbers.
 
-    Rational(8, 6) will produce a rational number equivalent to
+    Fraction(8, 6) will produce a rational number equivalent to
     4/3. Both arguments must be Integral. The numerator defaults to 0
-    and the denominator defaults to 1 so that Rational(3) == 3 and
-    Rational() == 0.
+    and the denominator defaults to 1 so that Fraction(3) == 3 and
+    Fraction() == 0.
 
-    Rationals can also be constructed from strings of the form
+    Fraction can also be constructed from strings of the form
     '[-+]?[0-9]+((/|.)[0-9]+)?', optionally surrounded by spaces.
 
     """
@@ -61,7 +60,7 @@
         numerator/denominator pair.
 
         """
-        self = super(Rational, cls).__new__(cls)
+        self = super(Fraction, cls).__new__(cls)
 
         if denominator == 1:
             if isinstance(numerator, str):
@@ -69,7 +68,7 @@
                 input = numerator
                 m = _RATIONAL_FORMAT.match(input)
                 if m is None:
-                    raise ValueError('Invalid literal for Rational: ' + input)
+                    raise ValueError('Invalid literal for Fraction: ' + input)
                 numerator = m.group('num')
                 decimal = m.group('decimal')
                 if decimal:
@@ -86,7 +85,7 @@
                     numerator = -numerator
 
             elif (not isinstance(numerator, numbers.Integral) and
-                  isinstance(numerator, RationalAbc)):
+                  isinstance(numerator, numbers.Rational)):
                 # Handle copies from other rationals.
                 other_rational = numerator
                 numerator = other_rational.numerator
@@ -94,11 +93,11 @@
 
         if (not isinstance(numerator, numbers.Integral) or
             not isinstance(denominator, numbers.Integral)):
-            raise TypeError("Rational(%(numerator)s, %(denominator)s):"
+            raise TypeError("Fraction(%(numerator)s, %(denominator)s):"
                             " Both arguments must be integral." % locals())
 
         if denominator == 0:
-            raise ZeroDivisionError('Rational(%s, 0)' % numerator)
+            raise ZeroDivisionError('Fraction(%s, 0)' % numerator)
 
         g = gcd(numerator, denominator)
         self._numerator = int(numerator // g)
@@ -109,7 +108,7 @@
     def from_float(cls, f):
         """Converts a finite float to a rational number, exactly.
 
-        Beware that Rational.from_float(0.3) != Rational(3, 10).
+        Beware that Fraction.from_float(0.3) != Fraction(3, 10).
 
         """
         if not isinstance(f, float):
@@ -141,7 +140,7 @@
 
     @classmethod
     def from_continued_fraction(cls, seq):
-        'Build a Rational from a continued fraction expessed as a sequence'
+        'Build a Fraction from a continued fraction expessed as a sequence'
         n, d = 1, 0
         for e in reversed(seq):
             n, d = d, n
@@ -168,7 +167,7 @@
         if self.denominator <= max_denominator:
             return self
         cf = self.as_continued_fraction()
-        result = Rational(0)
+        result = Fraction(0)
         for i in range(1, len(cf)):
             new = self.from_continued_fraction(cf[:i])
             if new.denominator > max_denominator:
@@ -186,7 +185,7 @@
 
     def __repr__(self):
         """repr(self)"""
-        return ('Rational(%r,%r)' % (self.numerator, self.denominator))
+        return ('Fraction(%r,%r)' % (self.numerator, self.denominator))
 
     def __str__(self):
         """str(self)"""
@@ -206,13 +205,13 @@
         that mixed-mode operations either call an implementation whose
         author knew about the types of both arguments, or convert both
         to the nearest built in type and do the operation there. In
-        Rational, that means that we define __add__ and __radd__ as:
+        Fraction, that means that we define __add__ and __radd__ as:
 
             def __add__(self, other):
                 # Both types have numerators/denominator attributes,
                 # so do the operation directly
-                if isinstance(other, (int, Rational)):
-                    return Rational(self.numerator * other.denominator +
+                if isinstance(other, (int, Fraction)):
+                    return Fraction(self.numerator * other.denominator +
                                     other.numerator * self.denominator,
                                     self.denominator * other.denominator)
                 # float and complex don't have those operations, but we
@@ -227,8 +226,8 @@
             def __radd__(self, other):
                 # radd handles more types than add because there's
                 # nothing left to fall back to.
-                if isinstance(other, RationalAbc):
-                    return Rational(self.numerator * other.denominator +
+                if isinstance(other, numbers.Rational):
+                    return Fraction(self.numerator * other.denominator +
                                     other.numerator * self.denominator,
                                     self.denominator * other.denominator)
                 elif isinstance(other, Real):
@@ -239,32 +238,32 @@
 
 
         There are 5 different cases for a mixed-type addition on
-        Rational. I'll refer to all of the above code that doesn't
-        refer to Rational, float, or complex as "boilerplate". 'r'
-        will be an instance of Rational, which is a subtype of
-        RationalAbc (r : Rational <: RationalAbc), and b : B <:
+        Fraction. I'll refer to all of the above code that doesn't
+        refer to Fraction, float, or complex as "boilerplate". 'r'
+        will be an instance of Fraction, which is a subtype of
+        Rational (r : Fraction <: Rational), and b : B <:
         Complex. The first three involve 'r + b':
 
-            1. If B <: Rational, int, float, or complex, we handle
+            1. If B <: Fraction, int, float, or complex, we handle
                that specially, and all is well.
-            2. If Rational falls back to the boilerplate code, and it
+            2. If Fraction falls back to the boilerplate code, and it
                were to return a value from __add__, we'd miss the
                possibility that B defines a more intelligent __radd__,
                so the boilerplate should return NotImplemented from
-               __add__. In particular, we don't handle RationalAbc
+               __add__. In particular, we don't handle Rational
                here, even though we could get an exact answer, in case
                the other type wants to do something special.
-            3. If B <: Rational, Python tries B.__radd__ before
-               Rational.__add__. This is ok, because it was
-               implemented with knowledge of Rational, so it can
+            3. If B <: Fraction, Python tries B.__radd__ before
+               Fraction.__add__. This is ok, because it was
+               implemented with knowledge of Fraction, so it can
                handle those instances before delegating to Real or
                Complex.
 
         The next two situations describe 'b + r'. We assume that b
-        didn't know about Rational in its implementation, and that it
+        didn't know about Fraction in its implementation, and that it
         uses similar boilerplate code:
 
-            4. If B <: RationalAbc, then __radd_ converts both to the
+            4. If B <: Rational, then __radd_ converts both to the
                builtin rational type (hey look, that's us) and
                proceeds.
             5. Otherwise, __radd__ tries to find the nearest common
@@ -276,7 +275,7 @@
 
         """
         def forward(a, b):
-            if isinstance(b, (int, Rational)):
+            if isinstance(b, (int, Fraction)):
                 return monomorphic_operator(a, b)
             elif isinstance(b, float):
                 return fallback_operator(float(a), b)
@@ -288,7 +287,7 @@
         forward.__doc__ = monomorphic_operator.__doc__
 
         def reverse(b, a):
-            if isinstance(a, RationalAbc):
+            if isinstance(a, numbers.Rational):
                 # Includes ints.
                 return monomorphic_operator(a, b)
             elif isinstance(a, numbers.Real):
@@ -304,7 +303,7 @@
 
     def _add(a, b):
         """a + b"""
-        return Rational(a.numerator * b.denominator +
+        return Fraction(a.numerator * b.denominator +
                         b.numerator * a.denominator,
                         a.denominator * b.denominator)
 
@@ -312,7 +311,7 @@
 
     def _sub(a, b):
         """a - b"""
-        return Rational(a.numerator * b.denominator -
+        return Fraction(a.numerator * b.denominator -
                         b.numerator * a.denominator,
                         a.denominator * b.denominator)
 
@@ -320,13 +319,13 @@
 
     def _mul(a, b):
         """a * b"""
-        return Rational(a.numerator * b.numerator, a.denominator * b.denominator)
+        return Fraction(a.numerator * b.numerator, a.denominator * b.denominator)
 
     __mul__, __rmul__ = _operator_fallbacks(_mul, operator.mul)
 
     def _div(a, b):
         """a / b"""
-        return Rational(a.numerator * b.denominator,
+        return Fraction(a.numerator * b.denominator,
                         a.denominator * b.numerator)
 
     __truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv)
@@ -357,14 +356,14 @@
         result will be rational.
 
         """
-        if isinstance(b, RationalAbc):
+        if isinstance(b, numbers.Rational):
             if b.denominator == 1:
                 power = b.numerator
                 if power >= 0:
-                    return Rational(a.numerator ** power,
+                    return Fraction(a.numerator ** power,
                                     a.denominator ** power)
                 else:
-                    return Rational(a.denominator ** -power,
+                    return Fraction(a.denominator ** -power,
                                     a.numerator ** -power)
             else:
                 # A fractional power will generally produce an
@@ -379,8 +378,8 @@
             # If a is an int, keep it that way if possible.
             return a ** b.numerator
 
-        if isinstance(a, RationalAbc):
-            return Rational(a.numerator, a.denominator) ** b
+        if isinstance(a, numbers.Rational):
+            return Fraction(a.numerator, a.denominator) ** b
 
         if b.denominator == 1:
             return a ** b.numerator
@@ -388,16 +387,16 @@
         return a ** float(b)
 
     def __pos__(a):
-        """+a: Coerces a subclass instance to Rational"""
-        return Rational(a.numerator, a.denominator)
+        """+a: Coerces a subclass instance to Fraction"""
+        return Fraction(a.numerator, a.denominator)
 
     def __neg__(a):
         """-a"""
-        return Rational(-a.numerator, a.denominator)
+        return Fraction(-a.numerator, a.denominator)
 
     def __abs__(a):
         """abs(a)"""
-        return Rational(abs(a.numerator), a.denominator)
+        return Fraction(abs(a.numerator), a.denominator)
 
     def __trunc__(a):
         """trunc(a)"""
@@ -433,12 +432,12 @@
                 return floor + 1
         shift = 10**abs(ndigits)
         # See _operator_fallbacks.forward to check that the results of
-        # these operations will always be Rational and therefore have
+        # these operations will always be Fraction and therefore have
         # round().
         if ndigits > 0:
-            return Rational(round(self * shift), shift)
+            return Fraction(round(self * shift), shift)
         else:
-            return Rational(round(self / shift) * shift)
+            return Fraction(round(self / shift) * shift)
 
     def __hash__(self):
         """hash(self)
@@ -461,7 +460,7 @@
 
     def __eq__(a, b):
         """a == b"""
-        if isinstance(b, RationalAbc):
+        if isinstance(b, numbers.Rational):
             return (a.numerator == b.numerator and
                     a.denominator == b.denominator)
         if isinstance(b, numbers.Complex) and b.imag == 0:
@@ -488,7 +487,7 @@
         if isinstance(b, float):
             b = a.from_float(b)
         try:
-            # XXX: If b <: Real but not <: RationalAbc, this is likely
+            # XXX: If b <: Real but not <: Rational, this is likely
             # to fall back to a float. If the actual values differ by
             # less than MIN_FLOAT, this could falsely call them equal,
             # which would make <= inconsistent with ==. Better ways of
@@ -496,7 +495,7 @@
             diff = a - b
         except TypeError:
             return NotImplemented
-        if isinstance(diff, RationalAbc):
+        if isinstance(diff, numbers.Rational):
             return op(diff.numerator, 0)
         return op(diff, 0)
 
@@ -526,11 +525,11 @@
         return (self.__class__, (str(self),))
 
     def __copy__(self):
-        if type(self) == Rational:
+        if type(self) == Fraction:
             return self     # I'm immutable; therefore I am my own clone
         return self.__class__(self.numerator, self.denominator)
 
     def __deepcopy__(self, memo):
-        if type(self) == Rational:
+        if type(self) == Fraction:
             return self     # My components are also immutable
         return self.__class__(self.numerator, self.denominator)

Modified: python/branches/py3k/Lib/pickletools.py
==============================================================================
--- python/branches/py3k/Lib/pickletools.py	(original)
+++ python/branches/py3k/Lib/pickletools.py	Mon Feb 11 07:19:17 2008
@@ -14,9 +14,7 @@
 import pickle
 import re
 
-__all__ = ['dis',
-           'genops',
-          ]
+__all__ = ['dis', 'genops', 'optimize']
 
 bytes_types = pickle.bytes_types
 
@@ -1836,6 +1834,33 @@
             break
 
 ##############################################################################
+# A pickle optimizer.
+
+def optimize(p):
+    'Optimize a pickle string by removing unused PUT opcodes'
+    gets = set()            # set of args used by a GET opcode
+    puts = []               # (arg, startpos, stoppos) for the PUT opcodes
+    prevpos = None          # set to pos if previous opcode was a PUT
+    for opcode, arg, pos in genops(p):
+        if prevpos is not None:
+            puts.append((prevarg, prevpos, pos))
+            prevpos = None
+        if 'PUT' in opcode.name:
+            prevarg, prevpos = arg, pos
+        elif 'GET' in opcode.name:
+            gets.add(arg)
+
+    # Copy the pickle string except for PUTS without a corresponding GET
+    s = []
+    i = 0
+    for arg, start, stop in puts:
+        j = stop if (arg in gets) else start
+        s.append(p[i:j])
+        i = stop
+    s.append(p[i:])
+    return ''.join(s)
+
+##############################################################################
 # A symbolic pickle disassembler.
 
 def dis(pickle, out=None, memo=None, indentlevel=4):

Deleted: /python/branches/py3k/Lib/rational.py
==============================================================================
--- /python/branches/py3k/Lib/rational.py	Mon Feb 11 07:19:17 2008
+++ (empty file)
@@ -1,536 +0,0 @@
-# Originally contributed by Sjoerd Mullender.
-# Significantly modified by Jeffrey Yasskin <jyasskin at gmail.com>.
-
-"""Rational, infinite-precision, real numbers."""
-
-import math
-import numbers
-import operator
-import re
-
-__all__ = ["Rational"]
-
-RationalAbc = numbers.Rational
-
-
-def gcd(a, b):
-    """Calculate the Greatest Common Divisor of a and b.
-
-    Unless b==0, the result will have the same sign as b (so that when
-    b is divided by it, the result comes out positive).
-    """
-    while b:
-        a, b = b, a%b
-    return a
-
-
-_RATIONAL_FORMAT = re.compile(r"""
-    \A\s*                      # optional whitespace at the start, then
-    (?P<sign>[-+]?)            # an optional sign, then
-    (?=\d|\.\d)                # lookahead for digit or .digit
-    (?P<num>\d*)               # numerator (possibly empty)
-    (?:                        # followed by an optional
-       /(?P<denom>\d+)         # / and denominator
-    |                          # or
-       \.(?P<decimal>\d*)      # decimal point and fractional part
-    )?
-    \s*\Z                      # and optional whitespace to finish
-""", re.VERBOSE)
-
-
-class Rational(RationalAbc):
-    """This class implements rational numbers.
-
-    Rational(8, 6) will produce a rational number equivalent to
-    4/3. Both arguments must be Integral. The numerator defaults to 0
-    and the denominator defaults to 1 so that Rational(3) == 3 and
-    Rational() == 0.
-
-    Rationals can also be constructed from strings of the form
-    '[-+]?[0-9]+((/|.)[0-9]+)?', optionally surrounded by spaces.
-
-    """
-
-    __slots__ = ('_numerator', '_denominator')
-
-    # We're immutable, so use __new__ not __init__
-    def __new__(cls, numerator=0, denominator=1):
-        """Constructs a Rational.
-
-        Takes a string like '3/2' or '1.5', another Rational, or a
-        numerator/denominator pair.
-
-        """
-        self = super(Rational, cls).__new__(cls)
-
-        if denominator == 1:
-            if isinstance(numerator, str):
-                # Handle construction from strings.
-                input = numerator
-                m = _RATIONAL_FORMAT.match(input)
-                if m is None:
-                    raise ValueError('Invalid literal for Rational: ' + input)
-                numerator = m.group('num')
-                decimal = m.group('decimal')
-                if decimal:
-                    # The literal is a decimal number.
-                    numerator = int(numerator + decimal)
-                    denominator = 10**len(decimal)
-                else:
-                    # The literal is an integer or fraction.
-                    numerator = int(numerator)
-                    # Default denominator to 1.
-                    denominator = int(m.group('denom') or 1)
-
-                if m.group('sign') == '-':
-                    numerator = -numerator
-
-            elif (not isinstance(numerator, numbers.Integral) and
-                  isinstance(numerator, RationalAbc)):
-                # Handle copies from other rationals.
-                other_rational = numerator
-                numerator = other_rational.numerator
-                denominator = other_rational.denominator
-
-        if (not isinstance(numerator, numbers.Integral) or
-            not isinstance(denominator, numbers.Integral)):
-            raise TypeError("Rational(%(numerator)s, %(denominator)s):"
-                            " Both arguments must be integral." % locals())
-
-        if denominator == 0:
-            raise ZeroDivisionError('Rational(%s, 0)' % numerator)
-
-        g = gcd(numerator, denominator)
-        self._numerator = int(numerator // g)
-        self._denominator = int(denominator // g)
-        return self
-
-    @classmethod
-    def from_float(cls, f):
-        """Converts a finite float to a rational number, exactly.
-
-        Beware that Rational.from_float(0.3) != Rational(3, 10).
-
-        """
-        if not isinstance(f, float):
-            raise TypeError("%s.from_float() only takes floats, not %r (%s)" %
-                            (cls.__name__, f, type(f).__name__))
-        if math.isnan(f) or math.isinf(f):
-            raise TypeError("Cannot convert %r to %s." % (f, cls.__name__))
-        return cls(*f.as_integer_ratio())
-
-    @classmethod
-    def from_decimal(cls, dec):
-        """Converts a finite Decimal instance to a rational number, exactly."""
-        from decimal import Decimal
-        if not isinstance(dec, Decimal):
-            raise TypeError(
-                "%s.from_decimal() only takes Decimals, not %r (%s)" %
-                (cls.__name__, dec, type(dec).__name__))
-        if not dec.is_finite():
-            # Catches infinities and nans.
-            raise TypeError("Cannot convert %s to %s." % (dec, cls.__name__))
-        sign, digits, exp = dec.as_tuple()
-        digits = int(''.join(map(str, digits)))
-        if sign:
-            digits = -digits
-        if exp >= 0:
-            return cls(digits * 10 ** exp)
-        else:
-            return cls(digits, 10 ** -exp)
-
-    @classmethod
-    def from_continued_fraction(cls, seq):
-        'Build a Rational from a continued fraction expessed as a sequence'
-        n, d = 1, 0
-        for e in reversed(seq):
-            n, d = d, n
-            n += e * d
-        return cls(n, d) if seq else cls(0)
-
-    def as_continued_fraction(self):
-        'Return continued fraction expressed as a list'
-        n = self.numerator
-        d = self.denominator
-        cf = []
-        while d:
-            e = int(n // d)
-            cf.append(e)
-            n -= e * d
-            n, d = d, n
-        return cf
-
-    def approximate(self, max_denominator):
-        'Best rational approximation with a denominator <= max_denominator'
-        # XXX First cut at algorithm
-        # Still needs rounding rules as specified at
-        #       http://en.wikipedia.org/wiki/Continued_fraction
-        if self.denominator <= max_denominator:
-            return self
-        cf = self.as_continued_fraction()
-        result = Rational(0)
-        for i in range(1, len(cf)):
-            new = self.from_continued_fraction(cf[:i])
-            if new.denominator > max_denominator:
-                break
-            result = new
-        return result
-
-    @property
-    def numerator(a):
-        return a._numerator
-
-    @property
-    def denominator(a):
-        return a._denominator
-
-    def __repr__(self):
-        """repr(self)"""
-        return ('Rational(%r,%r)' % (self.numerator, self.denominator))
-
-    def __str__(self):
-        """str(self)"""
-        if self.denominator == 1:
-            return str(self.numerator)
-        else:
-            return '%s/%s' % (self.numerator, self.denominator)
-
-    def _operator_fallbacks(monomorphic_operator, fallback_operator):
-        """Generates forward and reverse operators given a purely-rational
-        operator and a function from the operator module.
-
-        Use this like:
-        __op__, __rop__ = _operator_fallbacks(just_rational_op, operator.op)
-
-        In general, we want to implement the arithmetic operations so
-        that mixed-mode operations either call an implementation whose
-        author knew about the types of both arguments, or convert both
-        to the nearest built in type and do the operation there. In
-        Rational, that means that we define __add__ and __radd__ as:
-
-            def __add__(self, other):
-                # Both types have numerators/denominator attributes,
-                # so do the operation directly
-                if isinstance(other, (int, Rational)):
-                    return Rational(self.numerator * other.denominator +
-                                    other.numerator * self.denominator,
-                                    self.denominator * other.denominator)
-                # float and complex don't have those operations, but we
-                # know about those types, so special case them.
-                elif isinstance(other, float):
-                    return float(self) + other
-                elif isinstance(other, complex):
-                    return complex(self) + other
-                # Let the other type take over.
-                return NotImplemented
-
-            def __radd__(self, other):
-                # radd handles more types than add because there's
-                # nothing left to fall back to.
-                if isinstance(other, RationalAbc):
-                    return Rational(self.numerator * other.denominator +
-                                    other.numerator * self.denominator,
-                                    self.denominator * other.denominator)
-                elif isinstance(other, Real):
-                    return float(other) + float(self)
-                elif isinstance(other, Complex):
-                    return complex(other) + complex(self)
-                return NotImplemented
-
-
-        There are 5 different cases for a mixed-type addition on
-        Rational. I'll refer to all of the above code that doesn't
-        refer to Rational, float, or complex as "boilerplate". 'r'
-        will be an instance of Rational, which is a subtype of
-        RationalAbc (r : Rational <: RationalAbc), and b : B <:
-        Complex. The first three involve 'r + b':
-
-            1. If B <: Rational, int, float, or complex, we handle
-               that specially, and all is well.
-            2. If Rational falls back to the boilerplate code, and it
-               were to return a value from __add__, we'd miss the
-               possibility that B defines a more intelligent __radd__,
-               so the boilerplate should return NotImplemented from
-               __add__. In particular, we don't handle RationalAbc
-               here, even though we could get an exact answer, in case
-               the other type wants to do something special.
-            3. If B <: Rational, Python tries B.__radd__ before
-               Rational.__add__. This is ok, because it was
-               implemented with knowledge of Rational, so it can
-               handle those instances before delegating to Real or
-               Complex.
-
-        The next two situations describe 'b + r'. We assume that b
-        didn't know about Rational in its implementation, and that it
-        uses similar boilerplate code:
-
-            4. If B <: RationalAbc, then __radd_ converts both to the
-               builtin rational type (hey look, that's us) and
-               proceeds.
-            5. Otherwise, __radd__ tries to find the nearest common
-               base ABC, and fall back to its builtin type. Since this
-               class doesn't subclass a concrete type, there's no
-               implementation to fall back to, so we need to try as
-               hard as possible to return an actual value, or the user
-               will get a TypeError.
-
-        """
-        def forward(a, b):
-            if isinstance(b, (int, Rational)):
-                return monomorphic_operator(a, b)
-            elif isinstance(b, float):
-                return fallback_operator(float(a), b)
-            elif isinstance(b, complex):
-                return fallback_operator(complex(a), b)
-            else:
-                return NotImplemented
-        forward.__name__ = '__' + fallback_operator.__name__ + '__'
-        forward.__doc__ = monomorphic_operator.__doc__
-
-        def reverse(b, a):
-            if isinstance(a, RationalAbc):
-                # Includes ints.
-                return monomorphic_operator(a, b)
-            elif isinstance(a, numbers.Real):
-                return fallback_operator(float(a), float(b))
-            elif isinstance(a, numbers.Complex):
-                return fallback_operator(complex(a), complex(b))
-            else:
-                return NotImplemented
-        reverse.__name__ = '__r' + fallback_operator.__name__ + '__'
-        reverse.__doc__ = monomorphic_operator.__doc__
-
-        return forward, reverse
-
-    def _add(a, b):
-        """a + b"""
-        return Rational(a.numerator * b.denominator +
-                        b.numerator * a.denominator,
-                        a.denominator * b.denominator)
-
-    __add__, __radd__ = _operator_fallbacks(_add, operator.add)
-
-    def _sub(a, b):
-        """a - b"""
-        return Rational(a.numerator * b.denominator -
-                        b.numerator * a.denominator,
-                        a.denominator * b.denominator)
-
-    __sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub)
-
-    def _mul(a, b):
-        """a * b"""
-        return Rational(a.numerator * b.numerator, a.denominator * b.denominator)
-
-    __mul__, __rmul__ = _operator_fallbacks(_mul, operator.mul)
-
-    def _div(a, b):
-        """a / b"""
-        return Rational(a.numerator * b.denominator,
-                        a.denominator * b.numerator)
-
-    __truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv)
-
-    def __floordiv__(a, b):
-        """a // b"""
-        return math.floor(a / b)
-
-    def __rfloordiv__(b, a):
-        """a // b"""
-        return math.floor(a / b)
-
-    def __mod__(a, b):
-        """a % b"""
-        div = a // b
-        return a - b * div
-
-    def __rmod__(b, a):
-        """a % b"""
-        div = a // b
-        return a - b * div
-
-    def __pow__(a, b):
-        """a ** b
-
-        If b is not an integer, the result will be a float or complex
-        since roots are generally irrational. If b is an integer, the
-        result will be rational.
-
-        """
-        if isinstance(b, RationalAbc):
-            if b.denominator == 1:
-                power = b.numerator
-                if power >= 0:
-                    return Rational(a.numerator ** power,
-                                    a.denominator ** power)
-                else:
-                    return Rational(a.denominator ** -power,
-                                    a.numerator ** -power)
-            else:
-                # A fractional power will generally produce an
-                # irrational number.
-                return float(a) ** float(b)
-        else:
-            return float(a) ** b
-
-    def __rpow__(b, a):
-        """a ** b"""
-        if b.denominator == 1 and b.numerator >= 0:
-            # If a is an int, keep it that way if possible.
-            return a ** b.numerator
-
-        if isinstance(a, RationalAbc):
-            return Rational(a.numerator, a.denominator) ** b
-
-        if b.denominator == 1:
-            return a ** b.numerator
-
-        return a ** float(b)
-
-    def __pos__(a):
-        """+a: Coerces a subclass instance to Rational"""
-        return Rational(a.numerator, a.denominator)
-
-    def __neg__(a):
-        """-a"""
-        return Rational(-a.numerator, a.denominator)
-
-    def __abs__(a):
-        """abs(a)"""
-        return Rational(abs(a.numerator), a.denominator)
-
-    def __trunc__(a):
-        """trunc(a)"""
-        if a.numerator < 0:
-            return -(-a.numerator // a.denominator)
-        else:
-            return a.numerator // a.denominator
-
-    def __floor__(a):
-        """Will be math.floor(a) in 3.0."""
-        return a.numerator // a.denominator
-
-    def __ceil__(a):
-        """Will be math.ceil(a) in 3.0."""
-        # The negations cleverly convince floordiv to return the ceiling.
-        return -(-a.numerator // a.denominator)
-
-    def __round__(self, ndigits=None):
-        """Will be round(self, ndigits) in 3.0.
-
-        Rounds half toward even.
-        """
-        if ndigits is None:
-            floor, remainder = divmod(self.numerator, self.denominator)
-            if remainder * 2 < self.denominator:
-                return floor
-            elif remainder * 2 > self.denominator:
-                return floor + 1
-            # Deal with the half case:
-            elif floor % 2 == 0:
-                return floor
-            else:
-                return floor + 1
-        shift = 10**abs(ndigits)
-        # See _operator_fallbacks.forward to check that the results of
-        # these operations will always be Rational and therefore have
-        # round().
-        if ndigits > 0:
-            return Rational(round(self * shift), shift)
-        else:
-            return Rational(round(self / shift) * shift)
-
-    def __hash__(self):
-        """hash(self)
-
-        Tricky because values that are exactly representable as a
-        float must have the same hash as that float.
-
-        """
-        # XXX since this method is expensive, consider caching the result
-        if self.denominator == 1:
-            # Get integers right.
-            return hash(self.numerator)
-        # Expensive check, but definitely correct.
-        if self == float(self):
-            return hash(float(self))
-        else:
-            # Use tuple's hash to avoid a high collision rate on
-            # simple fractions.
-            return hash((self.numerator, self.denominator))
-
-    def __eq__(a, b):
-        """a == b"""
-        if isinstance(b, RationalAbc):
-            return (a.numerator == b.numerator and
-                    a.denominator == b.denominator)
-        if isinstance(b, numbers.Complex) and b.imag == 0:
-            b = b.real
-        if isinstance(b, float):
-            return a == a.from_float(b)
-        else:
-            # XXX: If b.__eq__ is implemented like this method, it may
-            # give the wrong answer after float(a) changes a's
-            # value. Better ways of doing this are welcome.
-            return float(a) == b
-
-    def _subtractAndCompareToZero(a, b, op):
-        """Helper function for comparison operators.
-
-        Subtracts b from a, exactly if possible, and compares the
-        result with 0 using op, in such a way that the comparison
-        won't recurse. If the difference raises a TypeError, returns
-        NotImplemented instead.
-
-        """
-        if isinstance(b, numbers.Complex) and b.imag == 0:
-            b = b.real
-        if isinstance(b, float):
-            b = a.from_float(b)
-        try:
-            # XXX: If b <: Real but not <: RationalAbc, this is likely
-            # to fall back to a float. If the actual values differ by
-            # less than MIN_FLOAT, this could falsely call them equal,
-            # which would make <= inconsistent with ==. Better ways of
-            # doing this are welcome.
-            diff = a - b
-        except TypeError:
-            return NotImplemented
-        if isinstance(diff, RationalAbc):
-            return op(diff.numerator, 0)
-        return op(diff, 0)
-
-    def __lt__(a, b):
-        """a < b"""
-        return a._subtractAndCompareToZero(b, operator.lt)
-
-    def __gt__(a, b):
-        """a > b"""
-        return a._subtractAndCompareToZero(b, operator.gt)
-
-    def __le__(a, b):
-        """a <= b"""
-        return a._subtractAndCompareToZero(b, operator.le)
-
-    def __ge__(a, b):
-        """a >= b"""
-        return a._subtractAndCompareToZero(b, operator.ge)
-
-    def __bool__(a):
-        """a != 0"""
-        return a.numerator != 0
-
-    # support for pickling, copy, and deepcopy
-
-    def __reduce__(self):
-        return (self.__class__, (str(self),))
-
-    def __copy__(self):
-        if type(self) == Rational:
-            return self     # I'm immutable; therefore I am my own clone
-        return self.__class__(self.numerator, self.denominator)
-
-    def __deepcopy__(self, memo):
-        if type(self) == Rational:
-            return self     # My components are also immutable
-        return self.__class__(self.numerator, self.denominator)

Modified: python/branches/py3k/Lib/test/test_builtin.py
==============================================================================
--- python/branches/py3k/Lib/test/test_builtin.py	(original)
+++ python/branches/py3k/Lib/test/test_builtin.py	Mon Feb 11 07:19:17 2008
@@ -5,7 +5,7 @@
                               run_with_locale
 from operator import neg
 
-import sys, warnings, random, collections, io, rational
+import sys, warnings, random, collections, io, rational, fractions
 warnings.filterwarnings("ignore", "hex../oct.. of negative int",
                         FutureWarning, __name__)
 warnings.filterwarnings("ignore", "integer argument expected",
@@ -607,7 +607,7 @@
             n, d = f.as_integer_ratio()
             self.assertEqual(float(n).__truediv__(d), f)
 
-        R = rational.Rational
+        R = fractions.Fraction
         self.assertEqual(R(0, 1),
                          R(*float(0.0).as_integer_ratio()))
         self.assertEqual(R(5, 2),

Copied: python/branches/py3k/Lib/test/test_fractions.py (from r60724, python/branches/py3k/Lib/test/test_rational.py)
==============================================================================
--- python/branches/py3k/Lib/test/test_rational.py	(original)
+++ python/branches/py3k/Lib/test/test_fractions.py	Mon Feb 11 07:19:17 2008
@@ -1,15 +1,15 @@
-"""Tests for Lib/rational.py."""
+"""Tests for Lib/fractions.py."""
 
 from decimal import Decimal
 from test.test_support import run_unittest, verbose
 import math
 import operator
-import rational
+import fractions
 import unittest
 from copy import copy, deepcopy
 from pickle import dumps, loads
-R = rational.Rational
-gcd = rational.gcd
+R = fractions.Fraction
+gcd = fractions.gcd
 
 
 class GcdTest(unittest.TestCase):
@@ -31,7 +31,7 @@
     return (r.numerator, r.denominator)
 
 
-class RationalTest(unittest.TestCase):
+class FractionTest(unittest.TestCase):
 
     def assertTypedEquals(self, expected, actual):
         """Asserts that both the types and values are the same."""
@@ -60,7 +60,7 @@
         self.assertEquals((7, 15), _components(R(7, 15)))
         self.assertEquals((10**23, 1), _components(R(10**23)))
 
-        self.assertRaisesMessage(ZeroDivisionError, "Rational(12, 0)",
+        self.assertRaisesMessage(ZeroDivisionError, "Fraction(12, 0)",
                                  R, 12, 0)
         self.assertRaises(TypeError, R, 1.5)
         self.assertRaises(TypeError, R, 1.5 + 3j)
@@ -81,41 +81,41 @@
         self.assertEquals((3, 5), _components(R(" .6 ")))
 
         self.assertRaisesMessage(
-            ZeroDivisionError, "Rational(3, 0)",
+            ZeroDivisionError, "Fraction(3, 0)",
             R, "3/0")
         self.assertRaisesMessage(
-            ValueError, "Invalid literal for Rational: 3/",
+            ValueError, "Invalid literal for Fraction: 3/",
             R, "3/")
         self.assertRaisesMessage(
-            ValueError, "Invalid literal for Rational: 3 /2",
+            ValueError, "Invalid literal for Fraction: 3 /2",
             R, "3 /2")
         self.assertRaisesMessage(
             # Denominators don't need a sign.
-            ValueError, "Invalid literal for Rational: 3/+2",
+            ValueError, "Invalid literal for Fraction: 3/+2",
             R, "3/+2")
         self.assertRaisesMessage(
             # Imitate float's parsing.
-            ValueError, "Invalid literal for Rational: + 3/2",
+            ValueError, "Invalid literal for Fraction: + 3/2",
             R, "+ 3/2")
         self.assertRaisesMessage(
             # Avoid treating '.' as a regex special character.
-            ValueError, "Invalid literal for Rational: 3a2",
+            ValueError, "Invalid literal for Fraction: 3a2",
             R, "3a2")
         self.assertRaisesMessage(
             # Only parse ordinary decimals, not scientific form.
-            ValueError, "Invalid literal for Rational: 3.2e4",
+            ValueError, "Invalid literal for Fraction: 3.2e4",
             R, "3.2e4")
         self.assertRaisesMessage(
             # Don't accept combinations of decimals and rationals.
-            ValueError, "Invalid literal for Rational: 3/7.2",
+            ValueError, "Invalid literal for Fraction: 3/7.2",
             R, "3/7.2")
         self.assertRaisesMessage(
             # Don't accept combinations of decimals and rationals.
-            ValueError, "Invalid literal for Rational: 3.2/7",
+            ValueError, "Invalid literal for Fraction: 3.2/7",
             R, "3.2/7")
         self.assertRaisesMessage(
             # Allow 3. and .3, but not .
-            ValueError, "Invalid literal for Rational: .",
+            ValueError, "Invalid literal for Fraction: .",
             R, ".")
 
     def testImmutable(self):
@@ -136,7 +136,7 @@
 
     def testFromFloat(self):
         self.assertRaisesMessage(
-            TypeError, "Rational.from_float() only takes floats, not 3 (int)",
+            TypeError, "Fraction.from_float() only takes floats, not 3 (int)",
             R.from_float, 3)
 
         self.assertEquals((0, 1), _components(R.from_float(-0.0)))
@@ -152,19 +152,19 @@
         inf = 1e1000
         nan = inf - inf
         self.assertRaisesMessage(
-            TypeError, "Cannot convert inf to Rational.",
+            TypeError, "Cannot convert inf to Fraction.",
             R.from_float, inf)
         self.assertRaisesMessage(
-            TypeError, "Cannot convert -inf to Rational.",
+            TypeError, "Cannot convert -inf to Fraction.",
             R.from_float, -inf)
         self.assertRaisesMessage(
-            TypeError, "Cannot convert nan to Rational.",
+            TypeError, "Cannot convert nan to Fraction.",
             R.from_float, nan)
 
     def testFromDecimal(self):
         self.assertRaisesMessage(
             TypeError,
-            "Rational.from_decimal() only takes Decimals, not 3 (int)",
+            "Fraction.from_decimal() only takes Decimals, not 3 (int)",
             R.from_decimal, 3)
         self.assertEquals(R(0), R.from_decimal(Decimal("-0")))
         self.assertEquals(R(5, 10), R.from_decimal(Decimal("0.5")))
@@ -174,16 +174,16 @@
                           R.from_decimal(Decimal("0." + "9" * 30)))
 
         self.assertRaisesMessage(
-            TypeError, "Cannot convert Infinity to Rational.",
+            TypeError, "Cannot convert Infinity to Fraction.",
             R.from_decimal, Decimal("inf"))
         self.assertRaisesMessage(
-            TypeError, "Cannot convert -Infinity to Rational.",
+            TypeError, "Cannot convert -Infinity to Fraction.",
             R.from_decimal, Decimal("-inf"))
         self.assertRaisesMessage(
-            TypeError, "Cannot convert NaN to Rational.",
+            TypeError, "Cannot convert NaN to Fraction.",
             R.from_decimal, Decimal("nan"))
         self.assertRaisesMessage(
-            TypeError, "Cannot convert sNaN to Rational.",
+            TypeError, "Cannot convert sNaN to Fraction.",
             R.from_decimal, Decimal("snan"))
 
     def testFromContinuedFraction(self):
@@ -316,7 +316,7 @@
         # Decimal refuses mixed comparisons.
         self.assertRaisesMessage(
             TypeError,
-            "unsupported operand type(s) for +: 'Rational' and 'Decimal'",
+            "unsupported operand type(s) for +: 'Fraction' and 'Decimal'",
             operator.add, R(3,11), Decimal('3.1415926'))
         self.assertNotEquals(R(5, 2), Decimal('2.5'))
 
@@ -378,7 +378,7 @@
         self.assertFalse(R(5, 2) == 2)
 
     def testStringification(self):
-        self.assertEquals("Rational(7,3)", repr(R(7, 3)))
+        self.assertEquals("Fraction(7,3)", repr(R(7, 3)))
         self.assertEquals("7/3", str(R(7, 3)))
         self.assertEquals("7", str(R(7, 1)))
 
@@ -421,7 +421,7 @@
         self.assertEqual(id(r), id(deepcopy(r)))
 
 def test_main():
-    run_unittest(RationalTest, GcdTest)
+    run_unittest(FractionTest, GcdTest)
 
 if __name__ == '__main__':
     test_main()

Deleted: /python/branches/py3k/Lib/test/test_rational.py
==============================================================================
--- /python/branches/py3k/Lib/test/test_rational.py	Mon Feb 11 07:19:17 2008
+++ (empty file)
@@ -1,427 +0,0 @@
-"""Tests for Lib/rational.py."""
-
-from decimal import Decimal
-from test.test_support import run_unittest, verbose
-import math
-import operator
-import rational
-import unittest
-from copy import copy, deepcopy
-from pickle import dumps, loads
-R = rational.Rational
-gcd = rational.gcd
-
-
-class GcdTest(unittest.TestCase):
-
-    def testMisc(self):
-        self.assertEquals(0, gcd(0, 0))
-        self.assertEquals(1, gcd(1, 0))
-        self.assertEquals(-1, gcd(-1, 0))
-        self.assertEquals(1, gcd(0, 1))
-        self.assertEquals(-1, gcd(0, -1))
-        self.assertEquals(1, gcd(7, 1))
-        self.assertEquals(-1, gcd(7, -1))
-        self.assertEquals(1, gcd(-23, 15))
-        self.assertEquals(12, gcd(120, 84))
-        self.assertEquals(-12, gcd(84, -120))
-
-
-def _components(r):
-    return (r.numerator, r.denominator)
-
-
-class RationalTest(unittest.TestCase):
-
-    def assertTypedEquals(self, expected, actual):
-        """Asserts that both the types and values are the same."""
-        self.assertEquals(type(expected), type(actual))
-        self.assertEquals(expected, actual)
-
-    def assertRaisesMessage(self, exc_type, message,
-                            callable, *args, **kwargs):
-        """Asserts that callable(*args, **kwargs) raises exc_type(message)."""
-        try:
-            callable(*args, **kwargs)
-        except exc_type as e:
-            self.assertEquals(message, str(e))
-        else:
-            self.fail("%s not raised" % exc_type.__name__)
-
-    def testInit(self):
-        self.assertEquals((0, 1), _components(R()))
-        self.assertEquals((7, 1), _components(R(7)))
-        self.assertEquals((7, 3), _components(R(R(7, 3))))
-
-        self.assertEquals((-1, 1), _components(R(-1, 1)))
-        self.assertEquals((-1, 1), _components(R(1, -1)))
-        self.assertEquals((1, 1), _components(R(-2, -2)))
-        self.assertEquals((1, 2), _components(R(5, 10)))
-        self.assertEquals((7, 15), _components(R(7, 15)))
-        self.assertEquals((10**23, 1), _components(R(10**23)))
-
-        self.assertRaisesMessage(ZeroDivisionError, "Rational(12, 0)",
-                                 R, 12, 0)
-        self.assertRaises(TypeError, R, 1.5)
-        self.assertRaises(TypeError, R, 1.5 + 3j)
-
-        self.assertRaises(TypeError, R, R(1, 2), 3)
-        self.assertRaises(TypeError, R, "3/2", 3)
-
-    def testFromString(self):
-        self.assertEquals((5, 1), _components(R("5")))
-        self.assertEquals((3, 2), _components(R("3/2")))
-        self.assertEquals((3, 2), _components(R(" \n  +3/2")))
-        self.assertEquals((-3, 2), _components(R("-3/2  ")))
-        self.assertEquals((3, 2), _components(R("    03/02 \n  ")))
-        self.assertEquals((3, 2), _components(R("    03/02 \n  ")))
-        self.assertEquals((16, 5), _components(R(" 3.2 ")))
-        self.assertEquals((-16, 5), _components(R(" -3.2 ")))
-        self.assertEquals((-3, 1), _components(R(" -3. ")))
-        self.assertEquals((3, 5), _components(R(" .6 ")))
-
-        self.assertRaisesMessage(
-            ZeroDivisionError, "Rational(3, 0)",
-            R, "3/0")
-        self.assertRaisesMessage(
-            ValueError, "Invalid literal for Rational: 3/",
-            R, "3/")
-        self.assertRaisesMessage(
-            ValueError, "Invalid literal for Rational: 3 /2",
-            R, "3 /2")
-        self.assertRaisesMessage(
-            # Denominators don't need a sign.
-            ValueError, "Invalid literal for Rational: 3/+2",
-            R, "3/+2")
-        self.assertRaisesMessage(
-            # Imitate float's parsing.
-            ValueError, "Invalid literal for Rational: + 3/2",
-            R, "+ 3/2")
-        self.assertRaisesMessage(
-            # Avoid treating '.' as a regex special character.
-            ValueError, "Invalid literal for Rational: 3a2",
-            R, "3a2")
-        self.assertRaisesMessage(
-            # Only parse ordinary decimals, not scientific form.
-            ValueError, "Invalid literal for Rational: 3.2e4",
-            R, "3.2e4")
-        self.assertRaisesMessage(
-            # Don't accept combinations of decimals and rationals.
-            ValueError, "Invalid literal for Rational: 3/7.2",
-            R, "3/7.2")
-        self.assertRaisesMessage(
-            # Don't accept combinations of decimals and rationals.
-            ValueError, "Invalid literal for Rational: 3.2/7",
-            R, "3.2/7")
-        self.assertRaisesMessage(
-            # Allow 3. and .3, but not .
-            ValueError, "Invalid literal for Rational: .",
-            R, ".")
-
-    def testImmutable(self):
-        r = R(7, 3)
-        r.__init__(2, 15)
-        self.assertEquals((7, 3), _components(r))
-
-        self.assertRaises(AttributeError, setattr, r, 'numerator', 12)
-        self.assertRaises(AttributeError, setattr, r, 'denominator', 6)
-        self.assertEquals((7, 3), _components(r))
-
-        # But if you _really_ need to:
-        r._numerator = 4
-        r._denominator = 2
-        self.assertEquals((4, 2), _components(r))
-        # Which breaks some important operations:
-        self.assertNotEquals(R(4, 2), r)
-
-    def testFromFloat(self):
-        self.assertRaisesMessage(
-            TypeError, "Rational.from_float() only takes floats, not 3 (int)",
-            R.from_float, 3)
-
-        self.assertEquals((0, 1), _components(R.from_float(-0.0)))
-        self.assertEquals((10, 1), _components(R.from_float(10.0)))
-        self.assertEquals((-5, 2), _components(R.from_float(-2.5)))
-        self.assertEquals((99999999999999991611392, 1),
-                          _components(R.from_float(1e23)))
-        self.assertEquals(float(10**23), float(R.from_float(1e23)))
-        self.assertEquals((3602879701896397, 1125899906842624),
-                          _components(R.from_float(3.2)))
-        self.assertEquals(3.2, float(R.from_float(3.2)))
-
-        inf = 1e1000
-        nan = inf - inf
-        self.assertRaisesMessage(
-            TypeError, "Cannot convert inf to Rational.",
-            R.from_float, inf)
-        self.assertRaisesMessage(
-            TypeError, "Cannot convert -inf to Rational.",
-            R.from_float, -inf)
-        self.assertRaisesMessage(
-            TypeError, "Cannot convert nan to Rational.",
-            R.from_float, nan)
-
-    def testFromDecimal(self):
-        self.assertRaisesMessage(
-            TypeError,
-            "Rational.from_decimal() only takes Decimals, not 3 (int)",
-            R.from_decimal, 3)
-        self.assertEquals(R(0), R.from_decimal(Decimal("-0")))
-        self.assertEquals(R(5, 10), R.from_decimal(Decimal("0.5")))
-        self.assertEquals(R(5, 1000), R.from_decimal(Decimal("5e-3")))
-        self.assertEquals(R(5000), R.from_decimal(Decimal("5e3")))
-        self.assertEquals(1 - R(1, 10**30),
-                          R.from_decimal(Decimal("0." + "9" * 30)))
-
-        self.assertRaisesMessage(
-            TypeError, "Cannot convert Infinity to Rational.",
-            R.from_decimal, Decimal("inf"))
-        self.assertRaisesMessage(
-            TypeError, "Cannot convert -Infinity to Rational.",
-            R.from_decimal, Decimal("-inf"))
-        self.assertRaisesMessage(
-            TypeError, "Cannot convert NaN to Rational.",
-            R.from_decimal, Decimal("nan"))
-        self.assertRaisesMessage(
-            TypeError, "Cannot convert sNaN to Rational.",
-            R.from_decimal, Decimal("snan"))
-
-    def testFromContinuedFraction(self):
-        self.assertRaises(TypeError, R.from_continued_fraction, None)
-        phi = R.from_continued_fraction([1]*100)
-        self.assertEquals(round(phi - (1 + 5 ** 0.5) / 2, 10), 0.0)
-
-        minusphi = R.from_continued_fraction([-1]*100)
-        self.assertEquals(round(minusphi + (1 + 5 ** 0.5) / 2, 10), 0.0)
-
-        self.assertEquals(R.from_continued_fraction([0]), R(0))
-        self.assertEquals(R.from_continued_fraction([]), R(0))
-
-    def testAsContinuedFraction(self):
-        self.assertEqual(R.from_float(math.pi).as_continued_fraction()[:15],
-                         [3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 3, 3])
-        self.assertEqual(R.from_float(-math.pi).as_continued_fraction()[:16],
-                         [-4, 1, 6, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 3, 3])
-        self.assertEqual(R(0).as_continued_fraction(), [0])
-
-    def testApproximateFrom(self):
-        self.assertEqual(R.from_float(math.pi).approximate(10000), R(355, 113))
-        self.assertEqual(R.from_float(-math.pi).approximate(10000), R(-355, 113))
-        self.assertEqual(R.from_float(0.0).approximate(10000), R(0))
-
-    def testConversions(self):
-        self.assertTypedEquals(-1, math.trunc(R(-11, 10)))
-        self.assertTypedEquals(-2, math.floor(R(-11, 10)))
-        self.assertTypedEquals(-1, math.ceil(R(-11, 10)))
-        self.assertTypedEquals(-1, math.ceil(R(-10, 10)))
-        self.assertTypedEquals(-1, int(R(-11, 10)))
-
-        self.assertTypedEquals(0, round(R(-1, 10)))
-        self.assertTypedEquals(0, round(R(-5, 10)))
-        self.assertTypedEquals(-2, round(R(-15, 10)))
-        self.assertTypedEquals(-1, round(R(-7, 10)))
-
-        self.assertEquals(False, bool(R(0, 1)))
-        self.assertEquals(True, bool(R(3, 2)))
-        self.assertTypedEquals(0.1, float(R(1, 10)))
-
-        # Check that __float__ isn't implemented by converting the
-        # numerator and denominator to float before dividing.
-        self.assertRaises(OverflowError, float, int('2'*400+'7'))
-        self.assertAlmostEquals(2.0/3,
-                                float(R(int('2'*400+'7'), int('3'*400+'1'))))
-
-        self.assertTypedEquals(0.1+0j, complex(R(1,10)))
-
-    def testRound(self):
-        self.assertTypedEquals(R(-200), round(R(-150), -2))
-        self.assertTypedEquals(R(-200), round(R(-250), -2))
-        self.assertTypedEquals(R(30), round(R(26), -1))
-        self.assertTypedEquals(R(-2, 10), round(R(-15, 100), 1))
-        self.assertTypedEquals(R(-2, 10), round(R(-25, 100), 1))
-
-
-    def testArithmetic(self):
-        self.assertEquals(R(1, 2), R(1, 10) + R(2, 5))
-        self.assertEquals(R(-3, 10), R(1, 10) - R(2, 5))
-        self.assertEquals(R(1, 25), R(1, 10) * R(2, 5))
-        self.assertEquals(R(1, 4), R(1, 10) / R(2, 5))
-        self.assertTypedEquals(2, R(9, 10) // R(2, 5))
-        self.assertTypedEquals(10**23, R(10**23, 1) // R(1))
-        self.assertEquals(R(2, 3), R(-7, 3) % R(3, 2))
-        self.assertEquals(R(8, 27), R(2, 3) ** R(3))
-        self.assertEquals(R(27, 8), R(2, 3) ** R(-3))
-        self.assertTypedEquals(2.0, R(4) ** R(1, 2))
-        z = pow(R(-1), R(1, 2))
-        self.assertAlmostEquals(z.real, 0)
-        self.assertEquals(z.imag, 1)
-
-    def testMixedArithmetic(self):
-        self.assertTypedEquals(R(11, 10), R(1, 10) + 1)
-        self.assertTypedEquals(1.1, R(1, 10) + 1.0)
-        self.assertTypedEquals(1.1 + 0j, R(1, 10) + (1.0 + 0j))
-        self.assertTypedEquals(R(11, 10), 1 + R(1, 10))
-        self.assertTypedEquals(1.1, 1.0 + R(1, 10))
-        self.assertTypedEquals(1.1 + 0j, (1.0 + 0j) + R(1, 10))
-
-        self.assertTypedEquals(R(-9, 10), R(1, 10) - 1)
-        self.assertTypedEquals(-0.9, R(1, 10) - 1.0)
-        self.assertTypedEquals(-0.9 + 0j, R(1, 10) - (1.0 + 0j))
-        self.assertTypedEquals(R(9, 10), 1 - R(1, 10))
-        self.assertTypedEquals(0.9, 1.0 - R(1, 10))
-        self.assertTypedEquals(0.9 + 0j, (1.0 + 0j) - R(1, 10))
-
-        self.assertTypedEquals(R(1, 10), R(1, 10) * 1)
-        self.assertTypedEquals(0.1, R(1, 10) * 1.0)
-        self.assertTypedEquals(0.1 + 0j, R(1, 10) * (1.0 + 0j))
-        self.assertTypedEquals(R(1, 10), 1 * R(1, 10))
-        self.assertTypedEquals(0.1, 1.0 * R(1, 10))
-        self.assertTypedEquals(0.1 + 0j, (1.0 + 0j) * R(1, 10))
-
-        self.assertTypedEquals(R(1, 10), R(1, 10) / 1)
-        self.assertTypedEquals(0.1, R(1, 10) / 1.0)
-        self.assertTypedEquals(0.1 + 0j, R(1, 10) / (1.0 + 0j))
-        self.assertTypedEquals(R(10, 1), 1 / R(1, 10))
-        self.assertTypedEquals(10.0, 1.0 / R(1, 10))
-        self.assertTypedEquals(10.0 + 0j, (1.0 + 0j) / R(1, 10))
-
-        self.assertTypedEquals(0, R(1, 10) // 1)
-        self.assertTypedEquals(0, R(1, 10) // 1.0)
-        self.assertTypedEquals(10, 1 // R(1, 10))
-        self.assertTypedEquals(10**23, 10**22 // R(1, 10))
-        self.assertTypedEquals(10, 1.0 // R(1, 10))
-
-        self.assertTypedEquals(R(1, 10), R(1, 10) % 1)
-        self.assertTypedEquals(0.1, R(1, 10) % 1.0)
-        self.assertTypedEquals(R(0, 1), 1 % R(1, 10))
-        self.assertTypedEquals(0.0, 1.0 % R(1, 10))
-
-        # No need for divmod since we don't override it.
-
-        # ** has more interesting conversion rules.
-        self.assertTypedEquals(R(100, 1), R(1, 10) ** -2)
-        self.assertTypedEquals(R(100, 1), R(10, 1) ** 2)
-        self.assertTypedEquals(0.1, R(1, 10) ** 1.0)
-        self.assertTypedEquals(0.1 + 0j, R(1, 10) ** (1.0 + 0j))
-        self.assertTypedEquals(4 , 2 ** R(2, 1))
-        z = pow(-1, R(1, 2))
-        self.assertAlmostEquals(0, z.real)
-        self.assertEquals(1, z.imag)
-        self.assertTypedEquals(R(1, 4) , 2 ** R(-2, 1))
-        self.assertTypedEquals(2.0 , 4 ** R(1, 2))
-        self.assertTypedEquals(0.25, 2.0 ** R(-2, 1))
-        self.assertTypedEquals(1.0 + 0j, (1.0 + 0j) ** R(1, 10))
-
-    def testMixingWithDecimal(self):
-        # Decimal refuses mixed comparisons.
-        self.assertRaisesMessage(
-            TypeError,
-            "unsupported operand type(s) for +: 'Rational' and 'Decimal'",
-            operator.add, R(3,11), Decimal('3.1415926'))
-        self.assertNotEquals(R(5, 2), Decimal('2.5'))
-
-    def testComparisons(self):
-        self.assertTrue(R(1, 2) < R(2, 3))
-        self.assertFalse(R(1, 2) < R(1, 2))
-        self.assertTrue(R(1, 2) <= R(2, 3))
-        self.assertTrue(R(1, 2) <= R(1, 2))
-        self.assertFalse(R(2, 3) <= R(1, 2))
-        self.assertTrue(R(1, 2) == R(1, 2))
-        self.assertFalse(R(1, 2) == R(1, 3))
-        self.assertFalse(R(1, 2) != R(1, 2))
-        self.assertTrue(R(1, 2) != R(1, 3))
-
-    def testMixedLess(self):
-        self.assertTrue(2 < R(5, 2))
-        self.assertFalse(2 < R(4, 2))
-        self.assertTrue(R(5, 2) < 3)
-        self.assertFalse(R(4, 2) < 2)
-
-        self.assertTrue(R(1, 2) < 0.6)
-        self.assertFalse(R(1, 2) < 0.4)
-        self.assertTrue(0.4 < R(1, 2))
-        self.assertFalse(0.5 < R(1, 2))
-
-    def testMixedLessEqual(self):
-        self.assertTrue(0.5 <= R(1, 2))
-        self.assertFalse(0.6 <= R(1, 2))
-        self.assertTrue(R(1, 2) <= 0.5)
-        self.assertFalse(R(1, 2) <= 0.4)
-        self.assertTrue(2 <= R(4, 2))
-        self.assertFalse(2 <= R(3, 2))
-        self.assertTrue(R(4, 2) <= 2)
-        self.assertFalse(R(5, 2) <= 2)
-
-    def testBigFloatComparisons(self):
-        # Because 10**23 can't be represented exactly as a float:
-        self.assertFalse(R(10**23) == float(10**23))
-        # The first test demonstrates why these are important.
-        self.assertFalse(1e23 < float(R(math.trunc(1e23) + 1)))
-        self.assertTrue(1e23 < R(math.trunc(1e23) + 1))
-        self.assertFalse(1e23 <= R(math.trunc(1e23) - 1))
-        self.assertTrue(1e23 > R(math.trunc(1e23) - 1))
-        self.assertFalse(1e23 >= R(math.trunc(1e23) + 1))
-
-    def testBigComplexComparisons(self):
-        self.assertFalse(R(10**23) == complex(10**23))
-        self.assertTrue(R(10**23) > complex(10**23))
-        self.assertFalse(R(10**23) <= complex(10**23))
-
-    def testMixedEqual(self):
-        self.assertTrue(0.5 == R(1, 2))
-        self.assertFalse(0.6 == R(1, 2))
-        self.assertTrue(R(1, 2) == 0.5)
-        self.assertFalse(R(1, 2) == 0.4)
-        self.assertTrue(2 == R(4, 2))
-        self.assertFalse(2 == R(3, 2))
-        self.assertTrue(R(4, 2) == 2)
-        self.assertFalse(R(5, 2) == 2)
-
-    def testStringification(self):
-        self.assertEquals("Rational(7,3)", repr(R(7, 3)))
-        self.assertEquals("7/3", str(R(7, 3)))
-        self.assertEquals("7", str(R(7, 1)))
-
-    def testHash(self):
-        self.assertEquals(hash(2.5), hash(R(5, 2)))
-        self.assertEquals(hash(10**50), hash(R(10**50)))
-        self.assertNotEquals(hash(float(10**23)), hash(R(10**23)))
-
-    def testApproximatePi(self):
-        # Algorithm borrowed from
-        # http://docs.python.org/lib/decimal-recipes.html
-        three = R(3)
-        lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24
-        while abs(s - lasts) > R(1, 10**9):
-            lasts = s
-            n, na = n+na, na+8
-            d, da = d+da, da+32
-            t = (t * n) / d
-            s += t
-        self.assertAlmostEquals(math.pi, s)
-
-    def testApproximateCos1(self):
-        # Algorithm borrowed from
-        # http://docs.python.org/lib/decimal-recipes.html
-        x = R(1)
-        i, lasts, s, fact, num, sign = 0, 0, R(1), 1, 1, 1
-        while abs(s - lasts) > R(1, 10**9):
-            lasts = s
-            i += 2
-            fact *= i * (i-1)
-            num *= x * x
-            sign *= -1
-            s += num / fact * sign
-        self.assertAlmostEquals(math.cos(1), s)
-
-    def test_copy_deepcopy_pickle(self):
-        r = R(13, 7)
-        self.assertEqual(r, loads(dumps(r)))
-        self.assertEqual(id(r), id(copy(r)))
-        self.assertEqual(id(r), id(deepcopy(r)))
-
-def test_main():
-    run_unittest(RationalTest, GcdTest)
-
-if __name__ == '__main__':
-    test_main()

Modified: python/branches/py3k/Modules/_collectionsmodule.c
==============================================================================
--- python/branches/py3k/Modules/_collectionsmodule.c	(original)
+++ python/branches/py3k/Modules/_collectionsmodule.c	Mon Feb 11 07:19:17 2008
@@ -1182,6 +1182,8 @@
 static PyMethodDef defdict_methods[] = {
 	{"__missing__", (PyCFunction)defdict_missing, METH_O,
 	 defdict_missing_doc},
+	{"copy", (PyCFunction)defdict_copy, METH_NOARGS,
+         defdict_copy_doc},
 	{"__copy__", (PyCFunction)defdict_copy, METH_NOARGS,
 	 defdict_copy_doc},
 	{"__reduce__", (PyCFunction)defdict_reduce, METH_NOARGS,


More information about the Python-3000-checkins mailing list