Imported Upstream version 3.21.91
[platform/upstream/python-gobject.git] / gi / pygi-repository.c
1 /* -*- Mode: C; c-basic-offset: 4 -*-
2  * vim: tabstop=4 shiftwidth=4 expandtab
3  *
4  * Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org>
5  *
6  *   pygi-repository.c: GIRepository wrapper.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library 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 GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include "pygi-repository.h"
23 #include "pygi-info.h"
24
25 #include <pyglib-python-compat.h>
26
27 PyObject *PyGIRepositoryError;
28
29 PYGLIB_DEFINE_TYPE("gi.Repository", PyGIRepository_Type, PyGIRepository);
30
31 static PyObject *
32 _wrap_g_irepository_enumerate_versions (PyGIRepository *self,
33                                         PyObject       *args,
34                                         PyObject       *kwargs)
35 {
36     static char *kwlist[] = { "namespace", NULL };
37     const char *namespace_;
38     GList *versions, *item;
39     PyObject *ret = NULL;
40
41     if (!PyArg_ParseTupleAndKeywords (args, kwargs, "s:Repository.enumerate_versions",
42                                       kwlist, &namespace_)) {
43         return NULL;
44     }
45
46     versions = g_irepository_enumerate_versions (self->repository, namespace_);
47     ret = PyList_New(0);
48     for (item = versions; item; item = item->next) {
49         char *version = item->data;
50         PyObject *py_version = PYGLIB_PyUnicode_FromString (version);
51         PyList_Append(ret, py_version);
52         Py_DECREF(py_version);
53         g_free (version);
54     }
55     g_list_free(versions);
56
57     return ret;
58 }
59
60 static PyObject *
61 _wrap_g_irepository_get_default (PyObject *self)
62 {
63     static PyGIRepository *repository = NULL;
64
65     if (!repository) {
66         repository = (PyGIRepository *) PyObject_New (PyGIRepository, &PyGIRepository_Type);
67         if (repository == NULL) {
68             return NULL;
69         }
70
71         repository->repository = g_irepository_get_default();
72     }
73
74     Py_INCREF ( (PyObject *) repository);
75     return (PyObject *) repository;
76 }
77
78 static PyObject *
79 _wrap_g_irepository_require (PyGIRepository *self,
80                              PyObject       *args,
81                              PyObject       *kwargs)
82 {
83     static char *kwlist[] = { "namespace", "version", "lazy", NULL };
84
85     const char *namespace_;
86     const char *version = NULL;
87     PyObject *lazy = NULL;
88     GIRepositoryLoadFlags flags = 0;
89     GError *error;
90
91     if (!PyArg_ParseTupleAndKeywords (args, kwargs, "s|zO:Repository.require",
92                                       kwlist, &namespace_, &version, &lazy)) {
93         return NULL;
94     }
95
96     if (lazy != NULL && PyObject_IsTrue (lazy)) {
97         flags |= G_IREPOSITORY_LOAD_FLAG_LAZY;
98     }
99
100     error = NULL;
101     g_irepository_require (self->repository, namespace_, version, flags, &error);
102     if (error != NULL) {
103         PyErr_SetString (PyGIRepositoryError, error->message);
104         g_error_free (error);
105         return NULL;
106     }
107
108     Py_RETURN_NONE;
109 }
110
111 static PyObject *
112 _wrap_g_irepository_is_registered (PyGIRepository *self,
113                                    PyObject       *args,
114                                    PyObject       *kwargs)
115 {
116     static char *kwlist[] = { "namespace", "version", NULL };
117     const char *namespace_;
118     const char *version = NULL;
119
120     if (!PyArg_ParseTupleAndKeywords (args, kwargs, "s|z:Repository.is_registered",
121                                       kwlist, &namespace_, &version)) {
122         return NULL;
123     }
124
125     return PyBool_FromLong (g_irepository_is_registered (self->repository,
126                                                          namespace_, version));
127 }
128
129 static PyObject *
130 _wrap_g_irepository_find_by_name (PyGIRepository *self,
131                                   PyObject       *args,
132                                   PyObject       *kwargs)
133 {
134     static char *kwlist[] = { "namespace", "name", NULL };
135
136     const char *namespace_;
137     const char *name;
138     GIBaseInfo *info;
139     PyObject *py_info;
140     size_t len;
141     char *trimmed_name = NULL;
142
143     if (!PyArg_ParseTupleAndKeywords (args, kwargs,
144                                       "ss:Repository.find_by_name", kwlist, &namespace_, &name)) {
145         return NULL;
146     }
147
148     /* If the given name ends with an underscore, it might be due to usage
149      * as an accessible replacement for something in GI with the same name
150      * as a Python keyword. Test for this and trim it out if necessary.
151      */
152     len = strlen (name);
153     if (len > 0 && name[len-1] == '_') {
154         trimmed_name = g_strndup (name, len-1);
155         if (_pygi_is_python_keyword (trimmed_name)) {
156             name = trimmed_name;
157         }
158     }
159
160     info = g_irepository_find_by_name (self->repository, namespace_, name);
161     g_free (trimmed_name);
162
163     if (info == NULL) {
164         Py_RETURN_NONE;
165     }
166
167     py_info = _pygi_info_new (info);
168
169     g_base_info_unref (info);
170
171     return py_info;
172 }
173
174 static PyObject *
175 _wrap_g_irepository_get_infos (PyGIRepository *self,
176                                PyObject       *args,
177                                PyObject       *kwargs)
178 {
179     static char *kwlist[] = { "namespace", NULL };
180
181     const char *namespace_;
182     gssize n_infos;
183     PyObject *infos;
184     gssize i;
185
186     if (!PyArg_ParseTupleAndKeywords (args, kwargs, "s:Repository.get_infos",
187                                       kwlist, &namespace_)) {
188         return NULL;
189     }
190
191     n_infos = g_irepository_get_n_infos (self->repository, namespace_);
192     if (n_infos < 0) {
193         PyErr_Format (PyExc_RuntimeError, "Namespace '%s' not loaded", namespace_);
194         return NULL;
195     }
196
197     infos = PyTuple_New (n_infos);
198
199     for (i = 0; i < n_infos; i++) {
200         GIBaseInfo *info;
201         PyObject *py_info;
202
203         info = g_irepository_get_info (self->repository, namespace_, i);
204         g_assert (info != NULL);
205
206         py_info = _pygi_info_new (info);
207
208         g_base_info_unref (info);
209
210         if (py_info == NULL) {
211             Py_CLEAR (infos);
212             break;
213         }
214
215         PyTuple_SET_ITEM (infos, i, py_info);
216     }
217
218     return infos;
219 }
220
221 static PyObject *
222 _wrap_g_irepository_get_typelib_path (PyGIRepository *self,
223                                       PyObject       *args,
224                                       PyObject       *kwargs)
225 {
226     static char *kwlist[] = { "namespace", NULL };
227     const char *namespace_;
228     const gchar *typelib_path;
229
230     if (!PyArg_ParseTupleAndKeywords (args, kwargs,
231                                       "s:Repository.get_typelib_path", kwlist, &namespace_)) {
232         return NULL;
233     }
234
235     typelib_path = g_irepository_get_typelib_path (self->repository, namespace_);
236     if (typelib_path == NULL) {
237         PyErr_Format (PyExc_RuntimeError, "Namespace '%s' not loaded", namespace_);
238         return NULL;
239     }
240
241     return PYGLIB_PyBytes_FromString (typelib_path);
242 }
243
244 static PyObject *
245 _wrap_g_irepository_get_version (PyGIRepository *self,
246                                  PyObject       *args,
247                                  PyObject       *kwargs)
248 {
249     static char *kwlist[] = { "namespace", NULL };
250     const char *namespace_;
251     const gchar *version;
252
253     if (!PyArg_ParseTupleAndKeywords (args, kwargs,
254                                       "s:Repository.get_version", kwlist, &namespace_)) {
255         return NULL;
256     }
257
258     version = g_irepository_get_version (self->repository, namespace_);
259     if (version == NULL) {
260         PyErr_Format (PyExc_RuntimeError, "Namespace '%s' not loaded", namespace_);
261         return NULL;
262     }
263
264     return PYGLIB_PyUnicode_FromString (version);
265 }
266
267 static PyObject *
268 _wrap_g_irepository_get_loaded_namespaces (PyGIRepository *self)
269 {
270     char **namespaces;
271     PyObject *py_namespaces;
272     gssize i;
273
274     namespaces = g_irepository_get_loaded_namespaces (self->repository);
275
276     py_namespaces = PyList_New (0);
277     for (i = 0; namespaces[i] != NULL; i++) {
278         PyObject *py_namespace = PYGLIB_PyUnicode_FromString (namespaces[i]);
279         PyList_Append (py_namespaces, py_namespace);
280         Py_DECREF(py_namespace);
281         g_free (namespaces[i]);
282     }
283
284     g_free (namespaces);
285
286     return py_namespaces;
287 }
288
289 static PyObject *
290 _wrap_g_irepository_get_dependencies (PyGIRepository *self,
291                                       PyObject       *args,
292                                       PyObject       *kwargs)
293 {
294     static char *kwlist[] = { "namespace", NULL };
295     const char *namespace_;
296     char **namespaces;
297     PyObject *py_namespaces;
298     gssize i;
299
300     if (!PyArg_ParseTupleAndKeywords (args, kwargs,
301                                       "s:Repository.get_dependencies", kwlist, &namespace_)) {
302         return NULL;
303     }
304
305     py_namespaces = PyList_New (0);
306     /* Returns NULL in case of no dependencies */
307     namespaces = g_irepository_get_dependencies (self->repository, namespace_);
308     if (namespaces == NULL) {
309         return py_namespaces;
310     }
311
312     for (i = 0; namespaces[i] != NULL; i++) {
313         PyObject *py_namespace = PYGLIB_PyUnicode_FromString (namespaces[i]);
314         PyList_Append (py_namespaces, py_namespace);
315         Py_DECREF(py_namespace);
316     }
317
318     g_strfreev (namespaces);
319
320     return py_namespaces;
321 }
322
323
324 static PyObject *
325 _wrap_g_irepository_get_immediate_dependencies (PyGIRepository *self,
326                                                 PyObject       *args,
327                                                 PyObject       *kwargs)
328 {
329     static char *kwlist[] = { "namespace", NULL };
330     const char *namespace_;
331     char **namespaces;
332     PyObject *py_namespaces;
333     gssize i;
334
335     if (!PyArg_ParseTupleAndKeywords (args, kwargs,
336                                       "s:Repository.get_immediate_dependencies",
337                                       kwlist, &namespace_)) {
338         return NULL;
339     }
340
341     py_namespaces = PyList_New (0);
342     namespaces = g_irepository_get_immediate_dependencies (self->repository,
343                                                            namespace_);
344
345     for (i = 0; namespaces[i] != NULL; i++) {
346         PyObject *py_namespace = PYGLIB_PyUnicode_FromString (namespaces[i]);
347         PyList_Append (py_namespaces, py_namespace);
348         Py_DECREF (py_namespace);
349     }
350
351     g_strfreev (namespaces);
352
353     return py_namespaces;
354 }
355
356
357 static PyMethodDef _PyGIRepository_methods[] = {
358     { "enumerate_versions", (PyCFunction) _wrap_g_irepository_enumerate_versions, METH_VARARGS | METH_KEYWORDS },
359     { "get_default", (PyCFunction) _wrap_g_irepository_get_default, METH_STATIC | METH_NOARGS },
360     { "require", (PyCFunction) _wrap_g_irepository_require, METH_VARARGS | METH_KEYWORDS },
361     { "get_infos", (PyCFunction) _wrap_g_irepository_get_infos, METH_VARARGS | METH_KEYWORDS },
362     { "find_by_name", (PyCFunction) _wrap_g_irepository_find_by_name, METH_VARARGS | METH_KEYWORDS },
363     { "get_typelib_path", (PyCFunction) _wrap_g_irepository_get_typelib_path, METH_VARARGS | METH_KEYWORDS },
364     { "get_version", (PyCFunction) _wrap_g_irepository_get_version, METH_VARARGS | METH_KEYWORDS },
365     { "get_loaded_namespaces", (PyCFunction) _wrap_g_irepository_get_loaded_namespaces, METH_NOARGS },
366     { "get_dependencies", (PyCFunction) _wrap_g_irepository_get_dependencies, METH_VARARGS | METH_KEYWORDS  },
367     { "get_immediate_dependencies", (PyCFunction) _wrap_g_irepository_get_immediate_dependencies, METH_VARARGS | METH_KEYWORDS  },
368     { "is_registered", (PyCFunction) _wrap_g_irepository_is_registered, METH_VARARGS | METH_KEYWORDS  },
369     { NULL, NULL, 0 }
370 };
371
372 void
373 _pygi_repository_register_types (PyObject *m)
374 {
375     Py_TYPE(&PyGIRepository_Type) = &PyType_Type;
376
377     PyGIRepository_Type.tp_flags = Py_TPFLAGS_DEFAULT;
378     PyGIRepository_Type.tp_methods = _PyGIRepository_methods;
379
380     if (PyType_Ready (&PyGIRepository_Type)) {
381         return;
382     }
383
384     if (PyModule_AddObject (m, "Repository", (PyObject *) &PyGIRepository_Type)) {
385         return;
386     }
387
388     PyGIRepositoryError = PyErr_NewException ("gi.RepositoryError", NULL, NULL);
389     if (PyModule_AddObject (m, "RepositoryError", PyGIRepositoryError)) {
390         return;
391     }
392 }
393