From 63bc0fb0aa463a70a0d115fad21219b896683c8d Mon Sep 17 00:00:00 2001 From: Dwayne Litzenberger Date: Sun, 14 Jul 2013 20:26:53 -0700 Subject: Improve C extension autodocs - Add __all__ to C cipher & hash modules - Update hash module docstrings to document the block_size and digest_size variables. Closes: https://bugs.launchpad.net/pycrypto/+bug/1179255 --- src/MD2.c | 8 ++++- src/MD4.c | 8 ++++- src/RIPEMD160.c | 8 ++++- src/SHA224.c | 8 ++++- src/SHA256.c | 8 ++++- src/SHA384.c | 8 ++++- src/SHA512.c | 8 ++++- src/block_template.c | 23 ++++++++++++++ src/hash_template.c | 86 +++++++++++++++++++++++++++++++++++++++++++-------- src/stream_template.c | 17 ++++++++++ 10 files changed, 162 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/MD2.c b/src/MD2.c index 4214ac0..86ea859 100644 --- a/src/MD2.c +++ b/src/MD2.c @@ -49,7 +49,13 @@ static char MODULE__doc__[] = "\n" "This algorithm is both slow and insecure. Do not use it for new designs.\n" "\n" - ".. _RFC1319: http://tools.ietf.org/html/rfc1319\n"; + ".. _RFC1319: http://tools.ietf.org/html/rfc1319\n" + "\n" + ":Variables:\n" + " block_size\n" + " The internal block size of the hash algorithm in bytes.\n" + " digest_size\n" + " The size of the resulting hash in bytes.\n"; typedef uint8_t U8; typedef uint32_t U32; diff --git a/src/MD4.c b/src/MD4.c index a2be10e..2d38339 100644 --- a/src/MD4.c +++ b/src/MD4.c @@ -48,7 +48,13 @@ static char MODULE__doc__[] = "\n" "This algorithm is insecure. Do not use it for new designs.\n" "\n" - ".. _RFC1320: http://tools.ietf.org/html/rfc1320\n"; + ".. _RFC1320: http://tools.ietf.org/html/rfc1320\n" + "\n" + ":Variables:\n" + " block_size\n" + " The internal block size of the hash algorithm in bytes.\n" + " digest_size\n" + " The size of the resulting hash in bytes.\n"; typedef uint32_t U32; typedef uint8_t U8; diff --git a/src/RIPEMD160.c b/src/RIPEMD160.c index 67fec96..8b33bab 100644 --- a/src/RIPEMD160.c +++ b/src/RIPEMD160.c @@ -68,7 +68,13 @@ static char MODULE__doc__[] = "extensively as SHA-1. Moreover, it provides an informal security level of just\n" "80bits.\n" "\n" - ".. _RIPEMD-160: http://homes.esat.kuleuven.be/~bosselae/ripemd160.html\n"; + ".. _RIPEMD-160: http://homes.esat.kuleuven.be/~bosselae/ripemd160.html\n" + "\n" + ":Variables:\n" + " block_size\n" + " The internal block size of the hash algorithm in bytes.\n" + " digest_size\n" + " The size of the resulting hash in bytes.\n"; #define RIPEMD160_MAGIC 0x9f19dd68u typedef struct { diff --git a/src/SHA224.c b/src/SHA224.c index e060e11..b0d15d8 100644 --- a/src/SHA224.c +++ b/src/SHA224.c @@ -49,7 +49,13 @@ static char MODULE__doc__[] = "\n" "*SHA* stands for Secure Hash Algorithm.\n" "\n" - ".. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf\n"; + ".. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf\n" + "\n" + ":Variables:\n" + " block_size\n" + " The internal block size of the hash algorithm in bytes.\n" + " digest_size\n" + " The size of the resulting hash in bytes.\n"; #include "hash_SHA2.h" diff --git a/src/SHA256.c b/src/SHA256.c index b735b81..a856fbb 100644 --- a/src/SHA256.c +++ b/src/SHA256.c @@ -49,7 +49,13 @@ static char MODULE__doc__[] = "\n" "*SHA* stands for Secure Hash Algorithm.\n" "\n" - ".. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf\n"; + ".. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf\n" + "\n" + ":Variables:\n" + " block_size\n" + " The internal block size of the hash algorithm in bytes.\n" + " digest_size\n" + " The size of the resulting hash in bytes.\n"; #include "hash_SHA2.h" diff --git a/src/SHA384.c b/src/SHA384.c index 8bc099a..7ae9ff4 100644 --- a/src/SHA384.c +++ b/src/SHA384.c @@ -49,7 +49,13 @@ static char MODULE__doc__[] = "\n" "*SHA* stands for Secure Hash Algorithm.\n" "\n" - ".. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf\n"; + ".. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf\n" + "\n" + ":Variables:\n" + " block_size\n" + " The internal block size of the hash algorithm in bytes.\n" + " digest_size\n" + " The size of the resulting hash in bytes.\n"; #include "hash_SHA2.h" diff --git a/src/SHA512.c b/src/SHA512.c index 4b06b2f..b25747b 100644 --- a/src/SHA512.c +++ b/src/SHA512.c @@ -49,7 +49,13 @@ static char MODULE__doc__[] = "\n" "*SHA* stands for Secure Hash Algorithm.\n" "\n" - ".. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf\n"; + ".. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf\n" + "\n" + ":Variables:\n" + " block_size\n" + " The internal block size of the hash algorithm in bytes.\n" + " digest_size\n" + " The size of the resulting hash in bytes.\n"; #include "hash_SHA2.h" diff --git a/src/block_template.c b/src/block_template.c index d932ce9..436a4cc 100644 --- a/src/block_template.c +++ b/src/block_template.c @@ -715,6 +715,7 @@ _MODULE_NAME (void) { PyObject *m = NULL; PyObject *abiver = NULL; + PyObject *__all__ = NULL; if (PyType_Ready(&ALGtype) < 0) goto errout; @@ -728,6 +729,11 @@ _MODULE_NAME (void) if (m == NULL) goto errout; + /* Add the type object to the module (using the name of the module itself), + * so that its methods docstrings are discoverable by introspection tools. */ + PyObject_SetAttrString(m, _MODULE_STRING, (PyObject *)&ALGtype); + + /* Add some symbolic constants to the module */ PyModule_AddIntConstant(m, "MODE_ECB", MODE_ECB); PyModule_AddIntConstant(m, "MODE_CBC", MODE_CBC); PyModule_AddIntConstant(m, "MODE_CFB", MODE_CFB); @@ -756,6 +762,22 @@ _MODULE_NAME (void) goto errout; } + /* Create __all__ (to help generate documentation) */ + __all__ = PyList_New(10); + if (__all__ == NULL) + goto errout; + PyList_SetItem(__all__, 0, PyString_FromString(_MODULE_STRING)); /* This is the ALGType object */ + PyList_SetItem(__all__, 1, PyString_FromString("new")); + PyList_SetItem(__all__, 2, PyString_FromString("MODE_ECB")); + PyList_SetItem(__all__, 3, PyString_FromString("MODE_CBC")); + PyList_SetItem(__all__, 4, PyString_FromString("MODE_CFB")); + PyList_SetItem(__all__, 5, PyString_FromString("MODE_PGP")); + PyList_SetItem(__all__, 6, PyString_FromString("MODE_OFB")); + PyList_SetItem(__all__, 7, PyString_FromString("MODE_CTR")); + PyList_SetItem(__all__, 8, PyString_FromString("block_size")); + PyList_SetItem(__all__, 9, PyString_FromString("key_size")); + PyObject_SetAttrString(m, "__all__", __all__); + out: /* Final error check */ if (m == NULL && !PyErr_Occurred()) { @@ -765,6 +787,7 @@ out: /* Free local objects here */ Py_CLEAR(abiver); + Py_CLEAR(__all__); /* Return */ #ifdef IS_PY3K diff --git a/src/hash_template.c b/src/hash_template.c index 106e70b..fa5a1b6 100644 --- a/src/hash_template.c +++ b/src/hash_template.c @@ -48,6 +48,9 @@ typedef struct { */ staticforward PyTypeObject ALGtype; +static char ALG__doc__[] = +"Class that implements a " _MODULE_STRING " hash."; + static ALGobject * newALGobject(void) { @@ -72,8 +75,16 @@ ALG_dealloc(PyObject *ptr) /* External methods for a hashing object */ -static char ALG_copy__doc__[] = -"copy(): Return a copy of the hashing object."; +static char ALG_copy__doc__[] = +"copy()\n" +"Return a copy (\"clone\") of the hash object.\n" +"\n" +"The copy will have the same internal state as the original hash\n" +"object.\n" +"This can be used to efficiently compute the digests of strings that\n" +"share a common initial substring.\n" +"\n" +":Return: A hash object of the same type\n"; static PyObject * ALG_copy(ALGobject *self, PyObject *args) @@ -91,8 +102,15 @@ ALG_copy(ALGobject *self, PyObject *args) return((PyObject *)newobj); } -static char ALG_digest__doc__[] = -"digest(): Return the digest value as a string of binary data."; +static char ALG_digest__doc__[] = +"digest()\n" +"Return the **binary** (non-printable) digest of the message that has been hashed so far.\n" +"\n" +"This method does not change the state of the hash object.\n" +"You can continue updating the object after calling this function.\n" +"\n" +":Return: A byte string of `digest_size` bytes. It may contain non-ASCII\n" +"characters, including null bytes.\n"; static PyObject * ALG_digest(ALGobject *self, PyObject *args) @@ -103,8 +121,14 @@ ALG_digest(ALGobject *self, PyObject *args) return (PyObject *)hash_digest(&(self->st)); } -static char ALG_hexdigest__doc__[] = -"hexdigest(): Return the digest value as a string of hexadecimal digits."; +static char ALG_hexdigest__doc__[] = +"hexdigest()\n" +"Return the **printable** digest of the message that has been hashed so far.\n" +"\n" +"This method does not change the state of the hash object.\n" +"\n" +":Return: A string of 2* `digest_size` characters. It contains only\n" +"hexadecimal ASCII digits.\n"; static PyObject * ALG_hexdigest(ALGobject *self, PyObject *args) @@ -143,8 +167,22 @@ ALG_hexdigest(ALGobject *self, PyObject *args) return retval; } -static char ALG_update__doc__[] = -"update(string): Update this hashing object's state with the provided string."; +static char ALG_update__doc__[] = +"update(data)\n" +"Continue hashing of a message by consuming the next chunk of data.\n" +"\n" +"Repeated calls are equivalent to a single call with the concatenation\n" +"of all the arguments. In other words:\n" +"\n" +" >>> m.update(a); m.update(b)\n" +"\n" +"is equivalent to:\n" +"\n" +" >>> m.update(a+b)\n" +"\n" +":Parameters:\n" +" data : byte string\n" +" The next chunk of the message being hashed.\n"; static PyObject * ALG_update(ALGobject *self, PyObject *args) @@ -167,10 +205,16 @@ ALG_update(ALGobject *self, PyObject *args) /** Forward declaration for this module's new() method **/ static char ALG_new__doc__[] = -"new([string]): Return a new " _MODULE_STRING -" hashing object. An optional string " -"argument may be provided; if present, this string will be " -"automatically hashed into the initial state of the object."; +"new(data=None)\n" +"Return a fresh instance of the hash object.\n" +"\n" +":Parameters:\n" +" data : byte string\n" +" The very first chunk of the message to hash.\n" +" It is equivalent to an early call to `" _MODULE_STRING ".update()`.\n" +" Optional.\n" +"\n" +":Return: A `" _MODULE_STRING "` object\n"; static PyObject *ALG_new(PyObject*, PyObject*); @@ -228,7 +272,7 @@ static PyTypeObject ALGtype = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ + ALG__doc__, /*tp_doc*/ 0, /*tp_traverse*/ 0, /*tp_clear*/ 0, /*tp_richcompare*/ @@ -301,6 +345,7 @@ PyMODINIT_FUNC _MODULE_NAME (void) { PyObject *m = NULL; + PyObject *__all__ = NULL; if (PyType_Ready(&ALGtype) < 0) goto errout; @@ -314,10 +359,24 @@ _MODULE_NAME (void) if (m == NULL) goto errout; + /* Add the type object to the module (using the name of the module itself), + * so that its methods docstrings are discoverable by introspection tools. */ + PyObject_SetAttrString(m, _MODULE_STRING, (PyObject *)&ALGtype); + /* Add some symbolic constants to the module */ PyModule_AddIntConstant(m, "digest_size", DIGEST_SIZE); PyModule_AddIntConstant(m, "block_size", BLOCK_SIZE); + /* Create __all__ (to help generate documentation) */ + __all__ = PyList_New(4); + if (__all__ == NULL) + goto errout; + PyList_SetItem(__all__, 0, PyString_FromString(_MODULE_STRING)); /* This is the ALGType object */ + PyList_SetItem(__all__, 1, PyString_FromString("new")); + PyList_SetItem(__all__, 2, PyString_FromString("digest_size")); + PyList_SetItem(__all__, 3, PyString_FromString("block_size")); + PyObject_SetAttrString(m, "__all__", __all__); + out: /* Final error check, then return */ if (m == NULL && !PyErr_Occurred()) { @@ -326,6 +385,7 @@ out: } /* Free local objects here */ + Py_CLEAR(__all__); /* Return */ #ifdef IS_PY3K diff --git a/src/stream_template.c b/src/stream_template.c index 1770a3c..c0aa42c 100644 --- a/src/stream_template.c +++ b/src/stream_template.c @@ -278,6 +278,7 @@ PyMODINIT_FUNC _MODULE_NAME (void) { PyObject *m = NULL; + PyObject *__all__ = NULL; if (PyType_Ready(&ALGtype) < 0) goto errout; @@ -292,9 +293,24 @@ _MODULE_NAME (void) if (m == NULL) goto errout; + /* Add the type object to the module (using the name of the module itself), + * so that its methods docstrings are discoverable by introspection tools. */ + PyObject_SetAttrString(m, _MODULE_STRING, (PyObject *)&ALGtype); + + /* Add some symbolic constants to the module */ PyModule_AddIntConstant(m, "block_size", BLOCK_SIZE); PyModule_AddIntConstant(m, "key_size", KEY_SIZE); + /* Create __all__ (to help generate documentation) */ + __all__ = PyList_New(4); + if (__all__ == NULL) + goto errout; + PyList_SetItem(__all__, 0, PyString_FromString(_MODULE_STRING)); /* This is the ALGType object */ + PyList_SetItem(__all__, 1, PyString_FromString("new")); + PyList_SetItem(__all__, 2, PyString_FromString("block_size")); + PyList_SetItem(__all__, 3, PyString_FromString("key_size")); + PyObject_SetAttrString(m, "__all__", __all__); + out: /* Final error check */ if (m == NULL && !PyErr_Occurred()) { @@ -303,6 +319,7 @@ out: } /* Free local objects here */ + Py_CLEAR(__all__); /* Return */ #ifdef IS_PY3K -- cgit v1.2.1