[Home] DMelt member access. Java source code: org.python.core.PyDictionary
/*
* Copyright (c) Corporation for National Research Initiatives
* Copyright (c) Jython Developers
*/
package org.python.core;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentHashMap;
import org.python.core.AbstractDict.ValuesIter;
import org.python.core.AbstractDict.KeysIter;
import org.python.core.AbstractDict.ItemsIter;
import org.python.expose.ExposedClassMethod;
import org.python.expose.ExposedMethod;
import org.python.expose.ExposedNew;
import org.python.expose.ExposedType;
import org.python.expose.MethodType;
import org.python.util.Generic;
/**
* A builtin python dictionary.
*/
@ExposedType(name = "dict", base = PyObject.class, doc = BuiltinDocs.dict_doc)
public class PyDictionary extends AbstractDict implements ConcurrentMap, Traverseproc {
public static final PyType TYPE = PyType.fromClass(PyDictionary.class);
{
/* Ensure dict is not Hashable */
TYPE.object___setattr__("__hash__", Py.None);
}
private final ConcurrentMap internalMap;
public ConcurrentMap getMap() {
return internalMap;
}
/**
* Create an empty dictionary.
*/
public PyDictionary() {
this(TYPE);
}
/**
* Create a dictionary of type with the specified initial capacity.
*/
public PyDictionary(PyType type, int capacity) {
super(type);
internalMap = new ConcurrentHashMap(capacity, Generic.CHM_LOAD_FACTOR,
Generic.CHM_CONCURRENCY_LEVEL);
}
/**
* For derived types
*/
public PyDictionary(PyType type) {
super(type);
internalMap = Generic.concurrentMap();
}
/**
* Create a new dictionary which is based on given map.
*/
public PyDictionary(Map map) {
this(TYPE, map);
}
public PyDictionary(ConcurrentMap backingMap, boolean useBackingMap) {
super(TYPE);
internalMap = backingMap;
}
public PyDictionary(PyType type, ConcurrentMap backingMap, boolean useBackingMap) {
super(type);
internalMap = backingMap;
}
/**
* Create a new dictionary which is populated with entries the given map.
*/
public PyDictionary(PyType type, Map map) {
this(type, Math.max((int) (map.size() / Generic.CHM_LOAD_FACTOR) + 1,
Generic.CHM_INITIAL_CAPACITY));
getMap().putAll(map);
}
/**
* Create a new dictionary without initializing table. Used for dictionary
* factories, with different backing maps, at the cost that it prevents us from making table be final.
*/
/* TODO we may want to revisit this API, but our chain calling of super makes this tough */
protected PyDictionary(PyType type, boolean initializeBacking) {
super(type);
if (initializeBacking) {
internalMap = Generic.concurrentMap();
} else {
internalMap = null; /* for later initialization */
}
}
/**
* Create a new dictionary with the element as content.
*
* @param elements
* The initial elements that is inserted in the dictionary. Even numbered elements
* are keys, odd numbered elements are values.
*/
public PyDictionary(PyObject elements[]) {
this();
ConcurrentMap map = getMap();
for (int i = 0; i < elements.length; i += 2) {
map.put(elements[i], elements[i + 1]);
}
}
@ExposedMethod(doc = BuiltinDocs.dict___init___doc)
@ExposedNew
protected final void dict___init__(PyObject[] args, String[] keywords) {
updateCommon(args, keywords, "dict");
}
public static PyObject fromkeys(PyObject keys) {
return fromkeys(keys, Py.None);
}
public static PyObject fromkeys(PyObject keys, PyObject value) {
return dict_fromkeys(TYPE, keys, value);
}
@ExposedClassMethod(defaults = "Py.None", doc = BuiltinDocs.dict_fromkeys_doc)
static PyObject dict_fromkeys(PyType type, PyObject keys, PyObject value) {
PyObject d = type.__call__();
for (PyObject o : keys.asIterable()) {
d.__setitem__(o, value);
}
return d;
}
@Override
public int __len__() {
return dict___len__();
}
@ExposedMethod(doc = BuiltinDocs.dict___len___doc)
final int dict___len__() {
return getMap().size();
}
@Override
public boolean __nonzero__() {
return getMap().size() != 0;
}
@Override
public PyObject __finditem__(int index) {
throw Py.TypeError("loop over non-sequence");
}
@Override
public PyObject __finditem__(PyObject key) {
return getMap().get(key);
}
@ExposedMethod(doc = BuiltinDocs.dict___getitem___doc)
protected final PyObject dict___getitem__(PyObject key) {
PyObject result = getMap().get(key);
if (result != null) {
return result;
}
/* Look up __missing__ method if we're a subclass. */
PyType type = getType();
if (type != TYPE) {
PyObject missing = type.lookup("__missing__");
if (missing != null) {
return missing.__get__(this, type).__call__(key);
}
}
throw Py.KeyError(key);
}
@Override
public void __setitem__(PyObject key, PyObject value) {
dict___setitem__(key, value);
}
@ExposedMethod(doc = BuiltinDocs.dict___setitem___doc)
final void dict___setitem__(PyObject key, PyObject value) {
getMap().put(key, value);
}
@Override
public void __delitem__(PyObject key) {
dict___delitem__(key);
}
@ExposedMethod(doc = BuiltinDocs.dict___delitem___doc)
final void dict___delitem__(PyObject key) {
Object ret = getMap().remove(key);
if (ret == null) {
throw Py.KeyError(key.toString());
}
}
@Override
public PyObject __iter__() {
return dict___iter__();
}
@ExposedMethod(doc = BuiltinDocs.dict___iter___doc)
final PyObject dict___iter__() {
return iterkeys();
}
@Override
public String toString() {
return dict_toString();
}
@ExposedMethod(names = {"__repr__", "__str__"}, doc = BuiltinDocs.dict___str___doc)
final String dict_toString() {
ThreadState ts = Py.getThreadState();
if (!ts.enterRepr(this)) {
return "{...}";
}
StringBuilder buf = new StringBuilder("{");
for (Entry entry : getMap().entrySet()) {
buf.append((entry.getKey()).__repr__().toString());
buf.append(": ");
buf.append((entry.getValue()).__repr__().toString());
buf.append(", ");
}
if (buf.length() > 1) {
buf.delete(buf.length() - 2, buf.length());
}
buf.append("}");
ts.exitRepr(this);
return buf.toString();
}
@Override
public PyObject __eq__(PyObject otherObj) {
return dict___eq__(otherObj);
}
@ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.dict___eq___doc)
final PyObject dict___eq__(PyObject otherObj) {
PyType thisType = getType();
PyType otherType = otherObj.getType();
if (otherType != thisType && !thisType.isSubType(otherType)
&& !otherType.isSubType(thisType) || otherType == PyObject.TYPE) {
return null;
}
PyDictionary other = (PyDictionary)otherObj;
int an = getMap().size();
int bn = other.getMap().size();
if (an != bn) {
return Py.False;
}
PyList akeys = keys();
for (int i = 0; i < an; i++) {
PyObject akey = akeys.pyget(i);
PyObject bvalue = other.__finditem__(akey);
if (bvalue == null) {
return Py.False;
}
PyObject avalue = __finditem__(akey);
if (!avalue._eq(bvalue).__nonzero__()) {
return Py.False;
}
}
return Py.True;
}
@Override
public PyObject __ne__(PyObject otherObj) {
return dict___ne__(otherObj);
}
@ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.dict___ne___doc)
final PyObject dict___ne__(PyObject otherObj) {
PyObject eq_result = __eq__(otherObj);
if (eq_result == null) {
return null;
}
return eq_result.__not__();
}
@ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.dict___lt___doc)
final PyObject dict___lt__(PyObject otherObj) {
int result = __cmp__(otherObj);
if (result == -2) {
return null;
}
return result < 0 ? Py.True : Py.False;
}
@ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.dict___gt___doc)
final PyObject dict___gt__(PyObject otherObj) {
int result = __cmp__(otherObj);
if (result == -2) {
return null;
}
return result > 0 ? Py.True : Py.False;
}
@ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.dict___le___doc)
final PyObject dict___le__(PyObject otherObj) {
int result = __cmp__(otherObj);
if (result == -2) {
return null;
}
return result <= 0 ? Py.True : Py.False;
}
@ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.dict___ge___doc)
final PyObject dict___ge__(PyObject otherObj) {
int result = __cmp__(otherObj);
if (result == -2) {
return null;
}
return result >= 0 ? Py.True : Py.False;
}
@Override
public int __cmp__(PyObject otherObj) {
return dict___cmp__(otherObj);
}
@ExposedMethod(type = MethodType.CMP, doc = BuiltinDocs.dict___cmp___doc)
final int dict___cmp__(PyObject otherObj) {
PyType thisType = getType();
PyType otherType = otherObj.getType();
if (otherType != thisType && !thisType.isSubType(otherType)
&& !otherType.isSubType(thisType) || otherType == PyObject.TYPE) {
return -2;
}
PyDictionary other = (PyDictionary)otherObj;
int an = getMap().size();
int bn = other.getMap().size();
if (an < bn) {
return -1;
}
if (an > bn) {
return 1;
}
PyList akeys = keys();
PyList bkeys = other.keys();
akeys.sort();
bkeys.sort();
for (int i = 0; i < bn; i++) {
PyObject akey = akeys.pyget(i);
PyObject bkey = bkeys.pyget(i);
int c = akey._cmp(bkey);
if (c != 0) {
return c;
}
PyObject avalue = __finditem__(akey);
PyObject bvalue = other.__finditem__(bkey);
if (avalue == null) {
if (bvalue == null) {
continue;
}
return -3;
} else if (bvalue == null) {
return -3;
}
c = avalue._cmp(bvalue);
if (c != 0) {
return c;
}
}
return 0;
}
/**
* Return true if the key exist in the dictionary.
*/
public boolean has_key(PyObject key) {
return dict_has_key(key);
}
@ExposedMethod(doc = BuiltinDocs.dict_has_key_doc)
final boolean dict_has_key(PyObject key) {
return getMap().containsKey(key);
}
@Override
public boolean __contains__(PyObject o) {
return dict___contains__(o);
}
@ExposedMethod(doc = BuiltinDocs.dict___contains___doc)
final boolean dict___contains__(PyObject o) {
return dict_has_key(o);
}
/**
* Return this[key] if the key exists in the mapping, defaultObj is returned
* otherwise.
*
* @param key the key to lookup in the dictionary.
* @param defaultObj the value to return if the key does not exists in the mapping.
*/
public PyObject get(PyObject key, PyObject defaultObj) {
return dict_get(key, defaultObj);
}
@ExposedMethod(defaults = "Py.None", doc = BuiltinDocs.dict_get_doc)
final PyObject dict_get(PyObject key, PyObject defaultObj) {
PyObject o = getMap().get(key);
return o == null ? defaultObj : o;
}
/**
* Return this[key] if the key exists in the mapping, None
* is returned otherwise.
*
* @param key the key to lookup in the dictionary.
*/
public PyObject get(PyObject key) {
return dict_get(key, Py.None);
}
/**
* Return a shallow copy of the dictionary.
*/
public PyDictionary copy() {
return dict_copy();
}
@ExposedMethod(doc = BuiltinDocs.dict_copy_doc)
final PyDictionary dict_copy() {
return new PyDictionary(getMap()); /* no need to clone() */
}
/**
* Remove all items from the dictionary.
*/
public void clear() {
dict_clear();
}
@ExposedMethod(doc = BuiltinDocs.dict_clear_doc)
final void dict_clear() {
getMap().clear();
}
/**
* Insert all the key:value pairs from d into
* this dictionary.
*/
public void update(PyObject other) {
dict_update(new PyObject[] {other}, Py.NoKeywords);
}
@ExposedMethod(doc = BuiltinDocs.dict_update_doc)
final void dict_update(PyObject[] args, String[] keywords) {
updateCommon(args, keywords, "update");
}
public void updateCommon(PyObject[] args, String[] keywords, String methName) {
int nargs = args.length - keywords.length;
if (nargs > 1) {
throw PyBuiltinCallable.DefaultInfo.unexpectedCall(nargs, false, methName, 0, 1);
}
if (nargs == 1) {
PyObject arg = args[0];
Object proxy = arg.getJavaProxy();
if (proxy instanceof Map) {
merge((Map)proxy);
}
else if (arg.__findattr__("keys") != null) {
merge(arg);
} else {
mergeFromSeq(arg);
}
}
for (int i = 0; i < keywords.length; i++) {
dict___setitem__(Py.newString(keywords[i]), args[nargs + i]);
}
}
private void merge(Map
Ads help maintain this website.