Skip to content

Commit 0466628

Browse files
committed
Merge branch 'master'
2 parents d35c1b0 + c29f564 commit 0466628

37 files changed

+838
-440
lines changed

docs/contributor/CONTRIBUTING.md

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -167,16 +167,11 @@ implementation isn't quite ready, so you have to put the flags somewhere else to
167167
debug. You can see `-debug-java` and `--inspect` below, to debug in Java
168168
debugger or Chromium, respectively.
169169

170-
ENABLE_CPYTHON_TAGGED_UNITTESTS=true mx python3 \
171-
graalpython/com.oracle.graal.python.test/src/graalpytest.py \
172-
[-debug-java] [--inspect] \
173-
graalpython/com.oracle.graal.python.test/src/tests/test_tagged_unittests.py \
174-
-k NAME-OF-CPYTHON-UNITTEST
170+
mx python-run-cpython-unittest [-debug-java] [--inspect] NAME-OF-CPYTHON-UNITTEST
175171

176172
A tag file can be regenerated with
177173

178-
mx python graalpython/com.oracle.graal.python.test/src/tests/test_tagged_unittests.py \
179-
--retag NAME-OF-CPYTHON-UNITTEST
174+
mx python-retag-unittests NAME-OF-CPYTHON-UNITTEST
180175

181176
There's also multiple other gates that may fail with changes. One of these is
182177
our *style* gate, which checks formatting rules and copyrights. To auto-fix most

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

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,16 @@ def test_formatting():
8484
# because the object is considered as a mapping...
8585
assert " " % MyPseudoMapping() == " "
8686

87+
# Localized format still honors the sign specifier
88+
assert format(1234.5, "+n").startswith("+")
89+
90+
91+
class MyComplex(complex):
92+
def __repr__(self):
93+
return 'wrong answer'
94+
def __str__(self):
95+
return '42'
96+
8797

8898
def test_complex_formatting():
8999
assert format(3+2j, ">20,.4f") == " 3.0000+2.0000j"
@@ -102,6 +112,8 @@ def test_complex_formatting():
102112
assert format(1+2j, "") == "(1+2j)"
103113
assert format(complex(1, float("NaN")), "") == "(1+nanj)"
104114
assert format(complex(1, float("Inf")), "") == "(1+infj)"
115+
assert format(MyComplex(3j), "") == "42"
116+
assert format(MyComplex(3j), " <5") == "3j "
105117

106118

107119
class AnyRepr:
@@ -147,11 +159,29 @@ def test_formatting_errors(self):
147159
self.assertRaises(ValueError, lambda: format(3+2j, "0=30,.4f"))
148160

149161

150-
class MyFloat(float):
151-
def __str__(self):
152-
return "__str__ overridden for float"
162+
def test_overridden_str():
163+
class MyInt(int):
164+
def __str__(self):
165+
return '42'
153166

167+
class MyFloat(float):
168+
def __str__(self):
169+
return "__str__ overridden for float"
154170

155-
def test_overridden_str():
171+
# floats w/o type specifier, but with other flags should produce
172+
# something like __str__ but not actually call __str__. Only when
173+
# the formatting string is empty it calls actual __str__.
156174
assert "{}".format(MyFloat(2)) == "__str__ overridden for float"
157175
assert "{0:10}".format(MyFloat(2)) == " 2.0"
176+
assert format(MyFloat(2), "") == "__str__ overridden for float"
177+
assert format(MyFloat(2), "5") == " 2.0"
178+
179+
assert format(10000.0, '_') == "10_000.0"
180+
assert format(10000.0, '') == "10000.0"
181+
# if precision is set use '%g' instead of the __str__ like formatting:
182+
assert format(10000.0, "+,.3") == "+1e+04"
183+
184+
assert "{}".format(MyInt(2)) == "42"
185+
assert "{0:10}".format(MyInt(2)) == " 2"
186+
assert format(MyInt(2), "") == "42"
187+
assert format(MyInt(2), "5") == " 2"

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,16 @@
66
*graalpython.lib-python.3.test.test_builtin.BuiltinTest.test_bytearray_translate
77
*graalpython.lib-python.3.test.test_builtin.BuiltinTest.test_callable
88
*graalpython.lib-python.3.test.test_builtin.BuiltinTest.test_cmp
9+
*graalpython.lib-python.3.test.test_builtin.BuiltinTest.test_compile_async_generator
10+
*graalpython.lib-python.3.test.test_builtin.BuiltinTest.test_compile_top_level_await
11+
*graalpython.lib-python.3.test.test_builtin.BuiltinTest.test_construct_singletons
912
*graalpython.lib-python.3.test.test_builtin.BuiltinTest.test_delattr
13+
*graalpython.lib-python.3.test.test_builtin.BuiltinTest.test_eval
1014
*graalpython.lib-python.3.test.test_builtin.BuiltinTest.test_exec
1115
*graalpython.lib-python.3.test.test_builtin.BuiltinTest.test_exec_redirected
1216
*graalpython.lib-python.3.test.test_builtin.BuiltinTest.test_filter
1317
*graalpython.lib-python.3.test.test_builtin.BuiltinTest.test_filter_pickle
18+
*graalpython.lib-python.3.test.test_builtin.BuiltinTest.test_general_eval
1419
*graalpython.lib-python.3.test.test_builtin.BuiltinTest.test_hex
1520
*graalpython.lib-python.3.test.test_builtin.BuiltinTest.test_id
1621
*graalpython.lib-python.3.test.test_builtin.BuiltinTest.test_isinstance
@@ -45,3 +50,5 @@
4550
*graalpython.lib-python.3.test.test_builtin.TestBreakpoint.test_envar_unimportable
4651
*graalpython.lib-python.3.test.test_builtin.TestSorted.test_basic
4752
*graalpython.lib-python.3.test.test_builtin.TestSorted.test_inputtypes
53+
*graalpython.lib-python.3.test.test_builtin.TestType.test_type_doc
54+
*graalpython.lib-python.3.test.test_builtin.TestType.test_type_nokwargs

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
*graalpython.lib-python.3.test.test_float.FormatTestCase.test_issue35560
66
*graalpython.lib-python.3.test.test_float.FormatTestCase.test_issue5864
77
*graalpython.lib-python.3.test.test_float.GeneralFloatCases.test_float_containment
8-
*graalpython.lib-python.3.test.test_float.GeneralFloatCases.test_float_with_comma
98
*graalpython.lib-python.3.test.test_float.GeneralFloatCases.test_floatasratio
109
*graalpython.lib-python.3.test.test_float.GeneralFloatCases.test_keyword_args
1110
*graalpython.lib-python.3.test.test_float.HexFloatTestCase.test_ends

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
*graalpython.lib-python.3.test.test_format.FormatTest.test_str_format
33
*graalpython.lib-python.3.test.test_format.FormatTest.test_bytes_and_bytearray_format
44
*graalpython.lib-python.3.test.test_format.FormatTest.test_nul
5+
*graalpython.lib-python.3.test.test_format.FormatTest.test_non_ascii
6+
*graalpython.lib-python.3.test.test_format.FormatTest.test_locale
57
*graalpython.lib-python.3.test.test_format.FormatTest.test_optimisations
68
*graalpython.lib-python.3.test.test_format.FormatTest.test_precision
79
*graalpython.lib-python.3.test.test_format.FormatTest.test_precision_c_limits

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*graalpython.lib-python.3.test.test_long.LongTest.test_karatsuba
1616
*graalpython.lib-python.3.test.test_long.LongTest.test_logs
1717
*graalpython.lib-python.3.test.test_long.LongTest.test_long
18+
*graalpython.lib-python.3.test.test_long.LongTest.test_format
1819
*graalpython.lib-python.3.test.test_long.LongTest.test_lshift_of_zero
1920
*graalpython.lib-python.3.test.test_long.LongTest.test_mod_division
2021
*graalpython.lib-python.3.test.test_long.LongTest.test_nan_inf

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

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError;
8585

8686
import java.math.BigInteger;
87+
import java.nio.charset.StandardCharsets;
8788
import java.util.Arrays;
8889
import java.util.List;
8990
import java.util.Locale;
@@ -160,6 +161,7 @@
160161
import com.oracle.graal.python.nodes.BuiltinNames;
161162
import com.oracle.graal.python.nodes.ErrorMessages;
162163
import com.oracle.graal.python.nodes.PGuards;
164+
import com.oracle.graal.python.nodes.SpecialAttributeNames;
163165
import com.oracle.graal.python.nodes.SpecialMethodNames;
164166
import com.oracle.graal.python.nodes.attributes.GetAttributeNode;
165167
import com.oracle.graal.python.nodes.attributes.GetAttributeNode.GetAnyAttributeNode;
@@ -2146,23 +2148,24 @@ public abstract static class TypeNode extends PythonBuiltinNode {
21462148
@Specialization(guards = {"isNoValue(bases)", "isNoValue(dict)"})
21472149
@SuppressWarnings("unused")
21482150
Object type(Object cls, Object obj, PNone bases, PNone dict, PKeyword[] kwds,
2149-
@Cached("create()") GetClassNode getClass) {
2151+
@Cached GetClassNode getClass) {
21502152
return getClass.execute(obj);
21512153
}
21522154

2153-
@Specialization
2154-
Object type(VirtualFrame frame, Object cls, String name, PTuple bases, PDict namespace, PKeyword[] kwds,
2155+
@Specialization(guards = "isString(wName)")
2156+
Object typeNew(VirtualFrame frame, Object cls, Object wName, PTuple bases, PDict namespace, PKeyword[] kwds,
21552157
@CachedLibrary(limit = "4") PythonObjectLibrary lib,
2156-
@CachedLibrary(limit = "1") HashingStorageLibrary nslib,
2157-
@CachedLibrary(limit = "1") HashingStorageLibrary glib,
2158+
@CachedLibrary(limit = "2") HashingStorageLibrary nslib,
21582159
@Cached BranchProfile updatedStorage,
21592160
@Cached("create(__NEW__)") LookupInheritedAttributeNode getNewFuncNode,
21602161
@Cached("create(__INIT_SUBCLASS__)") GetAttributeNode getInitSubclassNode,
21612162
@Cached("create(__SET_NAME__)") LookupInheritedAttributeNode getSetNameNode,
2163+
@Cached CastToJavaStringNode castStr,
21622164
@Cached CallNode callSetNameNode,
21632165
@Cached CallNode callInitSubclassNode,
21642166
@Cached CallNode callNewFuncNode) {
21652167
// Determine the proper metatype to deal with this
2168+
String name = castStr.execute(wName);
21662169
Object metaclass = calculate_metaclass(frame, cls, bases, lib);
21672170
if (metaclass != cls) {
21682171
Object newFunc = getNewFuncNode.execute(metaclass);
@@ -2195,7 +2198,7 @@ Object type(VirtualFrame frame, Object cls, String name, PTuple bases, PDict nam
21952198
PFrame callerFrame = getReadCallerFrameNode().executeWith(frame, 0);
21962199
PythonObject globals = callerFrame.getGlobals();
21972200
if (globals != null) {
2198-
String moduleName = getModuleNameFromGlobals(globals, glib);
2201+
String moduleName = getModuleNameFromGlobals(globals, nslib);
21992202
if (moduleName != null) {
22002203
ensureWriteAttrNode().execute(frame, newType, __MODULE__, moduleName);
22012204
}
@@ -2225,6 +2228,19 @@ Object type(VirtualFrame frame, Object cls, String name, PTuple bases, PDict nam
22252228
}
22262229
}
22272230

2231+
@Fallback
2232+
Object generic(@SuppressWarnings("unused") Object cls, @SuppressWarnings("unused") Object name, Object bases, Object namespace, @SuppressWarnings("unused") Object kwds) {
2233+
if (!(bases instanceof PTuple)) {
2234+
throw raise(TypeError, ErrorMessages.ARG_D_MUST_BE_S_NOT_P, "type.__new__()", 2, "tuple", bases);
2235+
} else if (namespace == PNone.NO_VALUE) {
2236+
throw raise(TypeError, ErrorMessages.TAKES_D_OR_D_ARGS, "type()", 1, 3);
2237+
} else if (!(namespace instanceof PDict)) {
2238+
throw raise(TypeError, ErrorMessages.ARG_D_MUST_BE_S_NOT_P, "type.__new__()", 3, "dict", bases);
2239+
} else {
2240+
throw CompilerDirectives.shouldNotReachHere("type fallback reached incorrectly");
2241+
}
2242+
}
2243+
22282244
private String getModuleNameFromGlobals(PythonObject globals, HashingStorageLibrary hlib) {
22292245
Object nameAttr;
22302246
if (globals instanceof PythonModule) {
@@ -2295,6 +2311,22 @@ private PythonClass typeMetaclass(VirtualFrame frame, String name, PTuple bases,
22952311
} else {
22962312
pythonClass.setAttribute(key, value);
22972313
}
2314+
} else if (SpecialAttributeNames.__DOC__.equals(key)) {
2315+
// CPython sets tp_doc to a copy of dict['__doc__'], if that is a string. It
2316+
// forcibly encodes the string as UTF-8, and raises an error if that is not
2317+
// possible.
2318+
String doc = null;
2319+
if (value instanceof String) {
2320+
doc = (String) value;
2321+
} else if (value instanceof PString) {
2322+
doc = ((PString) value).getValue();
2323+
}
2324+
if (doc != null) {
2325+
if (!canEncode(doc)) {
2326+
throw raise(PythonBuiltinClassType.UnicodeEncodeError, ErrorMessages.CANNOT_ENCODE_DOCSTR, doc);
2327+
}
2328+
}
2329+
pythonClass.setAttribute(key, value);
22982330
} else {
22992331
pythonClass.setAttribute(key, value);
23002332
}
@@ -2365,6 +2397,11 @@ private PythonClass typeMetaclass(VirtualFrame frame, String name, PTuple bases,
23652397
return pythonClass;
23662398
}
23672399

2400+
@TruffleBoundary
2401+
private static boolean canEncode(String doc) {
2402+
return StandardCharsets.UTF_8.newEncoder().canEncode(doc);
2403+
}
2404+
23682405
@TruffleBoundary
23692406
private PTuple copySlots(String className, SequenceStorage slotList, int slotlen, boolean add_dict, boolean add_weak, PDict namespace, HashingStorageLibrary nslib) {
23702407
SequenceStorage newSlots = new ObjectSequenceStorage(slotlen - PInt.intValue(add_dict) - PInt.intValue(add_weak));
@@ -2659,44 +2696,30 @@ Object doNative(PythonAbstractNativeObject self, Object[] varargs, PKeyword[] kw
26592696
@Builtin(name = "NotImplementedType", minNumOfPositionalArgs = 1, constructsClass = PythonBuiltinClassType.PNotImplemented, isPublic = false)
26602697
@GenerateNodeFactory
26612698
public abstract static class NotImplementedTypeNode extends PythonBuiltinNode {
2662-
protected PythonBuiltinClass getNotImplementedClass() {
2663-
return getCore().lookupType(PythonBuiltinClassType.PNotImplemented);
2664-
}
2665-
2699+
@SuppressWarnings("unused")
26662700
@Specialization
26672701
public PNotImplemented module(Object cls) {
2668-
if (cls != getNotImplementedClass()) {
2669-
throw raise(TypeError, ErrorMessages.OBJ_ISNT_CALLABLE, "NotImplementedType");
2670-
} else {
2671-
return PNotImplemented.NOT_IMPLEMENTED;
2672-
}
2702+
return PNotImplemented.NOT_IMPLEMENTED;
26732703
}
26742704
}
26752705

2676-
@Builtin(name = "ellipsis", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PEllipsis, isPublic = false)
2706+
@Builtin(name = "ellipsis", minNumOfPositionalArgs = 1, constructsClass = PythonBuiltinClassType.PEllipsis, isPublic = false)
26772707
@GenerateNodeFactory
26782708
public abstract static class EllipsisTypeNode extends PythonBuiltinNode {
26792709
@SuppressWarnings("unused")
26802710
@Specialization
2681-
public PEllipsis call(Object cls, Object args, Object kwds) {
2711+
public PEllipsis call(Object cls) {
26822712
return PEllipsis.INSTANCE;
26832713
}
26842714
}
26852715

26862716
@Builtin(name = "NoneType", minNumOfPositionalArgs = 1, constructsClass = PythonBuiltinClassType.PNone, isPublic = false)
26872717
@GenerateNodeFactory
26882718
public abstract static class NoneTypeNode extends PythonBuiltinNode {
2689-
protected PythonBuiltinClass getNoneClass() {
2690-
return getCore().lookupType(PythonBuiltinClassType.PNone);
2691-
}
2692-
2719+
@SuppressWarnings("unused")
26932720
@Specialization
26942721
public PNone module(Object cls) {
2695-
if (cls != getNoneClass()) {
2696-
throw raise(TypeError, ErrorMessages.IS_NOT_SUBTYPE_OF, "NoneType.__new__", cls, "NoneType");
2697-
} else {
2698-
return PNone.NONE;
2699-
}
2722+
return PNone.NONE;
27002723
}
27012724
}
27022725

0 commit comments

Comments
 (0)