"""
import os
+import codecs
from ctypes import c_char_p, c_void_p, c_uint, c_long, byref, POINTER
from notmuch.globals import (nmlib, STATUS, NotmuchError, NotInitializedError,
NullPointerError, Enum, _str,
:exc:`XapianError` as the underlying database has been
modified. Close and reopen the database to continue working with it.
+ :class:`Database` objects implement the context manager protocol
+ so you can use the :keyword:`with` statement to ensure that the
+ database is properly closed.
+
.. note::
Any function in this class can and will throw an
else:
self.create(path)
+ def __del__(self):
+ self.close()
+
def _assert_db_is_initialized(self):
"""Raises :exc:`NotInitializedError` if self._db is `None`"""
if self._db is None:
raise NotmuchError(message="Could not open the specified database")
self._db = res
+ _close = nmlib.notmuch_database_close
+ _close.argtypes = [NotmuchDatabaseP]
+ _close.restype = None
+
+ def close(self):
+ """Close and free the notmuch database if needed"""
+ if self._db is not None:
+ self._close(self._db)
+ self._db = None
+
+ def __enter__(self):
+ '''
+ Implements the context manager protocol.
+ '''
+ return self
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ '''
+ Implements the context manager protocol.
+ '''
+ self.close()
+
def get_path(self):
"""Returns the file path of an open database"""
self._assert_db_is_initialized()
removed.
"""
self._assert_db_is_initialized()
- return self._remove_message(self._db, filename)
+ return self._remove_message(self._db, _str(filename))
def find_message(self, msgid):
"""Returns a :class:`Message` as identified by its message ID
def __repr__(self):
return "'Notmuch DB " + self.get_path() + "'"
- _close = nmlib.notmuch_database_close
- _close.argtypes = [NotmuchDatabaseP]
- _close.restype = None
-
- def __del__(self):
- """Close and free the notmuch database if needed"""
- if self._db is not None:
- self._close(self._db)
-
def _get_user_default_db(self):
""" Reads a user's notmuch config and returns his db location
Throws a NotmuchError if it cannot find it"""
- from ConfigParser import SafeConfigParser
+ try:
+ # python3.x
+ from configparser import SafeConfigParser
+ except ImportError:
+ # python2.x
+ from ConfigParser import SafeConfigParser
+
config = SafeConfigParser()
conf_f = os.getenv('NOTMUCH_CONFIG',
os.path.expanduser('~/.notmuch-config'))
- config.read(conf_f)
+ config.readfp(codecs.open(conf_f, 'r', 'utf-8'))
if not config.has_option('database', 'path'):
raise NotmuchError(message="No DB path specified"
" and no user default found")
- return config.get('database', 'path').decode('utf-8')
+ return config.get('database', 'path')
@property
def db_p(self):
_move_to_next.argtypes = [NotmuchFilenamesP]
_move_to_next.restype = None
- def next(self):
+ def __next__(self):
if not self._files_p:
raise NotmuchError(STATUS.NOT_INITIALIZED)
self._files_p = None
raise StopIteration
- file = Filenames._get(self._files_p)
+ file_ = Filenames._get(self._files_p)
self._move_to_next(self._files_p)
- return file
+ return file_.decode('utf-8', 'ignore')
+ next = __next__ # python2.x iterator protocol compatibility
def __len__(self):
"""len(:class:`Filenames`) returns the number of contained files