]> granicus.if.org Git - python/commitdiff
As discussed on python-dev, remove several operator functions
authorRaymond Hettinger <python@rcn.com>
Mon, 26 Jan 2009 02:09:03 +0000 (02:09 +0000)
committerRaymond Hettinger <python@rcn.com>
Mon, 26 Jan 2009 02:09:03 +0000 (02:09 +0000)
isSequenceType(), isMappingType(), and isNumberType() in favor
of using abstract base classes.  Also, remove repeat() and irepeat()
in favor of mul() and imul().

After the buildbots have had a go at this.  Will backport to Py3.0.1.
For Py2.7, will just mark as deprecated.

Doc/library/operator.rst
Lib/locale.py
Lib/test/test_array.py
Lib/test/test_bool.py
Lib/test/test_operator.py
Misc/NEWS
Modules/operator.c

index d1d1c168ad91065b1e07cd0bf04f8248b57c2323..089c7fafe6f98ad1487261e5fd7061ec54b309f7 100644 (file)
@@ -221,12 +221,6 @@ Operations which work with sequences include:
    Return the index of the first of occurrence of *b* in *a*.
 
 
-.. function:: repeat(a, b)
-              __repeat__(a, b)
-
-   Return ``a * b`` where *a* is a sequence and *b* is an integer.
-
-
 .. function:: setitem(a, b, c)
               __setitem__(a, b, c)
 
@@ -294,13 +288,6 @@ example, the :term:`statement` ``x += y`` is equivalent to
    ``a = ipow(a, b)`` is equivalent to ``a **= b``.
 
 
-.. function:: irepeat(a, b)
-              __irepeat__(a, b)
-
-   ``a = irepeat(a, b)`` is equivalent to ``a *= b`` where *a* is a sequence and
-   *b* is an integer.
-
-
 .. function:: irshift(a, b)
               __irshift__(a, b)
 
@@ -324,67 +311,6 @@ example, the :term:`statement` ``x += y`` is equivalent to
 
    ``a = ixor(a, b)`` is equivalent to ``a ^= b``.
 
-
-The :mod:`operator` module also defines a few predicates to test the type of
-objects.
-
-.. XXX just remove them?
-.. note::
-
-   Be careful not to misinterpret the results of these functions; none have any
-   measure of reliability with instance objects.
-   For example:
-
-      >>> class C:
-      ...     pass
-      ...
-      >>> import operator
-      >>> obj = C()
-      >>> operator.isMappingType(obj)
-      True
-
-.. note::
-
-   Since there are now abstract classes for collection types, you should write,
-   for example, ``isinstance(obj, collections.Mapping)`` and ``isinstance(obj,
-   collections.Sequence)``.
-
-.. function:: isMappingType(obj)
-
-   Returns true if the object *obj* supports the mapping interface. This is true for
-   dictionaries and all instance objects defining :meth:`__getitem__`.
-
-   .. warning::
-
-      There is no reliable way to test if an instance supports the complete mapping
-      protocol since the interface itself is ill-defined.  This makes this test less
-      useful than it otherwise might be.
-
-
-.. function:: isNumberType(obj)
-
-   Returns true if the object *obj* represents a number.  This is true for all
-   numeric types implemented in C.
-
-   .. warning::
-
-      There is no reliable way to test if an instance supports the complete numeric
-      interface since the interface itself is ill-defined.  This makes this test less
-      useful than it otherwise might be.
-
-
-.. function:: isSequenceType(obj)
-
-   Returns true if the object *obj* supports the sequence protocol. This returns true
-   for all objects which define sequence methods in C, and for all instance objects
-   defining :meth:`__getitem__`.
-
-   .. warning::
-
-      There is no reliable way to test if an instance supports the complete sequence
-      interface since the interface itself is ill-defined.  This makes this test less
-      useful than it otherwise might be.
-
 Example: Build a dictionary that maps the ordinals from ``0`` to ``255`` to
 their character equivalents.
 
@@ -513,8 +439,6 @@ Python syntax and the functions in the :mod:`operator` module.
 +-----------------------+-------------------------+---------------------------------+
 | Right Shift           | ``a >> b``              | ``rshift(a, b)``                |
 +-----------------------+-------------------------+---------------------------------+
-| Sequence Repetition   | ``seq * i``             | ``repeat(seq, i)``              |
-+-----------------------+-------------------------+---------------------------------+
 | String Formatting     | ``s % obj``             | ``mod(s, obj)``                 |
 +-----------------------+-------------------------+---------------------------------+
 | Subtraction           | ``a - b``               | ``sub(a, b)``                   |
index 0bed19e292f7069f7ac19799793bac6c9a58283d..4116ef122be744c86bf28653e016c2de4a7ae75f 100644 (file)
@@ -187,7 +187,7 @@ def format(percent, value, grouping=False, monetary=False, *additional):
             formatted = _group(formatted, monetary=monetary)[0]
     return formatted
 
-import re, operator
+import re, collections
 _percent_re = re.compile(r'%(?:\((?P<key>.*?)\))?'
                          r'(?P<modifiers>[-#0-9 +*.hlL]*?)[eEfFgGdiouxXcrs%]')
 
@@ -207,7 +207,7 @@ def format_string(f, val, grouping=False):
             del new_val[i+1:i+1+starcount]
             i += (1 + starcount)
         val = tuple(new_val)
-    elif operator.isMappingType(val):
+    elif isinstance(val, collections.Mapping):
         for perc in percents:
             key = perc.group("key")
             val[key] = format(perc.group(), val[key], grouping)
index 2b80a7d041056035be80d286b9e01622474380a0..08c64cb73c4c50d81c5c1faf5490fc529a055ced 100755 (executable)
@@ -725,8 +725,6 @@ class BaseTest(unittest.TestCase):
         self.assertRaises(BufferError, operator.setitem, a, slice(0, 0), a)
         self.assertRaises(BufferError, operator.delitem, a, 0)
         self.assertRaises(BufferError, operator.delitem, a, slice(0, 1))
-        self.assertRaises(BufferError, operator.irepeat, a, 2)
-        self.assertRaises(BufferError, operator.irepeat, a, 0)
 
     def test_weakref(self):
         s = array.array(self.typecode, self.example)
index 591b0eb3964186c91e74c979ae2578659278d5b9..80229aa1f979c8cf691536cb8bd877596459bdf0 100644 (file)
@@ -245,16 +245,10 @@ class BoolTest(unittest.TestCase):
         import operator
         self.assertIs(operator.truth(0), False)
         self.assertIs(operator.truth(1), True)
-        self.assertIs(operator.isNumberType(None), False)
-        self.assertIs(operator.isNumberType(0), True)
         self.assertIs(operator.not_(1), False)
         self.assertIs(operator.not_(0), True)
-        self.assertIs(operator.isSequenceType(0), False)
-        self.assertIs(operator.isSequenceType([]), True)
         self.assertIs(operator.contains([], 1), False)
         self.assertIs(operator.contains([1], 1), True)
-        self.assertIs(operator.isMappingType(1), False)
-        self.assertIs(operator.isMappingType({}), True)
         self.assertIs(operator.lt(0, 0), False)
         self.assertIs(operator.lt(0, 1), True)
         self.assertIs(operator.is_(True, True), True)
index 2a02dac2f62f82f8d85ee0d2b6c2744b362b7f10..bf38298a45705e4a4404f26ea705e1885d4de56e 100644 (file)
@@ -164,31 +164,6 @@ class OperatorTestCase(unittest.TestCase):
         self.failUnlessRaises(TypeError, operator.invert, None)
         self.assertEqual(operator.inv(4), -5)
 
-    def test_isMappingType(self):
-        self.failUnlessRaises(TypeError, operator.isMappingType)
-        self.failIf(operator.isMappingType(1))
-        self.failIf(operator.isMappingType(operator.isMappingType))
-        self.failUnless(operator.isMappingType(operator.__dict__))
-        self.failUnless(operator.isMappingType({}))
-
-    def test_isNumberType(self):
-        self.failUnlessRaises(TypeError, operator.isNumberType)
-        self.failUnless(operator.isNumberType(8))
-        self.failUnless(operator.isNumberType(8j))
-        self.failUnless(operator.isNumberType(8))
-        self.failUnless(operator.isNumberType(8.3))
-        self.failIf(operator.isNumberType(dir()))
-
-    def test_isSequenceType(self):
-        self.failUnlessRaises(TypeError, operator.isSequenceType)
-        self.failUnless(operator.isSequenceType(dir()))
-        self.failUnless(operator.isSequenceType(()))
-        self.failUnless(operator.isSequenceType(range(10)))
-        self.failUnless(operator.isSequenceType('yeahbuddy'))
-        self.failIf(operator.isSequenceType(3))
-        class Dict(dict): pass
-        self.failIf(operator.isSequenceType(Dict()))
-
     def test_lshift(self):
         self.failUnlessRaises(TypeError, operator.lshift)
         self.failUnlessRaises(TypeError, operator.lshift, None, 42)
@@ -235,31 +210,6 @@ class OperatorTestCase(unittest.TestCase):
         self.assertRaises(TypeError, operator.pow, 1)
         self.assertRaises(TypeError, operator.pow, 1, 2, 3)
 
-    def test_repeat(self):
-        a = list(range(3))
-        self.failUnlessRaises(TypeError, operator.repeat)
-        self.failUnlessRaises(TypeError, operator.repeat, a, None)
-        self.failUnless(operator.repeat(a, 2) == a+a)
-        self.failUnless(operator.repeat(a, 1) == a)
-        self.failUnless(operator.repeat(a, 0) == [])
-        a = (1, 2, 3)
-        self.failUnless(operator.repeat(a, 2) == a+a)
-        self.failUnless(operator.repeat(a, 1) == a)
-        self.failUnless(operator.repeat(a, 0) == ())
-        a = '123'
-        self.failUnless(operator.repeat(a, 2) == a+a)
-        self.failUnless(operator.repeat(a, 1) == a)
-        self.failUnless(operator.repeat(a, 0) == '')
-        a = Seq1([4, 5, 6])
-        self.failUnless(operator.repeat(a, 2) == [4, 5, 6, 4, 5, 6])
-        self.failUnless(operator.repeat(a, 1) == [4, 5, 6])
-        self.failUnless(operator.repeat(a, 0) == [])
-        a = Seq2([4, 5, 6])
-        self.failUnless(operator.repeat(a, 2) == [4, 5, 6, 4, 5, 6])
-        self.failUnless(operator.repeat(a, 1) == [4, 5, 6])
-        self.failUnless(operator.repeat(a, 0) == [])
-        self.failUnlessRaises(TypeError, operator.repeat, 6, 7)
-
     def test_rshift(self):
         self.failUnlessRaises(TypeError, operator.rshift)
         self.failUnlessRaises(TypeError, operator.rshift, None, 42)
@@ -443,7 +393,6 @@ class OperatorTestCase(unittest.TestCase):
         self.assertEqual(operator.itruediv (c, 5), "itruediv")
         self.assertEqual(operator.ixor     (c, 5), "ixor")
         self.assertEqual(operator.iconcat  (c, c), "iadd")
-        self.assertEqual(operator.irepeat  (c, 5), "imul")
         self.assertEqual(operator.__iadd__     (c, 5), "iadd")
         self.assertEqual(operator.__iand__     (c, 5), "iand")
         self.assertEqual(operator.__ifloordiv__(c, 5), "ifloordiv")
@@ -457,7 +406,6 @@ class OperatorTestCase(unittest.TestCase):
         self.assertEqual(operator.__itruediv__ (c, 5), "itruediv")
         self.assertEqual(operator.__ixor__     (c, 5), "ixor")
         self.assertEqual(operator.__iconcat__  (c, c), "iadd")
-        self.assertEqual(operator.__irepeat__  (c, 5), "imul")
 
 def test_main(verbose=None):
     import sys
index 02630568ea7c7a537ab5e9ebd10623424bf072be..3c6922842cf38625f8623c9f0b0b050682de6f66 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -144,6 +144,10 @@ Core and Builtins
 Library
 -------
 
+- Removed isSequenceType(), isMappingType, and isNumberType() from the
+  operator module; use the abstract base classes instead.  Also removed
+  the repeat() function; use mul() instead.
+
 - Issue #4863: distutils.mwerkscompiler has been removed.
 
 - Fix and properly document the multiprocessing module's logging
index 1398fcabb2cefb166c3232c034d44a9d64abde94..9a1efb26d93650fb0dfa0279ba7c7c5cd1f626d2 100644 (file)
@@ -65,7 +65,6 @@ used for special class methods; variants without leading and trailing\n\
   if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \
   return PyObject_RichCompare(a1,a2,A); }
 
-spami(isNumberType     , PyNumber_Check)
 spami(truth            , PyObject_IsTrue)
 spam2(op_add           , PyNumber_Add)
 spam2(op_sub           , PyNumber_Subtract)
@@ -95,15 +94,11 @@ spam2(op_irshift       , PyNumber_InPlaceRshift)
 spam2(op_iand          , PyNumber_InPlaceAnd)
 spam2(op_ixor          , PyNumber_InPlaceXor)
 spam2(op_ior           , PyNumber_InPlaceOr)
-spami(isSequenceType   , PySequence_Check)
 spam2(op_concat        , PySequence_Concat)
-spamoi(op_repeat       , PySequence_Repeat)
 spam2(op_iconcat       , PySequence_InPlaceConcat)
-spamoi(op_irepeat      , PySequence_InPlaceRepeat)
 spami2b(op_contains     , PySequence_Contains)
 spamn2(indexOf         , PySequence_Index)
 spamn2(countOf         , PySequence_Count)
-spami(isMappingType    , PyMapping_Check)
 spam2(op_getitem       , PyObject_GetItem)
 spam2n(op_delitem       , PyObject_DelItem)
 spam3n(op_setitem      , PyObject_SetItem)
@@ -173,10 +168,6 @@ is_not(PyObject *s, PyObject *a)
 
 static struct PyMethodDef operator_methods[] = {
 
-spam1o(isNumberType,
- "isNumberType(a) -- Return True if a has a numeric type, False otherwise.")
-spam1o(isSequenceType,
- "isSequenceType(a) -- Return True if a has a sequence type, False otherwise.")
 spam1o(truth,
  "truth(a) -- Return True if a is true, False otherwise.")
 spam2(contains,__contains__,
@@ -185,8 +176,6 @@ spam1(indexOf,
  "indexOf(a, b) -- Return the first index of b in a.")
 spam1(countOf,
  "countOf(a, b) -- Return the number of times b occurs in a.")
-spam1o(isMappingType,
- "isMappingType(a) -- Return True if a has a mapping type, False otherwise.")
 
 spam1(is_, "is_(a, b) -- Same as a is b.")
 spam1(is_not, "is_not(a, b) -- Same as a is not b.")
@@ -221,12 +210,8 @@ spam2(ixor,__ixor__, "ixor(a, b) -- Same as a ^= b.")
 spam2(ior,__ior__, "ior(a, b) -- Same as a |= b.")
 spam2(concat,__concat__,
  "concat(a, b) -- Same as a + b, for a and b sequences.")
-spam2(repeat,__repeat__,
- "repeat(a, b) -- Return a * b, where a is a sequence, and b is an integer.")
 spam2(iconcat,__iconcat__,
  "iconcat(a, b) -- Same as a += b, for a and b sequences.")
-spam2(irepeat,__irepeat__,
- "irepeat(a, b) -- Same as a *= b, where a is a sequence, and b is an integer.")
 spam2(getitem,__getitem__,
  "getitem(a, b) -- Same as a[b].")
 spam2(setitem,__setitem__,