~ubuntu-branches/ubuntu/trusty/python3.4/trusty-proposed

« back to all changes in this revision

Viewing changes to Modules/_gdbmmodule.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-11-25 09:44:27 UTC
  • Revision ID: package-import@ubuntu.com-20131125094427-lzxj8ap5w01lmo7f
Tags: upstream-3.4~b1
ImportĀ upstreamĀ versionĀ 3.4~b1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/* DBM module using dictionary interface */
 
3
/* Author: Anthony Baxter, after dbmmodule.c */
 
4
/* Doc strings: Mitch Chapman */
 
5
 
 
6
 
 
7
#include "Python.h"
 
8
 
 
9
#include <sys/types.h>
 
10
#include <sys/stat.h>
 
11
#include <fcntl.h>
 
12
#include "gdbm.h"
 
13
 
 
14
#if defined(WIN32) && !defined(__CYGWIN__)
 
15
#include "gdbmerrno.h"
 
16
extern const char * gdbm_strerror(gdbm_error);
 
17
#endif
 
18
 
 
19
PyDoc_STRVAR(gdbmmodule__doc__,
 
20
"This module provides an interface to the GNU DBM (GDBM) library.\n\
 
21
\n\
 
22
This module is quite similar to the dbm module, but uses GDBM instead to\n\
 
23
provide some additional functionality. Please note that the file formats\n\
 
24
created by GDBM and dbm are incompatible. \n\
 
25
\n\
 
26
GDBM objects behave like mappings (dictionaries), except that keys and\n\
 
27
values are always strings. Printing a GDBM object doesn't print the\n\
 
28
keys and values, and the items() and values() methods are not\n\
 
29
supported.");
 
30
 
 
31
typedef struct {
 
32
    PyObject_HEAD
 
33
    int di_size;        /* -1 means recompute */
 
34
    GDBM_FILE di_dbm;
 
35
} dbmobject;
 
36
 
 
37
static PyTypeObject Dbmtype;
 
38
 
 
39
#define is_dbmobject(v) (Py_TYPE(v) == &Dbmtype)
 
40
#define check_dbmobject_open(v) if ((v)->di_dbm == NULL) \
 
41
    { PyErr_SetString(DbmError, "GDBM object has already been closed"); \
 
42
      return NULL; }
 
43
 
 
44
 
 
45
 
 
46
static PyObject *DbmError;
 
47
 
 
48
PyDoc_STRVAR(gdbm_object__doc__,
 
49
"This object represents a GDBM database.\n\
 
50
GDBM objects behave like mappings (dictionaries), except that keys and\n\
 
51
values are always strings. Printing a GDBM object doesn't print the\n\
 
52
keys and values, and the items() and values() methods are not\n\
 
53
supported.\n\
 
54
\n\
 
55
GDBM objects also support additional operations such as firstkey,\n\
 
56
nextkey, reorganize, and sync.");
 
57
 
 
58
static PyObject *
 
59
newdbmobject(char *file, int flags, int mode)
 
60
{
 
61
    dbmobject *dp;
 
62
 
 
63
    dp = PyObject_New(dbmobject, &Dbmtype);
 
64
    if (dp == NULL)
 
65
        return NULL;
 
66
    dp->di_size = -1;
 
67
    errno = 0;
 
68
    if ((dp->di_dbm = gdbm_open(file, 0, flags, mode, NULL)) == 0) {
 
69
        if (errno != 0)
 
70
            PyErr_SetFromErrno(DbmError);
 
71
        else
 
72
            PyErr_SetString(DbmError, gdbm_strerror(gdbm_errno));
 
73
        Py_DECREF(dp);
 
74
        return NULL;
 
75
    }
 
76
    return (PyObject *)dp;
 
77
}
 
78
 
 
79
/* Methods */
 
80
 
 
81
static void
 
82
dbm_dealloc(dbmobject *dp)
 
83
{
 
84
    if (dp->di_dbm)
 
85
        gdbm_close(dp->di_dbm);
 
86
    PyObject_Del(dp);
 
87
}
 
88
 
 
89
static Py_ssize_t
 
90
dbm_length(dbmobject *dp)
 
91
{
 
92
    if (dp->di_dbm == NULL) {
 
93
        PyErr_SetString(DbmError, "GDBM object has already been closed");
 
94
        return -1;
 
95
    }
 
96
    if (dp->di_size < 0) {
 
97
        datum key,okey;
 
98
        int size;
 
99
        okey.dsize=0;
 
100
        okey.dptr=NULL;
 
101
 
 
102
        size = 0;
 
103
        for (key=gdbm_firstkey(dp->di_dbm); key.dptr;
 
104
             key = gdbm_nextkey(dp->di_dbm,okey)) {
 
105
            size++;
 
106
            if(okey.dsize) free(okey.dptr);
 
107
            okey=key;
 
108
        }
 
109
        dp->di_size = size;
 
110
    }
 
111
    return dp->di_size;
 
112
}
 
113
 
 
114
static PyObject *
 
115
dbm_subscript(dbmobject *dp, PyObject *key)
 
116
{
 
117
    PyObject *v;
 
118
    datum drec, krec;
 
119
 
 
120
    if (!PyArg_Parse(key, "s#", &krec.dptr, &krec.dsize) )
 
121
        return NULL;
 
122
 
 
123
    if (dp->di_dbm == NULL) {
 
124
        PyErr_SetString(DbmError,
 
125
                        "GDBM object has already been closed");
 
126
        return NULL;
 
127
    }
 
128
    drec = gdbm_fetch(dp->di_dbm, krec);
 
129
    if (drec.dptr == 0) {
 
130
        PyErr_SetObject(PyExc_KeyError, key);
 
131
        return NULL;
 
132
    }
 
133
    v = PyBytes_FromStringAndSize(drec.dptr, drec.dsize);
 
134
    free(drec.dptr);
 
135
    return v;
 
136
}
 
137
 
 
138
PyDoc_STRVAR(dbm_get__doc__,
 
139
"get(key[, default]) -> value\n\
 
140
Get the value for key, or default if not present; if not given,\n\
 
141
default is None.");
 
142
 
 
143
static PyObject *
 
144
dbm_get(dbmobject *dp, PyObject *args)
 
145
{
 
146
    PyObject *v, *res;
 
147
    PyObject *def = Py_None;
 
148
 
 
149
    if (!PyArg_UnpackTuple(args, "get", 1, 2, &v, &def))
 
150
        return NULL;
 
151
    res = dbm_subscript(dp, v);
 
152
    if (res == NULL && PyErr_ExceptionMatches(PyExc_KeyError)) {
 
153
        PyErr_Clear();
 
154
        Py_INCREF(def);
 
155
        return def;
 
156
    }
 
157
    return res;
 
158
}
 
159
 
 
160
static int
 
161
dbm_ass_sub(dbmobject *dp, PyObject *v, PyObject *w)
 
162
{
 
163
    datum krec, drec;
 
164
 
 
165
    if (!PyArg_Parse(v, "s#", &krec.dptr, &krec.dsize) ) {
 
166
        PyErr_SetString(PyExc_TypeError,
 
167
                        "gdbm mappings have bytes or string indices only");
 
168
        return -1;
 
169
    }
 
170
    if (dp->di_dbm == NULL) {
 
171
        PyErr_SetString(DbmError,
 
172
                        "GDBM object has already been closed");
 
173
        return -1;
 
174
    }
 
175
    dp->di_size = -1;
 
176
    if (w == NULL) {
 
177
        if (gdbm_delete(dp->di_dbm, krec) < 0) {
 
178
            PyErr_SetObject(PyExc_KeyError, v);
 
179
            return -1;
 
180
        }
 
181
    }
 
182
    else {
 
183
        if (!PyArg_Parse(w, "s#", &drec.dptr, &drec.dsize)) {
 
184
            PyErr_SetString(PyExc_TypeError,
 
185
                            "gdbm mappings have byte or string elements only");
 
186
            return -1;
 
187
        }
 
188
        errno = 0;
 
189
        if (gdbm_store(dp->di_dbm, krec, drec, GDBM_REPLACE) < 0) {
 
190
            if (errno != 0)
 
191
                PyErr_SetFromErrno(DbmError);
 
192
            else
 
193
                PyErr_SetString(DbmError,
 
194
                                gdbm_strerror(gdbm_errno));
 
195
            return -1;
 
196
        }
 
197
    }
 
198
    return 0;
 
199
}
 
200
 
 
201
PyDoc_STRVAR(dbm_setdefault__doc__,
 
202
"setdefault(key[, default]) -> value\n\
 
203
Get value for key, or set it to default and return default if not present;\n\
 
204
if not given, default is None.");
 
205
 
 
206
static PyObject *
 
207
dbm_setdefault(dbmobject *dp, PyObject *args)
 
208
{
 
209
    PyObject *v, *res;
 
210
    PyObject *def = Py_None;
 
211
 
 
212
    if (!PyArg_UnpackTuple(args, "setdefault", 1, 2, &v, &def))
 
213
        return NULL;
 
214
    res = dbm_subscript(dp, v);
 
215
    if (res == NULL && PyErr_ExceptionMatches(PyExc_KeyError)) {
 
216
        PyErr_Clear();
 
217
        if (dbm_ass_sub(dp, v, def) < 0)
 
218
            return NULL;
 
219
        return dbm_subscript(dp, v);
 
220
    }
 
221
    return res;
 
222
}
 
223
 
 
224
static PyMappingMethods dbm_as_mapping = {
 
225
    (lenfunc)dbm_length,                /*mp_length*/
 
226
    (binaryfunc)dbm_subscript,          /*mp_subscript*/
 
227
    (objobjargproc)dbm_ass_sub,         /*mp_ass_subscript*/
 
228
};
 
229
 
 
230
PyDoc_STRVAR(dbm_close__doc__,
 
231
"close() -> None\n\
 
232
Closes the database.");
 
233
 
 
234
static PyObject *
 
235
dbm_close(dbmobject *dp, PyObject *unused)
 
236
{
 
237
    if (dp->di_dbm)
 
238
        gdbm_close(dp->di_dbm);
 
239
    dp->di_dbm = NULL;
 
240
    Py_INCREF(Py_None);
 
241
    return Py_None;
 
242
}
 
243
 
 
244
/* XXX Should return a set or a set view */
 
245
PyDoc_STRVAR(dbm_keys__doc__,
 
246
"keys() -> list_of_keys\n\
 
247
Get a list of all keys in the database.");
 
248
 
 
249
static PyObject *
 
250
dbm_keys(dbmobject *dp, PyObject *unused)
 
251
{
 
252
    PyObject *v, *item;
 
253
    datum key, nextkey;
 
254
    int err;
 
255
 
 
256
    if (dp == NULL || !is_dbmobject(dp)) {
 
257
        PyErr_BadInternalCall();
 
258
        return NULL;
 
259
    }
 
260
    check_dbmobject_open(dp);
 
261
 
 
262
    v = PyList_New(0);
 
263
    if (v == NULL)
 
264
        return NULL;
 
265
 
 
266
    key = gdbm_firstkey(dp->di_dbm);
 
267
    while (key.dptr) {
 
268
        item = PyBytes_FromStringAndSize(key.dptr, key.dsize);
 
269
        if (item == NULL) {
 
270
            free(key.dptr);
 
271
            Py_DECREF(v);
 
272
            return NULL;
 
273
        }
 
274
        err = PyList_Append(v, item);
 
275
        Py_DECREF(item);
 
276
        if (err != 0) {
 
277
            free(key.dptr);
 
278
            Py_DECREF(v);
 
279
            return NULL;
 
280
        }
 
281
        nextkey = gdbm_nextkey(dp->di_dbm, key);
 
282
        free(key.dptr);
 
283
        key = nextkey;
 
284
    }
 
285
    return v;
 
286
}
 
287
 
 
288
static int
 
289
dbm_contains(PyObject *self, PyObject *arg)
 
290
{
 
291
    dbmobject *dp = (dbmobject *)self;
 
292
    datum key;
 
293
    Py_ssize_t size;
 
294
 
 
295
    if ((dp)->di_dbm == NULL) {
 
296
        PyErr_SetString(DbmError,
 
297
                        "GDBM object has already been closed");
 
298
        return -1;
 
299
    }
 
300
    if (PyUnicode_Check(arg)) {
 
301
        key.dptr = PyUnicode_AsUTF8AndSize(arg, &size);
 
302
        key.dsize = size;
 
303
        if (key.dptr == NULL)
 
304
            return -1;
 
305
    }
 
306
    else if (!PyBytes_Check(arg)) {
 
307
        PyErr_Format(PyExc_TypeError,
 
308
                     "gdbm key must be bytes or string, not %.100s",
 
309
                     arg->ob_type->tp_name);
 
310
        return -1;
 
311
    }
 
312
    else {
 
313
        key.dptr = PyBytes_AS_STRING(arg);
 
314
        key.dsize = PyBytes_GET_SIZE(arg);
 
315
    }
 
316
    return gdbm_exists(dp->di_dbm, key);
 
317
}
 
318
 
 
319
static PySequenceMethods dbm_as_sequence = {
 
320
        0,                      /* sq_length */
 
321
        0,                      /* sq_concat */
 
322
        0,                      /* sq_repeat */
 
323
        0,                      /* sq_item */
 
324
        0,                      /* sq_slice */
 
325
        0,                      /* sq_ass_item */
 
326
        0,                      /* sq_ass_slice */
 
327
        dbm_contains,           /* sq_contains */
 
328
        0,                      /* sq_inplace_concat */
 
329
        0,                      /* sq_inplace_repeat */
 
330
};
 
331
 
 
332
PyDoc_STRVAR(dbm_firstkey__doc__,
 
333
"firstkey() -> key\n\
 
334
It's possible to loop over every key in the database using this method\n\
 
335
and the nextkey() method. The traversal is ordered by GDBM's internal\n\
 
336
hash values, and won't be sorted by the key values. This method\n\
 
337
returns the starting key.");
 
338
 
 
339
static PyObject *
 
340
dbm_firstkey(dbmobject *dp, PyObject *unused)
 
341
{
 
342
    PyObject *v;
 
343
    datum key;
 
344
 
 
345
    check_dbmobject_open(dp);
 
346
    key = gdbm_firstkey(dp->di_dbm);
 
347
    if (key.dptr) {
 
348
        v = PyBytes_FromStringAndSize(key.dptr, key.dsize);
 
349
        free(key.dptr);
 
350
        return v;
 
351
    }
 
352
    else {
 
353
        Py_INCREF(Py_None);
 
354
        return Py_None;
 
355
    }
 
356
}
 
357
 
 
358
PyDoc_STRVAR(dbm_nextkey__doc__,
 
359
"nextkey(key) -> next_key\n\
 
360
Returns the key that follows key in the traversal.\n\
 
361
The following code prints every key in the database db, without having\n\
 
362
to create a list in memory that contains them all:\n\
 
363
\n\
 
364
      k = db.firstkey()\n\
 
365
      while k != None:\n\
 
366
          print k\n\
 
367
          k = db.nextkey(k)");
 
368
 
 
369
static PyObject *
 
370
dbm_nextkey(dbmobject *dp, PyObject *args)
 
371
{
 
372
    PyObject *v;
 
373
    datum key, nextkey;
 
374
 
 
375
    if (!PyArg_ParseTuple(args, "s#:nextkey", &key.dptr, &key.dsize))
 
376
        return NULL;
 
377
    check_dbmobject_open(dp);
 
378
    nextkey = gdbm_nextkey(dp->di_dbm, key);
 
379
    if (nextkey.dptr) {
 
380
        v = PyBytes_FromStringAndSize(nextkey.dptr, nextkey.dsize);
 
381
        free(nextkey.dptr);
 
382
        return v;
 
383
    }
 
384
    else {
 
385
        Py_INCREF(Py_None);
 
386
        return Py_None;
 
387
    }
 
388
}
 
389
 
 
390
PyDoc_STRVAR(dbm_reorganize__doc__,
 
391
"reorganize() -> None\n\
 
392
If you have carried out a lot of deletions and would like to shrink\n\
 
393
the space used by the GDBM file, this routine will reorganize the\n\
 
394
database. GDBM will not shorten the length of a database file except\n\
 
395
by using this reorganization; otherwise, deleted file space will be\n\
 
396
kept and reused as new (key,value) pairs are added.");
 
397
 
 
398
static PyObject *
 
399
dbm_reorganize(dbmobject *dp, PyObject *unused)
 
400
{
 
401
    check_dbmobject_open(dp);
 
402
    errno = 0;
 
403
    if (gdbm_reorganize(dp->di_dbm) < 0) {
 
404
        if (errno != 0)
 
405
            PyErr_SetFromErrno(DbmError);
 
406
        else
 
407
            PyErr_SetString(DbmError, gdbm_strerror(gdbm_errno));
 
408
        return NULL;
 
409
    }
 
410
    Py_INCREF(Py_None);
 
411
    return Py_None;
 
412
}
 
413
 
 
414
PyDoc_STRVAR(dbm_sync__doc__,
 
415
"sync() -> None\n\
 
416
When the database has been opened in fast mode, this method forces\n\
 
417
any unwritten data to be written to the disk.");
 
418
 
 
419
static PyObject *
 
420
dbm_sync(dbmobject *dp, PyObject *unused)
 
421
{
 
422
    check_dbmobject_open(dp);
 
423
    gdbm_sync(dp->di_dbm);
 
424
    Py_INCREF(Py_None);
 
425
    return Py_None;
 
426
}
 
427
 
 
428
static PyObject *
 
429
dbm__enter__(PyObject *self, PyObject *args)
 
430
{
 
431
    Py_INCREF(self);
 
432
    return self;
 
433
}
 
434
 
 
435
static PyObject *
 
436
dbm__exit__(PyObject *self, PyObject *args)
 
437
{
 
438
    _Py_IDENTIFIER(close);
 
439
    return _PyObject_CallMethodId(self, &PyId_close, NULL);
 
440
}
 
441
 
 
442
static PyMethodDef dbm_methods[] = {
 
443
    {"close",     (PyCFunction)dbm_close,   METH_NOARGS, dbm_close__doc__},
 
444
    {"keys",      (PyCFunction)dbm_keys,    METH_NOARGS, dbm_keys__doc__},
 
445
    {"firstkey",  (PyCFunction)dbm_firstkey,METH_NOARGS, dbm_firstkey__doc__},
 
446
    {"nextkey",   (PyCFunction)dbm_nextkey, METH_VARARGS, dbm_nextkey__doc__},
 
447
    {"reorganize",(PyCFunction)dbm_reorganize,METH_NOARGS, dbm_reorganize__doc__},
 
448
    {"sync",      (PyCFunction)dbm_sync,    METH_NOARGS, dbm_sync__doc__},
 
449
    {"get",       (PyCFunction)dbm_get,     METH_VARARGS, dbm_get__doc__},
 
450
    {"setdefault",(PyCFunction)dbm_setdefault,METH_VARARGS, dbm_setdefault__doc__},
 
451
    {"__enter__", dbm__enter__, METH_NOARGS, NULL},
 
452
    {"__exit__",  dbm__exit__, METH_VARARGS, NULL},
 
453
    {NULL,              NULL}           /* sentinel */
 
454
};
 
455
 
 
456
static PyTypeObject Dbmtype = {
 
457
    PyVarObject_HEAD_INIT(0, 0)
 
458
    "_gdbm.gdbm",
 
459
    sizeof(dbmobject),
 
460
    0,
 
461
    (destructor)dbm_dealloc,            /*tp_dealloc*/
 
462
    0,                                  /*tp_print*/
 
463
    0,                                  /*tp_getattr*/
 
464
    0,                                  /*tp_setattr*/
 
465
    0,                                  /*tp_reserved*/
 
466
    0,                                  /*tp_repr*/
 
467
    0,                                  /*tp_as_number*/
 
468
    &dbm_as_sequence,                   /*tp_as_sequence*/
 
469
    &dbm_as_mapping,                    /*tp_as_mapping*/
 
470
    0,                                  /*tp_hash*/
 
471
    0,                                  /*tp_call*/
 
472
    0,                                  /*tp_str*/
 
473
    0,                                  /*tp_getattro*/
 
474
    0,                                  /*tp_setattro*/
 
475
    0,                                  /*tp_as_buffer*/
 
476
    Py_TPFLAGS_DEFAULT,                 /*tp_xxx4*/
 
477
    gdbm_object__doc__,                 /*tp_doc*/
 
478
    0,                                  /*tp_traverse*/
 
479
    0,                                  /*tp_clear*/
 
480
    0,                                  /*tp_richcompare*/
 
481
    0,                                  /*tp_weaklistoffset*/
 
482
    0,                                  /*tp_iter*/
 
483
    0,                                  /*tp_iternext*/
 
484
    dbm_methods,                        /*tp_methods*/
 
485
};
 
486
 
 
487
/* ----------------------------------------------------------------- */
 
488
 
 
489
PyDoc_STRVAR(dbmopen__doc__,
 
490
"open(filename, [flags, [mode]])  -> dbm_object\n\
 
491
Open a dbm database and return a dbm object. The filename argument is\n\
 
492
the name of the database file.\n\
 
493
\n\
 
494
The optional flags argument can be 'r' (to open an existing database\n\
 
495
for reading only -- default), 'w' (to open an existing database for\n\
 
496
reading and writing), 'c' (which creates the database if it doesn't\n\
 
497
exist), or 'n' (which always creates a new empty database).\n\
 
498
\n\
 
499
Some versions of gdbm support additional flags which must be\n\
 
500
appended to one of the flags described above. The module constant\n\
 
501
'open_flags' is a string of valid additional flags. The 'f' flag\n\
 
502
opens the database in fast mode; altered data will not automatically\n\
 
503
be written to the disk after every change. This results in faster\n\
 
504
writes to the database, but may result in an inconsistent database\n\
 
505
if the program crashes while the database is still open. Use the\n\
 
506
sync() method to force any unwritten data to be written to the disk.\n\
 
507
The 's' flag causes all database operations to be synchronized to\n\
 
508
disk. The 'u' flag disables locking of the database file.\n\
 
509
\n\
 
510
The optional mode argument is the Unix mode of the file, used only\n\
 
511
when the database has to be created. It defaults to octal 0666. ");
 
512
 
 
513
static PyObject *
 
514
dbmopen(PyObject *self, PyObject *args)
 
515
{
 
516
    char *name;
 
517
    char *flags = "r";
 
518
    int iflags;
 
519
    int mode = 0666;
 
520
 
 
521
    if (!PyArg_ParseTuple(args, "s|si:open", &name, &flags, &mode))
 
522
        return NULL;
 
523
    switch (flags[0]) {
 
524
    case 'r':
 
525
        iflags = GDBM_READER;
 
526
        break;
 
527
    case 'w':
 
528
        iflags = GDBM_WRITER;
 
529
        break;
 
530
    case 'c':
 
531
        iflags = GDBM_WRCREAT;
 
532
        break;
 
533
    case 'n':
 
534
        iflags = GDBM_NEWDB;
 
535
        break;
 
536
    default:
 
537
        PyErr_SetString(DbmError,
 
538
                        "First flag must be one of 'r', 'w', 'c' or 'n'");
 
539
        return NULL;
 
540
    }
 
541
    for (flags++; *flags != '\0'; flags++) {
 
542
        char buf[40];
 
543
        switch (*flags) {
 
544
#ifdef GDBM_FAST
 
545
            case 'f':
 
546
                iflags |= GDBM_FAST;
 
547
                break;
 
548
#endif
 
549
#ifdef GDBM_SYNC
 
550
            case 's':
 
551
                iflags |= GDBM_SYNC;
 
552
                break;
 
553
#endif
 
554
#ifdef GDBM_NOLOCK
 
555
            case 'u':
 
556
                iflags |= GDBM_NOLOCK;
 
557
                break;
 
558
#endif
 
559
            default:
 
560
                PyOS_snprintf(buf, sizeof(buf), "Flag '%c' is not supported.",
 
561
                              *flags);
 
562
                PyErr_SetString(DbmError, buf);
 
563
                return NULL;
 
564
        }
 
565
    }
 
566
 
 
567
    return newdbmobject(name, iflags, mode);
 
568
}
 
569
 
 
570
static char dbmmodule_open_flags[] = "rwcn"
 
571
#ifdef GDBM_FAST
 
572
                                     "f"
 
573
#endif
 
574
#ifdef GDBM_SYNC
 
575
                                     "s"
 
576
#endif
 
577
#ifdef GDBM_NOLOCK
 
578
                                     "u"
 
579
#endif
 
580
                                     ;
 
581
 
 
582
static PyMethodDef dbmmodule_methods[] = {
 
583
    { "open", (PyCFunction)dbmopen, METH_VARARGS, dbmopen__doc__},
 
584
    { 0, 0 },
 
585
};
 
586
 
 
587
 
 
588
static struct PyModuleDef _gdbmmodule = {
 
589
        PyModuleDef_HEAD_INIT,
 
590
        "_gdbm",
 
591
        gdbmmodule__doc__,
 
592
        -1,
 
593
        dbmmodule_methods,
 
594
        NULL,
 
595
        NULL,
 
596
        NULL,
 
597
        NULL
 
598
};
 
599
 
 
600
PyMODINIT_FUNC
 
601
PyInit__gdbm(void) {
 
602
    PyObject *m, *d, *s;
 
603
 
 
604
    if (PyType_Ready(&Dbmtype) < 0)
 
605
            return NULL;
 
606
    m = PyModule_Create(&_gdbmmodule);
 
607
    if (m == NULL)
 
608
        return NULL;
 
609
    d = PyModule_GetDict(m);
 
610
    DbmError = PyErr_NewException("_gdbm.error", PyExc_IOError, NULL);
 
611
    if (DbmError != NULL) {
 
612
        PyDict_SetItemString(d, "error", DbmError);
 
613
        s = PyUnicode_FromString(dbmmodule_open_flags);
 
614
        PyDict_SetItemString(d, "open_flags", s);
 
615
        Py_DECREF(s);
 
616
    }
 
617
    return m;
 
618
}