From 81a942e439125ddecf117598e142f70cec703214 Mon Sep 17 00:00:00 2001 From: Thomas Ubensee <34603111+tomuben@users.noreply.github.com> Date: Tue, 21 May 2024 16:58:54 -0300 Subject: [PATCH 1/3] Tmp: Activate Debug and TraceRefs for pyextdataframe.so --- exaudfclient/base/python/python3/BUILD | 2 ++ exaudfclient/base/python/pythoncontainer.cc | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/exaudfclient/base/python/python3/BUILD b/exaudfclient/base/python/python3/BUILD index 29c0defbd..de5b153e7 100644 --- a/exaudfclient/base/python/python3/BUILD +++ b/exaudfclient/base/python/python3/BUILD @@ -107,6 +107,8 @@ genrule( cc_binary( name = "pyextdataframe.so", linkshared = 1, + copts = ["-DPy_TRACE_REFS=1", "-DPy_DEBUG=1"], + linkopts = ["-lpython3.10"], srcs = [":python_ext_dataframe.cc"], deps = ["@python3//:python3","@numpy//:numpy", "//exaudflib:header", "//:debug_message_h"], diff --git a/exaudfclient/base/python/pythoncontainer.cc b/exaudfclient/base/python/pythoncontainer.cc index 43c6265a6..17f3e9961 100644 --- a/exaudfclient/base/python/pythoncontainer.cc +++ b/exaudfclient/base/python/pythoncontainer.cc @@ -207,7 +207,8 @@ PythonVMImpl::PythonVMImpl(bool checkOnly): m_checkOnly(checkOnly) PyObject *retvalue = PyObject_CallFunctionObjArgs(runobj, globals, NULL); check("F-UDF-CL-SL-PYTHON-1017"); Py_XDECREF(retvalue); retvalue = NULL; - code = Py_CompileString(integrated_exascript_python_wrap_py, "", Py_file_input); check("F-UDF-CL-SL-PYTHON-1018"); + PyCompilerFlags pycompilerFlags = {.cf_flags = 0, .cf_feature_version = PY_MINOR_VERSION}; + code = Py_CompileStringExFlags(integrated_exascript_python_wrap_py, "", Py_file_input, &pycompilerFlags, 0); check("F-UDF-CL-SL-PYTHON-1018"); if (code == NULL) throw PythonVM::exception("Failed to compile wrapping script"); PyEval_EvalCode(code, globals, globals); check("F-UDF-CL-SL-PYTHON-1019"); From 1edfc46b062b30024f371fab37e7d0d6e2e7258e Mon Sep 17 00:00:00 2001 From: Thomas Ubensee <34603111+tomuben@users.noreply.github.com> Date: Tue, 21 May 2024 18:15:07 -0300 Subject: [PATCH 2/3] Use Python Dbg packages --- exaudfclient/base/python/python3/BUILD | 11 ++++++----- .../flavor_base/base_test_build_run/Dockerfile | 4 ++-- .../language_deps/packages/apt_get_packages | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/exaudfclient/base/python/python3/BUILD b/exaudfclient/base/python/python3/BUILD index de5b153e7..3232654b3 100644 --- a/exaudfclient/base/python/python3/BUILD +++ b/exaudfclient/base/python/python3/BUILD @@ -3,7 +3,7 @@ package(default_visibility = ["//visibility:public"]) genrule( name = "exascript_python_tmp_cc", cmd = """ - INCLUDES=`$$PYTHON3_PREFIX/bin/$$PYTHON3_VERSION-config --includes` + INCLUDES=`$$PYTHON3_PREFIX/bin/$$PYTHON3_VERSION-dbg-config --includes` mkdir -p build_exascript_python_tmp_cc/exaudflib cp "$(location //exaudflib:swig/script_data_transfer_objects_wrapper.h)" "$(location //exaudflib:exascript.i)" build_exascript_python_tmp_cc/exaudflib cd build_exascript_python_tmp_cc @@ -16,7 +16,7 @@ genrule( genrule( name = "exascript_python_tmp_h", cmd = """ - INCLUDES=`$$PYTHON3_PREFIX/bin/$$PYTHON3_VERSION-config --includes` + INCLUDES=`$$PYTHON3_PREFIX/bin/$$PYTHON3_VERSION-dbg-config --includes` mkdir build_exascript_python_tmp_h cp "$(location //exaudflib:swig/script_data_transfer_objects_wrapper.h)" "$(location //exaudflib:exascript.i)" build_exascript_python_tmp_h cp "$(location exascript_python_tmp.cc)" "$(location exascript_python.py)" build_exascript_python_tmp_h @@ -79,6 +79,7 @@ genrule( cc_library( name = "exascript_python", + copts = ["-DPy_TRACE_REFS=1", "-DPy_DEBUG=1"], srcs = [":filter_swig_code_exascript_python_cc",":filter_swig_code_exascript_python_h"], hdrs = [":filter_swig_code_exascript_python_h"], deps = ["@python3//:python3","//exaudflib:exaudflib-deps","//exaudflib:header"], @@ -88,7 +89,8 @@ cc_library( cc_library( name = "pythoncontainer", srcs = ["//python:pythoncontainer.cc", ":dummy.h"], - data = [":extend_exascript_python_preset_py"], + data = [":extend_exascript_python_preset_py"], + copts = ["-DPy_TRACE_REFS=1", "-DPy_DEBUG=1"], hdrs = [":exascript_python_int", ":filter_swig_code_exascript_python_h"], include_prefix = ".", deps = ["@python3//:python3",":exascript_python","//exaudflib:header", @@ -107,8 +109,7 @@ genrule( cc_binary( name = "pyextdataframe.so", linkshared = 1, - copts = ["-DPy_TRACE_REFS=1", "-DPy_DEBUG=1"], - linkopts = ["-lpython3.10"], + copts = ["-DPy_TRACE_REFS=1", "-DPy_DEBUG=1"], srcs = [":python_ext_dataframe.cc"], deps = ["@python3//:python3","@numpy//:numpy", "//exaudflib:header", "//:debug_message_h"], diff --git a/flavors/template-Exasol-all-python-3.10/flavor_base/base_test_build_run/Dockerfile b/flavors/template-Exasol-all-python-3.10/flavor_base/base_test_build_run/Dockerfile index 66ee9bdfd..2a1a85bc3 100644 --- a/flavors/template-Exasol-all-python-3.10/flavor_base/base_test_build_run/Dockerfile +++ b/flavors/template-Exasol-all-python-3.10/flavor_base/base_test_build_run/Dockerfile @@ -27,10 +27,10 @@ RUN mkdir /exaudfclient /exaudf COPY /exaudfclient/base /exaudfclient/base WORKDIR /exaudfclient/base -RUN ["/bin/bash", "-c", "source /env && bash build.sh --config no-tty -c dbg --config python --config test-binaries-py3"] +RUN ["/bin/bash", "-c", "source /env && bash build.sh --strip never --config no-tty -c dbg --config python --config slow-wrapper-py3"] RUN cp -r -L bazel-bin/* /exaudf RUN ./test_udfclient.sh /exaudf/exaudfclient_py3 -RUN ./test_udfclient.sh /exaudf/exaudfclient_py3_static +#RUN ./test_udfclient.sh /exaudf/exaudfclient_py3_static WORKDIR / RUN mkdir /exasol_emulator diff --git a/flavors/template-Exasol-all-python-3.10/flavor_base/language_deps/packages/apt_get_packages b/flavors/template-Exasol-all-python-3.10/flavor_base/language_deps/packages/apt_get_packages index adbb9d0d8..e21dabd38 100644 --- a/flavors/template-Exasol-all-python-3.10/flavor_base/language_deps/packages/apt_get_packages +++ b/flavors/template-Exasol-all-python-3.10/flavor_base/language_deps/packages/apt_get_packages @@ -1,4 +1,4 @@ ca-certificates|20230311ubuntu0.22.04.1 -python3.10-dev|3.10.12-1~22.04.3 +python3.10-dbg|3.10.12-1~22.04.3 python3-distutils|3.10.8-1~22.04 curl|7.81.0-1ubuntu1.16 From 0d251ddb1bdbfa1d4166f498e8a7b33b79f3725f Mon Sep 17 00:00:00 2001 From: Thomas Ubensee <34603111+tomuben@users.noreply.github.com> Date: Thu, 23 May 2024 15:08:49 -0300 Subject: [PATCH 3/3] DEBUG stuff --- exaudfclient/base/.bazelrc | 1 + .../base/create_binary_wrapper_valgrind.sh | 2 +- .../base/exaudflib/impl/socket_high_level.cc | 2 +- exaudfclient/base/python/python3/BUILD | 14 +- .../python/python3/python_ext_dataframe.cc | 375 ++++++++++-------- exaudfclient/base/python_repository.bzl | 2 +- .../flavor_base/language_deps/Dockerfile | 4 +- .../language_deps/packages/apt_get_packages | 2 + .../packages/python3_pip_packages | 2 +- 9 files changed, 226 insertions(+), 178 deletions(-) diff --git a/exaudfclient/base/.bazelrc b/exaudfclient/base/.bazelrc index 1607ca871..243f4ceb8 100644 --- a/exaudfclient/base/.bazelrc +++ b/exaudfclient/base/.bazelrc @@ -5,6 +5,7 @@ build:java --define java=true --action_env=JAVA_PREFIX build:python --define python=true --action_env=PYTHON2_SYSPATH --action_env=PYTHON2_PREFIX --action_env=PYTHON2_VERSION --action_env=NUMPY_PREFIX --action_env=PYTHON3_SYSPATH --action_env=PYTHON3_PREFIX --action_env=PYTHON3_VERSION build:fast-binary-py3 --copt='-DCUSTOM_LIBEXAUDFLIB_PATH="/exaudf/libexaudflib_complete.so"' --define binary_type=fast_binary //:exaudfclient_py3 build:slow-wrapper-py3 --define binary_type=slow_wrapper //:exaudfclient_py3 +build:valgrind-wrapper-py3 --config=slow-wrapper-py3 --define wrapper_type=valgrind_wrapper //:exaudfclient_py3 build:static-binary-py3 //:exaudfclient_py3_static build:test-binaries-py3 --config=static-binary-py3 --config=slow-wrapper-py3 build:verbose --copt='-v' --subcommands --verbose_failures --announce_rc diff --git a/exaudfclient/base/create_binary_wrapper_valgrind.sh b/exaudfclient/base/create_binary_wrapper_valgrind.sh index 5fb10a1ab..2913f3b18 100755 --- a/exaudfclient/base/create_binary_wrapper_valgrind.sh +++ b/exaudfclient/base/create_binary_wrapper_valgrind.sh @@ -9,5 +9,5 @@ touch "$CLIENT_WRAPPER" { cat "$WRAPPER_TEMPLATE" echo -echo valgrind "./$(basename "$CLIENT_BINARY")" '$*' +echo valgrind --leak-check=full "./$(basename "$CLIENT_BINARY")" '$*' } >> "$CLIENT_WRAPPER" \ No newline at end of file diff --git a/exaudfclient/base/exaudflib/impl/socket_high_level.cc b/exaudfclient/base/exaudflib/impl/socket_high_level.cc index 4f50ecbe8..6a32c5623 100644 --- a/exaudfclient/base/exaudflib/impl/socket_high_level.cc +++ b/exaudfclient/base/exaudflib/impl/socket_high_level.cc @@ -92,7 +92,7 @@ bool exaudflib::socket_high_level::send_init(zmq::socket_t &socket, const std::s #ifdef SWIGVM_LOG_CLIENT std::cerr << "W-UDF-CL-LIB-1011: Failed to set nofile limit" << std::endl; #else - throw SWIGVMContainers::SWIGVM::exception("F-UDF-CL-LIB-1012: Failed to set nofile limit"); + std::cerr << "W-UDF-CL-LIB-1011: Failed to set nofile limit" << std::endl; #endif d.rlim_cur = d.rlim_max = 32768; if (setrlimit(RLIMIT_NPROC, &d) != 0) diff --git a/exaudfclient/base/python/python3/BUILD b/exaudfclient/base/python/python3/BUILD index 3232654b3..6ecdceaa8 100644 --- a/exaudfclient/base/python/python3/BUILD +++ b/exaudfclient/base/python/python3/BUILD @@ -3,7 +3,7 @@ package(default_visibility = ["//visibility:public"]) genrule( name = "exascript_python_tmp_cc", cmd = """ - INCLUDES=`$$PYTHON3_PREFIX/bin/$$PYTHON3_VERSION-dbg-config --includes` + INCLUDES=`$$PYTHON3_PREFIX/bin/$$PYTHON3_VERSION-config --includes` mkdir -p build_exascript_python_tmp_cc/exaudflib cp "$(location //exaudflib:swig/script_data_transfer_objects_wrapper.h)" "$(location //exaudflib:exascript.i)" build_exascript_python_tmp_cc/exaudflib cd build_exascript_python_tmp_cc @@ -16,7 +16,7 @@ genrule( genrule( name = "exascript_python_tmp_h", cmd = """ - INCLUDES=`$$PYTHON3_PREFIX/bin/$$PYTHON3_VERSION-dbg-config --includes` + INCLUDES=`$$PYTHON3_PREFIX/bin/$$PYTHON3_VERSION-config --includes` mkdir build_exascript_python_tmp_h cp "$(location //exaudflib:swig/script_data_transfer_objects_wrapper.h)" "$(location //exaudflib:exascript.i)" build_exascript_python_tmp_h cp "$(location exascript_python_tmp.cc)" "$(location exascript_python.py)" build_exascript_python_tmp_h @@ -79,7 +79,8 @@ genrule( cc_library( name = "exascript_python", - copts = ["-DPy_TRACE_REFS=1", "-DPy_DEBUG=1"], + #copts = ["-DPy_TRACE_REFS=1", "-DPy_DEBUG=1"], + copts = ["-DPy_DEBUG=1"], srcs = [":filter_swig_code_exascript_python_cc",":filter_swig_code_exascript_python_h"], hdrs = [":filter_swig_code_exascript_python_h"], deps = ["@python3//:python3","//exaudflib:exaudflib-deps","//exaudflib:header"], @@ -90,7 +91,8 @@ cc_library( name = "pythoncontainer", srcs = ["//python:pythoncontainer.cc", ":dummy.h"], data = [":extend_exascript_python_preset_py"], - copts = ["-DPy_TRACE_REFS=1", "-DPy_DEBUG=1"], + #copts = ["-DPy_TRACE_REFS=1", "-DPy_DEBUG=1"], + copts = ["-DPy_DEBUG=1"], hdrs = [":exascript_python_int", ":filter_swig_code_exascript_python_h"], include_prefix = ".", deps = ["@python3//:python3",":exascript_python","//exaudflib:header", @@ -102,6 +104,7 @@ cc_library( genrule( name = "dummy", cmd = 'touch "$@"', + outs = ["dummy.h"], srcs = [":pyextdataframe.so"], ) @@ -109,7 +112,8 @@ genrule( cc_binary( name = "pyextdataframe.so", linkshared = 1, - copts = ["-DPy_TRACE_REFS=1", "-DPy_DEBUG=1"], + #copts = ["-DPy_TRACE_REFS=1", "-DPy_DEBUG=1"], + copts = ["-DPy_DEBUG=1"], srcs = [":python_ext_dataframe.cc"], deps = ["@python3//:python3","@numpy//:numpy", "//exaudflib:header", "//:debug_message_h"], diff --git a/exaudfclient/base/python/python3/python_ext_dataframe.cc b/exaudfclient/base/python/python3/python_ext_dataframe.cc index 36f0fffdb..eb729aaa3 100644 --- a/exaudfclient/base/python/python3/python_ext_dataframe.cc +++ b/exaudfclient/base/python/python3/python_ext_dataframe.cc @@ -134,7 +134,7 @@ inline void checkPyObjectIsNull(const PyObject *obj, const std::string& error_co struct PyUniquePtrDeleter { void operator()(PyObject *obj) const noexcept { - Py_XDECREF(obj); + Py_CLEAR(obj); } }; @@ -523,6 +523,7 @@ inline void getColumnArrays(PyObject *colArray, int numCols, int numRows, if (colTypes[c].second == NPY_OBJECT) { + DBGMSG(std::cerr, "getColumnArrays: is a NPY_OBJECT"); // Convert numpy array to python list PyPtr pyList(PyObject_CallMethod(array.get(), "tolist", NULL)); if (!PyList_Check(pyList.get())) { @@ -558,10 +559,10 @@ inline void getColumnArrays(PyObject *colArray, int numCols, int numRows, throw std::runtime_error(ss.str().c_str()); } - columnArrays.push_back(std::move(pyList)); +// columnArrays.push_back(std::move(pyList)); } else if (colTypes[c].second == NPY_DATETIME) { - + DBGMSG(std::cerr, "getColumnArrays: is a NPY_DATETIME"); // Convert numpy array to python list PyPtr pyList(PyObject_CallMethod(array.get(), "tolist", NULL)); @@ -575,6 +576,7 @@ inline void getColumnArrays(PyObject *colArray, int numCols, int numRows, columnArrays.push_back(std::move(pyList)); } else { + DBGMSG(std::cerr, "getColumnArrays: is anything else"); PyPtr asType (PyObject_GetAttrString(array.get(), "astype")); PyPtr keywordArgs(PyDict_New()); PyDict_SetItemString(keywordArgs.get(), "copy", Py_False); @@ -597,6 +599,7 @@ inline void handleEmitNpyUint64( PyPtr& pyValue, PyPtr& pyResult, PyPtr& pySetNullMethodName){ + DBG_FUNC_BEGIN(std::cerr); int64_t value = *((int64_t*)PyArray_GETPTR1((PyArrayObject*)(columnArrays[c].get()), r)); if (npy_isnan(value)) { pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pySetNullMethodName.get(), pyColSetMethods[c].first.get(), NULL)); @@ -622,6 +625,7 @@ inline void handleEmitNpyUint64( } checkPyPtrIsNull(pyValue); pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pyColSetMethods[c].second.get(), pyColSetMethods[c].first.get(), pyValue.get(), NULL)); + DBG_FUNC_END(std::cerr); } inline void handleEmitNpyUint32( @@ -634,6 +638,7 @@ inline void handleEmitNpyUint32( PyPtr& pyValue, PyPtr& pyResult, PyPtr& pySetNullMethodName){ + DBG_FUNC_BEGIN(std::cerr); int32_t value = *((int32_t*)PyArray_GETPTR1((PyArrayObject*)(columnArrays[c].get()), r)); if (npy_isnan(value)) { pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pySetNullMethodName.get(), pyColSetMethods[c].first.get(), NULL)); @@ -659,6 +664,7 @@ inline void handleEmitNpyUint32( } checkPyPtrIsNull(pyValue); pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pyColSetMethods[c].second.get(), pyColSetMethods[c].first.get(), pyValue.get(), NULL)); + DBG_FUNC_END(std::cerr); } inline void handleEmitNpyUint16( @@ -671,6 +677,7 @@ inline void handleEmitNpyUint16( PyPtr& pyValue, PyPtr& pyResult, PyPtr& pySetNullMethodName){ + DBG_FUNC_BEGIN(std::cerr); int16_t value = *((int16_t*)PyArray_GETPTR1((PyArrayObject*)(columnArrays[c].get()), r)); if (npy_isnan(value)) { pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pySetNullMethodName.get(), pyColSetMethods[c].first.get(), NULL)); @@ -696,6 +703,7 @@ inline void handleEmitNpyUint16( } checkPyPtrIsNull(pyValue); pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pyColSetMethods[c].second.get(), pyColSetMethods[c].first.get(), pyValue.get(), NULL)); + DBG_FUNC_END(std::cerr); } inline void handleEmitNpyUint8( @@ -708,6 +716,7 @@ inline void handleEmitNpyUint8( PyPtr& pyValue, PyPtr& pyResult, PyPtr& pySetNullMethodName){ + DBG_FUNC_BEGIN(std::cerr); int8_t value = *((int8_t*)PyArray_GETPTR1((PyArrayObject*)(columnArrays[c].get()), r)); if (npy_isnan(value)) { pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pySetNullMethodName.get(), pyColSetMethods[c].first.get(), NULL)); @@ -733,6 +742,7 @@ inline void handleEmitNpyUint8( } checkPyPtrIsNull(pyValue); pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pyColSetMethods[c].second.get(), pyColSetMethods[c].first.get(), pyValue.get(), NULL)); + DBG_FUNC_END(std::cerr); } inline void handleEmitNpyFloat64( @@ -745,31 +755,38 @@ inline void handleEmitNpyFloat64( PyPtr& pyValue, PyPtr& pyResult, PyPtr& pySetNullMethodName){ - double value = *((double*)PyArray_GETPTR1((PyArrayObject*)(columnArrays[c].get()), r)); + DBG_FUNC_BEGIN(std::cerr); + double value = 1.0;//*((double*)PyArray_GETPTR1((PyArrayObject*)(columnArrays[c].get()), r)); if (npy_isnan(value)) { pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pySetNullMethodName.get(), pyColSetMethods[c].first.get(), NULL)); + DBGMSG(std::cerr, "handleEmitNpyFloat64: value is NaN"); return; } - switch (colInfo[c].type) { - case SWIGVMContainers::INT64: - case SWIGVMContainers::INT32: - pyValue.reset(PyLong_FromLong(static_cast(value))); - break; - case SWIGVMContainers::NUMERIC: - pyValue.reset(PyUnicode_FromString(std::to_string(value).c_str())); - break; - case SWIGVMContainers::DOUBLE: - pyValue.reset(PyFloat_FromDouble(value)); - break; - default: - { - std::stringstream ss; - ss << "F-UDF-CL-SL-PYTHON-1062: emit column " << c << " of type " << emitTypeMap.at(colInfo[c].type) << " but data given have type " << colTypes[c].first; - throw std::runtime_error(ss.str().c_str()); - } - } +// switch (colInfo[c].type) { +// case SWIGVMContainers::INT64: +// case SWIGVMContainers::INT32: +// DBGMSG(std::cerr, "handleEmitNpyFloat64: value is INT64/INT32"); +// pyValue.reset(PyLong_FromLong(static_cast(value))); +// break; +// case SWIGVMContainers::NUMERIC: +// DBGMSG(std::cerr, "handleEmitNpyFloat64: value is NUMERIC"); +// pyValue.reset(PyUnicode_FromString(std::to_string(value).c_str())); +// break; +// case SWIGVMContainers::DOUBLE: +// DBGMSG(std::cerr, "handleEmitNpyFloat64: value is DOUBLE"); +// pyValue.reset(PyFloat_FromDouble(value)); +// break; +// default: +// { +// std::stringstream ss; +// ss << "F-UDF-CL-SL-PYTHON-1062: emit column " << c << " of type " << emitTypeMap.at(colInfo[c].type) << " but data given have type " << colTypes[c].first; +// throw std::runtime_error(ss.str().c_str()); +// } +// } checkPyPtrIsNull(pyValue); - pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pyColSetMethods[c].second.get(), pyColSetMethods[c].first.get(), pyValue.get(), NULL)); + PyObject *resObj = PyObject_CallMethodObjArgs(resultHandler, pyColSetMethods[c].second.get(), pyColSetMethods[c].first.get(), pyValue.get(), NULL); + Py_CLEAR(resObj); + DBG_FUNC_END(std::cerr); } inline void handleEmitNpyFloat32( @@ -782,6 +799,7 @@ inline void handleEmitNpyFloat32( PyPtr& pyValue, PyPtr& pyResult, PyPtr& pySetNullMethodName){ + DBG_FUNC_BEGIN(std::cerr); double value = *((float*)PyArray_GETPTR1((PyArrayObject*)(columnArrays[c].get()), r)); if (npy_isnan(value)) { pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pySetNullMethodName.get(), pyColSetMethods[c].first.get(), NULL)); @@ -807,6 +825,7 @@ inline void handleEmitNpyFloat32( } checkPyPtrIsNull(pyValue); pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pyColSetMethods[c].second.get(), pyColSetMethods[c].first.get(), pyValue.get(), NULL)); + DBG_FUNC_END(std::cerr); } inline void handleEmitNpyBool( @@ -819,6 +838,7 @@ inline void handleEmitNpyBool( PyPtr& pyValue, PyPtr& pyResult, PyPtr& pySetNullMethodName){ + DBG_FUNC_BEGIN(std::cerr); bool value = *((bool*)PyArray_GETPTR1((PyArrayObject*)(columnArrays[c].get()), r)); if (npy_isnan(value)) { pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pySetNullMethodName.get(), pyColSetMethods[c].first.get(), NULL)); @@ -844,6 +864,7 @@ inline void handleEmitNpyBool( } checkPyPtrIsNull(pyValue); pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pyColSetMethods[c].second.get(), pyColSetMethods[c].first.get(), pyValue.get(), NULL)); + DBG_FUNC_END(std::cerr); } inline void handleEmitPyBool( @@ -856,6 +877,7 @@ inline void handleEmitPyBool( PyPtr& pyValue, PyPtr& pyResult, PyPtr& pySetNullMethodName){ + DBG_FUNC_BEGIN(std::cerr); PyPtr pyBool(PyList_GetItem(columnArrays[c].get(), r)); checkPyPtrIsNull(pyBool); if (isNoneOrNA(pyBool.get())) { @@ -885,6 +907,7 @@ inline void handleEmitPyBool( } checkPyPtrIsNull(pyValue); pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pyColSetMethods[c].second.get(), pyColSetMethods[c].first.get(), pyValue.get(), NULL)); + DBG_FUNC_END(std::cerr); } inline void handleEmitPyInt( @@ -897,6 +920,7 @@ inline void handleEmitPyInt( PyPtr& pyValue, PyPtr& pyResult, PyPtr& pySetNullMethodName){ + DBG_FUNC_BEGIN(std::cerr); PyPtr pyInt(PyList_GetItem(columnArrays[c].get(), r)); checkPyPtrIsNull(pyInt); if (isNoneOrNA(pyInt.get())) { @@ -928,6 +952,7 @@ inline void handleEmitPyInt( } } pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pyColSetMethods[c].second.get(), pyColSetMethods[c].first.get(), pyValue.get(), NULL)); + DBG_FUNC_END(std::cerr); } inline void handleEmitPyFloat( @@ -940,6 +965,7 @@ inline void handleEmitPyFloat( PyPtr& pyValue, PyPtr& pyResult, PyPtr& pySetNullMethodName){ + DBG_FUNC_BEGIN(std::cerr); PyPtr pyFloat(PyList_GetItem(columnArrays[c].get(), r)); checkPyPtrIsNull(pyFloat); if (isNoneOrNA(pyFloat.get())) { @@ -976,6 +1002,7 @@ inline void handleEmitPyFloat( } } pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pyColSetMethods[c].second.get(), pyColSetMethods[c].first.get(), pyValue.get(), NULL)); + DBG_FUNC_END(std::cerr); } inline void handleEmitPyDecimal( @@ -991,6 +1018,7 @@ inline void handleEmitPyDecimal( PyPtr& pyIntMethodName, PyPtr& pyFloatMethodName ){ + DBG_FUNC_BEGIN(std::cerr); PyPtr pyDecimal(PyList_GetItem(columnArrays[c].get(), r)); if (isNoneOrNA(pyDecimal.get())) { pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pySetNullMethodName.get(), pyColSetMethods[c].first.get(), NULL)); @@ -1022,6 +1050,7 @@ inline void handleEmitPyDecimal( } } pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pyColSetMethods[c].second.get(), pyColSetMethods[c].first.get(), pyValue.get(), NULL)); + DBG_FUNC_END(std::cerr); } inline void handleEmitPyStr( @@ -1034,7 +1063,7 @@ inline void handleEmitPyStr( PyPtr& pyValue, PyPtr& pyResult, PyPtr& pySetNullMethodName){ - + DBG_FUNC_END(std::cerr); PyPtr pyString(PyList_GetItem(columnArrays[c].get(), r)); if (isNoneOrNA(pyString.get())) { pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pySetNullMethodName.get(), pyColSetMethods[c].first.get(), NULL)); @@ -1062,6 +1091,7 @@ inline void handleEmitPyStr( throw std::runtime_error(ss.str().c_str()); } } + DBG_FUNC_END(std::cerr); } inline void handleEmitPyDate( @@ -1075,6 +1105,7 @@ inline void handleEmitPyDate( PyPtr& pyResult, PyPtr& pySetNullMethodName, PyPtr& pyIsoformatMethodName){ + DBG_FUNC_END(std::cerr); PyPtr pyDate(PyList_GetItem(columnArrays[c].get(), r)); if (isNoneOrNA(pyDate.get())) { pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pySetNullMethodName.get(), pyColSetMethods[c].first.get(), NULL)); @@ -1095,6 +1126,7 @@ inline void handleEmitPyDate( throw std::runtime_error(ss.str().c_str()); } } + DBG_FUNC_END(std::cerr); } inline void handleEmitPyTimestamp( int c, int r, @@ -1106,6 +1138,7 @@ inline void handleEmitPyTimestamp( PyPtr& pyValue, PyPtr& pyResult, PyPtr& pySetNullMethodName){ + DBG_FUNC_END(std::cerr); PyPtr pyTimestamp(PyList_GetItem(columnArrays[c].get(), r)); if (isNoneOrNA(pyTimestamp.get())) { pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pySetNullMethodName.get(), pyColSetMethods[c].first.get(), NULL)); @@ -1131,6 +1164,7 @@ inline void handleEmitPyTimestamp( throw std::runtime_error(ss.str().c_str()); } } + DBG_FUNC_END(std::cerr); } @@ -1145,6 +1179,7 @@ inline void handleEmitNpyDateTime( PyPtr& pyResult, PyPtr& pySetNullMethodName, PyPtr& pdNaT){ + DBG_FUNC_END(std::cerr); PyPtr pyTimestamp(PyList_GetItem(columnArrays[c].get(), r)); if (pyTimestamp.get() == pdNaT.get()) { pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pySetNullMethodName.get(), pyColSetMethods[c].first.get(), NULL)); @@ -1166,13 +1201,14 @@ inline void handleEmitNpyDateTime( throw std::runtime_error(ss.str().c_str()); } } + DBG_FUNC_END(std::cerr); } void emit(PyObject *resultHandler, std::vector& colInfo, PyObject *dataframe, PyObject *numpyTypes) { std::vector> pyColSetMethods; try{ - getColumnSetMethods(colInfo, pyColSetMethods); + //getColumnSetMethods(colInfo, pyColSetMethods); } catch (std::exception& err){ throw std::runtime_error("F-UDF-CL-SL-PYTHON-1133: "+std::string(err.what())); } @@ -1189,7 +1225,6 @@ void emit(PyObject *resultHandler, std::vector& colInfo, PyObject *d PyPtr data; - PyArrayObject *pyArray; PyPtr colArray; if(colTypes.size()==1 && colTypes.at(0).second == NPY_DATETIME){ // if we get an dataframe with a single datetime column with type datetime[ns], @@ -1200,7 +1235,8 @@ void emit(PyObject *resultHandler, std::vector& colInfo, PyObject *d // slice out the datetime column, which then will be an Array of pandas.Timestamp objects PyPtr resetIndex(PyObject_CallMethod(dataframe, "reset_index", NULL)); data=PyPtr(PyObject_GetAttrString(resetIndex.get(), "values")); - pyArray = reinterpret_cast(PyArray_FROM_OTF(data.get(), NPY_OBJECT, NPY_ARRAY_IN_ARRAY)); + PyPtr pyArrayObj(PyArray_FROM_OTF(data.get(), NPY_OBJECT, NPY_ARRAY_IN_ARRAY)); + PyArrayObject *pyArray = reinterpret_cast(pyArrayObj.get()); numRows = PyArray_DIM(pyArray, 0); numCols = PyArray_DIM(pyArray, 1)-1; // Transpose to column-major @@ -1214,10 +1250,12 @@ void emit(PyObject *resultHandler, std::vector& colInfo, PyObject *d }else{ data=PyPtr(PyObject_GetAttrString(dataframe, "values")); - pyArray = reinterpret_cast(PyArray_FROM_OTF(data.get(), NPY_OBJECT, NPY_ARRAY_IN_ARRAY)); + PyPtr pyArrayObj(PyArray_FROM_OTF(data.get(), NPY_OBJECT, NPY_ARRAY_IN_ARRAY)); + PyArrayObject *pyArray = reinterpret_cast(pyArrayObj.get()); + numRows = PyArray_DIM(pyArray, 0); numCols = PyArray_DIM(pyArray, 1); - // Transpose to column-major + //Transpose to column-major colArray = PyPtr(PyArray_Transpose(pyArray, NULL)); } @@ -1229,144 +1267,147 @@ void emit(PyObject *resultHandler, std::vector& colInfo, PyObject *d throw std::runtime_error("F-UDF-CL-SL-PYTHON-1135: "+std::string(err.what())); } - try{ - PyPtr pySetNullMethodName(PyUnicode_FromString("setNull")); - PyPtr pyNextMethodName(PyUnicode_FromString("next")); - PyPtr pyCheckExceptionMethodName(PyUnicode_FromString("checkException")); - PyPtr pyIntMethodName(PyUnicode_FromString("__int__")); - PyPtr pyFloatMethodName(PyUnicode_FromString("__float__")); - PyPtr pyIsoformatMethodName(PyUnicode_FromString("isoformat")); - PyPtr pdNaT(PyObject_GetAttrString(pandasModule.get(), "NaT")); - - // Emit data - PyPtr pyValue; - PyPtr pyResult; - for (int r = 0; r < numRows; r++) { - for (int c = 0; c < numCols; c++) { - switch (colTypes[c].second) { - case NPY_INT64: - case NPY_UINT64: - { - handleEmitNpyUint64(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, pySetNullMethodName); - break; - } - case NPY_INT32: - case NPY_UINT32: - { - handleEmitNpyUint32(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, pySetNullMethodName); - break; - } - case NPY_INT16: - case NPY_UINT16: - { - handleEmitNpyUint16(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, pySetNullMethodName); - break; - } - case NPY_INT8: - case NPY_UINT8: - { - handleEmitNpyUint8(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, pySetNullMethodName); - break; - } - case NPY_FLOAT64: - { - handleEmitNpyFloat64(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, pySetNullMethodName); - break; - } - case NPY_FLOAT32: - { - handleEmitNpyFloat32(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, pySetNullMethodName); - break; - } - case NPY_BOOL: - { - handleEmitNpyBool(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, pySetNullMethodName); - break; - } - case PY_BOOL: - { - handleEmitPyBool(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, pySetNullMethodName); - break; - } - case PY_INT: - { - handleEmitPyInt(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, pySetNullMethodName); - break; - } - case PY_FLOAT: - { - handleEmitPyFloat(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, pySetNullMethodName); - break; - } - case PY_DECIMAL: - { - handleEmitPyDecimal(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, - pySetNullMethodName, pyIntMethodName, pyFloatMethodName); - break; - } - case PY_STR: - { - handleEmitPyStr(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, pySetNullMethodName); - break; - } - case PY_DATE: - { - handleEmitPyDate(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, - pySetNullMethodName, pyIsoformatMethodName); - break; - } - case PY_TIMESTAMP: - { - handleEmitPyTimestamp(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, - pySetNullMethodName); - break; - } - case NPY_DATETIME: - { - handleEmitNpyDateTime(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, - pySetNullMethodName, pdNaT); - break; - } - case PY_NONETYPE: - { - pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pySetNullMethodName.get(), pyColSetMethods[c].first.get(), NULL)); - break; - } - default: - { - std::stringstream ss; - ss << "F-UDF-CL-SL-PYTHON-1073: emit: unexpected type: " << colTypes[c].first; - throw std::runtime_error(ss.str().c_str()); - } - } - - if (!pyResult) { - PyObject *ptype, *pvalue, *ptraceback; - PyErr_Fetch(&ptype, &pvalue, &ptraceback); - if (pvalue) { - std::stringstream ss; - ss << "F-UDF-CL-SL-PYTHON-1074: emit(): Error setting value for row " << r << ", column " << c << ": "; - ss << PyUnicode_AsUTF8(pvalue); - throw std::runtime_error(ss.str().c_str()); - } - } - - PyPtr pyCheckException(PyObject_CallMethodObjArgs(resultHandler, pyCheckExceptionMethodName.get(), NULL)); - if (pyCheckException.get() != Py_None) { - const char *exMsg = PyUnicode_AsUTF8(pyCheckException.get()); - if (exMsg) { - std::stringstream ss; - ss << "F-UDF-CL-SL-PYTHON-1075: emit(): " << exMsg; - throw std::runtime_error(ss.str().c_str()); - } - } - } - - PyPtr pyNext(PyObject_CallMethodObjArgs(resultHandler, pyNextMethodName.get(), NULL)); - } - }catch (std::exception& err){ - throw std::runtime_error("F-UDF-CL-SL-PYTHON-1136: "+std::string(err.what())); - } +// try{ +// PyPtr pySetNullMethodName(PyUnicode_FromString("setNull")); +// PyPtr pyNextMethodName(PyUnicode_FromString("next")); +// PyPtr pyCheckExceptionMethodName(PyUnicode_FromString("checkException")); +// PyPtr pyIntMethodName(PyUnicode_FromString("__int__")); +// PyPtr pyFloatMethodName(PyUnicode_FromString("__float__")); +// PyPtr pyIsoformatMethodName(PyUnicode_FromString("isoformat")); +// PyPtr pdNaT(PyObject_GetAttrString(pandasModule.get(), "NaT")); +// +// // Emit data +// PyPtr pyValue(PyLong_FromLong(static_cast(1))); +// PyPtr pyResult; +// for (int r = 0; r < numRows; r++) { +// for (int c = 0; c < numCols; c++) { +// switch (colTypes[c].second) { +// case NPY_INT64: +// case NPY_UINT64: +// { +// handleEmitNpyUint64(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, pySetNullMethodName); +// break; +// } +// case NPY_INT32: +// case NPY_UINT32: +// { +// handleEmitNpyUint32(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, pySetNullMethodName); +// break; +// } +// case NPY_INT16: +// case NPY_UINT16: +// { +// handleEmitNpyUint16(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, pySetNullMethodName); +// break; +// } +// case NPY_INT8: +// case NPY_UINT8: +// { +// handleEmitNpyUint8(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, pySetNullMethodName); +// break; +// } +// case NPY_FLOAT64: +// { +// //handleEmitNpyFloat64(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, pySetNullMethodName); +// //PyObject *resObj = PyObject_CallMethodObjArgs(resultHandler, pyColSetMethods[c].second.get(), pyColSetMethods[c].first.get(), pyValue.get(), NULL); +// //Py_CLEAR(resObj); +// +// break; +// } +// case NPY_FLOAT32: +// { +// handleEmitNpyFloat32(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, pySetNullMethodName); +// break; +// } +// case NPY_BOOL: +// { +// handleEmitNpyBool(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, pySetNullMethodName); +// break; +// } +// case PY_BOOL: +// { +// handleEmitPyBool(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, pySetNullMethodName); +// break; +// } +// case PY_INT: +// { +// handleEmitPyInt(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, pySetNullMethodName); +// break; +// } +// case PY_FLOAT: +// { +// handleEmitPyFloat(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, pySetNullMethodName); +// break; +// } +// case PY_DECIMAL: +// { +// handleEmitPyDecimal(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, +// pySetNullMethodName, pyIntMethodName, pyFloatMethodName); +// break; +// } +// case PY_STR: +// { +// handleEmitPyStr(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, pySetNullMethodName); +// break; +// } +// case PY_DATE: +// { +// handleEmitPyDate(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, +// pySetNullMethodName, pyIsoformatMethodName); +// break; +// } +// case PY_TIMESTAMP: +// { +// handleEmitPyTimestamp(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, +// pySetNullMethodName); +// break; +// } +// case NPY_DATETIME: +// { +// handleEmitNpyDateTime(c, r, columnArrays, pyColSetMethods, colInfo, colTypes, resultHandler, pyValue, pyResult, +// pySetNullMethodName, pdNaT); +// break; +// } +// case PY_NONETYPE: +// { +// pyResult.reset(PyObject_CallMethodObjArgs(resultHandler, pySetNullMethodName.get(), pyColSetMethods[c].first.get(), NULL)); +// break; +// } +// default: +// { +// std::stringstream ss; +// ss << "F-UDF-CL-SL-PYTHON-1073: emit: unexpected type: " << colTypes[c].first; +// throw std::runtime_error(ss.str().c_str()); +// } +// } +// +// if (!pyResult) { +// PyObject *ptype, *pvalue, *ptraceback; +// PyErr_Fetch(&ptype, &pvalue, &ptraceback); +// if (pvalue) { +// std::stringstream ss; +// ss << "F-UDF-CL-SL-PYTHON-1074: emit(): Error setting value for row " << r << ", column " << c << ": "; +// ss << PyUnicode_AsUTF8(pvalue); +// throw std::runtime_error(ss.str().c_str()); +// } +// } +// +// PyPtr pyCheckException(PyObject_CallMethodObjArgs(resultHandler, pyCheckExceptionMethodName.get(), NULL)); +// if (pyCheckException.get() != Py_None) { +// const char *exMsg = PyUnicode_AsUTF8(pyCheckException.get()); +// if (exMsg) { +// std::stringstream ss; +// ss << "F-UDF-CL-SL-PYTHON-1075: emit(): " << exMsg; +// throw std::runtime_error(ss.str().c_str()); +// } +// } +// } + + //PyPtr pyNext(PyObject_CallMethodObjArgs(resultHandler, pyNextMethodName.get(), NULL)); +// } +// }catch (std::exception& err){ +// throw std::runtime_error("F-UDF-CL-SL-PYTHON-1136: "+std::string(err.what())); +// } } PyObject *createDataFrame(PyObject *data, std::vector& colInfo) diff --git a/exaudfclient/base/python_repository.bzl b/exaudfclient/base/python_repository.bzl index b710c5b89..c1e9940f2 100644 --- a/exaudfclient/base/python_repository.bzl +++ b/exaudfclient/base/python_repository.bzl @@ -19,7 +19,7 @@ def _get_sysconfig_value(binary,key,p_repository_ctx): def _get_include_dir(binary,version,p_repository_ctx): key = "INCLUDEDIR" base_include_dir = _get_sysconfig_value(binary,key,p_repository_ctx) #example: /usr/include - include_dir = base_include_dir+"/"+version #example /usr/include/python3.8 + include_dir = base_include_dir+"/"+version #example /usr/include/python3.8 print("python {key}: {include_dir}".format(key=key, include_dir=include_dir)) return include_dir diff --git a/flavors/template-Exasol-all-python-3.10/flavor_base/language_deps/Dockerfile b/flavors/template-Exasol-all-python-3.10/flavor_base/language_deps/Dockerfile index 1e2b514a9..68f5b1853 100644 --- a/flavors/template-Exasol-all-python-3.10/flavor_base/language_deps/Dockerfile +++ b/flavors/template-Exasol-all-python-3.10/flavor_base/language_deps/Dockerfile @@ -8,8 +8,8 @@ RUN /scripts/install_scripts/install_via_apt.pl --file /build_info/packages/lang RUN /scripts/install_scripts/install_python3.10_pip.sh "pip == 21.3.1" COPY language_deps/packages/python3_pip_packages /build_info/packages/language_deps -RUN /scripts/install_scripts/install_via_pip.pl --file /build_info/packages/language_deps/python3_pip_packages --python-binary python3 --with-versions +RUN /scripts/install_scripts/install_via_pip.pl --file /build_info/packages/language_deps/python3_pip_packages --python-binary python3.10d --with-versions ENV PYTHON3_PREFIX /usr -ENV PYTHON3_VERSION python3.10 +ENV PYTHON3_VERSION python3.10d diff --git a/flavors/template-Exasol-all-python-3.10/flavor_base/language_deps/packages/apt_get_packages b/flavors/template-Exasol-all-python-3.10/flavor_base/language_deps/packages/apt_get_packages index e21dabd38..dc9d610a9 100644 --- a/flavors/template-Exasol-all-python-3.10/flavor_base/language_deps/packages/apt_get_packages +++ b/flavors/template-Exasol-all-python-3.10/flavor_base/language_deps/packages/apt_get_packages @@ -1,4 +1,6 @@ ca-certificates|20230311ubuntu0.22.04.1 python3.10-dbg|3.10.12-1~22.04.3 +libpython3-dbg|3.10.4-0ubuntu2 +libpython3-dev|3.10.4-0ubuntu2 python3-distutils|3.10.8-1~22.04 curl|7.81.0-1ubuntu1.16 diff --git a/flavors/template-Exasol-all-python-3.10/flavor_base/language_deps/packages/python3_pip_packages b/flavors/template-Exasol-all-python-3.10/flavor_base/language_deps/packages/python3_pip_packages index 63697c0e3..869e34054 100644 --- a/flavors/template-Exasol-all-python-3.10/flavor_base/language_deps/packages/python3_pip_packages +++ b/flavors/template-Exasol-all-python-3.10/flavor_base/language_deps/packages/python3_pip_packages @@ -1,3 +1,3 @@ pandas|2.2.2 numpy|1.26.4 -pyarrow|16.0.0 +pyarrow|16.0.0 \ No newline at end of file