Skip to content

Commit ebe5ae5

Browse files
committed
fix in PyMappingCheckNode
- all PSequence types are also a mapping - PDeque which has __getitem__ isn't
1 parent 2cf0e08 commit ebe5ae5

File tree

6 files changed

+77
-18
lines changed

6 files changed

+77
-18
lines changed

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

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
1+
# Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
22
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
33
#
44
# The Universal Permissive License (UPL), Version 1.0
@@ -38,6 +38,8 @@
3838
# SOFTWARE.
3939

4040
# the dict representation of a type is a mappingproxy
41+
import array, collections
42+
4143
_mappingproxy = type(type.__dict__)
4244

4345

@@ -128,6 +130,25 @@ def test_iter():
128130

129131
mp_keys = set([k for k in mp])
130132
assert d.keys() == mp_keys
133+
134+
def test_create():
135+
_mappingproxy(dict())
136+
mp = _mappingproxy({'a': 1})
137+
_mappingproxy(mp)
138+
_mappingproxy('abc')
139+
_mappingproxy(b'abc')
140+
_mappingproxy(bytearray(b'abc'))
141+
assert_raises(TypeError, _mappingproxy, ())
142+
assert_raises(TypeError,_mappingproxy, (1,2,3))
143+
assert_raises(TypeError,_mappingproxy, [])
144+
assert_raises(TypeError,_mappingproxy, [1,2,3])
145+
_mappingproxy(memoryview(b'abc'))
146+
_mappingproxy(array.array("I", [1,2,3]))
147+
assert_raises(TypeError, _mappingproxy, collections.deque([1,2,3]))
148+
assert_raises(TypeError, _mappingproxy, set())
149+
assert_raises(TypeError, _mappingproxy, {1,2,3})
150+
assert_raises(TypeError, _mappingproxy, None)
151+
assert_raises(TypeError, _mappingproxy, 123)
131152

132153
def test_iter_changed_size():
133154
class A:

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3190,7 +3190,8 @@ public abstract static class MappingproxyNode extends PythonBinaryBuiltinNode {
31903190
@Specialization(guards = "!isNoValue(obj)")
31913191
Object doMapping(Object klass, Object obj,
31923192
@Cached PyMappingCheckNode mappingCheckNode) {
3193-
if (mappingCheckNode.execute(obj)) {
3193+
// descrobject.c mappingproxy_check_mapping()
3194+
if (!(obj instanceof PList || obj instanceof PTuple) && mappingCheckNode.execute(obj)) {
31943195
return factory().createMappingproxy(klass, obj);
31953196
}
31963197
throw raise(TypeError, ErrorMessages.ARG_MUST_BE_S_NOT_P, "mappingproxy()", "mapping", obj);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyMappingCheckNode.java

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -43,10 +43,13 @@
4343
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
4444
import com.oracle.graal.python.builtins.objects.PNone;
4545
import com.oracle.graal.python.builtins.objects.array.PArray;
46+
import com.oracle.graal.python.builtins.objects.deque.PDeque;
4647
import com.oracle.graal.python.builtins.objects.dict.PDict;
48+
import com.oracle.graal.python.builtins.objects.mappingproxy.PMappingproxy;
4749
import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView;
4850
import com.oracle.graal.python.builtins.objects.object.PythonObject;
4951
import com.oracle.graal.python.builtins.objects.range.PRange;
52+
import com.oracle.graal.python.builtins.objects.set.PBaseSet;
5053
import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot;
5154
import com.oracle.graal.python.nodes.PNodeWithContext;
5255
import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode;
@@ -75,42 +78,62 @@ static boolean doDict(@SuppressWarnings("unused") PDict object) {
7578

7679
@Specialization
7780
static boolean doString(@SuppressWarnings("unused") String object) {
78-
return false;
81+
return true;
7982
}
8083

8184
@Specialization
8285
static boolean doSequence(@SuppressWarnings("unused") PSequence object) {
83-
return false;
86+
return true;
8487
}
8588

8689
@Specialization
8790
static boolean doArray(@SuppressWarnings("unused") PArray object) {
88-
return false;
91+
return true;
8992
}
9093

9194
@Specialization
9295
static boolean doMemoryView(@SuppressWarnings("unused") PMemoryView object) {
93-
return false;
96+
return true;
97+
}
98+
99+
@Specialization
100+
static boolean doMappingproxy(@SuppressWarnings("unused") PMappingproxy object) {
101+
return true;
94102
}
95103

96104
@Specialization
97105
static boolean doRange(@SuppressWarnings("unused") PRange object) {
106+
return true;
107+
}
108+
109+
@Specialization
110+
static boolean doDeque(@SuppressWarnings("unused") PDeque object) {
111+
return false;
112+
}
113+
114+
@Specialization
115+
static boolean doSet(@SuppressWarnings("unused") PBaseSet object) {
98116
return false;
99117
}
100118

101119
protected static boolean cannotBeMapping(Object object) {
102-
return object instanceof String || object instanceof PSequence || object instanceof PArray || object instanceof PMemoryView || object instanceof PRange;
120+
return object instanceof PDeque || object instanceof PBaseSet;
121+
}
122+
123+
protected static boolean isKnownMapping(Object object) {
124+
return object instanceof PDict || object instanceof String || object instanceof PSequence || object instanceof PArray ||
125+
object instanceof PMemoryView || object instanceof PRange || object instanceof PMappingproxy;
103126
}
104127

105-
@Specialization(guards = "!cannotBeMapping(object)")
128+
@Specialization(guards = {"!isKnownMapping(object)", "!cannotBeMapping(object)"})
106129
boolean doPythonObject(PythonObject object,
107130
@Shared("getClass") @Cached GetClassNode getClassNode,
108131
@Shared("lookupGetItem") @Cached(parameters = "GetItem") LookupCallableSlotInMRONode lookupGetItem) {
109132
Object type = getClassNode.execute(object);
110133
return lookupGetItem.execute(type) != PNone.NO_VALUE;
111134
}
112135

113-
@Specialization(guards = "!cannotBeMapping(object)", replaces = "doPythonObject")
136+
@Specialization(guards = {"!isKnownMapping(object)", "!cannotBeMapping(object)"}, replaces = "doPythonObject")
114137
boolean doGeneric(Object object,
115138
@Shared("getClass") @Cached GetClassNode getClassNode,
116139
@Shared("lookupGetItem") @Cached(parameters = "GetItem") LookupCallableSlotInMRONode lookupGetItem,

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/BytesFormatProcessor.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -57,7 +57,10 @@
5757
import com.oracle.graal.python.builtins.objects.bytes.PBytesLike;
5858
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodesFactory.ToByteArrayNodeGen;
5959
import com.oracle.graal.python.builtins.objects.ints.PInt;
60+
import com.oracle.graal.python.builtins.objects.str.PString;
61+
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
6062
import com.oracle.graal.python.builtins.objects.tuple.TupleBuiltins;
63+
import com.oracle.graal.python.lib.PyMappingCheckNode;
6164
import com.oracle.graal.python.lib.PyObjectAsciiNode;
6265
import com.oracle.graal.python.lib.PyObjectGetItem;
6366
import com.oracle.graal.python.nodes.ErrorMessages;
@@ -113,6 +116,12 @@ Object parseMappingKey(int start, int end) {
113116
return core.factory().createBytes(Arrays.copyOfRange(formatBytes, start, end));
114117
}
115118

119+
@Override
120+
protected boolean isMapping(Object obj) {
121+
// bytesobject.c _PyBytes_FormatEx()
122+
return !(obj instanceof PTuple || obj instanceof PBytesLike || obj instanceof PString || obj instanceof String) && PyMappingCheckNode.getUncached().execute(obj);
123+
}
124+
116125
@Override
117126
protected double asFloat(Object arg) {
118127
try {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/FormatProcessor.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2021, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2022, Oracle and/or its affiliates.
33
* Copyright (c) -2016 Jython Developers
44
*
55
* Licensed under PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
@@ -24,7 +24,6 @@
2424
import com.oracle.graal.python.builtins.objects.ints.PInt;
2525
import com.oracle.graal.python.builtins.objects.tuple.TupleBuiltins;
2626
import com.oracle.graal.python.lib.PyFloatAsDoubleNode;
27-
import com.oracle.graal.python.lib.PyMappingCheckNode;
2827
import com.oracle.graal.python.lib.PyObjectGetItem;
2928
import com.oracle.graal.python.lib.PyObjectSizeNode;
3029
import com.oracle.graal.python.nodes.ErrorMessages;
@@ -90,6 +89,8 @@ <F extends InternalFormat.Formatter> F setupFormat(F f) {
9089

9190
abstract Object parseMappingKey(int start, int end);
9291

92+
protected abstract boolean isMapping(Object obj);
93+
9394
static Object lookupAttribute(Object owner, String name) {
9495
return LookupAttributeInMRONode.Dynamic.getUncached().execute(GetClassNode.getUncached().execute(owner), name);
9596
}
@@ -230,10 +231,6 @@ protected static boolean isString(Object args1, Object lazyClass) {
230231
return PGuards.isString(args1) || isSubtype(lazyClass, PythonBuiltinClassType.PString);
231232
}
232233

233-
protected static boolean isMapping(Object args1) {
234-
return PyMappingCheckNode.getUncached().execute(args1);
235-
}
236-
237234
protected static boolean isSubtype(Object lazyClass, PythonBuiltinClassType clazz) {
238235
return IsSubtypeNodeGen.getUncached().execute(lazyClass, clazz);
239236
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/StringFormatProcessor.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2021, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2022, Oracle and/or its affiliates.
33
* Copyright (c) -2016 Jython Developers
44
*
55
* Licensed under PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
@@ -11,7 +11,9 @@
1111

1212
import com.oracle.graal.python.builtins.Python3Core;
1313
import com.oracle.graal.python.builtins.objects.str.PString;
14+
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
1415
import com.oracle.graal.python.builtins.objects.tuple.TupleBuiltins;
16+
import com.oracle.graal.python.lib.PyMappingCheckNode;
1517
import com.oracle.graal.python.lib.PyObjectAsciiNode;
1618
import com.oracle.graal.python.lib.PyObjectGetItem;
1719
import com.oracle.graal.python.lib.PyObjectReprAsJavaStringNode;
@@ -58,6 +60,12 @@ Object parseMappingKey(int start, int end) {
5860
return formatText.substring(start, end);
5961
}
6062

63+
@Override
64+
protected boolean isMapping(Object obj) {
65+
// unicodeobject.c PyUnicode_Format()
66+
return !(obj instanceof PTuple || obj instanceof PString || obj instanceof String) && PyMappingCheckNode.getUncached().execute(obj);
67+
}
68+
6169
private static boolean isOneCharacter(String str) {
6270
return str.length() == 1 || (str.length() == 2 && str.codePointCount(0, 2) == 1);
6371
}

0 commit comments

Comments
 (0)