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 5636f300be..3523aa93f3 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 @@ -46,8 +46,9 @@ try: raise TypeError -except: +except TypeError as e: TB = sys.exc_info()[2] + exception_with_traceback = e class TestExceptionobject(object): @@ -148,18 +149,80 @@ def raise_exception_without_cause(): return e +exception_with_cause = AssertionError() +exception_with_cause.__cause__ = NameError() +exception_with_context = AssertionError() +exception_with_context.__context__ = AttributeError() + class TestExceptionobjectFunctions(CPyExtTestCase): test_PyException_SetTraceback = CPyExtFunction( - lambda args: 0, + lambda args: args[1], + lambda: ( + (AssertionError(), TB), + (exception_with_traceback, None), + ), + code=''' + static PyObject* wrap_PyException_SetTraceback(PyObject* exc, PyObject* traceback) { + PyException_SetTraceback(exc, traceback); + traceback = PyException_GetTraceback(exc); + if (traceback == NULL) { + Py_RETURN_NONE; + } else { + return traceback; + } + } + ''', + callfunction='wrap_PyException_SetTraceback', + argspec='OO', + arguments=['PyObject* exc', 'PyObject* traceback'], + resultspec='O', + ) + + test_PyException_SetCause = CPyExtFunction( + lambda args: args[1], + lambda: ( + (AssertionError(), NameError()), + (exception_with_context, None), + ), + code=''' + static PyObject* wrap_PyException_SetCause(PyObject* exc, PyObject* cause) { + PyException_SetCause(exc, cause != Py_None ? cause : NULL); + cause = PyException_GetCause(exc); + if (cause == NULL) { + Py_RETURN_NONE; + } else { + return cause; + } + } + ''', + callfunction='wrap_PyException_SetCause', + argspec='OO', + arguments=['PyObject* exc', 'PyObject* cause'], + resultspec='O', + ) + + test_PyException_SetContext = CPyExtFunction( + lambda args: args[1], lambda: ( - ( - AssertionError(), TB - ), + (AssertionError(), NameError()), + (exception_with_cause, None), ), - resultspec="i", - argspec="OO", - arguments=["PyObject* exc", "PyObject* tb"], + code=''' + static PyObject* wrap_PyException_SetContext(PyObject* exc, PyObject* context) { + PyException_SetContext(exc, context != Py_None ? context : NULL); + context = PyException_GetContext(exc); + if (context == NULL) { + Py_RETURN_NONE; + } else { + return context; + } + } + ''', + callfunction='wrap_PyException_SetContext', + argspec='OO', + arguments=['PyObject* exc', 'PyObject* context'], + resultspec='O', ) 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 419ff0b44b..ea7bab3baf 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 @@ -60,8 +60,6 @@ import static com.oracle.graal.python.nodes.BuiltinNames.T_LAST_VALUE; import static com.oracle.graal.python.nodes.ErrorMessages.EXCEPTION_NOT_BASEEXCEPTION; import static com.oracle.graal.python.nodes.ErrorMessages.MUST_BE_MODULE_CLASS; -import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___CAUSE__; -import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___CONTEXT__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DOC__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___MODULE__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___TRACEBACK__; @@ -560,9 +558,9 @@ abstract static class PyException_SetCause extends CApiBinaryBuiltinNode { @Specialization Object setCause(Object exc, Object cause, @Bind("this") Node inliningTarget, - @Cached PyObjectSetAttr setAttrNode) { - setAttrNode.execute(inliningTarget, exc, T___CAUSE__, cause); - return PNone.NONE; + @Cached ExceptionNodes.SetCauseNode setCauseNode) { + setCauseNode.execute(inliningTarget, exc, cause != PNone.NO_VALUE ? cause : PNone.NONE); + return PNone.NO_VALUE; } } @@ -571,8 +569,8 @@ abstract static class PyException_GetCause extends CApiUnaryBuiltinNode { @Specialization Object getCause(Object exc, @Bind("this") Node inliningTarget, - @Cached PyObjectGetAttr getAttrNode) { - return noneToNativeNull(inliningTarget, getAttrNode.execute(inliningTarget, exc, T___CAUSE__)); + @Cached ExceptionNodes.GetCauseNode getCauseNode) { + return noneToNativeNull(inliningTarget, getCauseNode.execute(inliningTarget, exc)); } } @@ -581,8 +579,8 @@ abstract static class PyException_GetContext extends CApiUnaryBuiltinNode { @Specialization Object setCause(Object exc, @Bind("this") Node inliningTarget, - @Cached PyObjectGetAttr getAttrNode) { - return noneToNativeNull(inliningTarget, getAttrNode.execute(inliningTarget, exc, T___CONTEXT__)); + @Cached ExceptionNodes.GetContextNode getContextNode) { + return noneToNativeNull(inliningTarget, getContextNode.execute(inliningTarget, exc)); } } @@ -591,9 +589,9 @@ abstract static class PyException_SetContext extends CApiBinaryBuiltinNode { @Specialization Object setContext(Object exc, Object context, @Bind("this") Node inliningTarget, - @Cached PyObjectSetAttr setAttrNode) { - setAttrNode.execute(inliningTarget, exc, T___CONTEXT__, context); - return PNone.NONE; + @Cached ExceptionNodes.SetContextNode setContextNode) { + setContextNode.execute(inliningTarget, exc, context != PNone.NO_VALUE ? context : PNone.NONE); + return PNone.NO_VALUE; } } @@ -603,8 +601,8 @@ abstract static class PyException_GetTraceback extends CApiUnaryBuiltinNode { @Specialization Object getTraceback(Object exc, @Bind("this") Node inliningTarget, - @Cached PyObjectGetAttr getAttrNode) { - return noneToNativeNull(inliningTarget, getAttrNode.execute(inliningTarget, exc, T___TRACEBACK__)); + @Cached ExceptionNodes.GetTracebackNode getTracebackNode) { + return noneToNativeNull(inliningTarget, getTracebackNode.execute(inliningTarget, exc)); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java index c675d12fd6..2df45bec29 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java @@ -40,6 +40,7 @@ */ package com.oracle.graal.python.builtins.modules.io; +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.AttributeError; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.IOUnsupportedOperation; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PTextIOWrapper; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.RuntimeError; @@ -94,6 +95,7 @@ import static com.oracle.graal.python.builtins.modules.io.TextIOWrapperNodes.setNewline; import static com.oracle.graal.python.builtins.modules.io.TextIOWrapperNodes.validateNewline; import static com.oracle.graal.python.nodes.ErrorMessages.A_STRICTLY_POSITIVE_INTEGER_IS_REQUIRED; +import static com.oracle.graal.python.nodes.ErrorMessages.CANNOT_DELETE; import static com.oracle.graal.python.nodes.ErrorMessages.CAN_T_DO_NONZERO_CUR_RELATIVE_SEEKS; import static com.oracle.graal.python.nodes.ErrorMessages.CAN_T_DO_NONZERO_END_RELATIVE_SEEKS; import static com.oracle.graal.python.nodes.ErrorMessages.CAN_T_RECONSTRUCT_LOGICAL_FILE_POSITION; @@ -136,6 +138,7 @@ import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.common.SequenceNodes; +import com.oracle.graal.python.builtins.objects.getsetdescriptor.DescriptorDeleteMarker; import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.str.StringNodes.StringReplaceNode; import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode; @@ -1157,7 +1160,7 @@ static TruffleString doit(PTextIO self) { } } - @Builtin(name = J__CHUNK_SIZE, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true) + @Builtin(name = J__CHUNK_SIZE, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true, allowsDelete = true) @GenerateNodeFactory abstract static class ChunkSizeNode extends PythonBuiltinNode { @@ -1166,7 +1169,7 @@ static Object none(PTextIO self, @SuppressWarnings("unused") PNone none) { return self.getChunkSize(); } - @Specialization(guards = {"self.isOK()", "!self.isDetached()", "!isNoValue(arg)"}) + @Specialization(guards = {"self.isOK()", "!self.isDetached()", "!isNoValue(arg)", "!isDeleteMarker(arg)"}) static Object chunkSize(VirtualFrame frame, PTextIO self, Object arg, @Bind("this") Node inliningTarget, @Cached PyNumberAsSizeNode asSizeNode, @@ -1179,6 +1182,12 @@ static Object chunkSize(VirtualFrame frame, PTextIO self, Object arg, return 0; } + @Specialization(guards = {"self.isOK()", "!self.isDetached()"}) + static Object noDelete(@SuppressWarnings("unused") PTextIO self, @SuppressWarnings("unused") DescriptorDeleteMarker marker, + @Shared @Cached PRaiseNode raiseNode) { + throw raiseNode.raise(AttributeError, CANNOT_DELETE); + } + @Specialization(guards = "!self.isOK()") static Object initError(@SuppressWarnings("unused") PTextIO self, @SuppressWarnings("unused") Object arg, @Shared @Cached PRaiseNode raiseNode) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/DescriptorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/DescriptorBuiltins.java index 8f04885663..09f580f2da 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/DescriptorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/DescriptorBuiltins.java @@ -40,12 +40,10 @@ */ package com.oracle.graal.python.builtins.objects.getsetdescriptor; -import static com.oracle.graal.python.builtins.modules.io.IONodes.T__CHUNK_SIZE; import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___NAME__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___QUALNAME__; import static com.oracle.graal.python.runtime.exception.PythonErrorType.AttributeError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; -import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import java.util.List; @@ -226,11 +224,6 @@ Object doGetSetDescriptor(VirtualFrame frame, GetSetDescriptor descr, Object obj } else { branchProfile.enter(inliningTarget); if (descr.getSet() != null) { - if (descr.getName().equalsUncached(T__CHUNK_SIZE, TS_ENCODING)) { - // This is a special error message case. see - // Modules/_io/textio.c:textiowrapper_chunk_size_set - throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.CANNOT_DELETE); - } throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANNOT_DELETE_ATTRIBUTE, getNameNode.execute(inliningTarget, descr.getType()), descr.getName()); } else { throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.ATTRIBUTE_S_OF_P_OBJECTS_IS_NOT_WRITABLE, descr.getName(), obj); diff --git a/graalpython/lib-graalpython/patches/jiter/jiter.patch b/graalpython/lib-graalpython/patches/jiter/jiter.patch new file mode 100644 index 0000000000..51f7398e2b --- /dev/null +++ b/graalpython/lib-graalpython/patches/jiter/jiter.patch @@ -0,0 +1,22 @@ +diff --git a/crates/jiter/src/py_string_cache.rs b/crates/jiter/src/py_string_cache.rs +index 96dcf66..21e6979 100644 +--- a/crates/jiter/src/py_string_cache.rs ++++ b/crates/jiter/src/py_string_cache.rs +@@ -200,7 +200,7 @@ pub fn pystring_fast_new<'py>(py: Python<'py>, s: &str, ascii_only: bool) -> Bou + + /// Faster creation of PyString from an ASCII string, inspired by + /// https://github.com/ijl/orjson/blob/3.10.0/src/str/create.rs#L41 +-#[cfg(not(PyPy))] ++#[cfg(all(not(PyPy), not(GraalPy)))] + unsafe fn pystring_ascii_new<'py>(py: Python<'py>, s: &str) -> Bound<'py, PyString> { + let ptr = pyo3::ffi::PyUnicode_New(s.len() as isize, 127); + // see https://github.com/pydantic/jiter/pull/72#discussion_r1545485907 +@@ -212,7 +212,7 @@ unsafe fn pystring_ascii_new<'py>(py: Python<'py>, s: &str) -> Bound<'py, PyStri + } + + // ffi::PyUnicode_DATA seems to be broken for pypy, hence this, marked as unsafe to avoid warnings +-#[cfg(PyPy)] ++#[cfg(any(PyPy, GraalPy))] + unsafe fn pystring_ascii_new<'py>(py: Python<'py>, s: &str) -> Bound<'py, PyString> { + PyString::new_bound(py, s) + } diff --git a/graalpython/lib-graalpython/patches/jiter/metadata.toml b/graalpython/lib-graalpython/patches/jiter/metadata.toml new file mode 100644 index 0000000000..b38abeb207 --- /dev/null +++ b/graalpython/lib-graalpython/patches/jiter/metadata.toml @@ -0,0 +1,3 @@ +[[rules]] +patch = 'jiter.patch' +license = 'MIT' diff --git a/graalpython/lib-graalpython/patches/mlx/metadata.toml b/graalpython/lib-graalpython/patches/mlx/metadata.toml index e8416c006f..6ae9e9b7b0 100644 --- a/graalpython/lib-graalpython/patches/mlx/metadata.toml +++ b/graalpython/lib-graalpython/patches/mlx/metadata.toml @@ -1,3 +1,7 @@ +[[rules]] +patch = 'mlx.patch' +license = 'MIT' + [[add-sources]] version = '0.16.3' url = 'https://github.com/ml-explore/mlx/archive/refs/tags/v0.16.3.tar.gz' diff --git a/graalpython/lib-graalpython/patches/mlx/mlx.patch b/graalpython/lib-graalpython/patches/mlx/mlx.patch new file mode 100644 index 0000000000..d74d6e7aec --- /dev/null +++ b/graalpython/lib-graalpython/patches/mlx/mlx.patch @@ -0,0 +1,12 @@ +diff --git a/setup.py b/setup.py +index 7bd1be4..390c84c 100644 +--- a/setup.py ++++ b/setup.py +@@ -13,6 +13,7 @@ from setuptools.command.build_ext import build_ext + + + def get_version(version): ++ return version + if "PYPI_RELEASE" not in os.environ: + today = datetime.date.today() + version = f"{version}.dev{today.year}{today.month:02d}{today.day:02d}" diff --git a/graalpython/lib-graalpython/patches/safetensors/metadata.toml b/graalpython/lib-graalpython/patches/safetensors/metadata.toml index ba3fbf8bcf..eae4709bfb 100644 --- a/graalpython/lib-graalpython/patches/safetensors/metadata.toml +++ b/graalpython/lib-graalpython/patches/safetensors/metadata.toml @@ -1,4 +1,6 @@ [[rules]] +# Recent versions should use pyo3 with upstream support for graalpy +install-priority = 0 version = '== 0.3.3' patch = 'safetensors-0.3.3.patch' license = 'Apache-2.0' diff --git a/graalpython/lib-graalpython/patches/tokenizers/metadata.toml b/graalpython/lib-graalpython/patches/tokenizers/metadata.toml index d4cc4d2c86..3f0aa01c04 100644 --- a/graalpython/lib-graalpython/patches/tokenizers/metadata.toml +++ b/graalpython/lib-graalpython/patches/tokenizers/metadata.toml @@ -1,3 +1,8 @@ +[[rules]] +version = '>= 0.19' +patch = 'tokenizers-0.19-plus.patch' +license = 'Apache-2.0' + [[rules]] version = '== 0.13.3' patch = 'tokenizers-0.13.3.patch' diff --git a/graalpython/lib-graalpython/patches/tokenizers/tokenizers-0.19-plus.patch b/graalpython/lib-graalpython/patches/tokenizers/tokenizers-0.19-plus.patch new file mode 100644 index 0000000000..c1b9923c82 --- /dev/null +++ b/graalpython/lib-graalpython/patches/tokenizers/tokenizers-0.19-plus.patch @@ -0,0 +1,28 @@ +diff --git a/bindings/python/src/lib.rs b/bindings/python/src/lib.rs +index 3f1e713..6dd3c72 100644 +--- a/bindings/python/src/lib.rs ++++ b/bindings/python/src/lib.rs +@@ -50,14 +50,16 @@ extern "C" fn child_after_fork() { + pub fn tokenizers(m: &Bound<'_, PyModule>) -> PyResult<()> { + let _ = env_logger::try_init_from_env("TOKENIZERS_LOG"); + ++ // GraalPy change: Disable the atfork warning. This triggers a ton of false positives when ++ // jline calls stty and we don't support fork anyway + // Register the fork callback +- #[cfg(target_family = "unix")] +- unsafe { +- if !REGISTERED_FORK_CALLBACK { +- libc::pthread_atfork(None, None, Some(child_after_fork)); +- REGISTERED_FORK_CALLBACK = true; +- } +- } ++ // #[cfg(target_family = "unix")] ++ // unsafe { ++ // if !REGISTERED_FORK_CALLBACK { ++ // libc::pthread_atfork(None, None, Some(child_after_fork)); ++ // REGISTERED_FORK_CALLBACK = true; ++ // } ++ // } + + m.add_class::()?; + m.add_class::()?;