mirror of
https://github.com/python/cpython.git
synced 2025-10-10 00:43:41 +00:00
adding in-place operators to the operator module.
This commit is contained in:
parent
ecc275bcef
commit
f5bd3b442d
3 changed files with 190 additions and 1 deletions
|
@ -237,6 +237,108 @@ sequence \var{v}.
|
|||
\end{funcdesc}
|
||||
|
||||
|
||||
Many operations have an ``in-place'' version. The following functions
|
||||
provide a more primitive access to in-place operators than the usual
|
||||
syntax does; for example, the statement \code{x += y} is equivalent to
|
||||
\code{x = operator.iadd(x, y)}. Another way to put it is to say that
|
||||
\code{z = operator.iadd(x, y)} is equivalent to the compound statement
|
||||
\code{z = x; z += y}.
|
||||
|
||||
\begin{funcdesc}{iadd}{a, b}
|
||||
\funcline{__iadd__}{a, b}
|
||||
\code{a = iadd(a, b)} is equivalent to \code{a += b}.
|
||||
\versionadded{2.5}
|
||||
\end{funcdesc}
|
||||
|
||||
\begin{funcdesc}{iand}{a, b}
|
||||
\funcline{__iand__}{a, b}
|
||||
\code{a = iand(a, b)} is equivalent to \code{a \&= b}.
|
||||
\versionadded{2.5}
|
||||
\end{funcdesc}
|
||||
|
||||
\begin{funcdesc}{iconcat}{a, b}
|
||||
\funcline{__iconcat__}{a, b}
|
||||
\code{a = iconcat(a, b)} is equivalent to \code{a += b} for \var{a}
|
||||
and \var{b} sequences.
|
||||
\versionadded{2.5}
|
||||
\end{funcdesc}
|
||||
|
||||
\begin{funcdesc}{idiv}{a, b}
|
||||
\funcline{__idiv__}{a, b}
|
||||
\code{a = idiv(a, b)} is equivalent to \code{a /= b} when
|
||||
\code{__future__.division} is not in effect.
|
||||
\versionadded{2.5}
|
||||
\end{funcdesc}
|
||||
|
||||
\begin{funcdesc}{ifloordiv}{a, b}
|
||||
\funcline{__ifloordiv__}{a, b}
|
||||
\code{a = ifloordiv(a, b)} is equivalent to \code{a //= b}.
|
||||
\versionadded{2.5}
|
||||
\end{funcdesc}
|
||||
|
||||
\begin{funcdesc}{ilshift}{a, b}
|
||||
\funcline{__ilshift__}{a, b}
|
||||
\code{a = ilshift(a, b)} is equivalent to \code{a <}\code{<= b}.
|
||||
\versionadded{2.5}
|
||||
\end{funcdesc}
|
||||
|
||||
\begin{funcdesc}{imod}{a, b}
|
||||
\funcline{__imod__}{a, b}
|
||||
\code{a = imod(a, b)} is equivalent to \code{a \%= b}.
|
||||
\versionadded{2.5}
|
||||
\end{funcdesc}
|
||||
|
||||
\begin{funcdesc}{imul}{a, b}
|
||||
\funcline{__imul__}{a, b}
|
||||
\code{a = imul(a, b)} is equivalent to \code{a *= b}.
|
||||
\versionadded{2.5}
|
||||
\end{funcdesc}
|
||||
|
||||
\begin{funcdesc}{ior}{a, b}
|
||||
\funcline{__ior__}{a, b}
|
||||
\code{a = ior(a, b)} is equivalent to \code{a |= b}.
|
||||
\versionadded{2.5}
|
||||
\end{funcdesc}
|
||||
|
||||
\begin{funcdesc}{ipow}{a, b}
|
||||
\funcline{__ipow__}{a, b}
|
||||
\code{a = ipow(a, b)} is equivalent to \code{a **= b}.
|
||||
\versionadded{2.5}
|
||||
\end{funcdesc}
|
||||
|
||||
\begin{funcdesc}{irepeat}{a, b}
|
||||
\funcline{__irepeat__}{a, b}
|
||||
\code{a = irepeat(a, b)} is equivalent to \code{a *= b} where
|
||||
\var{a} is a sequence and \var{b} is an integer.
|
||||
\versionadded{2.5}
|
||||
\end{funcdesc}
|
||||
|
||||
\begin{funcdesc}{irshift}{a, b}
|
||||
\funcline{__irshift__}{a, b}
|
||||
\code{a = irshift(a, b)} is equivalent to \code{a >}\code{>= b}.
|
||||
\versionadded{2.5}
|
||||
\end{funcdesc}
|
||||
|
||||
\begin{funcdesc}{isub}{a, b}
|
||||
\funcline{__isub__}{a, b}
|
||||
\code{a = isub(a, b)} is equivalent to \code{a -= b}.
|
||||
\versionadded{2.5}
|
||||
\end{funcdesc}
|
||||
|
||||
\begin{funcdesc}{itruediv}{a, b}
|
||||
\funcline{__itruediv__}{a, b}
|
||||
\code{a = itruediv(a, b)} is equivalent to \code{a /= b} when
|
||||
\code{__future__.division} is in effect.
|
||||
\versionadded{2.5}
|
||||
\end{funcdesc}
|
||||
|
||||
\begin{funcdesc}{ixor}{a, b}
|
||||
\funcline{__ixor__}{a, b}
|
||||
\code{a = ixor(a, b)} is equivalent to \code{a \textasciicircum= b}.
|
||||
\versionadded{2.5}
|
||||
\end{funcdesc}
|
||||
|
||||
|
||||
The \module{operator} module also defines a few predicates to test the
|
||||
type of objects. \note{Be careful not to misinterpret the
|
||||
results of these functions; only \function{isCallable()} has any
|
||||
|
|
|
@ -412,6 +412,53 @@ class OperatorTestCase(unittest.TestCase):
|
|||
self.assertEqual(operator.itemgetter(2,10,5)(data), ('2', '10', '5'))
|
||||
self.assertRaises(TypeError, operator.itemgetter(2, 'x', 5), data)
|
||||
|
||||
def test_inplace(self):
|
||||
class C(object):
|
||||
def __iadd__ (self, other): return "iadd"
|
||||
def __iand__ (self, other): return "iand"
|
||||
def __idiv__ (self, other): return "idiv"
|
||||
def __ifloordiv__(self, other): return "ifloordiv"
|
||||
def __ilshift__ (self, other): return "ilshift"
|
||||
def __imod__ (self, other): return "imod"
|
||||
def __imul__ (self, other): return "imul"
|
||||
def __ior__ (self, other): return "ior"
|
||||
def __ipow__ (self, other): return "ipow"
|
||||
def __irshift__ (self, other): return "irshift"
|
||||
def __isub__ (self, other): return "isub"
|
||||
def __itruediv__ (self, other): return "itruediv"
|
||||
def __ixor__ (self, other): return "ixor"
|
||||
def __getitem__(self, other): return 5 # so that C is a sequence
|
||||
c = C()
|
||||
self.assertEqual(operator.iadd (c, 5), "iadd")
|
||||
self.assertEqual(operator.iand (c, 5), "iand")
|
||||
self.assertEqual(operator.idiv (c, 5), "idiv")
|
||||
self.assertEqual(operator.ifloordiv(c, 5), "ifloordiv")
|
||||
self.assertEqual(operator.ilshift (c, 5), "ilshift")
|
||||
self.assertEqual(operator.imod (c, 5), "imod")
|
||||
self.assertEqual(operator.imul (c, 5), "imul")
|
||||
self.assertEqual(operator.ior (c, 5), "ior")
|
||||
self.assertEqual(operator.ipow (c, 5), "ipow")
|
||||
self.assertEqual(operator.irshift (c, 5), "irshift")
|
||||
self.assertEqual(operator.isub (c, 5), "isub")
|
||||
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.__idiv__ (c, 5), "idiv")
|
||||
self.assertEqual(operator.__ifloordiv__(c, 5), "ifloordiv")
|
||||
self.assertEqual(operator.__ilshift__ (c, 5), "ilshift")
|
||||
self.assertEqual(operator.__imod__ (c, 5), "imod")
|
||||
self.assertEqual(operator.__imul__ (c, 5), "imul")
|
||||
self.assertEqual(operator.__ior__ (c, 5), "ior")
|
||||
self.assertEqual(operator.__ipow__ (c, 5), "ipow")
|
||||
self.assertEqual(operator.__irshift__ (c, 5), "irshift")
|
||||
self.assertEqual(operator.__isub__ (c, 5), "isub")
|
||||
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
|
||||
|
|
|
@ -80,9 +80,23 @@ spami(op_not_ , PyObject_Not)
|
|||
spam2(op_and_ , PyNumber_And)
|
||||
spam2(op_xor , PyNumber_Xor)
|
||||
spam2(op_or_ , PyNumber_Or)
|
||||
spam2(op_iadd , PyNumber_InPlaceAdd)
|
||||
spam2(op_isub , PyNumber_InPlaceSubtract)
|
||||
spam2(op_imul , PyNumber_InPlaceMultiply)
|
||||
spam2(op_idiv , PyNumber_InPlaceDivide)
|
||||
spam2(op_ifloordiv , PyNumber_InPlaceFloorDivide)
|
||||
spam2(op_itruediv , PyNumber_InPlaceTrueDivide)
|
||||
spam2(op_imod , PyNumber_InPlaceRemainder)
|
||||
spam2(op_ilshift , PyNumber_InPlaceLshift)
|
||||
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)
|
||||
spami2b(sequenceIncludes, PySequence_Contains)
|
||||
spami2(indexOf , PySequence_Index)
|
||||
|
@ -107,6 +121,15 @@ op_pow(PyObject *s, PyObject *a)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
op_ipow(PyObject *s, PyObject *a)
|
||||
{
|
||||
PyObject *a1, *a2;
|
||||
if (PyArg_UnpackTuple(a,"ipow", 2, 2, &a1, &a2))
|
||||
return PyNumber_InPlacePower(a1, a2, Py_None);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
is_(PyObject *s, PyObject *a)
|
||||
{
|
||||
|
@ -224,10 +247,26 @@ spam2o(not_,__not__, "not_(a) -- Same as not a.")
|
|||
spam2(and_,__and__, "and_(a, b) -- Same as a & b.")
|
||||
spam2(xor,__xor__, "xor(a, b) -- Same as a ^ b.")
|
||||
spam2(or_,__or__, "or_(a, b) -- Same as a | b.")
|
||||
spam2(iadd,__iadd__, "iadd(a, b) -- Same as a += b.")
|
||||
spam2(isub,__isub__, "isub(a, b) -- Same as a -= b.")
|
||||
spam2(imul,__imul__, "imul(a, b) -- Same as a *= b.")
|
||||
spam2(idiv,__idiv__, "idiv(a, b) -- Same as a /= b when __future__.division is not in effect.")
|
||||
spam2(ifloordiv,__ifloordiv__, "ifloordiv(a, b) -- Same as a //= b.")
|
||||
spam2(itruediv,__itruediv__, "itruediv(a, b) -- Same as a /= b when __future__.division is in effect.")
|
||||
spam2(imod,__imod__, "imod(a, b) -- Same as a %= b.")
|
||||
spam2(ilshift,__ilshift__, "ilshift(a, b) -- Same as a <<= b.")
|
||||
spam2(irshift,__irshift__, "irshift(a, b) -- Same as a >>= b.")
|
||||
spam2(iand,__iand__, "iand(a, b) -- Same as a &= b.")
|
||||
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__,
|
||||
|
@ -235,6 +274,7 @@ spam2(setitem,__setitem__,
|
|||
spam2(delitem,__delitem__,
|
||||
"delitem(a, b) -- Same as del a[b].")
|
||||
spam2(pow,__pow__, "pow(a, b) -- Same as a ** b.")
|
||||
spam2(ipow,__ipow__, "ipow(a, b) -- Same as a **= b.")
|
||||
spam2(getslice,__getslice__,
|
||||
"getslice(a, b, c) -- Same as a[b:c].")
|
||||
spam2(setslice,__setslice__,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue