Skip to content

Commit 1c2b072

Browse files
committed
implemented PyMapping_Size
1 parent 9449ddc commit 1c2b072

File tree

4 files changed

+104
-15
lines changed

4 files changed

+104
-15
lines changed

graalpython/com.oracle.graal.python.cext/src/abstract.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,8 @@ Py_ssize_t PySequence_Size(PyObject *s) {
290290
return UPCALL_CEXT_L(_jls_PySequence_Size, native_to_java(s));
291291
}
292292

293-
// taken from CPython "Objects/abstract.c"
294-
// called for native python objects
293+
// PySequence_Size downcall for native python objects
294+
// taken from CPython "Objects/abstract.c/Py_Sequence_Size"
295295
Py_ssize_t PyTruffle_Sequence_Size(PyObject *s) {
296296
PySequenceMethods *m;
297297

@@ -546,8 +546,14 @@ int PyBuffer_IsContiguous(const Py_buffer *view, char order) {
546546
return 0;
547547
}
548548

549-
// partially taken from CPython "Objects/abstract.c"
550-
Py_ssize_t PyMapping_Size(PyObject *o) {
549+
UPCALL_ID(PyMapping_Size);
550+
Py_ssize_t PyMapping_Size(PyObject *s) {
551+
return UPCALL_CEXT_L(_jls_PyMapping_Size, native_to_java(s));
552+
}
553+
554+
// PyMapping_Size downcall for native python objects
555+
// partially taken from CPython "Objects/abstract.c/Py_Mapping_Size"
556+
Py_ssize_t PyTruffle_Mapping_Size(PyObject *o) {
551557
PyMappingMethods *m;
552558

553559
if (o == NULL) {

graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_abstract.py

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,24 @@ def _reference_next(args):
105105
except BaseException:
106106
raise SystemError
107107

108-
109-
def _reference_size(args):
108+
def _reference_seq_size(args):
110109
seq = args[0]
111-
if isinstance(seq, dict):
112-
return -1
113-
if not hasattr(seq, '__len__'):
114-
raise TypeError()
110+
# XXX check
111+
if isinstance(seq, dict) or isinstance(seq, type(type.__dict__)) or isinstance(seq, set) or isinstance(seq, frozenset) or not hasattr(seq, '__len__'):
112+
if sys.version_info.minor >= 6:
113+
raise SystemError
114+
else:
115+
raise TypeError
115116
return len(seq)
116117

118+
def _reference_mapping_size(args):
119+
m = args[0]
120+
if not (isinstance(m, dict) or isinstance(m, type(type.__dict__))) or not hasattr(m, '__getitem__'):
121+
if sys.version_info.minor >= 6:
122+
raise SystemError
123+
else:
124+
raise TypeError
125+
return len(m)
117126

118127
def _reference_getitem(args):
119128
seq = args[0]
@@ -728,7 +737,9 @@ def compile_module(self, name):
728737
)
729738

730739
test_PySequence_Check = CPyExtFunction(
731-
lambda args: not isinstance(args[0], dict) and hasattr(args[0], '__getitem__'),
740+
lambda args: not isinstance(args[0], dict) and not isinstance(args[0], type(type.__dict__)) and hasattr(args[0], '__getitem__'),
741+
# XXX check
742+
# lambda args: not isinstance(args[0], dict) and (isinstance(args[0], set) or isinstance(args[0], frozenset) or hasattr(args[0], '__getitem__')),
732743
lambda: (
733744
(tuple(),),
734745
((1, 2, 3),),
@@ -738,19 +749,22 @@ def compile_module(self, name):
738749
([None],),
739750
(dict(),),
740751
(set(),),
752+
(frozenset(),),
741753
({'a', 'b'},),
742754
({'a':0, 'b':1},),
755+
(type.__dict__,), #mappingproxy
743756
(DummySequence(),),
744757
(DummyListSubclass(),),
745758
('hello',),
759+
(NoNumber(),),
746760
),
747761
resultspec="i",
748762
argspec='O',
749763
arguments=["PyObject* sequence"],
750764
)
751765

752766
test_PySequence_Size = CPyExtFunction(
753-
_reference_size,
767+
_reference_seq_size,
754768
lambda: (
755769
(tuple(),),
756770
((1, 2, 3),),
@@ -759,8 +773,13 @@ def compile_module(self, name):
759773
(['a', 'b', 'c'],),
760774
([None],),
761775
(set(),),
776+
(frozenset(),),
762777
(DummyListSubclass(),),
763778
('hello',),
779+
({},),
780+
({1, 1},),
781+
(type.__dict__,), #mappingproxy
782+
(NoNumber(),),
764783
),
765784
resultspec="n",
766785
argspec='O',
@@ -951,6 +970,30 @@ def compile_module(self, name):
951970
cmpfunc=unhandled_error_compare
952971
)
953972

973+
test_PyMapping_Size = CPyExtFunction(
974+
_reference_mapping_size,
975+
lambda: (
976+
(tuple(),),
977+
((1, 2, 3),),
978+
((None,),),
979+
([],),
980+
(['a', 'b', 'c'],),
981+
([None],),
982+
(set(),),
983+
(frozenset(),),
984+
(DummyListSubclass(),),
985+
('hello',),
986+
({},),
987+
({1, 1},),
988+
(type.__dict__,), #mappingproxy
989+
(NoNumber(),),
990+
),
991+
resultspec="n",
992+
argspec='O',
993+
arguments=["PyObject* mapping"],
994+
cmpfunc=unhandled_error_compare
995+
)
996+
954997
test_PyIndex_Check = CPyExtFunction(
955998
lambda args: hasattr(args[0], "__index__"),
956999
lambda: (

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextAbstractBuiltins.java

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,12 @@
4040
*/
4141
package com.oracle.graal.python.builtins.modules.cext;
4242

43+
import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_PY_TRUFFLE_MAPPING_SIZE;
44+
import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_PY_TRUFFLE_SEQUENCE_SIZE;
4345
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError;
4446
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
4547
import static com.oracle.graal.python.nodes.ErrorMessages.BASE_MUST_BE;
48+
import static com.oracle.graal.python.nodes.ErrorMessages.OBJ_ISNT_MAPPING;
4649
import static com.oracle.graal.python.nodes.ErrorMessages.P_OBJ_DOES_NOT_SUPPORT_ITEM_ASSIGMENT;
4750
import static com.oracle.graal.python.nodes.SpecialMethodNames.__GETITEM__;
4851
import static com.oracle.graal.python.nodes.SpecialMethodNames.__IADD__;
@@ -83,7 +86,6 @@
8386
import com.oracle.graal.python.builtins.objects.common.PHashingCollection;
8487
import com.oracle.graal.python.builtins.objects.common.SequenceNodes;
8588
import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.DefaultCheckFunctionResultNode;
86-
import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_PY_TRUFFLE_SEQUENCE_SIZE;
8789
import com.oracle.graal.python.builtins.objects.dict.DictBuiltins.ItemsNode;
8890
import com.oracle.graal.python.builtins.objects.dict.DictBuiltins.KeysNode;
8991
import com.oracle.graal.python.builtins.objects.dict.DictBuiltins.ValuesNode;
@@ -943,7 +945,7 @@ static boolean check(Object object,
943945

944946
@Builtin(name = "PySequence_GetItem", minNumOfPositionalArgs = 2)
945947
@GenerateNodeFactory
946-
abstract static class PySequenceGetItem extends PythonBinaryBuiltinNode {
948+
abstract static class PySequenceGetItemNode extends PythonBinaryBuiltinNode {
947949

948950
@Specialization
949951
Object doManaged(VirtualFrame frame, Object listWrapper, Object position,
@@ -1008,7 +1010,7 @@ Object notSequence(VirtualFrame frame, Object obj,
10081010

10091011
@Builtin(name = "PyObject_GetItem", minNumOfPositionalArgs = 2)
10101012
@GenerateNodeFactory
1011-
abstract static class PyObjectGetItem extends PythonBinaryBuiltinNode {
1013+
abstract static class PyObjectGetItemNode extends PythonBinaryBuiltinNode {
10121014
@Specialization
10131015
Object doManaged(VirtualFrame frame, Object listWrapper, Object key,
10141016
@Cached com.oracle.graal.python.lib.PyObjectGetItem getItem,
@@ -1177,6 +1179,43 @@ public Object values(VirtualFrame frame, Object obj,
11771179
}
11781180
}
11791181

1182+
@Builtin(name = "PyMapping_Size", minNumOfPositionalArgs = 1)
1183+
@GenerateNodeFactory
1184+
@ImportStatic(SpecialMethodNames.class)
1185+
abstract static class PyMappingSizeNode extends PythonUnaryBuiltinNode {
1186+
1187+
@Specialization(guards = "checkNode.execute(obj)")
1188+
static int doSequence(VirtualFrame frame, Object obj,
1189+
@SuppressWarnings("unused") @Cached PyMappingCheckNode checkNode,
1190+
@Cached PyObjectSizeNode sizeNode,
1191+
@Cached TransformExceptionToNativeNode transformExceptionToNativeNode) {
1192+
try {
1193+
return sizeNode.execute(frame, obj);
1194+
} catch (PException e) {
1195+
transformExceptionToNativeNode.execute(frame, e);
1196+
return -1;
1197+
}
1198+
}
1199+
1200+
@Specialization(guards = "isNativeObject(obj)")
1201+
static Object doNative(VirtualFrame frame, Object obj,
1202+
@Cached ToSulongNode toSulongNode,
1203+
@Cached AsPythonObjectNode asPythonObjectNode,
1204+
@Cached PCallCapiFunction callCapiFunction,
1205+
@Cached DefaultCheckFunctionResultNode checkFunctionResultNode) {
1206+
Object result = callCapiFunction.call(FUN_PY_TRUFFLE_MAPPING_SIZE, toSulongNode.execute(obj));
1207+
checkFunctionResultNode.execute(PythonContext.get(callCapiFunction), FUN_PY_TRUFFLE_MAPPING_SIZE.getName(), result);
1208+
return asPythonObjectNode.execute(result);
1209+
}
1210+
1211+
@Specialization(guards = {"!isNativeObject(obj)", "!checkNode.execute(obj)"})
1212+
Object notSequence(VirtualFrame frame, Object obj,
1213+
@SuppressWarnings("unused") @Cached PyMappingCheckNode checkNode,
1214+
@Cached PRaiseNativeNode raiseNativeNode) {
1215+
return raiseNativeNode.raiseInt(frame, -1, TypeError, OBJ_ISNT_MAPPING, obj);
1216+
}
1217+
}
1218+
11801219
/////// PyIter ///////
11811220

11821221
@Builtin(name = "PyIter_Next", minNumOfPositionalArgs = 1)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/NativeCAPISymbol.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ public enum NativeCAPISymbol implements NativeCExtSymbol {
164164
FUN_GET_LONG_BITS_PER_DIGIT("get_long_bits_in_digit"),
165165
FUN_BULK_SUBREF("PyTruffle_bulk_SUBREF"),
166166
FUN_TRUFFLE_ADD_SUBOFFSET("truffle_add_suboffset"),
167+
FUN_PY_TRUFFLE_MAPPING_SIZE("PyTruffle_Mapping_Size"),
167168
FUN_PY_TRUFFLE_MEMORYVIEW_FROM_BUFFER("PyTruffle_MemoryViewFromBuffer"),
168169
FUN_PY_TRUFFLE_MEMORYVIEW_FROM_OBJECT("PyTruffle_MemoryViewFromObject"),
169170
FUN_PY_TRUFFLE_RELEASE_BUFFER("PyTruffle_ReleaseBuffer"),

0 commit comments

Comments
 (0)