Skip to content

Commit a7aab78

Browse files
committed
[GR-34916] Intrinsify python_cext - PySequence/Unicode_XXX.
PullRequest: graalpython/2055
2 parents c49818a + fcc627b commit a7aab78

File tree

11 files changed

+1104
-196
lines changed

11 files changed

+1104
-196
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ PyObject* PySequence_Concat(PyObject *s, PyObject *o) {
549549

550550
UPCALL_ID(PySequence_InPlaceRepeat);
551551
PyObject* PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count) {
552-
return UPCALL_CEXT_O(_jls_PySequence_Repeat, native_to_java(o), count);
552+
return UPCALL_CEXT_O(_jls_PySequence_InPlaceRepeat, native_to_java(o), count);
553553
}
554554

555555
UPCALL_ID(PySequence_InPlaceConcat);

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

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,15 @@ def _reference_fast(args):
139139
return obj
140140
return list(obj)
141141

142+
def _wrap_slice_fun(fun, since=0, default=None):
143+
def wrapped_fun(args):
144+
if not isinstance(args[0], list) and not isinstance(args[0], set) and not isinstance(args[0], tuple) and not isinstance(args[0], str):
145+
if sys.version_info.minor >= since:
146+
raise SystemError("expected list type")
147+
else:
148+
return default
149+
return fun(args)
150+
return wrapped_fun
142151

143152
class NoNumber():
144153
pass
@@ -733,6 +742,7 @@ def compile_module(self, name):
733742
({'a':0, 'b':1},),
734743
(DummySequence(),),
735744
(DummyListSubclass(),),
745+
('hello',),
736746
),
737747
resultspec="i",
738748
argspec='O',
@@ -750,6 +760,7 @@ def compile_module(self, name):
750760
([None],),
751761
(set(),),
752762
(DummyListSubclass(),),
763+
('hello',),
753764
),
754765
resultspec="n",
755766
argspec='O',
@@ -772,13 +783,58 @@ def compile_module(self, name):
772783
(set(), 0),
773784
({'a', 'b'}, 0),
774785
(DummyListSubclass(), 1),
786+
('hello', 1),
775787
),
776788
resultspec="O",
777789
argspec='On',
778790
arguments=["PyObject* sequence", "Py_ssize_t idx"],
779791
cmpfunc=unhandled_error_compare
780792
)
781-
793+
794+
test_PySequence_GetSlice = CPyExtFunction(
795+
_wrap_slice_fun(lambda args: args[0][args[1]:args[2]]),
796+
lambda: (
797+
(tuple(), 0, 1),
798+
((1, 2, 3), 1, 2),
799+
((None,), 1, 2),
800+
([], 0, 1),
801+
(['a', 'b', 'c'], 1, 2),
802+
([None], 0, 1),
803+
(set(), 0, 1),
804+
({'a', 'b'}, 1, 2),
805+
(DummyListSubclass(), 0, 1),
806+
('hello', 0, 1),
807+
),
808+
resultspec="O",
809+
argspec='Onn',
810+
arguments=["PyObject* sequence", "Py_ssize_t ilow", "Py_ssize_t ihigh"],
811+
cmpfunc=unhandled_error_compare
812+
)
813+
814+
test_PySequence_Contains = CPyExtFunction(
815+
lambda args: args[1] in args[0],
816+
lambda: (
817+
(tuple(), 1),
818+
((1, 2, 3), 1),
819+
((1, 2, 3), 4),
820+
((None,), 1),
821+
([], 1),
822+
(['a', 'b', 'c'], 'a'),
823+
(['a', 'b', 'c'], 'd'),
824+
([None], 1),
825+
(set(), 1),
826+
({'a', 'b'}, 'a'),
827+
({'a', 'b'}, 'c'),
828+
(DummyListSubclass(), 1),
829+
('hello', 'e'),
830+
('hello', 'x'),
831+
),
832+
resultspec="i",
833+
argspec='OO',
834+
arguments=["PyObject* haystack", "PyObject* needle"],
835+
cmpfunc=unhandled_error_compare
836+
)
837+
782838
test_PySequence_ITEM = CPyExtFunction(
783839
_reference_getitem,
784840
lambda: (
@@ -788,6 +844,7 @@ def compile_module(self, name):
788844
([], 10),
789845
(['a', 'b', 'c'], 2),
790846
([None], 0),
847+
('hello', 0),
791848
),
792849
resultspec="O",
793850
argspec='On',
@@ -803,6 +860,7 @@ def compile_module(self, name):
803860
((None,), 1, None),
804861
([], 10, 1),
805862
(['a', 'b', 'c'], 2, 'z'),
863+
('hello', 2, 'z'),
806864
),
807865
code=''' PyObject* wrap_PySequence_SetItem(PyObject* sequence, Py_ssize_t idx, PyObject* value) {
808866
if (PySequence_SetItem(sequence, idx, value) < 0) {
@@ -830,6 +888,27 @@ def compile_module(self, name):
830888
({'a': 0, 'b': 1, 'c': 2},),
831889
(None,),
832890
(0,),
891+
('hello',),
892+
),
893+
resultspec="O",
894+
argspec='O',
895+
arguments=["PyObject* sequence"],
896+
cmpfunc=unhandled_error_compare
897+
)
898+
899+
test_PySequence_List = CPyExtFunction(
900+
lambda args: list(args[0]),
901+
lambda: (
902+
(list(),),
903+
((1, 2, 3),),
904+
((None,),),
905+
([],),
906+
(['a', 'b', 'c'],),
907+
({'a', 'b', 'c'},),
908+
({'a': 0, 'b': 1, 'c': 2},),
909+
(None,),
910+
(0,),
911+
('hello',),
833912
),
834913
resultspec="O",
835914
argspec='O',

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

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,53 @@ def _reference_contains(args):
9898
raise TypeError
9999
return args[1] in args[0]
100100

101+
def _reference_compare(args):
102+
if not isinstance(args[0], str) or not isinstance(args[1], str):
103+
if sys.version_info.minor >= 6:
104+
raise SystemError
105+
else:
106+
raise TypeError
107+
108+
if args[0] == args[1]:
109+
return 0
110+
elif args[0] < args[1]:
111+
return -1
112+
else:
113+
return 1
114+
115+
def _reference_as_encoded_string(args):
116+
if not isinstance(args[0], str):
117+
raise TypeError
118+
119+
s = args[0]
120+
encoding = args[1]
121+
errors = args[2]
122+
return s.encode(encoding, errors)
123+
124+
_codecs_module = None
125+
def _reference_as_unicode_escape_string(args):
126+
if not isinstance(args[0], str):
127+
raise TypeError
128+
global _codecs_module
129+
if not _codecs_module:
130+
import _codecs as _codecs_module
131+
return _codecs_module.unicode_escape_encode(args[0])[0]
132+
133+
def _reference_tailmatch(args):
134+
if not isinstance(args[0], str) or not isinstance(args[1], str):
135+
if sys.version_info.minor >= 6:
136+
raise SystemError
137+
else:
138+
raise TypeError
139+
140+
s = args[0]
141+
substr = args[1]
142+
start = args[2]
143+
end = args[3]
144+
direction = args[4]
145+
if direction > 0:
146+
return 1 if s[start:end].endswith(substr) else 0
147+
return 1 if s[start:end].startswith(substr) else 0
101148

102149
class CustomString(str):
103150
pass
@@ -509,6 +556,37 @@ def compile_module(self, name):
509556
arguments=["PyObject* str", "PyObject* seq"],
510557
cmpfunc=unhandled_error_compare
511558
)
559+
560+
test_PyUnicode_Compare = CPyExtFunction(
561+
_reference_compare,
562+
lambda: (
563+
("a", "a"),
564+
("a", "b"),
565+
("a", None),
566+
("a", 1),
567+
),
568+
resultspec="i",
569+
argspec='OO',
570+
arguments=["PyObject* left", "PyObject* right"],
571+
cmpfunc=unhandled_error_compare
572+
)
573+
574+
test_PyUnicode_Tailmatch = CPyExtFunction(
575+
_reference_tailmatch,
576+
lambda: (
577+
("abc", "a", 0, 1, 0),
578+
("abc", "a", 0, 1, 1),
579+
("abc", "a", 0, 0, 1),
580+
("abc", "c", 0, 1, 0),
581+
("abc", "c", 0, 1, 1),
582+
("abc", None, 0, 1, 1),
583+
("abc", 1, 1, 0, 1),
584+
),
585+
resultspec="i",
586+
argspec='OOnni',
587+
arguments=["PyObject* left", "PyObject* right", "Py_ssize_t start", "Py_ssize_t end", "int direction"],
588+
cmpfunc=unhandled_error_compare
589+
)
512590

513591
test_PyUnicode_FromOrdinal = CPyExtFunction(
514592
lambda args: chr(args[0]),
@@ -545,21 +623,34 @@ def compile_module(self, name):
545623

546624

547625
test_PyUnicode_AsEncodedString = CPyExtFunction(
548-
lambda args: args[0].encode(args[1], args[2]),
626+
_reference_as_encoded_string,
549627
lambda: (
550628
("abcd", "ascii", "report"),
551629
("abcd", "utf8", "report"),
552630
("öüä", "ascii", "report"),
553631
("öüä", "utf8", "report"),
554632
("öüä", "ascii", "ignore"),
555633
("öüä", "ascii", "replace"),
634+
(1, "ascii", "replace"),
556635
),
557636
resultspec="O",
558637
argspec='Oss',
559638
arguments=["PyObject* str", "const char* encoding", "const char* errors"],
560639
cmpfunc=unhandled_error_compare
561640
)
562641

642+
test_PyUnicode_AsUnicodeEscapeString = CPyExtFunction(
643+
_reference_as_unicode_escape_string,
644+
lambda: (
645+
("abcd",),
646+
("öüä",),
647+
(1,),
648+
),
649+
resultspec="O",
650+
argspec='O',
651+
arguments=["PyObject* s"],
652+
cmpfunc=unhandled_error_compare
653+
)
563654

564655
# NOTE: this test assumes that Python uses UTF-8 encoding for source files
565656
test_PyUnicode_FromWideChar = CPyExtFunction(

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ Object encode(Object self, String encoding, String errors,
537537

538538
@Fallback
539539
Object encode(Object str, @SuppressWarnings("unused") Object encoding, @SuppressWarnings("unused") Object errors) {
540-
throw raise(TypeError, ErrorMessages.CANT_CONVERT_TO_STR_EXPLICITELY, str);
540+
throw raise(TypeError, ErrorMessages.CANT_CONVERT_TO_STR_IMPLICITLY, str);
541541
}
542542
}
543543

@@ -1335,7 +1335,7 @@ Object encode(VirtualFrame frame, Object obj, Object errors,
13351335

13361336
@Builtin(name = "unicode_escape_encode", minNumOfPositionalArgs = 1, parameterNames = {"obj", "errors"})
13371337
@GenerateNodeFactory
1338-
abstract static class UnicodeEscapeEncodeNode extends PythonBinaryBuiltinNode {
1338+
public abstract static class UnicodeEscapeEncodeNode extends PythonBinaryBuiltinNode {
13391339
@Specialization
13401340
Object encode(VirtualFrame frame, Object obj, Object errors,
13411341
@Cached CodecsEncodeNode encode) {

0 commit comments

Comments
 (0)