From 9b7e24a2cb37fb52af13219f625cd719e364a346 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Mon, 7 Mar 2022 18:30:28 -0800 Subject: [PATCH] plpython: Code cleanup related to removal of Python 2 support. Since 19252e8ec93 we reject Python 2 during build configuration. Now that the dust on the buildfarm has settled, remove Python 2 specific code, including the "Python 2/3 porting layer". The code to detect conflicts between plpython using Python 2 and 3 is not removed, in case somebody creates an out-of-tree version adding back support for Python 2. Reviewed-By: Peter Eisentraut Reviewed-By: Tom Lane Discussion: https://postgr.es/m/20211031184548.g4sxfe47n2kyi55r@alap3.anarazel.de --- contrib/hstore_plpython/hstore_plpython.c | 12 ++--- contrib/jsonb_plpython/jsonb_plpython.c | 27 +++++------ contrib/ltree_plpython/ltree_plpython.c | 6 +-- src/pl/plpython/plpy_cursorobject.c | 8 +-- src/pl/plpython/plpy_elog.c | 26 +++++----- src/pl/plpython/plpy_exec.c | 44 ++++++++--------- src/pl/plpython/plpy_main.c | 59 ++++------------------- src/pl/plpython/plpy_planobject.c | 2 +- src/pl/plpython/plpy_plpymodule.c | 32 +++--------- src/pl/plpython/plpy_plpymodule.h | 2 - src/pl/plpython/plpy_resultobject.c | 16 ++---- src/pl/plpython/plpy_spi.c | 10 ++-- src/pl/plpython/plpy_typeio.c | 40 ++++++--------- src/pl/plpython/plpy_util.c | 9 ---- src/pl/plpython/plpy_util.h | 2 - src/pl/plpython/plpython.h | 34 +------------ 16 files changed, 95 insertions(+), 234 deletions(-) diff --git a/contrib/hstore_plpython/hstore_plpython.c b/contrib/hstore_plpython/hstore_plpython.c index 39bad55802..889ece315d 100644 --- a/contrib/hstore_plpython/hstore_plpython.c +++ b/contrib/hstore_plpython/hstore_plpython.c @@ -12,10 +12,8 @@ extern void _PG_init(void); /* Linkage to functions in plpython module */ typedef char *(*PLyObject_AsString_t) (PyObject *plrv); static PLyObject_AsString_t PLyObject_AsString_p; -#if PY_MAJOR_VERSION >= 3 typedef PyObject *(*PLyUnicode_FromStringAndSize_t) (const char *s, Py_ssize_t size); static PLyUnicode_FromStringAndSize_t PLyUnicode_FromStringAndSize_p; -#endif /* Linkage to functions in hstore module */ typedef HStore *(*hstoreUpgrade_t) (Datum orig); @@ -41,12 +39,10 @@ _PG_init(void) PLyObject_AsString_p = (PLyObject_AsString_t) load_external_function("$libdir/" PLPYTHON_LIBNAME, "PLyObject_AsString", true, NULL); -#if PY_MAJOR_VERSION >= 3 AssertVariableIsOfType(&PLyUnicode_FromStringAndSize, PLyUnicode_FromStringAndSize_t); PLyUnicode_FromStringAndSize_p = (PLyUnicode_FromStringAndSize_t) load_external_function("$libdir/" PLPYTHON_LIBNAME, "PLyUnicode_FromStringAndSize", true, NULL); -#endif AssertVariableIsOfType(&hstoreUpgrade, hstoreUpgrade_t); hstoreUpgrade_p = (hstoreUpgrade_t) load_external_function("$libdir/hstore", "hstoreUpgrade", @@ -102,16 +98,16 @@ hstore_to_plpython(PG_FUNCTION_ARGS) { PyObject *key; - key = PyString_FromStringAndSize(HSTORE_KEY(entries, base, i), - HSTORE_KEYLEN(entries, i)); + key = PLyUnicode_FromStringAndSize(HSTORE_KEY(entries, base, i), + HSTORE_KEYLEN(entries, i)); if (HSTORE_VALISNULL(entries, i)) PyDict_SetItem(dict, key, Py_None); else { PyObject *value; - value = PyString_FromStringAndSize(HSTORE_VAL(entries, base, i), - HSTORE_VALLEN(entries, i)); + value = PLyUnicode_FromStringAndSize(HSTORE_VAL(entries, base, i), + HSTORE_VALLEN(entries, i)); PyDict_SetItem(dict, key, value); Py_XDECREF(value); } diff --git a/contrib/jsonb_plpython/jsonb_plpython.c b/contrib/jsonb_plpython/jsonb_plpython.c index 836c178770..03bbfa87d9 100644 --- a/contrib/jsonb_plpython/jsonb_plpython.c +++ b/contrib/jsonb_plpython/jsonb_plpython.c @@ -28,11 +28,9 @@ static PyObject *PLyObject_FromJsonbContainer(JsonbContainer *jsonb); static JsonbValue *PLyObject_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state, bool is_elem); -#if PY_MAJOR_VERSION >= 3 typedef PyObject *(*PLyUnicode_FromStringAndSize_t) (const char *s, Py_ssize_t size); static PLyUnicode_FromStringAndSize_t PLyUnicode_FromStringAndSize_p; -#endif /* * Module initialize function: fetch function pointers for cross-module calls. @@ -45,13 +43,10 @@ _PG_init(void) PLyObject_AsString_p = (PLyObject_AsString_t) load_external_function("$libdir/" PLPYTHON_LIBNAME, "PLyObject_AsString", true, NULL); -#if PY_MAJOR_VERSION >= 3 AssertVariableIsOfType(&PLyUnicode_FromStringAndSize, PLyUnicode_FromStringAndSize_t); PLyUnicode_FromStringAndSize_p = (PLyUnicode_FromStringAndSize_t) load_external_function("$libdir/" PLPYTHON_LIBNAME, "PLyUnicode_FromStringAndSize", true, NULL); -#endif - AssertVariableIsOfType(&PLy_elog_impl, PLy_elog_impl_t); PLy_elog_impl_p = (PLy_elog_impl_t) load_external_function("$libdir/" PLPYTHON_LIBNAME, "PLy_elog_impl", @@ -65,25 +60,25 @@ _PG_init(void) #define PLy_elog (PLy_elog_impl_p) /* - * PLyString_FromJsonbValue + * PLyUnicode_FromJsonbValue * * Transform string JsonbValue to Python string. */ static PyObject * -PLyString_FromJsonbValue(JsonbValue *jbv) +PLyUnicode_FromJsonbValue(JsonbValue *jbv) { Assert(jbv->type == jbvString); - return PyString_FromStringAndSize(jbv->val.string.val, jbv->val.string.len); + return PLyUnicode_FromStringAndSize(jbv->val.string.val, jbv->val.string.len); } /* - * PLyString_ToJsonbValue + * PLyUnicode_ToJsonbValue * * Transform Python string to JsonbValue. */ static void -PLyString_ToJsonbValue(PyObject *obj, JsonbValue *jbvElem) +PLyUnicode_ToJsonbValue(PyObject *obj, JsonbValue *jbvElem) { jbvElem->type = jbvString; jbvElem->val.string.val = PLyObject_AsString(obj); @@ -118,7 +113,7 @@ PLyObject_FromJsonbValue(JsonbValue *jsonbValue) } case jbvString: - return PLyString_FromJsonbValue(jsonbValue); + return PLyUnicode_FromJsonbValue(jsonbValue); case jbvBool: if (jsonbValue->val.boolean) @@ -210,7 +205,7 @@ PLyObject_FromJsonbContainer(JsonbContainer *jsonb) if (r != WJB_KEY) continue; - key = PLyString_FromJsonbValue(&v); + key = PLyUnicode_FromJsonbValue(&v); if (!key) { Py_XDECREF(result_v); @@ -298,7 +293,7 @@ PLyMapping_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state) else { /* All others types of keys we serialize to string */ - PLyString_ToJsonbValue(key, &jbvKey); + PLyUnicode_ToJsonbValue(key, &jbvKey); } (void) pushJsonbValue(jsonb_state, WJB_KEY, &jbvKey); @@ -415,7 +410,7 @@ PLyObject_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state, bool is_ele { JsonbValue *out; - if (!(PyString_Check(obj) || PyUnicode_Check(obj))) + if (!PyUnicode_Check(obj)) { if (PySequence_Check(obj)) return PLySequence_ToJsonbValue(obj, jsonb_state); @@ -427,8 +422,8 @@ PLyObject_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state, bool is_ele if (obj == Py_None) out->type = jbvNull; - else if (PyString_Check(obj) || PyUnicode_Check(obj)) - PLyString_ToJsonbValue(obj, out); + else if (PyUnicode_Check(obj)) + PLyUnicode_ToJsonbValue(obj, out); /* * PyNumber_Check() returns true for booleans, so boolean check should diff --git a/contrib/ltree_plpython/ltree_plpython.c b/contrib/ltree_plpython/ltree_plpython.c index 1570e77dd9..7431a1150a 100644 --- a/contrib/ltree_plpython/ltree_plpython.c +++ b/contrib/ltree_plpython/ltree_plpython.c @@ -9,10 +9,8 @@ PG_MODULE_MAGIC; extern void _PG_init(void); /* Linkage to functions in plpython module */ -#if PY_MAJOR_VERSION >= 3 typedef PyObject *(*PLyUnicode_FromStringAndSize_t) (const char *s, Py_ssize_t size); static PLyUnicode_FromStringAndSize_t PLyUnicode_FromStringAndSize_p; -#endif /* @@ -22,12 +20,10 @@ void _PG_init(void) { /* Asserts verify that typedefs above match original declarations */ -#if PY_MAJOR_VERSION >= 3 AssertVariableIsOfType(&PLyUnicode_FromStringAndSize, PLyUnicode_FromStringAndSize_t); PLyUnicode_FromStringAndSize_p = (PLyUnicode_FromStringAndSize_t) load_external_function("$libdir/" PLPYTHON_LIBNAME, "PLyUnicode_FromStringAndSize", true, NULL); -#endif } @@ -54,7 +50,7 @@ ltree_to_plpython(PG_FUNCTION_ARGS) curlevel = LTREE_FIRST(in); for (i = 0; i < in->numlevel; i++) { - PyList_SetItem(list, i, PyString_FromStringAndSize(curlevel->name, curlevel->len)); + PyList_SetItem(list, i, PLyUnicode_FromStringAndSize(curlevel->name, curlevel->len)); curlevel = LEVEL_NEXT(curlevel); } diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index 08d8b607e3..6b6e743345 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -40,7 +40,7 @@ static PyTypeObject PLy_CursorType = { .tp_name = "PLyCursor", .tp_basicsize = sizeof(PLyCursorObject), .tp_dealloc = PLy_cursor_dealloc, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_ITER, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, .tp_doc = PLy_cursor_doc, .tp_iter = PyObject_SelfIter, .tp_iternext = PLy_cursor_iternext, @@ -150,7 +150,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) if (args) { - if (!PySequence_Check(args) || PyString_Check(args) || PyUnicode_Check(args)) + if (!PySequence_Check(args) || PyUnicode_Check(args)) { PLy_exception_set(PyExc_TypeError, "plpy.cursor takes a sequence as its second argument"); return NULL; @@ -169,7 +169,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) if (!so) PLy_elog(ERROR, "could not execute plan"); - sv = PyString_AsString(so); + sv = PLyUnicode_AsString(so); PLy_exception_set_plural(PyExc_TypeError, "Expected sequence of %d argument, got %d: %s", "Expected sequence of %d arguments, got %d: %s", @@ -410,7 +410,7 @@ PLy_cursor_fetch(PyObject *self, PyObject *args) SPI_cursor_fetch(portal, true, count); Py_DECREF(ret->status); - ret->status = PyInt_FromLong(SPI_OK_FETCH); + ret->status = PyLong_FromLong(SPI_OK_FETCH); Py_DECREF(ret->nrows); ret->nrows = PyLong_FromUnsignedLongLong(SPI_processed); diff --git a/src/pl/plpython/plpy_elog.c b/src/pl/plpython/plpy_elog.c index 224b8836fb..7c627eacfb 100644 --- a/src/pl/plpython/plpy_elog.c +++ b/src/pl/plpython/plpy_elog.c @@ -193,24 +193,20 @@ PLy_traceback(PyObject *e, PyObject *v, PyObject *tb, e_type_o = PyObject_GetAttrString(e, "__name__"); e_module_o = PyObject_GetAttrString(e, "__module__"); if (e_type_o) - e_type_s = PyString_AsString(e_type_o); + e_type_s = PLyUnicode_AsString(e_type_o); if (e_type_s) - e_module_s = PyString_AsString(e_module_o); + e_module_s = PLyUnicode_AsString(e_module_o); if (v && ((vob = PyObject_Str(v)) != NULL)) - vstr = PyString_AsString(vob); + vstr = PLyUnicode_AsString(vob); else vstr = "unknown"; initStringInfo(&xstr); if (!e_type_s || !e_module_s) { - if (PyString_Check(e)) - /* deprecated string exceptions */ - appendStringInfoString(&xstr, PyString_AsString(e)); - else - /* shouldn't happen */ - appendStringInfoString(&xstr, "unrecognized exception"); + /* shouldn't happen */ + appendStringInfoString(&xstr, "unrecognized exception"); } /* mimics behavior of traceback.format_exception_only */ else if (strcmp(e_module_s, "builtins") == 0 @@ -290,11 +286,11 @@ PLy_traceback(PyObject *e, PyObject *v, PyObject *tb, if (*tb_depth == 1) fname = ""; else - fname = PyString_AsString(name); + fname = PLyUnicode_AsString(name); proname = PLy_procedure_name(exec_ctx->curr_proc); - plain_filename = PyString_AsString(filename); - plain_lineno = PyInt_AsLong(lineno); + plain_filename = PLyUnicode_AsString(filename); + plain_lineno = PyLong_AsLong(lineno); if (proname == NULL) appendStringInfo(&tbstr, "\n PL/Python anonymous code block, line %ld, in %s", @@ -365,7 +361,7 @@ PLy_get_sqlerrcode(PyObject *exc, int *sqlerrcode) if (sqlstate == NULL) return; - buffer = PyString_AsString(sqlstate); + buffer = PLyUnicode_AsString(sqlstate); if (strlen(buffer) == 5 && strspn(buffer, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") == 5) { @@ -573,7 +569,7 @@ get_string_attr(PyObject *obj, char *attrname, char **str) val = PyObject_GetAttrString(obj, attrname); if (val != NULL && val != Py_None) { - *str = pstrdup(PyString_AsString(val)); + *str = pstrdup(PLyUnicode_AsString(val)); } Py_XDECREF(val); } @@ -589,7 +585,7 @@ set_string_attr(PyObject *obj, char *attrname, char *str) if (str != NULL) { - val = PyString_FromString(str); + val = PLyUnicode_FromString(str); if (!val) return false; } diff --git a/src/pl/plpython/plpy_exec.c b/src/pl/plpython/plpy_exec.c index c6f6a6fbcc..150b3a5977 100644 --- a/src/pl/plpython/plpy_exec.c +++ b/src/pl/plpython/plpy_exec.c @@ -294,7 +294,7 @@ PLy_exec_function(FunctionCallInfo fcinfo, PLyProcedure *proc) /* trigger subhandler * * the python function is expected to return Py_None if the tuple is - * acceptable and unmodified. Otherwise it should return a PyString + * acceptable and unmodified. Otherwise it should return a PyUnicode * object who's value is SKIP, or MODIFY. SKIP means don't perform * this action. MODIFY means the tuple has been modified, so update * tuple and perform action. SKIP and MODIFY assume the trigger fires @@ -360,9 +360,7 @@ PLy_exec_trigger(FunctionCallInfo fcinfo, PLyProcedure *proc) { char *srv; - if (PyString_Check(plrv)) - srv = PyString_AsString(plrv); - else if (PyUnicode_Check(plrv)) + if (PyUnicode_Check(plrv)) srv = PLyUnicode_AsString(plrv); else { @@ -700,35 +698,35 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *r if (!pltdata) return NULL; - pltname = PyString_FromString(tdata->tg_trigger->tgname); + pltname = PLyUnicode_FromString(tdata->tg_trigger->tgname); PyDict_SetItemString(pltdata, "name", pltname); Py_DECREF(pltname); stroid = DatumGetCString(DirectFunctionCall1(oidout, ObjectIdGetDatum(tdata->tg_relation->rd_id))); - pltrelid = PyString_FromString(stroid); + pltrelid = PLyUnicode_FromString(stroid); PyDict_SetItemString(pltdata, "relid", pltrelid); Py_DECREF(pltrelid); pfree(stroid); stroid = SPI_getrelname(tdata->tg_relation); - plttablename = PyString_FromString(stroid); + plttablename = PLyUnicode_FromString(stroid); PyDict_SetItemString(pltdata, "table_name", plttablename); Py_DECREF(plttablename); pfree(stroid); stroid = SPI_getnspname(tdata->tg_relation); - plttableschema = PyString_FromString(stroid); + plttableschema = PLyUnicode_FromString(stroid); PyDict_SetItemString(pltdata, "table_schema", plttableschema); Py_DECREF(plttableschema); pfree(stroid); if (TRIGGER_FIRED_BEFORE(tdata->tg_event)) - pltwhen = PyString_FromString("BEFORE"); + pltwhen = PLyUnicode_FromString("BEFORE"); else if (TRIGGER_FIRED_AFTER(tdata->tg_event)) - pltwhen = PyString_FromString("AFTER"); + pltwhen = PLyUnicode_FromString("AFTER"); else if (TRIGGER_FIRED_INSTEAD(tdata->tg_event)) - pltwhen = PyString_FromString("INSTEAD OF"); + pltwhen = PLyUnicode_FromString("INSTEAD OF"); else { elog(ERROR, "unrecognized WHEN tg_event: %u", tdata->tg_event); @@ -739,7 +737,7 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *r if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event)) { - pltlevel = PyString_FromString("ROW"); + pltlevel = PLyUnicode_FromString("ROW"); PyDict_SetItemString(pltdata, "level", pltlevel); Py_DECREF(pltlevel); @@ -750,7 +748,7 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *r if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event)) { - pltevent = PyString_FromString("INSERT"); + pltevent = PLyUnicode_FromString("INSERT"); PyDict_SetItemString(pltdata, "old", Py_None); pytnew = PLy_input_from_tuple(&proc->result_in, @@ -763,7 +761,7 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *r } else if (TRIGGER_FIRED_BY_DELETE(tdata->tg_event)) { - pltevent = PyString_FromString("DELETE"); + pltevent = PLyUnicode_FromString("DELETE"); PyDict_SetItemString(pltdata, "new", Py_None); pytold = PLy_input_from_tuple(&proc->result_in, @@ -776,7 +774,7 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *r } else if (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event)) { - pltevent = PyString_FromString("UPDATE"); + pltevent = PLyUnicode_FromString("UPDATE"); pytnew = PLy_input_from_tuple(&proc->result_in, tdata->tg_newtuple, @@ -803,7 +801,7 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *r } else if (TRIGGER_FIRED_FOR_STATEMENT(tdata->tg_event)) { - pltlevel = PyString_FromString("STATEMENT"); + pltlevel = PLyUnicode_FromString("STATEMENT"); PyDict_SetItemString(pltdata, "level", pltlevel); Py_DECREF(pltlevel); @@ -812,13 +810,13 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *r *rv = NULL; if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event)) - pltevent = PyString_FromString("INSERT"); + pltevent = PLyUnicode_FromString("INSERT"); else if (TRIGGER_FIRED_BY_DELETE(tdata->tg_event)) - pltevent = PyString_FromString("DELETE"); + pltevent = PLyUnicode_FromString("DELETE"); else if (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event)) - pltevent = PyString_FromString("UPDATE"); + pltevent = PLyUnicode_FromString("UPDATE"); else if (TRIGGER_FIRED_BY_TRUNCATE(tdata->tg_event)) - pltevent = PyString_FromString("TRUNCATE"); + pltevent = PLyUnicode_FromString("TRUNCATE"); else { elog(ERROR, "unrecognized OP tg_event: %u", tdata->tg_event); @@ -847,7 +845,7 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *r } for (i = 0; i < tdata->tg_trigger->tgnargs; i++) { - pltarg = PyString_FromString(tdata->tg_trigger->tgargs[i]); + pltarg = PLyUnicode_FromString(tdata->tg_trigger->tgargs[i]); /* * stolen, don't Py_DECREF @@ -931,9 +929,7 @@ PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata, PLyObToDatum *att; platt = PyList_GetItem(plkeys, i); - if (PyString_Check(platt)) - plattstr = PyString_AsString(platt); - else if (PyUnicode_Check(platt)) + if (PyUnicode_Check(platt)) plattstr = PLyUnicode_AsString(platt); else { diff --git a/src/pl/plpython/plpy_main.c b/src/pl/plpython/plpy_main.c index 3eedaa80da..0bce106495 100644 --- a/src/pl/plpython/plpy_main.c +++ b/src/pl/plpython/plpy_main.c @@ -28,27 +28,13 @@ * exported functions */ -#if PY_MAJOR_VERSION >= 3 -/* Use separate names to reduce confusion */ -#define plpython_validator plpython3_validator -#define plpython_call_handler plpython3_call_handler -#define plpython_inline_handler plpython3_inline_handler -#endif - extern void _PG_init(void); PG_MODULE_MAGIC; -PG_FUNCTION_INFO_V1(plpython_validator); -PG_FUNCTION_INFO_V1(plpython_call_handler); -PG_FUNCTION_INFO_V1(plpython_inline_handler); - -#if PY_MAJOR_VERSION < 3 -/* Define aliases plpython2_call_handler etc */ -PG_FUNCTION_INFO_V1(plpython2_validator); -PG_FUNCTION_INFO_V1(plpython2_call_handler); -PG_FUNCTION_INFO_V1(plpython2_inline_handler); -#endif +PG_FUNCTION_INFO_V1(plpython3_validator); +PG_FUNCTION_INFO_V1(plpython3_call_handler); +PG_FUNCTION_INFO_V1(plpython3_inline_handler); static bool PLy_procedure_is_trigger(Form_pg_proc procStruct); @@ -82,6 +68,10 @@ _PG_init(void) * the actual failure for later, so that operations like pg_restore can * load more than one plpython library so long as they don't try to do * anything much with the language. + * + * While we only support Python 3 these days, somebody might create an + * out-of-tree version adding back support for Python 2. Conflicts with + * such an extension should be detected. */ bitmask_ptr = (int **) find_rendezvous_variable("plpython_version_bitmask"); if (!(*bitmask_ptr)) /* am I the first? */ @@ -125,13 +115,9 @@ PLy_initialize(void) if (inited) return; -#if PY_MAJOR_VERSION >= 3 PyImport_AppendInittab("plpy", PyInit_plpy); -#endif Py_Initialize(); -#if PY_MAJOR_VERSION >= 3 PyImport_ImportModule("plpy"); -#endif PLy_init_interp(); PLy_init_plpy(); if (PyErr_Occurred()) @@ -171,7 +157,7 @@ PLy_init_interp(void) } Datum -plpython_validator(PG_FUNCTION_ARGS) +plpython3_validator(PG_FUNCTION_ARGS) { Oid funcoid = PG_GETARG_OID(0); HeapTuple tuple; @@ -203,17 +189,8 @@ plpython_validator(PG_FUNCTION_ARGS) PG_RETURN_VOID(); } -#if PY_MAJOR_VERSION < 3 Datum -plpython2_validator(PG_FUNCTION_ARGS) -{ - /* call plpython validator with our fcinfo so it gets our oid */ - return plpython_validator(fcinfo); -} -#endif /* PY_MAJOR_VERSION < 3 */ - -Datum -plpython_call_handler(PG_FUNCTION_ARGS) +plpython3_call_handler(PG_FUNCTION_ARGS) { bool nonatomic; Datum retval; @@ -284,16 +261,8 @@ plpython_call_handler(PG_FUNCTION_ARGS) return retval; } -#if PY_MAJOR_VERSION < 3 Datum -plpython2_call_handler(PG_FUNCTION_ARGS) -{ - return plpython_call_handler(fcinfo); -} -#endif /* PY_MAJOR_VERSION < 3 */ - -Datum -plpython_inline_handler(PG_FUNCTION_ARGS) +plpython3_inline_handler(PG_FUNCTION_ARGS) { LOCAL_FCINFO(fake_fcinfo, 0); InlineCodeBlock *codeblock = (InlineCodeBlock *) DatumGetPointer(PG_GETARG_DATUM(0)); @@ -368,14 +337,6 @@ plpython_inline_handler(PG_FUNCTION_ARGS) PG_RETURN_VOID(); } -#if PY_MAJOR_VERSION < 3 -Datum -plpython2_inline_handler(PG_FUNCTION_ARGS) -{ - return plpython_inline_handler(fcinfo); -} -#endif /* PY_MAJOR_VERSION < 3 */ - static bool PLy_procedure_is_trigger(Form_pg_proc procStruct) { diff --git a/src/pl/plpython/plpy_planobject.c b/src/pl/plpython/plpy_planobject.c index 5951d2a6ff..ec2439c6a1 100644 --- a/src/pl/plpython/plpy_planobject.c +++ b/src/pl/plpython/plpy_planobject.c @@ -119,7 +119,7 @@ PLy_plan_status(PyObject *self, PyObject *args) { Py_INCREF(Py_True); return Py_True; - /* return PyInt_FromLong(self->status); */ + /* return PyLong_FromLong(self->status); */ } return NULL; } diff --git a/src/pl/plpython/plpy_plpymodule.c b/src/pl/plpython/plpy_plpymodule.c index 907f89d153..fa08f0dbfb 100644 --- a/src/pl/plpython/plpy_plpymodule.c +++ b/src/pl/plpython/plpy_plpymodule.c @@ -107,7 +107,6 @@ static PyMethodDef PLy_exc_methods[] = { {NULL, NULL, 0, NULL} }; -#if PY_MAJOR_VERSION >= 3 static PyModuleDef PLy_module = { PyModuleDef_HEAD_INIT, .m_name = "plpy", @@ -139,7 +138,6 @@ PyInit_plpy(void) return m; } -#endif /* PY_MAJOR_VERSION >= 3 */ void PLy_init_plpy(void) @@ -148,10 +146,6 @@ PLy_init_plpy(void) *main_dict, *plpy_mod; -#if PY_MAJOR_VERSION < 3 - PyObject *plpy; -#endif - /* * initialize plpy module */ @@ -160,13 +154,7 @@ PLy_init_plpy(void) PLy_subtransaction_init_type(); PLy_cursor_init_type(); -#if PY_MAJOR_VERSION >= 3 PyModule_Create(&PLy_module); - /* for Python 3 we initialized the exceptions in PyInit_plpy */ -#else - plpy = Py_InitModule("plpy", PLy_methods); - PLy_add_exceptions(plpy); -#endif /* PyDict_SetItemString(plpy, "PlanType", (PyObject *) &PLy_PlanType); */ @@ -189,11 +177,7 @@ PLy_add_exceptions(PyObject *plpy) PyObject *excmod; HASHCTL hash_ctl; -#if PY_MAJOR_VERSION < 3 - excmod = Py_InitModule("spiexceptions", PLy_exc_methods); -#else excmod = PyModule_Create(&PLy_exc_module); -#endif if (excmod == NULL) PLy_elog(ERROR, "could not create the spiexceptions module"); @@ -268,7 +252,7 @@ PLy_generate_spi_exceptions(PyObject *mod, PyObject *base) if (dict == NULL) PLy_elog(ERROR, NULL); - sqlstate = PyString_FromString(unpack_sql_state(exception_map[i].sqlstate)); + sqlstate = PLyUnicode_FromString(unpack_sql_state(exception_map[i].sqlstate)); if (sqlstate == NULL) PLy_elog(ERROR, "could not generate SPI exceptions"); @@ -346,7 +330,7 @@ PLy_quote_literal(PyObject *self, PyObject *args) return NULL; quoted = quote_literal_cstr(str); - ret = PyString_FromString(quoted); + ret = PLyUnicode_FromString(quoted); pfree(quoted); return ret; @@ -363,10 +347,10 @@ PLy_quote_nullable(PyObject *self, PyObject *args) return NULL; if (str == NULL) - return PyString_FromString("NULL"); + return PLyUnicode_FromString("NULL"); quoted = quote_literal_cstr(str); - ret = PyString_FromString(quoted); + ret = PLyUnicode_FromString(quoted); pfree(quoted); return ret; @@ -383,7 +367,7 @@ PLy_quote_ident(PyObject *self, PyObject *args) return NULL; quoted = quote_identifier(str); - ret = PyString_FromString(quoted); + ret = PLyUnicode_FromString(quoted); return ret; } @@ -400,7 +384,7 @@ object_to_string(PyObject *obj) { char *str; - str = pstrdup(PyString_AsString(so)); + str = pstrdup(PLyUnicode_AsString(so)); Py_DECREF(so); return str; @@ -444,7 +428,7 @@ PLy_output(volatile int level, PyObject *self, PyObject *args, PyObject *kw) else so = PyObject_Str(args); - if (so == NULL || ((message = PyString_AsString(so)) == NULL)) + if (so == NULL || ((message = PLyUnicode_AsString(so)) == NULL)) { level = ERROR; message = dgettext(TEXTDOMAIN, "could not parse error message in plpy.elog"); @@ -457,7 +441,7 @@ PLy_output(volatile int level, PyObject *self, PyObject *args, PyObject *kw) { while (PyDict_Next(kw, &pos, &key, &value)) { - char *keyword = PyString_AsString(key); + char *keyword = PLyUnicode_AsString(key); if (strcmp(keyword, "message") == 0) { diff --git a/src/pl/plpython/plpy_plpymodule.h b/src/pl/plpython/plpy_plpymodule.h index 54d78101ce..ad6436aca7 100644 --- a/src/pl/plpython/plpy_plpymodule.h +++ b/src/pl/plpython/plpy_plpymodule.h @@ -11,9 +11,7 @@ extern HTAB *PLy_spi_exceptions; -#if PY_MAJOR_VERSION >= 3 PyMODINIT_FUNC PyInit_plpy(void); -#endif extern void PLy_init_plpy(void); #endif /* PLPY_PLPYMODULE_H */ diff --git a/src/pl/plpython/plpy_resultobject.c b/src/pl/plpython/plpy_resultobject.c index 54f39419c8..a8516b2db3 100644 --- a/src/pl/plpython/plpy_resultobject.c +++ b/src/pl/plpython/plpy_resultobject.c @@ -76,7 +76,7 @@ PLy_result_new(void) Py_INCREF(Py_None); ob->status = Py_None; - ob->nrows = PyInt_FromLong(-1); + ob->nrows = PyLong_FromLong(-1); ob->rows = PyList_New(0); ob->tupdesc = NULL; if (!ob->rows) @@ -125,7 +125,7 @@ PLy_result_colnames(PyObject *self, PyObject *unused) { Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i); - PyList_SET_ITEM(list, i, PyString_FromString(NameStr(attr->attname))); + PyList_SET_ITEM(list, i, PLyUnicode_FromString(NameStr(attr->attname))); } return list; @@ -151,7 +151,7 @@ PLy_result_coltypes(PyObject *self, PyObject *unused) { Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i); - PyList_SET_ITEM(list, i, PyInt_FromLong(attr->atttypid)); + PyList_SET_ITEM(list, i, PyLong_FromLong(attr->atttypid)); } return list; @@ -177,7 +177,7 @@ PLy_result_coltypmods(PyObject *self, PyObject *unused) { Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i); - PyList_SET_ITEM(list, i, PyInt_FromLong(attr->atttypmod)); + PyList_SET_ITEM(list, i, PyLong_FromLong(attr->atttypmod)); } return list; @@ -226,19 +226,11 @@ PLy_result_str(PyObject *arg) { PLyResultObject *ob = (PLyResultObject *) arg; -#if PY_MAJOR_VERSION >= 3 return PyUnicode_FromFormat("<%s status=%S nrows=%S rows=%S>", Py_TYPE(ob)->tp_name, ob->status, ob->nrows, ob->rows); -#else - return PyString_FromFormat("<%s status=%ld nrows=%ld rows=%s>", - ob->ob_type->tp_name, - PyInt_AsLong(ob->status), - PyInt_AsLong(ob->nrows), - PyString_AsString(PyObject_Str(ob->rows))); -#endif } static PyObject * diff --git a/src/pl/plpython/plpy_spi.c b/src/pl/plpython/plpy_spi.c index 86d70470a7..9a71a42c15 100644 --- a/src/pl/plpython/plpy_spi.c +++ b/src/pl/plpython/plpy_spi.c @@ -90,9 +90,7 @@ PLy_spi_prepare(PyObject *self, PyObject *args) int32 typmod; optr = PySequence_GetItem(list, i); - if (PyString_Check(optr)) - sptr = PyString_AsString(optr); - else if (PyUnicode_Check(optr)) + if (PyUnicode_Check(optr)) sptr = PLyUnicode_AsString(optr); else { @@ -186,7 +184,7 @@ PLy_spi_execute_plan(PyObject *ob, PyObject *list, long limit) if (list != NULL) { - if (!PySequence_Check(list) || PyString_Check(list) || PyUnicode_Check(list)) + if (!PySequence_Check(list) || PyUnicode_Check(list)) { PLy_exception_set(PyExc_TypeError, "plpy.execute takes a sequence as its second argument"); return NULL; @@ -205,7 +203,7 @@ PLy_spi_execute_plan(PyObject *ob, PyObject *list, long limit) if (!so) PLy_elog(ERROR, "could not execute plan"); - sv = PyString_AsString(so); + sv = PLyUnicode_AsString(so); PLy_exception_set_plural(PyExc_TypeError, "Expected sequence of %d argument, got %d: %s", "Expected sequence of %d arguments, got %d: %s", @@ -360,7 +358,7 @@ PLy_spi_execute_fetch_result(SPITupleTable *tuptable, uint64 rows, int status) return NULL; } Py_DECREF(result->status); - result->status = PyInt_FromLong(status); + result->status = PyLong_FromLong(status); if (status > 0 && tuptable == NULL) { diff --git a/src/pl/plpython/plpy_typeio.c b/src/pl/plpython/plpy_typeio.c index 5e807b139f..7018c9d404 100644 --- a/src/pl/plpython/plpy_typeio.c +++ b/src/pl/plpython/plpy_typeio.c @@ -26,12 +26,12 @@ static PyObject *PLyBool_FromBool(PLyDatumToOb *arg, Datum d); static PyObject *PLyFloat_FromFloat4(PLyDatumToOb *arg, Datum d); static PyObject *PLyFloat_FromFloat8(PLyDatumToOb *arg, Datum d); static PyObject *PLyDecimal_FromNumeric(PLyDatumToOb *arg, Datum d); -static PyObject *PLyInt_FromInt16(PLyDatumToOb *arg, Datum d); -static PyObject *PLyInt_FromInt32(PLyDatumToOb *arg, Datum d); +static PyObject *PLyLong_FromInt16(PLyDatumToOb *arg, Datum d); +static PyObject *PLyLong_FromInt32(PLyDatumToOb *arg, Datum d); static PyObject *PLyLong_FromInt64(PLyDatumToOb *arg, Datum d); static PyObject *PLyLong_FromOid(PLyDatumToOb *arg, Datum d); static PyObject *PLyBytes_FromBytea(PLyDatumToOb *arg, Datum d); -static PyObject *PLyString_FromScalar(PLyDatumToOb *arg, Datum d); +static PyObject *PLyUnicode_FromScalar(PLyDatumToOb *arg, Datum d); static PyObject *PLyObject_FromTransform(PLyDatumToOb *arg, Datum d); static PyObject *PLyList_FromArray(PLyDatumToOb *arg, Datum d); static PyObject *PLyList_FromArray_recurse(PLyDatumToOb *elm, int *dims, int ndim, int dim, @@ -59,7 +59,7 @@ static void PLySequence_ToArray_recurse(PLyObToDatum *elm, PyObject *list, Datum *elems, bool *nulls, int *currelem); /* conversion from Python objects to composite Datums */ -static Datum PLyString_ToComposite(PLyObToDatum *arg, PyObject *string, bool inarray); +static Datum PLyUnicode_ToComposite(PLyObToDatum *arg, PyObject *string, bool inarray); static Datum PLyMapping_ToComposite(PLyObToDatum *arg, TupleDesc desc, PyObject *mapping); static Datum PLySequence_ToComposite(PLyObToDatum *arg, TupleDesc desc, PyObject *sequence); static Datum PLyGenericObject_ToComposite(PLyObToDatum *arg, TupleDesc desc, PyObject *object, bool inarray); @@ -517,10 +517,10 @@ PLy_input_setup_func(PLyDatumToOb *arg, MemoryContext arg_mcxt, arg->func = PLyDecimal_FromNumeric; break; case INT2OID: - arg->func = PLyInt_FromInt16; + arg->func = PLyLong_FromInt16; break; case INT4OID: - arg->func = PLyInt_FromInt32; + arg->func = PLyLong_FromInt32; break; case INT8OID: arg->func = PLyLong_FromInt64; @@ -532,7 +532,7 @@ PLy_input_setup_func(PLyDatumToOb *arg, MemoryContext arg_mcxt, arg->func = PLyBytes_FromBytea; break; default: - arg->func = PLyString_FromScalar; + arg->func = PLyUnicode_FromScalar; getTypeOutputInfo(typeOid, &typoutput, &typisvarlena); fmgr_info_cxt(typoutput, &arg->u.scalar.typfunc, arg_mcxt); break; @@ -600,15 +600,15 @@ PLyDecimal_FromNumeric(PLyDatumToOb *arg, Datum d) } static PyObject * -PLyInt_FromInt16(PLyDatumToOb *arg, Datum d) +PLyLong_FromInt16(PLyDatumToOb *arg, Datum d) { - return PyInt_FromLong(DatumGetInt16(d)); + return PyLong_FromLong(DatumGetInt16(d)); } static PyObject * -PLyInt_FromInt32(PLyDatumToOb *arg, Datum d) +PLyLong_FromInt32(PLyDatumToOb *arg, Datum d) { - return PyInt_FromLong(DatumGetInt32(d)); + return PyLong_FromLong(DatumGetInt32(d)); } static PyObject * @@ -638,10 +638,10 @@ PLyBytes_FromBytea(PLyDatumToOb *arg, Datum d) * Generic input conversion using a SQL type's output function. */ static PyObject * -PLyString_FromScalar(PLyDatumToOb *arg, Datum d) +PLyUnicode_FromScalar(PLyDatumToOb *arg, Datum d) { char *x = OutputFunctionCall(&arg->u.scalar.typfunc, d); - PyObject *r = PyString_FromString(x); + PyObject *r = PLyUnicode_FromString(x); pfree(x); return r; @@ -954,8 +954,8 @@ PLyObject_ToComposite(PLyObToDatum *arg, PyObject *plrv, * The string conversion case doesn't require a tupdesc, nor per-field * conversion data, so just go for it if that's the case to use. */ - if (PyString_Check(plrv) || PyUnicode_Check(plrv)) - return PLyString_ToComposite(arg, plrv, inarray); + if (PyUnicode_Check(plrv)) + return PLyUnicode_ToComposite(arg, plrv, inarray); /* * If we're dealing with a named composite type, we must look up the @@ -1032,25 +1032,17 @@ PLyObject_AsString(PyObject *plrv) else if (PyFloat_Check(plrv)) { /* use repr() for floats, str() is lossy */ -#if PY_MAJOR_VERSION >= 3 PyObject *s = PyObject_Repr(plrv); plrv_bo = PLyUnicode_Bytes(s); Py_XDECREF(s); -#else - plrv_bo = PyObject_Repr(plrv); -#endif } else { -#if PY_MAJOR_VERSION >= 3 PyObject *s = PyObject_Str(plrv); plrv_bo = PLyUnicode_Bytes(s); Py_XDECREF(s); -#else - plrv_bo = PyObject_Str(plrv); -#endif } if (!plrv_bo) PLy_elog(ERROR, "could not create string representation of Python object"); @@ -1299,7 +1291,7 @@ PLySequence_ToArray_recurse(PLyObToDatum *elm, PyObject *list, * Convert a Python string to composite, using record_in. */ static Datum -PLyString_ToComposite(PLyObToDatum *arg, PyObject *string, bool inarray) +PLyUnicode_ToComposite(PLyObToDatum *arg, PyObject *string, bool inarray) { char *str; diff --git a/src/pl/plpython/plpy_util.c b/src/pl/plpython/plpy_util.c index 4a7d7264d7..22e2a599ad 100644 --- a/src/pl/plpython/plpy_util.c +++ b/src/pl/plpython/plpy_util.c @@ -78,12 +78,6 @@ PLyUnicode_Bytes(PyObject *unicode) * Convert a Python unicode object to a C string in PostgreSQL server * encoding. No Python object reference is passed out of this * function. The result is palloc'ed. - * - * Note that this function is disguised as PyString_AsString() when - * using Python 3. That function returns a pointer into the internal - * memory of the argument, which isn't exactly the interface of this - * function. But in either case you get a rather short-lived - * reference that you ought to better leave alone. */ char * PLyUnicode_AsString(PyObject *unicode) @@ -95,7 +89,6 @@ PLyUnicode_AsString(PyObject *unicode) return rv; } -#if PY_MAJOR_VERSION >= 3 /* * Convert a C string in the PostgreSQL server encoding to a Python * unicode object. Reference ownership is passed to the caller. @@ -126,5 +119,3 @@ PLyUnicode_FromString(const char *s) { return PLyUnicode_FromStringAndSize(s, strlen(s)); } - -#endif /* PY_MAJOR_VERSION >= 3 */ diff --git a/src/pl/plpython/plpy_util.h b/src/pl/plpython/plpy_util.h index c9ba7edc0e..7c6577925e 100644 --- a/src/pl/plpython/plpy_util.h +++ b/src/pl/plpython/plpy_util.h @@ -11,9 +11,7 @@ extern PyObject *PLyUnicode_Bytes(PyObject *unicode); extern char *PLyUnicode_AsString(PyObject *unicode); -#if PY_MAJOR_VERSION >= 3 extern PyObject *PLyUnicode_FromString(const char *s); extern PyObject *PLyUnicode_FromStringAndSize(const char *s, Py_ssize_t size); -#endif #endif /* PLPY_UTIL_H */ diff --git a/src/pl/plpython/plpython.h b/src/pl/plpython/plpython.h index 05e4362dab..2a0c9bf036 100644 --- a/src/pl/plpython/plpython.h +++ b/src/pl/plpython/plpython.h @@ -59,37 +59,6 @@ #include #endif -/* - * Python 2/3 strings/unicode/bytes handling. Python 2 has strings - * and unicode, Python 3 has strings, which are unicode on the C - * level, and bytes. The porting convention, which is similarly used - * in Python 2.6, is that "Unicode" is always unicode, and "Bytes" are - * bytes in Python 3 and strings in Python 2. Since we keep - * supporting Python 2 and its usual strings, we provide a - * compatibility layer for Python 3 that when asked to convert a C - * string to a Python string it converts the C string from the - * PostgreSQL server encoding to a Python Unicode object. - */ -#if PY_MAJOR_VERSION >= 3 -#define PyString_Check(x) 0 -#define PyString_AsString(x) PLyUnicode_AsString(x) -#define PyString_FromString(x) PLyUnicode_FromString(x) -#define PyString_FromStringAndSize(x, size) PLyUnicode_FromStringAndSize(x, size) -#endif - -/* - * Python 3 only has long. - */ -#if PY_MAJOR_VERSION >= 3 -#define PyInt_FromLong(x) PyLong_FromLong(x) -#define PyInt_AsLong(x) PyLong_AsLong(x) -#endif - -/* Python 3 removed the Py_TPFLAGS_HAVE_ITER flag */ -#if PY_MAJOR_VERSION >= 3 -#define Py_TPFLAGS_HAVE_ITER 0 -#endif - /* define our text domain for translations */ #undef TEXTDOMAIN #define TEXTDOMAIN PG_TEXTDOMAIN("plpython") @@ -130,8 +99,7 @@ #define printf(...) pg_printf(__VA_ARGS__) /* - * Used throughout, and also by the Python 2/3 porting layer, so it's easier to - * just include it everywhere. + * Used throughout, so it's easier to just include it everywhere. */ #include "plpy_util.h"