Stop using "probabilistic" to mean "weighted", etc
[xapian.git] / xapian-bindings / python / python.i
blob761edd5d691562777417c7406967327229103a88
1 %module(directors="1", moduleimport="from . import _xapian
2 from new import instancemethod as new_instancemethod") xapian
3 %{
4 /* python.i: SWIG interface file for the Python bindings
6 * Copyright (C) 2011,2012,2013,2015,2016,2018 Olly Betts
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
21 * USA
25 %pythonbegin %{
26 """
27 Xapian is a highly adaptable toolkit which allows developers to easily
28 add advanced indexing and search facilities to their own applications.
29 It has built-in support for several families of weighting models
30 and also supports a rich set of boolean query operators.
32 In addition to the doc strings provided by this python library, you
33 may wish to look at the library's overall documentation, either
34 installed along with the bindings or online at
35 <https://xapian.org/docs/bindings/python/>, as well as the library's
36 documentation, possibly installed with the library or with its
37 development files, or again online at <https://xapian.org/docs/>.
38 """
41 %begin %{
42 #include <config.h>
44 #ifdef __clang__
45 // The Python 2.7 headers have several uses of the C register keyword, which
46 // result in warnings from clang++ 6. There's nothing we can really do about
47 // them, so just suppress them.
48 # pragma clang diagnostic push
49 # pragma clang diagnostic ignored "-Wdeprecated-register"
50 #endif
52 #include <Python.h>
54 #ifdef __clang__
55 # pragma clang diagnostic pop
56 #endif
58 /* Override SWIG's standard GIL locking machinery - we want to avoid the
59 * overhead of thread locking when the user's code isn't using threads,
60 * and to handle the GIL in a way which also works in sub-interpreters.
62 #define SWIG_PYTHON_NO_USE_GIL
64 #ifdef THREAD_LOCAL
66 static THREAD_LOCAL PyThreadState * swig_pythreadstate = NULL;
68 inline void swig_pythreadstate_ensure_init() { }
70 inline PyThreadState * swig_pythreadstate_reset() {
71 PyThreadState * v = swig_pythreadstate;
72 if (v) swig_pythreadstate = NULL;
73 return v;
76 inline PyThreadState * swig_pythreadstate_set(PyThreadState * v) {
77 PyThreadState * old = swig_pythreadstate;
78 swig_pythreadstate = v;
79 return old;
82 #else
84 #include <pthread.h>
86 static pthread_key_t swig_pythreadstate_key;
87 static pthread_once_t swig_pythreadstate_key_once = PTHREAD_ONCE_INIT;
89 static void swig_pythreadstate_make_key()
91 if (pthread_key_create(&swig_pythreadstate_key, NULL) != 0)
92 Py_FatalError("pthread_key_create failed");
95 inline void swig_pythreadstate_ensure_init() {
96 pthread_once(&swig_pythreadstate_key_once, swig_pythreadstate_make_key);
99 inline PyThreadState * swig_pythreadstate_reset() {
100 PyThreadState * v = (PyThreadState*)pthread_getspecific(swig_pythreadstate_key);
101 if (v) pthread_setspecific(swig_pythreadstate_key, NULL);
102 return v;
105 inline PyThreadState* swig_pythreadstate_set(PyThreadState * v) {
106 PyThreadState * old = (PyThreadState*)pthread_getspecific(swig_pythreadstate_key);
107 pthread_setspecific(swig_pythreadstate_key, (void*)v);
108 return old;
111 #endif
113 class XapianSWIG_Python_Thread_Block {
114 bool status;
115 public:
116 XapianSWIG_Python_Thread_Block() : status(false) {
117 if (PyEval_ThreadsInitialized()) {
118 swig_pythreadstate_ensure_init();
119 PyThreadState * ts = swig_pythreadstate_reset();
120 if (ts) {
121 status = true;
122 PyEval_RestoreThread(ts);
126 void end() {
127 if (status) {
128 if (swig_pythreadstate_set(PyEval_SaveThread()))
129 Py_FatalError("swig_pythreadstate set in XapianSWIG_Python_Thread_Block::end()");
130 status = false;
133 ~XapianSWIG_Python_Thread_Block() { end(); }
136 class XapianSWIG_Python_Thread_Allow {
137 bool status;
138 public:
139 XapianSWIG_Python_Thread_Allow() : status(PyEval_ThreadsInitialized()) {
140 if (status) {
141 swig_pythreadstate_ensure_init();
142 if (swig_pythreadstate_set(PyEval_SaveThread()))
143 Py_FatalError("swig_pythreadstate set in XapianSWIG_Python_Thread_Allow ctor");
146 void end() {
147 if (status) {
148 PyThreadState * ts = swig_pythreadstate_reset();
149 if (!ts)
150 Py_FatalError("swig_pythreadstate unset in XapianSWIG_Python_Thread_Block::end()");
151 PyEval_RestoreThread(ts);
152 status = false;
155 ~XapianSWIG_Python_Thread_Allow() { end(); }
158 #define SWIG_PYTHON_THREAD_BEGIN_BLOCK XapianSWIG_Python_Thread_Block _xapian_swig_thread_block
159 #define SWIG_PYTHON_THREAD_END_BLOCK _xapian_swig_thread_block.end()
160 #define SWIG_PYTHON_THREAD_BEGIN_ALLOW XapianSWIG_Python_Thread_Allow _xapian_swig_thread_allow
161 #define SWIG_PYTHON_THREAD_END_ALLOW _xapian_swig_thread_allow.end()
164 // Use SWIG directors for Python wrappers.
165 #define XAPIAN_SWIG_DIRECTORS
167 %include version.i
168 %include ../xapian-head.i
170 // Doccomments from Doxgyen-generated XML from C++ API docs.
171 %include doccomments.i
173 // Manually added exceptions for cases where the automatic comments aren't
174 // helpful, or are missing.
175 %include extracomments.i
177 %include util.i
179 #define XAPIAN_MIXED_SUBQUERIES_BY_ITERATOR_TYPEMAP
181 // Don't release the GIL for this method since we use Python C API calls to do
182 // the iteration.
183 %nothreadallow Xapian::Query::Query(op op_, XapianSWIGQueryItor qbegin, XapianSWIGQueryItor qend, Xapian::termcount parameter = 0);
185 %typemap(typecheck, precedence=500) (XapianSWIGQueryItor qbegin, XapianSWIGQueryItor qend) {
186 // Checking for a sequence is enough to disambiguate currently.
187 $1 = PySequence_Check($input);
191 class XapianSWIGQueryItor {
192 mutable PyObject * seq;
194 int i;
196 /// str_obj must be a string object.
197 Xapian::Query str_obj_to_query(PyObject * str_obj) const {
198 char * p;
199 Py_ssize_t len;
200 (void)PyString_AsStringAndSize(str_obj, &p, &len);
201 return Xapian::Query(string(p, len));
204 public:
205 typedef std::random_access_iterator_tag iterator_category;
206 typedef Xapian::Query value_type;
207 typedef Xapian::termcount_diff difference_type;
208 typedef Xapian::Query * pointer;
209 typedef Xapian::Query & reference;
211 XapianSWIGQueryItor() : seq(NULL), i(0) { }
213 void begin(PyObject * seq_) {
214 seq = seq_;
217 void end(PyObject * seq_) {
218 i = PySequence_Fast_GET_SIZE(seq_);
221 void free_seq() {
222 Py_CLEAR(seq);
225 XapianSWIGQueryItor & operator++() {
226 ++i;
227 return *this;
230 Xapian::Query operator*() const {
231 PyObject * obj = PySequence_Fast_GET_ITEM(seq, i);
233 // Unicode object.
234 if (PyUnicode_Check(obj)) {
235 PyObject *s = PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(obj),
236 PyUnicode_GET_SIZE(obj),
237 "ignore");
238 if (!s) goto fail;
239 Xapian::Query result = str_obj_to_query(s);
240 Py_DECREF(s);
241 return result;
244 // String.
245 if (PyString_Check(obj))
246 return str_obj_to_query(obj);
248 // xapian.Query object (or unexpected object type).
250 Xapian::Query * result_ptr = Xapian::get_py_query(obj);
251 if (result_ptr) return *result_ptr;
254 fail:
255 throw Xapian::InvalidArgumentError("Expected Query object or string");
258 bool operator==(const XapianSWIGQueryItor & o) {
259 return i == o.i;
262 bool operator!=(const XapianSWIGQueryItor & o) {
263 return !(*this == o);
266 difference_type operator-(const XapianSWIGQueryItor &o) const {
267 return i - o.i;
273 %typemap(in) (XapianSWIGQueryItor qbegin, XapianSWIGQueryItor qend) {
274 PyObject * seq;
275 seq = PySequence_Fast($input,
276 "expected sequence of Query objects and/or strings");
277 if (!seq) SWIG_fail;
278 $1.begin(seq);
279 $2.end(seq);
282 %typemap(freearg) (XapianSWIGQueryItor qbegin, XapianSWIGQueryItor qend)
283 %{ $1.free_seq(); %}
285 %include except.i
286 %include ../xapian-headers.i
287 %include extra.i