diff --git a/.github/workflows/downstream-tests.yml b/.github/workflows/downstream-tests.yml index 235a6c7c78..02eb747bec 100644 --- a/.github/workflows/downstream-tests.yml +++ b/.github/workflows/downstream-tests.yml @@ -12,36 +12,40 @@ jobs: name: - pybind11 - virtualenv - # Currently fails - # - pyo3 + - pyo3 os: - id: ubuntu-latest - graalpy_platform: linux-amd64 + platform: linux + arch: amd64 - id: macos-latest - graalpy_platform: darwin-aarch64 + platform: darwin + arch: aarch64 runs-on: ${{ matrix.os.id }} steps: - - name: Install CMake - if: ${{ matrix.name == 'pybind11' }} - uses: lukka/get-cmake@latest - with: - cmakeVersion: 3.30.8 - ninjaVersion: 1.12.1 + - name: Install CMake (Linux) + if: ${{ matrix.os.platform == 'linux' && matrix.name == 'pybind11' }} + run: | + sudo apt-get update + sudo apt-get install -y cmake + + - name: Install CMake (Darwin) + if: ${{ matrix.os.platform == 'darwin' && matrix.name == 'pybind11' }} + run: brew install cmake - name: Install Rust toolchain if: ${{ matrix.name == 'pyo3' }} - uses: actions-rs/toolchain@v1 - with: - toolchain: stable + run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + echo "${HOME}/.cargo/bin" >> $GITHUB_PATH - name: Checkout main repository uses: actions/checkout@v4 - name: Get GraalPy EA build run: | - tarball="$(curl -sfL https://raw.githubusercontent.com/graalvm/graal-languages-ea-builds/refs/heads/main/graalpy/versions/latest-native-${{ matrix.os.graalpy_platform }}.url)" + tarball="$(curl -sfL https://raw.githubusercontent.com/graalvm/graal-languages-ea-builds/refs/heads/main/graalpy/versions/latest-native-${{ matrix.os.platform }}-${{ matrix.os.arch}}.url)" curl -sfL "$tarball" | tar xz - name: Run downstream tests for ${{ matrix.name }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 09b6830cfb..8e5c3fce21 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -34,3 +34,4 @@ repos: language: python types: [text] files: '\.(java|py|md|c|h|sh)$' + exclude: '^graalpython/lib-python/.*' diff --git a/graalpython/com.oracle.graal.python.cext/CAPIFunctions.txt b/graalpython/com.oracle.graal.python.cext/CAPIFunctions.txt index 6098ed73e2..ad6331eaa6 100644 --- a/graalpython/com.oracle.graal.python.cext/CAPIFunctions.txt +++ b/graalpython/com.oracle.graal.python.cext/CAPIFunctions.txt @@ -120,7 +120,9 @@ PyDescr_NewMember;PyObject*;PyTypeObject*|PyMemberDef* PyDescr_NewMethod;PyObject*;PyTypeObject*|PyMethodDef* PyDescr_NewWrapper;PyObject*;PyTypeObject*|struct wrapperbase*|void* PyDictProxy_New;PyObject*;PyObject* +PyDict_AddWatcher;int;PyDict_WatchCallback PyDict_Clear;void;PyObject* +PyDict_ClearWatcher;int;int PyDict_Contains;int;PyObject*|PyObject* PyDict_Copy;PyObject*;PyObject* PyDict_DelItem;int;PyObject*|PyObject* @@ -138,19 +140,23 @@ PyDict_SetDefault;PyObject*;PyObject*|PyObject*|PyObject* PyDict_SetItem;int;PyObject*|PyObject*|PyObject* PyDict_SetItemString;int;PyObject*|const char*|PyObject* PyDict_Size;Py_ssize_t;PyObject* +PyDict_Unwatch;int;int|PyObject* PyDict_Update;int;PyObject*|PyObject* PyDict_Values;PyObject*;PyObject* +PyDict_Watch;int;int|PyObject* PyErr_BadArgument;int;void PyErr_BadInternalCall;void;void PyErr_CheckSignals;int;void PyErr_Clear;void;void PyErr_Display;void;PyObject*|PyObject*|PyObject* +PyErr_DisplayException;void;PyObject* PyErr_ExceptionMatches;int;PyObject* PyErr_Fetch;void;PyObject**|PyObject**|PyObject** PyErr_Format;PyObject*;PyObject*|const char*|... PyErr_FormatV;PyObject*;PyObject*|const char*|va_list PyErr_GetExcInfo;void;PyObject**|PyObject**|PyObject** PyErr_GetHandledException;PyObject*;void +PyErr_GetRaisedException;PyObject*;void PyErr_GivenExceptionMatches;int;PyObject*|PyObject* PyErr_NewException;PyObject*;const char*|PyObject*|PyObject* PyErr_NewExceptionWithDoc;PyObject*;const char*|const char*|PyObject*|PyObject* @@ -176,6 +182,7 @@ PyErr_SetInterrupt;void;void PyErr_SetInterruptEx;int;int PyErr_SetNone;void;PyObject* PyErr_SetObject;void;PyObject*|PyObject* +PyErr_SetRaisedException;void;PyObject* PyErr_SetString;void;PyObject*|const char* PyErr_SyntaxLocation;void;const char*|int PyErr_SyntaxLocationEx;void;const char*|int|int @@ -208,12 +215,16 @@ PyEval_ReleaseThread;void;PyThreadState* PyEval_RestoreThread;void;PyThreadState* PyEval_SaveThread;PyThreadState*;void PyEval_SetProfile;void;Py_tracefunc|PyObject* +PyEval_SetProfileAllThreads;void;Py_tracefunc|PyObject* PyEval_SetTrace;void;Py_tracefunc|PyObject* +PyEval_SetTraceAllThreads;void;Py_tracefunc|PyObject* PyEval_ThreadsInitialized;int;void PyExceptionClass_Name;const char*;PyObject* +PyException_GetArgs;PyObject*;PyObject* PyException_GetCause;PyObject*;PyObject* PyException_GetContext;PyObject*;PyObject* PyException_GetTraceback;PyObject*;PyObject* +PyException_SetArgs;void;PyObject*|PyObject* PyException_SetCause;void;PyObject*|PyObject* PyException_SetContext;void;PyObject*|PyObject* PyException_SetTraceback;int;PyObject*|PyObject* @@ -247,9 +258,13 @@ PyFrame_GetGlobals;PyObject*;PyFrameObject* PyFrame_GetLasti;int;PyFrameObject* PyFrame_GetLineNumber;int;PyFrameObject* PyFrame_GetLocals;PyObject*;PyFrameObject* +PyFrame_GetVar;PyObject*;PyFrameObject*|PyObject* +PyFrame_GetVarString;PyObject*;PyFrameObject*|const char* PyFrame_LocalsToFast;void;PyFrameObject*|int PyFrame_New;PyFrameObject*;PyThreadState*|PyCodeObject*|PyObject*|PyObject* PyFrozenSet_New;PyObject*;PyObject* +PyFunction_AddWatcher;int;PyFunction_WatchCallback +PyFunction_ClearWatcher;int;int PyFunction_GetAnnotations;PyObject*;PyObject* PyFunction_GetClosure;PyObject*;PyObject* PyFunction_GetCode;PyObject*;PyObject* @@ -272,6 +287,7 @@ PyGILState_Check;int;void PyGILState_Ensure;PyGILState_STATE;void PyGILState_GetThisThreadState;PyThreadState*;void PyGILState_Release;void;PyGILState_STATE +PyGen_GetCode;PyCodeObject*;PyGenObject* PyGen_New;PyObject*;PyFrameObject* PyGen_NewWithQualName;PyObject*;PyFrameObject*|PyObject*|PyObject* PyHash_GetFuncDef;PyHash_FuncDef*;void @@ -504,7 +520,9 @@ PyObject_GetAttr;PyObject*;PyObject*|PyObject* PyObject_GetAttrString;PyObject*;PyObject*|const char* PyObject_GetBuffer;int;PyObject*|Py_buffer*|int PyObject_GetItem;PyObject*;PyObject*|PyObject* +PyObject_GetItemData;void*;PyObject* PyObject_GetIter;PyObject*;PyObject* +PyObject_GetTypeData;void*;PyObject*|PyTypeObject* PyObject_HasAttr;int;PyObject*|PyObject* PyObject_HasAttrString;int;PyObject*|const char* PyObject_Hash;Py_hash_t;PyObject* @@ -588,7 +606,6 @@ PySet_Discard;int;PyObject*|PyObject* PySet_New;PyObject*;PyObject* PySet_Pop;PyObject*;PyObject* PySet_Size;Py_ssize_t;PyObject* -PySignal_SetWakeupFd;int;int PySlice_AdjustIndices;Py_ssize_t;Py_ssize_t|Py_ssize_t*|Py_ssize_t*|Py_ssize_t PySlice_GetIndices;int;PyObject*|Py_ssize_t|Py_ssize_t*|Py_ssize_t*|Py_ssize_t* PySlice_GetIndicesEx;int;PyObject*|Py_ssize_t|Py_ssize_t*|Py_ssize_t*|Py_ssize_t*|Py_ssize_t* @@ -678,12 +695,16 @@ PyTuple_New;PyObject*;Py_ssize_t PyTuple_Pack;PyObject*;Py_ssize_t|... PyTuple_SetItem;int;PyObject*|Py_ssize_t|PyObject* PyTuple_Size;Py_ssize_t;PyObject* +PyType_AddWatcher;int;PyType_WatchCallback PyType_ClearCache;unsigned int;void +PyType_ClearWatcher;int;int +PyType_FromMetaclass;PyObject*;PyTypeObject*|PyObject*|PyType_Spec*|PyObject* PyType_FromModuleAndSpec;PyObject*;PyObject*|PyType_Spec*|PyObject* PyType_FromSpec;PyObject*;PyType_Spec* PyType_FromSpecWithBases;PyObject*;PyType_Spec*|PyObject* PyType_GenericAlloc;PyObject*;PyTypeObject*|Py_ssize_t PyType_GenericNew;PyObject*;PyTypeObject*|PyObject*|PyObject* +PyType_GetDict;PyObject*;PyTypeObject* PyType_GetFlags;unsigned long;PyTypeObject* PyType_GetModule;PyObject*;PyTypeObject* PyType_GetModuleByDef;PyObject*;PyTypeObject*|PyModuleDef* @@ -691,10 +712,13 @@ PyType_GetModuleState;void*;PyTypeObject* PyType_GetName;PyObject*;PyTypeObject* PyType_GetQualName;PyObject*;PyTypeObject* PyType_GetSlot;void*;PyTypeObject*|int +PyType_GetTypeDataSize;Py_ssize_t;PyTypeObject* PyType_IsSubtype;int;PyTypeObject*|PyTypeObject* PyType_Modified;void;PyTypeObject* PyType_Ready;int;PyTypeObject* PyType_SUPPORTS_WEAKREFS;int;PyTypeObject* +PyType_Unwatch;int;int|PyObject* +PyType_Watch;int;int|PyObject* PyUnicodeDecodeError_Create;PyObject*;const char*|const char*|Py_ssize_t|Py_ssize_t|Py_ssize_t|const char* PyUnicodeDecodeError_GetEncoding;PyObject*;PyObject* PyUnicodeDecodeError_GetEnd;int;PyObject*|Py_ssize_t* @@ -806,8 +830,22 @@ PyUnstable_Code_GetExtra;int;PyObject*|Py_ssize_t|void** PyUnstable_Code_New;PyCodeObject*;int|int|int|int|int|PyObject*|PyObject*|PyObject*|PyObject*|PyObject*|PyObject*|PyObject*|PyObject*|PyObject*|int|PyObject*|PyObject* PyUnstable_Code_NewWithPosOnlyArgs;PyCodeObject*;int|int|int|int|int|int|PyObject*|PyObject*|PyObject*|PyObject*|PyObject*|PyObject*|PyObject*|PyObject*|PyObject*|int|PyObject*|PyObject* PyUnstable_Code_SetExtra;int;PyObject*|Py_ssize_t|void* +PyUnstable_Eval_RequestCodeExtraIndex;Py_ssize_t;freefunc +PyUnstable_Exc_PrepReraiseStar;PyObject*;PyObject*|PyObject* +PyUnstable_GC_VisitObjects;void;gcvisitobjects_t|void* +PyUnstable_InterpreterFrame_GetCode;PyObject*;struct _PyInterpreterFrame* +PyUnstable_InterpreterFrame_GetLasti;int;struct _PyInterpreterFrame* +PyUnstable_InterpreterFrame_GetLine;int;struct _PyInterpreterFrame* +PyUnstable_Long_CompactValue;Py_ssize_t;const PyLongObject* +PyUnstable_Long_IsCompact;int;const PyLongObject* +PyUnstable_Object_GC_NewWithExtraData;PyObject*;PyTypeObject*|size_t +PyUnstable_PerfMapState_Fini;void;void +PyUnstable_PerfMapState_Init;int;void +PyUnstable_Type_AssignVersionTag;int;PyTypeObject* +PyUnstable_WritePerfMapEntry;int;const void*|unsigned int|const char* PyVectorcall_Call;PyObject*;PyObject*|PyObject*|PyObject* PyVectorcall_Function;vectorcallfunc;PyObject* +PyVectorcall_NARGS;Py_ssize_t;size_t PyWeakref_GetObject;PyObject*;PyObject* PyWeakref_NewProxy;PyObject*;PyObject*|PyObject* PyWeakref_NewRef;PyObject*;PyObject*|PyObject* @@ -861,6 +899,7 @@ Py_LeaveRecursiveCall;void;void Py_Main;int;int|wchar_t** Py_MakePendingCalls;int;void Py_NewInterpreter;PyThreadState*;void +Py_NewInterpreterFromConfig;PyStatus;PyThreadState**|const PyInterpreterConfig* Py_NewRef;PyObject*;PyObject* Py_PreInitialize;PyStatus;const PyPreConfig* Py_PreInitializeFromArgs;PyStatus;const PyPreConfig*|Py_ssize_t|wchar_t** @@ -942,14 +981,15 @@ _PyDict_SetItemId;int;PyObject*|_Py_Identifier*|PyObject* _PyDict_SetItem_KnownHash;int;PyObject*|PyObject*|PyObject*|Py_hash_t _PyDict_SizeOf;Py_ssize_t;PyDictObject* _PyErr_BadInternalCall;void;const char*|int -_PyErr_ChainExceptions;void;PyObject*|PyObject*|PyObject* _PyErr_ChainExceptions1;void;PyObject* +_PyErr_ChainExceptions;void;PyObject*|PyObject*|PyObject* _PyErr_CheckSignals;int;void _PyErr_FormatFromCause;PyObject*;PyObject*|const char*|... _PyErr_GetExcInfo;void;PyThreadState*|PyObject**|PyObject**|PyObject** _PyErr_GetHandledException;PyObject*;PyThreadState* _PyErr_GetTopmostException;_PyErr_StackItem*;PyThreadState* _PyErr_ProgramDecodedTextObject;PyObject*;PyObject*|int|const char* +_PyErr_SetFromPyStatus;PyObject*;PyStatus _PyErr_SetHandledException;void;PyThreadState*|PyObject* _PyErr_SetKeyError;void;PyObject* _PyErr_WriteUnraisableMsg;void;const char*|PyObject* @@ -957,12 +997,13 @@ _PyEval_EvalFrameDefault;PyObject*;PyThreadState*|struct _PyInterpreterFrame*|in _PyEval_GetBuiltin;PyObject*;PyObject* _PyEval_GetBuiltinId;PyObject*;_Py_Identifier* _PyEval_GetSwitchInterval;unsigned long;void +_PyEval_MakePendingCalls;int;PyThreadState* _PyEval_SetProfile;int;PyThreadState*|Py_tracefunc|PyObject* _PyEval_SetSwitchInterval;void;unsigned long _PyEval_SetTrace;int;PyThreadState*|Py_tracefunc|PyObject* _PyEval_SliceIndex;int;PyObject*|Py_ssize_t* _PyEval_SliceIndexNotNone;int;PyObject*|Py_ssize_t* -PyUnstable_Eval_RequestCodeExtraIndex;Py_ssize_t;freefunc +_PyException_AddNote;int;PyObject*|PyObject* _PyFrame_IsEntryFrame;int;PyFrameObject* _PyFunction_Vectorcall;PyObject*;PyObject*|PyObject*const*|size_t|PyObject* _PyGILState_GetInterpreterStateUnsafe;PyInterpreterState*;void @@ -1000,6 +1041,7 @@ _PyLong_Format;PyObject*;PyObject*|int _PyLong_Frexp;double;PyLongObject*|Py_ssize_t* _PyLong_FromByteArray;PyObject*;const unsigned char*|size_t|int|int _PyLong_FromBytes;PyObject*;const char*|Py_ssize_t|int +_PyLong_FromDigits;PyLongObject*;int|Py_ssize_t|digit* _PyLong_FromTime_t;PyObject*;time_t _PyLong_GCD;PyObject*;PyObject*|PyObject* _PyLong_Lshift;PyObject*;PyObject*|size_t @@ -1034,6 +1076,7 @@ _PyObject_CallMethodId_SizeT;PyObject*;PyObject*|_Py_Identifier*|const char*|... _PyObject_CallMethod_SizeT;PyObject*;PyObject*|const char*|const char*|... _PyObject_CheckConsistency;int;PyObject*|int _PyObject_CheckCrossInterpreterData;int;PyObject* +_PyObject_ClearManagedDict;void;PyObject* _PyObject_DebugTypeStats;void;FILE* _PyObject_Dump;void;PyObject* _PyObject_FastCall;PyObject*;PyObject*|PyObject*const*|Py_ssize_t @@ -1061,6 +1104,7 @@ _PyObject_NextNotImplemented;PyObject*;PyObject* _PyObject_RealIsInstance;int;PyObject*|PyObject* _PyObject_RealIsSubclass;int;PyObject*|PyObject* _PyObject_SetAttrId;int;PyObject*|_Py_Identifier*|PyObject* +_PyObject_VisitManagedDict;int;PyObject*|visitproc|void* _PyRun_AnyFileObject;int;FILE*|PyObject*|int|PyCompilerFlags* _PyRun_InteractiveLoopObject;int;FILE*|PyObject*|PyCompilerFlags* _PyRun_SimpleFileObject;int;FILE*|PyObject*|int|PyCompilerFlags* @@ -1090,6 +1134,7 @@ _PyTime_AsTimespec_clamp;void;_PyTime_t|struct timespec* _PyTime_AsTimeval;int;_PyTime_t|struct timeval*|_PyTime_round_t _PyTime_AsTimevalTime_t;int;_PyTime_t|time_t*|int*|_PyTime_round_t _PyTime_AsTimeval_clamp;void;_PyTime_t|struct timeval*|_PyTime_round_t +_PyTime_FromMicrosecondsClamp;_PyTime_t;_PyTime_t _PyTime_FromMillisecondsObject;int;_PyTime_t*|PyObject*|_PyTime_round_t _PyTime_FromNanoseconds;_PyTime_t;_PyTime_t _PyTime_FromNanosecondsObject;int;_PyTime_t*|PyObject* @@ -1109,7 +1154,18 @@ _PyTime_ObjectToTimespec;int;PyObject*|time_t*|long*|_PyTime_round_t _PyTime_ObjectToTimeval;int;PyObject*|time_t*|long*|_PyTime_round_t _PyTime_gmtime;int;time_t|struct tm* _PyTime_localtime;int;time_t|struct tm* +_PyTraceMalloc_ClearTraces;void;void +_PyTraceMalloc_GetMemory;size_t;void +_PyTraceMalloc_GetObjectTraceback;PyObject*;PyObject* _PyTraceMalloc_GetTraceback;PyObject*;unsigned int|uintptr_t +_PyTraceMalloc_GetTracebackLimit;int;void +_PyTraceMalloc_GetTracedMemory;PyObject*;void +_PyTraceMalloc_GetTraces;PyObject*;void +_PyTraceMalloc_Init;int;void +_PyTraceMalloc_IsTracing;int;void +_PyTraceMalloc_ResetPeak;void;void +_PyTraceMalloc_Start;int;int +_PyTraceMalloc_Stop;void;void _PyTraceback_Add;void;const char*|const char*|int _PyTrash_begin;int;PyThreadState*|PyObject* _PyTrash_cond;int;PyObject*|destructor @@ -1190,6 +1246,7 @@ _PyUnicode_WideCharString_Opt_Converter;int;PyObject*|void* _PyUnicode_XStrip;PyObject*;PyObject*|int|PyObject* _PyWeakref_ClearRef;void;PyWeakReference* _PyWeakref_GetWeakrefCount;Py_ssize_t;PyWeakReference* +_Py_AtExit;int;PyInterpreterState*|atexit_datacallbackfunc|void* _Py_BreakPoint;void;void _Py_BuildValue_SizeT;PyObject*;const char*|... _Py_CheckFunctionResult;PyObject*;PyThreadState*|PyObject*|PyObject*|const char* @@ -1210,8 +1267,10 @@ _Py_IncRef;void;PyObject* _Py_InitializeMain;PyStatus;void _Py_IsCoreInitialized;int;void _Py_IsFinalizing;int;void +_Py_IsInterpreterFinalizing;int;PyInterpreterState* _Py_LegacyLocaleDetected;int;int _Py_NewReference;void;PyObject* +_Py_NewReferenceNoTotal;void;PyObject* _Py_RestoreSignals;void;void _Py_SetLocaleFromEnv;char*;int _Py_SetProgramFullPath;void;const wchar_t* diff --git a/graalpython/com.oracle.graal.python.cext/src/dictobject.c b/graalpython/com.oracle.graal.python.cext/src/dictobject.c index 2f74399a2b..937d570133 100644 --- a/graalpython/com.oracle.graal.python.cext/src/dictobject.c +++ b/graalpython/com.oracle.graal.python.cext/src/dictobject.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2024, Oracle and/or its affiliates. +/* Copyright (c) 2024, 2025, Oracle and/or its affiliates. * Copyright (C) 1996-2024 Python Software Foundation * * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -5555,10 +5555,12 @@ _PyObject_IsInstanceDictEmpty(PyObject *obj) } return ((PyDictObject *)dict)->ma_used == 0; } +#endif // GraalPy change void _PyObject_FreeInstanceAttributes(PyObject *self) { +#if 0 // GraalPy change PyTypeObject *tp = Py_TYPE(self); assert(Py_TYPE(self)->tp_flags & Py_TPFLAGS_MANAGED_DICT); PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(self); @@ -5571,11 +5573,13 @@ _PyObject_FreeInstanceAttributes(PyObject *self) Py_XDECREF(values->values[i]); } free_values(values); +#endif // GraalPy change } int _PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg) { +#if 0 // GraalPy change PyTypeObject *tp = Py_TYPE(obj); if((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { return 0; @@ -5593,12 +5597,14 @@ _PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg) PyObject *dict = _PyDictOrValues_GetDict(dorv); Py_VISIT(dict); } +#endif // GraalPy change return 0; } void _PyObject_ClearManagedDict(PyObject *obj) { +#if 0 // GraalPy change PyTypeObject *tp = Py_TYPE(obj); if((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { return; @@ -5620,8 +5626,8 @@ _PyObject_ClearManagedDict(PyObject *obj) Py_DECREF(dict); } } -} #endif // GraalPy change +} PyObject * PyObject_GenericGetDict(PyObject *obj, void *context) diff --git a/graalpython/com.oracle.graal.python.cext/src/errors.c b/graalpython/com.oracle.graal.python.cext/src/errors.c index bf31bd6bb6..fe6e079778 100644 --- a/graalpython/com.oracle.graal.python.cext/src/errors.c +++ b/graalpython/com.oracle.graal.python.cext/src/errors.c @@ -597,18 +597,30 @@ _PyErr_GetExcInfo(PyThreadState *tstate, // GraalPy change: different implementation PyObject* result = GraalPyTruffleErr_GetExcInfo(); if(result == NULL) { - *p_type = NULL; - *p_value = NULL; - *p_traceback = NULL; + *p_type = Py_NewRef(Py_None); + *p_value = Py_NewRef(Py_None); + *p_traceback = Py_NewRef(Py_None); } else { - *p_type = Py_XNewRef(PyTuple_GetItem(result, 0)); - *p_value = Py_XNewRef(PyTuple_GetItem(result, 1)); - *p_traceback = Py_XNewRef(PyTuple_GetItem(result, 2)); + *p_type = Py_XNewRef(PyTuple_GetItem(result, 0)); + *p_value = Py_XNewRef(PyTuple_GetItem(result, 1)); + *p_traceback = Py_XNewRef(PyTuple_GetItem(result, 2)); Py_DecRef(result); } } #if 0 // GraalPy change +PyObject* +_PyErr_GetHandledException(PyThreadState *tstate) +{ + _PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate); + PyObject *exc = exc_info->exc_value; + if (exc == NULL || exc == Py_None) { + return NULL; + } + return Py_NewRef(exc); +} +#endif // GraalPy change + PyObject* PyErr_GetHandledException(void) { @@ -616,11 +628,13 @@ PyErr_GetHandledException(void) return _PyErr_GetHandledException(tstate); } +#if 0 // GraalPy change void _PyErr_SetHandledException(PyThreadState *tstate, PyObject *exc) { Py_XSETREF(tstate->exc_info->exc_value, Py_XNewRef(exc)); } +#endif // GraalPy change void PyErr_SetHandledException(PyObject *exc) @@ -628,7 +642,6 @@ PyErr_SetHandledException(PyObject *exc) PyThreadState *tstate = _PyThreadState_GET(); _PyErr_SetHandledException(tstate, exc); } -#endif // GraalPy change void PyErr_GetExcInfo(PyObject **p_type, PyObject **p_value, PyObject **p_traceback) @@ -637,7 +650,6 @@ PyErr_GetExcInfo(PyObject **p_type, PyObject **p_value, PyObject **p_traceback) _PyErr_GetExcInfo(tstate, p_type, p_value, p_traceback); } -#if 0 // GraalPy change void PyErr_SetExcInfo(PyObject *type, PyObject *value, PyObject *traceback) { @@ -649,6 +661,7 @@ PyErr_SetExcInfo(PyObject *type, PyObject *value, PyObject *traceback) } +#if 0 // GraalPy change PyObject* _PyErr_StackItemToExcInfoTuple(_PyErr_StackItem *err_info) { diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_capsule.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_capsule.py index 1cb6422c1e..d32a20ad71 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_capsule.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_capsule.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, 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,12 +37,21 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. import gc +import re + import os import time from . import CPyExtTestCase, CPyExtFunction, unhandled_error_compare, CPyExtType +def _capsule_repr_cmpfunc(a, b): + if isinstance(a, str) and (b, str): + a = re.sub("0x[a-f0-9]+", "0xaaa", a) + b = re.sub("0x[a-f0-9]+", "0xaaa", b) + return unhandled_error_compare(a, b) + + class TestPyCapsule(CPyExtTestCase): test_PyCapsule_CheckExact = CPyExtFunction( lambda args: True, @@ -150,6 +159,24 @@ class TestPyCapsule(CPyExtTestCase): cmpfunc=unhandled_error_compare ) + test_PyCapsule__repr__ = CPyExtFunction( + lambda args: f'', + lambda: ( + ("hello", 0xDEADBEEF), + ), + code=''' + PyObject* wrap_PyCapsule__repr__(char * name, Py_ssize_t ptr) { + PyObject* capsule = PyCapsule_New((void*)ptr, name, NULL); + return PyObject_Repr(capsule); + } + ''', + resultspec="O", + argspec='sn', + arguments=["char* name", "Py_ssize_t ptr"], + callfunction="wrap_PyCapsule__repr__", + cmpfunc=_capsule_repr_cmpfunc, + ) + if os.environ.get('GRAALPYTEST_RUN_GC_TESTS'): def test_capsule_destructor(self): Tester = CPyExtType( @@ -161,7 +188,7 @@ def test_capsule_destructor(self): PyDict_SetItemString(contents, "destructor_was_here", Py_NewRef(Py_True)); Py_DECREF(contents); } - + static PyObject* create_capsule(PyObject* unused, PyObject* contents) { return PyCapsule_New(Py_NewRef(contents), "capsule", capsule_destructor); } diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_err.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_err.py index 5832b644c9..4e0d68e986 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_err.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_err.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, 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 @@ -186,12 +186,12 @@ class Dummy: pass -def raise_erorr(): +def raise_error(): raise NameError try: - raise_erorr() + raise_error() except NameError as e: example_traceback = e.__traceback__ else: @@ -654,6 +654,78 @@ class TestPyErr(CPyExtTestCase): # ) +class TestCaughtException(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.tester = CPyExtType( + "CaughtExceptionTester", + """ + PyObject* TestPyErr_GetHandledException(PyObject* self) { + PyObject* result = PyErr_GetHandledException(); + if (result == NULL) + Py_RETURN_NONE; + return result; + } + PyObject* TestPyErr_GetExcInfo(PyObject* self) { + PyObject* typ; + PyObject* val; + PyObject* tb; + PyErr_GetExcInfo(&typ, &val, &tb); + return Py_BuildValue("OOO", typ, val, tb); + } + PyObject* TestPyErr_SetHandledException(PyObject* self, PyObject* arg) { + PyErr_SetHandledException(arg != Py_None? arg : NULL); + return TestPyErr_GetHandledException(NULL); + } + PyObject* TestPyErr_SetExcInfo(PyObject* self, PyObject* arg) { + PyErr_SetExcInfo(Py_NewRef(Py_None), Py_NewRef(arg), Py_NewRef(Py_None)); + return TestPyErr_GetHandledException(NULL); + } + """, + tp_methods=''' + {"PyErr_GetHandledException", (PyCFunction)TestPyErr_GetHandledException, METH_NOARGS | METH_STATIC, ""}, + {"PyErr_GetExcInfo", (PyCFunction)TestPyErr_GetExcInfo, METH_NOARGS | METH_STATIC, ""}, + {"PyErr_SetHandledException", (PyCFunction)TestPyErr_SetHandledException, METH_O | METH_STATIC, ""}, + {"PyErr_SetExcInfo", (PyCFunction)TestPyErr_SetExcInfo, METH_O | METH_STATIC, ""} + ''' + ) + + def test_PyErr_GetHandledException(self): + try: + raise IndexError + except IndexError as e: + self.assertIs(self.tester.PyErr_GetHandledException(), e) + # do a second time because this time we won't do a stack walk + self.assertIs(self.tester.PyErr_GetHandledException(), e) + + def test_PyErr_GetHandledException_no_exception(self): + self.assertIsNone(self.tester.PyErr_GetHandledException()) + self.assertIsNone(self.tester.PyErr_GetHandledException()) + + def test_PyErr_GetExcInfo(self): + try: + raise IndexError + except IndexError as e: + self.assertEqual(self.tester.PyErr_GetExcInfo(), (type(e), e, e.__traceback__)) + # do a second time because this time we won't do a stack walk + self.assertEqual(self.tester.PyErr_GetExcInfo(), (type(e), e, e.__traceback__)) + + def test_PyErr_GetExcInfo_no_exception(self): + self.assertEqual(self.tester.PyErr_GetExcInfo(), (None, None, None)) + self.assertEqual(self.tester.PyErr_GetExcInfo(), (None, None, None)) + + def test_TestPyErr_SetHandledException(self): + e = IndexError() + # TODO on GraalPy the exception doesn't propagate to the function frame, so we can't use sys.exc_info() here + self.assertIs(self.tester.PyErr_SetHandledException(e), e) + self.assertIsNone(self.tester.PyErr_SetHandledException(None)) + + def test_TestPyErr_SetExcInfo(self): + e = IndexError() + self.assertIs(self.tester.PyErr_SetExcInfo(e), e) + self.assertIsNone(self.tester.PyErr_SetExcInfo(None)) + + def raise_native_exception(): raise ExceptionSubclass(1) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_exceptionobject.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_exceptionobject.py index 03f6d4e95d..2d5ad1348e 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_exceptionobject.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_exceptionobject.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, 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 @@ -49,86 +49,6 @@ exception_with_traceback = e -class TestExceptionobject(unittest.TestCase): - def test_exc_info(self): - TestExcInfo = CPyExtType("TestExcInfo", - """ - PyObject* get_exc_info(PyObject* self) { - PyObject* typ; - PyObject* val; - PyObject* tb; - PyErr_GetExcInfo(&typ, &val, &tb); - Py_XDECREF(val); - Py_XDECREF(tb); - if (typ == NULL) { - Py_RETURN_NONE; - } - return typ; - } - """, - tp_methods='{"get_exc_info", (PyCFunction)get_exc_info, METH_NOARGS, ""}' - ) - tester = TestExcInfo() - try: - raise IndexError - except IndexError: - exc_type = tester.get_exc_info() - assert exc_type == IndexError - - # do a second time because this time we won't do a stack walk - # disabled due to GR-34711 - # exc_type = tester.get_exc_info() - # assert exc_type == IndexError - else: - assert False - - def test_set_exc_info(self): - TestSetExcInfo = CPyExtType("TestSetExcInfo", - """ - PyObject* set_exc_info(PyObject* self, PyObject* args) { - PyObject* typ = PyTuple_GetItem(args, 0); - PyObject* val = PyTuple_GetItem(args, 1); - PyObject* tb = PyTuple_GetItem(args, 2); - PyObject* typ1 = NULL; - PyObject* val1 = NULL; - PyObject* tb1 = NULL; - - Py_XINCREF(typ); - Py_XINCREF(val); - Py_XINCREF(tb); - PyErr_SetExcInfo(typ, val, tb); - - PyErr_GetExcInfo(&typ1, &val1, &tb1); - // ignore the traceback for now - if(typ == typ1 && val == val1) { - return Py_True; - } - return Py_False; - } - """, - tp_methods='{"set_exc_info", (PyCFunction)set_exc_info, METH_O, ""}' - ) - tester = TestSetExcInfo() - try: - raise IndexError - except: - typ, val, tb = sys.exc_info() - assert typ == IndexError - - - - # overwrite exception info - expected = (ValueError, ValueError(), None) - res = tester.set_exc_info(expected) - assert res - - # TODO uncomment once supported - # actual = sys.exc_info() - # assert actual == expected - else: - assert False - - def raise_exception_with_cause(): try: raise RuntimeError() diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_float.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_float.py index d05f53d74d..6f4b3cb978 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_float.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_float.py @@ -146,6 +146,8 @@ class TestPyFloat(CPyExtTestCase): ("nan",), ("-inf",), ("not-a-float",), + (b"1",), + (memoryview(b"1"),), ), resultspec="O", argspec='O', diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_modsupport.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_modsupport.py index ca2c5aeea2..8a7c77f218 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_modsupport.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_modsupport.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, 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 @@ -81,6 +81,15 @@ def _reference_parse_tuple(args): raise TypeError +def _reference_validate_keywords(args): + kwargs = args[0] + if not isinstance(kwargs, dict): + raise SystemError + if not all(isinstance(k, str) for k in kwargs): + raise TypeError + return 1 + + class Indexable: def __int__(self): return 456 @@ -717,3 +726,16 @@ def compare_new_object(x, y): arguments=["PyObject* a"], cmpfunc=compare_new_object ) + + test_PyArg_ValidateKeywordArguments = CPyExtFunction( + _reference_validate_keywords, + lambda: ( + ({'a': 1, 'b': 2},), + ({'a': 1, 1: 2},), + ("not-dict",), + ), + resultspec='i', + argspec='O', + arguments=["PyObject* kwds"], + cmpfunc=unhandled_error_compare, + ) 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 c0e51deae7..5407b0292d 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 @@ -269,6 +269,7 @@ import com.oracle.graal.python.builtins.objects.thread.ThreadLocalBuiltins; import com.oracle.graal.python.builtins.objects.tokenize.TokenizerIterBuiltins; import com.oracle.graal.python.builtins.objects.traceback.TracebackBuiltins; +import com.oracle.graal.python.builtins.objects.tuple.CapsuleBuiltins; import com.oracle.graal.python.builtins.objects.tuple.InstantiableStructSequenceBuiltins; import com.oracle.graal.python.builtins.objects.tuple.StructSequenceBuiltins; import com.oracle.graal.python.builtins.objects.tuple.TupleBuiltins; @@ -1251,7 +1252,7 @@ def takewhile(predicate, iterable): // CPython uses separate keys, values, items python types for the iterators. ContextIterator("context_iterator", PythonObject, newBuilder().publishInModule(J__CONTEXTVARS).slots(ContextIteratorBuiltins.SLOTS)), - Capsule("PyCapsule", PythonObject, newBuilder().basetype()), + Capsule("PyCapsule", PythonObject, newBuilder().basetype().slots(CapsuleBuiltins.SLOTS)), PTokenizerIter("TokenizerIter", PythonObject, newBuilder().publishInModule("_tokenize").basetype().slots(TokenizerIterBuiltins.SLOTS)), diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextDictBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextDictBuiltins.java index f8a2d152f8..3771a81c60 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextDictBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextDictBuiltins.java @@ -76,6 +76,7 @@ import com.oracle.graal.python.builtins.objects.cext.capi.CApiContext; import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions; import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess; +import com.oracle.graal.python.builtins.objects.common.DynamicObjectStorage; import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage; import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes.SetItemNode; import com.oracle.graal.python.builtins.objects.common.HashingStorage; @@ -93,6 +94,7 @@ import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageLen; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageSetItem; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageSetItemWithHash; +import com.oracle.graal.python.builtins.objects.common.KeywordsStorage; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetItemNode; import com.oracle.graal.python.builtins.objects.dict.DictBuiltins.ClearNode; import com.oracle.graal.python.builtins.objects.dict.DictBuiltins.PopNode; @@ -105,6 +107,7 @@ import com.oracle.graal.python.lib.PyDictSetDefault; import com.oracle.graal.python.lib.PyObjectGetAttr; import com.oracle.graal.python.lib.PyObjectHashNode; +import com.oracle.graal.python.lib.PyUnicodeCheckNode; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.builtins.ListNodes.ConstructListNode; import com.oracle.graal.python.nodes.call.CallNode; @@ -127,6 +130,7 @@ import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedBranchProfile; +import com.oracle.truffle.api.profiles.InlinedConditionProfile; import com.oracle.truffle.api.profiles.InlinedLoopConditionProfile; public final class PythonCextDictBuiltins { @@ -654,4 +658,32 @@ static boolean isTracked(Object object, CStructAccess.ReadI64Node readI64Node) { // return false; } } + + @CApiBuiltin(ret = Int, args = {PyObject}, call = Direct) + abstract static class _PyDict_HasOnlyStringKeys extends CApiUnaryBuiltinNode { + + @Specialization + static int check(PDict dict, + @Bind Node inliningTarget, + @Cached InlinedConditionProfile storageProfile, + @Cached InlinedLoopConditionProfile loopConditionProfile, + @Cached HashingStorageGetIterator getIter, + @Cached HashingStorageIteratorNext getIterNext, + @Cached HashingStorageIteratorKey getIterKey, + @Cached PyUnicodeCheckNode check) { + HashingStorage storage = dict.getDictStorage(); + // Keywords and dynamic object storages only allow strings + if (storageProfile.profile(inliningTarget, storage instanceof KeywordsStorage || storage instanceof DynamicObjectStorage)) { + return 1; + } + HashingStorageIterator it = getIter.execute(inliningTarget, storage); + while (loopConditionProfile.profile(inliningTarget, getIterNext.execute(inliningTarget, storage, it))) { + Object key = getIterKey.execute(inliningTarget, storage, it); + if (!check.execute(inliningTarget, key)) { + return 0; + } + } + return 1; + } + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextErrBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextErrBuiltins.java index 2f7294d8a0..c39172bcaf 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextErrBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextErrBuiltins.java @@ -49,6 +49,7 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Int; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObject; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectTransfer; +import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyThreadState; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Void; import static com.oracle.graal.python.builtins.objects.exception.PBaseException.T_CODE; import static com.oracle.graal.python.nodes.BuiltinNames.T_EXCEPTHOOK; @@ -118,7 +119,6 @@ import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Shared; -import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.exception.AbstractTruffleException; import com.oracle.truffle.api.nodes.Node; @@ -151,11 +151,12 @@ static Object clear(Object exception, @SuppressWarnings("unused") PNone tb) { } } - @CApiBuiltin(ret = Void, args = {PyObject, PyObject, PyObject}, call = Direct) - abstract static class PyErr_SetExcInfo extends CApiTernaryBuiltinNode { + @CApiBuiltin(ret = Void, args = {PyThreadState, PyObject}, call = Direct) + abstract static class _PyErr_SetHandledException extends CApiBinaryBuiltinNode { + @Specialization @SuppressWarnings("unused") - Object doClear(Object typ, PNone val, Object tb, + static Object doClear(@SuppressWarnings("unused") Object threadState, PNone val, @Bind("this") Node inliningTarget, @Bind PythonContext context) { PythonLanguage lang = context.getLanguage(inliningTarget); @@ -164,7 +165,7 @@ Object doClear(Object typ, PNone val, Object tb, } @Specialization - Object doFull(@SuppressWarnings("unused") Object typ, PBaseException val, @SuppressWarnings("unused") Object tb, + static Object doFull(@SuppressWarnings("unused") Object threadState, PBaseException val, @Bind("this") Node inliningTarget, @Bind PythonContext context) { PythonLanguage language = context.getLanguage(inliningTarget); @@ -172,14 +173,6 @@ Object doFull(@SuppressWarnings("unused") Object typ, PBaseException val, @Suppr context.getThreadState(language).setCaughtException(e); return PNone.NONE; } - - @Fallback - @SuppressWarnings("unused") - Object doFallback(Object typ, Object val, Object tb) { - // TODO we should still store the values to return them with 'PyErr_GetExcInfo' (or - // 'sys.exc_info') - return PNone.NONE; - } } /** @@ -313,6 +306,23 @@ Object info( } } + @CApiBuiltin(ret = PyObjectTransfer, args = {PyThreadState}, call = Direct) + abstract static class _PyErr_GetHandledException extends CApiUnaryBuiltinNode { + + @Specialization + static Object get(@SuppressWarnings("unused") Object threadState, + @Bind("this") Node inliningTarget, + @Cached GetCaughtExceptionNode getCaughtExceptionNode, + @Cached GetEscapedExceptionNode getEscapedExceptionNode) { + AbstractTruffleException caughtException = getCaughtExceptionNode.executeFromNative(); + if (caughtException == null) { + return PythonContext.get(inliningTarget).getNativeNull(); + } + assert caughtException != PException.NO_EXCEPTION; + return getEscapedExceptionNode.execute(inliningTarget, caughtException); + } + } + @CApiBuiltin(ret = Void, args = {ConstCharPtrAsTruffleString, PyObject}, call = Direct) abstract static class _PyErr_WriteUnraisableMsg extends CApiBinaryBuiltinNode { @Specialization @@ -491,4 +501,27 @@ Object setTraceback(Object exc, Object traceback, return 0; } } + + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject}, call = Direct) + abstract static class PyException_GetArgs extends CApiUnaryBuiltinNode { + + @Specialization + static Object get(Object exc, + @Bind Node inliningTarget, + @Cached ExceptionNodes.GetArgsNode getArgsNode) { + return getArgsNode.execute(inliningTarget, exc); + } + } + + @CApiBuiltin(ret = Void, args = {PyObject, PyObject}, call = Direct) + abstract static class PyException_SetArgs extends CApiBinaryBuiltinNode { + + @Specialization + static Object set(PBaseException exc, PTuple args, + @Bind Node inliningTarget, + @Cached ExceptionNodes.SetArgsNode setArgsNode) { + setArgsNode.execute(inliningTarget, exc, args); + return PNone.NO_VALUE; + } + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextFloatBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextFloatBuiltins.java index 855c106f90..1fd5e30340 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextFloatBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextFloatBuiltins.java @@ -44,7 +44,6 @@ import static com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiCallPath.Direct; import static com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiCallPath.Ignored; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObject; -import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectAsTruffleString; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectTransfer; import static com.oracle.graal.python.nodes.ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC_WAS_S_P; @@ -59,7 +58,6 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.strings.TruffleString; public final class PythonCextFloatBuiltins { @@ -101,11 +99,11 @@ static double doGenericErr(Object object, } } - @CApiBuiltin(ret = PyObjectTransfer, args = {PyObjectAsTruffleString}, call = Direct) + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject}, call = Direct) abstract static class PyFloat_FromString extends CApiUnaryBuiltinNode { @Specialization - static Object fromString(TruffleString string, + static Object fromString(Object string, @Bind("this") Node inliningTarget, @Cached PyFloatFromString pyFloatFromString) { return pyFloatFromString.execute(null, inliningTarget, string); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextPyStateBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextPyStateBuiltins.java index 36a161c79b..1b22c69df3 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextPyStateBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextPyStateBuiltins.java @@ -216,7 +216,7 @@ protected void perform(Access access) { @CApiBuiltin(ret = PyFrameObjectTransfer, args = {PyThreadState}, call = Direct) abstract static class PyThreadState_GetFrame extends CApiUnaryBuiltinNode { @Specialization - PFrame get( + PFrame get(@SuppressWarnings("unused") Object threadState, @Bind("this") Node inliningTarget, @Cached GetCurrentFrameRef getCurrentFrameRef, @Cached ReadCallerFrameNode readCallerFrameNode) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextSlotBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextSlotBuiltins.java index 6f77c25335..665087aee4 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextSlotBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextSlotBuiltins.java @@ -590,8 +590,9 @@ static Object get(Object object, @CApiBuiltin(ret = Pointer, args = {PyModuleObject}, call = Ignored) abstract static class Py_get_PyModuleObject_md_state extends CApiUnaryBuiltinNode { @Specialization - static Object get(PythonModule object) { - return object.getNativeModuleState(); + static Object get(PythonModule object, + @Bind Node inliningTarget) { + return object.getNativeModuleState() != null ? object.getNativeModuleState() : PythonContext.get(inliningTarget).getNativeNull(); } } @@ -743,7 +744,7 @@ static Object get(PString object, object.setNativeCharSequence(nativeSequence); /* * Create a native sequence storage to manage the lifetime of the native memory. - * + * * TODO it would be nicer if the native char sequence could manage its own memory */ writeAttribute.execute(inliningTarget, object, NATIVE_STORAGE, NativeByteSequenceStorage.create(ptr, byteLength, byteLength, true)); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiFunction.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiFunction.java index a95f510d7b..20ec2a44b1 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiFunction.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiFunction.java @@ -63,6 +63,9 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.CROSSINTERPDATAFUNC; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.ConstCharPtr; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.ConstCharPtrAsTruffleString; +import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.ConstPyInterpreterConfig; +import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.ConstPyLongObject; +import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.DIGIT_PTR; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Double; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.FILE_PTR; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.INITTAB; @@ -88,6 +91,7 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PY_COMPILER_FLAGS; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PY_COMPLEX; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PY_C_FUNCTION; +import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PY_GEN_OBJECT; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PY_GIL_STATE_STATE; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PY_HASH_T_PTR; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PY_IDENTIFIER; @@ -108,10 +112,14 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PrimitiveResult64; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyCodeAddressRange; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyCodeObject; +import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyCodeObjectTransfer; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyCode_WatchCallback; +import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyDict_WatchCallback; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyFrameObject; +import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyFrameObjectBorrowed; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyFrameObjectTransfer; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyFunctionObject; +import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyFunction_WatchCallback; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyGetSetDef; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyInterpreterState; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyLongObject; @@ -122,12 +130,15 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectBorrowed; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectConstPtr; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectPtr; +import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectRawPointer; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectTransfer; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PySendResult; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PySliceObject; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyThreadState; +import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyThreadStatePtr; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyTypeObject; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyTypeObjectTransfer; +import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyType_WatchCallback; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyVarObject; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Py_hash_t; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Py_ssize_t; @@ -165,6 +176,7 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor._PY_IDENTIFIER_PTR; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor._PyFrameEvalFunction; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor._PyInterpreterFrame; +import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.atexit_datacallbackfunc; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.destructor; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.freefunc; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.func_intvoidptr; @@ -172,7 +184,9 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.func_objint; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.func_objvoid; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.func_voidvoidptr; +import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.gcvisitobjects_t; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.vectorcallfunc; +import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.visitproc; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.xid_newobjectfunc; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins; @@ -248,6 +262,7 @@ public final class CApiFunction { @CApiBuiltin(name = "PyErr_Format", ret = PyObject, args = {PyObject, ConstCharPtrAsTruffleString, VARARGS}, call = CImpl) @CApiBuiltin(name = "PyErr_FormatV", ret = PyObject, args = {PyObject, ConstCharPtrAsTruffleString, VA_LIST}, call = CImpl) @CApiBuiltin(name = "PyErr_GetExcInfo", ret = Void, args = {PyObjectPtr, PyObjectPtr, PyObjectPtr}, call = CImpl) + @CApiBuiltin(name = "PyErr_GetHandledException", ret = PyObject, args = {}, call = CImpl) @CApiBuiltin(name = "PyErr_GivenExceptionMatches", ret = Int, args = {PyObject, PyObject}, call = CImpl) @CApiBuiltin(name = "PyErr_NoMemory", ret = PyObject, args = {}, call = CImpl) @CApiBuiltin(name = "PyErr_NormalizeException", ret = Void, args = {PyObjectPtr, PyObjectPtr, PyObjectPtr}, call = CImpl) @@ -255,10 +270,12 @@ public final class CApiFunction { @CApiBuiltin(name = "PyErr_Print", ret = Void, args = {}, call = CImpl) @CApiBuiltin(name = "PyErr_ResourceWarning", ret = Int, args = {PyObject, Py_ssize_t, ConstCharPtrAsTruffleString, VARARGS}, call = CImpl) @CApiBuiltin(name = "PyErr_Restore", ret = Void, args = {PyObject, PyObject, PyObject}, call = CImpl) + @CApiBuiltin(name = "PyErr_SetExcInfo", ret = Void, args = {PyObject, PyObject, PyObject}, call = CImpl) @CApiBuiltin(name = "PyErr_SetFromErrno", ret = PyObject, args = {PyObject}, call = CImpl) @CApiBuiltin(name = "PyErr_SetFromErrnoWithFilename", ret = PyObject, args = {PyObject, ConstCharPtrAsTruffleString}, call = CImpl) @CApiBuiltin(name = "PyErr_SetFromErrnoWithFilenameObject", ret = PyObject, args = {PyObject, PyObject}, call = CImpl) @CApiBuiltin(name = "PyErr_SetFromErrnoWithFilenameObjects", ret = PyObject, args = {PyObject, PyObject, PyObject}, call = CImpl) + @CApiBuiltin(name = "PyErr_SetHandledException", ret = Void, args = {PyObject}, call = CImpl) @CApiBuiltin(name = "PyErr_SetNone", ret = Void, args = {PyObject}, call = CImpl) @CApiBuiltin(name = "PyErr_SetObject", ret = Void, args = {PyObject, PyObject}, call = CImpl) @CApiBuiltin(name = "PyErr_SetString", ret = Void, args = {PyObject, ConstCharPtrAsTruffleString}, call = CImpl) @@ -740,11 +757,9 @@ public final class CApiFunction { @CApiBuiltin(name = "PyDescr_NewMethod", ret = PyObject, args = {PyTypeObject, PyMethodDef}, call = NotImplemented) @CApiBuiltin(name = "PyDescr_NewWrapper", ret = PyObject, args = {PyTypeObject, WRAPPERBASE, Pointer}, call = NotImplemented) @CApiBuiltin(name = "PyDict_MergeFromSeq2", ret = Int, args = {PyObject, PyObject, Int}, call = NotImplemented) - @CApiBuiltin(name = "PyErr_GetHandledException", ret = PyObject, args = {}, call = NotImplemented) @CApiBuiltin(name = "PyErr_ProgramText", ret = PyObject, args = {ConstCharPtrAsTruffleString, Int}, call = NotImplemented) @CApiBuiltin(name = "PyErr_ProgramTextObject", ret = PyObject, args = {PyObject, Int}, call = NotImplemented) @CApiBuiltin(name = "PyErr_RangedSyntaxLocationObject", ret = Void, args = {PyObject, Int, Int, Int, Int}, call = NotImplemented) - @CApiBuiltin(name = "PyErr_SetHandledException", ret = Void, args = {PyObject}, call = NotImplemented) @CApiBuiltin(name = "PyErr_SetImportError", ret = PyObject, args = {PyObject, PyObject, PyObject}, call = NotImplemented) @CApiBuiltin(name = "PyErr_SetImportErrorSubclass", ret = PyObject, args = {PyObject, PyObject, PyObject, PyObject}, call = NotImplemented) @CApiBuiltin(name = "PyErr_SetInterrupt", ret = Void, args = {}, call = NotImplemented) @@ -875,7 +890,6 @@ public final class CApiFunction { @CApiBuiltin(name = "PyRun_SimpleStringFlags", ret = Int, args = {ConstCharPtrAsTruffleString, PY_COMPILER_FLAGS}, call = NotImplemented) @CApiBuiltin(name = "PyRun_String", ret = PyObject, args = {ConstCharPtrAsTruffleString, Int, PyObject, PyObject}, call = NotImplemented) @CApiBuiltin(name = "PySequence_In", ret = Int, args = {PyObject, PyObject}, call = NotImplemented) - @CApiBuiltin(name = "PySignal_SetWakeupFd", ret = Int, args = {Int}, call = NotImplemented) @CApiBuiltin(name = "PySlice_GetIndices", ret = Int, args = {PyObject, Py_ssize_t, PY_SSIZE_T_PTR, PY_SSIZE_T_PTR, PY_SSIZE_T_PTR}, call = NotImplemented) @CApiBuiltin(name = "PySlice_GetIndicesEx", ret = Int, args = {PyObject, Py_ssize_t, PY_SSIZE_T_PTR, PY_SSIZE_T_PTR, PY_SSIZE_T_PTR, PY_SSIZE_T_PTR}, call = NotImplemented) @CApiBuiltin(name = "PyStatus_Error", ret = PYSTATUS, args = {ConstCharPtr}, call = CImpl) @@ -1043,14 +1057,11 @@ public final class CApiFunction { @CApiBuiltin(name = "_PyDict_DelItemIf", ret = Int, args = {PyObject, PyObject, func_objint}, call = NotImplemented) @CApiBuiltin(name = "_PyDict_DelItem_KnownHash", ret = Int, args = {PyObject, PyObject, Py_hash_t}, call = NotImplemented) @CApiBuiltin(name = "_PyDict_GetItemWithError", ret = PyObject, args = {PyObject, PyObject}, call = NotImplemented) - @CApiBuiltin(name = "_PyDict_HasOnlyStringKeys", ret = Int, args = {PyObject}, call = NotImplemented) @CApiBuiltin(name = "_PyDict_MergeEx", ret = Int, args = {PyObject, PyObject, Int}, call = NotImplemented) @CApiBuiltin(name = "_PyDict_SizeOf", ret = Py_ssize_t, args = {PYDICTOBJECT_PTR}, call = NotImplemented) @CApiBuiltin(name = "_PyErr_CheckSignals", ret = Int, args = {}, call = NotImplemented) - @CApiBuiltin(name = "_PyErr_GetHandledException", ret = PyObject, args = {PyThreadState}, call = NotImplemented) @CApiBuiltin(name = "_PyErr_GetTopmostException", ret = _PYERR_STACKITEM_PTR, args = {PyThreadState}, call = NotImplemented) @CApiBuiltin(name = "_PyErr_ProgramDecodedTextObject", ret = PyObject, args = {PyObject, Int, ConstCharPtr}, call = NotImplemented) - @CApiBuiltin(name = "_PyErr_SetHandledException", ret = Void, args = {PyThreadState, PyObject}, call = NotImplemented) @CApiBuiltin(name = "_PyErr_SetKeyError", ret = Void, args = {PyObject}, call = NotImplemented) @CApiBuiltin(name = "_PyEval_EvalFrameDefault", ret = PyObject, args = {PyThreadState, _PyInterpreterFrame, Int}, call = NotImplemented) @CApiBuiltin(name = "_PyEval_GetBuiltin", ret = PyObject, args = {PyObject}, call = NotImplemented) @@ -1241,6 +1252,65 @@ public final class CApiFunction { @CApiBuiltin(name = "_PyInterpreterState_HasFeature", ret = PrimitiveResult32, args = {PyInterpreterState, UNSIGNED_LONG}, call = CImpl) @CApiBuiltin(name = "_PyImport_AcquireLock", ret = Void, args = {PyInterpreterState}, call = NotImplemented) @CApiBuiltin(name = "_PyImport_ReleaseLock", ret = PrimitiveResult32, args = {PyInterpreterState}, call = NotImplemented) + @CApiBuiltin(name = "PyDict_AddWatcher", ret = PrimitiveResult32, args = {PyDict_WatchCallback}, call = NotImplemented) + @CApiBuiltin(name = "PyDict_ClearWatcher", ret = PrimitiveResult32, args = {PrimitiveResult32}, call = NotImplemented) + @CApiBuiltin(name = "PyDict_Unwatch", ret = PrimitiveResult32, args = {PrimitiveResult32, PyObjectRawPointer}, call = NotImplemented) + @CApiBuiltin(name = "PyDict_Watch", ret = PrimitiveResult32, args = {PrimitiveResult32, PyObjectRawPointer}, call = NotImplemented) + @CApiBuiltin(name = "PyErr_DisplayException", ret = Void, args = {PyObjectRawPointer}, call = NotImplemented) + @CApiBuiltin(name = "PyErr_GetRaisedException", ret = PyObjectRawPointer, args = {}, call = CImpl) + @CApiBuiltin(name = "PyErr_SetRaisedException", ret = Void, args = {PyObjectRawPointer}, call = CImpl) + @CApiBuiltin(name = "PyEval_SetProfileAllThreads", ret = Void, args = {PY_TRACEFUNC, PyObjectRawPointer}, call = NotImplemented) + @CApiBuiltin(name = "PyEval_SetTraceAllThreads", ret = Void, args = {PY_TRACEFUNC, PyObjectRawPointer}, call = NotImplemented) + @CApiBuiltin(name = "PyFrame_GetVar", ret = PyObjectRawPointer, args = {PyFrameObjectBorrowed, PyObjectRawPointer}, call = NotImplemented) + @CApiBuiltin(name = "PyFrame_GetVarString", ret = PyObjectRawPointer, args = {PyFrameObjectBorrowed, ConstCharPtr}, call = NotImplemented) + @CApiBuiltin(name = "PyFunction_AddWatcher", ret = PrimitiveResult32, args = {PyFunction_WatchCallback}, call = NotImplemented) + @CApiBuiltin(name = "PyFunction_ClearWatcher", ret = PrimitiveResult32, args = {PrimitiveResult32}, call = NotImplemented) + @CApiBuiltin(name = "PyGen_GetCode", ret = PyCodeObjectTransfer, args = {PY_GEN_OBJECT}, call = NotImplemented) + @CApiBuiltin(name = "PyObject_GetItemData", ret = Pointer, args = {PyObjectRawPointer}, call = CImpl) + @CApiBuiltin(name = "PyObject_GetTypeData", ret = Pointer, args = {PyObjectRawPointer, PyTypeObjectTransfer}, call = CImpl) + @CApiBuiltin(name = "PyType_AddWatcher", ret = PrimitiveResult32, args = {PyType_WatchCallback}, call = NotImplemented) + @CApiBuiltin(name = "PyType_ClearWatcher", ret = PrimitiveResult32, args = {PrimitiveResult32}, call = NotImplemented) + @CApiBuiltin(name = "PyType_FromMetaclass", ret = PyObjectRawPointer, args = {PyTypeObjectTransfer, PyObjectRawPointer, PY_TYPE_SPEC, PyObjectRawPointer}, call = CImpl) + @CApiBuiltin(name = "PyType_GetDict", ret = PyObjectRawPointer, args = {PyTypeObjectTransfer}, call = CImpl) + @CApiBuiltin(name = "PyType_GetTypeDataSize", ret = Py_ssize_t, args = {PyTypeObjectTransfer}, call = CImpl) + @CApiBuiltin(name = "PyType_Unwatch", ret = PrimitiveResult32, args = {PrimitiveResult32, PyObjectRawPointer}, call = NotImplemented) + @CApiBuiltin(name = "PyType_Watch", ret = PrimitiveResult32, args = {PrimitiveResult32, PyObjectRawPointer}, call = NotImplemented) + @CApiBuiltin(name = "PyUnstable_Exc_PrepReraiseStar", ret = PyObjectRawPointer, args = {PyObjectRawPointer, PyObjectRawPointer}, call = NotImplemented) + @CApiBuiltin(name = "PyUnstable_GC_VisitObjects", ret = Void, args = {gcvisitobjects_t, Pointer}, call = CImpl) + @CApiBuiltin(name = "PyUnstable_InterpreterFrame_GetCode", ret = PyObjectRawPointer, args = {_PyInterpreterFrame}, call = NotImplemented) + @CApiBuiltin(name = "PyUnstable_InterpreterFrame_GetLasti", ret = PrimitiveResult32, args = {_PyInterpreterFrame}, call = NotImplemented) + @CApiBuiltin(name = "PyUnstable_InterpreterFrame_GetLine", ret = PrimitiveResult32, args = {_PyInterpreterFrame}, call = NotImplemented) + @CApiBuiltin(name = "PyUnstable_Long_CompactValue", ret = Py_ssize_t, args = {ConstPyLongObject}, call = NotImplemented) + @CApiBuiltin(name = "PyUnstable_Long_IsCompact", ret = PrimitiveResult32, args = {ConstPyLongObject}, call = NotImplemented) + @CApiBuiltin(name = "PyUnstable_Object_GC_NewWithExtraData", ret = PyObjectRawPointer, args = {PyTypeObjectTransfer, SIZE_T}, call = CImpl) + @CApiBuiltin(name = "PyUnstable_PerfMapState_Fini", ret = Void, args = {}, call = NotImplemented) + @CApiBuiltin(name = "PyUnstable_PerfMapState_Init", ret = PrimitiveResult32, args = {}, call = NotImplemented) + @CApiBuiltin(name = "PyUnstable_Type_AssignVersionTag", ret = PrimitiveResult32, args = {PyTypeObjectTransfer}, call = NotImplemented) + @CApiBuiltin(name = "PyUnstable_WritePerfMapEntry", ret = PrimitiveResult32, args = {CONST_VOID_PTR, UNSIGNED_INT, ConstCharPtr}, call = NotImplemented) + @CApiBuiltin(name = "PyVectorcall_NARGS", ret = Py_ssize_t, args = {SIZE_T}, call = CImpl) + @CApiBuiltin(name = "Py_NewInterpreterFromConfig", ret = PYSTATUS, args = {PyThreadStatePtr, ConstPyInterpreterConfig}, call = NotImplemented) + @CApiBuiltin(name = "_PyErr_SetFromPyStatus", ret = PyObjectRawPointer, args = {PYSTATUS}, call = CImpl) + @CApiBuiltin(name = "_PyEval_MakePendingCalls", ret = PrimitiveResult32, args = {PyThreadState}, call = NotImplemented) + @CApiBuiltin(name = "_PyException_AddNote", ret = PrimitiveResult32, args = {PyObjectRawPointer, PyObjectRawPointer}, call = NotImplemented) + @CApiBuiltin(name = "_PyLong_FromDigits", ret = PyLongObject, args = {PrimitiveResult32, Py_ssize_t, DIGIT_PTR}, call = NotImplemented) + @CApiBuiltin(name = "_PyObject_ClearManagedDict", ret = Void, args = {PyObjectRawPointer}, call = CImpl) + @CApiBuiltin(name = "_PyObject_VisitManagedDict", ret = PrimitiveResult32, args = {PyObjectRawPointer, visitproc, Pointer}, call = CImpl) + @CApiBuiltin(name = "_PyTime_FromMicrosecondsClamp", ret = _PYTIME_T, args = {_PYTIME_T}, call = NotImplemented) + @CApiBuiltin(name = "_PyTraceMalloc_ClearTraces", ret = Void, args = {}, call = NotImplemented) + @CApiBuiltin(name = "_PyTraceMalloc_GetMemory", ret = SIZE_T, args = {}, call = NotImplemented) + @CApiBuiltin(name = "_PyTraceMalloc_GetObjectTraceback", ret = PyObjectRawPointer, args = {PyObjectRawPointer}, call = NotImplemented) + @CApiBuiltin(name = "_PyTraceMalloc_GetTracebackLimit", ret = PrimitiveResult32, args = {}, call = NotImplemented) + @CApiBuiltin(name = "_PyTraceMalloc_GetTracedMemory", ret = PyObjectRawPointer, args = {}, call = NotImplemented) + @CApiBuiltin(name = "_PyTraceMalloc_GetTraces", ret = PyObjectRawPointer, args = {}, call = NotImplemented) + @CApiBuiltin(name = "_PyTraceMalloc_Init", ret = PrimitiveResult32, args = {}, call = NotImplemented) + @CApiBuiltin(name = "_PyTraceMalloc_IsTracing", ret = PrimitiveResult32, args = {}, call = NotImplemented) + @CApiBuiltin(name = "_PyTraceMalloc_ResetPeak", ret = Void, args = {}, call = NotImplemented) + @CApiBuiltin(name = "_PyTraceMalloc_Start", ret = PrimitiveResult32, args = {PrimitiveResult32}, call = NotImplemented) + @CApiBuiltin(name = "_PyTraceMalloc_Stop", ret = Void, args = {}, call = NotImplemented) + @CApiBuiltin(name = "_Py_AtExit", ret = PrimitiveResult32, args = {PyInterpreterState, atexit_datacallbackfunc, Pointer}, call = NotImplemented) + @CApiBuiltin(name = "_Py_IsInterpreterFinalizing", ret = PrimitiveResult32, args = {PyInterpreterState}, call = NotImplemented) + @CApiBuiltin(name = "_Py_NewReferenceNoTotal", ret = Void, args = {PyObjectRawPointer}, call = CImpl) + // Windows only functions @CApiBuiltin(name = "PyUnicode_DecodeMBCS", ret = PyObject, args = {ConstCharPtr, Py_ssize_t, ConstCharPtr}, call = NotImplemented) @CApiBuiltin(name = "PyUnicode_DecodeMBCSStateful", ret = PyObject, args = {ConstCharPtr, Py_ssize_t, ConstCharPtr, PY_SSIZE_T_PTR}, call = NotImplemented) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/ArgDescriptor.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/ArgDescriptor.java index 2ad749fa0d..97acd8420d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/ArgDescriptor.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/ArgDescriptor.java @@ -200,6 +200,7 @@ public enum ArgDescriptor { INT64_T(ArgBehavior.Int64, "int64_t"), LONG_LONG(ArgBehavior.Int64, "long long"), LONG_PTR("long*"), + DIGIT_PTR(ArgBehavior.Pointer, "digit*"), PyASCIIObject(ArgBehavior.PyObject, "PyASCIIObject*"), PY_AUDITHOOKFUNCTION("Py_AuditHookFunction"), Py_buffer("Py_buffer"), @@ -230,8 +231,10 @@ public enum ArgDescriptor { PY_HASH_T_PTR(ArgBehavior.Pointer, "Py_hash_t*"), PY_IDENTIFIER("_Py_Identifier*"), PyInterpreterState(ArgBehavior.Pointer, "PyInterpreterState*"), + ConstPyInterpreterConfig(ArgBehavior.Pointer, "const PyInterpreterConfig*"), PY_LOCK_STATUS("PyLockStatus"), PyLongObject(ArgBehavior.PyObject, "PyLongObject*"), + ConstPyLongObject(ArgBehavior.PyObject, "const PyLongObject*"), PyLongObjectTransfer(ArgBehavior.PyObject, "PyLongObject*", true), PyMemberDef(ArgBehavior.Pointer, "PyMemberDef*"), PyModuleObject(ArgBehavior.PyObject, "PyModuleObject*"), @@ -254,6 +257,7 @@ public enum ArgDescriptor { PY_SSIZE_T_PTR(ArgBehavior.Pointer, "Py_ssize_t*"), PY_STRUCT_SEQUENCE_DESC("PyStructSequence_Desc*"), PyThreadState(ArgBehavior.Pointer, "PyThreadState*"), + PyThreadStatePtr(ArgBehavior.Pointer, "PyThreadState**"), PY_THREAD_TYPE_LOCK(ArgBehavior.Int64, "PyThread_type_lock"), PY_THREAD_TYPE_LOCK_PTR(ArgBehavior.Pointer, "PyThread_type_lock*"), PyTryBlock("PyTryBlock*"), @@ -285,6 +289,10 @@ public enum ArgDescriptor { PYUNICODE_KIND("enum PyUnicode_Kind"), PYWEAKREFERENCE_PTR(ArgBehavior.PyObject, "PyWeakReference*"), PYWIDESTRINGLIST_PTR("PyWideStringList*"), + PyDict_WatchCallback(ArgBehavior.Pointer, "PyDict_WatchCallback"), + PyFunction_WatchCallback(ArgBehavior.Pointer, "PyFunction_WatchCallback"), + PyType_WatchCallback(ArgBehavior.Pointer, "PyType_WatchCallback"), + gcvisitobjects_t(ArgBehavior.Pointer, "gcvisitobjects_t"), SIZE_T(ArgBehavior.Int64, "size_t"), SIZE_T_PTR("size_t*"), STAT_PTR("struct stat*"), @@ -318,6 +326,7 @@ public enum ArgDescriptor { getattrofunc(ArgBehavior.Pointer, "getattrofunc"), setattrofunc(ArgBehavior.Pointer, "setattrofunc"), traverseproc(ArgBehavior.Pointer, "traverseproc"), + visitproc(ArgBehavior.Pointer, "visitproc"), inquiry(ArgBehavior.Pointer, "inquiry"), richcmpfunc(ArgBehavior.Pointer, "richcmpfunc"), getiterfunc(ArgBehavior.Pointer, "getiterfunc"), @@ -349,6 +358,7 @@ public enum ArgDescriptor { func_objvoid("PyObject*(*)(void)"), func_objcharsizevoidptr("PyObject*(*)(const char*, Py_ssize_t, void*)"), xid_newobjectfunc(ArgBehavior.Pointer, "xid_newobjectfunc"), + atexit_datacallbackfunc(ArgBehavior.Pointer, "atexit_datacallbackfunc"), IterResult(ArgBehavior.PyObject, "void*", CheckIterNextResultNodeGen::create, CheckIterNextResultNodeGen.getUncached(), true), InquiryResult(ArgBehavior.Int32, "int", CheckInquiryResultNodeGen::create, CheckInquiryResultNodeGen.getUncached()), diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/structs/CStructAccess.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/structs/CStructAccess.java index d41b1d6d15..19cd39b617 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/structs/CStructAccess.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/structs/CStructAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, 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 @@ -354,6 +354,10 @@ static int readManaged(Object pointer, long offset, protected static boolean isCharSigned() { return CConstants.CHAR_MIN.longValue() < 0; } + + public static ReadByteNode getUncached() { + return CStructAccessFactory.ReadByteNodeGen.getUncached(); + } } @ImportStatic(PGuards.class) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/CapsuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/CapsuleBuiltins.java new file mode 100644 index 0000000000..bde5fb8490 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/CapsuleBuiltins.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2025, 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.tuple; + +import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; + +import java.util.Collections; +import java.util.List; + +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +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.capsule.PyCapsule; +import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; +import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +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.interop.InteropLibrary; +import com.oracle.truffle.api.strings.TruffleString; + +@CoreFunctions(extendClasses = PythonBuiltinClassType.Capsule) +public class CapsuleBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = CapsuleBuiltinsSlotsGen.SLOTS; + + @Override + protected List> getNodeFactories() { + return Collections.emptyList(); + } + + @Slot(value = SlotKind.tp_repr, isComplex = true) + @GenerateNodeFactory + abstract static class ReprNode extends PythonUnaryBuiltinNode { + + @Specialization + @TruffleBoundary + static Object repr(PyCapsule self) { + String name; + if (self.getNamePtr() == null || InteropLibrary.getUncached().isNull(self.getNamePtr())) { + name = "NULL"; + } else { + StringBuilder builder = new StringBuilder("\""); + int i = 0; + byte b; + while ((b = CStructAccess.ReadByteNode.getUncached().readArrayElement(self.getNamePtr(), i++)) != 0) { + builder.append((char) b); + } + builder.append('"'); + name = builder.toString(); + } + return TruffleString.fromJavaStringUncached(String.format("", name, PythonAbstractNativeObject.systemHashCodeAsHexString(self)), TS_ENCODING); + } + } +} diff --git a/graalpython/lib-graalpython/patches/metadata.toml b/graalpython/lib-graalpython/patches/metadata.toml index c88862ba29..2eacf2ae4d 100644 --- a/graalpython/lib-graalpython/patches/metadata.toml +++ b/graalpython/lib-graalpython/patches/metadata.toml @@ -729,6 +729,17 @@ version = '~= 0.11.0' patch = 'scikit-build-core.patch' license = 'Apache-2.0' +[[scikit-learn.rules]] +version = '> 1.7.0' +# 1.7.0 patch got upstreamed +install-priority = 2 + +[[scikit-learn.rules]] +version = '== 1.7.0' +patch = 'scikit-learn-1.7.0.patch' +license = 'BSD-3-Clause' +dist-type = 'sdist' + [[scikit-learn.rules]] version = '== 1.5.2' patch = 'scikit-learn-1.5.2.patch' diff --git a/graalpython/lib-graalpython/patches/scikit-learn-1.7.0.patch b/graalpython/lib-graalpython/patches/scikit-learn-1.7.0.patch new file mode 100644 index 0000000000..df82a5c509 --- /dev/null +++ b/graalpython/lib-graalpython/patches/scikit-learn-1.7.0.patch @@ -0,0 +1,14 @@ +diff --git a/sklearn/datasets/_svmlight_format_fast.pyx b/sklearn/datasets/_svmlight_format_fast.pyx +index 76a5954..0cc4424 100644 +--- a/sklearn/datasets/_svmlight_format_fast.pyx ++++ b/sklearn/datasets/_svmlight_format_fast.pyx +@@ -78,8 +78,7 @@ def _load_svmlight_file(f, dtype, bint multilabel, bint zero_based, + if n_features and features[0].startswith(qid_prefix): + _, value = features[0].split(COLON, 1) + if query_id: +- query.resize(len(query) + 1) +- query[len(query) - 1] = np.int64(value) ++ query = np.append(query, np.int64(value)) + features.pop(0) + n_features -= 1 + diff --git a/scripts/csignature.py b/scripts/csignature.py index 47402f5ed6..44aa1a8de0 100644 --- a/scripts/csignature.py +++ b/scripts/csignature.py @@ -79,7 +79,7 @@ ast = parse_file(f.name, use_cpp=True, cpp_args=cpp_args) lib_path = os.path.join(sysconfig.get_config_var('LIBDIR'), sysconfig.get_config_var('LDLIBRARY')) -out = subprocess.check_output(['nm', '--defined-only', '--format=just-symbols', lib_path], text=True) +out = subprocess.check_output(['nm', '--defined-only', '--dynamic', '--format=just-symbols', lib_path], text=True) exported_symbols = out.rstrip().splitlines()