Skip to content

Commit 4841ac9

Browse files
committed
[GR-23218] Make test_descr pass - smaller fixes.
PullRequest: graalpython/1252
2 parents 225e3bf + 5bf1b6d commit 4841ac9

File tree

8 files changed

+106
-30
lines changed

8 files changed

+106
-30
lines changed

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,15 @@ def test_bytes_init():
706706
bytes.__init__(ba, b'zzz')
707707
assert ba == bytes(b'abc')
708708

709+
def test_bytes_mod():
710+
assert b'%s' % (b'a') == b'a'
711+
raised = False
712+
try:
713+
b'%s' % (b'a', b'b')
714+
except TypeError:
715+
raised = True
716+
assert raised
717+
709718
class BaseLikeBytes:
710719

711720
def test_maketrans(self):

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,3 +1155,21 @@ def test_replace_count():
11551155
s = "1 2 3 1 2 3 1 2 3 1 2 3"
11561156
s = s.replace("1", "1 _", s.count("1"))
11571157
assert s == "1 _ 2 3 1 _ 2 3 1 _ 2 3 1 _ 2 3"
1158+
1159+
def test_str_add_result_type():
1160+
class S(str): pass
1161+
1162+
assert (S('') + S('a')).__class__ == str
1163+
assert (S('a') + S('')).__class__ == str
1164+
assert (S('') + S('')).__class__ == str
1165+
assert (S('a') + S('a')).__class__ == str
1166+
1167+
assert ('' + S('')).__class__ == str
1168+
assert ('a' + S('')).__class__ == str
1169+
assert (S('') + '').__class__ == str
1170+
assert (S('') + 'a').__class__ == str
1171+
1172+
assert ('' + '').__class__ == str
1173+
assert ('' + 'a').__class__ == str
1174+
assert ('a' + '').__class__ == str
1175+
assert ('a' + 'a').__class__ == str

graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_descr.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_abstractmethods
22
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_altmro
33
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_assign_slice
4+
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_basic_inheritance
45
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_binary_operator_override
56
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_bound_method_repr
67
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_bpo25750
@@ -50,6 +51,7 @@
5051
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_newslots
5152
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_not_implemented
5253
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_object_class
54+
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_object_class_assignment_between_heaptypes_and_nonheaptypes
5355
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_object_new
5456
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_object_new_and_init_with_parameters
5557
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_overloading
@@ -76,6 +78,7 @@
7678
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_staticmethods
7779
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_staticmethods_in_c
7880
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_str_of_str_subclass
81+
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_str_operations
7982
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_str_subclass_as_dict_key
8083
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_subclass_propagation
8184
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_testcapi_no_segfault

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectBuiltins.java

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,12 @@
100100
import com.oracle.graal.python.nodes.util.CannotCastException;
101101
import com.oracle.graal.python.nodes.util.CastToJavaStringNode;
102102
import com.oracle.graal.python.nodes.util.SplitArgsNode;
103+
import com.oracle.graal.python.runtime.PythonContext;
103104
import com.oracle.truffle.api.CompilerDirectives;
104105
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
105106
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
106107
import com.oracle.truffle.api.dsl.Cached;
108+
import com.oracle.truffle.api.dsl.CachedContext;
107109
import com.oracle.truffle.api.dsl.Fallback;
108110
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
109111
import com.oracle.truffle.api.dsl.ImportStatic;
@@ -132,48 +134,59 @@ abstract static class ClassNode extends PythonBinaryBuiltinNode {
132134

133135
@Child private CheckCompatibleForAssigmentNode compatibleForAssigmentNode;
134136

135-
private static final String ERROR_MESSAGE = "__class__ assignment only supported for heap types or ModuleType subclasses";
136-
137137
@Specialization(guards = "isNoValue(value)")
138138
Object getClass(Object self, @SuppressWarnings("unused") PNone value,
139139
@Cached("create()") GetClassNode getClass) {
140140
return getClass.execute(self);
141141
}
142142

143-
@Specialization
144-
Object setClass(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") PythonBuiltinClass klass) {
145-
throw raise(TypeError, ERROR_MESSAGE);
146-
}
147-
148143
@Specialization(guards = "isNativeClass(klass)")
149144
Object setClass(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object klass) {
150-
throw raise(TypeError, ERROR_MESSAGE);
145+
throw raise(TypeError, ErrorMessages.CLASS_ASSIGMENT_ONLY_SUPPORTED_FOR_HEAP_TYPES_OR_MODTYPE_SUBCLASSES);
151146
}
152147

153-
@Specialization(guards = "isPythonClass(value)")
148+
@Specialization(guards = "isPythonClass(value) || isPythonBuiltinClassType(value)")
154149
PNone setClass(VirtualFrame frame, PythonObject self, Object value,
155150
@CachedLibrary(limit = "2") PythonObjectLibrary lib1,
156151
@Cached("create()") BranchProfile errorValueBranch,
157-
@Cached("create()") BranchProfile errorSelfBranch) {
158-
if (value instanceof PythonBuiltinClass || PGuards.isNativeClass(value)) {
152+
@Cached("create()") BranchProfile errorSelfBranch,
153+
@CachedContext(PythonLanguage.class) PythonContext ctx) {
154+
if (isBuiltinClassNotModule(value) || PGuards.isNativeClass(value)) {
159155
errorValueBranch.enter();
160-
throw raise(TypeError, ERROR_MESSAGE);
156+
throw raise(TypeError, ErrorMessages.CLASS_ASSIGMENT_ONLY_SUPPORTED_FOR_HEAP_TYPES_OR_MODTYPE_SUBCLASSES);
161157
}
162158
Object lazyClass = lib1.getLazyPythonClass(self);
163-
if (lazyClass instanceof PythonBuiltinClassType || lazyClass instanceof PythonBuiltinClass || PGuards.isNativeClass(lazyClass)) {
159+
if (isBuiltinClassNotModule(lazyClass) || PGuards.isNativeClass(lazyClass)) {
164160
errorSelfBranch.enter();
165-
throw raise(TypeError, ERROR_MESSAGE);
161+
throw raise(TypeError, ErrorMessages.CLASS_ASSIGMENT_ONLY_SUPPORTED_FOR_HEAP_TYPES_OR_MODTYPE_SUBCLASSES);
166162
}
167163

168-
getCheckCompatibleForAssigmentNode().execute(frame, lazyClass, value);
164+
setClass(frame, self, lazyClass, value, ctx, lib1);
165+
return PNone.NONE;
166+
}
167+
168+
private void setClass(VirtualFrame frame, PythonObject self, Object lazyClass, Object value, PythonContext ctx, PythonObjectLibrary lib1) {
169+
if (lazyClass instanceof PythonBuiltinClassType) {
170+
getCheckCompatibleForAssigmentNode().execute(frame, ctx.getCore().lookupType((PythonBuiltinClassType) lazyClass), value);
171+
} else {
172+
getCheckCompatibleForAssigmentNode().execute(frame, lazyClass, value);
173+
}
169174

170175
lib1.setLazyPythonClass(self, value);
171-
return PNone.NONE;
172176
}
173177

174-
@Specialization(guards = {"isPythonClass(value)", "!isPythonObject(self)"})
178+
private static boolean isBuiltinClassNotModule(Object lazyClass) {
179+
if (lazyClass instanceof PythonBuiltinClass) {
180+
return ((PythonBuiltinClass) lazyClass).getType() != PythonBuiltinClassType.PythonModule;
181+
} else if (lazyClass instanceof PythonBuiltinClassType) {
182+
return ((PythonBuiltinClassType) lazyClass) != PythonBuiltinClassType.PythonModule;
183+
}
184+
return false;
185+
}
186+
187+
@Specialization(guards = {"isPythonClass(value) || isPythonBuiltinClassType(value)", "!isPythonObject(self)"})
175188
Object getClass(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object value) {
176-
throw raise(TypeError, ERROR_MESSAGE);
189+
throw raise(TypeError, ErrorMessages.CLASS_ASSIGMENT_ONLY_SUPPORTED_FOR_HEAP_TYPES_OR_MODTYPE_SUBCLASSES);
177190
}
178191

179192
@Fallback

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/PythonObjectLibrary.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ public boolean isLazyPythonClass(Object receiver) {
146146
* objects.
147147
*/
148148
public void setLazyPythonClass(Object receiver, Object cls) {
149-
PRaiseNode.getUncached().raise(PythonBuiltinClassType.TypeError, ErrorMessages.CLASS_ASSIGMENT_ONLY_SUPPORTED_FOR_HEAP_TYPES_OR_MODTYPE_SUBCLASSES, receiver);
149+
PRaiseNode.getUncached().raise(PythonBuiltinClassType.TypeError, ErrorMessages.CLASS_ASSIGMENT_ONLY_SUPPORTED_FOR_HEAP_TYPES_OR_MODTYPE_SUBCLASSES_NOT_P, receiver);
150150
}
151151

152152
/**

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringBuiltins.java

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,11 @@
9999
import com.oracle.graal.python.builtins.objects.str.StringNodes.JoinInternalNode;
100100
import com.oracle.graal.python.builtins.objects.str.StringNodes.SpliceNode;
101101
import com.oracle.graal.python.builtins.objects.str.StringNodes.StringLenNode;
102+
import com.oracle.graal.python.builtins.objects.str.StringNodes.StringMaterializeNode;
102103
import com.oracle.graal.python.builtins.objects.str.StringUtils.StripKind;
103104
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
104105
import com.oracle.graal.python.builtins.objects.tuple.TupleBuiltins;
106+
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode;
105107
import com.oracle.graal.python.nodes.ErrorMessages;
106108
import com.oracle.graal.python.nodes.PGuards;
107109
import com.oracle.graal.python.nodes.SpecialMethodNames;
@@ -420,28 +422,58 @@ String doSSSimple(String self, String other) {
420422
return self;
421423
}
422424

423-
@Specialization(guards = "!concatGuard(self, other.getCharSequence())")
424-
Object doSSSimple(String self, PString other) {
425+
@Specialization(guards = "!concatGuard(self, other.getCharSequence())", limit = "1")
426+
Object doSSSimple(String self, PString other,
427+
@Cached StringMaterializeNode materializeNode,
428+
@Cached IsSameTypeNode isSameType,
429+
@Cached BranchProfile isSameBranch,
430+
@CachedLibrary("other") PythonObjectLibrary lib) {
425431
if (LazyString.length(self, leftProfile1, leftProfile2) == 0) {
426-
return other;
432+
// result type has to be str
433+
if (isSameType.execute(lib.getLazyPythonClass(other), PythonBuiltinClassType.PString)) {
434+
isSameBranch.enter();
435+
return other;
436+
}
437+
return materializeNode.execute(other);
427438
}
428439
return self;
429440
}
430441

431-
@Specialization(guards = "!concatGuard(self.getCharSequence(), other)")
432-
Object doSSSimple(PString self, String other) {
442+
@Specialization(guards = "!concatGuard(self.getCharSequence(), other)", limit = "1")
443+
Object doSSSimple(PString self, String other,
444+
@Cached StringMaterializeNode materializeNode,
445+
@Cached IsSameTypeNode isSameType,
446+
@Cached BranchProfile isSameBranch,
447+
@CachedLibrary("self") PythonObjectLibrary lib) {
433448
if (LazyString.length(self.getCharSequence(), leftProfile1, leftProfile2) == 0) {
434449
return other;
435450
}
436-
return self;
451+
// result type has to be str
452+
if (isSameType.execute(lib.getLazyPythonClass(self), PythonBuiltinClassType.PString)) {
453+
isSameBranch.enter();
454+
return self;
455+
}
456+
return materializeNode.execute(self);
437457
}
438458

439459
@Specialization(guards = "!concatGuard(self.getCharSequence(), other.getCharSequence())")
440-
PString doSSSimple(PString self, PString other) {
460+
Object doSSSimple(PString self, PString other,
461+
@Cached StringMaterializeNode materializeNode,
462+
@Cached IsSameTypeNode isSameType,
463+
@Cached BranchProfile isSameBranch,
464+
@CachedLibrary(limit = "1") PythonObjectLibrary lib) {
441465
if (LazyString.length(self.getCharSequence(), leftProfile1, leftProfile2) == 0) {
442-
return other;
466+
if (isSameType.execute(lib.getLazyPythonClass(other), PythonBuiltinClassType.PString)) {
467+
isSameBranch.enter();
468+
return other;
469+
}
470+
return materializeNode.execute(other);
443471
}
444-
return self;
472+
if (isSameType.execute(lib.getLazyPythonClass(self), PythonBuiltinClassType.PString)) {
473+
isSameBranch.enter();
474+
return self;
475+
}
476+
return materializeNode.execute(self);
445477
}
446478

447479
@Specialization(guards = "concatGuard(self.getCharSequence(), other)")

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,8 @@ public abstract class ErrorMessages {
156156
public static final String CHARACTER_MAPPING_MUST_RETURN_INT_NONE_OR_STR = "character mapping must return integer, None or str";
157157
public static final String CHR_DOES_NOT_SUPPORT = "chr does not support PInt ";
158158
public static final String CLASS_ASIGMENT_S_LAYOUT_DIFFERS_FROM_S = "__class__ assignment: '%s' object layout differs from '%s'";
159-
public static final String CLASS_ASSIGMENT_ONLY_SUPPORTED_FOR_HEAP_TYPES_OR_MODTYPE_SUBCLASSES = "__class__ assignment only supported for heap types or ModuleType subclasses, not '%p'";
159+
public static final String CLASS_ASSIGMENT_ONLY_SUPPORTED_FOR_HEAP_TYPES_OR_MODTYPE_SUBCLASSES = "__class__ assignment only supported for heap types or ModuleType subclasses";
160+
public static final String CLASS_ASSIGMENT_ONLY_SUPPORTED_FOR_HEAP_TYPES_OR_MODTYPE_SUBCLASSES_NOT_P = "__class__ assignment only supported for heap types or ModuleType subclasses, not '%p'";
160161
public static final String CLASS_MUST_BE_SET_TO_CLASS = "__class__ must be set to a class, not '%p' object";
161162
public static final String MUST_BE_SET_TO_S_NOT_P = "%s must be set to a %s, not a '%p'";
162163
public static final String CLASSPATH_ARG_MUST_BE_STRING = "classpath argument %d must be string, not %p";

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ private T formatImpl(Object args1) {
494494
* of range; if a special value, it would be wrong if it were -1, indicating a single item
495495
* that has not yet been used.
496496
*/
497-
if (argIndex == -1 || (argIndex >= 0 && PythonObjectLibrary.getUncached().length(args1) > argIndex + 1)) {
497+
if (argIndex == -1 || (argIndex >= 0 && PythonObjectLibrary.getUncached().length(args1) >= argIndex + 1)) {
498498
throw core.raise(TypeError, ErrorMessages.NOT_ALL_ARGS_CONVERTED_DURING_FORMATTING, getFormatType());
499499
}
500500

0 commit comments

Comments
 (0)