1 |
|
|
/** |
2 |
|
|
* package.c : wrapper class around alpm_pkg_t |
3 |
|
|
* |
4 |
|
|
* Copyright (c) 2011 Rémy Oudompheng <remy@archlinux.org> |
5 |
|
|
* |
6 |
|
|
* This file is part of pyalpm. |
7 |
|
|
* |
8 |
|
|
* pyalpm is free software: you can redistribute it and/or modify |
9 |
|
|
* it under the terms of the GNU General Public License as published by |
10 |
|
|
* the Free Software Foundation, either version 3 of the License, or |
11 |
|
|
* (at your option) any later version. |
12 |
|
|
* |
13 |
|
|
* pyalpm 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. |
17 |
|
|
* |
18 |
|
|
* You should have received a copy of the GNU General Public License |
19 |
|
|
* along with pyalpm. If not, see <http://www.gnu.org/licenses/>. |
20 |
|
|
* |
21 |
|
|
*/ |
22 |
|
|
|
23 |
|
|
#include <pyconfig.h> |
24 |
|
|
#include <string.h> |
25 |
|
|
#include <alpm.h> |
26 |
|
|
#include <Python.h> |
27 |
|
|
#include "db.h" |
28 |
|
|
#include "util.h" |
29 |
|
|
#include "handle.h" |
30 |
|
|
#include "package.h" |
31 |
|
|
|
32 |
|
|
PyTypeObject AlpmPackageType; |
33 |
|
|
extern PyTypeObject AlpmHandleType; |
34 |
|
|
|
35 |
|
6 |
int PyAlpmPkg_Check(PyObject *object) { |
36 |
✗✗✗✓ ✗✗ |
3 |
return PyObject_TypeCheck(object, &AlpmPackageType); |
37 |
|
|
} |
38 |
|
|
|
39 |
|
3 |
static PyObject* pyalpm_pkg_repr(PyObject *rawself) { |
40 |
|
3 |
AlpmPackage *self = (AlpmPackage *)rawself; |
41 |
|
3 |
return PyUnicode_FromFormat("<alpm.Package(\"%s-%s-%s\") at %p>", |
42 |
|
|
alpm_pkg_get_name(self->c_data), |
43 |
|
|
alpm_pkg_get_version(self->c_data), |
44 |
|
|
alpm_pkg_get_arch(self->c_data), |
45 |
|
|
self); |
46 |
|
|
} |
47 |
|
|
|
48 |
|
3 |
static PyObject* pyalpm_pkg_str(PyObject *rawself) { |
49 |
|
3 |
AlpmPackage *self = (AlpmPackage *)rawself; |
50 |
|
3 |
return PyUnicode_FromFormat("alpm.Package(\"%s-%s-%s\")", |
51 |
|
|
alpm_pkg_get_name(self->c_data), |
52 |
|
|
alpm_pkg_get_version(self->c_data), |
53 |
|
|
alpm_pkg_get_arch(self->c_data)); |
54 |
|
|
} |
55 |
|
|
|
56 |
|
3 |
void pyalpm_pkg_unref(PyObject *object) { |
57 |
✗✓ |
3 |
if (PyAlpmPkg_Check(object)) |
58 |
|
3 |
((AlpmPackage*)(object))->needs_free = 0; |
59 |
|
3 |
} |
60 |
|
|
|
61 |
|
27 |
static void pyalpm_package_dealloc(AlpmPackage *self) { |
62 |
✗✓ |
27 |
if (self->needs_free) |
63 |
|
|
alpm_pkg_free(self->c_data); |
64 |
|
27 |
Py_TYPE(self)->tp_free((PyObject*)self); |
65 |
|
27 |
} |
66 |
|
|
|
67 |
|
|
/* Internal utility functions */ |
68 |
|
|
|
69 |
|
3 |
static PyObject* _pyobject_from_pmdepend(void* dep) { |
70 |
|
3 |
char *depstring = alpm_dep_compute_string((alpm_depend_t*)dep); |
71 |
|
3 |
PyObject *item = Py_BuildValue("s", depstring); |
72 |
|
3 |
free(depstring); |
73 |
|
3 |
return item; |
74 |
|
|
}; |
75 |
|
|
|
76 |
|
27 |
PyObject *pyalpm_package_from_pmpkg(void* data) { |
77 |
|
27 |
AlpmPackage *self; |
78 |
|
27 |
alpm_pkg_t *p = (alpm_pkg_t*)data; |
79 |
|
27 |
self = (AlpmPackage*)AlpmPackageType.tp_alloc(&AlpmPackageType, 0); |
80 |
✗✓ |
27 |
if (self == NULL) { |
81 |
|
|
PyErr_SetString(PyExc_RuntimeError, "unable to create package object"); |
82 |
|
|
return NULL; |
83 |
|
|
} |
84 |
|
|
|
85 |
|
27 |
self->c_data = p; |
86 |
|
27 |
self->needs_free = 0; |
87 |
|
27 |
return (PyObject *)self; |
88 |
|
|
} |
89 |
|
|
|
90 |
|
|
#define CHECK_IF_INITIALIZED() if (! self->c_data) { \ |
91 |
|
|
PyErr_SetString(alpm_error, "data is not initialized"); \ |
92 |
|
|
return NULL; \ |
93 |
|
|
} |
94 |
|
|
|
95 |
|
15 |
static PyObject* _get_string_attribute(AlpmPackage *self, const char* getter(alpm_pkg_t*)) { |
96 |
|
15 |
const char *attr; |
97 |
✗✓ |
15 |
if (! self->c_data) { |
98 |
|
|
PyErr_SetString(alpm_error, "data is not initialized"); |
99 |
|
|
return NULL; |
100 |
|
|
} |
101 |
|
15 |
attr = getter(self->c_data); |
102 |
✗✓ |
15 |
if (attr == NULL) Py_RETURN_NONE; |
103 |
|
15 |
return Py_BuildValue("s", attr); |
104 |
|
|
} |
105 |
|
|
|
106 |
|
|
struct list_getter { |
107 |
|
|
alpm_list_t *(*getter)(alpm_pkg_t *); |
108 |
|
|
PyObject *(*item_converter)(void *); |
109 |
|
|
}; |
110 |
|
|
|
111 |
|
|
/** Returns a Python list attribute */ |
112 |
|
6 |
static PyObject* _get_list_attribute(AlpmPackage *self, const struct list_getter *closure) { |
113 |
|
6 |
alpm_list_t *result = NULL; |
114 |
✗✓ |
6 |
CHECK_IF_INITIALIZED(); |
115 |
|
6 |
result = closure->getter(self->c_data); |
116 |
|
6 |
return alpmlist_to_pylist(result, closure->item_converter); |
117 |
|
|
} |
118 |
|
|
|
119 |
|
6 |
alpm_pkg_t *pmpkg_from_pyalpm_pkg(PyObject *object) { |
120 |
|
6 |
AlpmPackage *self = (AlpmPackage*)object; |
121 |
✗✓ |
6 |
CHECK_IF_INITIALIZED(); |
122 |
|
|
return self->c_data; |
123 |
|
|
} |
124 |
|
|
|
125 |
|
|
/** Converts a Python list of packages to an alpm_list_t linked list. |
126 |
|
|
* return 0 on success, -1 on failure |
127 |
|
|
*/ |
128 |
|
9 |
int pylist_pkg_to_alpmlist(PyObject *list, alpm_list_t **result) { |
129 |
|
9 |
alpm_list_t *ret = NULL; |
130 |
|
9 |
PyObject *iterator = PyObject_GetIter(list); |
131 |
|
9 |
PyObject *item; |
132 |
|
|
|
133 |
✗✓ |
9 |
if(iterator == NULL) { |
134 |
|
|
PyErr_SetString(PyExc_TypeError, "object is not iterable"); |
135 |
|
|
return -1; |
136 |
|
|
} |
137 |
|
|
|
138 |
✓✓ |
15 |
while((item = PyIter_Next(iterator))) |
139 |
|
|
{ |
140 |
✓✓✗✓
|
9 |
if (PyObject_TypeCheck(item, &AlpmPackageType)) { |
141 |
|
6 |
ret = alpm_list_add(ret, ((AlpmPackage*)item)->c_data); |
142 |
|
|
} else { |
143 |
|
3 |
PyErr_SetString(PyExc_TypeError, "list must contain only Package objects"); |
144 |
|
3 |
FREELIST(ret); |
145 |
|
3 |
return -1; |
146 |
|
|
} |
147 |
✗✓ |
21 |
Py_DECREF(item); |
148 |
|
|
} |
149 |
✓✗ |
6 |
Py_DECREF(iterator); |
150 |
|
|
|
151 |
|
6 |
*result = ret; |
152 |
|
6 |
return 0; |
153 |
|
|
} |
154 |
|
|
|
155 |
|
|
/* Python bindings */ |
156 |
|
|
|
157 |
|
3 |
PyObject *pyalpm_package_load(PyObject *self, PyObject *args, PyObject *kwargs) { |
158 |
|
3 |
alpm_handle_t *handle = ALPM_HANDLE(self); |
159 |
|
3 |
char *filename; |
160 |
|
3 |
int check_sig = ALPM_SIG_PACKAGE_OPTIONAL; |
161 |
|
3 |
char *kws[] = { "path", "check_sig", NULL }; |
162 |
|
3 |
alpm_pkg_t *result; |
163 |
|
3 |
AlpmPackage *pyresult; |
164 |
✓✗ |
3 |
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:load_pkg", kws, &filename, &check_sig)) { |
165 |
|
|
return NULL; |
166 |
|
|
} |
167 |
|
|
|
168 |
✗✓✗✗
|
3 |
if ((alpm_pkg_load(handle, filename, 1, check_sig, &result) == -1) || !result) { |
169 |
|
3 |
RET_ERR("loading package failed", alpm_errno(handle), NULL); |
170 |
|
|
} |
171 |
|
|
|
172 |
|
|
pyresult = (AlpmPackage*)pyalpm_package_from_pmpkg(result); |
173 |
|
|
if (!pyresult) return NULL; |
174 |
|
|
pyresult->needs_free = 1; |
175 |
|
|
return (PyObject*)pyresult; |
176 |
|
|
} |
177 |
|
|
|
178 |
|
3 |
static PyObject* pyalpm_package_get_builddate(AlpmPackage *self, void *closure) { |
179 |
✗✓ |
3 |
CHECK_IF_INITIALIZED(); |
180 |
|
3 |
return PyLong_FromLongLong(alpm_pkg_get_builddate(self->c_data)); |
181 |
|
|
} |
182 |
|
|
|
183 |
|
3 |
static PyObject* pyalpm_package_get_installdate(AlpmPackage *self, void *closure) { |
184 |
✗✓ |
3 |
CHECK_IF_INITIALIZED(); |
185 |
|
3 |
return PyLong_FromLongLong(alpm_pkg_get_installdate(self->c_data)); |
186 |
|
|
} |
187 |
|
|
|
188 |
|
3 |
static PyObject* pyalpm_package_get_size(AlpmPackage *self, void *closure) { |
189 |
✗✓ |
3 |
CHECK_IF_INITIALIZED(); |
190 |
|
3 |
return PyLong_FromLongLong(alpm_pkg_get_size(self->c_data)); |
191 |
|
|
} |
192 |
|
|
|
193 |
|
3 |
static PyObject* pyalpm_package_get_isize(AlpmPackage *self, void *closure) { |
194 |
✗✓ |
3 |
CHECK_IF_INITIALIZED(); |
195 |
|
3 |
return PyLong_FromLongLong(alpm_pkg_get_isize(self->c_data)); |
196 |
|
|
} |
197 |
|
|
|
198 |
|
3 |
static PyObject* pyalpm_package_get_reason(AlpmPackage *self, void *closure) { |
199 |
✗✓ |
3 |
CHECK_IF_INITIALIZED(); |
200 |
|
3 |
return PyLong_FromLong(alpm_pkg_get_reason(self->c_data)); |
201 |
|
|
} |
202 |
|
|
|
203 |
|
3 |
static PyObject* pyalpm_package_get_files(AlpmPackage *self, void *closure) { |
204 |
|
3 |
const alpm_filelist_t *flist = NULL; |
205 |
|
3 |
PyObject *result = NULL; |
206 |
|
|
|
207 |
✗✓ |
3 |
CHECK_IF_INITIALIZED(); |
208 |
|
|
|
209 |
|
3 |
flist = alpm_pkg_get_files(self->c_data); |
210 |
✗✓ |
3 |
if (!flist) |
211 |
|
|
Py_RETURN_NONE; |
212 |
|
|
else { |
213 |
|
3 |
ssize_t i; |
214 |
|
3 |
result = PyList_New((Py_ssize_t)flist->count); |
215 |
✓✓ |
21 |
for (i = 0; i < (ssize_t)flist->count; i++) { |
216 |
|
15 |
const alpm_file_t *file = flist->files + i; |
217 |
|
15 |
PyObject *filename = PyUnicode_DecodeFSDefault(file->name); |
218 |
|
15 |
PyObject *filesize = PyLong_FromLongLong(file->size); |
219 |
|
15 |
PyObject *filemode = PyLong_FromUnsignedLong(file->mode); |
220 |
|
15 |
PyObject *item = PyTuple_New(3); |
221 |
✓✗✓✗
|
15 |
if (item && filename && filesize && filemode) { |
222 |
|
15 |
PyTuple_SET_ITEM(item, 0, filename); |
223 |
|
15 |
PyTuple_SET_ITEM(item, 1, filesize); |
224 |
|
15 |
PyTuple_SET_ITEM(item, 2, filemode); |
225 |
|
15 |
PyList_SET_ITEM(result, i, item); |
226 |
|
|
} else { |
227 |
|
|
Py_CLEAR(item); |
228 |
|
|
Py_CLEAR(filename); |
229 |
|
|
Py_CLEAR(filesize); |
230 |
|
|
Py_CLEAR(filemode); |
231 |
|
|
return NULL; |
232 |
|
|
} |
233 |
|
|
} |
234 |
|
|
} |
235 |
|
|
return result; |
236 |
|
|
} |
237 |
|
|
|
238 |
|
|
/** Convert alpm_backup_t to Python tuples |
239 |
|
|
* The resulting tuple is (filename, hexadecimal hash) |
240 |
|
|
*/ |
241 |
|
3 |
static PyObject* pyobject_from_alpm_backup(void* data) { |
242 |
|
3 |
alpm_backup_t* item = (alpm_backup_t*)data; |
243 |
|
3 |
PyObject* tuple = Py_BuildValue("(ss)", item->name, item->hash); |
244 |
|
3 |
return tuple; |
245 |
|
|
} |
246 |
|
|
|
247 |
|
3 |
static PyObject* pyalpm_package_get_db(AlpmPackage *self, void *closure) { |
248 |
|
3 |
alpm_db_t* db; |
249 |
✗✓ |
3 |
CHECK_IF_INITIALIZED(); |
250 |
|
3 |
db = alpm_pkg_get_db(self->c_data); |
251 |
✓✗ |
3 |
if (db) |
252 |
|
3 |
return pyalpm_db_from_pmdb(db); |
253 |
|
|
else |
254 |
|
|
Py_RETURN_NONE; |
255 |
|
|
} |
256 |
|
|
|
257 |
|
3 |
static PyObject* pyalpm_pkg_has_scriptlet(AlpmPackage *self, void *closure) { |
258 |
✗✓ |
3 |
CHECK_IF_INITIALIZED(); |
259 |
|
3 |
return PyBool_FromLong(alpm_pkg_has_scriptlet(self->c_data)); |
260 |
|
|
} |
261 |
|
|
|
262 |
|
3 |
static PyObject* pyalpm_pkg_download_size(AlpmPackage *self, void *closure) { |
263 |
✗✓ |
3 |
CHECK_IF_INITIALIZED(); |
264 |
|
3 |
return PyLong_FromLongLong(alpm_pkg_download_size(self->c_data)); |
265 |
|
|
} |
266 |
|
|
|
267 |
|
3 |
static PyObject* pyalpm_pkg_compute_requiredby(PyObject *rawself, PyObject *args) { |
268 |
|
3 |
AlpmPackage *self = (AlpmPackage*)rawself; |
269 |
|
3 |
PyObject *pyresult; |
270 |
✗✓ |
3 |
CHECK_IF_INITIALIZED(); |
271 |
|
|
{ |
272 |
|
3 |
alpm_list_t *result = alpm_pkg_compute_requiredby(self->c_data); |
273 |
|
3 |
pyresult = alpmlist_to_pylist(result, pyobject_from_string); |
274 |
|
3 |
FREELIST(result); |
275 |
|
|
} |
276 |
|
3 |
return pyresult; |
277 |
|
|
} |
278 |
|
|
|
279 |
|
|
struct list_getter get_licenses = { alpm_pkg_get_licenses, pyobject_from_string }; |
280 |
|
|
struct list_getter get_groups = { alpm_pkg_get_groups, pyobject_from_string }; |
281 |
|
|
struct list_getter get_backup = { alpm_pkg_get_backup, pyobject_from_alpm_backup }; |
282 |
|
|
struct list_getter get_depends = { alpm_pkg_get_depends, _pyobject_from_pmdepend }; |
283 |
|
|
struct list_getter get_checkdepends = { alpm_pkg_get_checkdepends, _pyobject_from_pmdepend }; |
284 |
|
|
struct list_getter get_makedepends = { alpm_pkg_get_makedepends, _pyobject_from_pmdepend }; |
285 |
|
|
struct list_getter get_optdepends = { alpm_pkg_get_optdepends, _pyobject_from_pmdepend }; |
286 |
|
|
struct list_getter get_replaces = { alpm_pkg_get_replaces, _pyobject_from_pmdepend }; |
287 |
|
|
struct list_getter get_provides = { alpm_pkg_get_provides, _pyobject_from_pmdepend }; |
288 |
|
|
struct list_getter get_conflicts = { alpm_pkg_get_conflicts, _pyobject_from_pmdepend }; |
289 |
|
|
|
290 |
|
|
static struct PyGetSetDef AlpmPackageGetSet[] = { |
291 |
|
|
{ "db", (getter)pyalpm_package_get_db, 0, "the database from which the package comes from, or None", NULL } , |
292 |
|
|
/* description properties */ |
293 |
|
|
{ "name", (getter)_get_string_attribute, 0, "package name", alpm_pkg_get_name } , |
294 |
|
|
{ "version", (getter)_get_string_attribute, 0, "package version", alpm_pkg_get_version } , |
295 |
|
|
{ "desc", (getter)_get_string_attribute, 0, "package desc", alpm_pkg_get_desc } , |
296 |
|
|
{ "url", (getter)_get_string_attribute, 0, "package URL", alpm_pkg_get_url } , |
297 |
|
|
{ "arch", (getter)_get_string_attribute, 0, "target architecture", alpm_pkg_get_arch } , |
298 |
|
|
{ "licenses", (getter)_get_list_attribute, 0, "list of licenses", &get_licenses } , |
299 |
|
|
{ "groups", (getter)_get_list_attribute, 0, "list of package groups", &get_groups } , |
300 |
|
|
/* package properties */ |
301 |
|
|
{ "packager", (getter)_get_string_attribute, 0, "packager name", alpm_pkg_get_packager } , |
302 |
|
|
{ "md5sum", (getter)_get_string_attribute, 0, "package md5sum", alpm_pkg_get_md5sum } , |
303 |
|
|
{ "sha256sum", (getter)_get_string_attribute, 0, "package sha256sum as hexadecimal digits", alpm_pkg_get_sha256sum } , |
304 |
|
|
{ "base64_sig", (getter)_get_string_attribute, 0, "GPG signature encoded as base64", alpm_pkg_get_base64_sig } , |
305 |
|
|
{ "filename", (getter)_get_string_attribute, 0, "package filename", alpm_pkg_get_filename } , |
306 |
|
|
{ "base", (getter)_get_string_attribute, 0, "package base name", alpm_pkg_get_base }, |
307 |
|
|
{ "size", (getter)pyalpm_package_get_size, 0, "package size", NULL } , |
308 |
|
|
{ "isize", (getter)pyalpm_package_get_isize, 0, "installed size", NULL } , |
309 |
|
|
{ "reason", (getter)pyalpm_package_get_reason, 0, "install reason (0 = explicit, 1 = depend)", NULL } , |
310 |
|
|
{ "builddate", (getter)pyalpm_package_get_builddate, 0, "building time", NULL } , |
311 |
|
|
{ "installdate", (getter)pyalpm_package_get_installdate, 0, "install time", NULL } , |
312 |
|
|
{ "files", (getter)pyalpm_package_get_files, 0, "list of installed files", NULL } , |
313 |
|
|
{ "backup", (getter)_get_list_attribute, 0, "list of tuples (filename, md5sum)", &get_backup } , |
314 |
|
|
/* dependency information */ |
315 |
|
|
{ "depends", (getter)_get_list_attribute, 0, "list of dependencies", &get_depends } , |
316 |
|
|
{ "optdepends", (getter)_get_list_attribute, 0, "list of optional dependencies", &get_optdepends } , |
317 |
|
|
{ "checkdepends", (getter)_get_list_attribute, 0, "list of check dependencies", &get_checkdepends } , |
318 |
|
|
{ "makedepends", (getter)_get_list_attribute, 0, "list of make dependencies", &get_makedepends } , |
319 |
|
|
{ "conflicts", (getter)_get_list_attribute, 0, "list of conflicts", &get_conflicts } , |
320 |
|
|
{ "provides", (getter)_get_list_attribute, 0, "list of provided package names", &get_provides } , |
321 |
|
|
{ "replaces", (getter)_get_list_attribute, 0, "list of replaced packages", &get_replaces } , |
322 |
|
|
/* miscellaneous information */ |
323 |
|
|
{ "has_scriptlet", (getter)pyalpm_pkg_has_scriptlet, 0, "True if the package has an install script", NULL }, |
324 |
|
|
{ "download_size", (getter)pyalpm_pkg_download_size, 0, "predicted download size for this package", NULL }, |
325 |
|
|
{ NULL } |
326 |
|
|
}; |
327 |
|
|
|
328 |
|
|
static struct PyMethodDef pyalpm_pkg_methods[] = { |
329 |
|
|
{ "compute_requiredby", pyalpm_pkg_compute_requiredby, METH_NOARGS, |
330 |
|
|
"computes the list of packages requiring this package" }, |
331 |
|
|
{ NULL } |
332 |
|
|
}; |
333 |
|
|
|
334 |
|
|
PyTypeObject AlpmPackageType = { |
335 |
|
|
PyVarObject_HEAD_INIT(NULL, 0) |
336 |
|
|
"alpm.Package", /*tp_name*/ |
337 |
|
|
sizeof(AlpmPackage), /*tp_basicsize*/ |
338 |
|
|
0, /*tp_itemsize*/ |
339 |
|
|
.tp_dealloc = (destructor)pyalpm_package_dealloc, |
340 |
|
|
.tp_repr = pyalpm_pkg_repr, |
341 |
|
|
.tp_str = pyalpm_pkg_str, |
342 |
|
|
.tp_flags = Py_TPFLAGS_DEFAULT, |
343 |
|
|
.tp_doc = "Package object", |
344 |
|
|
.tp_methods = pyalpm_pkg_methods, |
345 |
|
|
.tp_getset = AlpmPackageGetSet, |
346 |
|
|
}; |
347 |
|
|
|
348 |
|
|
/** Initializes Package class in module */ |
349 |
|
3 |
void init_pyalpm_package(PyObject *module) { |
350 |
|
3 |
PyObject *type; |
351 |
|
|
|
352 |
✓✗ |
3 |
if (PyType_Ready(&AlpmPackageType) < 0) |
353 |
|
|
return; |
354 |
|
3 |
type = (PyObject*)&AlpmPackageType; |
355 |
|
3 |
Py_INCREF(type); |
356 |
|
3 |
PyModule_AddObject(module, "Package", type); |
357 |
|
|
|
358 |
|
|
/* package reasons */ |
359 |
|
3 |
PyModule_AddIntConstant(module, "PKG_REASON_EXPLICIT", ALPM_PKG_REASON_EXPLICIT); |
360 |
|
3 |
PyModule_AddIntConstant(module, "PKG_REASON_DEPEND", ALPM_PKG_REASON_DEPEND); |
361 |
|
|
|
362 |
|
|
/* signature check levels */ |
363 |
|
3 |
PyModule_AddIntConstant(module, "SIG_PACKAGE", ALPM_SIG_PACKAGE); |
364 |
|
3 |
PyModule_AddIntConstant(module, "SIG_PACKAGE_OPTIONAL", ALPM_SIG_PACKAGE_OPTIONAL); |
365 |
|
3 |
PyModule_AddIntConstant(module, "SIG_PACKAGE_MARGINAL_OK", ALPM_SIG_PACKAGE_MARGINAL_OK); |
366 |
|
3 |
PyModule_AddIntConstant(module, "SIG_PACKAGE_UNKNOWN_OK", ALPM_SIG_PACKAGE_UNKNOWN_OK); |
367 |
|
|
} |
368 |
|
|
|
369 |
|
|
/* vim: set ts=2 sw=2 et: */ |