Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Additionally, one can change the polyglot artifacts version with
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<com.oracle.graal.python.test.polyglot.version>25.1.3</com.oracle.graal.python.test.polyglot.version>
<com.oracle.graal.python.test.polyglot.version>25.2.3</com.oracle.graal.python.test.polyglot.version>
</properties>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2025, Oracle and/or its affiliates.
* Copyright (c) 2017, 2026, Oracle and/or its affiliates.
* Copyright (c) 2013, Regents of the University of California
*
* All rights reserved.
Expand Down Expand Up @@ -76,17 +76,21 @@ public static Context enterContext(Map<String, String> options, String[] args) {
return context;
}

private static void closeContext(Context ctxt) {
private static void closeContext(Context ctxt, boolean cancelIfExecuting) {
try {
ctxt.leave();
} catch (RuntimeException e) {
}
ctxt.close();
ctxt.close(cancelIfExecuting);
}

public static void closeContext() {
closeContext(false);
}

public static void closeContext(boolean cancelIfExecuting) {
if (context != null) {
closeContext(context);
closeContext(context, cancelIfExecuting);
context = null;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down Expand Up @@ -68,11 +68,12 @@ public void threadPool() {
"pool = ThreadPool(2)\n" +
"res = list(pool.imap(fun, items))\n" +
"pool.close()\n" +
"pool.join()\n" +
"\n" +
"print(res)\n";
final ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
final PrintStream printStream = new PrintStream(byteArray);
PythonTests.runScript(new HashMap<>(), new String[0], source, printStream, System.err, () -> PythonTests.closeContext());
PythonTests.runScript(new HashMap<>(), new String[0], source, printStream, System.err, () -> PythonTests.closeContext(true));
String result = byteArray.toString().replaceAll("\r\n", "\n");
assertEquals("[True, True, True, True, True, True, True, True, True, True]\n", result);
}
Expand Down
17 changes: 17 additions & 0 deletions graalpython/com.oracle.graal.python.test/src/tests/test_bytes.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

import base64
import sys
import unittest

Expand Down Expand Up @@ -629,6 +630,22 @@ def test_strip_bytes():
assert b'abc'.lstrip(b'ac') == b'bc'
assert b'abc'.rstrip(b'ac') == b'ab'


def test_strip_default_whitespace():
whitespace = b'\x09\x0a\x0b\x0c\x0d '
non_whitespace = b'\x1c\x1d\x1e\x1f'
for type2test in (bytes, bytearray):
value = type2test(whitespace + non_whitespace + whitespace)
assert value.strip() == non_whitespace
assert value.lstrip() == non_whitespace + whitespace
assert value.rstrip() == whitespace + non_whitespace


def test_strip_base32_result_with_control_bytes():
value = base64.b32decode(b'INFAO2ZW7APB2===')
assert value == b'CJ\x07k6\xf8\x1e\x1d'
assert value.strip() == value

class BaseTestSplit:

def test_string_error(self):
Expand Down
19 changes: 10 additions & 9 deletions graalpython/com.oracle.graal.python.test/src/tests/test_posix.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,16 +272,17 @@ def test_open_bytes_path(self):

def test_failed_read_write_errno(self):
read_fd, write_fd = os.pipe()
os.close(read_fd)
os.close(write_fd)

with self.assertRaises(OSError) as read_error:
os.read(read_fd, 1)
self.assertEqual(errno.EBADF, read_error.exception.errno)
try:
with self.assertRaises(OSError) as read_error:
os.read(write_fd, 1)
self.assertEqual(errno.EBADF, read_error.exception.errno)

with self.assertRaises(OSError) as write_error:
os.write(write_fd, b'x')
self.assertEqual(errno.EBADF, write_error.exception.errno)
with self.assertRaises(OSError) as write_error:
os.write(read_fd, b'x')
self.assertEqual(errno.EBADF, write_error.exception.errno)
finally:
os.close(read_fd)
os.close(write_fd)

def test_fd_converter(self):
class MyInt(int):
Expand Down
9 changes: 9 additions & 0 deletions graalpython/com.oracle.graal.python.test/src/tests/test_re.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,15 @@ def test_re_subn(self):
self.assertEqual(re.subn("b*", "x", "xyz", 2), ('xxxyz', 2))
self.assertEqual(re.subn("b*", "x", "xyz", count=2), ('xxxyz', 2))

def test_terminal_empty_match_after_consuming_match(self):
cases = [
(r"(?:(?P<g0>\*)){0,2}", "*"),
(r"(?:(?:\s){0,2}){0,2}", " "),
]
for pattern, string in cases:
self.assertEqual(re.sub(pattern, "X", string), "XX")
self.assertEqual(re.subn(pattern, "X", string), ("XX", 2))

def test_re_split(self):
for string in ":a:b::c", S(":a:b::c"):
self.assertTypedEqual(re.split(":", string),
Expand Down
28 changes: 28 additions & 0 deletions graalpython/com.oracle.graal.python.test/src/tests/test_repr.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,34 @@ def __repr__(self):
assert str(e) == "__repr__ returned non-string (type int)"


def test_numeric_str_uses_overridden_repr():
class IntSubclass(int):
def __repr__(self):
return "IntSubclass"

class FloatSubclass(float):
def __repr__(self):
return "FloatSubclass"

class ComplexSubclass(complex):
def __repr__(self):
return "ComplexSubclass"

for numeric_type in (int, float, bool, complex):
assert numeric_type.__str__ is object.__str__

for value, expected in (
(IntSubclass(), "IntSubclass"),
(FloatSubclass(), "FloatSubclass"),
(ComplexSubclass(), "ComplexSubclass"),
):
assert repr(value) == expected
assert str(value) == expected

assert str(True) == "True"
assert repr(True) == "True"


def test_repr_deep_userlist_raises_recursion_error():
a = UserList([])
for _ in range(REPR_RECURSION_LIMIT + 10):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1191,7 +1191,7 @@ private static Object doReplace(Object compiledRegex, Object compiledRegexMustAd
int n = 0;
int pos = 0;
boolean mustAdvance = false;
while ((count == 0 || n < count) && pos < stringLength) {
while ((count == 0 || n < count) && pos <= stringLength) {
final Object searchResult;
if (mustAdvance) {
searchResult = invokeExecMethodNodeMustAdvance.execute(inliningTarget, compiledRegexMustAdvance, input, pos);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2025, Oracle and/or its affiliates.
* Copyright (c) 2017, 2026, Oracle and/or its affiliates.
* Copyright (c) 2014, Regents of the University of California
*
* All rights reserved.
Expand Down Expand Up @@ -76,7 +76,7 @@ public static boolean bool(VirtualFrame frame, @SuppressWarnings("unused") Objec
}
}

@Slot(value = SlotKind.tp_str, isComplex = true)
@Slot(value = SlotKind.tp_repr, isComplex = true)
@TypeSystemReference(PythonIntegerTypes.class)
@GenerateNodeFactory
abstract static class StrNode extends PythonUnaryBuiltinNode {
Expand All @@ -96,11 +96,6 @@ public static TruffleString doPInt(PInt self) {
}
}

@Slot(value = SlotKind.tp_repr, isComplex = true)
@GenerateNodeFactory
abstract static class RepNode extends StrNode {
}

@Slot(value = SlotKind.nb_and, isComplex = true)
@GenerateNodeFactory
abstract static class AndNode extends BinaryOpBuiltinNode {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1922,7 +1922,7 @@ protected int findIndex(byte[] bs) {

@TruffleBoundary
private static boolean isWhitespace(byte b) {
return Character.isWhitespace(b);
return BytesUtils.isSpace(b);
}

protected int findIndex(byte[] bs, byte[] stripBs, int stripBsLen) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ protected static boolean isPrimitiveFloat(Node inliningTarget, Object cls, Built
}
}

@Slot(value = SlotKind.tp_str, isComplex = true)
@Slot(value = SlotKind.tp_repr, isComplex = true)
@GenerateNodeFactory
public abstract static class StrNode extends AbstractNumericUnaryBuiltin {
public static final Spec spec = new Spec(' ', '>', Spec.NONE, false, Spec.UNSPECIFIED, Spec.NONE, 0, 'r');
Expand All @@ -343,11 +343,6 @@ public static TruffleString doFormat(double d, FloatFormatter f) {
}
}

@Slot(value = SlotKind.tp_repr, isComplex = true)
@GenerateNodeFactory
abstract static class ReprNode extends StrNode {
}

@Builtin(name = J___FORMAT__, minNumOfPositionalArgs = 2, parameterNames = {"$self", "format_spec"})
@ArgumentClinic(name = "format_spec", conversion = ClinicConversion.TString)
@GenerateNodeFactory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2534,7 +2534,7 @@ static boolean toBoolean(PInt self) {
}
}

@Slot(value = SlotKind.tp_str, isComplex = true)
@Slot(value = SlotKind.tp_repr, isComplex = true)
@GenerateNodeFactory
@TypeSystemReference(PythonIntegerTypes.class)
abstract static class StrNode extends PythonUnaryBuiltinNode {
Expand Down Expand Up @@ -2592,11 +2592,6 @@ private static int positiveBitLength(PInt self) {
}
}

@Slot(value = SlotKind.tp_repr, isComplex = true)
@GenerateNodeFactory
abstract static class ReprNode extends StrNode {
}

@Builtin(name = J___FORMAT__, minNumOfPositionalArgs = 2, parameterNames = {"$self", "format_spec"})
@ArgumentClinic(name = "format_spec", conversion = ClinicConversion.TString)
@GenerateNodeFactory
Expand Down
19 changes: 15 additions & 4 deletions mx.graalpython/mx_graalpython_python_benchmarks.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,26 @@

def add_cpython_build_env(env=None):
if python3_home := os.environ.get("PYTHON3_HOME"):
include_dir = join(python3_home, "Include")
if os.path.exists(join(include_dir, "Python.h")):
checkout_include = join(python3_home, "Include")
installed_includes = sorted(glob.glob(join(python3_home, os.pardir, "include", "python*")))
include_dir = next(
(path for path in [checkout_include, *installed_includes] if os.path.exists(join(path, "Python.h"))),
None,
)
if include_dir:
env = env.copy() if env is not None else os.environ.copy()
python_includes = os.pathsep.join([include_dir, python3_home])
include_dirs = [include_dir]
if include_dir == checkout_include:
include_dirs.append(python3_home)
python_includes = os.pathsep.join(include_dirs)
include_flags = " ".join(f"-I{path}" for path in python_includes.split(os.pathsep))
env["CPATH"] = python_includes + (os.pathsep + env["CPATH"] if env.get("CPATH") else "")
for key in ["CFLAGS", "CPPFLAGS", "CXXFLAGS"]:
env[key] = include_flags + (" " + env[key] if env.get(key) else "")
env["LIBRARY_PATH"] = python3_home + (os.pathsep + env["LIBRARY_PATH"] if env.get("LIBRARY_PATH") else "")
lib_dir = join(python3_home, os.pardir, "lib")
if not os.path.isdir(lib_dir):
lib_dir = python3_home
env["LIBRARY_PATH"] = lib_dir + (os.pathsep + env["LIBRARY_PATH"] if env.get("LIBRARY_PATH") else "")
return env


Expand Down
Loading