Skip to content

Commit 75a621d

Browse files
committed
handle invalid dict c-tor arguments
1 parent f34b50d commit 75a621d

File tree

2 files changed

+46
-3
lines changed
  • graalpython

2 files changed

+46
-3
lines changed

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,18 @@ def test_init3():
165165
assert False, "expected ValueError"
166166
except ValueError as e:
167167
assert "dictionary update sequence element #4 has length 1; 2 is required" == str(e), "invalid error message"
168+
169+
try:
170+
dict("5")
171+
assert False, "expected ValueError"
172+
except ValueError as e:
173+
assert "dictionary update sequence element #0 has length 1; 2 is required" == str(e), "invalid error message"
174+
175+
try:
176+
dict([("a", 1), ("b", 2), ("c", 3), ("d", 4), "5"])
177+
assert False, "expected ValueError"
178+
except ValueError as e:
179+
assert "dictionary update sequence element #4 has length 1; 2 is required" == str(e), "invalid error message"
168180

169181

170182
def test_init4():
@@ -198,7 +210,13 @@ def __len__(self):
198210
assert set(d.keys()) == key_set, "unexpected keys: %s" % str(d.keys())
199211
assert set(d.values()) == {97, 98, 99, 100}, "unexpected values: %s" % str(d.values())
200212

201-
213+
def test_init6():
214+
try:
215+
dict(1)
216+
assert False, "expected TypeError"
217+
except TypeError as e:
218+
assert "'int' object is not iterable" == str(e), "invalid error message"
219+
202220
def test_init_kwargs():
203221
kwargs = {'ONE': 'one', 'TWO': 'two'}
204222
d = dict([(1, 11), (2, 22)], **kwargs)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DictBuiltins.java

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
import com.oracle.graal.python.builtins.objects.type.LazyPythonClass;
7474
import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass;
7575
import com.oracle.graal.python.nodes.ErrorMessages;
76+
import com.oracle.graal.python.nodes.PGuards;
7677
import com.oracle.graal.python.nodes.PRaiseNode;
7778
import com.oracle.graal.python.nodes.SpecialMethodNames;
7879
import static com.oracle.graal.python.nodes.SpecialMethodNames.__MISSING__;
@@ -92,6 +93,7 @@
9293
import com.oracle.graal.python.nodes.util.CastToJavaStringNode;
9394
import com.oracle.graal.python.runtime.PythonCore;
9495
import com.oracle.graal.python.runtime.exception.PException;
96+
import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError;
9597
import com.oracle.graal.python.runtime.sequence.PSequence;
9698
import com.oracle.truffle.api.CompilerDirectives;
9799
import com.oracle.truffle.api.dsl.Cached;
@@ -134,13 +136,28 @@ private HashingStorage.InitNode getInitNode() {
134136
return initNode;
135137
}
136138

137-
@Specialization(guards = "args.length == 1")
139+
@Specialization(guards = {"args.length == 1", "firstArgIterable(args, lib)", "!firstArgString(args)"})
138140
Object doVarargs(VirtualFrame frame, PDict self, Object[] args, PKeyword[] kwargs,
139-
@Cached SetDictStorageNode setStorage) {
141+
@Cached SetDictStorageNode setStorage,
142+
@SuppressWarnings("unused") @CachedLibrary(limit = "1") PythonObjectLibrary lib) {
140143
setStorage.execute(self, getInitNode().execute(frame, args[0], kwargs));
141144
return PNone.NONE;
142145
}
143146

147+
@SuppressWarnings("unused")
148+
@Specialization(guards = {"args.length == 1", "!firstArgIterable(args, lib)"})
149+
Object doVarargsNotIterable(Object self, Object[] args, @SuppressWarnings("unused") PKeyword[] kwargs,
150+
@CachedLibrary(limit = "1") PythonObjectLibrary lib) {
151+
throw raise(TypeError, ErrorMessages.OBJ_NOT_ITERABLE, args[0]);
152+
}
153+
154+
@SuppressWarnings("unused")
155+
@Specialization(guards = {"args.length == 1", "firstArgString(args)"})
156+
Object doString(Object self, Object[] args, PKeyword[] kwargs,
157+
@Cached PRaiseNode raise) {
158+
throw raise.raise(ValueError, ErrorMessages.DICT_UPDATE_SEQ_ELEM_HAS_LENGTH_2_REQUIRED, 0, 1);
159+
}
160+
144161
@Specialization(guards = "args.length == 0")
145162
Object doKeywords(VirtualFrame frame, PDict self, @SuppressWarnings("unused") Object[] args, PKeyword[] kwargs,
146163
@Cached SetDictStorageNode setStorage) {
@@ -152,6 +169,14 @@ Object doKeywords(VirtualFrame frame, PDict self, @SuppressWarnings("unused") Ob
152169
Object doGeneric(@SuppressWarnings("unused") PDict self, Object[] args, @SuppressWarnings("unused") PKeyword[] kwargs) {
153170
throw raise(TypeError, ErrorMessages.EXPECTED_AT_MOST_D_ARGS_GOT_D, "dict", 1, args.length);
154171
}
172+
173+
protected boolean firstArgIterable(Object[] args, PythonObjectLibrary lib) {
174+
return lib.isIterable(args[0]);
175+
}
176+
177+
protected boolean firstArgString(Object[] args) {
178+
return PGuards.isString(args[0]);
179+
}
155180
}
156181

157182
// setdefault(key[, default])

0 commit comments

Comments
 (0)