Commit 92cf95f4 authored by Guido van Rossum's avatar Guido van Rossum

Addressed SF bug 421973 (finally).

Rewrote the subsection on coercion rules (and made it a proper
subsection, with a label).  The new section is much less precise,
because precise rules would be too hard to give (== I don't know what
they are any more :-).  OTOH, the new section gives much more
up-to-date information.

Also noted that __coerce__ may return NotImplemented, with the same
meaning as None.

I beg Fred forgiveness: my use of \code{} is probably naive.  Please
fix this and other markup nits.  An index entry would be nice.

This could be a 2.2 bugfix candidate, if we bother about old docs
(Fred?)
parent 40bbae3b
...@@ -1511,74 +1511,116 @@ the common type would be the type of \code{other}, it is sufficient to ...@@ -1511,74 +1511,116 @@ the common type would be the type of \code{other}, it is sufficient to
return \code{None}, since the interpreter will also ask the other return \code{None}, since the interpreter will also ask the other
object to attempt a coercion (but sometimes, if the implementation of object to attempt a coercion (but sometimes, if the implementation of
the other type cannot be changed, it is useful to do the conversion to the other type cannot be changed, it is useful to do the conversion to
the other type here). the other type here). A return value of \code{NotImplemented} is
equivalent to returning \code{None}.
\end{methoddesc} \end{methoddesc}
\strong{Coercion rules}: to evaluate \var{x} \var{op} \var{y}, the \subsection{Coercion rules\label{coercion-rules}}
following steps are taken (where \method{__\var{op}__()} and
\method{__r\var{op}__()} are the method names corresponding to This section used to document the rules for coercion. As the language
\var{op}, e.g., if \var{op} is `\code{+}', \method{__add__()} and has evolved, the coercion rules have become hard to document
\method{__radd__()} are used). If an exception occurs at any point, precisely; documenting what one version of one particular
the evaluation is abandoned and exception handling takes over. implementation does is undesirable. Instead, here are some informal
guidelines regarding coercion. In Python 3.0, coercion will not be
supported.
\begin{itemize} \begin{itemize}
\item[0.] If \var{x} is a string object and \var{op} is the modulo \item
operator (\%), the string formatting operation is invoked and
the remaining steps are skipped. If the left operand of a \% operator is a string or Unicode object, no
coercion takes place and the string formatting operation is invoked
instead.
\item
It is no longer recommended to define a coercion operation.
Mixed-mode operations on types that don't define coercion pass the
original arguments to the operation.
\item
New-style classes (those derived from \code{object}) never invoke the
\code{__coerce__} method in response to a binary operator; the only
time \code{__coerce__} is invoked is when the built-in function
\code{coerce()} is called.
\item
For most intents and purposes, an operator that returns
\code{NotImplemented} is treated the same as one that is not
implemented at all.
\item[1.] If \var{x} is a class instance: \item
\begin{itemize} Below, \method{__op__()} and \method{__rop__()} are used to signify
the generic method names corresponding to an operator;
\method{__iop__} is used for the corresponding in-place operator. For
example, for the operator `\code{+}', \method{__add__()} and
\method{__radd__()} are used for the left and right variant of the
binary operator, and \method{__iadd__} for the in-place variant.
\item[1a.] If \var{x} has a \method{__coerce__()} method: \item
replace \var{x} and \var{y} with the 2-tuple returned by
\code{\var{x}.__coerce__(\var{y})}; skip to step 2 if the
coercion returns \code{None}.
\item[1b.] If neither \var{x} nor \var{y} is a class instance For objects \var{x} and \var{y}, first \code{\var{x}.__op__(\var{y})}
after coercion, go to step 3. is tried. If this is not implemented or returns \code{NotImplemented},
\code{\var{y}.__rop__(\var{x})} is tried. If this is also not
implemented or returns \code{NotImplemented}, a \code{TypeError}
exception is raised. But see the following exception:
\item[1c.] If \var{x} has a method \method{__\var{op}__()}, return \item
\code{\var{x}.__\var{op}__(\var{y})}; otherwise, restore \var{x} and
\var{y} to their value before step 1a.
\end{itemize} Exception to the previous item: if the left operand is an instance of
a built-in type or a new-style class, and the right operand is an
instance of a proper subclass of that type or class, the right
operand's \code{__rop__} method is tried \emph{before} the left
operand's \code{__op__} method. This is done so that a subclass can
completely override binary operators. Otherwise, the left operand's
__op__ method would always accept the right operand: when an instance
of a given class is expected, an instance of a subclass of that class
is always acceptable.
\item[2.] If \var{y} is a class instance: \item
\begin{itemize} When either operand type defines a coercion, this coercion is called
before that type's \code{__op__} or \code{__rop__} method is called,
but no sooner. If the coercion returns an object of a different type
for the operand whose coercion is invoked, part of the process is
redone using the new object.
\item[2a.] If \var{y} has a \method{__coerce__()} method: \item
replace \var{y} and \var{x} with the 2-tuple returned by
\code{\var{y}.__coerce__(\var{x})}; skip to step 3 if the
coercion returns \code{None}.
\item[2b.] If neither \var{x} nor \var{y} is a class instance When an in-place operator (like `\code{+=}') is used, if the left
after coercion, go to step 3. operand implements \code{__iop__}, it is invoked without any coercion.
When the operation falls back to \code{__op__} and/or \code{__rop__},
the normal coercion rules apply.
\item[2b.] If \var{y} has a method \method{__r\var{op}__()}, \item
return \code{\var{y}.__r\var{op}__(\var{x})}; otherwise,
restore \var{x} and \var{y} to their value before step 2a.
\end{itemize} In \var{x}\code{+}\var{y}, if \var{x} is a sequence that implements
sequence concatenation, sequence concatenation is invoked.
\item[3.] We only get here if neither \var{x} nor \var{y} is a class \item
instance.
\begin{itemize} In \var{x}\code{*}\var{y}, if one operator is a sequence that
implements sequence repetition, and the other is an integer
(\code{int} or \code{long}), sequence repetition is invoked.
\item[3a.] If \var{op} is `\code{+}' and \var{x} is a \item
sequence, sequence concatenation is invoked.
\item[3b.] If \var{op} is `\code{*}' and one operand is a Rich comparisons (implemented by methods \code{__eq__} and so on)
sequence and the other an integer, sequence repetition is never use coercion. Three-way comparison (implemented by
invoked. \code{__cmp__}) does use coercion under the same conditions as
other binary operations use it.
\item[3c.] Otherwise, both operands must be numbers; they are \item
coerced to a common type if possible, and the numeric
operation is invoked for that type.
\end{itemize} In the current implementation, the built-in numeric types \code{int},
\code{long} and \code{float} do not use coercion; the type
\code{complex} however does use it. The difference can become
apparent when subclassing these types. Over time, the type
\code{complex} may be fixed to avoid coercion. All these types
implement a \code{__coerce__} method, for use by the built-in
\code{coerce} function.
\end{itemize} \end{itemize}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment