From 8d42af5cb40b06fe9a419b5493ad67a041087be3 Mon Sep 17 00:00:00 2001 From: Jeongseop Lim Date: Fri, 30 Oct 2026 03:03:43 +0900 Subject: [PATCH] Add math.cbrt() and math.exp2() Both functions were added to the math module in Python 3.11 and were missing, so math.cbrt and math.exp2 raised AttributeError. cbrt uses Math.cbrt; exp2 uses Math.pow(2.0, x) and raises OverflowError on an infinite result from a finite argument, as exp does. Enable CPython's testCbrt and testExp2, which now pass. Signed-off-by: Jeongseop Lim --- .../src/tests/unittest_tags/test_math.txt | 2 ++ .../builtins/modules/MathModuleBuiltins.java | 34 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_math.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_math.txt index 538e088a16..170c54c851 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_math.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_math.txt @@ -23,6 +23,7 @@ test.test_math.MathTests.testAsinh @ darwin-arm64,linux-aarch64,linux-aarch64-gi test.test_math.MathTests.testAtan @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github test.test_math.MathTests.testAtan2 @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github test.test_math.MathTests.testAtanh @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github +test.test_math.MathTests.testCbrt @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github test.test_math.MathTests.testCeil @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github test.test_math.MathTests.testComb @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github test.test_math.MathTests.testConstants @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github @@ -32,6 +33,7 @@ test.test_math.MathTests.testCosh @ darwin-arm64,linux-aarch64,linux-aarch64-git test.test_math.MathTests.testDegrees @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github test.test_math.MathTests.testDist @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github test.test_math.MathTests.testExp @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github +test.test_math.MathTests.testExp2 @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github test.test_math.MathTests.testFabs @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github test.test_math.MathTests.testFactorial @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github test.test_math.MathTests.testFactorialNonIntegers @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MathModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MathModuleBuiltins.java index 029f6ac3cf..4f97e2fb64 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MathModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MathModuleBuiltins.java @@ -255,6 +255,22 @@ private static double compute(Node inliningTarget, double value, PRaiseNode rais } } + @Builtin(name = "cbrt", minNumOfPositionalArgs = 1, doc = "Return the cube root of x.") + @GenerateNodeFactory + public abstract static class CbrtNode extends PythonUnaryBuiltinNode { + + @Specialization + static double doGeneric(VirtualFrame frame, Object value, + @Bind Node inliningTarget, + @Cached MathUnaryHelperNode helperNode) { + return helperNode.execute(frame, inliningTarget, value, CbrtNode::compute); + } + + private static double compute(Node inliningTarget, double value, PRaiseNode raiseNode) { + return Math.cbrt(value); + } + } + @Builtin(name = "exp", minNumOfPositionalArgs = 1) @GenerateNodeFactory public abstract static class ExpNode extends PythonUnaryBuiltinNode { @@ -273,6 +289,24 @@ private static double compute(Node inliningTarget, double value, PRaiseNode rais } } + @Builtin(name = "exp2", minNumOfPositionalArgs = 1, doc = "Return 2 raised to the power of x.") + @GenerateNodeFactory + public abstract static class Exp2Node extends PythonUnaryBuiltinNode { + + @Specialization + static double doGeneric(VirtualFrame frame, Object value, + @Bind Node inliningTarget, + @Cached MathUnaryHelperNode helperNode) { + return helperNode.execute(frame, inliningTarget, value, Exp2Node::compute); + } + + private static double compute(Node inliningTarget, double value, PRaiseNode raiseNode) { + double result = Math.pow(2.0, value); + checkMathRangeError(Double.isFinite(value) && Double.isInfinite(result), inliningTarget, raiseNode); + return result; + } + } + @Builtin(name = "expm1", minNumOfPositionalArgs = 1) @GenerateNodeFactory public abstract static class Expm1Node extends PythonUnaryBuiltinNode {