Skip to content

Commit 0339649

Browse files
committed
[GR-16816] Improve pandas support
PullRequest: graalpython/577
2 parents 5499757 + 35414db commit 0339649

File tree

13 files changed

+209
-75
lines changed

13 files changed

+209
-75
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,20 @@
33
This changelog summarizes major changes between GraalVM versions of the Python
44
language runtime. The main focus is on user-observable behavior of the engine.
55

6+
## Version 19.2.0
7+
8+
* Implement PyStructSequence_* C API functions
9+
* Implement `_functools.partial` as a class instead of a function
10+
* Implement `type.__base__`
11+
* Implement reading C API type attributes `nb_inplace_add`, `nb_remainder`, `nb_subtract`, and `nb_floor_divide` for builtin types
12+
* Implement C API functions `_PyObject_CallFunction_SizeT`, `PyEval_InitThreads`, and `PyEval_ThreadsInitialized`
13+
* Implement writing to a function's `__dict__` field
14+
* Implement the C API thread state fields `overflowed` and `recursion_depth`
15+
* Fix printing of errors in the REPL
16+
* Fix printing full paths in traceback
17+
* Support the C API varargs functions with arbitrary numbers of arguments instead of imposing an upper limit
18+
* Improve performance of attribute reads and reading closure variables
19+
620
## Version 19.1.0
721

822
* Add `java.add_to_classpath` API to dynamically extend the host class path

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

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,8 @@ PyAPI_FUNC(int) Py_MakePendingCalls(void);
9494
PyAPI_FUNC(void) Py_SetRecursionLimit(int);
9595
PyAPI_FUNC(int) Py_GetRecursionLimit(void);
9696

97-
#define Py_EnterRecursiveCall(where) \
98-
(_Py_MakeRecCheck(PyThreadState_GET()->recursion_depth) && \
99-
_Py_CheckRecursiveCall(where))
100-
#define Py_LeaveRecursiveCall() \
101-
do{ if(_Py_MakeEndRecCheck(PyThreadState_GET()->recursion_depth)) \
102-
PyThreadState_GET()->overflowed = 0; \
103-
} while(0)
97+
#define Py_EnterRecursiveCall(where) 0
98+
#define Py_LeaveRecursiveCall()
10499
PyAPI_FUNC(int) _Py_CheckRecursiveCall(const char *where);
105100

106101
/* Due to the macros in which it's used, _Py_CheckRecursionLimit is in
@@ -130,13 +125,9 @@ PyAPI_DATA(int) _Py_CheckRecursionLimit;
130125
#define _Py_MakeEndRecCheck(x) \
131126
(--(x) < _Py_RecursionLimitLowerWaterMark(_Py_CheckRecursionLimit))
132127

133-
#define Py_ALLOW_RECURSION \
134-
do { unsigned char _old = PyThreadState_GET()->recursion_critical;\
135-
PyThreadState_GET()->recursion_critical = 1;
128+
#define Py_ALLOW_RECURSION
136129

137-
#define Py_END_ALLOW_RECURSION \
138-
PyThreadState_GET()->recursion_critical = _old; \
139-
} while(0);
130+
#define Py_END_ALLOW_RECURSION
140131

141132
PyAPI_FUNC(const char *) PyEval_GetFuncName(PyObject *);
142133
PyAPI_FUNC(const char *) PyEval_GetFuncDesc(PyObject *);

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ PyObject* PyEval_CallObjectWithKeywords(PyObject *func, PyObject *args, PyObject
5050
return PyObject_Call(func, args, kwargs);
5151
}
5252

53+
void PyEval_InitThreads() {
54+
// Nothing to do
55+
}
56+
57+
int PyEval_ThreadsInitialized() {
58+
return 1;
59+
}
60+
5361
PyThreadState* PyEval_SaveThread() {
5462
return NULL;
5563
}

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,19 @@ PyObject* PyObject_CallFunction(PyObject* callable, const char* fmt, ...) {
238238
return PyObject_CallObject(callable, args);
239239
}
240240

241+
PyObject* _PyObject_CallFunction_SizeT(PyObject* callable, const char* fmt, ...) {
242+
PyObject* args;
243+
CALL_WITH_VARARGS(args, Py_BuildValue, 2, fmt);
244+
if (strlen(fmt) < 2) {
245+
PyObject* singleArg = args;
246+
args = PyTuple_New(strlen(fmt));
247+
if (strlen(fmt) == 1) {
248+
PyTuple_SetItem(args, 0, singleArg);
249+
}
250+
}
251+
return PyObject_CallObject(callable, args);
252+
}
253+
241254
PyObject* PyObject_CallFunctionObjArgs(PyObject *callable, ...) {
242255
// the arguments are given as a variable list followed by NULL
243256
PyObject* args = PyTuple_New(polyglot_get_arg_count() - 2);

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,8 @@ int PyType_Ready(PyTypeObject* cls) {
440440
ADD_SLOT("__sub__", numbers->nb_subtract, -2);
441441
ADD_SLOT_CONV("__rsub__", wrap_reverse_binop, numbers->nb_subtract, -2);
442442
ADD_SLOT("__mul__", numbers->nb_multiply, -2);
443-
ADD_SLOT("__rem__", numbers->nb_remainder, -2);
443+
ADD_SLOT("__mod__", numbers->nb_remainder, -2);
444+
ADD_SLOT_CONV("__rmod__", wrap_reverse_binop, numbers->nb_remainder, -2);
444445
ADD_SLOT("__divmod__", numbers->nb_divmod, -2);
445446
ADD_SLOT_CONV("__pow__", wrap_pow, numbers->nb_power, -3);
446447
ADD_SLOT("__neg__", numbers->nb_negative, -1);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -408,30 +408,32 @@ protected SourceSection findSourceLocation(PythonContext context, Object value)
408408

409409
@Override
410410
protected String toString(PythonContext context, Object value) {
411-
final PythonModule builtins = context.getBuiltins();
412-
if (builtins != null) {
413-
// may be null during initialization
414-
Object reprAttribute = builtins.getAttribute(BuiltinNames.REPR);
415-
if (reprAttribute instanceof PBuiltinMethod) {
416-
// may be false if e.g. someone accessed our builtins reflectively
417-
Object reprFunction = ((PBuiltinMethod) reprAttribute).getFunction();
418-
if (reprFunction instanceof PBuiltinFunction) {
419-
// may be false if our builtins were tampered with
420-
Object[] userArgs = PArguments.create(2);
421-
PArguments.setArgument(userArgs, 0, PNone.NONE);
422-
PArguments.setArgument(userArgs, 1, value);
423-
try {
424-
Object result = InvokeNode.invokeUncached((PBuiltinFunction) reprFunction, userArgs);
425-
if (result instanceof String) {
426-
return (String) result;
427-
} else if (result instanceof PString) {
428-
return ((PString) result).getValue();
429-
} else {
430-
// This is illegal for a repr implementation, we ignore the result.
431-
// At this point it's probably difficult to report this properly.
411+
if (PythonOptions.getFlag(context, PythonOptions.UseReprForPrintString)) {
412+
final PythonModule builtins = context.getBuiltins();
413+
if (builtins != null) {
414+
// may be null during initialization
415+
Object reprAttribute = builtins.getAttribute(BuiltinNames.REPR);
416+
if (reprAttribute instanceof PBuiltinMethod) {
417+
// may be false if e.g. someone accessed our builtins reflectively
418+
Object reprFunction = ((PBuiltinMethod) reprAttribute).getFunction();
419+
if (reprFunction instanceof PBuiltinFunction) {
420+
// may be false if our builtins were tampered with
421+
Object[] userArgs = PArguments.create(2);
422+
PArguments.setArgument(userArgs, 0, PNone.NONE);
423+
PArguments.setArgument(userArgs, 1, value);
424+
try {
425+
Object result = InvokeNode.invokeUncached((PBuiltinFunction) reprFunction, userArgs);
426+
if (result instanceof String) {
427+
return (String) result;
428+
} else if (result instanceof PString) {
429+
return ((PString) result).getValue();
430+
} else {
431+
// This is illegal for a repr implementation, we ignore the result.
432+
// At this point it's probably difficult to report this properly.
433+
}
434+
} catch (PException e) {
435+
// Fall through to default
432436
}
433-
} catch (PException e) {
434-
// Fall through to default
435437
}
436438
}
437439
}
@@ -440,8 +442,12 @@ protected String toString(PythonContext context, Object value) {
440442
// return a String
441443
if (value instanceof PythonAbstractObject) {
442444
return ((PythonAbstractObject) value).toString();
445+
} else if (value instanceof String) {
446+
return (String) value;
447+
} else if (value instanceof Number) {
448+
return ((Number) value).toString();
443449
} else {
444-
return "illegal object";
450+
return "not a Python object";
445451
}
446452
}
447453

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/NativeMemberNames.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,15 @@ public final class NativeMemberNames {
105105
public static final String BUF_DELEGATE = "buf_delegate";
106106
public static final String BUF_READONLY = "readonly";
107107
public static final String NB_ADD = "nb_add";
108+
public static final String NB_SUBTRACT = "nb_subtract";
109+
public static final String NB_REMAINDER = "nb_remainder";
108110
public static final String NB_AND = "nb_and";
109111
public static final String NB_INDEX = "nb_index";
110112
public static final String NB_POW = "nb_power";
111113
public static final String NB_TRUE_DIVIDE = "nb_true_divide";
114+
public static final String NB_FLOOR_DIVIDE = "nb_floor_divide";
112115
public static final String NB_MULTIPLY = "nb_multiply";
116+
public static final String NB_INPLACE_ADD = "nb_inplace_add";
113117
public static final String NB_INPLACE_MULTIPLY = "nb_inplace_multiply";
114118
public static final String OB_FVAL = "ob_fval";
115119
public static final String START = "start";

0 commit comments

Comments
 (0)