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
@@ -1,4 +1,4 @@
# Copyright (c) 2018, 2025, 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 @@ -36,9 +36,8 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import os
import ast
import sys
import unittest


def assert_raises(err, fn, *args, **kwargs):
Expand Down Expand Up @@ -658,3 +657,14 @@ def test_faulthandler_many_threads():
if ids:
ids_per_block.append(ids)
assert len(ids) == 1, f"Interleaved output detected in block {header!r} with multiple thread func ids: {ids}"


def test_location_from_ast():
m = compile("a = 1\nx", "<stdin>", "exec", flags=ast.PyCF_ONLY_AST)

try:
exec(compile(m, "<stdin>", "exec"))
except NameError as e:
assert e.__traceback__.tb_next.tb_lineno == 2
else:
assert False
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ test.test_dictviews.DictSetTest.test_abc_registry @ darwin-arm64,linux-aarch64,l
test.test_dictviews.DictSetTest.test_compare_error @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github
test.test_dictviews.DictSetTest.test_constructors_not_callable @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github
test.test_dictviews.DictSetTest.test_copy @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github
test.test_dictviews.DictSetTest.test_deeply_nested_repr @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,win32-AMD64,win32-AMD64-github
# Unreliable RecursionError
!test.test_dictviews.DictSetTest.test_deeply_nested_repr
test.test_dictviews.DictSetTest.test_dict_items @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github
test.test_dictviews.DictSetTest.test_dict_keys @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github
test.test_dictviews.DictSetTest.test_dict_mixed_keys_items @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -788,20 +788,12 @@ boolean beginSourceSection(SourceRange sourceRange, Builder b) {
SourceRange oldSourceRange = this.currentLocation;
this.currentLocation = sourceRange;

if (ctx.source.hasCharacters()) {
int startOffset = getStartOffset(sourceRange);
int endOffset = getEndOffset(sourceRange);
int length = endOffset - startOffset;
if (length == 0) {
startOffset = 0;
}
b.beginSourceSection(startOffset, length);
beginSourceSectionInner(b, sourceRange);

if (oldSourceRange == null || oldSourceRange.startLine != sourceRange.startLine) {
b.beginTag(StatementTag.class);
b.beginBlock();
return true;
}
if (oldSourceRange == null || oldSourceRange.startLine != sourceRange.startLine) {
b.beginTag(StatementTag.class);
b.beginBlock();
return true;
}
return false;
}
Expand All @@ -820,39 +812,41 @@ void beginRootSourceSection(SSTNode node, Builder b) {
sourceRange = node.getSourceRange();
}

if (ctx.source.hasCharacters()) {
int startOffset = getStartOffset(sourceRange);
int endOffset = getEndOffset(sourceRange);
int length = endOffset - startOffset;
if (length == 0) {
startOffset = 0;
}
b.beginSourceSection(startOffset, length);
}
beginSourceSectionInner(b, sourceRange);
}

void endSourceSection(Builder b, boolean closeTag) {
if (ctx.source.hasCharacters()) {
if (closeTag) {
b.endBlock();
b.endTag(StatementTag.class);
private static void beginSourceSectionInner(Builder b, SourceRange sourceRange) {
if (sourceRange.startLine >= 1) {
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 {
/*
* 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.
*/
b.beginSourceSection(sourceRange.startLine, sourceRange.startColumn + 1, sourceRange.endLine, 1);
}
} else {
b.beginSourceSection(sourceRange.startLine);
}
b.endSourceSection();
} else {
b.beginSourceSectionUnavailable();
}
}

void endRootSourceSection(Builder b) {
if (ctx.source.hasCharacters()) {
b.endSourceSection();
void endSourceSection(Builder b, boolean closeTag) {
if (closeTag) {
b.endBlock();
b.endTag(StatementTag.class);
}
b.endSourceSection();
}

int getStartOffset(SourceRange sourceRange) {
return ctx.source.getLineStartOffset(sourceRange.startLine) + sourceRange.startColumn;
}

int getEndOffset(SourceRange sourceRange) {
return ctx.source.getLineStartOffset(sourceRange.endLine) + sourceRange.endColumn;
void endRootSourceSection(Builder b) {
b.endSourceSection();
}

void beginReturn(Builder b) {
Expand Down
Loading