~serge-hallyn/ubuntu/saucy/lxc/lxc-doc1

« back to all changes in this revision

Viewing changes to debian/patches/0003-python-module-fixes

  • Committer: Stéphane Graber
  • Date: 2013-04-18 20:04:55 UTC
  • Revision ID: stgraber@ubuntu.com-20130418200455-uueojm1cr8eky35e
Cherry pick python fixes

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Description: python: Lots of fixes in C extension
 
2
 Fixes a lot of issues found by a code review done by Barry Warsaw.
 
3
 .
 
4
 Those include:
 
5
  - Wrong signature for getters
 
6
  - Various memory leaks
 
7
  - Various optimizations
 
8
  - More consistent return values
 
9
  - Proper exception handling
 
10
 .
 
11
 Signed-off-by: Stéphane Graber <stgraber@ubuntu.com>
 
12
 Reported-by: Barry Warsaw <barry@ubuntu.com>
 
13
 Acked-by: Barry Warsaw <barry@ubuntu.com>
 
14
 Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
 
15
Author: Stéphane Graber <stgraber@ubuntu.com>
 
16
Origin: upstream
 
17
Forwarded: not-needed
 
18
 
 
19
diff --git a/src/python-lxc/lxc.c b/src/python-lxc/lxc.c
 
20
index 06d3396..85bab11 100644
 
21
--- a/src/python-lxc/lxc.c
 
22
+++ b/src/python-lxc/lxc.c
 
23
@@ -1,7 +1,7 @@
 
24
 /*
 
25
  * python-lxc: Python bindings for LXC
 
26
  *
 
27
- * (C) Copyright Canonical Ltd. 2012
 
28
+ * (C) Copyright Canonical Ltd. 2012-2013
 
29
  *
 
30
  * Authors:
 
31
  * Stéphane Graber <stgraber@ubuntu.com>
 
32
@@ -34,24 +34,40 @@ typedef struct {
 
33
 
 
34
 char**
 
35
 convert_tuple_to_char_pointer_array(PyObject *argv) {
 
36
-    int argc = PyTuple_Size(argv);
 
37
+    int argc = PyTuple_GET_SIZE(argv);
 
38
     int i;
 
39
 
 
40
     char **result = (char**) malloc(sizeof(char*)*argc + 1);
 
41
 
 
42
+    if (result == NULL) {
 
43
+        PyErr_SetNone(PyExc_MemoryError);
 
44
+        return NULL;
 
45
+    }
 
46
+
 
47
     for (i = 0; i < argc; i++) {
 
48
-        PyObject *pyobj = PyTuple_GetItem(argv, i);
 
49
+        PyObject *pyobj = PyTuple_GET_ITEM(argv, i);
 
50
+        assert(pyobj != NULL);
 
51
 
 
52
         char *str = NULL;
 
53
-        PyObject *pystr;
 
54
+        PyObject *pystr = NULL;
 
55
         if (!PyUnicode_Check(pyobj)) {
 
56
             PyErr_SetString(PyExc_ValueError, "Expected a string");
 
57
+            free(result);
 
58
             return NULL;
 
59
         }
 
60
 
 
61
         pystr = PyUnicode_AsUTF8String(pyobj);
 
62
+        if (pystr == NULL) {
 
63
+            PyErr_SetString(PyExc_ValueError, "Unable to convert to UTF-8");
 
64
+            free(result);
 
65
+            return NULL;
 
66
+        }
 
67
+
 
68
         str = PyBytes_AsString(pystr);
 
69
+        assert(str != NULL);
 
70
+
 
71
         memcpy((char *) &result[i], (char *) &str, sizeof(str));
 
72
+        Py_DECREF(pystr);
 
73
     }
 
74
 
 
75
     result[argc] = NULL;
 
76
@@ -62,6 +78,7 @@ convert_tuple_to_char_pointer_array(PyObject *argv) {
 
77
 static void
 
78
 Container_dealloc(Container* self)
 
79
 {
 
80
+    lxc_container_put(self->container);
 
81
     Py_TYPE(self)->tp_free((PyObject*)self);
 
82
 }
 
83
 
 
84
@@ -80,18 +97,27 @@ Container_init(Container *self, PyObject *args, PyObject *kwds)
 
85
 {
 
86
     static char *kwlist[] = {"name", "config_path", NULL};
 
87
     char *name = NULL;
 
88
+    PyObject *fs_config_path = NULL;
 
89
     char *config_path = NULL;
 
90
 
 
91
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", kwlist,
 
92
-                                      &name, &config_path))
 
93
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|O&", kwlist,
 
94
+                                      &name,
 
95
+                                      PyUnicode_FSConverter, &fs_config_path))
 
96
         return -1;
 
97
 
 
98
+    if (fs_config_path != NULL) {
 
99
+        config_path = PyBytes_AS_STRING(fs_config_path);
 
100
+        assert(config_path != NULL);
 
101
+    }
 
102
+
 
103
     self->container = lxc_container_new(name, config_path);
 
104
     if (!self->container) {
 
105
-        fprintf(stderr, "%d: error creating lxc_container %s\n", __LINE__, name);
 
106
+        Py_XDECREF(fs_config_path);
 
107
+        fprintf(stderr, "%d: error creating container %s\n", __LINE__, name);
 
108
         return -1;
 
109
     }
 
110
 
 
111
+    Py_XDECREF(fs_config_path);
 
112
     return 0;
 
113
 }
 
114
 
 
115
@@ -109,13 +135,14 @@ LXC_get_version(PyObject *self, PyObject *args)
 
116
 
 
117
 // Container properties
 
118
 static PyObject *
 
119
-Container_config_file_name(Container *self, PyObject *args, PyObject *kwds)
 
120
+Container_config_file_name(Container *self, void *closure)
 
121
 {
 
122
-    return PyUnicode_FromString(self->container->config_file_name(self->container));
 
123
+    return PyUnicode_FromString(
 
124
+                self->container->config_file_name(self->container));
 
125
 }
 
126
 
 
127
 static PyObject *
 
128
-Container_defined(Container *self, PyObject *args, PyObject *kwds)
 
129
+Container_defined(Container *self, void *closure)
 
130
 {
 
131
     if (self->container->is_defined(self->container)) {
 
132
         Py_RETURN_TRUE;
 
133
@@ -125,19 +152,19 @@ Container_defined(Container *self, PyObject *args, PyObject *kwds)
 
134
 }
 
135
 
 
136
 static PyObject *
 
137
-Container_init_pid(Container *self, PyObject *args, PyObject *kwds)
 
138
+Container_init_pid(Container *self, void *closure)
 
139
 {
 
140
-    return Py_BuildValue("i", self->container->init_pid(self->container));
 
141
+    return PyLong_FromLong(self->container->init_pid(self->container));
 
142
 }
 
143
 
 
144
 static PyObject *
 
145
-Container_name(Container *self, PyObject *args, PyObject *kwds)
 
146
+Container_name(Container *self, void *closure)
 
147
 {
 
148
     return PyUnicode_FromString(self->container->name);
 
149
 }
 
150
 
 
151
 static PyObject *
 
152
-Container_running(Container *self, PyObject *args, PyObject *kwds)
 
153
+Container_running(Container *self, void *closure)
 
154
 {
 
155
     if (self->container->is_running(self->container)) {
 
156
         Py_RETURN_TRUE;
 
157
@@ -147,7 +174,7 @@ Container_running(Container *self, PyObject *args, PyObject *kwds)
 
158
 }
 
159
 
 
160
 static PyObject *
 
161
-Container_state(Container *self, PyObject *args, PyObject *kwds)
 
162
+Container_state(Container *self, void *closure)
 
163
 {
 
164
     return PyUnicode_FromString(self->container->state(self->container));
 
165
 }
 
166
@@ -159,9 +186,9 @@ Container_clear_config_item(Container *self, PyObject *args, PyObject *kwds)
 
167
     static char *kwlist[] = {"key", NULL};
 
168
     char *key = NULL;
 
169
 
 
170
-    if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|", kwlist,
 
171
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist,
 
172
                                       &key))
 
173
-        Py_RETURN_FALSE;
 
174
+        return NULL;
 
175
 
 
176
     if (self->container->clear_config_item(self->container, key)) {
 
177
         Py_RETURN_TRUE;
 
178
@@ -175,25 +202,40 @@ Container_create(Container *self, PyObject *args, PyObject *kwds)
 
179
 {
 
180
     char* template_name = NULL;
 
181
     char** create_args = {NULL};
 
182
-    PyObject *vargs = NULL;
 
183
+    PyObject *retval = NULL, *vargs = NULL;
 
184
     static char *kwlist[] = {"template", "args", NULL};
 
185
 
 
186
     if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|O", kwlist,
 
187
                                       &template_name, &vargs))
 
188
-        Py_RETURN_FALSE;
 
189
+        return NULL;
 
190
 
 
191
-    if (vargs && PyTuple_Check(vargs)) {
 
192
-        create_args = convert_tuple_to_char_pointer_array(vargs);
 
193
-        if (!create_args) {
 
194
+    if (vargs) {
 
195
+        if (PyTuple_Check(vargs)) {
 
196
+            create_args = convert_tuple_to_char_pointer_array(vargs);
 
197
+            if (!create_args) {
 
198
+                return NULL;
 
199
+            }
 
200
+        }
 
201
+        else {
 
202
+            PyErr_SetString(PyExc_ValueError, "args needs to be a tuple");
 
203
             return NULL;
 
204
         }
 
205
     }
 
206
 
 
207
-    if (self->container->create(self->container, template_name, create_args)) {
 
208
-        Py_RETURN_TRUE;
 
209
+    if (self->container->create(self->container, template_name, create_args))
 
210
+        retval = Py_True;
 
211
+    else
 
212
+        retval = Py_False;
 
213
+
 
214
+    if (vargs) {
 
215
+        /* We cannot have gotten here unless vargs was given and create_args
 
216
+         * was successfully allocated.
 
217
+         */
 
218
+        free(create_args);
 
219
     }
 
220
 
 
221
-    Py_RETURN_FALSE;
 
222
+    Py_INCREF(retval);
 
223
+    return retval;
 
224
 }
 
225
 
 
226
 static PyObject *
 
227
@@ -222,23 +264,33 @@ Container_get_cgroup_item(Container *self, PyObject *args, PyObject *kwds)
 
228
     static char *kwlist[] = {"key", NULL};
 
229
     char* key = NULL;
 
230
     int len = 0;
 
231
+    PyObject *ret = NULL;
 
232
 
 
233
-    if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|", kwlist,
 
234
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist,
 
235
                                       &key))
 
236
-        Py_RETURN_FALSE;
 
237
+        return NULL;
 
238
 
 
239
     len = self->container->get_cgroup_item(self->container, key, NULL, 0);
 
240
 
 
241
-    if (len <= 0) {
 
242
-        Py_RETURN_FALSE;
 
243
+    if (len < 0) {
 
244
+        PyErr_SetString(PyExc_KeyError, "Invalid cgroup entry");
 
245
+        return NULL;
 
246
     }
 
247
 
 
248
     char* value = (char*) malloc(sizeof(char)*len + 1);
 
249
-    if (self->container->get_cgroup_item(self->container, key, value, len + 1) != len) {
 
250
-        Py_RETURN_FALSE;
 
251
+    if (value == NULL)
 
252
+        return PyErr_NoMemory();
 
253
+
 
254
+    if (self->container->get_cgroup_item(self->container,
 
255
+                                            key, value, len + 1) != len) {
 
256
+        PyErr_SetString(PyExc_ValueError, "Unable to read config value");
 
257
+        free(value);
 
258
+        return NULL;
 
259
     }
 
260
 
 
261
-    return PyUnicode_FromString(value);
 
262
+    ret = PyUnicode_FromString(value);
 
263
+    free(value);
 
264
+    return ret;
 
265
 }
 
266
 
 
267
 static PyObject *
 
268
@@ -247,29 +299,40 @@ Container_get_config_item(Container *self, PyObject *args, PyObject *kwds)
 
269
     static char *kwlist[] = {"key", NULL};
 
270
     char* key = NULL;
 
271
     int len = 0;
 
272
+    PyObject *ret = NULL;
 
273
 
 
274
     if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|", kwlist,
 
275
                                       &key))
 
276
-        Py_RETURN_FALSE;
 
277
+        return NULL;
 
278
 
 
279
     len = self->container->get_config_item(self->container, key, NULL, 0);
 
280
 
 
281
-    if (len <= 0) {
 
282
-        Py_RETURN_FALSE;
 
283
+    if (len < 0) {
 
284
+        PyErr_SetString(PyExc_KeyError, "Invalid configuration key");
 
285
+        return NULL;
 
286
     }
 
287
 
 
288
     char* value = (char*) malloc(sizeof(char)*len + 1);
 
289
-    if (self->container->get_config_item(self->container, key, value, len + 1) != len) {
 
290
-        Py_RETURN_FALSE;
 
291
+    if (value == NULL)
 
292
+        return PyErr_NoMemory();
 
293
+
 
294
+    if (self->container->get_config_item(self->container,
 
295
+                                            key, value, len + 1) != len) {
 
296
+        PyErr_SetString(PyExc_ValueError, "Unable to read config value");
 
297
+        free(value);
 
298
+        return NULL;
 
299
     }
 
300
 
 
301
-    return PyUnicode_FromString(value);
 
302
+    ret = PyUnicode_FromString(value);
 
303
+    free(value);
 
304
+    return ret;
 
305
 }
 
306
 
 
307
 static PyObject *
 
308
 Container_get_config_path(Container *self, PyObject *args, PyObject *kwds)
 
309
 {
 
310
-    return PyUnicode_FromString(self->container->get_config_path(self->container));
 
311
+    return PyUnicode_FromString(
 
312
+                self->container->get_config_path(self->container));
 
313
 }
 
314
 
 
315
 static PyObject *
 
316
@@ -278,39 +341,57 @@ Container_get_keys(Container *self, PyObject *args, PyObject *kwds)
 
317
     static char *kwlist[] = {"key", NULL};
 
318
     char* key = NULL;
 
319
     int len = 0;
 
320
+    PyObject *ret = NULL;
 
321
 
 
322
     if (! PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist,
 
323
                                       &key))
 
324
-        Py_RETURN_FALSE;
 
325
+        return NULL;
 
326
 
 
327
     len = self->container->get_keys(self->container, key, NULL, 0);
 
328
 
 
329
-    if (len <= 0) {
 
330
-        Py_RETURN_FALSE;
 
331
+    if (len < 0) {
 
332
+        PyErr_SetString(PyExc_KeyError, "Invalid configuration key");
 
333
+        return NULL;
 
334
     }
 
335
 
 
336
     char* value = (char*) malloc(sizeof(char)*len + 1);
 
337
-    if (self->container->get_keys(self->container, key, value, len + 1) != len) {
 
338
-        Py_RETURN_FALSE;
 
339
+    if (value == NULL)
 
340
+        return PyErr_NoMemory();
 
341
+
 
342
+    if (self->container->get_keys(self->container,
 
343
+                                    key, value, len + 1) != len) {
 
344
+        PyErr_SetString(PyExc_ValueError, "Unable to read config keys");
 
345
+        free(value);
 
346
+        return NULL;
 
347
     }
 
348
 
 
349
-    return PyUnicode_FromString(value);
 
350
+    ret = PyUnicode_FromString(value);
 
351
+    free(value);
 
352
+    return ret;
 
353
 }
 
354
 
 
355
 static PyObject *
 
356
 Container_load_config(Container *self, PyObject *args, PyObject *kwds)
 
357
 {
 
358
     static char *kwlist[] = {"path", NULL};
 
359
+    PyObject *fs_path = NULL;
 
360
     char* path = NULL;
 
361
 
 
362
-    if (! PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist,
 
363
-                                      &path))
 
364
-        Py_RETURN_FALSE;
 
365
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kwlist,
 
366
+                                      PyUnicode_FSConverter, &fs_path))
 
367
+        return NULL;
 
368
+
 
369
+    if (fs_path != NULL) {
 
370
+        path = PyBytes_AS_STRING(fs_path);
 
371
+        assert(path != NULL);
 
372
+    }
 
373
 
 
374
     if (self->container->load_config(self->container, path)) {
 
375
+        Py_XDECREF(fs_path);
 
376
         Py_RETURN_TRUE;
 
377
     }
 
378
 
 
379
+    Py_XDECREF(fs_path);
 
380
     Py_RETURN_FALSE;
 
381
 }
 
382
 
 
383
@@ -318,16 +399,24 @@ static PyObject *
 
384
 Container_save_config(Container *self, PyObject *args, PyObject *kwds)
 
385
 {
 
386
     static char *kwlist[] = {"path", NULL};
 
387
+    PyObject *fs_path = NULL;
 
388
     char* path = NULL;
 
389
 
 
390
-    if (! PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist,
 
391
-                                      &path))
 
392
-        Py_RETURN_FALSE;
 
393
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kwlist,
 
394
+                                      PyUnicode_FSConverter, &fs_path))
 
395
+        return NULL;
 
396
+
 
397
+    if (fs_path != NULL) {
 
398
+        path = PyBytes_AS_STRING(fs_path);
 
399
+        assert(path != NULL);
 
400
+    }
 
401
 
 
402
     if (self->container->save_config(self->container, path)) {
 
403
+        Py_XDECREF(fs_path);
 
404
         Py_RETURN_TRUE;
 
405
     }
 
406
 
 
407
+    Py_XDECREF(fs_path);
 
408
     Py_RETURN_FALSE;
 
409
 }
 
410
 
 
411
@@ -338,9 +427,9 @@ Container_set_cgroup_item(Container *self, PyObject *args, PyObject *kwds)
 
412
     char *key = NULL;
 
413
     char *value = NULL;
 
414
 
 
415
-    if (! PyArg_ParseTupleAndKeywords(args, kwds, "ss|", kwlist,
 
416
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "ss", kwlist,
 
417
                                       &key, &value))
 
418
-        Py_RETURN_FALSE;
 
419
+        return NULL;
 
420
 
 
421
     if (self->container->set_cgroup_item(self->container, key, value)) {
 
422
         Py_RETURN_TRUE;
 
423
@@ -356,9 +445,9 @@ Container_set_config_item(Container *self, PyObject *args, PyObject *kwds)
 
424
     char *key = NULL;
 
425
     char *value = NULL;
 
426
 
 
427
-    if (! PyArg_ParseTupleAndKeywords(args, kwds, "ss|", kwlist,
 
428
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "ss", kwlist,
 
429
                                       &key, &value))
 
430
-        Py_RETURN_FALSE;
 
431
+        return NULL;
 
432
 
 
433
     if (self->container->set_config_item(self->container, key, value)) {
 
434
         Py_RETURN_TRUE;
 
435
@@ -373,9 +462,9 @@ Container_set_config_path(Container *self, PyObject *args, PyObject *kwds)
 
436
     static char *kwlist[] = {"path", NULL};
 
437
     char *path = NULL;
 
438
 
 
439
-    if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|", kwlist,
 
440
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist,
 
441
                                       &path))
 
442
-        Py_RETURN_FALSE;
 
443
+        return NULL;
 
444
 
 
445
     if (self->container->set_config_path(self->container, path)) {
 
446
         Py_RETURN_TRUE;
 
447
@@ -392,7 +481,7 @@ Container_shutdown(Container *self, PyObject *args, PyObject *kwds)
 
448
 
 
449
     if (! PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwlist,
 
450
                                       &timeout))
 
451
-        Py_RETURN_FALSE;
 
452
+        return NULL;
 
453
 
 
454
     if (self->container->shutdown(self->container, timeout)) {
 
455
         Py_RETURN_TRUE;
 
456
@@ -405,13 +494,13 @@ static PyObject *
 
457
 Container_start(Container *self, PyObject *args, PyObject *kwds)
 
458
 {
 
459
     char** init_args = {NULL};
 
460
-    PyObject *useinit = NULL, *vargs = NULL;
 
461
+    PyObject *useinit = NULL, *retval = NULL, *vargs = NULL;
 
462
     int init_useinit = 0;
 
463
     static char *kwlist[] = {"useinit", "cmd", NULL};
 
464
 
 
465
     if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist,
 
466
                                       &useinit, &vargs))
 
467
-        Py_RETURN_FALSE;
 
468
+        return NULL;
 
469
 
 
470
     if (useinit && useinit == Py_True) {
 
471
         init_useinit = 1;
 
472
@@ -426,11 +515,20 @@ Container_start(Container *self, PyObject *args, PyObject *kwds)
 
473
 
 
474
     self->container->want_daemonize(self->container);
 
475
 
 
476
-    if (self->container->start(self->container, init_useinit, init_args)) {
 
477
-        Py_RETURN_TRUE;
 
478
+    if (self->container->start(self->container, init_useinit, init_args))
 
479
+        retval = Py_True;
 
480
+    else
 
481
+        retval = Py_False;
 
482
+
 
483
+    if (vargs) {
 
484
+        /* We cannot have gotten here unless vargs was given and create_args
 
485
+         * was successfully allocated.
 
486
+         */
 
487
+        free(init_args);
 
488
     }
 
489
 
 
490
-    Py_RETURN_FALSE;
 
491
+    Py_INCREF(retval);
 
492
+    return retval;
 
493
 }
 
494
 
 
495
 static PyObject *
 
496
@@ -462,7 +560,7 @@ Container_wait(Container *self, PyObject *args, PyObject *kwds)
 
497
 
 
498
     if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|i", kwlist,
 
499
                                       &state, &timeout))
 
500
-        Py_RETURN_FALSE;
 
501
+        return NULL;
 
502
 
 
503
     if (self->container->wait(self->container, state, timeout)) {
 
504
         Py_RETURN_TRUE;
 
505
@@ -473,125 +571,143 @@ Container_wait(Container *self, PyObject *args, PyObject *kwds)
 
506
 
 
507
 static PyGetSetDef Container_getseters[] = {
 
508
     {"config_file_name",
 
509
-     (getter)Container_config_file_name, 0,
 
510
+     (getter)Container_config_file_name, NULL,
 
511
      "Path to the container configuration",
 
512
      NULL},
 
513
     {"defined",
 
514
-     (getter)Container_defined, 0,
 
515
+     (getter)Container_defined, NULL,
 
516
      "Boolean indicating whether the container configuration exists",
 
517
      NULL},
 
518
     {"init_pid",
 
519
-     (getter)Container_init_pid, 0,
 
520
+     (getter)Container_init_pid, NULL,
 
521
      "PID of the container's init process in the host's PID namespace",
 
522
      NULL},
 
523
     {"name",
 
524
-     (getter)Container_name, 0,
 
525
+     (getter)Container_name, NULL,
 
526
      "Container name",
 
527
      NULL},
 
528
     {"running",
 
529
-     (getter)Container_running, 0,
 
530
+     (getter)Container_running, NULL,
 
531
      "Boolean indicating whether the container is running or not",
 
532
      NULL},
 
533
     {"state",
 
534
-     (getter)Container_state, 0,
 
535
+     (getter)Container_state, NULL,
 
536
      "Container state",
 
537
      NULL},
 
538
     {NULL, NULL, NULL, NULL, NULL}
 
539
 };
 
540
 
 
541
 static PyMethodDef Container_methods[] = {
 
542
-    {"clear_config_item", (PyCFunction)Container_clear_config_item, METH_VARARGS | METH_KEYWORDS,
 
543
+    {"clear_config_item", (PyCFunction)Container_clear_config_item,
 
544
+     METH_VARARGS|METH_KEYWORDS,
 
545
      "clear_config_item(key) -> boolean\n"
 
546
      "\n"
 
547
      "Clear the current value of a config key."
 
548
     },
 
549
-    {"create", (PyCFunction)Container_create, METH_VARARGS | METH_KEYWORDS,
 
550
+    {"create", (PyCFunction)Container_create,
 
551
+     METH_VARARGS|METH_KEYWORDS,
 
552
      "create(template, args = (,)) -> boolean\n"
 
553
      "\n"
 
554
      "Create a new rootfs for the container, using the given template "
 
555
      "and passing some optional arguments to it."
 
556
     },
 
557
-    {"destroy", (PyCFunction)Container_destroy, METH_NOARGS,
 
558
+    {"destroy", (PyCFunction)Container_destroy,
 
559
+     METH_NOARGS,
 
560
      "destroy() -> boolean\n"
 
561
      "\n"
 
562
      "Destroys the container."
 
563
     },
 
564
-    {"freeze", (PyCFunction)Container_freeze, METH_NOARGS,
 
565
+    {"freeze", (PyCFunction)Container_freeze,
 
566
+     METH_NOARGS,
 
567
      "freeze() -> boolean\n"
 
568
      "\n"
 
569
      "Freezes the container and returns its return code."
 
570
     },
 
571
-    {"get_cgroup_item", (PyCFunction)Container_get_cgroup_item, METH_VARARGS | METH_KEYWORDS,
 
572
+    {"get_cgroup_item", (PyCFunction)Container_get_cgroup_item,
 
573
+     METH_VARARGS|METH_KEYWORDS,
 
574
      "get_cgroup_item(key) -> string\n"
 
575
      "\n"
 
576
      "Get the current value of a cgroup entry."
 
577
     },
 
578
-    {"get_config_item", (PyCFunction)Container_get_config_item, METH_VARARGS | METH_KEYWORDS,
 
579
+    {"get_config_item", (PyCFunction)Container_get_config_item,
 
580
+     METH_VARARGS|METH_KEYWORDS,
 
581
      "get_config_item(key) -> string\n"
 
582
      "\n"
 
583
      "Get the current value of a config key."
 
584
     },
 
585
-    {"get_config_path", (PyCFunction)Container_get_config_path, METH_NOARGS,
 
586
+    {"get_config_path", (PyCFunction)Container_get_config_path,
 
587
+     METH_NOARGS,
 
588
      "get_config_path() -> string\n"
 
589
      "\n"
 
590
      "Return the LXC config path (where the containers are stored)."
 
591
     },
 
592
-    {"get_keys", (PyCFunction)Container_get_keys, METH_VARARGS | METH_KEYWORDS,
 
593
+    {"get_keys", (PyCFunction)Container_get_keys,
 
594
+     METH_VARARGS|METH_KEYWORDS,
 
595
      "get_keys(key) -> string\n"
 
596
      "\n"
 
597
      "Get a list of valid sub-keys for a key."
 
598
     },
 
599
-    {"load_config", (PyCFunction)Container_load_config, METH_VARARGS | METH_KEYWORDS,
 
600
+    {"load_config", (PyCFunction)Container_load_config,
 
601
+     METH_VARARGS|METH_KEYWORDS,
 
602
      "load_config(path = DEFAULT) -> boolean\n"
 
603
      "\n"
 
604
      "Read the container configuration from its default "
 
605
      "location or from an alternative location if provided."
 
606
     },
 
607
-    {"save_config", (PyCFunction)Container_save_config, METH_VARARGS | METH_KEYWORDS,
 
608
+    {"save_config", (PyCFunction)Container_save_config,
 
609
+     METH_VARARGS|METH_KEYWORDS,
 
610
      "save_config(path = DEFAULT) -> boolean\n"
 
611
      "\n"
 
612
      "Save the container configuration to its default "
 
613
      "location or to an alternative location if provided."
 
614
     },
 
615
-    {"set_cgroup_item", (PyCFunction)Container_set_cgroup_item, METH_VARARGS | METH_KEYWORDS,
 
616
+    {"set_cgroup_item", (PyCFunction)Container_set_cgroup_item,
 
617
+     METH_VARARGS|METH_KEYWORDS,
 
618
      "set_cgroup_item(key, value) -> boolean\n"
 
619
      "\n"
 
620
      "Set a cgroup entry to the provided value."
 
621
     },
 
622
-    {"set_config_item", (PyCFunction)Container_set_config_item, METH_VARARGS | METH_KEYWORDS,
 
623
+    {"set_config_item", (PyCFunction)Container_set_config_item,
 
624
+     METH_VARARGS|METH_KEYWORDS,
 
625
      "set_config_item(key, value) -> boolean\n"
 
626
      "\n"
 
627
      "Set a config key to the provided value."
 
628
     },
 
629
-    {"set_config_path", (PyCFunction)Container_set_config_path, METH_VARARGS | METH_KEYWORDS,
 
630
+    {"set_config_path", (PyCFunction)Container_set_config_path,
 
631
+     METH_VARARGS|METH_KEYWORDS,
 
632
      "set_config_path(path) -> boolean\n"
 
633
      "\n"
 
634
      "Set the LXC config path (where the containers are stored)."
 
635
     },
 
636
-    {"shutdown", (PyCFunction)Container_shutdown, METH_VARARGS | METH_KEYWORDS,
 
637
+    {"shutdown", (PyCFunction)Container_shutdown,
 
638
+     METH_VARARGS|METH_KEYWORDS,
 
639
      "shutdown(timeout = -1) -> boolean\n"
 
640
      "\n"
 
641
      "Sends SIGPWR to the container and wait for it to shutdown "
 
642
      "unless timeout is set to a positive value, in which case "
 
643
      "the container will be killed when the timeout is reached."
 
644
     },
 
645
-    {"start", (PyCFunction)Container_start, METH_VARARGS | METH_KEYWORDS,
 
646
+    {"start", (PyCFunction)Container_start,
 
647
+     METH_VARARGS|METH_KEYWORDS,
 
648
      "start(useinit = False, cmd = (,)) -> boolean\n"
 
649
      "\n"
 
650
      "Start the container, optionally using lxc-init and "
 
651
      "an alternate init command, then returns its return code."
 
652
     },
 
653
-    {"stop", (PyCFunction)Container_stop, METH_NOARGS,
 
654
+    {"stop", (PyCFunction)Container_stop,
 
655
+     METH_NOARGS,
 
656
      "stop() -> boolean\n"
 
657
      "\n"
 
658
      "Stop the container and returns its return code."
 
659
     },
 
660
-    {"unfreeze", (PyCFunction)Container_unfreeze, METH_NOARGS,
 
661
+    {"unfreeze", (PyCFunction)Container_unfreeze,
 
662
+     METH_NOARGS,
 
663
      "unfreeze() -> boolean\n"
 
664
      "\n"
 
665
      "Unfreezes the container and returns its return code."
 
666
     },
 
667
-    {"wait", (PyCFunction)Container_wait, METH_VARARGS | METH_KEYWORDS,
 
668
+    {"wait", (PyCFunction)Container_wait,
 
669
+     METH_VARARGS|METH_KEYWORDS,
 
670
      "wait(state, timeout = -1) -> boolean\n"
 
671
      "\n"
 
672
      "Wait for the container to reach a given state or timeout."