From 06f627df92b644a73c07096bed716d406d4f649d Mon Sep 17 00:00:00 2001 From: Sebastian Spaeth Date: Wed, 17 Mar 2010 11:45:13 +0100 Subject: [PATCH] Improve source documentation --- cnotmuch/database.py | 96 +++++++++++++++++++++++++++++++++---------- docs/source/conf.py | 1 + docs/source/index.rst | 35 +++++++++++++--- 3 files changed, 105 insertions(+), 27 deletions(-) diff --git a/cnotmuch/database.py b/cnotmuch/database.py index b4411ab1..eb54626d 100644 --- a/cnotmuch/database.py +++ b/cnotmuch/database.py @@ -5,16 +5,39 @@ import logging from datetime import date class Database(object): - """ Wrapper around a notmuch_database_t + """Represents a notmuch database (wraps notmuch_database_t) - Do note that as soon as we tear down this object, all derived queries, - threads, and messages will be freed as well. + .. note:: Do note that as soon as we tear down this object, all underlying + derived objects such as queries, threads, messages, tags etc will + be freed by the underlying library as well. Accessing these objects + will lead to segfaults and other unexpected behavior. + + We implement reference counting, so that parent objects can be + automatically freed when they are not needed anymore, for example:: + + db = Database('path',create=True) + msgs = Query(db,'from:myself').search_messages() + + This returns a :class:`Messages` which internally contains + a reference to the parent :class:`Query` object. Otherwise + the Query() would be immediately freed, taking our *msgs* + down with it. + + In this case, the above Query() object will be + automatically freed whenever we delete all derived objects, + ie in our case: `del (msgs)` would also delete the parent + Query (but not the parent Database() as that is still + referenced from the variable *db* in which it is stored. + + Pretty much the same is valid for all other objects in the hierarchy, + such as :class:`Query`, :class:`Messages`, :class:`Message`, + and :class:`Tags`. """ MODE = Enum(['READ_ONLY','READ_WRITE']) """Constants: Mode in which to open the database""" _std_db_path = None - """Class attribute of users default database""" + """Class attribute to cache user's default database""" """notmuch_database_get_path (notmuch_database_t *database)""" _get_path = nmlib.notmuch_database_get_path @@ -36,12 +59,24 @@ class Database(object): _create = nmlib.notmuch_database_create _create.restype = c_void_p - def __init__(self, path=None, create=False, status= MODE_READ_ONLY): - """ Open or create a notmuch database + def __init__(self, path=None, create=False, mode= MODE.READ_ONLY): + """If *path* is *None*, we will try to read a users notmuch + configuration and use his default database. If *create* is `True`, + the database will always be created in + :attr:`MODE.READ_WRITE` mode as creating an empty + database for reading only does not make a great deal of sense. - If path is None, we will try to read a users notmuch configuration and - use his default database. - Throws a NotmuchError in case of failure. + :param path: Directory to open/create the database in (see + above for behavior if `None`) + :type path: `str` or `None` + :param create: False to open an existing, True to create a new + database. + :type create: bool + :param mdoe: Mode to open a database in. Always + :attr:`MODE`.READ_WRITE when creating a new one. + :type mode: :attr:`MODE` + :returns: Nothing + :exception: :exc:`NotmuchError` in case of failure. """ self._db = None if path is None: @@ -54,27 +89,40 @@ class Database(object): if create == False: self.open(path, status) else: - self.create(path, status) + self.create(path) - def create(self, path, status=MODE_READ_ONLY): - """ notmuch_database_create(const char *path) + def create(self, path): + """Creates a new notmuch database - :returns: Raises :exc:`notmuch.NotmuchError` in case - of any failure (after printing an error message on stderr). + This function wraps *notmuch_database_create(...)* and creates + a new notmuch database at *path*. It will always return a database in + :attr:`MODE`.READ_WRITE mode as creating an empty database + for reading only does not make a great deal of sense. + + :param path: A directory in which we should create the database. + :type path: str + :returns: Nothing + :exception: :exc:`NotmuchError` in case of any failure + (after printing an error message on stderr). """ - res = Database._create(path, status) + if self._db is not None: + raise NotmuchError( + message="Cannot create db, this Database() already has an open one.") + + res = Database._create(path, MODE.READ_WRITE) if res is None: raise NotmuchError( message="Could not create the specified database") self._db = res - def open(self, path, status= MODE_READ_ONLY): + def open(self, path, status= MODE.READ_ONLY): """calls notmuch_database_open :returns: Raises :exc:`notmuch.NotmuchError` in case of any failure (after printing an error message on stderr). """ + res = Database._open(path, status) if res is None: @@ -88,11 +136,13 @@ class Database(object): def find_message(self, msgid): """notmuch_database_find_message - :param msgid: The message id - :ptype msgid: string - :returns: Message() or None if no message is found or if an + :param msgid: The message id + :type msgid: string + :returns: :class:`Message` or `None` if no message is found or if an out-of-memory situation occurs. + :exception: :exc:`NotmuchError` with STATUS.NOT_INITIALIZED if + the database was not intitialized. """ if self._db is None: raise NotmuchError(STATUS.NOT_INITIALIZED) @@ -102,9 +152,9 @@ class Database(object): return Message(msg_p, self) def get_all_tags(self): - """Return a Tags() object (list of all tags found in the database) + """Returns :class:`Tags` with a list of all tags found in the database - :returns: Tags() object or raises :exc:`NotmuchError` with + :returns: :class:`Tags` object or raises :exc:`NotmuchError` with STATUS.NULL_POINTER on error """ if self._db is None: @@ -139,7 +189,9 @@ class Database(object): @property def db_p(self): - """Returns a pointer to the current notmuch_database_t or None""" + """Property returning a pointer to the notmuch_database_t or `None`. + + This should normally not be needed by a user.""" return self._db #------------------------------------------------------------------------------ diff --git a/docs/source/conf.py b/docs/source/conf.py index 4d8be533..ee22837f 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -23,6 +23,7 @@ sys.path.append(os.path.abspath('../..')) # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo'] +autoclass_content = "both" # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] diff --git a/docs/source/index.rst b/docs/source/index.rst index e48c345a..06f21422 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -31,13 +31,35 @@ or: :mod:`notmuch` -- The Notmuch interface ============================================= -Document from cnotmuch.globals import nmlib,STATUS,NotmuchError +Document from cnotmuch.globals import nmlib,STATUS :class:`Database` -- The underlying notmuch database ----------------------------------------------------- -.. autoclass:: Database - :members: +.. autoclass:: Database([path=None[, create=False[, mode=MODE.READ_ONLY]]]) + + .. automethod:: create + + .. automethod:: open(path, status=MODE.READ_ONLY) + + .. automethod:: get_path + + .. automethod:: find_message + + .. automethod:: get_all_tags + + + .. attribute:: Database.MODE + + Defines constants that are used as the mode in which to open a database. + + READ_ONLY + Open the database in read-only mode + + READ_WRITE + Open the database in read-write mode + + .. autoattribute:: db_p :class:`Query` -- Represents a notmuch Query ----------------------------------------------- @@ -45,8 +67,6 @@ Document from cnotmuch.globals import nmlib,STATUS,NotmuchError .. autoclass:: Query :members: - .. note:: A Thread is what a call to notmuch.show() will return, containing a bunch of :class:`Message`\ s. - :class:`Messages` -- A bunch of messages ---------------------------------------- @@ -76,6 +96,11 @@ Document from cnotmuch.globals import nmlib,STATUS,NotmuchError This execption inherits directly from :exc:`Exception` and is raised on errors during the notmuch execution. +:class:`STATUS` -- Notmuch operation return status +-------------------------------------------------- +.. autoclass:: STATUS + :members: + Indices and tables ==================