diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_set.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_set.py index 3b5333d1fd..906afb64f1 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_set.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_set.py @@ -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 @@ -71,18 +71,18 @@ def _reference_pop(args): except AttributeError: raise SystemError - + def _reference_discard(args): s = args[0] if not (isinstance(s, set)): raise SystemError - + if args[1] in s: s.discard(args[1]) return 1 return 0 - + class FrozenSetSubclass(frozenset): pass @@ -267,7 +267,7 @@ class TestPySet(CPyExtTestCase): if (!res) { // avoid problems when building the result value *key = set; - *hash = 0; + *hash = 0; Py_INCREF(set); } return res; @@ -296,7 +296,7 @@ class TestPySet(CPyExtTestCase): argspec='O', cmpfunc=unhandled_error_compare ) - + # PySet_Discard test_PySet_Discard = CPyExtFunction( _reference_discard, @@ -313,3 +313,29 @@ class TestPySet(CPyExtTestCase): argumentnames=("set, key"), cmpfunc=unhandled_error_compare ) + + # Note: frozensets are allowed to be mutated if refcnt == 1 + test_PySet_Add = CPyExtFunction( + lambda args: frozenset({*args[1], args[2]}) if args[0] else {*args[1], args[2]}, + lambda: ( + (False, [1], 2), + (True, [1], 2), + ), + resultspec="O", + argspec='iOO', + arguments=("int frozen", "PyObject* iterable", "PyObject* object"), + code=''' + PyObject* wrap_PySet_Add(int frozen, PyObject* iterable, PyObject* object) { + PyObject* set = frozen? PyFrozenSet_New(iterable) : PySet_New(iterable); + if (!set) + return NULL; + if (PySet_Add(set, object) < 0) { + Py_DECREF(set); + return NULL; + } + return set; + } + ''', + callfunction="wrap_PySet_Add", + cmpfunc=unhandled_error_compare, + ) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_descr.py b/graalpython/com.oracle.graal.python.test/src/tests/test_descr.py index 0cf0d5a4c3..c951fed284 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_descr.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_descr.py @@ -1,4 +1,4 @@ -# Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2024, 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 @@ -77,3 +77,30 @@ def __eq__(self, other): o = ObjWithHashSlot() o.__hash__ = lambda: 1 assert hash(o) == 1 + + +def test_attribute_error_message(): + obj = object() + + try: + obj.foo + except AttributeError as e: + assert e.obj == obj + assert e.name == "foo" + assert str(e) == "'object' object has no attribute 'foo'" + + try: + obj.foo = 1 + except AttributeError as e: + # Note: as of 3.12, CPython doesn't set obj and name + assert str(e) == "'object' object has no attribute 'foo'" + + class MyClass: + pass + + try: + MyClass.foo + except AttributeError as e: + assert e.obj == MyClass + assert e.name == "foo" + assert str(e) == "type object 'MyClass' has no attribute 'foo'" diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_scope.py b/graalpython/com.oracle.graal.python.test/src/tests/test_scope.py index 1b9a67dd39..6af28e4aab 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_scope.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_scope.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2021, 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 @@ -37,6 +37,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from tests import util def assert_raises(err, fn, *args, **kwargs): raised = False @@ -945,3 +946,30 @@ def toInternal(obj): c = fnc.__code__ assert c.co_freevars == ('var',) assert c.co_cellvars == tuple() + + +@util.skipUnlessBytecodeDSL("name atttribute not populated in manual interpreter") +def test_name_errors(): + def assert_raises_name_error(name, fn, *args, **kwargs): + try: + fn(*args, **kwargs) + except NameError as e: + assert str(e) == f"name '{name}' is not defined" + assert e.name == name + + assert_raises_name_error('foo', exec, 'foo') + assert_raises_name_error('foo', exec, 'foo', {}) + assert_raises_name_error('foo', exec, 'del foo') + assert_raises_name_error('foo', exec, 'del foo', {}) + + def load_global(): + global xxx + xxx + + assert_raises_name_error('xxx', load_global) + + def delete_global(): + global yyy + del yyy + + assert_raises_name_error('yyy', delete_global) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_dict.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_dict.txt index 3ffd2d7ada..7f8864ee0d 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_dict.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_dict.txt @@ -43,7 +43,8 @@ test.test_dict.DictTest.test_pop @ darwin-arm64,linux-aarch64,linux-aarch64-gith test.test_dict.DictTest.test_popitem @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github test.test_dict.DictTest.test_reentrant_insertion @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github test.test_dict.DictTest.test_repr @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github -test.test_dict.DictTest.test_repr_deep @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github +# Transiently doesn't raise RecursionError +!test.test_dict.DictTest.test_repr_deep test.test_dict.DictTest.test_resize1 @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github test.test_dict.DictTest.test_resize2 @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github test.test_dict.DictTest.test_reverse_iterator_for_empty_dict @ 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/Python3Core.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Python3Core.java index d93243ce8a..1e537ec582 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Python3Core.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Python3Core.java @@ -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. @@ -102,9 +102,6 @@ import com.oracle.graal.python.builtins.modules.RandomModuleBuiltins; import com.oracle.graal.python.builtins.modules.ReadlineModuleBuiltins; import com.oracle.graal.python.builtins.modules.ResourceModuleBuiltins; -import com.oracle.graal.python.builtins.modules.re.MatchBuiltins; -import com.oracle.graal.python.builtins.modules.re.PatternBuiltins; -import com.oracle.graal.python.builtins.modules.re.SREModuleBuiltins; import com.oracle.graal.python.builtins.modules.SSLModuleBuiltins; import com.oracle.graal.python.builtins.modules.SelectModuleBuiltins; import com.oracle.graal.python.builtins.modules.SignalModuleBuiltins; @@ -204,6 +201,9 @@ import com.oracle.graal.python.builtins.modules.pickle.PicklerMemoProxyBuiltins; import com.oracle.graal.python.builtins.modules.pickle.UnpicklerBuiltins; import com.oracle.graal.python.builtins.modules.pickle.UnpicklerMemoProxyBuiltins; +import com.oracle.graal.python.builtins.modules.re.MatchBuiltins; +import com.oracle.graal.python.builtins.modules.re.PatternBuiltins; +import com.oracle.graal.python.builtins.modules.re.SREModuleBuiltins; import com.oracle.graal.python.builtins.modules.re.SREScannerBuiltins; import com.oracle.graal.python.builtins.modules.weakref.ProxyTypeBuiltins; import com.oracle.graal.python.builtins.modules.zlib.ZLibModuleBuiltins; @@ -247,6 +247,7 @@ import com.oracle.graal.python.builtins.objects.exception.BaseExceptionGroupBuiltins; import com.oracle.graal.python.builtins.objects.exception.ImportErrorBuiltins; import com.oracle.graal.python.builtins.objects.exception.KeyErrorBuiltins; +import com.oracle.graal.python.builtins.objects.exception.NameErrorBuiltins; import com.oracle.graal.python.builtins.objects.exception.OsErrorBuiltins; import com.oracle.graal.python.builtins.objects.exception.StopIterationBuiltins; import com.oracle.graal.python.builtins.objects.exception.SyntaxErrorBuiltins; @@ -583,6 +584,7 @@ private static PythonBuiltins[] initializeBuiltins(TruffleLanguage.Env env) { new com.oracle.graal.python.builtins.objects.types.UnionTypeBuiltins(), // exceptions new AttributeErrorBuiltins(), + new NameErrorBuiltins(), new SystemExitBuiltins(), new ImportErrorBuiltins(), new StopIterationBuiltins(), diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java index c69e845ab3..86e67d02c2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java @@ -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. @@ -168,6 +168,7 @@ import com.oracle.graal.python.builtins.objects.exception.BaseExceptionGroupBuiltins; import com.oracle.graal.python.builtins.objects.exception.ImportErrorBuiltins; import com.oracle.graal.python.builtins.objects.exception.KeyErrorBuiltins; +import com.oracle.graal.python.builtins.objects.exception.NameErrorBuiltins; import com.oracle.graal.python.builtins.objects.exception.OsErrorBuiltins; import com.oracle.graal.python.builtins.objects.exception.StopIterationBuiltins; import com.oracle.graal.python.builtins.objects.exception.SyntaxErrorBuiltins; @@ -756,7 +757,7 @@ It can be called either on the class (e.g. C.f()) or on an instance IndexError("IndexError", LookupError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), KeyError("KeyError", LookupError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(KeyErrorBuiltins.SLOTS)), MemoryError("MemoryError", Exception, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), - NameError("NameError", Exception, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + NameError("NameError", Exception, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(NameErrorBuiltins.SLOTS)), UnboundLocalError("UnboundLocalError", NameError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), OSError("OSError", Exception, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(OsErrorBuiltins.SLOTS)), BlockingIOError("BlockingIOError", OSError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java index 2b7124d226..e81bb0bbe2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2025, 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 @@ -113,7 +113,6 @@ import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.nodes.object.GetDictFromGlobalsNode; import com.oracle.graal.python.nodes.object.GetOrCreateDictNode; import com.oracle.graal.python.nodes.statement.AbstractImportNode; import com.oracle.graal.python.nodes.util.CannotCastException; @@ -215,7 +214,6 @@ static final class WarningsModuleNode extends Node { @Child PyObjectIsTrueNode isTrueNode; @Child IsSubClassNode isSubClassNode; @Child GetOrCreateDictNode getDictNode; - @Child GetDictFromGlobalsNode getDictFromGlobalsNode; @Child ReadFrameNode readFrameNode; @Child PyObjectLookupAttr lookupAttrNode; @Child PyObjectCallMethodObjArgs callMethodNode; @@ -398,15 +396,6 @@ private PDict getSysDict() { return getDictNode.executeCached(getContext().lookupBuiltinModule(T_SYS)); } - private PDict getGlobalsDict(Object globals) { - if (getDictFromGlobalsNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - reportPolymorphicSpecialize(); - getDictFromGlobalsNode = insert(GetDictFromGlobalsNode.create()); - } - return getDictFromGlobalsNode.executeCached(globals); - } - private PFrame getCallerFrame(VirtualFrame frame, int stackLevel, TruffleString[] skipFilePrefixes) { if (readFrameNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); @@ -891,7 +880,7 @@ private void setupContext(VirtualFrame frame, int stackLevel, TruffleString[] sk filename[0] = T_SYS; lineno[0] = 1; } else { - globals = getGlobalsDict(f.getGlobals()); + globals = (PDict) f.getGlobals(); lineno[0] = f.getLine(); RootCallTarget ct = f.getTarget(); if (ct != null) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/DateNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/DateNodes.java index f79814d3e3..b13780c403 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/DateNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/DateNodes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 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 @@ -40,6 +40,7 @@ */ package com.oracle.graal.python.builtins.modules.datetime; +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError; import static com.oracle.graal.python.builtins.modules.datetime.DatetimeModuleBuiltins.MAX_YEAR; import static com.oracle.graal.python.builtins.modules.datetime.DatetimeModuleBuiltins.MIN_YEAR; @@ -199,9 +200,10 @@ static PDate asManaged(PDate obj) { return obj; } - @Specialization - static PDate asManagedNative(PythonAbstractNativeObject obj, + @Specialization(guards = "checkNode.execute(inliningTarget, obj)", limit = "1") + static PDate asManagedNative(@SuppressWarnings("unused") Node inliningTarget, PythonAbstractNativeObject obj, @Bind PythonLanguage language, + @SuppressWarnings("unused") @Cached DateCheckNode checkNode, @Cached CStructAccess.ReadByteNode readByteNode) { int year = getYear(obj, readByteNode); int month = getMonth(obj, readByteNode); @@ -223,6 +225,12 @@ static int getMonth(PythonAbstractNativeObject self, CStructAccess.ReadByteNode static int getDay(PythonAbstractNativeObject self, CStructAccess.ReadByteNode readNode) { return readNode.readFromObjUnsigned(self, CFields.PyDateTime_Date__data, 3); } + + @Fallback + static PDate error(Object obj, + @Bind Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.S_EXPECTED_GOT_P, "date", obj); + } } @GenerateUncached diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/DateTimeNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/DateTimeNodes.java index a9366e4a4c..f6b3eddafb 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/DateTimeNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/DateTimeNodes.java @@ -308,9 +308,10 @@ static PDateTime asManaged(PDateTime obj) { return obj; } - @Specialization - static PDateTime asManagedNative(PythonAbstractNativeObject obj, + @Specialization(guards = "checkNode.execute(inliningTarget, obj)", limit = "1") + static PDateTime asManagedNative(@SuppressWarnings("unused") Node inliningTarget, PythonAbstractNativeObject obj, @Bind PythonLanguage language, + @SuppressWarnings("unused") @Cached DateTimeCheckNode checkNode, @Cached CStructAccess.ReadByteNode readByteNode, @Cached CStructAccess.ReadObjectNode readObjectNode) { int year = getYear(obj, readByteNode); @@ -329,6 +330,12 @@ static PDateTime asManagedNative(PythonAbstractNativeObject obj, return new PDateTime(cls, cls.getInstanceShape(language), year, month, day, hour, minute, second, microsecond, tzInfo, fold); } + @Fallback + static PDateTime error(Object obj, + @Bind Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.S_EXPECTED_GOT_P, "datetime", obj); + } + static int getYear(PythonAbstractNativeObject self, CStructAccess.ReadByteNode readNode) { int b0 = readNode.readFromObjUnsigned(self, CFields.PyDateTime_DateTime__data, 0); int b1 = readNode.readFromObjUnsigned(self, CFields.PyDateTime_DateTime__data, 1); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeDeltaNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeDeltaNodes.java index 9cda04779a..6dcd2390f9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeDeltaNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeDeltaNodes.java @@ -281,9 +281,10 @@ static PTimeDelta doPTimeDelta(PTimeDelta value) { return value; } - @Specialization - static PTimeDelta doNative(PythonAbstractNativeObject nativeDelta, + @Specialization(guards = "checkNode.execute(inliningTarget, nativeDelta)", limit = "1") + static PTimeDelta doNative(@SuppressWarnings("unused") Node inliningTarget, PythonAbstractNativeObject nativeDelta, @Bind PythonLanguage language, + @SuppressWarnings("unused") @Cached TimeDeltaCheckNode checkNode, @Cached CStructAccess.ReadI32Node readIntNode) { int days = getDays(nativeDelta, readIntNode); int seconds = getSeconds(nativeDelta, readIntNode); @@ -304,5 +305,11 @@ static int getSeconds(PythonAbstractNativeObject self, CStructAccess.ReadI32Node static int getMicroseconds(PythonAbstractNativeObject self, CStructAccess.ReadI32Node readNode) { return readNode.readFromObj(self, CFields.PyDateTime_Delta__microseconds); } + + @Fallback + static PTimeDelta error(Object obj, + @Bind Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.S_EXPECTED_GOT_P, "timedelta", obj); + } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeNodes.java index b57f0be6e0..e68f2781e5 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeNodes.java @@ -245,9 +245,10 @@ static PTime doPTime(PTime value) { return value; } - @Specialization - static PTime doNative(PythonAbstractNativeObject nativeTime, + @Specialization(guards = "checkNode.execute(inliningTarget, nativeTime)", limit = "1") + static PTime doNative(@SuppressWarnings("unused") Node inliningTarget, PythonAbstractNativeObject nativeTime, @Bind PythonLanguage language, + @SuppressWarnings("unused") @Cached TimeCheckNode checkNode, @Cached CStructAccess.ReadByteNode readByteNode, @Cached CStructAccess.ReadObjectNode readObjectNode) { int hour = getHour(nativeTime, readByteNode); @@ -295,6 +296,12 @@ private static Object getTzInfo(PythonAbstractNativeObject nativeTime, CStructAc static int getFold(PythonAbstractNativeObject self, CStructAccess.ReadByteNode readNode) { return readNode.readFromObjUnsigned(self, CFields.PyDateTime_Time__fold); } + + @Fallback + static PTime error(Object obj, + @Bind Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.S_EXPECTED_GOT_P, "time", obj); + } } @GenerateUncached diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiContext.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiContext.java index e1c0829879..dbc5401ef9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiContext.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -44,7 +44,6 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.PythonNativeWrapper.PythonAbstractObjectNativeWrapper.IMMORTAL_REFCNT; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.pollReferenceQueue; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___FILE__; -import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___LIBRARY__; import static com.oracle.graal.python.nodes.StringLiterals.J_NFI_LANGUAGE; import static com.oracle.graal.python.nodes.StringLiterals.T_DASH; import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING; @@ -1211,7 +1210,6 @@ public Object initCApiModule(Node node, Object sharedLibrary, TruffleString init // see: 'import.c: _PyImport_FixupExtensionObject' PythonModule module = (PythonModule) result; module.setAttribute(T___FILE__, spec.path); - module.setAttribute(T___LIBRARY__, sharedLibrary); addLoadedExtensionLibrary(sharedLibrary); // add to 'sys.modules' diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java index 9f14234c87..3aed43b991 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java @@ -1,5 +1,5 @@ /* - * 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 @@ -1781,7 +1781,6 @@ static Object createModule(Node node, CApiContext capiContext, ModuleSpec module } WriteAttributeToObjectNode.getUncached().execute(module, SpecialAttributeNames.T___DOC__, mDoc); - WriteAttributeToObjectNode.getUncached().execute(module, SpecialAttributeNames.T___LIBRARY__, library); capiContext.addLoadedExtensionLibrary(library); return module; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/PHashingCollection.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/PHashingCollection.java index c0b2aaabfe..95c7c490cd 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/PHashingCollection.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/PHashingCollection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, 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 @@ -41,7 +41,6 @@ package com.oracle.graal.python.builtins.objects.common; import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject; -import com.oracle.graal.python.builtins.objects.set.PFrozenSet; import com.oracle.truffle.api.object.Shape; public abstract class PHashingCollection extends PythonBuiltinObject { @@ -59,7 +58,6 @@ public final HashingStorage getDictStorage() { } public final void setDictStorage(HashingStorage storage) { - assert storage == this.storage || !(this instanceof PFrozenSet) : "frozenSet is unmodifiable"; assert storage != null; this.storage = storage; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/NameErrorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/NameErrorBuiltins.java new file mode 100644 index 0000000000..d688720bef --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/NameErrorBuiltins.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2025, 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 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * 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. + */ +package com.oracle.graal.python.builtins.objects.exception; + +import static com.oracle.graal.python.nodes.StringLiterals.T_NAME; +import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; + +import java.util.List; + +import com.oracle.graal.python.annotations.Builtin; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; +import com.oracle.graal.python.builtins.CoreFunctions; +import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.builtins.PythonBuiltins; +import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.function.PKeyword; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateNodeFactory; +import com.oracle.truffle.api.dsl.NodeFactory; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedLoopConditionProfile; +import com.oracle.truffle.api.strings.TruffleString; + +@CoreFunctions(extendClasses = PythonBuiltinClassType.NameError) +public final class NameErrorBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = NameErrorBuiltinsSlotsGen.SLOTS; + + @Override + protected List> getNodeFactories() { + return NameErrorBuiltinsFactory.getFactories(); + } + + private static final int IDX_NAME = 0; + private static final int NUM_ATTRS = IDX_NAME + 1; + + private static final BaseExceptionAttrNode.StorageFactory ATTR_FACTORY = (args) -> new Object[NUM_ATTRS]; + + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + abstract static class InitNode extends PythonVarargsBuiltinNode { + + @Specialization + static Object init(PBaseException self, Object[] args, PKeyword[] kwargs, + @Bind Node inliningTarget, + @Cached BaseExceptionBuiltins.BaseExceptionInitNode baseExceptionInitNode, + @Cached TruffleString.EqualNode equalNameNode, + @Cached InlinedLoopConditionProfile loopProfile, + @Cached PRaiseNode raiseNode) { + baseExceptionInitNode.execute(self, args); + Object[] attrs = new Object[NUM_ATTRS]; + loopProfile.profileCounted(inliningTarget, kwargs.length); + for (int i = 0; loopProfile.inject(inliningTarget, i < kwargs.length); i++) { + PKeyword kw = kwargs[i]; + TruffleString kwName = kw.getName(); + if (equalNameNode.execute(kwName, T_NAME, TS_ENCODING)) { + attrs[IDX_NAME] = kw.getValue(); + } else { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.S_IS_AN_INVALID_ARG_FOR_S, kw.getName(), "NameError"); + } + } + self.setExceptionAttributes(attrs); + return PNone.NONE; + } + } + + @Builtin(name = "name", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true, allowsDelete = true) + @GenerateNodeFactory + public abstract static class NameNode extends PythonBinaryBuiltinNode { + @Specialization + static Object generic(PBaseException self, Object value, + @Cached BaseExceptionAttrNode attrNode) { + return attrNode.execute(self, value, IDX_NAME, ATTR_FACTORY); + } + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/CommonGeneratorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/CommonGeneratorBuiltins.java index 20132e00be..b227c0a6e9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/CommonGeneratorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/CommonGeneratorBuiltins.java @@ -358,7 +358,6 @@ static Object sendThrow(VirtualFrame frame, PGenerator self, Object typ, Object @Cached ResumeGeneratorNode resumeGeneratorNode, @Cached ExceptionNodes.GetTracebackNode getTracebackNode, @Cached ExceptionNodes.SetTracebackNode setTracebackNode, - @Cached ExceptionNodes.SetContextNode setContextNode, @Cached WarningsModuleBuiltins.WarnNode warnNode, @Cached PRaiseNode raiseNode) { boolean hasTb = hasTbProfile.profile(inliningTarget, !(tb instanceof PNone)); @@ -379,8 +378,6 @@ static Object sendThrow(VirtualFrame frame, PGenerator self, Object typ, Object setTracebackNode.execute(inliningTarget, instance, tb); } PythonLanguage language = PythonLanguage.get(inliningTarget); - setContextNode.execute(inliningTarget, instance, PNone.NONE); // Will be filled when - // caught if (self.isCoroutine() && self.isFinished()) { throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.CANNOT_REUSE_CORO); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java index f16fc0944c..b97416bddd 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java @@ -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. @@ -589,7 +589,7 @@ protected Object doIt(VirtualFrame frame, Object object, Object keyObj, } } - throw raiseNode.raiseAttributeError(inliningTarget, ErrorMessages.OBJ_N_HAS_NO_ATTR_S, object, key); + throw raiseNode.raiseAttributeError(inliningTarget, ErrorMessages.TYPE_N_HAS_NO_ATTR, object, key); } private Object readAttributeOfClass(Object object, TruffleString key) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyImportImport.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyImportImport.java index 7c056c7d2c..cd3986edaf 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyImportImport.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyImportImport.java @@ -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 @@ -51,7 +51,6 @@ import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.nodes.call.CallNode; -import com.oracle.graal.python.nodes.object.GetDictFromGlobalsNode; import com.oracle.graal.python.nodes.statement.AbstractImportNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.object.PFactory; @@ -87,13 +86,12 @@ static Object doGeneric(VirtualFrame frame, Node inliningTarget, TruffleString m @Cached(inline = false) CallNode callNode, @Cached(inline = false) AbstractImportNode.PyImportImportModuleLevelObject importModuleLevelObject, @Cached PyEvalGetGlobals getGlobals, - @Cached(inline = false) GetDictFromGlobalsNode getDictFromGlobals, @Bind PythonLanguage language) { // Get the builtins from current globals Object globals = getGlobals.execute(frame, inliningTarget); Object builtins; if (noGlobalsProfile.profile(inliningTarget, globals != null)) { - builtins = getItemNode.execute(frame, inliningTarget, getDictFromGlobals.execute(inliningTarget, globals), T___BUILTINS__); + builtins = getItemNode.execute(frame, inliningTarget, globals, T___BUILTINS__); } else { // No globals -- use standard builtins, and fake globals builtins = importModuleLevelObject.execute(frame, PythonContext.get(inliningTarget), T_BUILTINS, null, null, 0); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java index f705a1edac..aa4d8e7cc3 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java @@ -337,7 +337,7 @@ public abstract class ErrorMessages { public static final TruffleString FORMATED_S_TOO_LONG = tsLiteral("formatted %s is too long (precision too large?)"); public static final TruffleString FUNC_CONSTRUCTION_NOT_SUPPORTED = tsLiteral("function construction not supported for (%p, %p, %p, %p, %p, %p)"); public static final TruffleString FUNC_TAKES_EXACTLY_D_ARGS = tsLiteral("function takes exaclty %d arguments (%d given)"); - public static final TruffleString S_TAKES_EXACTLY_D_ARGS = tsLiteral("%s takes exaclty %d arguments (%d given)"); + public static final TruffleString S_TAKES_EXACTLY_D_ARGS = tsLiteral("%s takes exactly %d arguments (%d given)"); public static final TruffleString S_TAKES_VARARGS = tsLiteral("%s takes varargs"); public static final TruffleString S_DOES_NOT_TAKE_VARARGS = tsLiteral("%s does not take varargs"); public static final TruffleString GCD_FOR_NATIVE_NOT_SUPPORTED = tsLiteral("gcd for native objects is not yet supported on GraalPy"); @@ -355,7 +355,7 @@ public abstract class ErrorMessages { public static final TruffleString GOT_UNEXPECTED_KEYWORD_ARG = tsLiteral("%s() got an unexpected keyword argument '%s'"); public static final TruffleString HANDLER_MUST_BE_CALLABLE = tsLiteral("handler must be callable"); public static final TruffleString HAS_NO_ATTR = tsLiteral("%p has no attribute '%s'"); - public static final TruffleString TYPE_N_HAS_NO_ATTR = tsLiteral("type object %s has no attribute '%s'"); + public static final TruffleString TYPE_N_HAS_NO_ATTR = tsLiteral("type object '%N' has no attribute '%s'"); public static final TruffleString P_HAS_NO_ATTRS_S_TO_ASSIGN = tsLiteral("'%p' object has no attributes (assign to .%s)"); public static final TruffleString P_HAS_NO_ATTRS_S_TO_DELETE = tsLiteral("'%p' object has no attributes (del .%s)"); public static final TruffleString P_HAS_RO_ATTRS_S_TO_ASSIGN = tsLiteral("'%p' object has only read-only attributes (assign to .%s)"); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PRaiseNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PRaiseNode.java index 69fce9795d..1e35eeef3f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PRaiseNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PRaiseNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -146,6 +146,16 @@ public static PException raiseAttributeErrorStatic(Node inliningTarget, TruffleS throw raiseWithDataStatic(inliningTarget, PythonBuiltinClassType.AttributeError, AttributeErrorBuiltins.dataForObjKey(obj, key), errorMessage, obj, key); } + public final PException raiseNameError(Node inliningTarget, Object name) { + executeEnterProfile(inliningTarget); + throw raiseNameErrorStatic(inliningTarget, name); + } + + @InliningCutoff + public static PException raiseNameErrorStatic(Node inliningTarget, Object name) { + throw raiseWithDataStatic(inliningTarget, PythonBuiltinClassType.NameError, new Object[]{name}, ErrorMessages.NAME_NOT_DEFINED, name); + } + public final PException raiseWithData(Node inliningTarget, PythonBuiltinClassType type, Object[] data, TruffleString format, Object... formatArgs) { executeEnterProfile(inliningTarget); throw raiseWithDataStatic(inliningTarget, type, data, format, formatArgs); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/SpecialAttributeNames.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/SpecialAttributeNames.java index d2de0dc456..e770b9aae6 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/SpecialAttributeNames.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/SpecialAttributeNames.java @@ -1,5 +1,5 @@ /* - * 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 @@ -111,8 +111,6 @@ public abstract class SpecialAttributeNames { public static final TruffleString T___FILE__ = tsLiteral("__file__"); - public static final TruffleString T___LIBRARY__ = tsLiteral("__library__"); - public static final TruffleString T___ORIGNAME__ = tsLiteral("__origname__"); public static final TruffleString T___CACHED__ = tsLiteral("__cached__"); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/MergedObjectTypeModuleGetAttributeNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/MergedObjectTypeModuleGetAttributeNode.java index f210f06429..233ed8654a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/MergedObjectTypeModuleGetAttributeNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/MergedObjectTypeModuleGetAttributeNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -181,7 +181,8 @@ static Object doIt(VirtualFrame frame, Node inliningTarget, Object object, Truff } } - throw raiseNode.raiseAttributeError(inliningTarget, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key); + TruffleString errorMessage = cachedSlot != TypeBuiltins.SLOTS.tp_getattro() ? ErrorMessages.OBJ_P_HAS_NO_ATTR_S : ErrorMessages.TYPE_N_HAS_NO_ATTR; + throw raiseNode.raiseAttributeError(inliningTarget, errorMessage, object, key); } catch (PException e) { // Extra behavior for module.__getattribute__ if (cachedSlot == ModuleBuiltins.SLOTS.tp_getattro()) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ImportStarNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ImportStarNode.java index 2bb99afb1a..d03f0d28c0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ImportStarNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ImportStarNode.java @@ -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. @@ -31,16 +31,13 @@ import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import static com.oracle.graal.python.util.PythonUtils.tsArray; -import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.function.PArguments; -import com.oracle.graal.python.builtins.objects.mappingproxy.PMappingproxy; import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.lib.IteratorExhausted; import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyObjectGetAttr; import com.oracle.graal.python.lib.PyObjectGetItem; import com.oracle.graal.python.lib.PyObjectGetIter; -import com.oracle.graal.python.lib.PyObjectSetAttr; import com.oracle.graal.python.lib.PyObjectSetItem; import com.oracle.graal.python.lib.PyObjectSizeNode; import com.oracle.graal.python.nodes.ErrorMessages; @@ -82,7 +79,6 @@ void doImport(VirtualFrame frame, TruffleString moduleName, int level, @CachedLibrary(limit = "1") InteropLibrary interopLib, @Cached ImportName importNameNode, @Cached PyObjectSetItem setItemNode, - @Cached PyObjectSetAttr setAttrNode, @Cached GetOrCreateDictNode getDictNode, @Cached PyObjectGetAttr getAttrNode, @Cached PyObjectGetIter getIterNode, @@ -109,7 +105,8 @@ void doImport(VirtualFrame frame, TruffleString moduleName, int level, String attrName = interopLib.asString(interopLib.readArrayElement(hostAttrs, i)); Object attr = interopLib.readMember(importedModule, attrName); attr = PForeignToPTypeNode.getUncached().executeConvert(attr); - writeAttribute(frame, inliningTarget, locals, TruffleString.fromJavaStringUncached(attrName, TS_ENCODING), attr, setItemNode, setAttrNode); + TruffleString name = TruffleString.fromJavaStringUncached(attrName, TS_ENCODING); + setItemNode.execute(frame, inliningTarget, locals, name, attr); } } catch (UnknownIdentifierException | UnsupportedMessageException | InvalidArrayIndexException e) { CompilerDirectives.transferToInterpreterAndInvalidate(); @@ -122,7 +119,7 @@ void doImport(VirtualFrame frame, TruffleString moduleName, int level, for (int i = 0; i < n; i++) { Object attrName = getItemNode.execute(frame, inliningTarget, attrAll, i); writeAttributeToLocals(frame, inliningTarget, moduleName, (PythonModule) importedModule, locals, attrName, true, castToTruffleStringNode, codePointLengthNode, - codePointAtIndexNode, getAttrNode, setItemNode, setAttrNode); + codePointAtIndexNode, getAttrNode, setItemNode); } } catch (PException e) { e.expectAttributeError(inliningTarget, isAttributeErrorProfile); @@ -136,24 +133,15 @@ void doImport(VirtualFrame frame, TruffleString moduleName, int level, break; } writeAttributeToLocals(frame, inliningTarget, moduleName, (PythonModule) importedModule, locals, key, false, castToTruffleStringNode, codePointLengthNode, - codePointAtIndexNode, getAttrNode, setItemNode, setAttrNode); + codePointAtIndexNode, getAttrNode, setItemNode); } } } } - // TODO: remove once we removed PythonModule globals - private static void writeAttribute(VirtualFrame frame, Node inliningTarget, Object globals, TruffleString name, Object value, PyObjectSetItem setItemNode, PyObjectSetAttr setAttrNode) { - if (globals instanceof PDict || globals instanceof PMappingproxy) { - setItemNode.execute(frame, inliningTarget, globals, name, value); - } else { - setAttrNode.execute(frame, inliningTarget, globals, name, value); - } - } - private void writeAttributeToLocals(VirtualFrame frame, Node inliningTarget, TruffleString moduleName, PythonModule importedModule, Object locals, Object attrName, boolean fromAll, CastToTruffleStringNode castToTruffleStringNode, TruffleString.CodePointLengthNode cpLenNode, TruffleString.CodePointAtIndexUTF32Node cpAtIndexNode, PyObjectGetAttr getAttr, - PyObjectSetItem dictWriteNode, PyObjectSetAttr setAttrNode) { + PyObjectSetItem dictWriteNode) { try { TruffleString name = castToTruffleStringNode.execute(inliningTarget, attrName); /* @@ -162,7 +150,7 @@ private void writeAttributeToLocals(VirtualFrame frame, Node inliningTarget, Tru */ if (fromAll || !startsWithUnderscore(name, cpLenNode, cpAtIndexNode)) { Object moduleAttr = getAttr.execute(frame, inliningTarget, importedModule, name); - writeAttribute(frame, inliningTarget, locals, name, moduleAttr, dictWriteNode, setAttrNode); + dictWriteNode.execute(frame, inliningTarget, locals, name, moduleAttr); } } catch (CannotCastException cce) { TruffleString format = fromAll ? ErrorMessages.ITEM_IN_S_MUST_BE_STRING : ErrorMessages.KEY_IN_S_MUST_BE_STRING; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java index b4ec86d752..a94c93e205 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java @@ -1272,8 +1272,13 @@ public static final class DeleteName { @Specialization(guards = "hasLocals(frame)") public static void performLocals(VirtualFrame frame, TruffleString name, @Bind Node inliningTarget, - @Cached PyObjectDelItem deleteNode) { - deleteNode.execute(frame, inliningTarget, PArguments.getSpecialArgument(frame), name); + @Cached PyObjectDelItem deleteNode, + @Cached PRaiseNode raiseNode) { + try { + deleteNode.execute(frame, inliningTarget, PArguments.getSpecialArgument(frame), name); + } catch (PException e) { + throw raiseNode.raiseNameError(inliningTarget, name); + } } @Specialization(guards = "!hasLocals(frame)") diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/DeleteGlobalNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/DeleteGlobalNode.java index 5fb4ec1583..c08e61a025 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/DeleteGlobalNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/DeleteGlobalNode.java @@ -1,5 +1,5 @@ /* - * 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 @@ -41,10 +41,10 @@ package com.oracle.graal.python.nodes.frame; import com.oracle.graal.python.builtins.objects.dict.PDict; -import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.lib.PyObjectDelItem; -import com.oracle.graal.python.lib.PyObjectSetAttr; import com.oracle.graal.python.nodes.PNodeWithContext; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.runtime.exception.PException; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -76,29 +76,24 @@ public final void executeWithGlobals(VirtualFrame frame, Object globals, Truffle static void deleteDictCached(VirtualFrame frame, @SuppressWarnings("unused") PDict globals, TruffleString attributeId, @Bind Node inliningTarget, @Cached(value = "globals", weak = true) PDict cachedGlobals, - @Shared("delItem") @Cached PyObjectDelItem deleteNode) { - deleteNode.execute(frame, inliningTarget, cachedGlobals, attributeId); + @Shared("delItem") @Cached PyObjectDelItem deleteNode, + @Shared @Cached PRaiseNode raiseNode) { + try { + deleteNode.execute(frame, inliningTarget, cachedGlobals, attributeId); + } catch (PException e) { + throw raiseNode.raiseNameError(inliningTarget, attributeId); + } } @Specialization(replaces = "deleteDictCached") static void deleteDict(VirtualFrame frame, PDict globals, TruffleString attributeId, @Bind Node inliningTarget, - @Shared("delItem") @Cached PyObjectDelItem deleteNode) { - deleteNode.execute(frame, inliningTarget, globals, attributeId); - } - - @Specialization(guards = {"isSingleContext()", "globals == cachedGlobals"}, limit = "1") - static void deleteModuleCached(VirtualFrame frame, @SuppressWarnings("unused") PythonModule globals, TruffleString attributeId, - @Bind Node inliningTarget, - @Cached(value = "globals", weak = true) PythonModule cachedGlobals, - @Shared @Cached PyObjectSetAttr setAttr) { - setAttr.delete(frame, inliningTarget, cachedGlobals, attributeId); - } - - @Specialization(replaces = "deleteModuleCached") - static void deleteModule(VirtualFrame frame, PythonModule globals, TruffleString attributeId, - @Bind Node inliningTarget, - @Shared @Cached PyObjectSetAttr setAttr) { - setAttr.delete(frame, inliningTarget, globals, attributeId); + @Shared("delItem") @Cached PyObjectDelItem deleteNode, + @Shared @Cached PRaiseNode raiseNode) { + try { + deleteNode.execute(frame, inliningTarget, globals, attributeId); + } catch (PException e) { + throw raiseNode.raiseNameError(inliningTarget, attributeId); + } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadBuiltinNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadBuiltinNode.java index 70f48acd3e..20e2d18bd4 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadBuiltinNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadBuiltinNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 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 @@ -40,12 +40,9 @@ */ package com.oracle.graal.python.nodes.frame; -import static com.oracle.graal.python.runtime.exception.PythonErrorType.NameError; - import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.nodes.BuiltinNames; -import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromModuleNode; @@ -84,7 +81,7 @@ Object returnBuiltinFromConstantModule(TruffleString attributeId, @InliningCutoff private static PException raiseNameNotDefined(Node inliningTarget, PRaiseNode raiseNode, TruffleString attributeId) { - throw raiseNode.raise(inliningTarget, NameError, ErrorMessages.NAME_NOT_DEFINED, attributeId); + throw raiseNode.raiseNameError(inliningTarget, attributeId); } @InliningCutoff diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/WriteGlobalNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/WriteGlobalNode.java index a8c1bed352..6ef428c580 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/WriteGlobalNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/WriteGlobalNode.java @@ -1,5 +1,5 @@ /* - * 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 @@ -43,10 +43,8 @@ import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes; import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.function.PArguments; -import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.lib.PyObjectSetItem; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -105,17 +103,4 @@ void writeGenericDict(VirtualFrame frame, PDict globals, TruffleString attribute @Cached PyObjectSetItem storeNode) { storeNode.execute(frame, inliningTarget, globals, attributeId, value); } - - @Specialization(guards = {"isSingleContext()", "globals == cachedGlobals"}, limit = "1") - void writeModuleCached(@SuppressWarnings("unused") PythonModule globals, TruffleString attributeId, Object value, - @Cached(value = "globals", weak = true) PythonModule cachedGlobals, - @Shared("write") @Cached WriteAttributeToObjectNode write) { - write.execute(cachedGlobals, attributeId, value); - } - - @Specialization(replaces = "writeModuleCached") - void writeModule(PythonModule globals, TruffleString attributeId, Object value, - @Shared("write") @Cached WriteAttributeToObjectNode write) { - write.execute(globals, attributeId, value); - } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetDictFromGlobalsNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetDictFromGlobalsNode.java deleted file mode 100644 index e4315be0f6..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetDictFromGlobalsNode.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2018, 2023, 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 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * 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. - */ -package com.oracle.graal.python.nodes.object; - -import com.oracle.graal.python.builtins.objects.dict.PDict; -import com.oracle.graal.python.builtins.objects.module.PythonModule; -import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.GenerateCached; -import com.oracle.truffle.api.dsl.GenerateInline; -import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.Node; - -@GenerateUncached -@GenerateInline(inlineByDefault = true) -@GenerateCached -public abstract class GetDictFromGlobalsNode extends PNodeWithContext { - - public abstract PDict execute(Node inliningTarget, Object globals); - - public final PDict executeCached(Object globals) { - return execute(this, globals); - } - - @Specialization - static PDict dict(PDict globals) { - return globals; - } - - @Specialization - static PDict dict(Node inliningTarget, PythonModule globals, - @Cached GetOrCreateDictNode getDict) { - return getDict.execute(inliningTarget, globals); - } - - @NeverDefault - public static GetDictFromGlobalsNode create() { - return GetDictFromGlobalsNodeGen.create(); - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/statement/AbstractImportNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/statement/AbstractImportNode.java index a5e31e4f3a..7bc12b1cfc 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/statement/AbstractImportNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/statement/AbstractImportNode.java @@ -1,5 +1,5 @@ /* - * 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 @@ -72,7 +72,6 @@ import com.oracle.graal.python.nodes.SpecialAttributeNames; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromPythonObjectNode; import com.oracle.graal.python.nodes.call.CallNode; -import com.oracle.graal.python.nodes.object.GetDictFromGlobalsNode; import com.oracle.graal.python.nodes.statement.AbstractImportNodeFactory.ImportNameNodeGen; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; @@ -196,20 +195,13 @@ static Object importName(VirtualFrame frame, PythonContext context, PythonModule @Cached InlinedConditionProfile importFuncProfile, @Cached PConstructAndRaiseNode.Lazy raiseNode, @Cached CallNode importCallNode, - @Cached GetDictFromGlobalsNode getDictNode, @Cached PyImportImportModuleLevelObject importModuleLevel) { Object importFunc = readAttrNode.execute(builtins, T___IMPORT__, null); if (importFunc == null) { throw raiseNode.get(inliningTarget).raiseImportError(frame, IMPORT_NOT_FOUND); } if (importFuncProfile.profile(inliningTarget, context.importFunc() != importFunc)) { - Object globalsArg; - if (globals instanceof PNone) { - globalsArg = globals; - } else { - globalsArg = getDictNode.execute(inliningTarget, globals); - } - return importCallNode.execute(frame, importFunc, name, globalsArg, PNone.NONE, PFactory.createTuple(PythonLanguage.get(inliningTarget), fromList), level); + return importCallNode.execute(frame, importFunc, name, globals, PNone.NONE, PFactory.createTuple(PythonLanguage.get(inliningTarget), fromList), level); } return importModuleLevel.execute(frame, context, name, globals, fromList, level); } @@ -474,10 +466,9 @@ protected static byte[] singleByte() { abstract TruffleString execute(Frame frame, TruffleString name, Object globals, int level); @Specialization - TruffleString resolveName(VirtualFrame frame, TruffleString name, Object globals, int level, + TruffleString resolveName(VirtualFrame frame, TruffleString name, PDict globals, int level, @Bind Node inliningTarget, @Cached PConstructAndRaiseNode constructAndRaiseNode, - @Cached GetDictFromGlobalsNode getDictNode, @Cached PyDictGetItem getPackageOrNameNode, @Cached PyDictGetItem getSpecNode, @Cached PyObjectGetAttr getParent, @@ -489,9 +480,8 @@ TruffleString resolveName(VirtualFrame frame, TruffleString name, Object globals @Cached TruffleStringBuilder.AppendStringNode appendStringNode, @Cached TruffleStringBuilder.ToStringNode toStringNode, @Cached(value = "singleByte()", uncached = "uncachedByte()", dimensions = 1) byte[] branchStates) { - PDict globalsDict = getDictNode.execute(inliningTarget, globals); - Object pkg = getPackageOrNameNode.execute(frame, inliningTarget, globalsDict, SpecialAttributeNames.T___PACKAGE__); - Object spec = getSpecNode.execute(frame, inliningTarget, globalsDict, SpecialAttributeNames.T___SPEC__); + Object pkg = getPackageOrNameNode.execute(frame, inliningTarget, globals, SpecialAttributeNames.T___PACKAGE__); + Object spec = getSpecNode.execute(frame, inliningTarget, globals, SpecialAttributeNames.T___SPEC__); TruffleString pkgString; if (pkg == PNone.NONE) { pkg = null; @@ -548,7 +538,7 @@ TruffleString resolveName(VirtualFrame frame, TruffleString name, Object globals // (tfel): we use the byte field to cut off this branch unless needed, and for // footprint when use the same node for __package__, __name__, and __path__ lookup - pkg = getPackageOrNameNode.execute(frame, inliningTarget, globalsDict, SpecialAttributeNames.T___NAME__); + pkg = getPackageOrNameNode.execute(frame, inliningTarget, globals, SpecialAttributeNames.T___NAME__); if (pkg == null) { if ((branchStates[0] & GOT_NO_NAME) == 0) { CompilerDirectives.transferToInterpreterAndInvalidate(); @@ -565,7 +555,7 @@ TruffleString resolveName(VirtualFrame frame, TruffleString name, Object globals } throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.TypeError, ErrorMessages.NAME_MUST_BE_A_STRING); } - Object path = getPackageOrNameNode.execute(frame, inliningTarget, globalsDict, SpecialAttributeNames.T___PATH__); + Object path = getPackageOrNameNode.execute(frame, inliningTarget, globals, SpecialAttributeNames.T___PATH__); if (path == null) { int dotIdx = indexOfCodePointNode.execute(pkgString, '.', 0, codePointLengthNode.execute(pkgString, TS_ENCODING), TS_ENCODING); if (dotIdx < 0) { diff --git a/graalpython/lib-graalpython/patches/metadata.toml b/graalpython/lib-graalpython/patches/metadata.toml index f1fbec47de..50a6a0b7c5 100644 --- a/graalpython/lib-graalpython/patches/metadata.toml +++ b/graalpython/lib-graalpython/patches/metadata.toml @@ -1049,4 +1049,9 @@ version = '== 4.3.3' [[librt.rules]] version = '== 0.7.8' patch = 'librt-0.7.8.patch' -license = 'MIT' \ No newline at end of file +license = 'MIT' + +[[opencv-python.rules]] +version = '== 4.12.*' +patch = 'opencv-python-4.12.patch' +license = 'Apache-2.0' diff --git a/graalpython/lib-graalpython/patches/opencv-python-4.12.patch b/graalpython/lib-graalpython/patches/opencv-python-4.12.patch new file mode 100644 index 0000000000..d3b91a560c --- /dev/null +++ b/graalpython/lib-graalpython/patches/opencv-python-4.12.patch @@ -0,0 +1,32 @@ +diff --git a/opencv/cmake/OpenCVFindLibsPerf.cmake b/opencv/cmake/OpenCVFindLibsPerf.cmake +index dfc9459..861a39c 100644 +--- a/opencv/cmake/OpenCVFindLibsPerf.cmake ++++ b/opencv/cmake/OpenCVFindLibsPerf.cmake +@@ -84,7 +84,13 @@ if(WITH_EIGEN AND NOT HAVE_EIGEN) + set(EIGEN_WORLD_VERSION ${EIGEN3_WORLD_VERSION}) + set(EIGEN_MAJOR_VERSION ${EIGEN3_MAJOR_VERSION}) + set(EIGEN_MINOR_VERSION ${EIGEN3_MINOR_VERSION}) +- else() # Eigen config file ++ elseif(DEFINED Eigen3_VERSION_MAJOR) # Recommended package config variables ++ # see https://github.com/opencv/opencv/issues/27530 ++ set(EIGEN_WORLD_VERSION ${Eigen3_VERSION_MAJOR}) ++ set(EIGEN_MAJOR_VERSION ${Eigen3_VERSION_MINOR}) ++ set(EIGEN_MINOR_VERSION ${Eigen3_VERSION_PATCH}) ++ else() # Deprecated package config variables ++ # Removed on master at https://gitlab.com/libeigen/eigen/-/commit/f2984cd0778dd0a1d7e74216d826eaff2bc6bfab + set(EIGEN_WORLD_VERSION ${EIGEN3_VERSION_MAJOR}) + set(EIGEN_MAJOR_VERSION ${EIGEN3_VERSION_MINOR}) + set(EIGEN_MINOR_VERSION ${EIGEN3_VERSION_PATCH}) +diff --git a/setup.py b/setup.py +index 8941218..be79b06 100755 +--- a/setup.py ++++ b/setup.py +@@ -187,7 +187,7 @@ def main(): + "-DBUILD_TESTS=OFF", + "-DBUILD_PERF_TESTS=OFF", + "-DBUILD_DOCS=OFF", +- "-DPYTHON3_LIMITED_API=ON", ++ "-DPYTHON3_LIMITED_API=OFF", + "-DBUILD_OPENEXR=ON", + ] + + ( diff --git a/mx.graalpython/downstream_tests.py b/mx.graalpython/downstream_tests.py index bcb8143b48..b05e8a2188 100644 --- a/mx.graalpython/downstream_tests.py +++ b/mx.graalpython/downstream_tests.py @@ -104,7 +104,7 @@ def downstream_test_hpy(graalpy, testdir=None, args=None, env=None, check=True, @downstream_test('pybind11') def downstream_test_pybind11(graalpy, testdir): - run(['git', 'clone', 'https://github.com/pybind/pybind11.git'], cwd=testdir) + run(['git', 'clone', 'https://github.com/pybind/pybind11.git', '--depth', '1'], cwd=testdir) src = testdir / 'pybind11' venv = src / 'venv' run([graalpy, '-m', 'venv', str(venv)]) @@ -120,7 +120,7 @@ def downstream_test_pybind11(graalpy, testdir): @downstream_test('virtualenv') def downstream_test_virtualenv(graalpy, testdir): - run(['git', 'clone', 'https://github.com/pypa/virtualenv.git', '-b', 'main'], cwd=testdir) + run(['git', 'clone', 'https://github.com/pypa/virtualenv.git', '-b', 'main', '--depth', '1'], cwd=testdir) src = testdir / 'virtualenv' venv = src / 'venv' run([graalpy, '-m', 'venv', str(venv)]) @@ -130,6 +130,15 @@ def downstream_test_virtualenv(graalpy, testdir): # Need to avoid pulling in graalpy seeder env['PIP_GRAALPY_DISABLE_PATCHING'] = '1' run_in_venv(venv, ['pip', 'install', f'{src}[test]'], env=env) + # Allow newer CPython for building zipapp, we don't have 3.11 in the CI anymore + run( + [ + 'sed', '-i', + 's/version in range(11, 6, -1)/version in range(14, 6, -1)/', + 'tests/integration/test_zipapp.py', + ], + cwd=src, + ) # Don't activate the venv, it interferes with the test run([ str(venv / 'bin' / 'pytest'), '-v', '--tb=short', 'tests', @@ -139,7 +148,7 @@ def downstream_test_virtualenv(graalpy, testdir): @downstream_test('pyo3') def downstream_test_pyo3(graalpy, testdir): - run(['git', 'clone', 'https://github.com/PyO3/pyo3.git', '-b', 'main'], cwd=testdir) + run(['git', 'clone', 'https://github.com/PyO3/pyo3.git', '-b', 'main', '--depth', '1'], cwd=testdir) src = testdir / 'pyo3' venv = src / 'venv' run([graalpy, '-m', 'venv', str(venv)]) @@ -149,9 +158,9 @@ def downstream_test_pyo3(graalpy, testdir): @downstream_test('pydantic-core') def downstream_test_pydantic_core(graalpy, testdir): - run(['git', 'clone', 'https://github.com/pydantic/pydantic.git', '-b', 'main'], cwd=testdir) + run(['git', 'clone', 'https://github.com/pydantic/pydantic.git', '-b', 'main', '--depth', '1'], cwd=testdir) src = testdir / 'pydantic' / 'pydantic-core' - run(['uv', 'sync', '--python', graalpy, '--group', 'testing-extra'], cwd=src) + run(['uv', 'sync', '--python', graalpy, '--group', 'testing-extra', '--no-install-project'], cwd=src) run(['uv', 'build', '--python', graalpy, '--wheel', '.'], cwd=src) [wheel] = (src.parent / 'dist').glob('pydantic_core-*graalpy*.whl') # uv doesn't accept wheels with devtags @@ -160,12 +169,12 @@ def downstream_test_pydantic_core(graalpy, testdir): run(['uv', 'pip', 'install', wheel], cwd=src) env = os.environ.copy() env['HYPOTHESIS_PROFILE'] = 'slow' - run(['uv', 'run', 'pytest', '-v', '--tb=short'], cwd=src, env=env) + run(['uv', 'run', '--no-sync', 'pytest', '-v', '--tb=short'], cwd=src, env=env) @downstream_test('jiter') def downstream_test_jiter(graalpy, testdir): - run(['git', 'clone', 'https://github.com/pydantic/jiter.git', '-b', 'main'], cwd=testdir) + run(['git', 'clone', 'https://github.com/pydantic/jiter.git', '-b', 'main', '--depth', '1'], cwd=testdir) src = testdir / 'jiter' venv = src / 'venv' run([graalpy, '-m', 'venv', str(venv)]) @@ -175,17 +184,25 @@ def downstream_test_jiter(graalpy, testdir): run_in_venv(venv, ['pytest', '-v', '--tb=short', 'crates/jiter-python/tests'], cwd=src) run_in_venv(venv, ['python', 'crates/jiter-python/bench.py', 'jiter', 'jiter-cache', '--fast'], cwd=src) + @downstream_test('cython') def downstream_test_cython(graalpy, testdir): - run(['git', 'clone', 'https://github.com/cython/cython.git', '-b', 'master'], cwd=testdir) + run(['git', 'clone', 'https://github.com/cython/cython.git', '-b', 'master', '--depth', '1'], cwd=testdir) src = testdir / 'cython' venv = src / 'venv' env = os.environ.copy() env["PYTHON_VERSION"] = "graalpy" env["BACKEND"] = "c" run([graalpy, '-m', 'venv', str(venv)]) + if os.environ.get('CI', '').lower() not in ('1', 'true'): + run(['sed', '-i', r's/^\s*sudo/#&/', 'Tools/ci-run.sh'], cwd=src) + try: + run([graalpy, '--version', '--experimental-options', '--engine.Compilation=false']) + except subprocess.CalledProcessError: + run(['sed', '-i', r's/--engine.Compilation=false//g', 'Tools/ci-run.sh'], cwd=src) run_in_venv(venv, ["bash", "./Tools/ci-run.sh"], cwd=src, env=env) + def run_downstream_test(python, project): testdir = Path('downstream-tests').absolute() shutil.rmtree(testdir, ignore_errors=True)