From 83ee6aaa06f90b14962eb93558e7e8711593b067 Mon Sep 17 00:00:00 2001
From: Iustin Pop <iusty@k1024.org>
Date: Mon, 30 Jun 2008 09:08:45 +0200
Subject: [PATCH] Docstring updates

More epydoc features are now used for prettier output.
---
 epydoc.conf |  27 ++++++++
 setup.py    |  15 ++--
 xattr.c     | 192 +++++++++++++++++++++++++++++++---------------------
 3 files changed, 154 insertions(+), 80 deletions(-)
 create mode 100644 epydoc.conf

diff --git a/epydoc.conf b/epydoc.conf
new file mode 100644
index 0000000..f9c154f
--- /dev/null
+++ b/epydoc.conf
@@ -0,0 +1,27 @@
+[epydoc]
+
+modules: xattr
+
+output: html
+
+target: html/ 
+
+verbosity: 0
+
+debug: 0
+
+simple-term: 1
+
+parse: no
+
+introspect: yes
+
+imports: no
+
+sourcecode: no
+
+name: Filesystem extended attributes for python
+
+url: http://pyxattr.sourceforge.net/
+
+frames: yes
diff --git a/setup.py b/setup.py
index ddb4381..aa4c59d 100755
--- a/setup.py
+++ b/setup.py
@@ -8,15 +8,22 @@ long_desc = """This is a C extension module for Python which
 implements extended attributes manipulation. It is a wrapper on top
 of the attr C library - see attr(5)."""
 version = "0.3.0"
-
+author = "Iustin Pop"
+author_email = "iusty@k1024.org"
+macros = [
+    ("_XATTR_VERSION", '"%s"' % version),
+    ("_XATTR_AUTHOR", '"%s"' % author),
+    ]
 setup(name = "pyxattr",
       version = version,
       description = "Filesystem extended attributes for python",
       long_description = long_desc,
-      author = "Iustin Pop",
-      author_email = "iusty@k1024.org",
+      author = author,
+      author_email = author_email,
       url = "http://pyxattr.sourceforge.net",
       license = "LGPL",
-      ext_modules = [Extension("xattr", ["xattr.c"], libraries=["attr"])],
+      ext_modules = [Extension("xattr", ["xattr.c"],
+                               libraries=["attr"],
+                               define_macros=macros)],
       test_suite = "test/test_xattr",
       )
diff --git a/xattr.c b/xattr.c
index 73f2e55..d932432 100644
--- a/xattr.c
+++ b/xattr.c
@@ -137,7 +137,8 @@ static char __pygetxattr_doc__[] =
     "    the file name given is a symbolic link, makes the\n"
     "    function operate on the symbolic link itself instead\n"
     "    of its target;\n"
-    "@deprecated: this function has been deprecated by the L{get} function\n"
+    "@deprecated: since version 0.4, this function has been deprecated\n"
+    "    by the L{get} function\n"
     ;
 
 static PyObject *
@@ -188,21 +189,22 @@ pygetxattr(PyObject *self, PyObject *args)
 static char __get_doc__[] =
     "Get the value of a given extended attribute.\n"
     "\n"
-    "@param item: the item to query; either a string representing the"
-    " filename, or a file-like object, or a file descriptor\n"
-    "@param name: the attribute whose value to set; usually in form of"
-    " system.posix_acl or user.mime_type\n"
+    "@param item: the item to query; either a string representing the\n"
+    "    filename, or a file-like object, or a file descriptor\n"
+    "@param name: the attribute whose value to set; usually in form of\n"
+    "    system.posix_acl or user.mime_type\n"
     "@type name: string\n"
-    "@param nofollow: if given and True, and the function is passed a"
-    " filename that points to a symlink, the function will act on the symlink"
-    " itself instead of its target\n"
+    "@param nofollow: if given and True, and the function is passed a\n"
+    "    filename that points to a symlink, the function will act on the\n"
+    "    symlink itself instead of its target\n"
     "@type nofollow: boolean\n"
-    "@param namespace: if given, the attribute must not contain the namespace"
-    " itself, but instead the namespace will be taken from this parameter\n"
+    "@param namespace: if given, the attribute must not contain the\n"
+    "    namespace itself, but instead the namespace will be taken from\n"
+    "    this parameter\n"
     "@type namespace: string\n"
     "@return: the value of the extended attribute (can contain NULLs)\n"
     "@rtype: string\n"
-    "@raise EnvironmentError: system errors will raise an exception\n"
+    "@raise EnvironmentError: caused by any system errors\n"
     "@since: 0.4\n"
     ;
 
@@ -266,28 +268,34 @@ static char __get_all_doc__[] =
     "This function performs a bulk-get of all extended attribute names\n"
     "and the corresponding value.\n"
     "Example:\n"
-    "  >>> xattr.get_all('/path/to/file')\n"
-    "  [('user.mime-type', 'plain/text'), ('user.comment', 'test'),"
-    " ('system.posix_acl_access', '\\x02\\x00...')]\n"
-    "  >>> xattr.get_all('/path/to/file', namespace=xattr.NS_USER)\n"
-    "  [('mime-type', 'plain/text'), ('comment', 'test')]\n"
+    "    >>> xattr.get_all('/path/to/file')\n"
+    "    [('user.mime-type', 'plain/text'), ('user.comment', 'test'),\n"
+    "     ('system.posix_acl_access', '\\x02\\x00...')]\n"
+    "    >>> xattr.get_all('/path/to/file', namespace=xattr.NS_USER)\n"
+    "    [('mime-type', 'plain/text'), ('comment', 'test')]\n"
     "\n"
-    "@param item: the item to query; either a string representing the"
-    " filename, or a file-like object, or a file descriptor\n"
-    "@keyword namespace: an optional namespace for filtering the"
-    " attributes; for example, querying all user attributes can be"
-    " accomplished by passing namespace=L{NS_USER}\n"
+    "@param item: the item to query; either a string representing the\n"
+    "    filename, or a file-like object, or a file descriptor\n"
+    "@keyword namespace: an optional namespace for filtering the\n"
+    "    attributes; for example, querying all user attributes can be\n"
+    "    accomplished by passing namespace=L{NS_USER}\n"
     "@type namespace: string\n"
-    "@keyword nofollow: if passed and true, if the target file is a symbolic"
-    " link,"
-    " the attributes for the link itself will be returned, instead of the"
-    " attributes of the target\n"
+    "@keyword nofollow: if passed and true, if the target file is a\n"
+    "    symbolic link, the attributes for the link itself will be\n"
+    "    returned, instead of the attributes of the target\n"
     "@type nofollow: boolean\n"
     "@return: list of tuples (name, value); note that if a namespace\n"
-    "argument was passed, it (and the separator) will be stripped from\n"
-    "the names returned\n"
+    "    argument was passed, it (and the separator) will be stripped from\n"
+    "    the names returned\n"
     "@rtype: list\n"
-    "@raise EnvironmentError: system errors will raise an exception\n"
+    "@raise EnvironmentError: caused by any system errors\n"
+    "@note: Since reading the whole attribute list is not an atomic\n"
+    "    operation, it might be possible that attributes are added\n"
+    "    or removed between the initial query and the actual reading\n"
+    "    of the attributes; the returned list will contain only the\n"
+    "    attributes that were present at the initial listing of the\n"
+    "    attribute names and that were still present when the read\n"
+    "    attempt for the value is made.\n"
     "@since: 0.4\n"
     ;
 
@@ -422,7 +430,8 @@ static char __pysetxattr_doc__[] =
     "    the file name given is a symbolic link, makes the\n"
     "    function operate on the symbolic link itself instead\n"
     "    of its target;\n"
-    "@deprecated: this function has been deprecated by the L{set} function\n"
+    "@deprecated: since version 0.4, this function has been deprecated\n"
+    "    by the L{set} function\n"
     ;
 
 /* Wrapper for setxattr */
@@ -457,30 +466,31 @@ pysetxattr(PyObject *self, PyObject *args)
 static char __set_doc__[] =
     "Set the value of a given extended attribute.\n"
     "\n"
-    "@param item: the item to query; either a string representing the"
-    " filename, or a file-like object, or a file descriptor\n"
-    "@param name: the attribute whose value to set; usually in form of"
-    " system.posix_acl or user.mime_type\n"
+    "@param item: the item to query; either a string representing the\n"
+    "    filename, or a file-like object, or a file descriptor\n"
+    "@param name: the attribute whose value to set; usually in form of\n"
+    "    system.posix_acl or user.mime_type\n"
     "@type name: string\n"
-    "@param value: a string, possibly with embedded NULLs; note that there"
-    " are restrictions regarding the size of the value, for"
-    " example, for ext2/ext3, maximum size is the block size\n"
+    "@param value: a string, possibly with embedded NULLs; note that there\n"
+    "    are restrictions regarding the size of the value, for\n"
+    "    example, for ext2/ext3, maximum size is the block size\n"
     "@type value: string\n"
-    "@param flags: if 0 or ommited the attribute will be"
-    " created or replaced; if L{XATTR_CREATE}, the attribute"
-    " will be created, giving an error if it already exists;"
-    " if L{XATTR_REPLACE}, the attribute will be replaced,"
-    " giving an error if it doesn't exists;\n"
+    "@param flags: if 0 or ommited the attribute will be\n"
+    "    created or replaced; if L{XATTR_CREATE}, the attribute\n"
+    "    will be created, giving an error if it already exists;\n"
+    "    if L{XATTR_REPLACE}, the attribute will be replaced,\n"
+    "    giving an error if it doesn't exists;\n"
     "@type flags: integer\n"
-    "@param nofollow: if given and True, and the function is passed a"
-    " filename that points to a symlink, the function will act on the symlink"
-    " itself instead of its target\n"
+    "@param nofollow: if given and True, and the function is passed a\n"
+    "    filename that points to a symlink, the function will act on the\n"
+    "    symlink itself instead of its target\n"
     "@type nofollow: boolean\n"
-    "@param namespace: if given, the attribute must not contain the namespace"
-    " itself, but instead the namespace will be taken from this parameter\n"
+    "@param namespace: if given, the attribute must not contain the\n"
+    "    namespace itself, but instead the namespace will be taken from\n"
+    "    this parameter\n"
     "@type namespace: string\n"
     "@rtype: None\n"
-    "@raise EnvironmentError: system errors will raise an exception\n"
+    "@raise EnvironmentError: caused by any system errors\n"
     "@since: 0.4\n"
     ;
 
@@ -537,7 +547,8 @@ static char __pyremovexattr_doc__[] =
     "    the file name given is a symbolic link, makes the\n"
     "    function operate on the symbolic link itself instead\n"
     "    of its target;\n"
-    "@deprecated: this function has been deprecated by the L{remove}"
+    "@deprecated: since version 0.4, this function has been deprecated\n"
+    "    by the L{remove}"
     " function\n"
     ;
 
@@ -570,21 +581,22 @@ pyremovexattr(PyObject *self, PyObject *args)
 static char __remove_doc__[] =
     "Remove an attribute from a file\n"
     "\n"
-    "@param item: the item to query; either a string representing the"
-    " filename, or a file-like object, or a file descriptor\n"
-    "@param name: the attribute whose value to set; usually in form of"
-    " system.posix_acl or user.mime_type\n"
+    "@param item: the item to query; either a string representing the\n"
+    "    filename, or a file-like object, or a file descriptor\n"
+    "@param name: the attribute whose value to set; usually in form of\n"
+    "    system.posix_acl or user.mime_type\n"
     "@type name: string\n"
-    "@param nofollow: if given and True, and the function is passed a"
-    " filename that points to a symlink, the function will act on the symlink"
-    " itself instead of its target\n"
+    "@param nofollow: if given and True, and the function is passed a\n"
+    "    filename that points to a symlink, the function will act on the\n"
+    "    symlink itself instead of its target\n"
     "@type nofollow: boolean\n"
-    "@param namespace: if given, the attribute must not contain the namespace"
-    " itself, but instead the namespace will be taken from this parameter\n"
+    "@param namespace: if given, the attribute must not contain the\n"
+    "    namespace itself, but instead the namespace will be taken from\n"
+    "    this parameter\n"
     "@type namespace: string\n"
     "@since: 0.4\n"
     "@rtype: None\n"
-    "@raise EnvironmentError: system errors will raise an exception\n"
+    "@raise EnvironmentError: caused by any system errors\n"
     ;
 
 /* Wrapper for removexattr */
@@ -633,7 +645,8 @@ static char __pylistxattr_doc__[] =
     "    the file name given is a symbolic link, makes the\n"
     "    function operate on the symbolic link itself instead\n"
     "    of its target;\n"
-    "@deprecated: this function has been deprecated by the L{list}"
+    "@deprecated: since version 0.4, this function has been deprecated\n"
+    "    by the L{list}"
     " function\n"
     ;
 
@@ -698,24 +711,26 @@ static char __list_doc__[] =
     "Return the list of attribute names for a file\n"
     "\n"
     "Example:\n"
-    "  >>> xattr.list('/path/to/file')\n"
-    "  ['user.test', 'user.comment', 'system.posix_acl_access']\n"
-    "  >>> xattr.list('/path/to/file', namespace=xattr.NS_USER)\n"
-    "  ['test', 'comment']\n"
+    "    >>> xattr.list('/path/to/file')\n"
+    "    ['user.test', 'user.comment', 'system.posix_acl_access']\n"
+    "    >>> xattr.list('/path/to/file', namespace=xattr.NS_USER)\n"
+    "    ['test', 'comment']\n"
     "\n"
-    "@param item: the item to query; either a string representing the"
-    " filename, or a file-like object, or a file descriptor\n"
-    "@param nofollow: if given and True, and the function is passed a"
-    " filename that points to a symlink, the function will act on the symlink"
-    " itself instead of its target\n"
+    "@param item: the item to query; either a string representing the\n"
+    "    filename, or a file-like object, or a file descriptor\n"
+    "@param nofollow: if given and True, and the function is passed a\n"
+    "    filename that points to a symlink, the function will act on the\n"
+    "    symlink itself instead of its target\n"
     "@type nofollow: boolean\n"
-    "@param namespace: if given, the attribute must not contain the namespace"
-    " itself, but instead the namespace will be taken from this parameter\n"
+    "@param namespace: if given, the attribute must not contain the\n"
+    "    namespace itself, but instead the namespace will be taken from\n"
+    "    this parameter\n"
     "@type namespace: string\n"
     "@return: list of strings; note that if a namespace argument was\n"
-    "passed, it (and the separator) will be stripped from the names returned\n"
+    "    passed, it (and the separator) will be stripped from the names\n"
+    "    returned\n"
     "@rtype: list\n"
-    "@raise EnvironmentError: system errors will raise an exception\n"
+    "@raise EnvironmentError: caused by any system errors\n"
     "@since: 0.4\n"
     ;
 
@@ -806,9 +821,13 @@ static char __xattr_doc__[] = \
     "This module gives access to the extended attributes present\n"
     "in some operating systems/filesystems. You can list attributes,\n"
     "get, set and remove them.\n"
-    "The last and optional parameter for all functions is a boolean \n"
-    "value which enables the 'l-' version of the functions - acting\n"
-    "on symbolic links and not their destination.\n"
+    "\n"
+    "The module exposes two sets of functions:\n"
+    "  - the 'old' L{listxattr}, L{getxattr}, L{setxattr}, L{removexattr}\n"
+    "    functions which are deprecated since version 0.4\n"
+    "  - the new L{list}, L{get}, L{get_all}, L{set}, L{remove} functions\n"
+    "    which expose a namespace-aware API and simplify a bit the calling\n"
+    "    model by using keyword arguments\n"
     "\n"
     "Example: \n\n"
     "  >>> import xattr\n"
@@ -821,7 +840,24 @@ static char __xattr_doc__[] = \
     "  >>> xattr.listxattr(\"file.txt\")\n"
     "  ['user.mime_type', 'user.comment']\n"
     "  >>> xattr.removexattr (\"file.txt\", \"user.comment\")\n"
-    ""
+    "\n"
+    "@note: Most or all errors reported by the system while using the xattr\n"
+    "library will be reported by raising a L{EnvironmentError}; under Linux,\n"
+    "the following C{errno} values are used:\n"
+    "  - C{ENOATTR} and C{ENODATA} mean that the attribute name is invalid\n"
+    "  - C{ENOTSUP} and C{EOPNOTSUPP} mean that the filesystem does not\n"
+    "    support extended attributes, or that the namespace is invalid\n"
+    "  - C{E2BIG} mean that the attribute value is too big\n"
+    "  - C{ERANGE} mean that the attribute name is too big (it might also\n"
+    "    mean an error in the xattr module itself)\n"
+    "  - C{ENOSPC} and C{EDQUOT} are documented as meaning out of disk space\n"
+    "    or out of disk space because of quota limits\n"
+    "\n"
+    "@group Deprecated API: *xattr\n"
+    "@group Namespace constants: NS_*\n"
+    "@group set function flags: XATTR_CREATE, XATTR_REPLACE\n"
+    "@sort: list, get, get_all, set, remove, listxattr, getxattr, setxattr\n"
+    "    removexattr\n"
     ;
 
 void
@@ -829,6 +865,10 @@ initxattr(void)
 {
     PyObject *m = Py_InitModule3("xattr", xattr_methods, __xattr_doc__);
 
+    PyModule_AddStringConstant(m, "__author__", _XATTR_AUTHOR);
+    PyModule_AddStringConstant(m, "__version__", _XATTR_VERSION);
+    PyModule_AddStringConstant(m, "__docformat__", "epytext en");
+
     PyModule_AddIntConstant(m, "XATTR_CREATE", XATTR_CREATE);
     PyModule_AddIntConstant(m, "XATTR_REPLACE", XATTR_REPLACE);
 
-- 
2.39.5