Skip to content

Commit 9fb19f4

Browse files
committed
Improving code to better handle kwArgs and args.
Enhancing Javadoc for KeywordArguments. Removing mockup objects from the Argument tests.
1 parent 2abcd5a commit 9fb19f4

File tree

4 files changed

+142
-267
lines changed

4 files changed

+142
-267
lines changed

graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/interop/ArgsKwArgsTest.java

Lines changed: 36 additions & 228 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
import org.graalvm.polyglot.proxy.ProxyHashMap;
4949
import org.graalvm.polyglot.proxy.ProxyIterator;
5050
import org.graalvm.polyglot.proxy.ProxyObject;
51+
import org.graalvm.python.embedding.KeywordArguments;
52+
import org.graalvm.python.embedding.PositionalArguments;
5153
import org.junit.After;
5254
import org.junit.Before;
5355
import org.junit.Test;
@@ -80,201 +82,6 @@ private Value run(String evalString) {
8082
return context.eval("python", evalString);
8183
}
8284

83-
private static final class LazyArray implements ProxyArray {
84-
85-
private final Iterator<?> it;
86-
private long at;
87-
88-
LazyArray(Iterator<?> it) {
89-
this.it = it;
90-
this.at = 0;
91-
}
92-
93-
@Override
94-
public Object get(long index) {
95-
if (index == at) {
96-
at++;
97-
return it.next();
98-
}
99-
return null;
100-
}
101-
102-
@Override
103-
public void set(long index, Value value) {
104-
throw new UnsupportedOperationException();
105-
}
106-
107-
@Override
108-
public boolean remove(long index) {
109-
throw new UnsupportedOperationException();
110-
}
111-
112-
@Override
113-
public long getSize() {
114-
return it.hasNext() ? at + 1 : at;
115-
}
116-
}
117-
118-
private static class MockPositinalArgs implements ProxyArray, ProxyObject {
119-
120-
private static final String MEMBER_KEY = "org.graalvm.python.embedding.PositionalArguments.is_positional_arguments";
121-
122-
private final Object[] values;
123-
124-
private MockPositinalArgs(Object... values) {
125-
this.values = values;
126-
}
127-
128-
@Override
129-
public Object get(long index) {
130-
return this.values[(int) index];
131-
}
132-
133-
@Override
134-
public void set(long index, Value value) {
135-
throw new UnsupportedOperationException();
136-
}
137-
138-
@Override
139-
public long getSize() {
140-
return values.length;
141-
}
142-
143-
@Override
144-
public Object getMember(String key) {
145-
if (MEMBER_KEY.equals(key)) {
146-
return true;
147-
}
148-
throw new UnsupportedOperationException();
149-
}
150-
151-
@Override
152-
public Object getMemberKeys() {
153-
throw new UnsupportedOperationException();
154-
}
155-
156-
@Override
157-
public boolean hasMember(String key) {
158-
return MEMBER_KEY.equals(key);
159-
}
160-
161-
@Override
162-
public void putMember(String key, Value value) {
163-
throw new UnsupportedOperationException();
164-
}
165-
}
166-
167-
private static class MockKwArgs implements ProxyHashMap, ProxyObject {
168-
public static final String MEMBER_KEY = "org.graalvm.python.embedding.KeywordArguments.is_keyword_arguments";
169-
private final Map<String, Object> kwArgs;
170-
171-
private MockKwArgs(Map<String, Object> kwArgs) {
172-
this.kwArgs = kwArgs;
173-
}
174-
175-
@Override
176-
public long getHashSize() {
177-
return kwArgs.size();
178-
}
179-
180-
@Override
181-
public boolean hasHashEntry(Value key) {
182-
String unboxedKey = unboxKey(key);
183-
return kwArgs.containsKey(unboxedKey);
184-
}
185-
186-
@Override
187-
public Object getHashValue(Value key) {
188-
Object unboxedKey = unboxKey(key);
189-
return kwArgs.get(unboxedKey);
190-
}
191-
192-
@Override
193-
public void putHashEntry(Value key, Value value) {
194-
String unboxedKey = unboxKey(key);
195-
kwArgs.put(unboxedKey, value.isHostObject() ? value.asHostObject() : value);
196-
}
197-
198-
@Override
199-
public Object getHashEntriesIterator() {
200-
Iterator<Map.Entry<String, Object>> entryIterator = kwArgs.entrySet().iterator();
201-
return new ProxyIterator() {
202-
@Override
203-
public boolean hasNext() {
204-
return entryIterator.hasNext();
205-
}
206-
207-
@Override
208-
public Object getNext() throws NoSuchElementException, UnsupportedOperationException {
209-
return new ArgsKwArgsTest.MockKwArgs.ProxyEntryImpl(entryIterator.next());
210-
}
211-
};
212-
}
213-
214-
@Override
215-
public Object getMember(String key) {
216-
if (MEMBER_KEY.equals(key)) {
217-
return true;
218-
}
219-
throw new UnsupportedOperationException();
220-
}
221-
222-
@Override
223-
public Object getMemberKeys() {
224-
throw new UnsupportedOperationException();
225-
}
226-
227-
@Override
228-
public boolean hasMember(String key) {
229-
return MEMBER_KEY.equals(key);
230-
}
231-
232-
@Override
233-
public void putMember(String key, Value value) {
234-
throw new UnsupportedOperationException();
235-
}
236-
237-
private static String unboxKey(Value key) {
238-
return key.asString();
239-
}
240-
241-
private class ProxyEntryImpl implements ProxyArray {
242-
243-
private Map.Entry<String, Object> mapEntry;
244-
245-
ProxyEntryImpl(Map.Entry<String, Object> mapEntry) {
246-
this.mapEntry = mapEntry;
247-
}
248-
249-
@Override
250-
public Object get(long index) {
251-
if (index == 0L) {
252-
return mapEntry.getKey();
253-
} else if (index == 1L) {
254-
return mapEntry.getValue();
255-
} else {
256-
throw new ArrayIndexOutOfBoundsException();
257-
}
258-
}
259-
260-
@Override
261-
public void set(long index, Value value) {
262-
if (index == 0L) {
263-
throw new UnsupportedOperationException();
264-
} else if (index == 1L) {
265-
ArgsKwArgsTest.MockKwArgs.this.kwArgs.put(mapEntry.getKey(), value.isHostObject() ? value.asHostObject() : value);
266-
} else {
267-
throw new ArrayIndexOutOfBoundsException();
268-
}
269-
}
270-
271-
@Override
272-
public long getSize() {
273-
return 2;
274-
}
275-
}
276-
}
277-
27885
@Test
27986
public void testPositionalArgs01() {
28087
// @formatter:off
@@ -290,12 +97,12 @@ def sum(*args):
29097
assertEquals(0, module.invokeMember("sum").asInt());
29198
assertEquals(22, module.invokeMember("sum", 22).asInt());
29299
assertEquals(60, module.invokeMember("sum",10, 20, 30).asInt());
293-
assertEquals(6, module.invokeMember("sum", new ArgsKwArgsTest.MockPositinalArgs(1,2,3)).asInt());
100+
assertEquals(6, module.invokeMember("sum", PositionalArguments.of(1,2,3)).asInt());
294101

295-
assertEquals(0, module.invokeMember("sum", new ArgsKwArgsTest.MockPositinalArgs()).asInt());
296-
assertEquals(0, module.invokeMember("sum", new ArgsKwArgsTest.MockKwArgs(Map.of())).asInt());
102+
assertEquals(0, module.invokeMember("sum", PositionalArguments.of()).asInt());
103+
assertEquals(0, module.invokeMember("sum", KeywordArguments.from(Map.of())).asInt());
297104

298-
PolyglotException pe = assertThrows(PolyglotException.class, () -> {assertEquals(0, module.invokeMember("sum", new ArgsKwArgsTest.MockKwArgs(Map.of("one", 1))).asInt());});
105+
PolyglotException pe = assertThrows(PolyglotException.class, () -> {assertEquals(0, module.invokeMember("sum", KeywordArguments.of("one", 1)).asInt());});
299106
assertEquals("TypeError: sum() got an unexpected keyword argument 'one'", pe.getMessage());
300107

301108
}
@@ -317,13 +124,13 @@ def text(a, *args):
317124
assertEquals("a=0,", module.invokeMember("text", 0).asString());
318125
assertEquals("a=22,args[0]=33,", module.invokeMember("text", 22,33).asString());
319126
assertEquals("a='hello',args[0]=ahoj,args[1]=cau,", module.invokeMember("text","hello", "ahoj", "cau").asString());
320-
assertEquals("a='6',args[0]=1,args[1]=2,args[2]=3,", module.invokeMember("text", "6", new ArgsKwArgsTest.MockPositinalArgs(1,2,3)).asString());
321-
assertEquals("a=1,args[0]=2,args[1]=3,", module.invokeMember("text",new ArgsKwArgsTest.MockPositinalArgs(1,2,3)).asString());
322-
assertEquals("a=1,", module.invokeMember("text",new ArgsKwArgsTest.MockPositinalArgs(1)).asString());
127+
assertEquals("a='6',args[0]=1,args[1]=2,args[2]=3,", module.invokeMember("text", "6", PositionalArguments.of(1,2,3)).asString());
128+
assertEquals("a=1,args[0]=2,args[1]=3,", module.invokeMember("text", PositionalArguments.of(1,2,3)).asString());
129+
assertEquals("a=1,", module.invokeMember("text", PositionalArguments.of(1)).asString());
323130

324-
assertEquals("a=1,", module.invokeMember("text", new ArgsKwArgsTest.MockKwArgs(Map.of("a", 1))).asString());
131+
assertEquals("a=1,", module.invokeMember("text", KeywordArguments.of("a", 1)).asString());
325132

326-
PolyglotException pe = assertThrows(PolyglotException.class, () -> {module.invokeMember("text", new ArgsKwArgsTest.MockKwArgs(Map.of("a", 1, "b", 2)));});
133+
PolyglotException pe = assertThrows(PolyglotException.class, () -> {module.invokeMember("text", KeywordArguments.of("a", 1, "b", 2));});
327134
assertEquals("TypeError: text() got an unexpected keyword argument 'b'", pe.getMessage());
328135
}
329136

@@ -344,22 +151,23 @@ def text(a,b=44, *args):
344151
assertEquals("a=0,b=44,", module.invokeMember("text", 0).asString());
345152
assertEquals("a=22,b=33,", module.invokeMember("text", 22,33).asString());
346153
assertEquals("a='hello',b='ahoj',args[0]=cau,", module.invokeMember("text","hello", "ahoj", "cau").asString());
347-
assertEquals("a='6',b=1,args[0]=2,args[1]=3,", module.invokeMember("text", "6", new ArgsKwArgsTest.MockPositinalArgs(1,2,3)).asString());
348-
assertEquals("a=1,b=44,", module.invokeMember("text",new ArgsKwArgsTest.MockPositinalArgs(1)).asString());
349-
assertEquals("a=1,b=2,", module.invokeMember("text",new ArgsKwArgsTest.MockPositinalArgs(1,2)).asString());
350-
assertEquals("a=1,b=2,args[0]=3,", module.invokeMember("text",new ArgsKwArgsTest.MockPositinalArgs(1,2,3)).asString());
351-
assertEquals("a='a',b='b',args[0]=1,args[1]=2,args[2]=3,", module.invokeMember("text","a", "b", new ArgsKwArgsTest.MockPositinalArgs(1,2,3)).asString());
154+
assertEquals("a='6',b=1,args[0]=2,args[1]=3,", module.invokeMember("text", "6", PositionalArguments.of(1,2,3)).asString());
155+
assertEquals("a=1,b=44,", module.invokeMember("text", PositionalArguments.of(1)).asString());
156+
assertEquals("a=1,b=2,", module.invokeMember("text", PositionalArguments.of(1,2)).asString());
157+
assertEquals("a=1,b=2,args[0]=3,", module.invokeMember("text", PositionalArguments.of(1,2,3)).asString());
158+
assertEquals("a='a',b='b',args[0]=1,args[1]=2,args[2]=3,", module.invokeMember("text","a", "b", PositionalArguments.of(1,2,3)).asString());
352159
}
353160

354-
private String assertAllKeysInText(String text, Map<String, Object> kwArgs) {
161+
private static String assertAllKeysInText(String text, Map<String, Object> kwArgs) {
162+
String rest = text;
355163
for (Map.Entry<String, Object> entry : kwArgs.entrySet()) {
356164
String key = entry.getKey();
357165
Object val = entry.getValue();
358166
String keyVal = "[" + key + ":" + val.toString() +"],";
359167
assertTrue("The string \"" + keyVal + "\" was not found in \"" + text + "\"" , text.contains(keyVal));
360-
text = text.replace(keyVal, "");
168+
rest = rest.replace(keyVal, "");
361169
}
362-
return text;
170+
return rest;
363171
}
364172

365173
@Test
@@ -375,19 +183,19 @@ def text(**kwArgs):
375183
);
376184

377185
assertEquals("", module.invokeMember("text").asString());
378-
assertEquals("", module.invokeMember("text", new ArgsKwArgsTest.MockKwArgs(Map.of())).asString());
186+
assertEquals("", module.invokeMember("text", KeywordArguments.from(Map.of())).asString());
379187

380188
Map<String, Object> kwargsMap = Map.of("key1", 1);
381-
String remaining = assertAllKeysInText(module.invokeMember("text", new ArgsKwArgsTest.MockKwArgs(kwargsMap)).asString(), kwargsMap);
189+
String remaining = assertAllKeysInText(module.invokeMember("text", KeywordArguments.from(kwargsMap)).asString(), kwargsMap);
382190
assertTrue(remaining.isEmpty());
383191

384192
kwargsMap = Map.of("key1", 1, "key2", 22);
385-
remaining = assertAllKeysInText(module.invokeMember("text", new ArgsKwArgsTest.MockKwArgs(kwargsMap)).asString(), kwargsMap);
193+
remaining = assertAllKeysInText(module.invokeMember("text", KeywordArguments.from(kwargsMap)).asString(), kwargsMap);
386194
assertTrue(remaining.isEmpty());
387195

388-
assertTrue(module.invokeMember("text", new ArgsKwArgsTest.MockPositinalArgs()).asString().isEmpty());
196+
assertTrue(module.invokeMember("text", PositionalArguments.of()).asString().isEmpty());
389197

390-
PolyglotException pe = assertThrows(PolyglotException.class, () -> {module.invokeMember("text", new ArgsKwArgsTest.MockPositinalArgs(44)).asString();});
198+
PolyglotException pe = assertThrows(PolyglotException.class, () -> {module.invokeMember("text", PositionalArguments.of(44)).asString();});
391199
assertEquals("TypeError: text() takes 0 positional arguments but 1 was given", pe.getMessage());
392200
}
393201

@@ -404,26 +212,26 @@ def text(*,named1, **kwArgs):
404212
);
405213

406214
Map<String, Object> kwargsMap = Map.of("named1", 1);
407-
String remaining = assertAllKeysInText(module.invokeMember("text", new ArgsKwArgsTest.MockKwArgs(kwargsMap)).asString(), kwargsMap);
215+
String remaining = assertAllKeysInText(module.invokeMember("text", KeywordArguments.from(kwargsMap)).asString(), kwargsMap);
408216
assertTrue(remaining.isEmpty());
409217

410218
kwargsMap = Map.of("named1", 1, "named2", 2);
411-
remaining = assertAllKeysInText(module.invokeMember("text", new ArgsKwArgsTest.MockKwArgs(kwargsMap)).asString(), kwargsMap);
219+
remaining = assertAllKeysInText(module.invokeMember("text", KeywordArguments.from(kwargsMap)).asString(), kwargsMap);
412220
assertTrue(remaining.isEmpty());
413221

414222
PolyglotException pe = assertThrows(PolyglotException.class, () -> {module.invokeMember("text").asString();});
415223
assertEquals("TypeError: text() missing 1 required keyword-only argument: 'named1'", pe.getMessage());
416224

417-
pe = assertThrows(PolyglotException.class, () -> {module.invokeMember("text", new ArgsKwArgsTest.MockKwArgs(Map.of())).asString();});
225+
pe = assertThrows(PolyglotException.class, () -> {module.invokeMember("text", KeywordArguments.from(Map.of())).asString();});
418226
assertEquals("TypeError: text() missing 1 required keyword-only argument: 'named1'", pe.getMessage());
419227

420-
pe = assertThrows(PolyglotException.class, () -> {module.invokeMember("text", new ArgsKwArgsTest.MockKwArgs(Map.of("named2", 10))).asString();});
228+
pe = assertThrows(PolyglotException.class, () -> {module.invokeMember("text", KeywordArguments.of("named2", 10)).asString();});
421229
assertEquals("TypeError: text() missing 1 required keyword-only argument: 'named1'", pe.getMessage());
422230

423-
pe = assertThrows(PolyglotException.class, () -> {module.invokeMember("text", new ArgsKwArgsTest.MockPositinalArgs()).asString();});
231+
pe = assertThrows(PolyglotException.class, () -> {module.invokeMember("text", PositionalArguments.of()).asString();});
424232
assertEquals("TypeError: text() missing 1 required keyword-only argument: 'named1'", pe.getMessage());
425233

426-
pe = assertThrows(PolyglotException.class, () -> {module.invokeMember("text", new ArgsKwArgsTest.MockPositinalArgs(10)).asString();});
234+
pe = assertThrows(PolyglotException.class, () -> {module.invokeMember("text", PositionalArguments.of(10)).asString();});
427235
assertEquals("TypeError: text() takes 0 positional arguments but 1 was given", pe.getMessage());
428236
}
429237

@@ -440,11 +248,11 @@ def text(*,named1, named2=44, **kwArgs):
440248
);
441249

442250
Map<String, Object> kwargsMap = Map.of("named1", 1);
443-
String remaining = assertAllKeysInText(module.invokeMember("text", new ArgsKwArgsTest.MockKwArgs(kwargsMap)).asString(), kwargsMap);
251+
String remaining = assertAllKeysInText(module.invokeMember("text", KeywordArguments.from(kwargsMap)).asString(), kwargsMap);
444252
assertEquals("[named2:44],",remaining);
445253

446254
kwargsMap = Map.of("named1", 1, "named2", 2);
447-
remaining = assertAllKeysInText(module.invokeMember("text", new ArgsKwArgsTest.MockKwArgs(kwargsMap)).asString(), kwargsMap);
255+
remaining = assertAllKeysInText(module.invokeMember("text", KeywordArguments.from(kwargsMap)).asString(), kwargsMap);
448256
assertTrue(remaining.isEmpty());
449257
}
450258

@@ -459,15 +267,15 @@ def text(*,named1, named2=44):
459267
);
460268

461269
Map<String, Object> kwargsMap = Map.of("named1", 1);
462-
String remaining = module.invokeMember("text", new ArgsKwArgsTest.MockKwArgs(kwargsMap)).asString();
270+
String remaining = module.invokeMember("text", KeywordArguments.from(kwargsMap)).asString();
463271
assertEquals("[named1:1],[named2:44],",remaining);
464272

465273
kwargsMap = Map.of("named1", 1, "named2", 2);
466-
remaining = module.invokeMember("text", new ArgsKwArgsTest.MockKwArgs(kwargsMap)).asString();
274+
remaining = module.invokeMember("text", KeywordArguments.from(kwargsMap)).asString();
467275
assertEquals("[named1:1],[named2:2],",remaining);
468276

469277
PolyglotException pe = assertThrows(PolyglotException.class, () -> {module.invokeMember("text",
470-
module.invokeMember("text", new ArgsKwArgsTest.MockKwArgs(Map.of("named1", 1, "named2", 2, "named3", 3)))).asString();});
278+
module.invokeMember("text", KeywordArguments.of("named1", 1, "named2", 2, "named3", 3))).asString();});
471279
assertEquals("TypeError: text() got an unexpected keyword argument 'named3'", pe.getMessage());
472280
}
473281
}

0 commit comments

Comments
 (0)