[issue20193] Derby: Convert the zlib, _bz2 and _lzma modules to use Argument Clinic

Serhiy Storchaka report at bugs.python.org
Wed Jan 22 13:59:10 CET 2014


Serhiy Storchaka added the comment:

Thank you Nadeem for the review.

Here are updated patches. Addressed Nadeem's comments. Compress and decompress 
objects in bz2 and lzma modules now use Argument Clinic for __init__ and to 
generate class docstring. I think these patches are ready to commit (except 
that the name of clinic file will be changed soon).

The zlib module still suffer from a bug #20293.

----------
Added file: http://bugs.python.org/file33617/zlib_clinic.patch
Added file: http://bugs.python.org/file33618/bz2_clinic.patch
Added file: http://bugs.python.org/file33619/lzma_clinic.patch

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue20193>
_______________________________________
-------------- next part --------------
diff -r a62072cf50a2 Modules/zlibmodule.c
--- a/Modules/zlibmodule.c	Wed Jan 22 12:26:01 2014 +0100
+++ b/Modules/zlibmodule.c	Wed Jan 22 14:49:18 2014 +0200
@@ -82,42 +82,13 @@
 }
 
 /*[clinic input]
+output preset file
 module zlib
 class zlib.Compress
 class zlib.Decompress
 [clinic start generated code]*/
 /*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
 
-PyDoc_STRVAR(compressobj__doc__,
-"compressobj(level=-1, method=DEFLATED, wbits=15, memlevel=8,\n"
-"            strategy=Z_DEFAULT_STRATEGY[, zdict])\n"
-" -- Return a compressor object.\n"
-"\n"
-"level is the compression level (an integer in the range 0-9; default is 6).\n"
-"Higher compression levels are slower, but produce smaller results.\n"
-"\n"
-"method is the compression algorithm. If given, this must be DEFLATED.\n"
-"\n"
-"wbits is the base two logarithm of the window size (range: 8..15).\n"
-"\n"
-"memlevel controls the amount of memory used for internal compression state.\n"
-"Valid values range from 1 to 9. Higher values result in higher memory usage,\n"
-"faster compression, and smaller output.\n"
-"\n"
-"strategy is used to tune the compression algorithm. Possible values are\n"
-"Z_DEFAULT_STRATEGY, Z_FILTERED, and Z_HUFFMAN_ONLY.\n"
-"\n"
-"zdict is the predefined compression dictionary - a sequence of bytes\n"
-"containing subsequences that are likely to occur in the input data.");
-
-PyDoc_STRVAR(decompressobj__doc__,
-"decompressobj([wbits[, zdict]]) -- Return a decompressor object.\n"
-"\n"
-"Optional arg wbits is the window buffer size.\n"
-"\n"
-"Optional arg zdict is the predefined compression dictionary. This must be\n"
-"the same dictionary as used by the compressor that produced the input data.");
-
 static compobject *
 newcompobject(PyTypeObject *type)
 {
@@ -165,70 +136,20 @@
 }
 
 /*[clinic input]
+zlib.compress
 
-zlib.compress
     bytes: Py_buffer
         Binary data to be compressed.
-    [
-    level: int
+    level: int(c_default="Z_DEFAULT_COMPRESSION") = Z_DEFAULT_COMPRESSION
         Compression level, in 0-9.
-    ]
     /
 
-Returns compressed string.
-
+Returns a bytes object containing compressed data.
 [clinic start generated code]*/
 
-PyDoc_STRVAR(zlib_compress__doc__,
-"compress(bytes, [level])\n"
-"Returns compressed string.\n"
-"\n"
-"  bytes\n"
-"    Binary data to be compressed.\n"
-"  level\n"
-"    Compression level, in 0-9.");
-
-#define ZLIB_COMPRESS_METHODDEF    \
-    {"compress", (PyCFunction)zlib_compress, METH_VARARGS, zlib_compress__doc__},
-
 static PyObject *
-zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int group_right_1, int level);
-
-static PyObject *
-zlib_compress(PyModuleDef *module, PyObject *args)
-{
-    PyObject *return_value = NULL;
-    Py_buffer bytes = {NULL, NULL};
-    int group_right_1 = 0;
-    int level = 0;
-
-    switch (PyTuple_GET_SIZE(args)) {
-        case 1:
-            if (!PyArg_ParseTuple(args, "y*:compress", &bytes))
-                goto exit;
-            break;
-        case 2:
-            if (!PyArg_ParseTuple(args, "y*i:compress", &bytes, &level))
-                goto exit;
-            group_right_1 = 1;
-            break;
-        default:
-            PyErr_SetString(PyExc_TypeError, "zlib.compress requires 1 to 2 arguments");
-            goto exit;
-    }
-    return_value = zlib_compress_impl(module, &bytes, group_right_1, level);
-
-exit:
-    /* Cleanup for bytes */
-    if (bytes.obj)
-       PyBuffer_Release(&bytes);
-
-    return return_value;
-}
-
-static PyObject *
-zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int group_right_1, int level)
-/*[clinic end generated code: checksum=74648f97e6b9d3cc9cd568d47262d462bded7ed0]*/
+zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int level)
+/*[clinic end generated code: checksum=5d7dd4588788efd3516e5f4225050d6413632601]*/
 {
     PyObject *ReturnVal = NULL;
     Byte *input, *output = NULL;
@@ -236,9 +157,6 @@
     int err;
     z_stream zst;
 
-    if (!group_right_1)
-        level = Z_DEFAULT_COMPRESSION;
-
     if ((size_t)bytes->len > UINT_MAX) {
         PyErr_SetString(PyExc_OverflowError,
                         "Size does not fit in an unsigned int");
@@ -312,6 +230,7 @@
 class uint_converter(CConverter):
     type = 'unsigned int'
     converter = 'uint_converter'
+    c_ignored_default = "0"
 
 [python start generated code]*/
 /*[python end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
@@ -347,35 +266,38 @@
     return 1;
 }
 
-PyDoc_STRVAR(decompress__doc__,
-"decompress(string[, wbits[, bufsize]]) -- Return decompressed string.\n"
-"\n"
-"Optional arg wbits is the window buffer size.  Optional arg bufsize is\n"
-"the initial output buffer size.");
+/*[clinic input]
+zlib.decompress
+
+    data: Py_buffer
+        Compressed data.
+    wbits: int(c_default="DEF_WBITS") = unspecified
+        The window buffer size.
+    bufsize: uint(c_default="DEFAULTALLOC") = unspecified
+        The initial output buffer size.
+    /
+
+Returns a bytes object containing the uncompressed data.
+[clinic start generated code]*/
 
 static PyObject *
-PyZlib_decompress(PyObject *self, PyObject *args)
+zlib_decompress_impl(PyModuleDef *module, Py_buffer *data, int wbits, unsigned int bufsize)
+/*[clinic end generated code: checksum=9e5464e72df9cb5fee73df662dbcaed867e01d32]*/
 {
     PyObject *result_str = NULL;
-    Py_buffer pinput;
     Byte *input;
     unsigned int length;
     int err;
-    int wsize=DEF_WBITS;
-    unsigned int bufsize = DEFAULTALLOC, new_bufsize;
+    unsigned int new_bufsize;
     z_stream zst;
 
-    if (!PyArg_ParseTuple(args, "y*|iO&:decompress",
-                          &pinput, &wsize, uint_converter, &bufsize))
-        return NULL;
-
-    if ((size_t)pinput.len > UINT_MAX) {
+    if ((size_t)data->len > UINT_MAX) {
         PyErr_SetString(PyExc_OverflowError,
                         "Size does not fit in an unsigned int");
         goto error;
     }
-    input = pinput.buf;
-    length = (unsigned int)pinput.len;
+    input = data->buf;
+    length = (unsigned int)data->len;
 
     if (bufsize == 0)
         bufsize = 1;
@@ -391,7 +313,7 @@
     zst.zfree = PyZlib_Free;
     zst.next_out = (Byte *)PyBytes_AS_STRING(result_str);
     zst.next_in = (Byte *)input;
-    err = inflateInit2(&zst, wsize);
+    err = inflateInit2(&zst, wbits);
 
     switch(err) {
     case(Z_OK):
@@ -457,32 +379,45 @@
     if (_PyBytes_Resize(&result_str, zst.total_out) < 0)
         goto error;
 
-    PyBuffer_Release(&pinput);
     return result_str;
 
  error:
-    PyBuffer_Release(&pinput);
     Py_XDECREF(result_str);
     return NULL;
 }
 
+/*[clinic input]
+zlib.compressobj
+
+    level: int(c_default="Z_DEFAULT_COMPRESSION") = Z_DEFAULT_COMPRESSION
+        The compression level (an integer in the range 0-9; default is 6).
+        Higher compression levels are slower, but produce smaller results.
+    method: int(c_default="DEFLATED") = DEFLATED
+        The compression algorithm.  If given, this must be DEFLATED.
+    wbits: int(c_default="MAX_WBITS") = MAX_WBITS
+        The base two logarithm of the window size (range: 8..15).
+    memLevel: int(c_default="DEF_MEM_LEVEL") = DEF_MEM_LEVEL
+        Controls the amount of memory used for internal compression state.
+        Valid values range from 1 to 9.  Higher values result in higher memory
+        usage, faster compression, and smaller output.
+    strategy: int(c_default="Z_DEFAULT_STRATEGY") = Z_DEFAULT_STRATEGY
+        Used to tune the compression algorithm.  Possible values are
+        Z_DEFAULT_STRATEGY, Z_FILTERED, and Z_HUFFMAN_ONLY.
+    zdict: Py_buffer = None
+        The predefined compression dictionary - a sequence of bytes
+        containing subsequences that are likely to occur in the input data.
+
+Return a compressor object.
+[clinic start generated code]*/
+
 static PyObject *
-PyZlib_compressobj(PyObject *selfptr, PyObject *args, PyObject *kwargs)
+zlib_compressobj_impl(PyModuleDef *module, int level, int method, int wbits, int memLevel, int strategy, Py_buffer *zdict)
+/*[clinic end generated code: checksum=89e5a6c1449caa9ed76f1baad066600e985151a9]*/
 {
     compobject *self = NULL;
-    int level=Z_DEFAULT_COMPRESSION, method=DEFLATED;
-    int wbits=MAX_WBITS, memLevel=DEF_MEM_LEVEL, strategy=0, err;
-    Py_buffer zdict;
-    static char *kwlist[] = {"level", "method", "wbits",
-                             "memLevel", "strategy", "zdict", NULL};
+    int err;
 
-    zdict.buf = NULL; /* Sentinel, so we can tell whether zdict was supplied. */
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iiiiiy*:compressobj",
-                                     kwlist, &level, &method, &wbits,
-                                     &memLevel, &strategy, &zdict))
-        return NULL;
-
-    if (zdict.buf != NULL && (size_t)zdict.len > UINT_MAX) {
+    if (zdict->buf != NULL && (size_t)zdict->len > UINT_MAX) {
         PyErr_SetString(PyExc_OverflowError,
                         "zdict length does not fit in an unsigned int");
         goto error;
@@ -500,11 +435,11 @@
     switch(err) {
     case (Z_OK):
         self->is_initialised = 1;
-        if (zdict.buf == NULL) {
+        if (zdict->buf == NULL) {
             goto success;
         } else {
             err = deflateSetDictionary(&self->zst,
-                                       zdict.buf, (unsigned int)zdict.len);
+                                       zdict->buf, (unsigned int)zdict->len);
             switch (err) {
             case (Z_OK):
                 goto success;
@@ -532,22 +467,28 @@
     Py_XDECREF(self);
     self = NULL;
  success:
-    if (zdict.buf != NULL)
-        PyBuffer_Release(&zdict);
     return (PyObject*)self;
 }
 
+/*[clinic input]
+zlib.decompressobj
+
+    wbits: int(c_default="DEF_WBITS") = unspecified
+        The window buffer size.
+    zdict: object(c_default="NULL") = unspecified
+        The predefined compression dictionary.  This must be the same
+        dictionary as used by the compressor that produced the input data.
+
+Return a decompressor object.
+[clinic start generated code]*/
+
 static PyObject *
-PyZlib_decompressobj(PyObject *selfptr, PyObject *args, PyObject *kwargs)
+zlib_decompressobj_impl(PyModuleDef *module, int wbits, PyObject *zdict)
+/*[clinic end generated code: checksum=8ccd583fbd631798566d415933cd44440c8a74b5]*/
 {
-    static char *kwlist[] = {"wbits", "zdict", NULL};
-    int wbits=DEF_WBITS, err;
+    int err;
     compobject *self;
-    PyObject *zdict=NULL;
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iO:decompressobj",
-                                     kwlist, &wbits, &zdict))
-        return NULL;
     if (zdict != NULL && !PyObject_CheckBuffer(zdict)) {
         PyErr_SetString(PyExc_TypeError,
                         "zdict argument must support the buffer protocol");
@@ -615,37 +556,42 @@
     Dealloc(self);
 }
 
-PyDoc_STRVAR(comp_compress__doc__,
-"compress(data) -- Return a string containing data compressed.\n"
-"\n"
-"After calling this function, some of the input data may still\n"
-"be stored in internal buffers for later processing.\n"
-"Call the flush() method to clear these buffers.");
+/*[clinic input]
+zlib.Compress.compress
 
+    self: self(type="compobject *")
+    data: Py_buffer
+        Binary data to be compressed.
+    /
+
+Returns a bytes object containing compressed data.
+
+After calling this function, some of the input data may still
+be stored in internal buffers for later processing.
+Call the flush() method to clear these buffers.
+[clinic start generated code]*/
 
 static PyObject *
-PyZlib_objcompress(compobject *self, PyObject *args)
+zlib_Compress_compress_impl(compobject *self, Py_buffer *data)
+/*[clinic end generated code: checksum=5d5cd791cbc6a7f4b6de4ec12c085c88d4d3e31c]*/
 {
     int err;
     unsigned int inplen;
     unsigned int length = DEFAULTALLOC, new_length;
-    PyObject *RetVal = NULL;
-    Py_buffer pinput;
+    PyObject *RetVal;
     Byte *input;
     unsigned long start_total_out;
 
-    if (!PyArg_ParseTuple(args, "y*:compress", &pinput))
-        return NULL;
-    if ((size_t)pinput.len > UINT_MAX) {
+    if ((size_t)data->len > UINT_MAX) {
         PyErr_SetString(PyExc_OverflowError,
                         "Size does not fit in an unsigned int");
-        goto error_outer;
+        return NULL;
     }
-    input = pinput.buf;
-    inplen = (unsigned int)pinput.len;
+    input = data->buf;
+    inplen = (unsigned int)data->len;
 
     if (!(RetVal = PyBytes_FromStringAndSize(NULL, length)))
-        goto error_outer;
+        return NULL;
 
     ENTER_ZLIB(self);
 
@@ -668,7 +614,7 @@
             new_length = UINT_MAX;
         if (_PyBytes_Resize(&RetVal, new_length) < 0) {
             Py_CLEAR(RetVal);
-            goto error;
+            goto done;
         }
         self->zst.next_out =
             (unsigned char *)PyBytes_AS_STRING(RetVal) + length;
@@ -686,18 +632,15 @@
 
     if (err != Z_OK && err != Z_BUF_ERROR) {
         zlib_error(self->zst, err, "while compressing data");
-        Py_DECREF(RetVal);
-        RetVal = NULL;
-        goto error;
+        Py_CLEAR(RetVal);
+        goto done;
     }
     if (_PyBytes_Resize(&RetVal, self->zst.total_out - start_total_out) < 0) {
         Py_CLEAR(RetVal);
     }
 
- error:
+ done:
     LEAVE_ZLIB(self);
- error_outer:
-    PyBuffer_Release(&pinput);
     return RetVal;
 }
 
@@ -745,11 +688,9 @@
 }
 
 /*[clinic input]
-
 zlib.Decompress.decompress
 
     self: self(type="compobject *")
-
     data: Py_buffer
         The binary data to decompress.
     max_length: uint = 0
@@ -758,58 +699,16 @@
         the unconsumed_tail attribute.
     /
 
-Return a string containing the decompressed version of the data.
+Return a bytes object containing the decompressed version of the data.
 
 After calling this function, some of the input data may still be stored in
 internal buffers for later processing.
 Call the flush() method to clear these buffers.
 [clinic start generated code]*/
 
-PyDoc_STRVAR(zlib_Decompress_decompress__doc__,
-"decompress(data, max_length=0)\n"
-"Return a string containing the decompressed version of the data.\n"
-"\n"
-"  data\n"
-"    The binary data to decompress.\n"
-"  max_length\n"
-"    The maximum allowable length of the decompressed data.\n"
-"    Unconsumed input data will be stored in\n"
-"    the unconsumed_tail attribute.\n"
-"\n"
-"After calling this function, some of the input data may still be stored in\n"
-"internal buffers for later processing.\n"
-"Call the flush() method to clear these buffers.");
-
-#define ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF    \
-    {"decompress", (PyCFunction)zlib_Decompress_decompress, METH_VARARGS, zlib_Decompress_decompress__doc__},
-
-static PyObject *
-zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, unsigned int max_length);
-
-static PyObject *
-zlib_Decompress_decompress(PyObject *self, PyObject *args)
-{
-    PyObject *return_value = NULL;
-    Py_buffer data = {NULL, NULL};
-    unsigned int max_length = 0;
-
-    if (!PyArg_ParseTuple(args,
-        "y*|O&:decompress",
-        &data, uint_converter, &max_length))
-        goto exit;
-    return_value = zlib_Decompress_decompress_impl((compobject *)self, &data, max_length);
-
-exit:
-    /* Cleanup for data */
-    if (data.obj)
-       PyBuffer_Release(&data);
-
-    return return_value;
-}
-
 static PyObject *
 zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, unsigned int max_length)
-/*[clinic end generated code: checksum=e0058024c4a97b411d2e2197791b89fde175f76f]*/
+/*[clinic end generated code: checksum=755cccc9087bfe55486b7e15fa7e2ab60b4c86d6]*/
 {
     int err;
     unsigned int old_length, length = DEFAULTALLOC;
@@ -929,29 +828,31 @@
     return RetVal;
 }
 
-PyDoc_STRVAR(comp_flush__doc__,
-"flush( [mode] ) -- Return a string containing any remaining compressed data.\n"
-"\n"
-"mode can be one of the constants Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH; the\n"
-"default value used when mode is not specified is Z_FINISH.\n"
-"If mode == Z_FINISH, the compressor object can no longer be used after\n"
-"calling the flush() method.  Otherwise, more data can still be compressed.");
+/*[clinic input]
+zlib.Compress.flush
+
+    self: self(type="compobject *")
+    mode: int(c_default="Z_FINISH") = Z_FINISH
+        One of the constants Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH.
+        If mode == Z_FINISH, the compressor object can no longer be used after
+        calling the flush() method.  Otherwise, more data can still be compressed.
+    /
+
+Return a bytes object containing any remaining compressed data.
+[clinic start generated code]*/
 
 static PyObject *
-PyZlib_flush(compobject *self, PyObject *args)
+zlib_Compress_flush_impl(compobject *self, int mode)
+/*[clinic end generated code: checksum=a203f4cefc9de727aa1d2ea39d11c0a16c32041a]*/
 {
     int err;
     unsigned int length = DEFAULTALLOC, new_length;
     PyObject *RetVal;
-    int flushmode = Z_FINISH;
     unsigned long start_total_out;
 
-    if (!PyArg_ParseTuple(args, "|i:flush", &flushmode))
-        return NULL;
-
     /* Flushing with Z_NO_FLUSH is a no-op, so there's no point in
        doing any work at all; just return an empty string. */
-    if (flushmode == Z_NO_FLUSH) {
+    if (mode == Z_NO_FLUSH) {
         return PyBytes_FromStringAndSize(NULL, 0);
     }
 
@@ -966,7 +867,7 @@
     self->zst.next_out = (unsigned char *)PyBytes_AS_STRING(RetVal);
 
     Py_BEGIN_ALLOW_THREADS
-    err = deflate(&(self->zst), flushmode);
+    err = deflate(&(self->zst), mode);
     Py_END_ALLOW_THREADS
 
     /* while Z_OK and the output buffer is full, there might be more output,
@@ -986,14 +887,14 @@
         length = new_length;
 
         Py_BEGIN_ALLOW_THREADS
-        err = deflate(&(self->zst), flushmode);
+        err = deflate(&(self->zst), mode);
         Py_END_ALLOW_THREADS
     }
 
-    /* If flushmode is Z_FINISH, we also have to call deflateEnd() to free
+    /* If mode is Z_FINISH, we also have to call deflateEnd() to free
        various data structures. Note we should only get Z_STREAM_END when
-       flushmode is Z_FINISH, but checking both for safety*/
-    if (err == Z_STREAM_END && flushmode == Z_FINISH) {
+       mode is Z_FINISH, but checking both for safety*/
+    if (err == Z_STREAM_END && mode == Z_FINISH) {
         err = deflateEnd(&(self->zst));
         if (err != Z_OK) {
             zlib_error(self->zst, err, "while finishing compression");
@@ -1035,25 +936,9 @@
 Return a copy of the compression object.
 [clinic start generated code]*/
 
-PyDoc_STRVAR(zlib_Compress_copy__doc__,
-"copy()\n"
-"Return a copy of the compression object.");
-
-#define ZLIB_COMPRESS_COPY_METHODDEF    \
-    {"copy", (PyCFunction)zlib_Compress_copy, METH_NOARGS, zlib_Compress_copy__doc__},
-
-static PyObject *
-zlib_Compress_copy_impl(compobject *self);
-
-static PyObject *
-zlib_Compress_copy(PyObject *self, PyObject *Py_UNUSED(ignored))
-{
-    return zlib_Compress_copy_impl((compobject *)self);
-}
-
 static PyObject *
 zlib_Compress_copy_impl(compobject *self)
-/*[clinic end generated code: checksum=d57a7911deb7940e85a8d7e65af20b6e2df69000]*/
+/*[clinic end generated code: checksum=5144aa153c21e805afa5c19e5b48cf8e6480b5da]*/
 {
     compobject *retval = NULL;
     int err;
@@ -1103,11 +988,17 @@
     return NULL;
 }
 
-PyDoc_STRVAR(decomp_copy__doc__,
-"copy() -- Return a copy of the decompression object.");
+/*[clinic input]
+zlib.Decompress.copy
+
+    self: self(type="compobject *")
+
+Return a copy of the decompression object.
+[clinic start generated code]*/
 
 static PyObject *
-PyZlib_uncopy(compobject *self)
+zlib_Decompress_copy_impl(compobject *self)
+/*[clinic end generated code: checksum=02a883a2a510c8ccfeef3f89e317a275bfe8c094]*/
 {
     compobject *retval = NULL;
     int err;
@@ -1159,24 +1050,27 @@
 }
 #endif
 
-PyDoc_STRVAR(decomp_flush__doc__,
-"flush( [length] ) -- Return a string containing any remaining\n"
-"decompressed data. length, if given, is the initial size of the\n"
-"output buffer.\n"
-"\n"
-"The decompressor object can no longer be used after this call.");
+/*[clinic input]
+zlib.Decompress.flush
+
+    self: self(type="compobject *")
+    length: uint(c_default="DEFAULTALLOC") = unspecified
+        the initial size of the output buffer.
+    /
+
+Return a bytes object containing any remaining decompressed data.
+[clinic start generated code]*/
 
 static PyObject *
-PyZlib_unflush(compobject *self, PyObject *args)
+zlib_Decompress_flush_impl(compobject *self, unsigned int length)
+/*[clinic end generated code: checksum=db6fb753ab698e22afe3957c9da9e5e77f4bfc08]*/
 {
     int err;
-    unsigned int length = DEFAULTALLOC, new_length;
+    unsigned int new_length;
     PyObject * retval = NULL;
     unsigned long start_total_out;
     Py_ssize_t size;
 
-    if (!PyArg_ParseTuple(args, "|O&:flush", uint_converter, &length))
-        return NULL;
     if (length == 0) {
         PyErr_SetString(PyExc_ValueError, "length must be greater than zero");
         return NULL;
@@ -1252,12 +1146,12 @@
     return retval;
 }
 
+#include "zlibmodule.clinic.c"
+
 static PyMethodDef comp_methods[] =
 {
-    {"compress", (binaryfunc)PyZlib_objcompress, METH_VARARGS,
-                 comp_compress__doc__},
-    {"flush", (binaryfunc)PyZlib_flush, METH_VARARGS,
-              comp_flush__doc__},
+    ZLIB_COMPRESS_COMPRESS_METHODDEF
+    ZLIB_COMPRESS_FLUSH_METHODDEF
 #ifdef HAVE_ZLIB_COPY
     ZLIB_COMPRESS_COPY_METHODDEF
 #endif
@@ -1267,11 +1161,9 @@
 static PyMethodDef Decomp_methods[] =
 {
     ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF
-    {"flush", (binaryfunc)PyZlib_unflush, METH_VARARGS,
-              decomp_flush__doc__},
+    ZLIB_DECOMPRESS_FLUSH_METHODDEF
 #ifdef HAVE_ZLIB_COPY
-    {"copy",  (PyCFunction)PyZlib_uncopy, METH_NOARGS,
-              decomp_copy__doc__},
+    ZLIB_DECOMPRESS_COPY_METHODDEF
 #endif
     {NULL, NULL}
 };
@@ -1284,95 +1176,95 @@
     {NULL},
 };
 
-PyDoc_STRVAR(adler32__doc__,
-"adler32(string[, start]) -- Compute an Adler-32 checksum of string.\n"
-"\n"
-"An optional starting value can be specified.  The returned checksum is\n"
-"an integer.");
+/*[clinic input]
+zlib.adler32
+
+    data: Py_buffer
+    value: unsigned_int(bitwise=True) = 1
+        Starting value of the checksum.
+    /
+
+Compute an Adler-32 checksum of data.
+
+The returned checksum is an integer.
+[clinic start generated code]*/
 
 static PyObject *
-PyZlib_adler32(PyObject *self, PyObject *args)
+zlib_adler32_impl(PyModuleDef *module, Py_buffer *data, unsigned int value)
+/*[clinic end generated code: checksum=51d6d75ee655c78af8c968fdb4c11d97e62c67d5]*/
 {
-    unsigned int adler32val = 1;  /* adler32(0L, Z_NULL, 0) */
-    Py_buffer pbuf;
-
-    if (!PyArg_ParseTuple(args, "y*|I:adler32", &pbuf, &adler32val))
-        return NULL;
     /* Releasing the GIL for very small buffers is inefficient
        and may lower performance */
-    if (pbuf.len > 1024*5) {
-        unsigned char *buf = pbuf.buf;
-        Py_ssize_t len = pbuf.len;
+    if (data->len > 1024*5) {
+        unsigned char *buf = data->buf;
+        Py_ssize_t len = data->len;
 
         Py_BEGIN_ALLOW_THREADS
         /* Avoid truncation of length for very large buffers. adler32() takes
            length as an unsigned int, which may be narrower than Py_ssize_t. */
         while ((size_t)len > UINT_MAX) {
-            adler32val = adler32(adler32val, buf, UINT_MAX);
+            value = adler32(value, buf, UINT_MAX);
             buf += (size_t) UINT_MAX;
             len -= (size_t) UINT_MAX;
         }
-        adler32val = adler32(adler32val, buf, (unsigned int)len);
+        value = adler32(value, buf, (unsigned int)len);
         Py_END_ALLOW_THREADS
     } else {
-        adler32val = adler32(adler32val, pbuf.buf, (unsigned int)pbuf.len);
+        value = adler32(value, data->buf, (unsigned int)data->len);
     }
-    PyBuffer_Release(&pbuf);
-    return PyLong_FromUnsignedLong(adler32val & 0xffffffffU);
+    return PyLong_FromUnsignedLong(value & 0xffffffffU);
 }
 
-PyDoc_STRVAR(crc32__doc__,
-"crc32(string[, start]) -- Compute a CRC-32 checksum of string.\n"
-"\n"
-"An optional starting value can be specified.  The returned checksum is\n"
-"an integer.");
+/*[clinic input]
+zlib.crc32
+
+    data: Py_buffer
+    value: unsigned_int(bitwise=True) = 0
+        Starting value of the checksum.
+    /
+
+Compute a CRC-32 checksum of data.
+
+The returned checksum is an integer.
+[clinic start generated code]*/
 
 static PyObject *
-PyZlib_crc32(PyObject *self, PyObject *args)
+zlib_crc32_impl(PyModuleDef *module, Py_buffer *data, unsigned int value)
+/*[clinic end generated code: checksum=c1e986e74fe7b62369998a71a81ebeb9b73e8d4c]*/
 {
-    unsigned int crc32val = 0;  /* crc32(0L, Z_NULL, 0) */
-    Py_buffer pbuf;
     int signed_val;
 
-    if (!PyArg_ParseTuple(args, "y*|I:crc32", &pbuf, &crc32val))
-        return NULL;
     /* Releasing the GIL for very small buffers is inefficient
        and may lower performance */
-    if (pbuf.len > 1024*5) {
-        unsigned char *buf = pbuf.buf;
-        Py_ssize_t len = pbuf.len;
+    if (data->len > 1024*5) {
+        unsigned char *buf = data->buf;
+        Py_ssize_t len = data->len;
 
         Py_BEGIN_ALLOW_THREADS
         /* Avoid truncation of length for very large buffers. crc32() takes
            length as an unsigned int, which may be narrower than Py_ssize_t. */
         while ((size_t)len > UINT_MAX) {
-            crc32val = crc32(crc32val, buf, UINT_MAX);
+            value = crc32(value, buf, UINT_MAX);
             buf += (size_t) UINT_MAX;
             len -= (size_t) UINT_MAX;
         }
-        signed_val = crc32(crc32val, buf, (unsigned int)len);
+        signed_val = crc32(value, buf, (unsigned int)len);
         Py_END_ALLOW_THREADS
     } else {
-        signed_val = crc32(crc32val, pbuf.buf, (unsigned int)pbuf.len);
+        signed_val = crc32(value, data->buf, (unsigned int)data->len);
     }
-    PyBuffer_Release(&pbuf);
     return PyLong_FromUnsignedLong(signed_val & 0xffffffffU);
 }
 
 
 static PyMethodDef zlib_methods[] =
 {
-    {"adler32", (PyCFunction)PyZlib_adler32, METH_VARARGS,
-                adler32__doc__},
+    ZLIB_ADLER32_METHODDEF
     ZLIB_COMPRESS_METHODDEF
-    {"compressobj", (PyCFunction)PyZlib_compressobj, METH_VARARGS|METH_KEYWORDS,
-                    compressobj__doc__},
-    {"crc32", (PyCFunction)PyZlib_crc32, METH_VARARGS,
-              crc32__doc__},
-    {"decompress", (PyCFunction)PyZlib_decompress, METH_VARARGS,
-                   decompress__doc__},
-    {"decompressobj", (PyCFunction)PyZlib_decompressobj, METH_VARARGS|METH_KEYWORDS,
-                   decompressobj__doc__},
+    ZLIB_COMPRESSOBJ_METHODDEF
+    ZLIB_CRC32_METHODDEF
+    ZLIB_DECOMPRESS_METHODDEF
+    ZLIB_DECOMPRESSOBJ_METHODDEF
     {NULL, NULL}
 };
 
diff -r a62072cf50a2 Modules/zlibmodule.clinic.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Modules/zlibmodule.clinic.c	Wed Jan 22 14:49:18 2014 +0200
@@ -0,0 +1,410 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+PyDoc_STRVAR(zlib_compress__doc__,
+"compress(bytes, level=Z_DEFAULT_COMPRESSION)\n"
+"Returns a bytes object containing compressed data.\n"
+"\n"
+"  bytes\n"
+"    Binary data to be compressed.\n"
+"  level\n"
+"    Compression level, in 0-9.");
+
+#define ZLIB_COMPRESS_METHODDEF    \
+    {"compress", (PyCFunction)zlib_compress, METH_VARARGS, zlib_compress__doc__},
+
+static PyObject *
+zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int level);
+
+static PyObject *
+zlib_compress(PyModuleDef *module, PyObject *args)
+{
+    PyObject *return_value = NULL;
+    Py_buffer bytes = {NULL, NULL};
+    int level = Z_DEFAULT_COMPRESSION;
+
+    if (!PyArg_ParseTuple(args,
+        "y*|i:compress",
+        &bytes, &level))
+        goto exit;
+    return_value = zlib_compress_impl(module, &bytes, level);
+
+exit:
+    /* Cleanup for bytes */
+    if (bytes.obj)
+       PyBuffer_Release(&bytes);
+
+    return return_value;
+}
+
+PyDoc_STRVAR(zlib_decompress__doc__,
+"decompress(data, wbits=unspecified, bufsize=unspecified)\n"
+"Returns a bytes object containing the uncompressed data.\n"
+"\n"
+"  data\n"
+"    Compressed data.\n"
+"  wbits\n"
+"    The window buffer size.\n"
+"  bufsize\n"
+"    The initial output buffer size.");
+
+#define ZLIB_DECOMPRESS_METHODDEF    \
+    {"decompress", (PyCFunction)zlib_decompress, METH_VARARGS, zlib_decompress__doc__},
+
+static PyObject *
+zlib_decompress_impl(PyModuleDef *module, Py_buffer *data, int wbits, unsigned int bufsize);
+
+static PyObject *
+zlib_decompress(PyModuleDef *module, PyObject *args)
+{
+    PyObject *return_value = NULL;
+    Py_buffer data = {NULL, NULL};
+    int wbits = DEF_WBITS;
+    unsigned int bufsize = DEFAULTALLOC;
+
+    if (!PyArg_ParseTuple(args,
+        "y*|iO&:decompress",
+        &data, &wbits, uint_converter, &bufsize))
+        goto exit;
+    return_value = zlib_decompress_impl(module, &data, wbits, bufsize);
+
+exit:
+    /* Cleanup for data */
+    if (data.obj)
+       PyBuffer_Release(&data);
+
+    return return_value;
+}
+
+PyDoc_STRVAR(zlib_compressobj__doc__,
+"compressobj(level=Z_DEFAULT_COMPRESSION, method=DEFLATED, wbits=MAX_WBITS, memLevel=DEF_MEM_LEVEL, strategy=Z_DEFAULT_STRATEGY, zdict=None)\n"
+"Return a compressor object.\n"
+"\n"
+"  level\n"
+"    The compression level (an integer in the range 0-9; default is 6).\n"
+"    Higher compression levels are slower, but produce smaller results.\n"
+"  method\n"
+"    The compression algorithm.  If given, this must be DEFLATED.\n"
+"  wbits\n"
+"    The base two logarithm of the window size (range: 8..15).\n"
+"  memLevel\n"
+"    Controls the amount of memory used for internal compression state.\n"
+"    Valid values range from 1 to 9.  Higher values result in higher memory\n"
+"    usage, faster compression, and smaller output.\n"
+"  strategy\n"
+"    Used to tune the compression algorithm.  Possible values are\n"
+"    Z_DEFAULT_STRATEGY, Z_FILTERED, and Z_HUFFMAN_ONLY.\n"
+"  zdict\n"
+"    The predefined compression dictionary - a sequence of bytes\n"
+"    containing subsequences that are likely to occur in the input data.");
+
+#define ZLIB_COMPRESSOBJ_METHODDEF    \
+    {"compressobj", (PyCFunction)zlib_compressobj, METH_VARARGS|METH_KEYWORDS, zlib_compressobj__doc__},
+
+static PyObject *
+zlib_compressobj_impl(PyModuleDef *module, int level, int method, int wbits, int memLevel, int strategy, Py_buffer *zdict);
+
+static PyObject *
+zlib_compressobj(PyModuleDef *module, PyObject *args, PyObject *kwargs)
+{
+    PyObject *return_value = NULL;
+    static char *_keywords[] = {"level", "method", "wbits", "memLevel", "strategy", "zdict", NULL};
+    int level = Z_DEFAULT_COMPRESSION;
+    int method = DEFLATED;
+    int wbits = MAX_WBITS;
+    int memLevel = DEF_MEM_LEVEL;
+    int strategy = Z_DEFAULT_STRATEGY;
+    Py_buffer zdict = {NULL, NULL};
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+        "|iiiiiy*:compressobj", _keywords,
+        &level, &method, &wbits, &memLevel, &strategy, &zdict))
+        goto exit;
+    return_value = zlib_compressobj_impl(module, level, method, wbits, memLevel, strategy, &zdict);
+
+exit:
+    /* Cleanup for zdict */
+    if (zdict.obj)
+       PyBuffer_Release(&zdict);
+
+    return return_value;
+}
+
+PyDoc_STRVAR(zlib_decompressobj__doc__,
+"decompressobj(wbits=unspecified, zdict=unspecified)\n"
+"Return a decompressor object.\n"
+"\n"
+"  wbits\n"
+"    The window buffer size.\n"
+"  zdict\n"
+"    The predefined compression dictionary.  This must be the same\n"
+"    dictionary as used by the compressor that produced the input data.");
+
+#define ZLIB_DECOMPRESSOBJ_METHODDEF    \
+    {"decompressobj", (PyCFunction)zlib_decompressobj, METH_VARARGS|METH_KEYWORDS, zlib_decompressobj__doc__},
+
+static PyObject *
+zlib_decompressobj_impl(PyModuleDef *module, int wbits, PyObject *zdict);
+
+static PyObject *
+zlib_decompressobj(PyModuleDef *module, PyObject *args, PyObject *kwargs)
+{
+    PyObject *return_value = NULL;
+    static char *_keywords[] = {"wbits", "zdict", NULL};
+    int wbits = DEF_WBITS;
+    PyObject *zdict = NULL;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+        "|iO:decompressobj", _keywords,
+        &wbits, &zdict))
+        goto exit;
+    return_value = zlib_decompressobj_impl(module, wbits, zdict);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(zlib_Compress_compress__doc__,
+"compress(data)\n"
+"Returns a bytes object containing compressed data.\n"
+"\n"
+"  data\n"
+"    Binary data to be compressed.\n"
+"\n"
+"After calling this function, some of the input data may still\n"
+"be stored in internal buffers for later processing.\n"
+"Call the flush() method to clear these buffers.");
+
+#define ZLIB_COMPRESS_COMPRESS_METHODDEF    \
+    {"compress", (PyCFunction)zlib_Compress_compress, METH_VARARGS, zlib_Compress_compress__doc__},
+
+static PyObject *
+zlib_Compress_compress_impl(compobject *self, Py_buffer *data);
+
+static PyObject *
+zlib_Compress_compress(PyObject *self, PyObject *args)
+{
+    PyObject *return_value = NULL;
+    Py_buffer data = {NULL, NULL};
+
+    if (!PyArg_ParseTuple(args,
+        "y*:compress",
+        &data))
+        goto exit;
+    return_value = zlib_Compress_compress_impl((compobject *)self, &data);
+
+exit:
+    /* Cleanup for data */
+    if (data.obj)
+       PyBuffer_Release(&data);
+
+    return return_value;
+}
+
+PyDoc_STRVAR(zlib_Decompress_decompress__doc__,
+"decompress(data, max_length=0)\n"
+"Return a bytes object containing the decompressed version of the data.\n"
+"\n"
+"  data\n"
+"    The binary data to decompress.\n"
+"  max_length\n"
+"    The maximum allowable length of the decompressed data.\n"
+"    Unconsumed input data will be stored in\n"
+"    the unconsumed_tail attribute.\n"
+"\n"
+"After calling this function, some of the input data may still be stored in\n"
+"internal buffers for later processing.\n"
+"Call the flush() method to clear these buffers.");
+
+#define ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF    \
+    {"decompress", (PyCFunction)zlib_Decompress_decompress, METH_VARARGS, zlib_Decompress_decompress__doc__},
+
+static PyObject *
+zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, unsigned int max_length);
+
+static PyObject *
+zlib_Decompress_decompress(PyObject *self, PyObject *args)
+{
+    PyObject *return_value = NULL;
+    Py_buffer data = {NULL, NULL};
+    unsigned int max_length = 0;
+
+    if (!PyArg_ParseTuple(args,
+        "y*|O&:decompress",
+        &data, uint_converter, &max_length))
+        goto exit;
+    return_value = zlib_Decompress_decompress_impl((compobject *)self, &data, max_length);
+
+exit:
+    /* Cleanup for data */
+    if (data.obj)
+       PyBuffer_Release(&data);
+
+    return return_value;
+}
+
+PyDoc_STRVAR(zlib_Compress_flush__doc__,
+"flush(mode=Z_FINISH)\n"
+"Return a bytes object containing any remaining compressed data.\n"
+"\n"
+"  mode\n"
+"    One of the constants Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH.\n"
+"    If mode == Z_FINISH, the compressor object can no longer be used after\n"
+"    calling the flush() method.  Otherwise, more data can still be compressed.");
+
+#define ZLIB_COMPRESS_FLUSH_METHODDEF    \
+    {"flush", (PyCFunction)zlib_Compress_flush, METH_VARARGS, zlib_Compress_flush__doc__},
+
+static PyObject *
+zlib_Compress_flush_impl(compobject *self, int mode);
+
+static PyObject *
+zlib_Compress_flush(PyObject *self, PyObject *args)
+{
+    PyObject *return_value = NULL;
+    int mode = Z_FINISH;
+
+    if (!PyArg_ParseTuple(args,
+        "|i:flush",
+        &mode))
+        goto exit;
+    return_value = zlib_Compress_flush_impl((compobject *)self, mode);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(zlib_Compress_copy__doc__,
+"copy()\n"
+"Return a copy of the compression object.");
+
+#define ZLIB_COMPRESS_COPY_METHODDEF    \
+    {"copy", (PyCFunction)zlib_Compress_copy, METH_NOARGS, zlib_Compress_copy__doc__},
+
+static PyObject *
+zlib_Compress_copy_impl(compobject *self);
+
+static PyObject *
+zlib_Compress_copy(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+    return zlib_Compress_copy_impl((compobject *)self);
+}
+
+PyDoc_STRVAR(zlib_Decompress_copy__doc__,
+"copy()\n"
+"Return a copy of the decompression object.");
+
+#define ZLIB_DECOMPRESS_COPY_METHODDEF    \
+    {"copy", (PyCFunction)zlib_Decompress_copy, METH_NOARGS, zlib_Decompress_copy__doc__},
+
+static PyObject *
+zlib_Decompress_copy_impl(compobject *self);
+
+static PyObject *
+zlib_Decompress_copy(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+    return zlib_Decompress_copy_impl((compobject *)self);
+}
+
+PyDoc_STRVAR(zlib_Decompress_flush__doc__,
+"flush(length=unspecified)\n"
+"Return a bytes object containing any remaining decompressed data.\n"
+"\n"
+"  length\n"
+"    the initial size of the output buffer.");
+
+#define ZLIB_DECOMPRESS_FLUSH_METHODDEF    \
+    {"flush", (PyCFunction)zlib_Decompress_flush, METH_VARARGS, zlib_Decompress_flush__doc__},
+
+static PyObject *
+zlib_Decompress_flush_impl(compobject *self, unsigned int length);
+
+static PyObject *
+zlib_Decompress_flush(PyObject *self, PyObject *args)
+{
+    PyObject *return_value = NULL;
+    unsigned int length = DEFAULTALLOC;
+
+    if (!PyArg_ParseTuple(args,
+        "|O&:flush",
+        uint_converter, &length))
+        goto exit;
+    return_value = zlib_Decompress_flush_impl((compobject *)self, length);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(zlib_adler32__doc__,
+"adler32(data, value=1)\n"
+"Compute an Adler-32 checksum of data.\n"
+"\n"
+"  value\n"
+"    Starting value of the checksum.\n"
+"\n"
+"The returned checksum is an integer.");
+
+#define ZLIB_ADLER32_METHODDEF    \
+    {"adler32", (PyCFunction)zlib_adler32, METH_VARARGS, zlib_adler32__doc__},
+
+static PyObject *
+zlib_adler32_impl(PyModuleDef *module, Py_buffer *data, unsigned int value);
+
+static PyObject *
+zlib_adler32(PyModuleDef *module, PyObject *args)
+{
+    PyObject *return_value = NULL;
+    Py_buffer data = {NULL, NULL};
+    unsigned int value = 1;
+
+    if (!PyArg_ParseTuple(args,
+        "y*|I:adler32",
+        &data, &value))
+        goto exit;
+    return_value = zlib_adler32_impl(module, &data, value);
+
+exit:
+    /* Cleanup for data */
+    if (data.obj)
+       PyBuffer_Release(&data);
+
+    return return_value;
+}
+
+PyDoc_STRVAR(zlib_crc32__doc__,
+"crc32(data, value=0)\n"
+"Compute a CRC-32 checksum of data.\n"
+"\n"
+"  value\n"
+"    Starting value of the checksum.\n"
+"\n"
+"The returned checksum is an integer.");
+
+#define ZLIB_CRC32_METHODDEF    \
+    {"crc32", (PyCFunction)zlib_crc32, METH_VARARGS, zlib_crc32__doc__},
+
+static PyObject *
+zlib_crc32_impl(PyModuleDef *module, Py_buffer *data, unsigned int value);
+
+static PyObject *
+zlib_crc32(PyModuleDef *module, PyObject *args)
+{
+    PyObject *return_value = NULL;
+    Py_buffer data = {NULL, NULL};
+    unsigned int value = 0;
+
+    if (!PyArg_ParseTuple(args,
+        "y*|I:crc32",
+        &data, &value))
+        goto exit;
+    return_value = zlib_crc32_impl(module, &data, value);
+
+exit:
+    /* Cleanup for data */
+    if (data.obj)
+       PyBuffer_Release(&data);
+
+    return return_value;
+}
+/*[clinic end generated code: checksum=cee24603deddbfd9966a9cf37adc73a6e7aef634]*/
-------------- next part --------------
diff -r a62072cf50a2 Modules/_bz2module.c
--- a/Modules/_bz2module.c	Wed Jan 22 12:26:01 2014 +0100
+++ b/Modules/_bz2module.c	Wed Jan 22 14:49:47 2014 +0200
@@ -196,44 +196,61 @@
     return NULL;
 }
 
-PyDoc_STRVAR(BZ2Compressor_compress__doc__,
-"compress(data) -> bytes\n"
-"\n"
-"Provide data to the compressor object. Returns a chunk of\n"
-"compressed data if possible, or b'' otherwise.\n"
-"\n"
-"When you have finished providing data to the compressor, call the\n"
-"flush() method to finish the compression process.\n");
+/*[clinic input]
+output preset file
+module bz2
+class bz2.BZ2Compressor
+class bz2.BZ2Decompressor
+[clinic start generated code]*/
+/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
+
+#include "_bz2module.clinic.c"
+
+/*[clinic input]
+bz2.BZ2Compressor.compress
+
+    self: self(type="BZ2Compressor *")
+    data: Py_buffer
+    /
+
+Provide data to the compressor object.
+
+Returns a chunk of compressed data if possible, or b'' otherwise.
+
+When you have finished providing data to the compressor, call the
+flush() method to finish the compression process.
+[clinic start generated code]*/
 
 static PyObject *
-BZ2Compressor_compress(BZ2Compressor *self, PyObject *args)
+bz2_BZ2Compressor_compress_impl(BZ2Compressor *self, Py_buffer *data)
+/*[clinic end generated code: checksum=ee7e32540a3194b61bf10a81e214057760f366e2]*/
 {
-    Py_buffer buffer;
     PyObject *result = NULL;
 
-    if (!PyArg_ParseTuple(args, "y*:compress", &buffer))
-        return NULL;
-
     ACQUIRE_LOCK(self);
     if (self->flushed)
         PyErr_SetString(PyExc_ValueError, "Compressor has been flushed");
     else
-        result = compress(self, buffer.buf, buffer.len, BZ_RUN);
+        result = compress(self, data->buf, data->len, BZ_RUN);
     RELEASE_LOCK(self);
-    PyBuffer_Release(&buffer);
     return result;
 }
 
-PyDoc_STRVAR(BZ2Compressor_flush__doc__,
-"flush() -> bytes\n"
-"\n"
-"Finish the compression process. Returns the compressed data left\n"
-"in internal buffers.\n"
-"\n"
-"The compressor object may not be used after this method is called.\n");
+/*[clinic input]
+bz2.BZ2Compressor.flush
+
+    self: self(type="BZ2Compressor *")
+
+Finish the compression process.
+
+Returns the compressed data left in internal buffers.
+
+The compressor object may not be used after this method is called.
+[clinic start generated code]*/
 
 static PyObject *
-BZ2Compressor_flush(BZ2Compressor *self, PyObject *noargs)
+bz2_BZ2Compressor_flush_impl(BZ2Compressor *self)
+/*[clinic end generated code: checksum=174aede133d77dccb63a6a15d5ecdc5de77a03e9]*/
 {
     PyObject *result = NULL;
 
@@ -274,14 +291,25 @@
     PyMem_RawFree(ptr);
 }
 
+/*[clinic input]
+bz2.BZ2Compressor.__init__
+
+    self: self(type="BZ2Compressor *")
+    compresslevel: int = 9
+        Compression level, in 0-9.
+    /
+
+Create a compressor object for compressing data incrementally.
+
+For one-shot compression, use the compress() function instead.
+[clinic start generated code]*/
+
 static int
-BZ2Compressor_init(BZ2Compressor *self, PyObject *args, PyObject *kwargs)
+bz2_BZ2Compressor___init___impl(BZ2Compressor *self, int compresslevel)
+/*[clinic end generated code: checksum=423b8a96f6a06f68ddc45b2ab9dd60c792de9d25]*/
 {
-    int compresslevel = 9;
     int bzerror;
 
-    if (!PyArg_ParseTuple(args, "|i:BZ2Compressor", &compresslevel))
-        return -1;
     if (!(1 <= compresslevel && compresslevel <= 9)) {
         PyErr_SetString(PyExc_ValueError,
                         "compresslevel must be between 1 and 9");
@@ -324,23 +352,7 @@
     Py_TYPE(self)->tp_free((PyObject *)self);
 }
 
-static PyMethodDef BZ2Compressor_methods[] = {
-    {"compress",     (PyCFunction)BZ2Compressor_compress, METH_VARARGS,
-     BZ2Compressor_compress__doc__},
-    {"flush",        (PyCFunction)BZ2Compressor_flush,    METH_NOARGS,
-     BZ2Compressor_flush__doc__},
-    {"__getstate__", (PyCFunction)BZ2Compressor_getstate, METH_NOARGS},
-    {NULL}
-};
-
-PyDoc_STRVAR(BZ2Compressor__doc__,
-"BZ2Compressor(compresslevel=9)\n"
-"\n"
-"Create a compressor object for compressing data incrementally.\n"
-"\n"
-"compresslevel, if given, must be a number between 1 and 9.\n"
-"\n"
-"For one-shot compression, use the compress() function instead.\n");
+static PyMethodDef BZ2Compressor_methods[];
 
 static PyTypeObject BZ2Compressor_Type = {
     PyVarObject_HEAD_INIT(NULL, 0)
@@ -363,7 +375,7 @@
     0,                                  /* tp_setattro */
     0,                                  /* tp_as_buffer */
     Py_TPFLAGS_DEFAULT,                 /* tp_flags */
-    BZ2Compressor__doc__,               /* tp_doc */
+    bz2_BZ2Compressor___init____doc__,  /* tp_doc */
     0,                                  /* tp_traverse */
     0,                                  /* tp_clear */
     0,                                  /* tp_richcompare */
@@ -378,7 +390,7 @@
     0,                                  /* tp_descr_get */
     0,                                  /* tp_descr_set */
     0,                                  /* tp_dictoffset */
-    (initproc)BZ2Compressor_init,       /* tp_init */
+    bz2_BZ2Compressor___init__,         /* tp_init */
     0,                                  /* tp_alloc */
     PyType_GenericNew,                  /* tp_new */
 };
@@ -451,32 +463,34 @@
     return NULL;
 }
 
-PyDoc_STRVAR(BZ2Decompressor_decompress__doc__,
-"decompress(data) -> bytes\n"
-"\n"
-"Provide data to the decompressor object. Returns a chunk of\n"
-"decompressed data if possible, or b'' otherwise.\n"
-"\n"
-"Attempting to decompress data after the end of stream is reached\n"
-"raises an EOFError. Any data found after the end of the stream\n"
-"is ignored and saved in the unused_data attribute.\n");
+/*[clinic input]
+bz2.BZ2Decompressor.decompress
+
+    self: self(type="BZ2Decompressor *")
+    data: Py_buffer
+    /
+
+Provide data to the decompressor object.
+
+Returns a chunk of decompressed data if possible, or b'' otherwise.
+
+Attempting to decompress data after the end of stream is reached
+raises an EOFError.  Any data found after the end of the stream
+is ignored and saved in the unused_data attribute.
+[clinic start generated code]*/
 
 static PyObject *
-BZ2Decompressor_decompress(BZ2Decompressor *self, PyObject *args)
+bz2_BZ2Decompressor_decompress_impl(BZ2Decompressor *self, Py_buffer *data)
+/*[clinic end generated code: checksum=39f4c8064d9219f2bfd709fd9004487617588b32]*/
 {
-    Py_buffer buffer;
     PyObject *result = NULL;
 
-    if (!PyArg_ParseTuple(args, "y*:decompress", &buffer))
-        return NULL;
-
     ACQUIRE_LOCK(self);
     if (self->eof)
         PyErr_SetString(PyExc_EOFError, "End of stream already reached");
     else
-        result = decompress(self, buffer.buf, buffer.len);
+        result = decompress(self, data->buf, data->len);
     RELEASE_LOCK(self);
-    PyBuffer_Release(&buffer);
     return result;
 }
 
@@ -488,14 +502,22 @@
     return NULL;
 }
 
+/*[clinic input]
+bz2.BZ2Decompressor.__init__
+
+    self: self(type="BZ2Decompressor *")
+
+Create a decompressor object for decompressing data incrementally.
+
+For one-shot decompression, use the decompress() function instead.
+[clinic start generated code]*/
+
 static int
-BZ2Decompressor_init(BZ2Decompressor *self, PyObject *args, PyObject *kwargs)
+bz2_BZ2Decompressor___init___impl(BZ2Decompressor *self)
+/*[clinic end generated code: checksum=4d700522a687319e6afff0df15c8270d2a734d3f]*/
 {
     int bzerror;
 
-    if (!PyArg_ParseTuple(args, ":BZ2Decompressor"))
-        return -1;
-
 #ifdef WITH_THREAD
     self->lock = PyThread_allocate_lock();
     if (self->lock == NULL) {
@@ -535,9 +557,15 @@
     Py_TYPE(self)->tp_free((PyObject *)self);
 }
 
+static PyMethodDef BZ2Compressor_methods[] = {
+    BZ2_BZ2COMPRESSOR_COMPRESS_METHODDEF
+    BZ2_BZ2COMPRESSOR_FLUSH_METHODDEF
+    {"__getstate__", (PyCFunction)BZ2Compressor_getstate, METH_NOARGS},
+    {NULL}
+};
+
 static PyMethodDef BZ2Decompressor_methods[] = {
-    {"decompress", (PyCFunction)BZ2Decompressor_decompress, METH_VARARGS,
-     BZ2Decompressor_decompress__doc__},
+    BZ2_BZ2DECOMPRESSOR_DECOMPRESS_METHODDEF
     {"__getstate__", (PyCFunction)BZ2Decompressor_getstate, METH_NOARGS},
     {NULL}
 };
@@ -556,13 +584,6 @@
     {NULL}
 };
 
-PyDoc_STRVAR(BZ2Decompressor__doc__,
-"BZ2Decompressor()\n"
-"\n"
-"Create a decompressor object for decompressing data incrementally.\n"
-"\n"
-"For one-shot decompression, use the decompress() function instead.\n");
-
 static PyTypeObject BZ2Decompressor_Type = {
     PyVarObject_HEAD_INIT(NULL, 0)
     "_bz2.BZ2Decompressor",             /* tp_name */
@@ -584,7 +605,7 @@
     0,                                  /* tp_setattro */
     0,                                  /* tp_as_buffer */
     Py_TPFLAGS_DEFAULT,                 /* tp_flags */
-    BZ2Decompressor__doc__,             /* tp_doc */
+    bz2_BZ2Decompressor___init____doc__,  /* tp_doc */
     0,                                  /* tp_traverse */
     0,                                  /* tp_clear */
     0,                                  /* tp_richcompare */
@@ -599,7 +620,7 @@
     0,                                  /* tp_descr_get */
     0,                                  /* tp_descr_set */
     0,                                  /* tp_dictoffset */
-    (initproc)BZ2Decompressor_init,     /* tp_init */
+    bz2_BZ2Decompressor___init__,       /* tp_init */
     0,                                  /* tp_alloc */
     PyType_GenericNew,                  /* tp_new */
 };
diff -r a62072cf50a2 Modules/_bz2module.clinic.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Modules/_bz2module.clinic.c	Wed Jan 22 14:49:47 2014 +0200
@@ -0,0 +1,149 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+PyDoc_STRVAR(bz2_BZ2Compressor_compress__doc__,
+"compress(data)\n"
+"Provide data to the compressor object.\n"
+"\n"
+"Returns a chunk of compressed data if possible, or b\'\' otherwise.\n"
+"\n"
+"When you have finished providing data to the compressor, call the\n"
+"flush() method to finish the compression process.");
+
+#define BZ2_BZ2COMPRESSOR_COMPRESS_METHODDEF    \
+    {"compress", (PyCFunction)bz2_BZ2Compressor_compress, METH_VARARGS, bz2_BZ2Compressor_compress__doc__},
+
+static PyObject *
+bz2_BZ2Compressor_compress_impl(BZ2Compressor *self, Py_buffer *data);
+
+static PyObject *
+bz2_BZ2Compressor_compress(PyObject *self, PyObject *args)
+{
+    PyObject *return_value = NULL;
+    Py_buffer data = {NULL, NULL};
+
+    if (!PyArg_ParseTuple(args,
+        "y*:compress",
+        &data))
+        goto exit;
+    return_value = bz2_BZ2Compressor_compress_impl((BZ2Compressor *)self, &data);
+
+exit:
+    /* Cleanup for data */
+    if (data.obj)
+       PyBuffer_Release(&data);
+
+    return return_value;
+}
+
+PyDoc_STRVAR(bz2_BZ2Compressor_flush__doc__,
+"flush()\n"
+"Finish the compression process.\n"
+"\n"
+"Returns the compressed data left in internal buffers.\n"
+"\n"
+"The compressor object may not be used after this method is called.");
+
+#define BZ2_BZ2COMPRESSOR_FLUSH_METHODDEF    \
+    {"flush", (PyCFunction)bz2_BZ2Compressor_flush, METH_NOARGS, bz2_BZ2Compressor_flush__doc__},
+
+static PyObject *
+bz2_BZ2Compressor_flush_impl(BZ2Compressor *self);
+
+static PyObject *
+bz2_BZ2Compressor_flush(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+    return bz2_BZ2Compressor_flush_impl((BZ2Compressor *)self);
+}
+
+PyDoc_STRVAR(bz2_BZ2Compressor___init____doc__,
+"BZ2Compressor(compresslevel=9)\n"
+"Create a compressor object for compressing data incrementally.\n"
+"\n"
+"  compresslevel\n"
+"    Compression level, in 0-9.\n"
+"\n"
+"For one-shot compression, use the compress() function instead.");
+
+static int
+bz2_BZ2Compressor___init___impl(BZ2Compressor *self, int compresslevel);
+
+static int
+bz2_BZ2Compressor___init__(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+    int return_value = -1;
+    int compresslevel = 9;
+
+    if (!_PyArg_NoKeywords("__init__", kwargs))
+        goto exit;
+    if (!PyArg_ParseTuple(args,
+        "|i:__init__",
+        &compresslevel))
+        goto exit;
+    return_value = bz2_BZ2Compressor___init___impl((BZ2Compressor *)self, compresslevel);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(bz2_BZ2Decompressor_decompress__doc__,
+"decompress(data)\n"
+"Provide data to the decompressor object.\n"
+"\n"
+"Returns a chunk of decompressed data if possible, or b\'\' otherwise.\n"
+"\n"
+"Attempting to decompress data after the end of stream is reached\n"
+"raises an EOFError.  Any data found after the end of the stream\n"
+"is ignored and saved in the unused_data attribute.");
+
+#define BZ2_BZ2DECOMPRESSOR_DECOMPRESS_METHODDEF    \
+    {"decompress", (PyCFunction)bz2_BZ2Decompressor_decompress, METH_VARARGS, bz2_BZ2Decompressor_decompress__doc__},
+
+static PyObject *
+bz2_BZ2Decompressor_decompress_impl(BZ2Decompressor *self, Py_buffer *data);
+
+static PyObject *
+bz2_BZ2Decompressor_decompress(PyObject *self, PyObject *args)
+{
+    PyObject *return_value = NULL;
+    Py_buffer data = {NULL, NULL};
+
+    if (!PyArg_ParseTuple(args,
+        "y*:decompress",
+        &data))
+        goto exit;
+    return_value = bz2_BZ2Decompressor_decompress_impl((BZ2Decompressor *)self, &data);
+
+exit:
+    /* Cleanup for data */
+    if (data.obj)
+       PyBuffer_Release(&data);
+
+    return return_value;
+}
+
+PyDoc_STRVAR(bz2_BZ2Decompressor___init____doc__,
+"BZ2Decompressor()\n"
+"Create a decompressor object for decompressing data incrementally.\n"
+"\n"
+"For one-shot decompression, use the decompress() function instead.");
+
+static int
+bz2_BZ2Decompressor___init___impl(BZ2Decompressor *self);
+
+static int
+bz2_BZ2Decompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+    int return_value = -1;
+
+    if (!_PyArg_NoPositional("__init__", args))
+        goto exit;
+    if (!_PyArg_NoKeywords("__init__", kwargs))
+        goto exit;
+    return_value = bz2_BZ2Decompressor___init___impl((BZ2Decompressor *)self);
+
+exit:
+    return return_value;
+}
+/*[clinic end generated code: checksum=58449f6f9085faa460f2999f95f11b4f00b4871a]*/
-------------- next part --------------
diff -r a62072cf50a2 Modules/_lzmamodule.c
--- a/Modules/_lzmamodule.c	Wed Jan 22 12:26:01 2014 +0100
+++ b/Modules/_lzmamodule.c	Wed Jan 22 14:49:43 2014 +0200
@@ -298,36 +298,37 @@
     return options;
 }
 
-static void *
-parse_filter_spec(lzma_filter *f, PyObject *spec)
+static int
+lzma_filter_converter(PyObject *spec, void *ptr)
 {
+    lzma_filter *f = (lzma_filter *)ptr;
     PyObject *id_obj;
 
     if (!PyMapping_Check(spec)) {
         PyErr_SetString(PyExc_TypeError,
                         "Filter specifier must be a dict or dict-like object");
-        return NULL;
+        return 0;
     }
     id_obj = PyMapping_GetItemString(spec, "id");
     if (id_obj == NULL) {
         if (PyErr_ExceptionMatches(PyExc_KeyError))
             PyErr_SetString(PyExc_ValueError,
                             "Filter specifier must have an \"id\" entry");
-        return NULL;
+        return 0;
     }
     f->id = PyLong_AsUnsignedLongLong(id_obj);
     Py_DECREF(id_obj);
     if (PyErr_Occurred())
-        return NULL;
+        return 0;
 
     switch (f->id) {
         case LZMA_FILTER_LZMA1:
         case LZMA_FILTER_LZMA2:
             f->options = parse_filter_spec_lzma(spec);
-            return f->options;
+            return f->options != NULL;
         case LZMA_FILTER_DELTA:
             f->options = parse_filter_spec_delta(spec);
-            return f->options;
+            return f->options != NULL;
         case LZMA_FILTER_X86:
         case LZMA_FILTER_POWERPC:
         case LZMA_FILTER_IA64:
@@ -335,10 +336,10 @@
         case LZMA_FILTER_ARMTHUMB:
         case LZMA_FILTER_SPARC:
             f->options = parse_filter_spec_bcj(spec);
-            return f->options;
+            return f->options != NULL;
         default:
             PyErr_Format(PyExc_ValueError, "Invalid filter ID: %llu", f->id);
-            return NULL;
+            return 0;
     }
 }
 
@@ -369,7 +370,7 @@
     for (i = 0; i < num_filters; i++) {
         int ok = 1;
         PyObject *spec = PySequence_GetItem(filterspecs, i);
-        if (spec == NULL || parse_filter_spec(&filters[i], spec) == NULL)
+        if (spec == NULL || !lzma_filter_converter(spec, &filters[i]))
             ok = 0;
         Py_XDECREF(spec);
         if (!ok) {
@@ -468,6 +469,36 @@
 }
 
 
+/*[clinic input]
+output preset file
+module lzma
+class lzma.LZMACompressor
+class lzma.LZMADecompressor
+[clinic start generated code]*/
+/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
+
+#include "_lzmamodule.clinic.c"
+
+/*[python input]
+
+class lzma_vli_converter(CConverter):
+    type = 'lzma_vli'
+    converter = 'lzma_vli_converter'
+
+class lzma_filter_converter(CConverter):
+    type = 'lzma_filter'
+    converter = 'lzma_filter_converter'
+    c_default = c_ignored_default = "{LZMA_VLI_UNKNOWN, NULL}"
+
+    def cleanup(self):
+        name = ensure_legal_c_identifier(self.name)
+        return ('if (%(name)s.id != LZMA_VLI_UNKNOWN)\n'
+                '   PyMem_Free(%(name)s.options);\n') % {'name': name}
+
+[python start generated code]*/
+/*[python end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
+
+
 /* LZMACompressor class. */
 
 static PyObject *
@@ -512,44 +543,51 @@
     return NULL;
 }
 
-PyDoc_STRVAR(Compressor_compress_doc,
-"compress(data) -> bytes\n"
-"\n"
-"Provide data to the compressor object. Returns a chunk of\n"
-"compressed data if possible, or b\"\" otherwise.\n"
-"\n"
-"When you have finished providing data to the compressor, call the\n"
-"flush() method to finish the conversion process.\n");
+/*[clinic input]
+lzma.LZMACompressor.compress
+
+    self: self(type="Compressor *")
+    data: Py_buffer
+    /
+
+Provide data to the compressor object.
+
+Returns a chunk of compressed data if possible, or b'' otherwise.
+
+When you have finished providing data to the compressor, call the
+flush() method to finish the compression process.
+[clinic start generated code]*/
 
 static PyObject *
-Compressor_compress(Compressor *self, PyObject *args)
+lzma_LZMACompressor_compress_impl(Compressor *self, Py_buffer *data)
+/*[clinic end generated code: checksum=a6c82b0b3892e151f9fc04f1b6a56566754de6b5]*/
 {
-    Py_buffer buffer;
     PyObject *result = NULL;
 
-    if (!PyArg_ParseTuple(args, "y*:compress", &buffer))
-        return NULL;
-
     ACQUIRE_LOCK(self);
     if (self->flushed)
         PyErr_SetString(PyExc_ValueError, "Compressor has been flushed");
     else
-        result = compress(self, buffer.buf, buffer.len, LZMA_RUN);
+        result = compress(self, data->buf, data->len, LZMA_RUN);
     RELEASE_LOCK(self);
-    PyBuffer_Release(&buffer);
     return result;
 }
 
-PyDoc_STRVAR(Compressor_flush_doc,
-"flush() -> bytes\n"
-"\n"
-"Finish the compression process. Returns the compressed data left\n"
-"in internal buffers.\n"
-"\n"
-"The compressor object cannot be used after this method is called.\n");
+/*[clinic input]
+lzma.LZMACompressor.flush
+
+    self: self(type="Compressor *")
+
+Finish the compression process.
+
+Returns the compressed data left in internal buffers.
+
+The compressor object may not be used after this method is called.
+[clinic start generated code]*/
 
 static PyObject *
-Compressor_flush(Compressor *self, PyObject *noargs)
+lzma_LZMACompressor_flush_impl(Compressor *self)
+/*[clinic end generated code: checksum=418006f2533b8ca25a3e2d7949769e05bb593cc9]*/
 {
     PyObject *result = NULL;
 
@@ -650,21 +688,47 @@
         return 0;
 }
 
+/*[clinic input]
+lzma.LZMACompressor.__init__
+
+    self: self(type="Compressor *")
+    format: int(c_default="FORMAT_XZ") = FORMAT_XZ
+        The container format to use for the output.  This can
+        be FORMAT_XZ (default), FORMAT_ALONE, or FORMAT_RAW.
+
+    check: int(c_default="-1") = unspecified
+        The integrity check to use.  For FORMAT_XZ, the default
+        is CHECK_CRC64.  FORMAT_ALONE and FORMAT_RAW do not suport integrity
+        checks; for these formats, check must be omitted, or be CHECK_NONE.
+
+    preset: object = None
+        If provided should be an integer in the range 0-9, optionally
+        OR-ed with the constant PRESET_EXTREME.
+
+    filters: object = None
+        If provided should be a sequence of dicts.  Each dict should
+        have an entry for "id" indicating the ID of the filter, plus
+        additional entries for options to the filter.
+
+    /
+
+Create a compressor object for compressing data incrementally.
+
+The settings used by the compressor can be specified either as a
+preset compression level (with the 'preset' argument), or in detail
+as a custom filter chain (with the 'filters' argument).  For FORMAT_XZ
+and FORMAT_ALONE, the default is to use the PRESET_DEFAULT preset
+level.  For FORMAT_RAW, the caller must always specify a filter chain;
+the raw compressor does not support preset compression levels.
+
+For one-shot compression, use the compress() function instead.
+[clinic start generated code]*/
+
 static int
-Compressor_init(Compressor *self, PyObject *args, PyObject *kwargs)
+lzma_LZMACompressor___init___impl(Compressor *self, int format, int check, PyObject *preset, PyObject *filters)
+/*[clinic end generated code: checksum=667dce31976a26146d9a2ab0212ffe52e5c5df32]*/
 {
-    static char *arg_names[] = {"format", "check", "preset", "filters", NULL};
-    int format = FORMAT_XZ;
-    int check = -1;
-    uint32_t preset = LZMA_PRESET_DEFAULT;
-    PyObject *preset_obj = Py_None;
-    PyObject *filterspecs = Py_None;
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
-                                     "|iiOO:LZMACompressor", arg_names,
-                                     &format, &check, &preset_obj,
-                                     &filterspecs))
-        return -1;
+    uint32_t preset_ = LZMA_PRESET_DEFAULT;
 
     if (format != FORMAT_XZ && check != -1 && check != LZMA_CHECK_NONE) {
         PyErr_SetString(PyExc_ValueError,
@@ -672,14 +736,14 @@
         return -1;
     }
 
-    if (preset_obj != Py_None && filterspecs != Py_None) {
+    if (preset != Py_None && filters != Py_None) {
         PyErr_SetString(PyExc_ValueError,
                         "Cannot specify both preset and filter chain");
         return -1;
     }
 
-    if (preset_obj != Py_None)
-        if (!uint32_converter(preset_obj, &preset))
+    if (preset != Py_None)
+        if (!uint32_converter(preset, &preset_))
             return -1;
 
     self->alloc.opaque = NULL;
@@ -700,17 +764,17 @@
         case FORMAT_XZ:
             if (check == -1)
                 check = LZMA_CHECK_CRC64;
-            if (Compressor_init_xz(&self->lzs, check, preset, filterspecs) != 0)
+            if (Compressor_init_xz(&self->lzs, check, preset_, filters) != 0)
                 break;
             return 0;
 
         case FORMAT_ALONE:
-            if (Compressor_init_alone(&self->lzs, preset, filterspecs) != 0)
+            if (Compressor_init_alone(&self->lzs, preset_, filters) != 0)
                 break;
             return 0;
 
         case FORMAT_RAW:
-            if (Compressor_init_raw(&self->lzs, filterspecs) != 0)
+            if (Compressor_init_raw(&self->lzs, filters) != 0)
                 break;
             return 0;
 
@@ -739,42 +803,12 @@
 }
 
 static PyMethodDef Compressor_methods[] = {
-    {"compress", (PyCFunction)Compressor_compress, METH_VARARGS,
-     Compressor_compress_doc},
-    {"flush", (PyCFunction)Compressor_flush, METH_NOARGS,
-     Compressor_flush_doc},
+    LZMA_LZMACOMPRESSOR_COMPRESS_METHODDEF
+    LZMA_LZMACOMPRESSOR_FLUSH_METHODDEF
     {"__getstate__", (PyCFunction)Compressor_getstate, METH_NOARGS},
     {NULL}
 };
 
-PyDoc_STRVAR(Compressor_doc,
-"LZMACompressor(format=FORMAT_XZ, check=-1, preset=None, filters=None)\n"
-"\n"
-"Create a compressor object for compressing data incrementally.\n"
-"\n"
-"format specifies the container format to use for the output. This can\n"
-"be FORMAT_XZ (default), FORMAT_ALONE, or FORMAT_RAW.\n"
-"\n"
-"check specifies the integrity check to use. For FORMAT_XZ, the default\n"
-"is CHECK_CRC64. FORMAT_ALONE and FORMAT_RAW do not suport integrity\n"
-"checks; for these formats, check must be omitted, or be CHECK_NONE.\n"
-"\n"
-"The settings used by the compressor can be specified either as a\n"
-"preset compression level (with the 'preset' argument), or in detail\n"
-"as a custom filter chain (with the 'filters' argument). For FORMAT_XZ\n"
-"and FORMAT_ALONE, the default is to use the PRESET_DEFAULT preset\n"
-"level. For FORMAT_RAW, the caller must always specify a filter chain;\n"
-"the raw compressor does not support preset compression levels.\n"
-"\n"
-"preset (if provided) should be an integer in the range 0-9, optionally\n"
-"OR-ed with the constant PRESET_EXTREME.\n"
-"\n"
-"filters (if provided) should be a sequence of dicts. Each dict should\n"
-"have an entry for \"id\" indicating the ID of the filter, plus\n"
-"additional entries for options to the filter.\n"
-"\n"
-"For one-shot compression, use the compress() function instead.\n");
-
 static PyTypeObject Compressor_type = {
     PyVarObject_HEAD_INIT(NULL, 0)
     "_lzma.LZMACompressor",             /* tp_name */
@@ -796,7 +830,7 @@
     0,                                  /* tp_setattro */
     0,                                  /* tp_as_buffer */
     Py_TPFLAGS_DEFAULT,                 /* tp_flags */
-    Compressor_doc,                     /* tp_doc */
+    lzma_LZMACompressor___init____doc__,  /* tp_doc */
     0,                                  /* tp_traverse */
     0,                                  /* tp_clear */
     0,                                  /* tp_richcompare */
@@ -811,7 +845,7 @@
     0,                                  /* tp_descr_get */
     0,                                  /* tp_descr_set */
     0,                                  /* tp_dictoffset */
-    (initproc)Compressor_init,          /* tp_init */
+    lzma_LZMACompressor___init__,       /* tp_init */
     0,                                  /* tp_alloc */
     PyType_GenericNew,                  /* tp_new */
 };
@@ -872,32 +906,34 @@
     return NULL;
 }
 
-PyDoc_STRVAR(Decompressor_decompress_doc,
-"decompress(data) -> bytes\n"
-"\n"
-"Provide data to the decompressor object. Returns a chunk of\n"
-"decompressed data if possible, or b\"\" otherwise.\n"
-"\n"
-"Attempting to decompress data after the end of the stream is\n"
-"reached raises an EOFError. Any data found after the end of the\n"
-"stream is ignored, and saved in the unused_data attribute.\n");
+/*[clinic input]
+lzma.LZMADecompressor.decompress
+
+    self: self(type="Decompressor *")
+    data: Py_buffer
+    /
+
+Provide data to the decompressor object.
+
+Returns a chunk of decompressed data if possible, or b'' otherwise.
+
+Attempting to decompress data after the end of stream is reached
+raises an EOFError.  Any data found after the end of the stream
+is ignored and saved in the unused_data attribute.
+[clinic start generated code]*/
 
 static PyObject *
-Decompressor_decompress(Decompressor *self, PyObject *args)
+lzma_LZMADecompressor_decompress_impl(Decompressor *self, Py_buffer *data)
+/*[clinic end generated code: checksum=24be3317e1ba0ef15cfa4aa0bf2d6f4dccc697b0]*/
 {
-    Py_buffer buffer;
     PyObject *result = NULL;
 
-    if (!PyArg_ParseTuple(args, "y*:decompress", &buffer))
-        return NULL;
-
     ACQUIRE_LOCK(self);
     if (self->eof)
         PyErr_SetString(PyExc_EOFError, "Already at end of stream");
     else
-        result = decompress(self, buffer.buf, buffer.len);
+        result = decompress(self, data->buf, data->len);
     RELEASE_LOCK(self);
-    PyBuffer_Release(&buffer);
     return result;
 }
 
@@ -925,38 +961,58 @@
         return 0;
 }
 
+/*[clinic input]
+lzma.LZMADecompressor.__init__
+
+    self: self(type="Decompressor *")
+    format: int(c_default="FORMAT_AUTO") = FORMAT_AUTO
+        Specifies the container format of the input stream.  If this is
+        FORMAT_AUTO (the default), the decompressor will automatically detect
+        whether the input is FORMAT_XZ or FORMAT_ALONE.  Streams created with
+        FORMAT_RAW cannot be autodetected.
+
+    memlimit: object = None
+        Limit the amount of memory used by the decompressor.  This will cause
+        decompression to fail if the input cannot be decompressed within the
+        given limit.
+
+    filters: object = None
+        A custom filter chain.  This argument is required for FORMAT_RAW, and
+        not accepted with any other format.  When provided, this should be a
+        sequence of dicts, each indicating the ID and options for a single
+        filter.
+
+    /
+
+Create a decompressor object for decompressing data incrementally.
+
+For one-shot decompression, use the decompress() function instead.
+[clinic start generated code]*/
+
 static int
-Decompressor_init(Decompressor *self, PyObject *args, PyObject *kwargs)
+lzma_LZMADecompressor___init___impl(Decompressor *self, int format, PyObject *memlimit, PyObject *filters)
+/*[clinic end generated code: checksum=19b6b5806ded26326e496f7fc193c53db24b0c9a]*/
 {
-    static char *arg_names[] = {"format", "memlimit", "filters", NULL};
     const uint32_t decoder_flags = LZMA_TELL_ANY_CHECK | LZMA_TELL_NO_CHECK;
-    int format = FORMAT_AUTO;
-    uint64_t memlimit = UINT64_MAX;
-    PyObject *memlimit_obj = Py_None;
-    PyObject *filterspecs = Py_None;
+    uint64_t memlimit_ = UINT64_MAX;
     lzma_ret lzret;
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
-                                     "|iOO:LZMADecompressor", arg_names,
-                                     &format, &memlimit_obj, &filterspecs))
-        return -1;
-
-    if (memlimit_obj != Py_None) {
+    if (memlimit != Py_None) {
         if (format == FORMAT_RAW) {
             PyErr_SetString(PyExc_ValueError,
                             "Cannot specify memory limit with FORMAT_RAW");
             return -1;
         }
-        memlimit = PyLong_AsUnsignedLongLong(memlimit_obj);
+        memlimit_ = PyLong_AsUnsignedLongLong(memlimit);
         if (PyErr_Occurred())
             return -1;
     }
 
-    if (format == FORMAT_RAW && filterspecs == Py_None) {
+    if (format == FORMAT_RAW && filters == Py_None) {
         PyErr_SetString(PyExc_ValueError,
                         "Must specify filters for FORMAT_RAW");
         return -1;
-    } else if (format != FORMAT_RAW && filterspecs != Py_None) {
+    } else if (format != FORMAT_RAW && filters != Py_None) {
         PyErr_SetString(PyExc_ValueError,
                         "Cannot specify filters except with FORMAT_RAW");
         return -1;
@@ -982,27 +1038,27 @@
 
     switch (format) {
         case FORMAT_AUTO:
-            lzret = lzma_auto_decoder(&self->lzs, memlimit, decoder_flags);
+            lzret = lzma_auto_decoder(&self->lzs, memlimit_, decoder_flags);
             if (catch_lzma_error(lzret))
                 break;
             return 0;
 
         case FORMAT_XZ:
-            lzret = lzma_stream_decoder(&self->lzs, memlimit, decoder_flags);
+            lzret = lzma_stream_decoder(&self->lzs, memlimit_, decoder_flags);
             if (catch_lzma_error(lzret))
                 break;
             return 0;
 
         case FORMAT_ALONE:
             self->check = LZMA_CHECK_NONE;
-            lzret = lzma_alone_decoder(&self->lzs, memlimit);
+            lzret = lzma_alone_decoder(&self->lzs, memlimit_);
             if (catch_lzma_error(lzret))
                 break;
             return 0;
 
         case FORMAT_RAW:
             self->check = LZMA_CHECK_NONE;
-            if (Decompressor_init_raw(&self->lzs, filterspecs) == -1)
+            if (Decompressor_init_raw(&self->lzs, filters) == -1)
                 break;
             return 0;
 
@@ -1034,8 +1090,7 @@
 }
 
 static PyMethodDef Decompressor_methods[] = {
-    {"decompress", (PyCFunction)Decompressor_decompress, METH_VARARGS,
-     Decompressor_decompress_doc},
+    LZMA_LZMADECOMPRESSOR_DECOMPRESS_METHODDEF
     {"__getstate__", (PyCFunction)Decompressor_getstate, METH_NOARGS},
     {NULL}
 };
@@ -1059,27 +1114,6 @@
     {NULL}
 };
 
-PyDoc_STRVAR(Decompressor_doc,
-"LZMADecompressor(format=FORMAT_AUTO, memlimit=None, filters=None)\n"
-"\n"
-"Create a decompressor object for decompressing data incrementally.\n"
-"\n"
-"format specifies the container format of the input stream. If this is\n"
-"FORMAT_AUTO (the default), the decompressor will automatically detect\n"
-"whether the input is FORMAT_XZ or FORMAT_ALONE. Streams created with\n"
-"FORMAT_RAW cannot be autodetected.\n"
-"\n"
-"memlimit can be specified to limit the amount of memory used by the\n"
-"decompressor. This will cause decompression to fail if the input\n"
-"cannot be decompressed within the given limit.\n"
-"\n"
-"filters specifies a custom filter chain. This argument is required for\n"
-"FORMAT_RAW, and not accepted with any other format. When provided,\n"
-"this should be a sequence of dicts, each indicating the ID and options\n"
-"for a single filter.\n"
-"\n"
-"For one-shot decompression, use the decompress() function instead.\n");
-
 static PyTypeObject Decompressor_type = {
     PyVarObject_HEAD_INIT(NULL, 0)
     "_lzma.LZMADecompressor",           /* tp_name */
@@ -1101,7 +1135,7 @@
     0,                                  /* tp_setattro */
     0,                                  /* tp_as_buffer */
     Py_TPFLAGS_DEFAULT,                 /* tp_flags */
-    Decompressor_doc,                   /* tp_doc */
+    lzma_LZMADecompressor___init____doc__,  /* tp_doc */
     0,                                  /* tp_traverse */
     0,                                  /* tp_clear */
     0,                                  /* tp_richcompare */
@@ -1116,7 +1150,7 @@
     0,                                  /* tp_descr_get */
     0,                                  /* tp_descr_set */
     0,                                  /* tp_dictoffset */
-    (initproc)Decompressor_init,        /* tp_init */
+    lzma_LZMADecompressor___init__,     /* tp_init */
     0,                                  /* tp_alloc */
     PyType_GenericNew,                  /* tp_new */
 };
@@ -1124,48 +1158,42 @@
 
 /* Module-level functions. */
 
-PyDoc_STRVAR(is_check_supported_doc,
-"is_check_supported(check_id) -> bool\n"
-"\n"
-"Test whether the given integrity check is supported.\n"
-"\n"
-"Always returns True for CHECK_NONE and CHECK_CRC32.\n");
+/*[clinic input]
+lzma.is_check_supported
+    check_id: int
+    /
+
+Test whether the given integrity check is supported.
+
+Always returns True for CHECK_NONE and CHECK_CRC32.
+[clinic start generated code]*/
 
 static PyObject *
-is_check_supported(PyObject *self, PyObject *args)
+lzma_is_check_supported_impl(PyModuleDef *module, int check_id)
+/*[clinic end generated code: checksum=66986a6983dff2315fbe4e8b4ea79c8ed25c6406]*/
 {
-    int check_id;
-
-    if (!PyArg_ParseTuple(args, "i:is_check_supported", &check_id))
-        return NULL;
-
     return PyBool_FromLong(lzma_check_is_supported(check_id));
 }
 
 
-PyDoc_STRVAR(_encode_filter_properties_doc,
-"_encode_filter_properties(filter) -> bytes\n"
-"\n"
-"Return a bytes object encoding the options (properties) of the filter\n"
-"specified by *filter* (a dict).\n"
-"\n"
-"The result does not include the filter ID itself, only the options.\n");
+/*[clinic input]
+lzma._encode_filter_properties
+    filter: lzma_filter(c_default="{LZMA_VLI_UNKNOWN, NULL}")
+    /
+
+Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).
+
+The result does not include the filter ID itself, only the options.
+[clinic start generated code]*/
 
 static PyObject *
-_encode_filter_properties(PyObject *self, PyObject *args)
+lzma__encode_filter_properties_impl(PyModuleDef *module, lzma_filter filter)
+/*[clinic end generated code: checksum=1c3f9391ea615088d00c0a855a7a02eca63890d4]*/
 {
-    PyObject *filterspec;
-    lzma_filter filter;
     lzma_ret lzret;
     uint32_t encoded_size;
     PyObject *result = NULL;
 
-    if (!PyArg_ParseTuple(args, "O:_encode_filter_properties", &filterspec))
-        return NULL;
-
-    if (parse_filter_spec(&filter, filterspec) == NULL)
-        return NULL;
-
     lzret = lzma_properties_size(&encoded_size, &filter);
     if (catch_lzma_error(lzret))
         goto error;
@@ -1179,37 +1207,36 @@
     if (catch_lzma_error(lzret))
         goto error;
 
-    PyMem_Free(filter.options);
     return result;
 
 error:
     Py_XDECREF(result);
-    PyMem_Free(filter.options);
     return NULL;
 }
 
 
-PyDoc_STRVAR(_decode_filter_properties_doc,
-"_decode_filter_properties(filter_id, encoded_props) -> dict\n"
-"\n"
-"Return a dict describing a filter with ID *filter_id*, and options\n"
-"(properties) decoded from the bytes object *encoded_props*.\n");
+/*[clinic input]
+lzma._decode_filter_properties
+    filter_id: lzma_vli
+    encoded_props: Py_buffer
+    /
+
+Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).
+
+The result does not include the filter ID itself, only the options.
+[clinic start generated code]*/
 
 static PyObject *
-_decode_filter_properties(PyObject *self, PyObject *args)
+lzma__decode_filter_properties_impl(PyModuleDef *module, lzma_vli filter_id, Py_buffer *encoded_props)
+/*[clinic end generated code: checksum=2ffdb2520c442a566fb814013370a58327040f84]*/
 {
-    Py_buffer encoded_props;
     lzma_filter filter;
     lzma_ret lzret;
     PyObject *result = NULL;
-
-    if (!PyArg_ParseTuple(args, "O&y*:_decode_filter_properties",
-                          lzma_vli_converter, &filter.id, &encoded_props))
-        return NULL;
+    filter.id = filter_id;
 
     lzret = lzma_properties_decode(
-            &filter, NULL, encoded_props.buf, encoded_props.len);
-    PyBuffer_Release(&encoded_props);
+            &filter, NULL, encoded_props->buf, encoded_props->len);
     if (catch_lzma_error(lzret))
         return NULL;
 
@@ -1225,12 +1252,9 @@
 /* Module initialization. */
 
 static PyMethodDef module_methods[] = {
-    {"is_check_supported", (PyCFunction)is_check_supported,
-     METH_VARARGS, is_check_supported_doc},
-    {"_encode_filter_properties", (PyCFunction)_encode_filter_properties,
-     METH_VARARGS, _encode_filter_properties_doc},
-    {"_decode_filter_properties", (PyCFunction)_decode_filter_properties,
-     METH_VARARGS, _decode_filter_properties_doc},
+    LZMA_IS_CHECK_SUPPORTED_METHODDEF
+    LZMA__ENCODE_FILTER_PROPERTIES_METHODDEF
+    LZMA__DECODE_FILTER_PROPERTIES_METHODDEF
     {NULL}
 };
 
diff -r a62072cf50a2 Modules/_lzmamodule.clinic.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Modules/_lzmamodule.clinic.c	Wed Jan 22 14:49:43 2014 +0200
@@ -0,0 +1,284 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+PyDoc_STRVAR(lzma_LZMACompressor_compress__doc__,
+"compress(data)\n"
+"Provide data to the compressor object.\n"
+"\n"
+"Returns a chunk of compressed data if possible, or b\'\' otherwise.\n"
+"\n"
+"When you have finished providing data to the compressor, call the\n"
+"flush() method to finish the compression process.");
+
+#define LZMA_LZMACOMPRESSOR_COMPRESS_METHODDEF    \
+    {"compress", (PyCFunction)lzma_LZMACompressor_compress, METH_VARARGS, lzma_LZMACompressor_compress__doc__},
+
+static PyObject *
+lzma_LZMACompressor_compress_impl(Compressor *self, Py_buffer *data);
+
+static PyObject *
+lzma_LZMACompressor_compress(PyObject *self, PyObject *args)
+{
+    PyObject *return_value = NULL;
+    Py_buffer data = {NULL, NULL};
+
+    if (!PyArg_ParseTuple(args,
+        "y*:compress",
+        &data))
+        goto exit;
+    return_value = lzma_LZMACompressor_compress_impl((Compressor *)self, &data);
+
+exit:
+    /* Cleanup for data */
+    if (data.obj)
+       PyBuffer_Release(&data);
+
+    return return_value;
+}
+
+PyDoc_STRVAR(lzma_LZMACompressor_flush__doc__,
+"flush()\n"
+"Finish the compression process.\n"
+"\n"
+"Returns the compressed data left in internal buffers.\n"
+"\n"
+"The compressor object may not be used after this method is called.");
+
+#define LZMA_LZMACOMPRESSOR_FLUSH_METHODDEF    \
+    {"flush", (PyCFunction)lzma_LZMACompressor_flush, METH_NOARGS, lzma_LZMACompressor_flush__doc__},
+
+static PyObject *
+lzma_LZMACompressor_flush_impl(Compressor *self);
+
+static PyObject *
+lzma_LZMACompressor_flush(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+    return lzma_LZMACompressor_flush_impl((Compressor *)self);
+}
+
+PyDoc_STRVAR(lzma_LZMACompressor___init____doc__,
+"LZMACompressor(format=FORMAT_XZ, check=unspecified, preset=None, filters=None)\n"
+"Create a compressor object for compressing data incrementally.\n"
+"\n"
+"  format\n"
+"    The container format to use for the output.  This can\n"
+"    be FORMAT_XZ (default), FORMAT_ALONE, or FORMAT_RAW.\n"
+"  check\n"
+"    The integrity check to use.  For FORMAT_XZ, the default\n"
+"    is CHECK_CRC64.  FORMAT_ALONE and FORMAT_RAW do not suport integrity\n"
+"    checks; for these formats, check must be omitted, or be CHECK_NONE.\n"
+"  preset\n"
+"    If provided should be an integer in the range 0-9, optionally\n"
+"    OR-ed with the constant PRESET_EXTREME.\n"
+"  filters\n"
+"    If provided should be a sequence of dicts.  Each dict should\n"
+"    have an entry for \"id\" indicating the ID of the filter, plus\n"
+"    additional entries for options to the filter.\n"
+"\n"
+"The settings used by the compressor can be specified either as a\n"
+"preset compression level (with the \'preset\' argument), or in detail\n"
+"as a custom filter chain (with the \'filters\' argument).  For FORMAT_XZ\n"
+"and FORMAT_ALONE, the default is to use the PRESET_DEFAULT preset\n"
+"level.  For FORMAT_RAW, the caller must always specify a filter chain;\n"
+"the raw compressor does not support preset compression levels.\n"
+"\n"
+"For one-shot compression, use the compress() function instead.");
+
+static int
+lzma_LZMACompressor___init___impl(Compressor *self, int format, int check, PyObject *preset, PyObject *filters);
+
+static int
+lzma_LZMACompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+    int return_value = -1;
+    int format = FORMAT_XZ;
+    int check = -1;
+    PyObject *preset = Py_None;
+    PyObject *filters = Py_None;
+
+    if (!_PyArg_NoKeywords("__init__", kwargs))
+        goto exit;
+    if (!PyArg_ParseTuple(args,
+        "|iiOO:__init__",
+        &format, &check, &preset, &filters))
+        goto exit;
+    return_value = lzma_LZMACompressor___init___impl((Compressor *)self, format, check, preset, filters);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(lzma_LZMADecompressor_decompress__doc__,
+"decompress(data)\n"
+"Provide data to the decompressor object.\n"
+"\n"
+"Returns a chunk of decompressed data if possible, or b\'\' otherwise.\n"
+"\n"
+"Attempting to decompress data after the end of stream is reached\n"
+"raises an EOFError.  Any data found after the end of the stream\n"
+"is ignored and saved in the unused_data attribute.");
+
+#define LZMA_LZMADECOMPRESSOR_DECOMPRESS_METHODDEF    \
+    {"decompress", (PyCFunction)lzma_LZMADecompressor_decompress, METH_VARARGS, lzma_LZMADecompressor_decompress__doc__},
+
+static PyObject *
+lzma_LZMADecompressor_decompress_impl(Decompressor *self, Py_buffer *data);
+
+static PyObject *
+lzma_LZMADecompressor_decompress(PyObject *self, PyObject *args)
+{
+    PyObject *return_value = NULL;
+    Py_buffer data = {NULL, NULL};
+
+    if (!PyArg_ParseTuple(args,
+        "y*:decompress",
+        &data))
+        goto exit;
+    return_value = lzma_LZMADecompressor_decompress_impl((Decompressor *)self, &data);
+
+exit:
+    /* Cleanup for data */
+    if (data.obj)
+       PyBuffer_Release(&data);
+
+    return return_value;
+}
+
+PyDoc_STRVAR(lzma_LZMADecompressor___init____doc__,
+"LZMADecompressor(format=FORMAT_AUTO, memlimit=None, filters=None)\n"
+"Create a decompressor object for decompressing data incrementally.\n"
+"\n"
+"  format\n"
+"    Specifies the container format of the input stream.  If this is\n"
+"    FORMAT_AUTO (the default), the decompressor will automatically detect\n"
+"    whether the input is FORMAT_XZ or FORMAT_ALONE.  Streams created with\n"
+"    FORMAT_RAW cannot be autodetected.\n"
+"  memlimit\n"
+"    Limit the amount of memory used by the decompressor.  This will cause\n"
+"    decompression to fail if the input cannot be decompressed within the\n"
+"    given limit.\n"
+"  filters\n"
+"    A custom filter chain.  This argument is required for FORMAT_RAW, and\n"
+"    not accepted with any other format.  When provided, this should be a\n"
+"    sequence of dicts, each indicating the ID and options for a single\n"
+"    filter.\n"
+"\n"
+"For one-shot decompression, use the decompress() function instead.");
+
+static int
+lzma_LZMADecompressor___init___impl(Decompressor *self, int format, PyObject *memlimit, PyObject *filters);
+
+static int
+lzma_LZMADecompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+    int return_value = -1;
+    int format = FORMAT_AUTO;
+    PyObject *memlimit = Py_None;
+    PyObject *filters = Py_None;
+
+    if (!_PyArg_NoKeywords("__init__", kwargs))
+        goto exit;
+    if (!PyArg_ParseTuple(args,
+        "|iOO:__init__",
+        &format, &memlimit, &filters))
+        goto exit;
+    return_value = lzma_LZMADecompressor___init___impl((Decompressor *)self, format, memlimit, filters);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(lzma_is_check_supported__doc__,
+"is_check_supported(check_id)\n"
+"Test whether the given integrity check is supported.\n"
+"\n"
+"Always returns True for CHECK_NONE and CHECK_CRC32.");
+
+#define LZMA_IS_CHECK_SUPPORTED_METHODDEF    \
+    {"is_check_supported", (PyCFunction)lzma_is_check_supported, METH_VARARGS, lzma_is_check_supported__doc__},
+
+static PyObject *
+lzma_is_check_supported_impl(PyModuleDef *module, int check_id);
+
+static PyObject *
+lzma_is_check_supported(PyModuleDef *module, PyObject *args)
+{
+    PyObject *return_value = NULL;
+    int check_id;
+
+    if (!PyArg_ParseTuple(args,
+        "i:is_check_supported",
+        &check_id))
+        goto exit;
+    return_value = lzma_is_check_supported_impl(module, check_id);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(lzma__encode_filter_properties__doc__,
+"_encode_filter_properties(filter)\n"
+"Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).\n"
+"\n"
+"The result does not include the filter ID itself, only the options.");
+
+#define LZMA__ENCODE_FILTER_PROPERTIES_METHODDEF    \
+    {"_encode_filter_properties", (PyCFunction)lzma__encode_filter_properties, METH_VARARGS, lzma__encode_filter_properties__doc__},
+
+static PyObject *
+lzma__encode_filter_properties_impl(PyModuleDef *module, lzma_filter filter);
+
+static PyObject *
+lzma__encode_filter_properties(PyModuleDef *module, PyObject *args)
+{
+    PyObject *return_value = NULL;
+    lzma_filter filter = {LZMA_VLI_UNKNOWN, NULL};
+
+    if (!PyArg_ParseTuple(args,
+        "O&:_encode_filter_properties",
+        lzma_filter_converter, &filter))
+        goto exit;
+    return_value = lzma__encode_filter_properties_impl(module, filter);
+
+exit:
+    /* Cleanup for filter */
+    if (filter.id != LZMA_VLI_UNKNOWN)
+       PyMem_Free(filter.options);
+
+    return return_value;
+}
+
+PyDoc_STRVAR(lzma__decode_filter_properties__doc__,
+"_decode_filter_properties(filter_id, encoded_props)\n"
+"Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).\n"
+"\n"
+"The result does not include the filter ID itself, only the options.");
+
+#define LZMA__DECODE_FILTER_PROPERTIES_METHODDEF    \
+    {"_decode_filter_properties", (PyCFunction)lzma__decode_filter_properties, METH_VARARGS, lzma__decode_filter_properties__doc__},
+
+static PyObject *
+lzma__decode_filter_properties_impl(PyModuleDef *module, lzma_vli filter_id, Py_buffer *encoded_props);
+
+static PyObject *
+lzma__decode_filter_properties(PyModuleDef *module, PyObject *args)
+{
+    PyObject *return_value = NULL;
+    lzma_vli filter_id;
+    Py_buffer encoded_props = {NULL, NULL};
+
+    if (!PyArg_ParseTuple(args,
+        "O&y*:_decode_filter_properties",
+        lzma_vli_converter, &filter_id, &encoded_props))
+        goto exit;
+    return_value = lzma__decode_filter_properties_impl(module, filter_id, &encoded_props);
+
+exit:
+    /* Cleanup for encoded_props */
+    if (encoded_props.obj)
+       PyBuffer_Release(&encoded_props);
+
+    return return_value;
+}
+/*[clinic end generated code: checksum=66ee0c0b69a0f8b713dca135aa291cb0bfd4afb8]*/


More information about the Python-bugs-list mailing list