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
52 changes: 50 additions & 2 deletions graalpython/com.oracle.graal.python.test/src/tests/test_array.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2018, 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 @@ -37,6 +37,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

import copy
import types
from array import array

from tests.util import storage_to_native
Expand Down Expand Up @@ -112,11 +114,57 @@ def test_array_native_storage():
a.insert(1, -1)
assert a == array('l', [1, -1, 3])


def test_copy():
a = array('l', [1, 2, 3])
b = a.__copy__()
c = copy.copy(a)
assert type(b) is array
assert b == a
assert c == a
assert b is not a
assert c is not a
a[0] = 42
assert b == array('l', [1, 2, 3])
assert c == array('l', [1, 2, 3])


def test_copy_native_storage():
a = array('l', [1, 2, 3])
storage_to_native(a)
b = a.__copy__()
assert b == a
a[1] = 42
assert b == array('l', [1, 2, 3])


def test_deepcopy():
a = array('l', [1, 2, 3])
b = a.__deepcopy__({})
c = copy.deepcopy(a)
assert type(b) is array
assert b == a
assert c == a
assert b is not a
assert c is not a
a[0] = 42
assert b == array('l', [1, 2, 3])
assert c == array('l', [1, 2, 3])


def test_class_getitem():
alias = array[int]
assert isinstance(alias, types.GenericAlias)
assert alias.__origin__ is array
assert alias.__args__ == (int,)
assert array.__class_getitem__(str).__args__ == (str,)


def test_mul():
a = array('l', [1, 2, 3])
assert len(a * 0) == 0

b = a * 1
a[2] = 42
assert list(a) == [1, 2, 42]
assert list(b) == [1, 2, 3]
assert list(b) == [1, 2, 3]
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2019, 2022, Oracle and/or its affiliates.
# Copyright (c) 2019, 2026, Oracle and/or its affiliates.
# Copyright (C) 1996-2017 Python Software Foundation
#
# Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
Expand Down Expand Up @@ -104,15 +104,15 @@ def keyfunc(obj):

def test_generators(self):
# test that generators are accepted like input values

def g(seqn):
for i in seqn:
yield i

def g2(seqn):
for i in seqn:
yield (i, i)

self.assertEqual(list(accumulate(g([1,2]))), [1, 3])
self.assertEqual(list(chain(g([1,2]), g([3,4]))), [1, 2, 3, 4])
self.assertEqual(list(combinations(g([1,2]), 2)), [(1, 2)])
Expand All @@ -130,6 +130,10 @@ def g2(seqn):
self.assertEqual(list(tee(g([1, 2]))[0]), [1, 2])
self.assertEqual(list(zip_longest(g2([2,3]))), [((2, 2),), ((3, 3),)])

def test_islice_negative_stop(self):
self.assertRaises(ValueError, islice, count(), -1)
self.assertRaises(ValueError, islice, count(), 0, -1)

@unittest.skipIf(sys.implementation.name == 'cpython' and sys.version_info[0:2] < (3, 10), "skipping for cPython versions < 3.10")
def test_pairwise_drained(self):
p = pairwise("abcd")
Expand Down
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 ast
import linecache
import subprocess
import sys

Expand Down Expand Up @@ -104,6 +105,32 @@ def test():
)


def test_traceback_from_ast_without_end_positions():
import traceback

filename = "<ast without end positions>"
source = "def f():\n value = None\n raise AssertionError\n"
linecache.cache[filename] = (len(source), None, source.splitlines(True), filename)
tree = ast.parse(source, filename)
for node in ast.walk(tree):
if hasattr(node, "end_lineno"):
node.end_lineno = None
node.end_col_offset = None

namespace = {}
exec(compile(tree, filename, "exec"), namespace)
try:
namespace["f"]()
except AssertionError:
stack = traceback.TracebackException(*sys.exc_info()).stack
else:
assert False, "generated function did not raise"

assert stack[-1].name == "f"
assert stack[-1].lineno == 3
assert stack[-1].line == "raise AssertionError"


def test_basic_traceback_generator():
def foo():
yield 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
import static com.oracle.graal.python.nodes.ErrorMessages.S_TAKES_AT_MOST_D_ARGUMENTS_D_GIVEN;
import static com.oracle.graal.python.nodes.ErrorMessages.S_TAKES_NO_KEYWORD_ARGS;
import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DICT__;
import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CLASS_GETITEM__;
import static com.oracle.graal.python.nodes.SpecialMethodNames.J___COPY__;
import static com.oracle.graal.python.nodes.SpecialMethodNames.J___DEEPCOPY__;
import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE_EX__;
import static com.oracle.graal.python.nodes.StringLiterals.T_COMMA_SPACE;
import static com.oracle.graal.python.nodes.StringLiterals.T_LBRACKET;
Expand Down Expand Up @@ -984,6 +987,51 @@ static Object bufferinfo(PArray self,
}
}

@Builtin(name = J___COPY__, minNumOfPositionalArgs = 1)
@GenerateNodeFactory
abstract static class CopyNode extends PythonUnaryBuiltinNode {
@Specialization
static PArray copy(PArray self,
@CachedLibrary(limit = "2") PythonBufferAccessLibrary bufferLib,
@Bind PythonLanguage language) {
return copyArray(self, bufferLib, language);
}
}

@Builtin(name = J___DEEPCOPY__, minNumOfPositionalArgs = 2, parameterNames = {"$self", "memo"})
@GenerateNodeFactory
abstract static class DeepCopyNode extends PythonBinaryBuiltinNode {
@Specialization
static PArray copy(PArray self, @SuppressWarnings("unused") Object memo,
@CachedLibrary(limit = "2") PythonBufferAccessLibrary bufferLib,
@Bind PythonLanguage language) {
return copyArray(self, bufferLib, language);
}
}

private static PArray copyArray(PArray self, PythonBufferAccessLibrary bufferLib, PythonLanguage language) {
int length = self.getLength();
PArray newArray;
try {
newArray = PFactory.createArray(language, self.getFormatString(), self.getFormat(), length);
} catch (OverflowException e) {
// It is a copy of an existing array, the length cannot overflow.
throw CompilerDirectives.shouldNotReachHere();
}
bufferLib.readIntoBuffer(self.getBuffer(), 0, newArray.getBuffer(), 0, self.getBytesLength(), bufferLib);
return newArray;
}

@Builtin(name = J___CLASS_GETITEM__, minNumOfPositionalArgs = 2, isClassmethod = true)
@GenerateNodeFactory
abstract static class ClassGetItemNode extends PythonBinaryBuiltinNode {
@Specialization
static Object classGetItem(Object cls, Object key,
@Bind PythonLanguage language) {
return PFactory.createGenericAlias(language, cls, key);
}
}

@Builtin(name = J_APPEND, minNumOfPositionalArgs = 2)
@GenerateNodeFactory
abstract static class AppendNode extends PythonBinaryBuiltinNode {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 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 @@ -157,10 +157,10 @@ static Object constructOne(VirtualFrame frame, Object cls, Object[] args, PKeywo
stopNotInt.enter(inliningTarget);
throw raiseNode.raise(inliningTarget, ValueError, S_FOR_ISLICE_MUST_BE, "Indices");
}
}
if (stop < -1 || stop > SysModuleBuiltins.MAXSIZE) {
stopWrongValue.enter(inliningTarget);
throw raiseNode.raise(inliningTarget, ValueError, S_FOR_ISLICE_MUST_BE, "Indices");
if (stop < 0 || stop > SysModuleBuiltins.MAXSIZE) {
stopWrongValue.enter(inliningTarget);
throw raiseNode.raise(inliningTarget, ValueError, S_FOR_ISLICE_MUST_BE, "Indices");
}
}
} else if (argsLen2.profile(inliningTarget, args.length == 3) || argsLen3.profile(inliningTarget, args.length == 4)) {
if (args[1] != PNone.NONE) {
Expand All @@ -180,6 +180,10 @@ static Object constructOne(VirtualFrame frame, Object cls, Object[] args, PKeywo
stopNotInt.enter(inliningTarget);
throw raiseNode.raise(inliningTarget, ValueError, S_FOR_ISLICE_MUST_BE, "Stop argument");
}
if (stop < 0 || stop > SysModuleBuiltins.MAXSIZE) {
wrongValue.enter(inliningTarget);
throw raiseNode.raise(inliningTarget, ValueError, S_FOR_ISLICE_MUST_BE, "Indices");
}
}
if (start < 0 || stop < -1 || start > SysModuleBuiltins.MAXSIZE || stop > SysModuleBuiltins.MAXSIZE) {
wrongValue.enter(inliningTarget);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -828,17 +828,18 @@ void beginRootSourceSection(SSTNode node, Builder b) {
private static void beginSourceSectionInner(Builder b, SourceRange sourceRange) {
if (sourceRange.startLine >= 1 && sourceRange != SourceRange.ARTIFICIAL_RANGE) {
if (sourceRange.startColumn >= 0 && sourceRange.endLine >= sourceRange.startLine && sourceRange.endColumn >= 0) {
if (sourceRange.endColumn > 0) {
b.beginSourceSection(sourceRange.startLine, sourceRange.startColumn + 1, sourceRange.endLine, sourceRange.endColumn);
} else {
int startColumn = sourceRange.startColumn + 1;
int endColumn = sourceRange.endColumn > 0 ? sourceRange.endColumn : 1;
if (sourceRange.endLine == sourceRange.startLine && endColumn < startColumn) {
/*
* Truffle doesn't allow including an empty line with no characters, so we just
* include the first character to have at least something. It's not correct, but
* these cases are very rare, it occurs primarily in string consituents of
* top-level multiline format strings.
* Truffle doesn't allow source sections with empty or inverted ranges. These are
* rare, but can occur for string constituents of top-level multiline format
* strings and for AST-created code without end-position metadata.
*/
b.beginSourceSection(sourceRange.startLine, sourceRange.startColumn + 1, sourceRange.endLine, 1);
b.beginSourceSection(sourceRange.startLine);
return;
}
b.beginSourceSection(sourceRange.startLine, startColumn, sourceRange.endLine, endColumn);
} else {
b.beginSourceSection(sourceRange.startLine);
}
Expand Down
Loading
Loading