Skip to content

Commit c2cd948

Browse files
committed
Add GraalPyCFunction_GetDoc/SetDoc public API
1 parent 41cc531 commit c2cd948

File tree

4 files changed

+50
-3
lines changed

4 files changed

+50
-3
lines changed

graalpython/com.oracle.graal.python.cext/include/methodobject.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2018, 2023, Oracle and/or its affiliates.
1+
/* Copyright (c) 2018, 2024, Oracle and/or its affiliates.
22
* Copyright (C) 1996-2020 Python Software Foundation
33
*
44
* Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
@@ -125,6 +125,10 @@ PyAPI_FUNC(PyObject *) PyCMethod_New(PyMethodDef *, PyObject *,
125125
#define METH_METHOD 0x0200
126126
#endif
127127

128+
// GraalPy public API functions
129+
PyAPI_FUNC(const char*) GraalPyCFunction_GetDoc(PyObject *func);
130+
PyAPI_FUNC(void) GraalPyCFunction_SetDoc(PyObject *func, const char *doc);
131+
128132

129133
#ifndef Py_LIMITED_API
130134
# define Py_CPYTHON_METHODOBJECT_H

graalpython/com.oracle.graal.python.cext/src/methodobject.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,17 @@ void _PyCFunction_SetModule(PyObject *func, PyObject *mod) {
102102
void _PyCFunction_SetMethodDef(PyObject *func, PyMethodDef *def) {
103103
set_PyCFunctionObject_m_ml(func, def);
104104
}
105+
106+
// GraalPy additions
107+
const char *
108+
GraalPyCFunction_GetDoc(PyObject *func) {
109+
return PyCFunctionObject_m_ml(func)->ml_doc;
110+
}
111+
112+
void
113+
GraalPyCFunction_SetDoc(PyObject *func, const char *doc) {
114+
PyCFunctionObject_m_ml(func)->ml_doc = doc;
115+
if (points_to_py_handle_space(func)) {
116+
GraalPyTruffleCFunction_SetDoc(func, doc);
117+
}
118+
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextFuncBuiltins.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -41,16 +41,27 @@
4141
package com.oracle.graal.python.builtins.modules.cext;
4242

4343
import static com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiCallPath.Direct;
44+
import static com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiCallPath.Ignored;
45+
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.ConstCharPtrAsTruffleString;
4446
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObject;
4547
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectTransfer;
48+
import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DOC__;
4649

4750
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
51+
import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBinaryBuiltinNode;
4852
import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin;
4953
import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiUnaryBuiltinNode;
54+
import com.oracle.graal.python.builtins.objects.PNone;
55+
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor;
56+
import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
57+
import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod;
5058
import com.oracle.graal.python.builtins.objects.method.PDecoratedMethod;
5159
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
60+
import com.oracle.truffle.api.CompilerDirectives;
61+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
5262
import com.oracle.truffle.api.dsl.Cached;
5363
import com.oracle.truffle.api.dsl.Specialization;
64+
import com.oracle.truffle.api.strings.TruffleString;
5465

5566
public final class PythonCextFuncBuiltins {
5667

@@ -73,4 +84,22 @@ static Object staticmethod(Object callable,
7384
return factory.createClassmethodFromCallableObj(callable);
7485
}
7586
}
87+
88+
@CApiBuiltin(ret = ArgDescriptor.Void, args = {PyObject, ConstCharPtrAsTruffleString}, call = Ignored)
89+
abstract static class PyTruffleCFunction_SetDoc extends CApiBinaryBuiltinNode {
90+
@Specialization
91+
@TruffleBoundary
92+
static Object set(Object functionObj, TruffleString doc) {
93+
PBuiltinFunction function;
94+
if (functionObj instanceof PBuiltinFunction builtinFunction) {
95+
function = builtinFunction;
96+
} else if (functionObj instanceof PBuiltinMethod builtinMethod) {
97+
function = builtinMethod.getBuiltinFunction();
98+
} else {
99+
throw CompilerDirectives.shouldNotReachHere("Unexpected object passed to GraalPyCFunction_SetDoc");
100+
}
101+
function.setAttribute(T___DOC__, doc != null ? doc : PNone.NONE);
102+
return PNone.NO_VALUE;
103+
}
104+
}
76105
}

graalpython/lib-graalpython/modules/autopatch_capi.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ def consume_whitespace_forward(idx):
156156
r'\W(ob_refcnt)\W': (replace_field_access, 'Py_REFCNT(%receiver)'),
157157
r'\W(ob_item)\W': (replace_field_access, 'PySequence_Fast_ITEMS((PyObject*)%receiver)'),
158158
r'^\s*()(std::)?free\((const_cast<char \*>)?\(?\w+->m_ml->ml_doc\)?\);': (simple_replace, '//'),
159-
r'\W(m_ml\s*->\s*ml_doc)\W': (replace_field_access, 'PyObject_GetDoc((PyObject*)(%receiver))', 'PyObject_SetDoc((PyObject*)(%receiver), %value)'),
159+
r'\W(m_ml\s*->\s*ml_doc)\W': (replace_field_access, 'GraalPyCFunction_GetDoc((PyObject*)(%receiver))', 'GraalPyCFunction_SetDoc((PyObject*)(%receiver), %value)'),
160160
# Py_CLEAR/Py_VISIT on a function's module is skipped for us, Java GC takes care of it
161161
r'(Py_(?:CLEAR|VISIT)\((?:(?:\(?\([a-zA-Z0-9_]|[a-zA-Z0-9_])(?:[a-zA-Z0-9_]|\)|\*\)|->)*)->m_module\);)': (simple_replace, ''),
162162
r'\W(m_ml)\W': (replace_field_access, '_PyCFunction_GetMethodDef((PyObject*)(%receiver))', '_PyCFunction_SetMethodDef((PyObject*)(%receiver), %value)'),

0 commit comments

Comments
 (0)