Skip to content

Commit 5c3a945

Browse files
committed
[GR-23216] Make test_dictviews pass - update() and fromkeys().
PullRequest: graalpython/1014
2 parents 6778028 + 43e5e0e commit 5c3a945

File tree

13 files changed

+716
-276
lines changed

13 files changed

+716
-276
lines changed

graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/datatype/DictTests.java

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2018, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2020, Oracle and/or its affiliates.
33
* Copyright (c) 2013, Regents of the University of California
44
*
55
* All rights reserved.
@@ -54,36 +54,78 @@ public void del() {
5454
assertPrints("{3: 4}\n", source);
5555
}
5656

57+
@Test
58+
public void dict() {
59+
String source = "print(type({}))\n" +
60+
"print(type(iter({1: 'a', 2: 'b'})))\n" +
61+
"print({})\n" +
62+
"print({1: 'a'})\n" +
63+
"print({1: 'a', 2: 'b'})\n";
64+
65+
assertPrints("<class 'dict'>\n" +
66+
"<class 'dict_keyiterator'>\n" +
67+
"{}\n" +
68+
"{1: 'a'}\n" +
69+
"{1: 'a', 2: 'b'}\n", source);
70+
71+
source = "d = {1: 1}\n" +
72+
"d.__setitem__(2, d)\n" +
73+
"print(d)\n";
74+
assertPrints("{1: 1, 2: {...}}\n", source);
75+
}
76+
5777
@Test
5878
public void dictViewKeys() {
5979
String source = "print(type({}.keys()))\n" +
6080
"print(type(iter({1: 'a', 2: 'b'}.keys())))\n" +
81+
"print({}.keys())\n" +
82+
"print({1: 'a'}.keys())\n" +
6183
"print({1: 'a', 2: 'b'}.keys())\n";
6284

6385
assertPrints("<class 'dict_keys'>\n" +
64-
"<class 'dict_keysiterator'>\n" +
86+
"<class 'dict_keyiterator'>\n" +
87+
"dict_keys([])\n" +
88+
"dict_keys([1])\n" +
6589
"dict_keys([1, 2])\n", source);
6690
}
6791

6892
@Test
6993
public void dictViewValues() {
7094
String source = "print(type({}.values()))\n" +
7195
"print(type(iter({1: 'a', 2: 'b'}.values())))\n" +
96+
"print({}.values())\n" +
97+
"print({1: 'a'}.values())\n" +
7298
"print({1: 'a', 2: 'b'}.values())\n";
7399

74100
assertPrints("<class 'dict_values'>\n" +
75-
"<class 'dict_valuesiterator'>\n" +
101+
"<class 'dict_valueiterator'>\n" +
102+
"dict_values([])\n" +
103+
"dict_values(['a'])\n" +
76104
"dict_values(['a', 'b'])\n", source);
105+
106+
source = "d = {1: 1}\n" +
107+
"d.__setitem__(2, d)\n" +
108+
"print(d.values())\n";
109+
assertPrints("dict_values([1, {1: 1, 2: {...}}])\n", source);
77110
}
78111

79112
@Test
80113
public void dictViewItems() {
81114
String source = "print(type({}.items()))\n" +
82115
"print(type(iter({1: 'a', 2: 'b'}.items())))\n" +
116+
"print({}.items())\n" +
117+
"print({1: 'a'}.items())\n" +
83118
"print({1: 'a', 2: 'b'}.items())\n";
84119

85120
assertPrints("<class 'dict_items'>\n" +
86-
"<class 'dict_itemsiterator'>\n" +
121+
"<class 'dict_itemiterator'>\n" +
122+
"dict_items([])\n" +
123+
"dict_items([(1, 'a')])\n" +
87124
"dict_items([(1, 'a'), (2, 'b')])\n", source);
125+
126+
source = "d = {1: 1}\n" +
127+
"d.__setitem__(2, d)\n" +
128+
"print(d.items())\n";
129+
assertPrints("dict_items([(1, 1), (2, {1: 1, 2: {...}})])\n", source);
88130
}
89131
}

graalpython/com.oracle.graal.python.test/src/tests/test_dict.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,24 @@ def test_fromkeys():
103103
assert set(d.keys()) == {'a', 'b', 'c'}
104104
assert set(d.values()) == {o}
105105

106+
class preset(dict):
107+
def __init__(self):
108+
self['a'] = 1
109+
assert preset.fromkeys(['b']) == {'a':1, 'b':None}
110+
111+
class morethanoneinitargraiseserror(dict):
112+
def __init__(self, anotherArg):
113+
self.__init__()
114+
assert_raises(TypeError, morethanoneinitargraiseserror.fromkeys, [1])
115+
116+
class nosetitem:
117+
pass
118+
119+
class nosetitem2(dict):
120+
def __new__(cls):
121+
return nosetitem()
122+
assert_raises(TypeError, nosetitem2.fromkeys, [1])
123+
106124

107125
def test_init():
108126
d = dict(a=1, b=2, c=3)

graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_dict.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*graalpython.lib-python.3.test.test_dict.DictTest.test_eq
1818
*graalpython.lib-python.3.test.test_dict.DictTest.test_equal_operator_modifying_operand
1919
*graalpython.lib-python.3.test.test_dict.DictTest.test_errors_in_view_containment_check
20+
*graalpython.lib-python.3.test.test_dict.DictTest.test_fromkeys
2021
*graalpython.lib-python.3.test.test_dict.DictTest.test_fromkeys_operator_modifying_dict_operand
2122
*graalpython.lib-python.3.test.test_dict.DictTest.test_fromkeys_operator_modifying_set_operand
2223
*graalpython.lib-python.3.test.test_dict.DictTest.test_get
@@ -47,6 +48,7 @@
4748
*graalpython.lib-python.3.test.test_dict.DictTest.test_track_dynamic
4849
*graalpython.lib-python.3.test.test_dict.DictTest.test_track_literals
4950
*graalpython.lib-python.3.test.test_dict.DictTest.test_track_subtypes
51+
*graalpython.lib-python.3.test.test_dict.DictTest.test_update
5052
*graalpython.lib-python.3.test.test_dict.DictTest.test_values
5153
*graalpython.lib-python.3.test.test_dict.GeneralMappingTests.test_bool
5254
*graalpython.lib-python.3.test.test_dict.GeneralMappingTests.test_constructor
@@ -55,6 +57,7 @@
5557
*graalpython.lib-python.3.test.test_dict.GeneralMappingTests.test_len
5658
*graalpython.lib-python.3.test.test_dict.GeneralMappingTests.test_popitem
5759
*graalpython.lib-python.3.test.test_dict.GeneralMappingTests.test_setdefault
60+
*graalpython.lib-python.3.test.test_dict.GeneralMappingTests.test_update
5861
*graalpython.lib-python.3.test.test_dict.GeneralMappingTests.test_values
5962
*graalpython.lib-python.3.test.test_dict.SubclassMappingTests.test_bool
6063
*graalpython.lib-python.3.test.test_dict.SubclassMappingTests.test_constructor
@@ -63,4 +66,5 @@
6366
*graalpython.lib-python.3.test.test_dict.SubclassMappingTests.test_len
6467
*graalpython.lib-python.3.test.test_dict.SubclassMappingTests.test_popitem
6568
*graalpython.lib-python.3.test.test_dict.SubclassMappingTests.test_setdefault
69+
*graalpython.lib-python.3.test.test_dict.SubclassMappingTests.test_update
6670
*graalpython.lib-python.3.test.test_dict.SubclassMappingTests.test_values

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Python3Core.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
import com.oracle.graal.python.builtins.objects.dict.DictBuiltins;
107107
import com.oracle.graal.python.builtins.objects.dict.DictItemsIteratorBuiltins;
108108
import com.oracle.graal.python.builtins.objects.dict.DictKeysIteratorBuiltins;
109+
import com.oracle.graal.python.builtins.objects.dict.DictReprBuiltin;
109110
import com.oracle.graal.python.builtins.objects.dict.DictValuesBuiltins;
110111
import com.oracle.graal.python.builtins.objects.dict.DictValuesIteratorBuiltins;
111112
import com.oracle.graal.python.builtins.objects.dict.DictViewBuiltins;
@@ -209,7 +210,6 @@ private static final String[] initializeCoreFiles() {
209210
"_descriptor",
210211
"object",
211212
"sys",
212-
"dict",
213213
"_mappingproxy",
214214
"str",
215215
"type",
@@ -318,6 +318,7 @@ private static final PythonBuiltins[] initializeBuiltins() {
318318
new ForeignObjectBuiltins(),
319319
new ListBuiltins(),
320320
new DictBuiltins(),
321+
new DictReprBuiltin(),
321322
new DictViewBuiltins(),
322323
new DictValuesBuiltins(),
323324
new DictKeysIteratorBuiltins(),

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,12 @@ public enum PythonBuiltinClassType implements LazyPythonClass {
6969
PCell("cell"),
7070
PComplex("complex", BuiltinNames.BUILTINS),
7171
PDict("dict", BuiltinNames.BUILTINS),
72-
PDictKeysView("dict_keys"),
73-
PDictItemsIterator("dict_itemsiterator"),
74-
PDictItemsView("dict_items"),
75-
PDictKeysIterator("dict_keysiterator"),
76-
PDictValuesIterator("dict_valuesiterator"),
77-
PDictValuesView("dict_values"),
72+
PDictKeysView(BuiltinNames.DICT_KEYS),
73+
PDictItemsIterator(BuiltinNames.DICT_ITEMITERATOR),
74+
PDictItemsView(BuiltinNames.DICT_ITEMS),
75+
PDictKeysIterator(BuiltinNames.DICT_KEYITERATOR),
76+
PDictValuesIterator(BuiltinNames.DICT_VALUEITERATOR),
77+
PDictValuesView(BuiltinNames.DICT_VALUES),
7878
PEllipsis("ellipsis"),
7979
PEnumerate("enumerate", BuiltinNames.BUILTINS),
8080
PMap("map", BuiltinNames.BUILTINS),

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinConstructors.java

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@
3434
import static com.oracle.graal.python.nodes.BuiltinNames.CLASSMETHOD;
3535
import static com.oracle.graal.python.nodes.BuiltinNames.COMPLEX;
3636
import static com.oracle.graal.python.nodes.BuiltinNames.DICT;
37+
import static com.oracle.graal.python.nodes.BuiltinNames.DICT_ITEMS;
38+
import static com.oracle.graal.python.nodes.BuiltinNames.DICT_VALUES;
39+
import static com.oracle.graal.python.nodes.BuiltinNames.DICT_KEYS;
40+
import static com.oracle.graal.python.nodes.BuiltinNames.DICT_ITEMITERATOR;
41+
import static com.oracle.graal.python.nodes.BuiltinNames.DICT_KEYITERATOR;
42+
import static com.oracle.graal.python.nodes.BuiltinNames.DICT_VALUEITERATOR;
3743
import static com.oracle.graal.python.nodes.BuiltinNames.ENUMERATE;
3844
import static com.oracle.graal.python.nodes.BuiltinNames.FLOAT;
3945
import static com.oracle.graal.python.nodes.BuiltinNames.FROZENSET;
@@ -2670,63 +2676,63 @@ public PNone module(Object cls) {
26702676
}
26712677
}
26722678

2673-
@Builtin(name = "dict_keys", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PDictKeysView, isPublic = false)
2679+
@Builtin(name = DICT_KEYS, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PDictKeysView, isPublic = false)
26742680
@GenerateNodeFactory
26752681
public abstract static class DictKeysTypeNode extends PythonBuiltinNode {
26762682
@SuppressWarnings("unused")
26772683
@Specialization
26782684
public Object dictKeys(Object args, Object kwargs) {
2679-
throw raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "'dict_keys'");
2685+
throw raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, parentheses(DICT_KEYS));
26802686
}
26812687
}
26822688

2683-
@Builtin(name = "dict_keysiterator", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PDictKeysIterator, isPublic = false)
2689+
@Builtin(name = DICT_KEYITERATOR, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PDictKeysIterator, isPublic = false)
26842690
@GenerateNodeFactory
26852691
public abstract static class DictKeysIteratorTypeNode extends PythonBuiltinNode {
26862692
@SuppressWarnings("unused")
26872693
@Specialization
26882694
public Object dictKeys(Object args, Object kwargs) {
2689-
throw raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "'dict_keysiterator'");
2695+
throw raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, parentheses(DICT_KEYITERATOR));
26902696
}
26912697
}
26922698

2693-
@Builtin(name = "dict_values", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PDictValuesView, isPublic = false)
2699+
@Builtin(name = DICT_VALUES, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PDictValuesView, isPublic = false)
26942700
@GenerateNodeFactory
26952701
public abstract static class DictValuesTypeNode extends PythonBuiltinNode {
26962702
@SuppressWarnings("unused")
26972703
@Specialization
26982704
public Object dictKeys(Object args, Object kwargs) {
2699-
throw raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "'dict_values'");
2705+
throw raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, parentheses(DICT_VALUES));
27002706
}
27012707
}
27022708

2703-
@Builtin(name = "dict_valuesiterator", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PDictValuesIterator, isPublic = false)
2709+
@Builtin(name = DICT_VALUEITERATOR, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PDictValuesIterator, isPublic = false)
27042710
@GenerateNodeFactory
27052711
public abstract static class DictValuesIteratorTypeNode extends PythonBuiltinNode {
27062712
@SuppressWarnings("unused")
27072713
@Specialization
27082714
public Object dictKeys(Object args, Object kwargs) {
2709-
throw raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "'dict_valuesiterator'");
2715+
throw raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, parentheses(DICT_VALUEITERATOR));
27102716
}
27112717
}
27122718

2713-
@Builtin(name = "dict_items", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PDictItemsView, isPublic = false)
2719+
@Builtin(name = DICT_ITEMS, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PDictItemsView, isPublic = false)
27142720
@GenerateNodeFactory
27152721
public abstract static class DictItemsTypeNode extends PythonBuiltinNode {
27162722
@SuppressWarnings("unused")
27172723
@Specialization
27182724
public Object dictKeys(Object args, Object kwargs) {
2719-
throw raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "'dict_items'");
2725+
throw raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, parentheses(DICT_ITEMS));
27202726
}
27212727
}
27222728

2723-
@Builtin(name = "dict_itemsiterator", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PDictItemsIterator, isPublic = false)
2729+
@Builtin(name = DICT_ITEMITERATOR, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PDictItemsIterator, isPublic = false)
27242730
@GenerateNodeFactory
27252731
public abstract static class DictItemsIteratorTypeNode extends PythonBuiltinNode {
27262732
@SuppressWarnings("unused")
27272733
@Specialization
27282734
public Object dictKeys(Object args, Object kwargs) {
2729-
throw raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "'dict_itemsiterator'");
2735+
throw raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, parentheses(DICT_ITEMITERATOR));
27302736
}
27312737
}
27322738

@@ -3182,4 +3188,9 @@ PMap doit(LazyPythonClass self, @SuppressWarnings("unused") Object[] args, @Supp
31823188
return factory().createMap(self);
31833189
}
31843190
}
3191+
3192+
@TruffleBoundary
3193+
private static String parentheses(String str) {
3194+
return new StringBuilder("'").append(str).append("'").toString();
3195+
}
31853196
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/HashingCollectionNodes.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodesFactory.GetDictStorageNodeGen;
4444
import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodesFactory.LenNodeGen;
45+
import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodesFactory.SetDictStorageNodeGen;
4546
import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodesFactory.SetItemNodeGen;
4647
import com.oracle.graal.python.nodes.PGuards;
4748
import com.oracle.graal.python.nodes.PNodeWithContext;
@@ -131,4 +132,30 @@ public static GetDictStorageNode getUncached() {
131132
return GetDictStorageNodeGen.getUncached();
132133
}
133134
}
135+
136+
@ImportStatic({PGuards.class})
137+
@GenerateUncached
138+
public abstract static class SetDictStorageNode extends PNodeWithContext {
139+
140+
public abstract void execute(PHashingCollection c, HashingStorage storage);
141+
142+
@Specialization(limit = "4", guards = {"c.getClass() == cachedClass"})
143+
void setStorageCached(PHashingCollection c, HashingStorage storage,
144+
@Cached("c.getClass()") Class<? extends PHashingCollection> cachedClass) {
145+
cachedClass.cast(c).setDictStorage(storage);
146+
}
147+
148+
@Specialization(replaces = "setStorageCached")
149+
static void getStorageGeneric(PHashingCollection c, HashingStorage storage) {
150+
c.setDictStorage(storage);
151+
}
152+
153+
public static SetDictStorageNode create() {
154+
return SetDictStorageNodeGen.create();
155+
}
156+
157+
public static SetDictStorageNode getUncached() {
158+
return SetDictStorageNodeGen.getUncached();
159+
}
160+
}
134161
}

0 commit comments

Comments
 (0)