Skip to content

Commit

Permalink
Build with and without NumPy support
Browse files Browse the repository at this point in the history
This commit successfully builds `pyodbc` with and without NumPy support.
If NumPy is installed as an optional dependency, then you can retrieve
results from a database as NumPy arrays. If NumPy is not installed as an
optional dependency, then an error is given to the user indicating that
NumPy cannot be found.

- `setup.py` removes the `WITH_NUMPY` macro. `pyodbc` is set to build
  with NumPy support, as indicated in the `pyproject.toml` file. All
  references to this macro have also been removed in the C++ code.
- `src/cursor.cpp` removes the guards for allowing the `fetchdictarray`,
  on the cursor object, which is the way a user gets NumPy array objects
  back. It also aligns the objects in the `Cursor_methods` object.
- `src/npcontainer.cpp` removes NumPy build guards, moves the
  initialization of NumPy (with the import_array() macro).
- `src/npcontainer.h` removes unused guards.
- `src/pyodbcmodule.cpp` removes unused NumPy guards.
  • Loading branch information
ndmlny-qs committed Oct 20, 2023
1 parent 427f08f commit c341d13
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 45 deletions.
1 change: 0 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ def get_compiler_settings():
'define_macros': [('PYODBC_VERSION', VERSION)]
}
settings['include_dirs'].append(numpy.get_include())
settings['define_macros'].append(('WITH_NUMPY', '1'))

if os.name == 'nt':
settings['extra_compile_args'].extend([
Expand Down
12 changes: 5 additions & 7 deletions src/cursor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@
#include "dbspecific.h"
#include <datetime.h>

#ifdef WITH_NUMPY
#include "npcontainer.h"
#endif

inline bool StatementIsValid(Cursor* cursor)
{
Expand Down Expand Up @@ -2391,9 +2389,7 @@ static PyMethodDef Cursor_methods[] =
{ "fetchone", (PyCFunction)Cursor_fetchone, METH_NOARGS, fetchone_doc },
{ "fetchall", (PyCFunction)Cursor_fetchall, METH_NOARGS, fetchall_doc },
{ "fetchmany", (PyCFunction)Cursor_fetchmany, METH_VARARGS, fetchmany_doc },
#ifdef WITH_NUMPY
{ "fetchdictarray", (PyCFunction)Cursor_fetchdictarray, METH_VARARGS|METH_KEYWORDS, fetchdictarray_doc },
#endif
{ "nextset", (PyCFunction)Cursor_nextset, METH_NOARGS, nextset_doc },
{ "tables", (PyCFunction)Cursor_tables, METH_VARARGS|METH_KEYWORDS, tables_doc },
{ "columns", (PyCFunction)Cursor_columns, METH_VARARGS|METH_KEYWORDS, columns_doc },
Expand All @@ -2408,12 +2404,14 @@ static PyMethodDef Cursor_methods[] =
{ "skip", (PyCFunction)Cursor_skip, METH_VARARGS, skip_doc },
{ "commit", (PyCFunction)Cursor_commit, METH_NOARGS, commit_doc },
{ "rollback", (PyCFunction)Cursor_rollback, METH_NOARGS, rollback_doc },
{"cancel", (PyCFunction)Cursor_cancel, METH_NOARGS, cancel_doc},
{"__enter__", Cursor_enter, METH_NOARGS, enter_doc },
{"__exit__", Cursor_exit, METH_VARARGS, exit_doc },
{ "cancel", (PyCFunction)Cursor_cancel, METH_NOARGS, cancel_doc},
{ "__enter__", Cursor_enter, METH_NOARGS, enter_doc },
{ "__exit__", Cursor_exit, METH_VARARGS, exit_doc },
{0, 0, 0, 0}
};



static char cursor_doc[] =
"Cursor objects represent a database cursor, which is used to manage the context\n" \
"of a fetch operation. Cursors created from the same connection are not\n" \
Expand Down
37 changes: 12 additions & 25 deletions src/npcontainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#include "errors.h"
#include "dbspecific.h"

#include "numpy/ndarrayobject.h"
#include "numpy/arrayobject.h"
#include "numpy/npy_math.h"

// exported variables ----------------------------------------------------------
Expand Down Expand Up @@ -1493,7 +1493,6 @@ perform_array_query(query_desc& result, Cursor* cur, npy_intp nrows, bool lower,
"Can't allocate result buffers");
}
}

return 0;
}

Expand Down Expand Up @@ -1587,6 +1586,10 @@ static char *Cursor_npfetch_kwnames[] = {
PyObject*
Cursor_fetchdictarray(PyObject* self, PyObject* args, PyObject *kwargs)
{
PyObject* numpy = PyImport_ImportModule("numpy");
if (!numpy) {
return 0;
}
Cursor* cursor = Cursor_Validate(self, CURSOR_REQUIRE_RESULTS | CURSOR_RAISE_ERROR);
if (!cursor)
return 0;
Expand All @@ -1609,6 +1612,12 @@ Cursor_fetchdictarray(PyObject* self, PyObject* args, PyObject *kwargs)
TRACE_NOLOC("\n\nCursor fetchdictarray\n\tnrows:%d\n\treturn_nulls:%s\n\tnull_suffix:%s\n\thandle:%p\n\tunicode_results:%s\n",
(int)nrows, preserve_nulls?"yes":"no", null_suffix, (void*)cursor->hstmt);
/*cursor->cnxn->unicode_results?"Yes":"No");*/

import_array();
if (PyArray_GetNDArrayCFeatureVersion() >= 7) {
CAN_USE_DATETIME = true;
}

npy_intp arg = nrows;
PyObject *rv = create_fill_dictarray(cursor, arg, preserve_nulls?null_suffix:0);
TRACE_NOLOC("\nCursor fetchdictarray done.\n\tdictarray: %p\n\n", rv);
Expand Down Expand Up @@ -1658,27 +1667,5 @@ char fetchdictarray_doc[] =
"See Also\n" \
"--------\n" \
"fetchmany : Fetch rows into a Python list of rows.\n" \
"fetchall : Fetch the remaining rows into a Python lis of rows.\n" \
"fetchall : Fetch the remaining rows into a Python list of rows.\n" \
"\n";


#if PY_VERSION_HEX >= 0x03000000
int NpContainer_init()
#else
void NpContainer_init()
#endif
{
import_array();
// If the version of Numpy is >= API 7 (Numpy 1.7),
// then enable datetime features. This allows datetime
// to work even if pyodbc is built against Numpy 1.5.
if (PyArray_GetNDArrayCFeatureVersion() >= 7) {
CAN_USE_DATETIME = true;
}

#if PY_VERSION_HEX >= 0x03000000
return 0;
#else
return;
#endif
}
7 changes: 0 additions & 7 deletions src/npcontainer.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
#ifndef _NPCONTAINER_H_
#define _NPCONTAINER_H_


#if PY_VERSION_HEX >= 0x03000000
int NpContainer_init();
#else
void NpContainer_init();
#endif

PyObject *Cursor_fetchdictarray(PyObject *self, PyObject *args, PyObject *kwargs);

extern char fetchdictarray_doc[];
Expand Down
5 changes: 0 additions & 5 deletions src/pyodbcmodule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@
#include <time.h>
#include <stdarg.h>

#ifdef WITH_NUMPY
#include "npcontainer.h"
#endif

static PyObject* MakeConnectionString(PyObject* existing, PyObject* parts);

Expand Down Expand Up @@ -281,9 +279,6 @@ static bool import_types()
if (!InitializeDecimal())
return false;

#ifdef WITH_NUMPY
NpContainer_init();
#endif
return true;
}

Expand Down

0 comments on commit c341d13

Please sign in to comment.