// Copyright (c) Corporation for National Research Initiatives
package org.python.core;

import java.io.Serializable;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.python.expose.ExposedDelete;
import org.python.expose.ExposedGet;
import org.python.expose.ExposedMethod;
import org.python.expose.ExposedNew;
import org.python.expose.ExposedSet;
import org.python.expose.ExposedType;
import org.python.util.Generic;

/**
 * All objects known to the Jython runtime system are represented by an instance
 * of the class <code>PyObject</code> or one of its subclasses.
 */
@ExposedType(name = "object", doc = BuiltinDocs.object_doc)
public class PyObject implements Serializable {

    public static final PyType TYPE = PyType.fromClass(PyObject.class);

    /** The type of this object. */
    protected PyType objtype;

    /**
     * An underlying Java instance that this object is wrapping or is a subclass
     * of. Anything attempting to use the proxy should go through {@link #getJavaProxy()}
     * which ensures that it's initialized.
     */
    protected Object javaProxy;

    /** Primitives classes their wrapper classes. */
    private static final Map<Class<?>, Class<?>> primitiveMap = Generic.map();

    static {
        primitiveMap.put(Character.TYPE, Character.class);
        primitiveMap.put(Boolean.TYPE, Boolean.class);
        primitiveMap.put(Byte.TYPE, Byte.class);
        primitiveMap.put(Short.TYPE, Short.class);
        primitiveMap.put(Integer.TYPE, Integer.class);
        primitiveMap.put(Long.TYPE, Long.class);
        primitiveMap.put(Float.TYPE, Float.class);
        primitiveMap.put(Double.TYPE, Double.class);

        if (Py.BOOTSTRAP_TYPES.size() > 0) {
            Py.writeWarning("init", "Bootstrap types weren't encountered in bootstrapping: "
                            + Py.BOOTSTRAP_TYPES);
        }
    }

    public PyObject(PyType objtype) {
        this.objtype = objtype;
    }

    /**
     * The standard constructor for a <code>PyObject</code>. It will set the <code>objtype</code>
     * field to correspond to the specific subclass of <code>PyObject</code> being instantiated.
     **/
    public PyObject() {
        objtype = PyType.fromClass(getClass(), false);
    }

    /**
     * Creates the PyObject for the base type. The argument only exists to make the constructor
     * distinct.
     */
    PyObject(boolean ignored) {
        objtype = (PyType)this;
    }

    //XXX: in CPython object.__new__ has a doc string...
    @ExposedNew
    @ExposedMethod(doc = BuiltinDocs.object___init___doc)
    final void object___init__(PyObject[] args, String[] keywords) {
        // XXX: attempted fix for object(foo=1), etc
        // XXX: this doesn't work for metaclasses, for some reason
        /*
        if (args.length > 0) {
            throw Py.TypeError("default __new__ takes no parameters");
        }
        */
    }

    @ExposedGet(name = "__class__")
    public PyType getType() {
        return objtype;
    }

    @ExposedSet(name = "__class__")
    public void setType(PyType type) {
        if (type.builtin || getType().builtin) {
            throw Py.TypeError("__class__ assignment: only for heap types");
        }
        type.compatibleForAssignment(getType(), "__class__");
        objtype = type;
    }

    @ExposedDelete(name = "__class__")
    public void delType() {
        throw Py.TypeError("can't delete __class__ attribute");
    }

    // xxx
    public PyObject fastGetClass() {
        return objtype;
    }

    /**
     * Dispatch __init__ behavior
     */
    public void dispatch__init__(PyObject[] args, String[] keywords) {
    }

    /**
     * Attempts to automatically initialize our Java proxy if we have one and it wasn't initialized
     * by our __init__.
     */
    void proxyInit() {
        Class<?> c = getType().getProxyType();
        if (javaProxy != null || c == null) {
            return;
        }
        if (!PyProxy.class.isAssignableFrom(c)) {
            throw Py.SystemError("Automatic proxy initialization should only occur on proxy classes");
        }
        PyProxy proxy;
        ThreadState ts = Py.getThreadState();
        try {
            ts.pushInitializingProxy(this);
            try {
                proxy = (PyProxy)c.newInstance();
            } catch (java.lang.InstantiationException e) {
                Class<?> sup = c.getSuperclass();
                String msg = "Default constructor failed for Java superclass";
                if (sup != null) {
                    msg += " " + sup.getName();
                }
                throw Py.TypeError(msg);
            } catch (NoSuchMethodError nsme) {
                throw Py.TypeError("constructor requires arguments");
            } catch (Exception exc) {
                throw Py.JavaError(exc);
            }
        } finally {
            ts.popInitializingProxy();
        }
        if (javaProxy != null && javaProxy != proxy) {
            throw Py.TypeError("Proxy instance already initialized");
        }
        PyObject proxyInstance = proxy._getPyInstance();
        if (proxyInstance != null && proxyInstance != this) {
            throw Py.TypeError("Proxy initialized with another instance");
        }
        javaProxy = proxy;
    }

    /**
     * Equivalent to the standard Python __repr__ method.  This method
     * should not typically need to be overrriden.  The easiest way to
     * configure the string representation of a <code>PyObject</code> is to
     * override the standard Java <code>toString</code> method.
     **/
    // counter-intuitively exposing this as __str__, otherwise stack overflow
    // occurs during regression testing.  XXX: more detail for this comment
    // is needed.
    @ExposedMethod(names = "__str__", doc = BuiltinDocs.object___str___doc)
    public PyString __repr__() {
        return new PyString(toString());
    }

    @Override
    public String toString() {
        return object_toString();
    }

    @ExposedMethod(names = "__repr__", doc = BuiltinDocs.object___repr___doc)
    final String object_toString() {
        if (getType() == null) {
            return "unknown object";
        }

        String name = getType().getName();
        if (name == null) {
            return "unknown object";
        }

        PyObject module = getType().getModule();
        if (module instanceof PyString && !module.toString().equals("__builtin__")) {
            return String.format("<%s.%s object at %s>", module.toString(), name, Py.idstr(this));
        }
        return String.format("<%s object at %s>", name, Py.idstr(this));
    }

    /**
     * Equivalent to the standard Python __str__ method.  This method
     * should not typically need to be overridden.  The easiest way to
     * configure the string representation of a <code>PyObject</code> is to
     * override the standard Java <code>toString</code> method.
     **/
    public PyString __str__() {
        return __repr__();
    }

    public PyUnicode __unicode__() {
        return new PyUnicode(__str__());
    }

    /**
     * Equivalent to the standard Python __hash__ method.  This method can
     * not be overridden.  Instead, you should override the standard Java
     * <code>hashCode</code> method to return an appropriate hash code for
     * the <code>PyObject</code>.
     **/
    public final PyInteger __hash__() {
        return new PyInteger(hashCode());
    }

    @Override
    public int hashCode() {
        return object___hash__();
    }

    @ExposedMethod(doc = BuiltinDocs.object___hash___doc)
    final int object___hash__() {
        return System.identityHashCode(this);
    }

    /**
     * Should almost never be overridden.
     * If overridden, it is the subclasses responsibility to ensure that
     * <code>a.equals(b) == true</code> iff <code>cmp(a,b) == 0</code>
     **/
    @Override
    public boolean equals(Object ob_other) {
        if(ob_other == this) {
            return true;
        }
        return (ob_other instanceof PyObject) && _eq((PyObject)ob_other).__nonzero__();
    }

    /**
     * Equivalent to the standard Python __nonzero__ method. Returns whether of
     * not a given <code>PyObject</code> is considered true.
     */
    public boolean __nonzero__() {
        return true;
    }

    /**
     * Equivalent to the Jython __tojava__ method.
     * Tries to coerce this object to an instance of the requested Java class.
     * Returns the special object <code>Py.NoConversion</code>
     * if this <code>PyObject</code> can not be converted to the
     * desired Java class.
     *
     * @param c the Class to convert this <code>PyObject</code> to.
     **/
    public Object __tojava__(Class<?> c) {
        if ((c == Object.class || c == Serializable.class) && getJavaProxy() != null) {
            return javaProxy;
        }
        if (c.isInstance(this)) {
            return this;
        }
        if (c.isPrimitive()) {
            Class<?> tmp = primitiveMap.get(c);
            if (tmp != null) {
                c = tmp;
            }
        }
        if (c.isInstance(getJavaProxy())) {
            return javaProxy;
        }

        // convert faux floats
        // XXX: should also convert faux ints, but that breaks test_java_visibility
        // (ReflectedArgs resolution)
        if (c == Double.class || c == Float.class) {
            try {
                return __float__().asDouble();
            } catch (PyException pye) {
                if (!pye.match(Py.AttributeError)) {
                    throw pye;
                }
            }
        }

        return Py.NoConversion;
    }

    protected synchronized Object getJavaProxy() {
        if (javaProxy == null) {
            proxyInit();
        }
        return javaProxy;
    }

    /**
     * The basic method to override when implementing a callable object.
     *
     * The first len(args)-len(keywords) members of args[] are plain
     * arguments.  The last len(keywords) arguments are the values of the
     * keyword arguments.
     *
     * @param args     all arguments to the function (including
     *                 keyword arguments).
     * @param keywords the keywords used for all keyword arguments.
     **/
    public PyObject __call__(PyObject args[], String keywords[]) {
        throw Py.TypeError(String.format("'%s' object is not callable", getType().fastGetName()));
    }

    public PyObject __call__(ThreadState state, PyObject args[], String keywords[]) {
        return __call__(args, keywords);
    }

    /**
     * A variant of the __call__ method with one extra initial argument.
     * This variant is used to allow method invocations to be performed
     * efficiently.
     *
     * The default behavior is to invoke <code>__call__(args,
     * keywords)</code> with the appropriate arguments.  The only reason to
     * override this function would be for improved performance.
     *
     * @param arg1     the first argument to the function.
     * @param args     the last arguments to the function (including
     *                 keyword arguments).
     * @param keywords the keywords used for all keyword arguments.
     **/
    public PyObject __call__(PyObject arg1, PyObject args[], String keywords[]) {
        PyObject[] newArgs = new PyObject[args.length + 1];
        System.arraycopy(args, 0, newArgs, 1, args.length);
        newArgs[0] = arg1;
        return __call__(newArgs, keywords);
    }

    public PyObject __call__(ThreadState state, PyObject arg1, PyObject args[], String keywords[]) {
        return __call__(arg1, args, keywords);
    }

    /**
     * A variant of the __call__ method when no keywords are passed.  The
     * default behavior is to invoke <code>__call__(args, keywords)</code>
     * with the appropriate arguments.  The only reason to override this
     * function would be for improved performance.
     *
     * @param args     all arguments to the function.
     **/
    public PyObject __call__(PyObject args[]) {
        return __call__(args, Py.NoKeywords);
    }

    public PyObject __call__(ThreadState state, PyObject args[]) {
        return __call__(args);
    }

    /**
     * A variant of the __call__ method with no arguments.  The default
     * behavior is to invoke <code>__call__(args, keywords)</code> with the
     * appropriate arguments.  The only reason to override this function
     * would be for improved performance.
     **/
    public PyObject __call__() {
        return __call__(Py.EmptyObjects, Py.NoKeywords);
    }

    public PyObject __call__(ThreadState state) {
        return __call__();
    }

    /**
     * A variant of the __call__ method with one argument.  The default
     * behavior is to invoke <code>__call__(args, keywords)</code> with the
     * appropriate arguments.  The only reason to override this function
     * would be for improved performance.
     *
     * @param arg0     the single argument to the function.
     **/
    public PyObject __call__(PyObject arg0) {
        return __call__(new PyObject[] { arg0 }, Py.NoKeywords);
    }

    public PyObject __call__(ThreadState state, PyObject arg0) {
        return __call__(arg0);
    }

    /**
     * A variant of the __call__ method with two arguments.  The default
     * behavior is to invoke <code>__call__(args, keywords)</code> with the
     * appropriate arguments.  The only reason to override this function
     * would be for improved performance.
     *
     * @param arg0     the first argument to the function.
     * @param arg1     the second argument to the function.
     **/
    public PyObject __call__(PyObject arg0, PyObject arg1) {
        return __call__(new PyObject[] { arg0, arg1 }, Py.NoKeywords);
    }

    public PyObject __call__(ThreadState state, PyObject arg0, PyObject arg1) {
        return __call__(arg0, arg1);
    }

    /**
     * A variant of the __call__ method with three arguments.  The default
     * behavior is to invoke <code>__call__(args, keywords)</code> with the
     * appropriate arguments.  The only reason to override this function
     * would be for improved performance.
     *
     * @param arg0     the first argument to the function.
     * @param arg1     the second argument to the function.
     * @param arg2     the third argument to the function.
     **/
    public PyObject __call__(PyObject arg0, PyObject arg1, PyObject arg2) {
        return __call__(new PyObject[] { arg0, arg1, arg2 }, Py.NoKeywords);
    }

    public PyObject __call__(ThreadState state, PyObject arg0, PyObject arg1, PyObject arg2) {
        return __call__(arg0, arg1, arg2);
    }

    /**
     * A variant of the __call__ method with four arguments.  The default
     * behavior is to invoke <code>__call__(args, keywords)</code> with the
     * appropriate arguments.  The only reason to override this function
     * would be for improved performance.
     *
     * @param arg0     the first argument to the function.
     * @param arg1     the second argument to the function.
     * @param arg2     the third argument to the function.
     * @param arg3     the fourth argument to the function.
     **/
    public PyObject __call__(PyObject arg0, PyObject arg1, PyObject arg2, PyObject arg3) {
        return __call__(
            new PyObject[] { arg0, arg1, arg2, arg3 },
            Py.NoKeywords);
    }

    public PyObject __call__(ThreadState state, PyObject arg0, PyObject arg1, PyObject arg2, PyObject arg3) {
        return __call__(arg0, arg1, arg2, arg3);
    }

    public PyObject _callextra(PyObject[] args,
                               String[] keywords,
                               PyObject starargs,
                               PyObject kwargs) {

        int argslen = args.length;

        String name;
        if (this instanceof PyFunction) {
            name = ((PyFunction) this).__name__ + "() ";
        } else if (this instanceof PyBuiltinCallable) {
            name = ((PyBuiltinCallable)this).fastGetName().toString() + "() ";
        } else {
            name = getType().fastGetName() + " ";
        }
        if (kwargs != null) {
            PyObject keys = kwargs.__findattr__("keys");
            if(keys == null)
                throw Py.TypeError(name
                        + "argument after ** must be a mapping");
            for (String keyword : keywords)
                if (kwargs.__finditem__(keyword) != null)
                    throw Py.TypeError(
                        name
                            + "got multiple values for "
                            + "keyword argument '"
                            + keyword
                            + "'");
            argslen += kwargs.__len__();
        }
        List<PyObject> starObjs = null;
        if (starargs != null) {
            starObjs = new ArrayList<PyObject>();
            PyObject iter = Py.iter(starargs, name + "argument after * must be a sequence");
            for (PyObject cur = null; ((cur = iter.__iternext__()) != null); ) {
                starObjs.add(cur);
            }
            argslen += starObjs.size();
        }
        PyObject[] newargs = new PyObject[argslen];
        int argidx = args.length - keywords.length;
        System.arraycopy(args, 0, newargs, 0, argidx);
        if(starObjs != null) {
            Iterator<PyObject> it = starObjs.iterator();
            while(it.hasNext()) {
                newargs[argidx++] = it.next();
            }
        }
        System.arraycopy(args,
                         args.length - keywords.length,
                         newargs,
                         argidx,
                         keywords.length);
        argidx += keywords.length;

        if (kwargs != null) {
            String[] newkeywords =
                new String[keywords.length + kwargs.__len__()];
            System.arraycopy(keywords, 0, newkeywords, 0, keywords.length);

            PyObject keys = kwargs.invoke("keys");
            PyObject key;
            for (int i = 0;(key = keys.__finditem__(i)) != null; i++) {
                if (!(key instanceof PyString))
                    throw Py.TypeError(name + "keywords must be strings");
                newkeywords[keywords.length + i] =
                    ((PyString) key).internedString();
                newargs[argidx++] = kwargs.__finditem__(key);
            }
            keywords = newkeywords;
        }

        if (newargs.length != argidx) {
            args = new PyObject[argidx];
            System.arraycopy(newargs, 0, args, 0, argidx);
        } else
            args = newargs;
        return __call__(args, keywords);
    }

    public boolean isCallable() {
        return getType().lookup("__call__") != null;
    }

    public boolean isNumberType() {
        PyType type = getType();
        return type.lookup("__int__") != null || type.lookup("__float__") != null;
    }

    public boolean isMappingType() {
        PyType type = getType();
        return type.lookup("__getitem__") != null
                && !(isSequenceType() && type.lookup("__getslice__") != null);
    }

    public boolean isSequenceType() {
        return getType().lookup("__getitem__") != null;
    }

    /**
     * Determine if this object can act as an index (implements __index__).
     *
     * @return true if the object can act as an index
     */
    public boolean isIndex() {
        return getType().lookup("__index__") != null;
    }

    /* The basic functions to implement a mapping */

    /**
     * Equivalent to the standard Python __len__ method.
     * Part of the mapping discipline.
     *
     * @return the length of the object
     **/
    public int __len__() {
        throw Py.TypeError(String.format("object of type '%.200s' has no len()",
                                         getType().fastGetName()));
    }

    /**
     * Very similar to the standard Python __getitem__ method.
     * Instead of throwing a KeyError if the item isn't found,
     * this just returns null.
     *
     * Classes that wish to implement __getitem__ should
     * override this method instead (with the appropriate
     * semantics.
     *
     * @param key the key to lookup in this container
     *
     * @return the value corresponding to key or null if key is not found
     **/
    public PyObject __finditem__(PyObject key) {
        throw Py.TypeError(String.format("'%.200s' object is unsubscriptable",
                                         getType().fastGetName()));
    }

    /**
     * A variant of the __finditem__ method which accepts a primitive
     * <code>int</code> as the key.  By default, this method will call
     * <code>__finditem__(PyObject key)</code> with the appropriate args.
     * The only reason to override this method is for performance.
     *
     * @param key the key to lookup in this sequence.
     * @return the value corresponding to key or null if key is not found.
     *
     * @see #__finditem__(PyObject)
     **/
    public PyObject __finditem__(int key) {
        return __finditem__(new PyInteger(key));
    }

    /**
     * A variant of the __finditem__ method which accepts a Java
     * <code>String</code> as the key.  By default, this method will call
     * <code>__finditem__(PyObject key)</code> with the appropriate args.
     * The only reason to override this method is for performance.
     *
     * <b>Warning: key must be an interned string!!!!!!!!</b>
     *
     * @param key the key to lookup in this sequence -
     *            <b> must be an interned string </b>.
     * @return the value corresponding to key or null if key is not found.
     *
     * @see #__finditem__(PyObject)
     **/
    public PyObject __finditem__(String key) {
        return __finditem__(new PyString(key));
    }

    /**
     * Equivalent to the standard Python __getitem__ method.
     * This variant takes a primitive <code>int</code> as the key.
     * This method should not be overridden.
     * Override the <code>__finditem__</code> method instead.
     *
     * @param key the key to lookup in this container.
     * @return the value corresponding to that key.
     * @exception Py.KeyError if the key is not found.
     *
     * @see #__finditem__(int)
     **/
    public PyObject __getitem__(int key) {
        PyObject ret = __finditem__(key);
        if (ret == null)
            throw Py.KeyError("" + key);
        return ret;
    }

    /**
     * Equivalent to the standard Python __getitem__ method.
     * This method should not be overridden.
     * Override the <code>__finditem__</code> method instead.
     *
     * @param key the key to lookup in this container.
     * @return the value corresponding to that key.
     * @exception Py.KeyError if the key is not found.
     *
     * @see #__finditem__(PyObject)
     **/
    public PyObject __getitem__(PyObject key) {
        PyObject ret = __finditem__(key);
        if (ret == null) {
            throw Py.KeyError(key);
        }
        return ret;
    }

    /**
     * Equivalent to the standard Python __setitem__ method.
     *
     * @param key the key whose value will be set
     * @param value the value to set this key to
     **/
    public void __setitem__(PyObject key, PyObject value) {
        throw Py.TypeError(String.format("'%.200s' object does not support item assignment",
                                         getType().fastGetName()));
    }

    /**
     * A variant of the __setitem__ method which accepts a String
     * as the key.  <b>This String must be interned</b>.
     * By default, this will call
     * <code>__setitem__(PyObject key, PyObject value)</code>
     * with the appropriate args.
     * The only reason to override this method is for performance.
     *
     * @param key the key whose value will be set -
     *            <b> must be an interned string </b>.
     * @param value the value to set this key to
     *
     * @see #__setitem__(PyObject, PyObject)
     **/
    public void __setitem__(String key, PyObject value) {
        __setitem__(new PyString(key), value);
    }

    /**
     * A variant of the __setitem__ method which accepts a primitive
     * <code>int</code> as the key.
     * By default, this will call
     * <code>__setitem__(PyObject key, PyObject value)</code>
     * with the appropriate args.
     * The only reason to override this method is for performance.
     *
     * @param key the key whose value will be set
     * @param value the value to set this key to
     *
     * @see #__setitem__(PyObject, PyObject)
     **/
    public void __setitem__(int key, PyObject value) {
        __setitem__(new PyInteger(key), value);
    }

    /**
     * Equivalent to the standard Python __delitem__ method.
     *
     * @param key the key to be removed from the container
     * @exception Py.KeyError if the key is not found in the container
     **/
    public void __delitem__(PyObject key) {
        throw Py.TypeError(String.format("'%.200s' object doesn't support item deletion",
                                         getType().fastGetName()));
    }

    /**
     * A variant of the __delitem__ method which accepts a String
     * as the key.  <b>This String must be interned</b>.
     * By default, this will call
     * <code>__delitem__(PyObject key)</code>
     * with the appropriate args.
     * The only reason to override this method is for performance.
     *
     * @param key the key who will be removed -
     *            <b> must be an interned string </b>.
     * @exception Py.KeyError if the key is not found in the container
     *
     * @see #__delitem__(PyObject)
     **/
    public void __delitem__(String key) {
        __delitem__(new PyString(key));
    }

    public PyObject __getslice__(
        PyObject s_start,
        PyObject s_stop,
        PyObject s_step) {
        PySlice s = new PySlice(s_start, s_stop, s_step);
        return __getitem__(s);
    }

    public void __setslice__(
        PyObject s_start,
        PyObject s_stop,
        PyObject s_step,
        PyObject value) {
        PySlice s = new PySlice(s_start, s_stop, s_step);
        __setitem__(s, value);
    }

    public void __delslice__(
        PyObject s_start,
        PyObject s_stop,
        PyObject s_step) {
        PySlice s = new PySlice(s_start, s_stop, s_step);
        __delitem__(s);
    }

    public PyObject __getslice__(PyObject start, PyObject stop) {
        return __getslice__(start, stop, null);
    }

    public void __setslice__(PyObject start, PyObject stop, PyObject value) {
        __setslice__(start, stop, null, value);
    }

    public void __delslice__(PyObject start, PyObject stop) {
        __delslice__(start, stop, null);
    }

    /*The basic functions to implement an iterator */

    /**
     * Return an iterator that is used to iterate the element of this sequence. From version 2.2,
     * this method is the primary protocol for looping over sequences.
     * <p>
     * If a PyObject subclass should support iteration based in the __finditem__() method, it must
     * supply an implementation of __iter__() like this:
     *
     * <pre>
     * public PyObject __iter__() {
     *     return new PySequenceIter(this);
     * }
     * </pre>
     *
     * When iterating over a python sequence from java code, it should be done with code like this:
     *
     * <pre>
     * for (PyObject item : seq.asIterable()) {
     *     // Do somting with item
     * }
     * </pre>
     *
     * @since 2.2
     */
    public PyObject __iter__() {
        throw Py.TypeError(String.format("'%.200s' object is not iterable",
                                         getType().fastGetName()));
    }

    /**
     * Returns an Iterable over the Python iterator returned by __iter__ on this object. If this
     * object doesn't support __iter__, a TypeException will be raised when iterator is called on
     * the returned Iterable.
     */
    public Iterable<PyObject> asIterable() {
        return new Iterable<PyObject>() {
            public Iterator<PyObject> iterator() {
                return new WrappedIterIterator<PyObject>(__iter__()) {
                    public PyObject next() {
                        return getNext();
                    }
                };
            }
        };
    }

    /**
     * Return the next element of the sequence that this is an iterator
     * for. Returns null when the end of the sequence is reached.
     *
     * @since 2.2
     */
    public PyObject __iternext__() {
        return null;
    }

    /*The basic functions to implement a namespace*/

    /**
     * Very similar to the standard Python __getattr__ method. Instead of
     * throwing a AttributeError if the item isn't found, this just returns
     * null.
     *
     * By default, this method will call
     * <code>__findattr__(name.internedString)</code> with the appropriate
     * args.
     *
     * @param name the name to lookup in this namespace
     *
     * @return the value corresponding to name or null if name is not found
     */
    public final PyObject __findattr__(PyString name) {
        if (name == null) {
            return null;
        }
        return __findattr__(name.internedString());
    }

    /**
     * A variant of the __findattr__ method which accepts a Java
     * <code>String</code> as the name.
     *
     * <b>Warning: name must be an interned string!</b>
     *
     * @param name the name to lookup in this namespace
     * <b> must be an interned string </b>.
     * @return the value corresponding to name or null if name is not found
     **/
    public final PyObject __findattr__(String name) {
        try {
            return  __findattr_ex__(name);
        } catch (PyException exc) {
            if (exc.match(Py.AttributeError)) {
                return null;
            }
            throw exc;
        }
    }

    /**
     * Attribute lookup hook. If the attribute is not found, null may be
     * returned or a Py.AttributeError can be thrown, whatever is more
     * correct, efficient and/or convenient for the implementing class.
     *
     * Client code should use {@link #__getattr__(String)} or
     * {@link #__findattr__(String)}. Both methods have a clear policy for
     * failed lookups.
     *
     * @return The looked up value. May return null if the attribute is not found
     * @throws PyException(AttributeError) if the attribute is not found. This
     * is not mandatory, null can be returned if it fits the implementation
     * better, or for performance reasons.
     */
    public PyObject __findattr_ex__(String name) {
        return object___findattr__(name);
    }

    /**
     * Equivalent to the standard Python __getattr__ method.
     *
     * By default, this method will call
     * <code>__getattr__(name.internedString)</code> with the appropriate
     * args.
     *
     * @param name the name to lookup in this namespace
     * @return the value corresponding to name
     * @exception Py.AttributeError if the name is not found.
     *
     * @see #__findattr_ex__(String)
     **/
    public final PyObject __getattr__(PyString name) {
        return __getattr__(name.internedString());
    }

    /**
     * A variant of the __getattr__ method which accepts a Java
     * <code>String</code> as the name.
     * This method can not be overridden.
     * Override the <code>__findattr_ex__</code> method instead.
     *
     * <b>Warning: name must be an interned string!!!!!!!!</b>
     *
     * @param name the name to lookup in this namespace
     *             <b> must be an interned string </b>.
     * @return the value corresponding to name
     * @exception Py.AttributeError if the name is not found.
     *
     * @see #__findattr__(java.lang.String)
     **/
    public final PyObject __getattr__(String name) {
        PyObject ret = __findattr_ex__(name);
        if (ret == null)
            noAttributeError(name);
        return ret;
    }

    public void noAttributeError(String name) {
        throw Py.AttributeError(String.format("'%.50s' object has no attribute '%.400s'",
                                              getType().fastGetName(), name));
    }

    public void readonlyAttributeError(String name) {
        // XXX: Should be an AttributeError but CPython throws TypeError for read only
        // member descriptors (in structmember.c::PyMember_SetOne), which is expected by a
        // few tests. fixed in py3k: http://bugs.python.org/issue1687163
        throw Py.TypeError("readonly attribute");
    }

    /**
     * Equivalent to the standard Python __setattr__ method.
     * This method can not be overridden.
     *
     * @param name the name to lookup in this namespace
     * @exception Py.AttributeError if the name is not found.
     *
     * @see #__setattr__(java.lang.String, PyObject)
     **/
    public final void __setattr__(PyString name, PyObject value) {
        __setattr__(name.internedString(), value);
    }

    /**
     * A variant of the __setattr__ method which accepts a String
     * as the key.  <b>This String must be interned</b>.
     *
     * @param name  the name whose value will be set -
     *              <b> must be an interned string </b>.
     * @param value the value to set this name to
     *
     * @see #__setattr__(PyString, PyObject)
    **/
    public void __setattr__(String name, PyObject value) {
        object___setattr__(name, value);
    }

    /**
     * Equivalent to the standard Python __delattr__ method.
     * This method can not be overridden.
     *
     * @param name the name to which will be removed
     * @exception Py.AttributeError if the name doesn't exist
     *
     * @see #__delattr__(java.lang.String)
     **/
    public final void __delattr__(PyString name) {
        __delattr__(name.internedString());
    }

    /**
     * A variant of the __delattr__ method which accepts a String
     * as the key.  <b>This String must be interned</b>.
     * By default, this will call
     * <code>__delattr__(PyString name)</code>
     * with the appropriate args.
     * The only reason to override this method is for performance.
     *
     * @param name the name which will be removed -
     *             <b> must be an interned string </b>.
     * @exception Py.AttributeError if the name doesn't exist
     *
     * @see #__delattr__(PyString)
     **/
    public void __delattr__(String name) {
        object___delattr__(name);
    }

    // Used by import logic.
    protected PyObject impAttr(String name) {
        return __findattr__(name);
    }

    protected void mergeListAttr(PyDictionary accum, String attr) {
        PyObject obj = __findattr__(attr);
        if (obj == null) {
            return;
        }
        if (obj instanceof PyList) {
            for (PyObject name : obj.asIterable()) {
                accum.__setitem__(name, Py.None);
            }
        }
    }

    protected void mergeDictAttr(PyDictionary accum, String attr) {
        PyObject obj = __findattr__(attr);
        if (obj == null) {
            return;
        }
        if (obj instanceof PyDictionary || obj instanceof PyStringMap
            || obj instanceof PyDictProxy) {
            accum.update(obj);
        }
    }

    protected void mergeClassDict(PyDictionary accum, PyObject aClass) {
        // Merge in the type's dict (if any)
        aClass.mergeDictAttr(accum, "__dict__");

        // Recursively merge in the base types' (if any) dicts
        PyObject bases = aClass.__findattr__("__bases__");
        if (bases == null) {
            return;
        }
        // We have no guarantee that bases is a real tuple
        int len = bases.__len__();
        for (int i = 0; i < len; i++) {
            mergeClassDict(accum, bases.__getitem__(i));
        }
    }

    protected void __rawdir__(PyDictionary accum) {
        mergeDictAttr(accum, "__dict__");
        mergeListAttr(accum, "__methods__");
        mergeListAttr(accum, "__members__");
        // Class dict is a slower, more manual merge to match CPython
        PyObject itsClass = __findattr__("__class__");
        if (itsClass != null) {
            mergeClassDict(accum, itsClass);
        }
    }

    /**
     * Equivalent to the standard Python __dir__ method.
     *
     * @return a list of names defined by this object.
     **/
    public PyObject __dir__() {
        PyDictionary accum = new PyDictionary();
        __rawdir__(accum);
        PyList ret = accum.keys();
        ret.sort();
        return ret;
    }

    public PyObject _doget(PyObject container) {
        return this;
    }

    public PyObject _doget(PyObject container, PyObject wherefound) {
        return _doget(container);
    }

    public boolean _doset(PyObject container, PyObject value) {
        return false;
    }

    boolean jdontdel() {
        return false;
    }

    /* Numeric coercion */

    /**
     * Implements numeric coercion
     *
     * @param o the other object involved in the coercion
     * @return null if coercion is not implemented
     *         Py.None if coercion was not possible
     *         a single PyObject to use to replace o if this is unchanged;
     *         or a PyObject[2] consisting of replacements for this and o.
     **/
    public Object __coerce_ex__(PyObject o) {
        return null;
    }

    /**
     * Implements coerce(this,other), result as PyObject[]
     * @param other
     * @return PyObject[]
     */
    PyObject[] _coerce(PyObject other) {
        Object result;
        if (this.getType() == other.getType() &&
            !(this instanceof PyInstance)) {
            return new PyObject[] {this, other};
        }
        result = this.__coerce_ex__(other);
        if (result != null && result != Py.None) {
            if (result instanceof PyObject[]) {
                return (PyObject[])result;
            } else {
                return new PyObject[] {this, (PyObject)result};
            }
        }
        result = other.__coerce_ex__(this);
        if (result != null && result != Py.None) {
            if (result instanceof PyObject[]) {
                return (PyObject[])result;
            } else {
                return new PyObject[] {(PyObject)result, other};
            }
        }
        return null;

    }

    /**
     * Equivalent to the standard Python __coerce__ method.
     *
     * This method can not be overridden.
     * To implement __coerce__ functionality, override __coerce_ex__ instead.
     *
     * Also, <b>do not</b> call this method from exposed 'coerce' methods.
     * Instead, Use adaptToCoerceTuple over the result of the overriden
     * __coerce_ex__.
     *
     * @param pyo the other object involved in the coercion.
     * @return a tuple of this object and pyo coerced to the same type
     *         or Py.NotImplemented if no coercion is possible.
     * @see org.python.core.PyObject#__coerce_ex__(org.python.core.PyObject)
     **/
    public final PyObject __coerce__(PyObject pyo) {
        Object o = __coerce_ex__(pyo);
        if (o == null) {
            throw Py.AttributeError("__coerce__");
        }
        return adaptToCoerceTuple(o);
    }

    /**
     * Adapts the result of __coerce_ex__ to a tuple of two elements, with the
     * resulting coerced values, or to Py.NotImplemented, if o is Py.None.
     *
     * This is safe to be used from subclasses exposing '__coerce__'
     * (as opposed to {@link #__coerce__(PyObject)}, which calls the virtual
     * method {@link #__coerce_ex__(PyObject)})
     *
     * @param o either a PyObject[2] or a PyObject, as given by
     *        {@link #__coerce_ex__(PyObject)}.
     */
    protected final PyObject adaptToCoerceTuple(Object o) {
        if (o == Py.None) {
            return Py.NotImplemented;
        }
        if (o instanceof PyObject[]) {
            return new PyTuple((PyObject[]) o);
        } else {
            return new PyTuple(this, (PyObject) o );
        }
    }

    /* The basic comparision operations */

    /**
     * Equivalent to the standard Python __cmp__ method.
     *
     * @param other the object to compare this with.
     * @return -1 if this < o; 0 if this == o; +1 if this > o; -2 if no
     * comparison is implemented
     **/
    public int __cmp__(PyObject other) {
        return -2;
    }

    /**
     * Equivalent to the standard Python __eq__ method.
     *
     * @param other the object to compare this with.
     * @return the result of the comparison.
     **/
    public PyObject __eq__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __ne__ method.
     *
     * @param other the object to compare this with.
     * @return the result of the comparison.
     **/
    public PyObject __ne__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __le__ method.
     *
     * @param other the object to compare this with.
     * @return the result of the comparison.
     **/
    public PyObject __le__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __lt__ method.
     *
     * @param other the object to compare this with.
     * @return the result of the comparison.
     **/
    public PyObject __lt__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __ge__ method.
     *
     * @param other the object to compare this with.
     * @return the result of the comparison.
     **/
    public PyObject __ge__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __gt__ method.
     *
     * @param other the object to compare this with.
     * @return the result of the comparison.
     **/
    public PyObject __gt__(PyObject other) {
        return null;
    }

    /**
     * Implements cmp(this, other)
     *
     * @param o the object to compare this with.
     * @return -1 if this < 0; 0 if this == o; +1 if this > o
     **/
    public final int _cmp(PyObject o) {
        if (this == o) {
            return 0;
        }

        PyObject token = null;
        ThreadState ts = Py.getThreadState();
        try {
            if (++ts.compareStateNesting > 500) {
                if ((token = check_recursion(ts, this, o)) == null)
                    return 0;
            }

            PyObject result;
            result = __eq__(o);
            if (result == null) {
                result = o.__eq__(this);
            }
            if (result != null && result.__nonzero__()) {
                return 0;
            }

            result = __lt__(o);
            if (result == null) {
                result = o.__gt__(this);
            }
            if (result != null && result.__nonzero__()) {
                return -1;
            }

            result = __gt__(o);
            if (result == null) {
                result = o.__lt__(this);
            }
            if (result != null && result.__nonzero__()) {
                return 1;
            }

            return _cmp_unsafe(o);
        } finally {
            delete_token(ts, token);
            ts.compareStateNesting--;
        }
    }

    private PyObject make_pair(PyObject o) {
        if (System.identityHashCode(this) < System.identityHashCode(o))
            return new PyIdentityTuple(new PyObject[] { this, o });
        else
            return new PyIdentityTuple(new PyObject[] { o, this });
    }

    private final int _default_cmp(PyObject other) {
        int result;
        if (_is(other).__nonzero__())
            return 0;

        /* None is smaller than anything */
        if (this == Py.None) {
            return -1;
        }
        if (other == Py.None) {
            return 1;
        }

        // No rational way to compare these, so ask their classes to compare
        PyType type = getType();
        PyType otherType = other.getType();
        if (type == otherType) {
            return Py.id(this) < Py.id(other) ? -1 : 1;
        }

        // different type: compare type names; numbers are smaller
        String typeName = isNumberType() ? "" : type.fastGetName();
        String otherTypeName = other.isNumberType() ? "" : otherType.fastGetName();
        result = typeName.compareTo(otherTypeName);
        if (result == 0) {
            // Same type name, or (more likely) incomparable numeric types
            return Py.id(type) < Py.id(otherType) ? -1 : 1;
        }
        return result < 0 ? -1 : 1;
    }

    private final int _cmp_unsafe(PyObject other) {
        // Shortcut for equal objects
        if (this == other)
            return 0;

        int result = _try__cmp__(other);
        if (result != -2) {
            return result;
        }
        return this._default_cmp(other);
    }

    /*
     *  Like _cmp_unsafe but limited to ==/!= as 0/!=0,
     *  thus it avoids to invoke _default_cmp.
     */
    private final int _cmpeq_unsafe(PyObject other) {
        // Shortcut for equal objects
        if (this == other)
            return 0;

        int result = _try__cmp__(other);
        if (result != -2) {
            return result;
        }

        return this._is(other).__nonzero__()?0:1;
    }

    /**
     * Tries a 3-way comparison, using __cmp__. It tries the following
     * operations until one of them succeed:<ul>
     *  <li>this.__cmp__(other)
     *  <li>other.__cmp__(this)
     *  <li>this._coerce(other) followed by coerced_this.__cmp__(coerced_other)</ul>
     *
     * @return -1, 0, -1 or -2, according to the {@link #__cmp__} protocol.
     */
    private int _try__cmp__(PyObject other) {
        int result;
        result = this.__cmp__(other);
        if (result != -2)
            return result;

        if (!(this instanceof PyInstance)) {
            result = other.__cmp__(this);
            if (result != -2)
                return -result;
        }
        // Final attempt: coerce both arguments and compare that. We are doing
        // this the same point where CPython 2.5 does. (See
        // <http://svn.python.org/projects/python/tags/r252/Objects/object.c> at
        // the end of try_3way_compare).
        //
        // This is not exactly was is specified on
        // <http://docs.python.org/ref/coercion-rules.html>, where coercion is
        // supposed to happen before trying __cmp__.

        PyObject[] coerced = _coerce(other);
        if (coerced != null) {
            result = coerced[0].__cmp__(coerced[1]);
            if (result != -2) {
                return result;
            }
        }
        return -2;
    }



    private final static PyObject check_recursion(
        ThreadState ts,
        PyObject o1,
        PyObject o2) {
        PyDictionary stateDict = ts.getCompareStateDict();

        PyObject pair = o1.make_pair(o2);

        if (stateDict.__finditem__(pair) != null)
            return null;

        stateDict.__setitem__(pair, pair);
        return pair;
    }

    private final static void delete_token(ThreadState ts, PyObject token) {
        if (token == null)
            return;
        PyDictionary stateDict = ts.getCompareStateDict();

        stateDict.__delitem__(token);
    }

    /**
     * Implements the Python expression <code>this == other</code>.
     *
     * @param o the object to compare this with.
     * @return the result of the comparison
     **/
    public final PyObject _eq(PyObject o) {
        PyObject token = null;
        PyType t1 = this.getType();
        PyType t2 = o.getType();

        if (t1 != t2 && t2.isSubType(t1)) {
            return o._eq(this);
        }

        ThreadState ts = Py.getThreadState();
        try {
            if (++ts.compareStateNesting > 10) {
                if ((token = check_recursion(ts, this, o)) == null)
                    return Py.True;
            }
            PyObject res = __eq__(o);
            if (res != null)
                return res;
            res = o.__eq__(this);
            if (res != null)
                return res;
            return _cmpeq_unsafe(o) == 0 ? Py.True : Py.False;
        } finally {
            delete_token(ts, token);
            ts.compareStateNesting--;
        }
    }

    /**
     * Implements the Python expression <code>this != other</code>.
     *
     * @param o the object to compare this with.
     * @return the result of the comparison
     **/
    public final PyObject _ne(PyObject o) {
        PyObject token = null;
        PyType t1 = this.getType();
        PyType t2 = o.getType();

        if (t1 != t2 && t2.isSubType(t1)) {
            return o._ne(this);
        }

        ThreadState ts = Py.getThreadState();
        try {
            if (++ts.compareStateNesting > 10) {
                if ((token = check_recursion(ts, this, o)) == null)
                    return Py.False;
            }
            PyObject res = __ne__(o);
            if (res != null)
                return res;
            res = o.__ne__(this);
            if (res != null)
                return res;
            return _cmpeq_unsafe(o) != 0 ? Py.True : Py.False;
        } finally {
            delete_token(ts, token);
            ts.compareStateNesting--;
        }
    }

    /**
     * Implements the Python expression <code>this &lt;= other</code>.
     *
     * @param o the object to compare this with.
     * @return the result of the comparison
     **/
    public final PyObject _le(PyObject o) {
        PyObject token = null;
        PyType t1 = this.getType();
        PyType t2 = o.getType();

        if (t1 != t2 && t2.isSubType(t1)) {
            return o._ge(this);
        }

        ThreadState ts = Py.getThreadState();
        try {
            if (++ts.compareStateNesting > 10) {
                if ((token = check_recursion(ts, this, o)) == null)
                    throw Py.ValueError("can't order recursive values");
            }
            PyObject res = __le__(o);
            if (res != null)
                return res;
            res = o.__ge__(this);
            if (res != null)
                return res;
            return _cmp_unsafe(o) <= 0 ? Py.True : Py.False;
        } finally {
            delete_token(ts, token);
            ts.compareStateNesting--;
        }
    }

    /**
     * Implements the Python expression <code>this &lt; other</code>.
     *
     * @param o the object to compare this with.
     * @return the result of the comparison
     **/
    public final PyObject _lt(PyObject o) {
        PyObject token = null;
        PyType t1 = this.getType();
        PyType t2 = o.getType();

        if (t1 != t2 && t2.isSubType(t1)) {
            return o._gt(this);
        }

        ThreadState ts = Py.getThreadState();
        try {
            if (++ts.compareStateNesting > 10) {
                if ((token = check_recursion(ts, this, o)) == null)
                    throw Py.ValueError("can't order recursive values");
            }
            PyObject res = __lt__(o);
            if (res != null)
                return res;
            res = o.__gt__(this);
            if (res != null)
                return res;
            return _cmp_unsafe(o) < 0 ? Py.True : Py.False;
        } finally {
            delete_token(ts, token);
            ts.compareStateNesting--;
        }
    }

    /**
     * Implements the Python expression <code>this &gt;= other</code>.
     *
     * @param o the object to compare this with.
     * @return the result of the comparison
     **/
    public final PyObject _ge(PyObject o) {
        PyObject token = null;
        PyType t1 = this.getType();
        PyType t2 = o.getType();

        if (t1 != t2 && t2.isSubType(t1)) {
            return o._le(this);
        }

        ThreadState ts = Py.getThreadState();
        try {
            if (++ts.compareStateNesting > 10) {
                if ((token = check_recursion(ts, this, o)) == null)
                    throw Py.ValueError("can't order recursive values");
            }
            PyObject res = __ge__(o);
            if (res != null)
                return res;
            res = o.__le__(this);
            if (res != null)
                return res;
            return _cmp_unsafe(o) >= 0 ? Py.True : Py.False;
        } finally {
            delete_token(ts, token);
            ts.compareStateNesting--;
        }
    }

    /**
     * Implements the Python expression <code>this &gt; other</code>.
     *
     * @param o the object to compare this with.
     * @return the result of the comparison
     **/
    public final PyObject _gt(PyObject o) {
        PyObject token = null;
        PyType t1 = this.getType();
        PyType t2 = o.getType();

        if (t1 != t2 && t2.isSubType(t1)) {
            return o._lt(this);
        }

        ThreadState ts = Py.getThreadState();
        try {
            if (++ts.compareStateNesting > 10) {
                if ((token = check_recursion(ts, this, o)) == null)
                    throw Py.ValueError("can't order recursive values");
            }
            PyObject res = __gt__(o);
            if (res != null)
                return res;
            res = o.__lt__(this);
            if (res != null)
                return res;
            return _cmp_unsafe(o) > 0 ? Py.True : Py.False;
        } finally {
            delete_token(ts, token);
            ts.compareStateNesting--;
        }

    }

    /**
     * Implements <code>is</code> operator.
     *
     * @param o the object to compare this with.
     * @return the result of the comparison
     **/
    public PyObject _is(PyObject o) {
        // Access javaProxy directly here as is is for object identity, and at best getJavaProxy
        // will initialize a new object with a different identity
        return this == o || (javaProxy != null && javaProxy == o.javaProxy) ? Py.True : Py.False;
    }

    /**
     * Implements <code>is not</code> operator.
     *
     * @param o the object to compare this with.
     * @return the result of the comparison
     **/
    public PyObject _isnot(PyObject o) {
        // Access javaProxy directly here as is is for object identity, and at best getJavaProxy
        // will initialize a new object with a different identity
        return this != o && (javaProxy == null || javaProxy != o.javaProxy) ? Py.True : Py.False;
    }

    /**
     * Implements <code>in</code> operator.
     *
     * @param o the container to search for this element.
     * @return the result of the search.
     **/
    public final PyObject _in(PyObject o) {
        return Py.newBoolean(o.__contains__(this));
    }

    /**
     * Implements <code>not in</code> operator.
     *
     * @param o the container to search for this element.
     * @return the result of the search.
     **/
    public final PyObject _notin(PyObject o) {
        return Py.newBoolean(!o.__contains__(this));
    }

    /**
     * Equivalent to the standard Python __contains__ method.
     *
     * @param o the element to search for in this container.
     * @return the result of the search.
     **/
    public boolean __contains__(PyObject o) {
        return object___contains__(o);
    }

    final boolean object___contains__(PyObject o) {
        for (PyObject item : asIterable()) {
            if (o.equals(item)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Implements boolean not
     *
     * @return not this.
     **/
    public PyObject __not__() {
        return __nonzero__() ? Py.False : Py.True;
    }

    /* The basic numeric operations */

    /**
     * Equivalent to the standard Python __hex__ method
     * Should only be overridden by numeric objects that can be
     * reasonably represented as a hexadecimal string.
     *
     * @return a string representing this object as a hexadecimal number.
     **/
    public PyString __hex__() {
        throw Py.TypeError("hex() argument can't be converted to hex");
    }

    /**
     * Equivalent to the standard Python __oct__ method.
     * Should only be overridden by numeric objects that can be
     * reasonably represented as an octal string.
     *
     * @return a string representing this object as an octal number.
     **/
    public PyString __oct__() {
        throw Py.TypeError("oct() argument can't be converted to oct");
    }

    /**
     * Equivalent to the standard Python __int__ method.
     * Should only be overridden by numeric objects that can be
     * reasonably coerced into an integer.
     *
     * @return an integer corresponding to the value of this object.
     **/
    public PyObject __int__() {
        throw Py.AttributeError("__int__");
    }

    /**
     * Equivalent to the standard Python __long__ method.
     * Should only be overridden by numeric objects that can be
     * reasonably coerced into a python long.
     *
     * @return a PyLong or PyInteger corresponding to the value of this object.
     **/
    public PyObject __long__() {
        throw Py.AttributeError("__long__");
    }

    /**
     * Equivalent to the standard Python __float__ method.
     * Should only be overridden by numeric objects that can be
     * reasonably coerced into a python float.
     *
     * @return a float corresponding to the value of this object.
     **/
    public PyFloat __float__() {
        throw Py.AttributeError("__float__");
    }

    /**
     * Equivalent to the standard Python __complex__ method.
     * Should only be overridden by numeric objects that can be
     * reasonably coerced into a python complex number.
     *
     * @return a complex number corresponding to the value of this object.
     **/
    public PyComplex __complex__() {
        throw Py.AttributeError("__complex__");
    }

    /**
     * Equivalent to the standard Python __pos__ method.
     *
     * @return +this.
     **/
    public PyObject __pos__() {
        throw Py.TypeError(String.format("bad operand type for unary +: '%.200s'",
                                         getType().fastGetName()));
    }

    /**
     * Equivalent to the standard Python __neg__ method.
     *
     * @return -this.
     **/
    public PyObject __neg__() {
        throw Py.TypeError(String.format("bad operand type for unary -: '%.200s'",
                                         getType().fastGetName()));
    }

    /**
     * Equivalent to the standard Python __abs__ method.
     *
     * @return abs(this).
     **/
    public PyObject __abs__() {
        throw Py.TypeError(String.format("bad operand type for abs(): '%.200s'",
                                         getType().fastGetName()));
    }

    /**
     * Equivalent to the standard Python __invert__ method.
     *
     * @return ~this.
     **/
    public PyObject __invert__() {
        throw Py.TypeError(String.format("bad operand type for unary ~: '%.200s'",
                                         getType().fastGetName()));
    }

    /**
     * Equivalent to the standard Python __index__ method.
     *
     * @return a PyInteger or PyLong
     * @throws a Py.TypeError if not supported
     **/
    public PyObject __index__() {
        throw Py.TypeError(String.format("'%.200s' object cannot be interpreted as an index",
                                         getType().fastGetName()));
    }

    /**
     * @param op the String form of the op (e.g. "+")
     * @param o2 the right operand
     */
    protected final String _unsupportedop(String op, PyObject o2) {
        Object[] args = {op, getType().fastGetName(), o2.getType().fastGetName()};
        String msg = unsupportedopMessage(op, o2);
        if (msg == null) {
            msg = o2.runsupportedopMessage(op, o2);
        }
        if (msg == null) {
            msg = "unsupported operand type(s) for {0}: ''{1}'' and ''{2}''";
        }
        return MessageFormat.format(msg, args);
    }

    /**
     * Should return an error message suitable for substitution where.
     *
     * {0} is the op name.
     * {1} is the left operand type.
     * {2} is the right operand type.
     */
    protected String unsupportedopMessage(String op, PyObject o2) {
        return null;
    }

    /**
     * Should return an error message suitable for substitution where.
     *
     * {0} is the op name.
     * {1} is the left operand type.
     * {2} is the right operand type.
     */
    protected String runsupportedopMessage(String op, PyObject o2) {
        return null;
    }

    /**
     * Implements the three argument power function.
     *
     * @param o2 the power to raise this number to.
     * @param o3 the modulus to perform this operation in or null if no
     *           modulo is to be used
     * @return this object raised to the given power in the given modulus
     **/
    public PyObject __pow__(PyObject o2, PyObject o3) {
        return null;
    }

    /**
     * Determine if the binary op on types t1 and t2 is an add
     * operation dealing with a str/unicode and a str/unicode
     * subclass.
     *
     * This operation is special cased in _binop_rule to match
     * CPython's handling; CPython uses tp_as_number and
     * tp_as_sequence to allow string/unicode subclasses to override
     * the left side's __add__ when that left side is an actual str or
     * unicode object (see test_concat_jy for examples).
     *
     * @param t1 left side PyType
     * @param t2 right side PyType
     * @param op the binary operation's String
     * @return true if this is a special case
     */
    private boolean isStrUnicodeSpecialCase(PyType t1, PyType t2, String op) {
        // XXX: We may need to generalize this rule to apply to other
        // situations
        // XXX: This method isn't expensive but could (and maybe
        // should?) be optimized for worst case scenarios
        return (op == "+") && (t1 == PyString.TYPE || t1 == PyUnicode.TYPE) &&
                (t2.isSubType(PyString.TYPE) || t2.isSubType(PyUnicode.TYPE));
    }

    private PyObject _binop_rule(PyType t1, PyObject o2, PyType t2,
            String left, String right, String op) {
        /*
         * this is the general rule for binary operation dispatching try first
         * __xxx__ with this and then __rxxx__ with o2 unless o2 is an instance
         * of subclass of the type of this, and further __xxx__ and __rxxx__ are
         * unrelated ( checked here by looking at where in the hierarchy they
         * are defined), in that case try them in the reverse order. This is the
         * same formulation as used by PyPy, see also
         * test_descr.subclass_right_op.
         */
        PyObject o1 = this;
        PyObject[] where = new PyObject[1];
        PyObject where1 = null, where2 = null;
        PyObject impl1 = t1.lookup_where(left, where);
        where1 = where[0];
        PyObject impl2 = t2.lookup_where(right, where);
        where2 = where[0];
        if (impl2 != null && impl1 != null && where1 != where2 &&
            (t2.isSubType(t1) && !Py.isSubClass(where1, where2)
                              && !Py.isSubClass(t1, where2)     ||
             isStrUnicodeSpecialCase(t1, t2, op))) {
            PyObject tmp = o1;
            o1 = o2;
            o2 = tmp;
            tmp = impl1;
            impl1 = impl2;
            impl2 = tmp;
            PyType ttmp;
            ttmp = t1;
            t1 = t2;
            t2 = ttmp;
        }
        PyObject res = null;
        if (impl1 != null) {
            res = impl1.__get__(o1, t1).__call__(o2);
            if (res != Py.NotImplemented) {
                return res;
            }
        }
        if (impl2 != null) {
            res = impl2.__get__(o2, t2).__call__(o1);
            if (res != Py.NotImplemented) {
                return res;
            }
        }
        throw Py.TypeError(_unsupportedop(op, o2));
    }

    // Generated by make_binops.py (Begin)

    /**
     * Equivalent to the standard Python __add__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the add, or null if this operation
     *            is not defined
     **/
    public PyObject __add__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __radd__ method
     * @param     other the object to perform this binary operation with
     *            (the left-hand operand).
     * @return    the result of the add, or null if this operation
     *            is not defined.
     **/
    public PyObject __radd__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __iadd__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the iadd, or null if this operation
     *            is not defined
     **/
    public PyObject __iadd__(PyObject other) {
        return null;
    }

    /**
      * Implements the Python expression <code>this + o2</code>
      * @param     o2 the object to perform this binary operation with.
      * @return    the result of the add.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _add(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_add(o2);
        }
        return _binop_rule(t1,o2,t2,"__add__","__radd__","+");
    }

    /**
     * Implements the Python expression <code>this + o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this binary operation with.
     * @return    the result of the add.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_add(PyObject o2) {
        PyObject x=__add__(o2);
        if (x!=null) {
            return x;
        }
        x=o2.__radd__(this);
        if (x!=null) {
            return x;
        }
        throw Py.TypeError(_unsupportedop("+",o2));
    }

    /**
      * Implements the Python expression <code>this += o2</code>
      * @param     o2 the object to perform this inplace binary
      *            operation with.
      * @return    the result of the iadd.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _iadd(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_iadd(o2);
        }
        PyObject impl=t1.lookup("__iadd__");
        if (impl!=null) {
            PyObject res=impl.__get__(this,t1).__call__(o2);
            if (res!=Py.NotImplemented) {
                return res;
            }
        }
        return _binop_rule(t1,o2,t2,"__add__","__radd__","+");
    }

    /**
     * Implements the Python expression <code>this += o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this inplace binary
     *            operation with.
     * @return    the result of the iadd.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_iadd(PyObject o2) {
        PyObject x=__iadd__(o2);
        if (x!=null) {
            return x;
        }
        return this._basic_add(o2);
    }

    /**
     * Equivalent to the standard Python __sub__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the sub, or null if this operation
     *            is not defined
     **/
    public PyObject __sub__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __rsub__ method
     * @param     other the object to perform this binary operation with
     *            (the left-hand operand).
     * @return    the result of the sub, or null if this operation
     *            is not defined.
     **/
    public PyObject __rsub__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __isub__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the isub, or null if this operation
     *            is not defined
     **/
    public PyObject __isub__(PyObject other) {
        return null;
    }

    /**
      * Implements the Python expression <code>this - o2</code>
      * @param     o2 the object to perform this binary operation with.
      * @return    the result of the sub.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _sub(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_sub(o2);
        }
        return _binop_rule(t1,o2,t2,"__sub__","__rsub__","-");
    }

    /**
     * Implements the Python expression <code>this - o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this binary operation with.
     * @return    the result of the sub.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_sub(PyObject o2) {
        PyObject x=__sub__(o2);
        if (x!=null) {
            return x;
        }
        x=o2.__rsub__(this);
        if (x!=null) {
            return x;
        }
        throw Py.TypeError(_unsupportedop("-",o2));
    }

    /**
      * Implements the Python expression <code>this -= o2</code>
      * @param     o2 the object to perform this inplace binary
      *            operation with.
      * @return    the result of the isub.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _isub(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_isub(o2);
        }
        PyObject impl=t1.lookup("__isub__");
        if (impl!=null) {
            PyObject res=impl.__get__(this,t1).__call__(o2);
            if (res!=Py.NotImplemented) {
                return res;
            }
        }
        return _binop_rule(t1,o2,t2,"__sub__","__rsub__","-");
    }

    /**
     * Implements the Python expression <code>this -= o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this inplace binary
     *            operation with.
     * @return    the result of the isub.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_isub(PyObject o2) {
        PyObject x=__isub__(o2);
        if (x!=null) {
            return x;
        }
        return this._basic_sub(o2);
    }

    /**
     * Equivalent to the standard Python __mul__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the mul, or null if this operation
     *            is not defined
     **/
    public PyObject __mul__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __rmul__ method
     * @param     other the object to perform this binary operation with
     *            (the left-hand operand).
     * @return    the result of the mul, or null if this operation
     *            is not defined.
     **/
    public PyObject __rmul__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __imul__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the imul, or null if this operation
     *            is not defined
     **/
    public PyObject __imul__(PyObject other) {
        return null;
    }

    /**
      * Implements the Python expression <code>this * o2</code>
      * @param     o2 the object to perform this binary operation with.
      * @return    the result of the mul.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _mul(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_mul(o2);
        }
        return _binop_rule(t1,o2,t2,"__mul__","__rmul__","*");
    }

    /**
     * Implements the Python expression <code>this * o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this binary operation with.
     * @return    the result of the mul.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_mul(PyObject o2) {
        PyObject x=__mul__(o2);
        if (x!=null) {
            return x;
        }
        x=o2.__rmul__(this);
        if (x!=null) {
            return x;
        }
        throw Py.TypeError(_unsupportedop("*",o2));
    }

    /**
      * Implements the Python expression <code>this *= o2</code>
      * @param     o2 the object to perform this inplace binary
      *            operation with.
      * @return    the result of the imul.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _imul(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_imul(o2);
        }
        PyObject impl=t1.lookup("__imul__");
        if (impl!=null) {
            PyObject res=impl.__get__(this,t1).__call__(o2);
            if (res!=Py.NotImplemented) {
                return res;
            }
        }
        return _binop_rule(t1,o2,t2,"__mul__","__rmul__","*");
    }

    /**
     * Implements the Python expression <code>this *= o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this inplace binary
     *            operation with.
     * @return    the result of the imul.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_imul(PyObject o2) {
        PyObject x=__imul__(o2);
        if (x!=null) {
            return x;
        }
        return this._basic_mul(o2);
    }

    /**
     * Equivalent to the standard Python __div__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the div, or null if this operation
     *            is not defined
     **/
    public PyObject __div__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __rdiv__ method
     * @param     other the object to perform this binary operation with
     *            (the left-hand operand).
     * @return    the result of the div, or null if this operation
     *            is not defined.
     **/
    public PyObject __rdiv__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __idiv__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the idiv, or null if this operation
     *            is not defined
     **/
    public PyObject __idiv__(PyObject other) {
        return null;
    }

    /**
      * Implements the Python expression <code>this / o2</code>
      * @param     o2 the object to perform this binary operation with.
      * @return    the result of the div.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _div(PyObject o2) {
        if (Options.Qnew)
            return _truediv(o2);
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_div(o2);
        }
        return _binop_rule(t1,o2,t2,"__div__","__rdiv__","/");
    }

    /**
     * Implements the Python expression <code>this / o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this binary operation with.
     * @return    the result of the div.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_div(PyObject o2) {
        PyObject x=__div__(o2);
        if (x!=null) {
            return x;
        }
        x=o2.__rdiv__(this);
        if (x!=null) {
            return x;
        }
        throw Py.TypeError(_unsupportedop("/",o2));
    }

    /**
      * Implements the Python expression <code>this /= o2</code>
      * @param     o2 the object to perform this inplace binary
      *            operation with.
      * @return    the result of the idiv.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _idiv(PyObject o2) {
        if (Options.Qnew)
            return _itruediv(o2);
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_idiv(o2);
        }
        PyObject impl=t1.lookup("__idiv__");
        if (impl!=null) {
            PyObject res=impl.__get__(this,t1).__call__(o2);
            if (res!=Py.NotImplemented) {
                return res;
            }
        }
        return _binop_rule(t1,o2,t2,"__div__","__rdiv__","/");
    }

    /**
     * Implements the Python expression <code>this /= o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this inplace binary
     *            operation with.
     * @return    the result of the idiv.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_idiv(PyObject o2) {
        PyObject x=__idiv__(o2);
        if (x!=null) {
            return x;
        }
        return this._basic_div(o2);
    }

    /**
     * Equivalent to the standard Python __floordiv__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the floordiv, or null if this operation
     *            is not defined
     **/
    public PyObject __floordiv__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __rfloordiv__ method
     * @param     other the object to perform this binary operation with
     *            (the left-hand operand).
     * @return    the result of the floordiv, or null if this operation
     *            is not defined.
     **/
    public PyObject __rfloordiv__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __ifloordiv__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the ifloordiv, or null if this operation
     *            is not defined
     **/
    public PyObject __ifloordiv__(PyObject other) {
        return null;
    }

    /**
      * Implements the Python expression <code>this // o2</code>
      * @param     o2 the object to perform this binary operation with.
      * @return    the result of the floordiv.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _floordiv(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_floordiv(o2);
        }
        return _binop_rule(t1,o2,t2,"__floordiv__","__rfloordiv__","//");
    }

    /**
     * Implements the Python expression <code>this // o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this binary operation with.
     * @return    the result of the floordiv.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_floordiv(PyObject o2) {
        PyObject x=__floordiv__(o2);
        if (x!=null) {
            return x;
        }
        x=o2.__rfloordiv__(this);
        if (x!=null) {
            return x;
        }
        throw Py.TypeError(_unsupportedop("//",o2));
    }

    /**
      * Implements the Python expression <code>this //= o2</code>
      * @param     o2 the object to perform this inplace binary
      *            operation with.
      * @return    the result of the ifloordiv.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _ifloordiv(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_ifloordiv(o2);
        }
        PyObject impl=t1.lookup("__ifloordiv__");
        if (impl!=null) {
            PyObject res=impl.__get__(this,t1).__call__(o2);
            if (res!=Py.NotImplemented) {
                return res;
            }
        }
        return _binop_rule(t1,o2,t2,"__floordiv__","__rfloordiv__","//");
    }

    /**
     * Implements the Python expression <code>this //= o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this inplace binary
     *            operation with.
     * @return    the result of the ifloordiv.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_ifloordiv(PyObject o2) {
        PyObject x=__ifloordiv__(o2);
        if (x!=null) {
            return x;
        }
        return this._basic_floordiv(o2);
    }

    /**
     * Equivalent to the standard Python __truediv__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the truediv, or null if this operation
     *            is not defined
     **/
    public PyObject __truediv__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __rtruediv__ method
     * @param     other the object to perform this binary operation with
     *            (the left-hand operand).
     * @return    the result of the truediv, or null if this operation
     *            is not defined.
     **/
    public PyObject __rtruediv__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __itruediv__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the itruediv, or null if this operation
     *            is not defined
     **/
    public PyObject __itruediv__(PyObject other) {
        return null;
    }

    /**
      * Implements the Python expression <code>this / o2</code>
      * @param     o2 the object to perform this binary operation with.
      * @return    the result of the truediv.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _truediv(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_truediv(o2);
        }
        return _binop_rule(t1,o2,t2,"__truediv__","__rtruediv__","/");
    }

    /**
     * Implements the Python expression <code>this / o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this binary operation with.
     * @return    the result of the truediv.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_truediv(PyObject o2) {
        PyObject x=__truediv__(o2);
        if (x!=null) {
            return x;
        }
        x=o2.__rtruediv__(this);
        if (x!=null) {
            return x;
        }
        throw Py.TypeError(_unsupportedop("/",o2));
    }

    /**
      * Implements the Python expression <code>this /= o2</code>
      * @param     o2 the object to perform this inplace binary
      *            operation with.
      * @return    the result of the itruediv.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _itruediv(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_itruediv(o2);
        }
        PyObject impl=t1.lookup("__itruediv__");
        if (impl!=null) {
            PyObject res=impl.__get__(this,t1).__call__(o2);
            if (res!=Py.NotImplemented) {
                return res;
            }
        }
        return _binop_rule(t1,o2,t2,"__truediv__","__rtruediv__","/");
    }

    /**
     * Implements the Python expression <code>this /= o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this inplace binary
     *            operation with.
     * @return    the result of the itruediv.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_itruediv(PyObject o2) {
        PyObject x=__itruediv__(o2);
        if (x!=null) {
            return x;
        }
        return this._basic_truediv(o2);
    }

    /**
     * Equivalent to the standard Python __mod__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the mod, or null if this operation
     *            is not defined
     **/
    public PyObject __mod__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __rmod__ method
     * @param     other the object to perform this binary operation with
     *            (the left-hand operand).
     * @return    the result of the mod, or null if this operation
     *            is not defined.
     **/
    public PyObject __rmod__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __imod__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the imod, or null if this operation
     *            is not defined
     **/
    public PyObject __imod__(PyObject other) {
        return null;
    }

    /**
      * Implements the Python expression <code>this % o2</code>
      * @param     o2 the object to perform this binary operation with.
      * @return    the result of the mod.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _mod(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_mod(o2);
        }
        return _binop_rule(t1,o2,t2,"__mod__","__rmod__","%");
    }

    /**
     * Implements the Python expression <code>this % o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this binary operation with.
     * @return    the result of the mod.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_mod(PyObject o2) {
        PyObject x=__mod__(o2);
        if (x!=null) {
            return x;
        }
        x=o2.__rmod__(this);
        if (x!=null) {
            return x;
        }
        throw Py.TypeError(_unsupportedop("%",o2));
    }

    /**
      * Implements the Python expression <code>this %= o2</code>
      * @param     o2 the object to perform this inplace binary
      *            operation with.
      * @return    the result of the imod.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _imod(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_imod(o2);
        }
        PyObject impl=t1.lookup("__imod__");
        if (impl!=null) {
            PyObject res=impl.__get__(this,t1).__call__(o2);
            if (res!=Py.NotImplemented) {
                return res;
            }
        }
        return _binop_rule(t1,o2,t2,"__mod__","__rmod__","%");
    }

    /**
     * Implements the Python expression <code>this %= o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this inplace binary
     *            operation with.
     * @return    the result of the imod.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_imod(PyObject o2) {
        PyObject x=__imod__(o2);
        if (x!=null) {
            return x;
        }
        return this._basic_mod(o2);
    }

    /**
     * Equivalent to the standard Python __divmod__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the divmod, or null if this operation
     *            is not defined
     **/
    public PyObject __divmod__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __rdivmod__ method
     * @param     other the object to perform this binary operation with
     *            (the left-hand operand).
     * @return    the result of the divmod, or null if this operation
     *            is not defined.
     **/
    public PyObject __rdivmod__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __idivmod__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the idivmod, or null if this operation
     *            is not defined
     **/
    public PyObject __idivmod__(PyObject other) {
        return null;
    }

    /**
      * Implements the Python expression <code>this divmod o2</code>
      * @param     o2 the object to perform this binary operation with.
      * @return    the result of the divmod.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _divmod(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_divmod(o2);
        }
        return _binop_rule(t1,o2,t2,"__divmod__","__rdivmod__","divmod");
    }

    /**
     * Implements the Python expression <code>this divmod o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this binary operation with.
     * @return    the result of the divmod.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_divmod(PyObject o2) {
        PyObject x=__divmod__(o2);
        if (x!=null) {
            return x;
        }
        x=o2.__rdivmod__(this);
        if (x!=null) {
            return x;
        }
        throw Py.TypeError(_unsupportedop("divmod",o2));
    }

    /**
      * Implements the Python expression <code>this divmod= o2</code>
      * @param     o2 the object to perform this inplace binary
      *            operation with.
      * @return    the result of the idivmod.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _idivmod(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_idivmod(o2);
        }
        PyObject impl=t1.lookup("__idivmod__");
        if (impl!=null) {
            PyObject res=impl.__get__(this,t1).__call__(o2);
            if (res!=Py.NotImplemented) {
                return res;
            }
        }
        return _binop_rule(t1,o2,t2,"__divmod__","__rdivmod__","divmod");
    }

    /**
     * Implements the Python expression <code>this divmod= o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this inplace binary
     *            operation with.
     * @return    the result of the idivmod.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_idivmod(PyObject o2) {
        PyObject x=__idivmod__(o2);
        if (x!=null) {
            return x;
        }
        return this._basic_divmod(o2);
    }

    /**
     * Equivalent to the standard Python __pow__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the pow, or null if this operation
     *            is not defined
     **/
    public PyObject __pow__(PyObject other) {
        return __pow__(other,null);
    }

    /**
     * Equivalent to the standard Python __rpow__ method
     * @param     other the object to perform this binary operation with
     *            (the left-hand operand).
     * @return    the result of the pow, or null if this operation
     *            is not defined.
     **/
    public PyObject __rpow__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __ipow__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the ipow, or null if this operation
     *            is not defined
     **/
    public PyObject __ipow__(PyObject other) {
        return null;
    }

    /**
      * Implements the Python expression <code>this ** o2</code>
      * @param     o2 the object to perform this binary operation with.
      * @return    the result of the pow.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _pow(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_pow(o2);
        }
        return _binop_rule(t1,o2,t2,"__pow__","__rpow__","**");
    }

    /**
     * Implements the Python expression <code>this ** o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this binary operation with.
     * @return    the result of the pow.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_pow(PyObject o2) {
        PyObject x=__pow__(o2);
        if (x!=null) {
            return x;
        }
        x=o2.__rpow__(this);
        if (x!=null) {
            return x;
        }
        throw Py.TypeError(_unsupportedop("**",o2));
    }

    /**
      * Implements the Python expression <code>this **= o2</code>
      * @param     o2 the object to perform this inplace binary
      *            operation with.
      * @return    the result of the ipow.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _ipow(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_ipow(o2);
        }
        PyObject impl=t1.lookup("__ipow__");
        if (impl!=null) {
            PyObject res=impl.__get__(this,t1).__call__(o2);
            if (res!=Py.NotImplemented) {
                return res;
            }
        }
        return _binop_rule(t1,o2,t2,"__pow__","__rpow__","**");
    }

    /**
     * Implements the Python expression <code>this **= o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this inplace binary
     *            operation with.
     * @return    the result of the ipow.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_ipow(PyObject o2) {
        PyObject x=__ipow__(o2);
        if (x!=null) {
            return x;
        }
        return this._basic_pow(o2);
    }

    /**
     * Equivalent to the standard Python __lshift__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the lshift, or null if this operation
     *            is not defined
     **/
    public PyObject __lshift__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __rlshift__ method
     * @param     other the object to perform this binary operation with
     *            (the left-hand operand).
     * @return    the result of the lshift, or null if this operation
     *            is not defined.
     **/
    public PyObject __rlshift__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __ilshift__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the ilshift, or null if this operation
     *            is not defined
     **/
    public PyObject __ilshift__(PyObject other) {
        return null;
    }

    /**
      * Implements the Python expression <code>this << o2</code>
      * @param     o2 the object to perform this binary operation with.
      * @return    the result of the lshift.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _lshift(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_lshift(o2);
        }
        return _binop_rule(t1,o2,t2,"__lshift__","__rlshift__","<<");
    }

    /**
     * Implements the Python expression <code>this << o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this binary operation with.
     * @return    the result of the lshift.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_lshift(PyObject o2) {
        PyObject x=__lshift__(o2);
        if (x!=null) {
            return x;
        }
        x=o2.__rlshift__(this);
        if (x!=null) {
            return x;
        }
        throw Py.TypeError(_unsupportedop("<<",o2));
    }

    /**
      * Implements the Python expression <code>this <<= o2</code>
      * @param     o2 the object to perform this inplace binary
      *            operation with.
      * @return    the result of the ilshift.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _ilshift(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_ilshift(o2);
        }
        PyObject impl=t1.lookup("__ilshift__");
        if (impl!=null) {
            PyObject res=impl.__get__(this,t1).__call__(o2);
            if (res!=Py.NotImplemented) {
                return res;
            }
        }
        return _binop_rule(t1,o2,t2,"__lshift__","__rlshift__","<<");
    }

    /**
     * Implements the Python expression <code>this <<= o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this inplace binary
     *            operation with.
     * @return    the result of the ilshift.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_ilshift(PyObject o2) {
        PyObject x=__ilshift__(o2);
        if (x!=null) {
            return x;
        }
        return this._basic_lshift(o2);
    }

    /**
     * Equivalent to the standard Python __rshift__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the rshift, or null if this operation
     *            is not defined
     **/
    public PyObject __rshift__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __rrshift__ method
     * @param     other the object to perform this binary operation with
     *            (the left-hand operand).
     * @return    the result of the rshift, or null if this operation
     *            is not defined.
     **/
    public PyObject __rrshift__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __irshift__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the irshift, or null if this operation
     *            is not defined
     **/
    public PyObject __irshift__(PyObject other) {
        return null;
    }

    /**
      * Implements the Python expression <code>this >> o2</code>
      * @param     o2 the object to perform this binary operation with.
      * @return    the result of the rshift.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _rshift(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_rshift(o2);
        }
        return _binop_rule(t1,o2,t2,"__rshift__","__rrshift__",">>");
    }

    /**
     * Implements the Python expression <code>this >> o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this binary operation with.
     * @return    the result of the rshift.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_rshift(PyObject o2) {
        PyObject x=__rshift__(o2);
        if (x!=null) {
            return x;
        }
        x=o2.__rrshift__(this);
        if (x!=null) {
            return x;
        }
        throw Py.TypeError(_unsupportedop(">>",o2));
    }

    /**
      * Implements the Python expression <code>this >>= o2</code>
      * @param     o2 the object to perform this inplace binary
      *            operation with.
      * @return    the result of the irshift.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _irshift(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_irshift(o2);
        }
        PyObject impl=t1.lookup("__irshift__");
        if (impl!=null) {
            PyObject res=impl.__get__(this,t1).__call__(o2);
            if (res!=Py.NotImplemented) {
                return res;
            }
        }
        return _binop_rule(t1,o2,t2,"__rshift__","__rrshift__",">>");
    }

    /**
     * Implements the Python expression <code>this >>= o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this inplace binary
     *            operation with.
     * @return    the result of the irshift.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_irshift(PyObject o2) {
        PyObject x=__irshift__(o2);
        if (x!=null) {
            return x;
        }
        return this._basic_rshift(o2);
    }

    /**
     * Equivalent to the standard Python __and__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the and, or null if this operation
     *            is not defined
     **/
    public PyObject __and__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __rand__ method
     * @param     other the object to perform this binary operation with
     *            (the left-hand operand).
     * @return    the result of the and, or null if this operation
     *            is not defined.
     **/
    public PyObject __rand__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __iand__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the iand, or null if this operation
     *            is not defined
     **/
    public PyObject __iand__(PyObject other) {
        return null;
    }

    /**
      * Implements the Python expression <code>this & o2</code>
      * @param     o2 the object to perform this binary operation with.
      * @return    the result of the and.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _and(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_and(o2);
        }
        return _binop_rule(t1,o2,t2,"__and__","__rand__","&");
    }

    /**
     * Implements the Python expression <code>this & o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this binary operation with.
     * @return    the result of the and.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_and(PyObject o2) {
        PyObject x=__and__(o2);
        if (x!=null) {
            return x;
        }
        x=o2.__rand__(this);
        if (x!=null) {
            return x;
        }
        throw Py.TypeError(_unsupportedop("&",o2));
    }

    /**
      * Implements the Python expression <code>this &= o2</code>
      * @param     o2 the object to perform this inplace binary
      *            operation with.
      * @return    the result of the iand.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _iand(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_iand(o2);
        }
        PyObject impl=t1.lookup("__iand__");
        if (impl!=null) {
            PyObject res=impl.__get__(this,t1).__call__(o2);
            if (res!=Py.NotImplemented) {
                return res;
            }
        }
        return _binop_rule(t1,o2,t2,"__and__","__rand__","&");
    }

    /**
     * Implements the Python expression <code>this &= o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this inplace binary
     *            operation with.
     * @return    the result of the iand.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_iand(PyObject o2) {
        PyObject x=__iand__(o2);
        if (x!=null) {
            return x;
        }
        return this._basic_and(o2);
    }

    /**
     * Equivalent to the standard Python __or__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the or, or null if this operation
     *            is not defined
     **/
    public PyObject __or__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __ror__ method
     * @param     other the object to perform this binary operation with
     *            (the left-hand operand).
     * @return    the result of the or, or null if this operation
     *            is not defined.
     **/
    public PyObject __ror__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __ior__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the ior, or null if this operation
     *            is not defined
     **/
    public PyObject __ior__(PyObject other) {
        return null;
    }

    /**
      * Implements the Python expression <code>this | o2</code>
      * @param     o2 the object to perform this binary operation with.
      * @return    the result of the or.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _or(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_or(o2);
        }
        return _binop_rule(t1,o2,t2,"__or__","__ror__","|");
    }

    /**
     * Implements the Python expression <code>this | o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this binary operation with.
     * @return    the result of the or.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_or(PyObject o2) {
        PyObject x=__or__(o2);
        if (x!=null) {
            return x;
        }
        x=o2.__ror__(this);
        if (x!=null) {
            return x;
        }
        throw Py.TypeError(_unsupportedop("|",o2));
    }

    /**
      * Implements the Python expression <code>this |= o2</code>
      * @param     o2 the object to perform this inplace binary
      *            operation with.
      * @return    the result of the ior.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _ior(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_ior(o2);
        }
        PyObject impl=t1.lookup("__ior__");
        if (impl!=null) {
            PyObject res=impl.__get__(this,t1).__call__(o2);
            if (res!=Py.NotImplemented) {
                return res;
            }
        }
        return _binop_rule(t1,o2,t2,"__or__","__ror__","|");
    }

    /**
     * Implements the Python expression <code>this |= o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this inplace binary
     *            operation with.
     * @return    the result of the ior.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_ior(PyObject o2) {
        PyObject x=__ior__(o2);
        if (x!=null) {
            return x;
        }
        return this._basic_or(o2);
    }

    /**
     * Equivalent to the standard Python __xor__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the xor, or null if this operation
     *            is not defined
     **/
    public PyObject __xor__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __rxor__ method
     * @param     other the object to perform this binary operation with
     *            (the left-hand operand).
     * @return    the result of the xor, or null if this operation
     *            is not defined.
     **/
    public PyObject __rxor__(PyObject other) {
        return null;
    }

    /**
     * Equivalent to the standard Python __ixor__ method
     * @param     other the object to perform this binary operation with
     *            (the right-hand operand).
     * @return    the result of the ixor, or null if this operation
     *            is not defined
     **/
    public PyObject __ixor__(PyObject other) {
        return null;
    }

    /**
      * Implements the Python expression <code>this ^ o2</code>
      * @param     o2 the object to perform this binary operation with.
      * @return    the result of the xor.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _xor(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_xor(o2);
        }
        return _binop_rule(t1,o2,t2,"__xor__","__rxor__","^");
    }

    /**
     * Implements the Python expression <code>this ^ o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this binary operation with.
     * @return    the result of the xor.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_xor(PyObject o2) {
        PyObject x=__xor__(o2);
        if (x!=null) {
            return x;
        }
        x=o2.__rxor__(this);
        if (x!=null) {
            return x;
        }
        throw Py.TypeError(_unsupportedop("^",o2));
    }

    /**
      * Implements the Python expression <code>this ^= o2</code>
      * @param     o2 the object to perform this inplace binary
      *            operation with.
      * @return    the result of the ixor.
      * @exception Py.TypeError if this operation can't be performed
      *            with these operands.
      **/
    public final PyObject _ixor(PyObject o2) {
        PyType t1=this.getType();
        PyType t2=o2.getType();
        if (t1==t2||t1.builtin&&t2.builtin) {
            return this._basic_ixor(o2);
        }
        PyObject impl=t1.lookup("__ixor__");
        if (impl!=null) {
            PyObject res=impl.__get__(this,t1).__call__(o2);
            if (res!=Py.NotImplemented) {
                return res;
            }
        }
        return _binop_rule(t1,o2,t2,"__xor__","__rxor__","^");
    }

    /**
     * Implements the Python expression <code>this ^= o2</code>
     * when this and o2 have the same type or are builtin types.
     * @param     o2 the object to perform this inplace binary
     *            operation with.
     * @return    the result of the ixor.
     * @exception Py.TypeError if this operation can't be performed
     *            with these operands.
     **/
    final PyObject _basic_ixor(PyObject o2) {
        PyObject x=__ixor__(o2);
        if (x!=null) {
            return x;
        }
        return this._basic_xor(o2);
    }

    // Generated by make_binops.py (End)

    /**
     * A convenience function for PyProxys.
     */
    public PyObject _jcallexc(Object[] args) throws Throwable {
        try {
            return __call__(Py.javas2pys(args));
        } catch (PyException e) {
            if (e.value.getJavaProxy() != null) {
                Object t = e.value.__tojava__(Throwable.class);
                if (t != null && t != Py.NoConversion) {
                    throw (Throwable) t;
                }
            } else {
                ThreadState ts = Py.getThreadState();
                if (ts.frame == null) {
                    Py.maybeSystemExit(e);
                }
                if (Options.showPythonProxyExceptions) {
                    Py.stderr.println(
                        "Exception in Python proxy returning to Java:");
                    Py.printException(e);
                }
            }
            throw e;
        }
    }

    public void _jthrow(Throwable t) {
        if (t instanceof RuntimeException)
            throw (RuntimeException) t;
        if (t instanceof Error)
            throw (Error) t;
        throw Py.JavaError(t);
    }

    public PyObject _jcall(Object[] args) {
        try {
            return _jcallexc(args);
        } catch (Throwable t) {
            _jthrow(t);
            return null;
        }
    }

    /* Shortcut methods for calling methods from Java */

    /**
     * Shortcut for calling a method on a PyObject from Java.
     * This form is equivalent to o.__getattr__(name).__call__(args, keywords)
     *
     * @param name the name of the method to call.  This must be an
     *             interned string!
     * @param args an array of the arguments to the call.
     * @param keywords the keywords to use in the call.
     * @return the result of calling the method name with args and keywords.
     **/
    public PyObject invoke(String name, PyObject[] args, String[] keywords) {
        PyObject f = __getattr__(name);
        return f.__call__(args, keywords);
    }

    public PyObject invoke(String name, PyObject[] args) {
        PyObject f = __getattr__(name);
        return f.__call__(args);
    }

    /**
     * Shortcut for calling a method on a PyObject with no args.
     *
     * @param name the name of the method to call.  This must be an
     * interned string!
     * @return the result of calling the method name with no args
     **/
    public PyObject invoke(String name) {
        PyObject f = __getattr__(name);
        return f.__call__();
    }

    /**
     * Shortcut for calling a method on a PyObject with one arg.
     *
     * @param name the name of the method to call.  This must be an
     * interned string!
     * @param arg1 the one argument of the method.
     * @return the result of calling the method name with arg1
     **/
    public PyObject invoke(String name, PyObject arg1) {
        PyObject f = __getattr__(name);
        return f.__call__(arg1);
    }

    /**
     * Shortcut for calling a method on a PyObject with two args.
     *
     * @param name the name of the method to call.  This must be an
     *        interned string!
     * @param arg1 the first argument of the method.
     * @param arg2 the second argument of the method.
     * @return the result of calling the method name with arg1 and arg2
     **/
    public PyObject invoke(String name, PyObject arg1, PyObject arg2) {
        PyObject f = __getattr__(name);
        return f.__call__(arg1, arg2);
    }

    /**
     * Shortcut for calling a method on a PyObject with one extra
     * initial argument.
     *
     * @param name the name of the method to call.  This must be an
     *        interned string!
     * @param arg1 the first argument of the method.
     * @param args an array of the arguments to the call.
     * @param keywords the keywords to use in the call.
     * @return the result of calling the method name with arg1 args
     * and keywords
     **/
    public PyObject invoke(String name, PyObject arg1, PyObject[] args, String[] keywords) {
        PyObject f = __getattr__(name);
        return f.__call__(arg1, args, keywords);
    }

    /* descriptors and lookup protocols */

    /** xxx implements where meaningful
     * @return internal object per instance dict or null
     */
    public PyObject fastGetDict() {
        return null;
    }

    /** xxx implements where meaningful
     * @return internal object __dict__ or null
     */
    public PyObject getDict() {
        return null;
    }

    public void setDict(PyObject newDict) {
        // fallback if setDict not implemented in subclass
        throw Py.TypeError("can't set attribute '__dict__' of instance of " + getType().fastGetName());
    }

    public void delDict() {
        // fallback to error
        throw Py.TypeError("can't delete attribute '__dict__' of instance of '" + getType().fastGetName()+ "'");
    }

    public boolean implementsDescrGet() {
        return objtype.hasGet;
    }

    public boolean implementsDescrSet() {
        return objtype.hasSet;
    }

    public boolean implementsDescrDelete() {
        return objtype.hasDelete;
    }

    public boolean isDataDescr() {
        return objtype.hasSet || objtype.hasDelete;
    }

    /**
     * Get descriptor for this PyObject.
     *
     * @param obj -
     *            the instance accessing this descriptor. Can be null if this is
     *            being accessed by a type.
     * @param type -
     *            the type accessing this descriptor. Will be null if obj exists
     *            as obj is of the type accessing the descriptor.
     * @return - the object defined for this descriptor for the given obj and
     *         type.
     */
    public PyObject __get__(PyObject obj, PyObject type) {
        return _doget(obj, type);
    }

    public void __set__(PyObject obj, PyObject value) {
        if (!_doset(obj, value)) {
            throw Py.AttributeError("object internal __set__ impl is abstract");
        }
    }

    public void __delete__(PyObject obj) {
        throw Py.AttributeError("object internal __delete__ impl is abstract");
    }

    @ExposedMethod(doc = BuiltinDocs.object___getattribute___doc)
    final PyObject object___getattribute__(PyObject arg0) {
        String name = asName(arg0);
        PyObject ret = object___findattr__(name);
        if (ret == null) {
            noAttributeError(name);
        }
        return ret;
    }

    // name must be interned
    final PyObject object___findattr__(String name) {
        PyObject descr = objtype.lookup(name);
        PyObject res;
        boolean get = false;

        if (descr != null) {
            get = descr.implementsDescrGet();
            if (get && descr.isDataDescr()) {
                return descr.__get__(this, objtype);
            }
        }

        PyObject obj_dict = fastGetDict();
        if (obj_dict != null) {
            res = obj_dict.__finditem__(name);
            if (res != null) {
                return res;
            }
        }

        if (get) {
            return descr.__get__(this, objtype);
        }

        if (descr != null) {
            return descr;
        }

        return null;
    }

    @ExposedMethod(doc = BuiltinDocs.object___setattr___doc)
    final void object___setattr__(PyObject name, PyObject value) {
        hackCheck("__setattr__");
        object___setattr__(asName(name), value);
    }

    final void object___setattr__(String name, PyObject value) {
        PyObject descr = objtype.lookup(name);
        boolean set = false;

        if (descr != null) {
            set = descr.implementsDescrSet();
            if (set && descr.isDataDescr()) {
                descr.__set__(this, value);
                return;
            }
        }

        PyObject obj_dict = fastGetDict();
        if (obj_dict != null) {
            obj_dict.__setitem__(name, value);
            return;
        }

        if (set) {
            descr.__set__(this, value);
        }

        if (descr != null) {
            readonlyAttributeError(name);
        }

        noAttributeError(name);
    }

    @ExposedMethod(doc = BuiltinDocs.object___delattr___doc)
    final void object___delattr__(PyObject name) {
        hackCheck("__delattr__");
        object___delattr__(asName(name));
    }

    public static final String asName(PyObject obj) {
        try {
            return obj.asName(0);
        } catch(PyObject.ConversionException e) {
            throw Py.TypeError("attribute name must be a string");
        }
    }

    final void object___delattr__(String name) {
        PyObject descr = objtype.lookup(name);
        boolean delete = false;

        if (descr != null) {
            delete = descr.implementsDescrDelete();
            if (delete && descr.isDataDescr()) {
                descr.__delete__(this);
                return;
            }
        }

        PyObject obj_dict = fastGetDict();
        if (obj_dict != null) {
            try {
                obj_dict.__delitem__(name);
            } catch (PyException exc) {
                if (exc.match(Py.KeyError)) {
                    noAttributeError(name);
                } else {
                    throw exc;
                }
            }
            return;
        }

        if (delete) {
            descr.__delete__(this);
        }

        if (descr != null) {
            readonlyAttributeError(name);
        }

        noAttributeError(name);
    }

    /**
     * Helper to check for object.__setattr__ or __delattr__ applied to a type (The Carlo
     * Verre hack).
     *
     * @param what String method name to check for
     */
    private void hackCheck(String what) {
        if (this instanceof PyType && ((PyType)this).builtin) {
            throw Py.TypeError(String.format("can't apply this %s to %s object", what,
                                             objtype.fastGetName()));
        }
    }

    /**
     * Used for pickling.  Default implementation calls object___reduce__.
     *
     * @return a tuple of (class, tuple)
     */
    public PyObject __reduce__() {
        return object___reduce__();
    }

    @ExposedMethod(doc = BuiltinDocs.object___reduce___doc)
    final PyObject object___reduce__() {
        return object___reduce_ex__(0);
    }

    /** Used for pickling.  If the subclass specifies __reduce__, it will
     * override __reduce_ex__ in the base-class, even if __reduce_ex__ was
     * called with an argument.
     *
     * @param arg PyInteger specifying reduce algorithm (method without this
     * argument defaults to 0).
     * @return a tuple of (class, tuple)
     */
    public PyObject __reduce_ex__(int arg) {
        return object___reduce_ex__(arg);
    }
    public PyObject __reduce_ex__() {
        return object___reduce_ex__(0);
    }

    @ExposedMethod(defaults = "0", doc = BuiltinDocs.object___reduce___doc)
    final PyObject object___reduce_ex__(int arg) {
        PyObject res;

        PyObject clsreduce = this.getType().__findattr__("__reduce__");
        PyObject objreduce = (new PyObject()).getType().__findattr__("__reduce__");

        if (clsreduce != objreduce) {
            res = this.__reduce__();
        } else if (arg >= 2) {
            res = reduce_2();
        } else {
            PyObject copyreg = __builtin__.__import__("copy_reg", null, null, Py.EmptyTuple);
            PyObject copyreg_reduce = copyreg.__findattr__("_reduce_ex");
            res = copyreg_reduce.__call__(this, new PyInteger(arg));
        }
        return res;
    }

    private static PyObject slotnames(PyObject cls) {
        PyObject slotnames;

        slotnames = cls.fastGetDict().__finditem__("__slotnames__");
        if (null != slotnames) {
            return slotnames;
        }

        PyObject copyreg = __builtin__.__import__("copy_reg", null, null, Py.EmptyTuple);
        PyObject copyreg_slotnames = copyreg.__findattr__("_slotnames");
        slotnames = copyreg_slotnames.__call__(cls);
        if (null != slotnames && Py.None != slotnames && (!(slotnames instanceof PyList))) {
            throw Py.TypeError("copy_reg._slotnames didn't return a list or None");
        }

        return slotnames;
    }

    private PyObject reduce_2() {
        PyObject args, state;
        PyObject res = null;
        int n,i;

        PyObject cls = this.__findattr__("__class__");

        PyObject getnewargs = this.__findattr__("__getnewargs__");
        if (null != getnewargs) {
            args = getnewargs.__call__();
            if (null != args && !(args instanceof PyTuple)) {
                throw Py.TypeError("__getnewargs__ should return a tuple");
            }
        } else {
            args = Py.EmptyTuple;
        }

        PyObject getstate = this.__findattr__("__getstate__");
        if (null != getstate) {
            state = getstate.__call__();
            if (null == state) {
                return res;
            }
        } else {
            state = this.__findattr__("__dict__");
            if (null == state) {
                state = Py.None;
            }

            PyObject names = slotnames(cls);
            if (null == names) {
                return res;
            }

            if (names != Py.None) {
                if (!(names instanceof PyList)) {
                    throw Py.AssertionError("slots not a list");
                }
                PyObject slots = new PyDictionary();

                n = 0;
                for (i = 0; i < ((PyList)names).size(); i++) {
                    PyObject name = ((PyList)names).pyget(i);
                    PyObject value = this.__findattr__(name.toString());
                    if (null == value) {
                        // do nothing
                    } else {
                        slots.__setitem__(name, value);
                        n++;
                    }
                }
                if (n > 0) {
                    state = new PyTuple(state, slots);
                }
            }
        }
        PyObject listitems;
        PyObject dictitems;
        if (!(this instanceof PyList)) {
            listitems = Py.None;
        } else {
            listitems = ((PyList)this).__iter__();
        }
        if (!(this instanceof PyDictionary)) {
            dictitems = Py.None;
        } else {
            dictitems = invoke("iteritems");
        }

        PyObject copyreg = __builtin__.__import__("copy_reg", null, null, Py.EmptyTuple);
        PyObject newobj = copyreg.__findattr__("__newobj__");

        n = ((PyTuple)args).size();
        PyObject args2[] = new PyObject[n+1];
        args2[0] = cls;
        for(i = 0; i < n; i++) {
            args2[i+1] = ((PyTuple)args).pyget(i);
        }

        return new PyTuple(newobj, new PyTuple(args2), state, listitems, dictitems);
    }

    public PyTuple __getnewargs__() {
        //default is empty tuple
        return new PyTuple();
    }

    /* arguments' conversion helpers */

    public static class ConversionException extends Exception {

        public int index;

        public ConversionException(int index) {
            this.index = index;
        }

    }

    public String asString(int index) throws ConversionException {
        throw new ConversionException(index);
    }

    public String asString(){
        throw Py.TypeError("expected a str");
    }

    public String asStringOrNull(int index) throws ConversionException {
       return asString(index);
    }

    public String asStringOrNull(){
        return asString();
    }

    // TODO - remove when all asName users are moved to the @Exposed annotation
    public String asName(int index) throws ConversionException {
        throw new ConversionException(index);
    }

    // TODO - remove when all generated users are migrated to @Exposed and asInt()
    public int asInt(int index) throws ConversionException {
        throw new ConversionException(index);
    }

    /**
     * Convert this object into an int. Throws a PyException on failure.
     *
     * @return an int value
     */
    public int asInt() {
        PyObject intObj;
        try {
            intObj = __int__();
        } catch (PyException pye) {
            if (pye.match(Py.AttributeError)) {
                throw Py.TypeError("an integer is required");
            }
            throw pye;
        }
        if (!(intObj instanceof PyInteger || intObj instanceof PyLong)) {
            // Shouldn't happen except with buggy builtin types
            throw Py.TypeError("nb_int should return int object");
        }
        return intObj.asInt();
    }

    public long asLong(int index) throws ConversionException {
        throw new ConversionException(index);
    }

    /**
     * Convert this object longo an long. Throws a PyException on failure.
     *
     * @return an long value
     */
    public long asLong() {
        PyObject longObj;
        try {
            longObj = __long__();
        } catch (PyException pye) {
            if (pye.match(Py.AttributeError)) {
                throw Py.TypeError("an integer is required");
            }
            throw pye;
        }
        if (!(longObj instanceof PyLong || longObj instanceof PyInteger)) {
            // Shouldn't happen except with buggy builtin types
            throw Py.TypeError("integer conversion failed");
        }
        return longObj.asLong();
    }

    /**
     * Convert this object into a double. Throws a PyException on failure.
     *
     * @return a double value
     */
    public double asDouble() {
        PyFloat floatObj;
        try {
            floatObj = __float__();
        } catch (PyException pye) {
            if (pye.match(Py.AttributeError)) {
                throw Py.TypeError("a float is required");
            }
            throw pye;
        }
        return floatObj.asDouble();
    }

    /**
     * Convert this object into an index-sized integer. Throws a PyException on failure.
     *
     * @return an index-sized int
     */
    public int asIndex() {
        return asIndex(null);
    }

    /**
     * Convert this object into an index-sized integer.
     *
     * Throws a Python exception on Overflow if specified an exception type for err.
     *
     * @param err the Python exception to raise on OverflowErrors
     * @return an index-sized int
     */
    public int asIndex(PyObject err) {
        // OverflowErrors are handled in PyLong.asIndex
        return __index__().asInt();
    }
}

/*
 * A very specialized tuple-like class used when detecting cycles during
 * object comparisons. This classes is different from an normal tuple
 * by hashing and comparing its elements by identity.
 */

class PyIdentityTuple extends PyObject {

    PyObject[] list;

    public PyIdentityTuple(PyObject elements[]) {
        list = elements;
    }

    @Override
    public int hashCode() {
        int x, y;
        int len = list.length;
        x = 0x345678;

        for (len--; len >= 0; len--) {
            y = System.identityHashCode(list[len]);
            x = (x + x + x) ^ y;
        }
        x ^= list.length;
        return x;
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof PyIdentityTuple))
            return false;
        PyIdentityTuple that = (PyIdentityTuple) o;
        if (list.length != that.list.length)
            return false;
        for (int i = 0; i < list.length; i++) {
            if (list[i] != that.list[i])
                return false;
        }
        return true;
    }

}
