This is an automated email from the ASF dual-hosted git repository.

isapego pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new de11d33ff1 IGNITE-22747 Python Client: add tox.ini for CI/CD (#4289)
de11d33ff1 is described below

commit de11d33ff168f3f5df362b5dbf6e8a2068559c12
Author: Igor Sapego <[email protected]>
AuthorDate: Mon Sep 2 16:00:44 2024 +0400

    IGNITE-22747 Python Client: add tox.ini for CI/CD (#4289)
---
 modules/platforms/python/cpp_module/CMakeLists.txt |   3 +
 modules/platforms/python/cpp_module/module.cpp     | 131 +++++++++++----------
 .../platforms/python/cpp_module/py_connection.cpp  |   6 +-
 modules/platforms/python/cpp_module/py_cursor.cpp  |   6 +-
 modules/platforms/python/pyignite3/__init__.py     |  55 ++++-----
 modules/platforms/python/setup.py                  |   2 +-
 modules/platforms/python/tox.ini                   |  30 +++++
 7 files changed, 138 insertions(+), 95 deletions(-)

diff --git a/modules/platforms/python/cpp_module/CMakeLists.txt 
b/modules/platforms/python/cpp_module/CMakeLists.txt
index 4c08dcb220..bb7ca0cf6b 100644
--- a/modules/platforms/python/cpp_module/CMakeLists.txt
+++ b/modules/platforms/python/cpp_module/CMakeLists.txt
@@ -54,4 +54,7 @@ if (WIN32)
     set_target_properties(${TARGET} PROPERTIES SUFFIX ".pyd")
     target_link_libraries(${TARGET} ${Python3_LIBRARIES})
     remove_definitions(-DUNICODE=1)
+else()
+    set_target_properties(${TARGET} PROPERTIES PREFIX "")
 endif()
+
diff --git a/modules/platforms/python/cpp_module/module.cpp 
b/modules/platforms/python/cpp_module/module.cpp
index 1a068b0420..9a7223e21b 100644
--- a/modules/platforms/python/cpp_module/module.cpp
+++ b/modules/platforms/python/cpp_module/module.cpp
@@ -28,71 +28,10 @@
 #include <Python.h>
 
 
-PyObject* connect(PyObject* self, PyObject *args, PyObject* kwargs);
-
-static PyMethodDef methods[] = {
-    {"connect", (PyCFunction) connect, METH_VARARGS | METH_KEYWORDS, nullptr},
-    {nullptr, nullptr, 0, nullptr}       /* Sentinel */
-};
-
-static struct PyModuleDef module_def = {
-    PyModuleDef_HEAD_INIT,
-    MODULE_NAME,
-    nullptr,                /* m_doc */
-    -1,                     /* m_size */
-    methods,                /* m_methods */
-    nullptr,                /* m_slots */
-    nullptr,                /* m_traverse */
-    nullptr,                /* m_clear */
-    nullptr,                /* m_free */
-};
-
-PyMODINIT_FUNC PyInit__pyignite3_extension(void) { // 
NOLINT(*-reserved-identifier)
-    PyObject* mod;
-
-    mod = PyModule_Create(&module_def);
-    if (mod == nullptr)
-        return nullptr;
-
-    if (prepare_py_connection_type() || prepare_py_cursor_type())
-        return nullptr;
-
-    if (register_py_connection_type(mod) || register_py_cursor_type(mod))
-        return nullptr;
-
-    return mod;
-}
-
-bool check_errors(ignite::diagnosable& diag) {
-    auto &records = diag.get_diagnostic_records();
-    if (records.is_successful())
-        return true;
-
-    std::string err_msg;
-    switch (records.get_return_code()) {
-        case SQL_INVALID_HANDLE:
-            err_msg = "Invalid object handle";
-            break;
-
-        case SQL_NO_DATA:
-            err_msg = "No data available";
-            break;
-
-        case SQL_ERROR:
-            auto record = records.get_status_record(1);
-            err_msg = record.get_message_text();
-            break;
-    }
-
-    // TODO: IGNITE-22226 Set a proper error here, not a standard one.
-    PyErr_SetString(PyExc_RuntimeError, err_msg.c_str());
-
-    return false;
-}
-
 static PyObject* make_connection(std::unique_ptr<ignite::sql_environment> env,
-    std::unique_ptr<ignite::sql_connection> conn) {
-        auto pyignite3_mod = PyImport_ImportModule("pyignite3");
+    std::unique_ptr<ignite::sql_connection> conn)
+{
+    auto pyignite3_mod = PyImport_ImportModule("pyignite3");
 
     if (!pyignite3_mod)
         return nullptr;
@@ -124,7 +63,7 @@ static PyObject* 
make_connection(std::unique_ptr<ignite::sql_environment> env,
     return conn_obj;
 }
 
-static PyObject* connect(PyObject* self, PyObject* args, PyObject* kwargs) {
+static PyObject* pyignite3_connect(PyObject* self, PyObject* args, PyObject* 
kwargs) {
     static char *kwlist[] = {
         "address",
         "identity",
@@ -193,4 +132,66 @@ static PyObject* connect(PyObject* self, PyObject* args, 
PyObject* kwargs) {
     return make_connection(std::move(sql_env), std::move(sql_conn));
 }
 
+static PyMethodDef methods[] = {
+    {"connect", (PyCFunction)pyignite3_connect, METH_VARARGS | METH_KEYWORDS, 
nullptr},
+    {nullptr, nullptr, 0, nullptr}       /* Sentinel */
+};
+
+static struct PyModuleDef module_def = {
+    PyModuleDef_HEAD_INIT,
+    MODULE_NAME,
+    nullptr,                /* m_doc */
+    -1,                     /* m_size */
+    methods,                /* m_methods */
+    nullptr,                /* m_slots */
+    nullptr,                /* m_traverse */
+    nullptr,                /* m_clear */
+    nullptr,                /* m_free */
+};
+
+PyMODINIT_FUNC PyInit__pyignite3_extension(void) { // 
NOLINT(*-reserved-identifier)
+    PyObject* mod;
+
+    mod = PyModule_Create(&module_def);
+    if (mod == nullptr)
+        return nullptr;
+
+    if (prepare_py_connection_type() || prepare_py_cursor_type())
+        return nullptr;
+
+    if (register_py_connection_type(mod) || register_py_cursor_type(mod))
+        return nullptr;
+
+    return mod;
+}
+
+bool check_errors(ignite::diagnosable& diag) {
+    auto &records = diag.get_diagnostic_records();
+    if (records.is_successful())
+        return true;
+
+    std::string err_msg;
+    switch (records.get_return_code()) {
+        case SQL_INVALID_HANDLE:
+            err_msg = "Invalid object handle";
+            break;
+
+        case SQL_NO_DATA:
+            err_msg = "No data available";
+            break;
+
+        case SQL_ERROR:
+            auto record = records.get_status_record(1);
+            err_msg = record.get_message_text();
+            break;
+    }
+
+    // TODO: IGNITE-22226 Set a proper error here, not a standard one.
+    PyErr_SetString(PyExc_RuntimeError, err_msg.c_str());
+
+    return false;
+}
+
+
+
 
diff --git a/modules/platforms/python/cpp_module/py_connection.cpp 
b/modules/platforms/python/cpp_module/py_connection.cpp
index 2dd6bd82b8..3960b17032 100644
--- a/modules/platforms/python/cpp_module/py_connection.cpp
+++ b/modules/platforms/python/cpp_module/py_connection.cpp
@@ -110,7 +110,11 @@ int prepare_py_connection_type() {
 }
 
 int register_py_connection_type(PyObject* mod) {
-    return PyModule_AddObjectRef(mod, PY_CONNECTION_CLASS_NAME, (PyObject 
*)&py_connection_type);
+    auto res = PyModule_AddObject(mod, PY_CONNECTION_CLASS_NAME, (PyObject 
*)&py_connection_type);
+    if (res < 0) {
+        Py_DECREF((PyObject *)&py_connection_type);
+    }
+    return res;
 }
 
 py_connection *make_py_connection(std::unique_ptr<ignite::sql_environment> env,
diff --git a/modules/platforms/python/cpp_module/py_cursor.cpp 
b/modules/platforms/python/cpp_module/py_cursor.cpp
index d3f76871d6..39a4961eb4 100644
--- a/modules/platforms/python/cpp_module/py_cursor.cpp
+++ b/modules/platforms/python/cpp_module/py_cursor.cpp
@@ -299,7 +299,11 @@ int prepare_py_cursor_type() {
 }
 
 int register_py_cursor_type(PyObject* mod) {
-    return PyModule_AddObjectRef(mod, PY_CURSOR_CLASS_NAME, (PyObject 
*)&py_cursor_type);
+    auto res = PyModule_AddObject(mod, PY_CURSOR_CLASS_NAME, (PyObject 
*)&py_cursor_type);
+    if (res < 0) {
+        Py_DECREF((PyObject *)&py_cursor_type);
+    }
+    return res;
 }
 
 py_cursor *make_py_cursor(std::unique_ptr<ignite::sql_statement> stmt) {
diff --git a/modules/platforms/python/pyignite3/__init__.py 
b/modules/platforms/python/pyignite3/__init__.py
index fabe96ac62..e4a77113d8 100644
--- a/modules/platforms/python/pyignite3/__init__.py
+++ b/modules/platforms/python/pyignite3/__init__.py
@@ -45,33 +45,34 @@ UUID = uuid.UUID
 
 
 def type_code_from_int(native: int):
-    match native:
-        case native_type_code.NIL:
-            return NIL
-        case native_type_code.BOOLEAN:
-            return BOOLEAN
-        case native_type_code.INT8 | native_type_code.INT16 | 
native_type_code.INT32 | native_type_code.INT64:
-            return INT
-        case native_type_code.FLOAT | native_type_code.DOUBLE:
-            return FLOAT
-        case native_type_code.DECIMAL | native_type_code.NUMBER:
-            return NUMBER
-        case native_type_code.DATE:
-            return DATE
-        case native_type_code.TIME:
-            return TIME
-        case native_type_code.DATETIME | native_type_code.TIMESTAMP:
-            return DATETIME
-        case native_type_code.UUID:
-            return UUID
-        case native_type_code.BITMASK:
-            return INT
-        case native_type_code.STRING:
-            return STRING
-        case native_type_code.BYTE_ARRAY:
-            return BINARY
-        case native_type_code.PERIOD | native_type_code.DURATION:
-            return DATETIME
+    if native == native_type_code.NIL:
+        return NIL
+    elif native == native_type_code.BOOLEAN:
+        return BOOLEAN
+    elif (native == native_type_code.INT8 or native == native_type_code.INT16
+          or native == native_type_code.INT32 or native == 
native_type_code.INT64):
+        return INT
+    elif native == native_type_code.FLOAT or native == native_type_code.DOUBLE:
+        return FLOAT
+    elif native == native_type_code.DECIMAL or native == 
native_type_code.NUMBER:
+        return NUMBER
+    elif native == native_type_code.DATE:
+        return DATE
+    elif native == native_type_code.TIME:
+        return TIME
+    elif native == native_type_code.DATETIME or native == 
native_type_code.TIMESTAMP:
+        return DATETIME
+    elif native == native_type_code.UUID:
+        return UUID
+    elif native == native_type_code.BITMASK:
+        return INT
+    elif native == native_type_code.STRING:
+        return STRING
+    elif native == native_type_code.BYTE_ARRAY:
+        return BINARY
+    elif native == native_type_code.PERIOD or native == 
native_type_code.DURATION:
+        return DATETIME
+    raise InterfaceError(f'Unsupported data type: {native}')
 
 
 class ColumnDescription:
diff --git a/modules/platforms/python/setup.py 
b/modules/platforms/python/setup.py
index 9779d2e8b9..53628e5618 100644
--- a/modules/platforms/python/setup.py
+++ b/modules/platforms/python/setup.py
@@ -82,7 +82,7 @@ class CMakeBuild(build_ext):
         for ext in self.extensions:
             ext_dir = 
os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name)))
             cfg = 'Release'
-            ext_file = 
os.path.splitext(self.get_ext_filename(self.get_ext_fullname(ext.name)))[0]
+            ext_file = 
os.path.splitext(os.path.basename(self.get_ext_filename(ext.name)))[0]
 
             cmake_args = [
                 f'-DCMAKE_BUILD_TYPE={cfg}',
diff --git a/modules/platforms/python/tox.ini b/modules/platforms/python/tox.ini
new file mode 100644
index 0000000000..542da4c479
--- /dev/null
+++ b/modules/platforms/python/tox.ini
@@ -0,0 +1,30 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+[tox]
+skipsdist = True
+envlist = codestyle,py{37,38,39}
+
+[testenv]
+passenv = TEAMCITY_VERSION IGNITE_HOME
+envdir = {homedir}/.virtualenvs/pyignite3-{envname}
+deps =
+    -r ./requirements/install.txt
+    -r ./requirements/tests.txt
+recreate = True
+usedevelop = True
+commands =
+    pytest {env:PYTESTARGS:} {posargs}
+

Reply via email to