mirror of
https://git.notmuchmail.org/git/notmuch
synced 2024-11-21 18:38:08 +01:00
python: refactor the python bindings
Move the Directory class into its own file, merge the two Filenames classes into one, deprecate Filenames.as_iterator, update the documentation accordingly. Signed-off-by: Justus Winter <4winter@informatik.uni-hamburg.de>
This commit is contained in:
parent
1736488ecf
commit
ba95980cf1
5 changed files with 256 additions and 263 deletions
|
@ -254,26 +254,28 @@ More information on specific topics can be found on the following pages:
|
|||
:class:`Filenames` -- An iterator over filenames
|
||||
------------------------------------------------
|
||||
|
||||
.. autoclass:: notmuch.database.Filenames
|
||||
.. autoclass:: notmuch.Filenames
|
||||
|
||||
.. automethod:: notmuch.database.Filenames.__len__
|
||||
.. automethod:: notmuch.Filenames.__len__
|
||||
|
||||
.. automethod:: notmuch.Filenames.as_generator
|
||||
|
||||
:class:`notmuch.database.Directoy` -- A directory entry in the database
|
||||
------------------------------------------------------------------------
|
||||
|
||||
.. autoclass:: notmuch.database.Directory
|
||||
.. autoclass:: notmuch.Directory
|
||||
|
||||
.. automethod:: notmuch.database.Directory.get_child_files
|
||||
.. automethod:: notmuch.Directory.get_child_files
|
||||
|
||||
.. automethod:: notmuch.database.Directory.get_child_directories
|
||||
.. automethod:: notmuch.Directory.get_child_directories
|
||||
|
||||
.. automethod:: notmuch.database.Directory.get_mtime
|
||||
.. automethod:: notmuch.Directory.get_mtime
|
||||
|
||||
.. automethod:: notmuch.database.Directory.set_mtime
|
||||
.. automethod:: notmuch.Directory.set_mtime
|
||||
|
||||
.. autoattribute:: notmuch.database.Directory.mtime
|
||||
.. autoattribute:: notmuch.Directory.mtime
|
||||
|
||||
.. autoattribute:: notmuch.database.Directory.path
|
||||
.. autoattribute:: notmuch.Directory.path
|
||||
|
||||
|
||||
The `next page <status_and_errors.html>`_ contains information on possible Status and Error values.
|
||||
|
|
|
@ -51,11 +51,14 @@ along with notmuch. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
Copyright 2010-2011 Sebastian Spaeth <Sebastian@SSpaeth.de>
|
||||
"""
|
||||
from notmuch.database import Database, Query
|
||||
from notmuch.message import Messages, Message
|
||||
from notmuch.thread import Threads, Thread
|
||||
from notmuch.tag import Tags
|
||||
from notmuch.globals import (
|
||||
from .database import Database
|
||||
from .directory import Directory
|
||||
from .filename import Filenames
|
||||
from .message import Messages, Message
|
||||
from .query import Query
|
||||
from .tag import Tags
|
||||
from .thread import Threads, Thread
|
||||
from .globals import (
|
||||
nmlib,
|
||||
STATUS,
|
||||
NotmuchError,
|
||||
|
@ -71,6 +74,6 @@ from notmuch.globals import (
|
|||
UnbalancedAtomicError,
|
||||
NotInitializedError,
|
||||
)
|
||||
from notmuch.version import __VERSION__
|
||||
from .version import __VERSION__
|
||||
__LICENSE__ = "GPL v3+"
|
||||
__AUTHOR__ = 'Sebastian Spaeth <Sebastian@SSpaeth.de>'
|
||||
|
|
|
@ -19,7 +19,7 @@ Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'
|
|||
|
||||
import os
|
||||
import codecs
|
||||
from ctypes import c_char_p, c_void_p, c_uint, c_long, byref, POINTER
|
||||
from ctypes import c_char_p, c_void_p, c_uint, byref, POINTER
|
||||
from notmuch.globals import (
|
||||
nmlib,
|
||||
STATUS,
|
||||
|
@ -34,11 +34,11 @@ from notmuch.globals import (
|
|||
NotmuchDirectoryP,
|
||||
NotmuchMessageP,
|
||||
NotmuchTagsP,
|
||||
NotmuchFilenamesP
|
||||
)
|
||||
from notmuch.message import Message
|
||||
from notmuch.tag import Tags
|
||||
from .query import Query
|
||||
from .directory import Directory
|
||||
|
||||
class Database(object):
|
||||
"""The :class:`Database` is the highest-level object that notmuch
|
||||
|
@ -603,238 +603,3 @@ class Database(object):
|
|||
guaranteed to remain stable in future versions).
|
||||
"""
|
||||
return self._db
|
||||
|
||||
|
||||
class Directory(object):
|
||||
"""Represents a directory entry in the notmuch directory
|
||||
|
||||
Modifying attributes of this object will modify the
|
||||
database, not the real directory attributes.
|
||||
|
||||
The Directory object is usually derived from another object
|
||||
e.g. via :meth:`Database.get_directory`, and will automatically be
|
||||
become invalid whenever that parent is deleted. You should
|
||||
therefore initialized this object handing it a reference to the
|
||||
parent, preventing the parent from automatically being garbage
|
||||
collected.
|
||||
"""
|
||||
|
||||
"""notmuch_directory_get_mtime"""
|
||||
_get_mtime = nmlib.notmuch_directory_get_mtime
|
||||
_get_mtime.argtypes = [NotmuchDirectoryP]
|
||||
_get_mtime.restype = c_long
|
||||
|
||||
"""notmuch_directory_set_mtime"""
|
||||
_set_mtime = nmlib.notmuch_directory_set_mtime
|
||||
_set_mtime.argtypes = [NotmuchDirectoryP, c_long]
|
||||
_set_mtime.restype = c_uint
|
||||
|
||||
"""notmuch_directory_get_child_files"""
|
||||
_get_child_files = nmlib.notmuch_directory_get_child_files
|
||||
_get_child_files.argtypes = [NotmuchDirectoryP]
|
||||
_get_child_files.restype = NotmuchFilenamesP
|
||||
|
||||
"""notmuch_directory_get_child_directories"""
|
||||
_get_child_directories = nmlib.notmuch_directory_get_child_directories
|
||||
_get_child_directories.argtypes = [NotmuchDirectoryP]
|
||||
_get_child_directories.restype = NotmuchFilenamesP
|
||||
|
||||
def _assert_dir_is_initialized(self):
|
||||
"""Raises a NotmuchError(:attr:`STATUS`.NOT_INITIALIZED)
|
||||
if dir_p is None"""
|
||||
if not self._dir_p:
|
||||
raise NotInitializedError()
|
||||
|
||||
def __init__(self, path, dir_p, parent):
|
||||
"""
|
||||
:param path: The absolute path of the directory object.
|
||||
:param dir_p: The pointer to an internal notmuch_directory_t object.
|
||||
:param parent: The object this Directory is derived from
|
||||
(usually a :class:`Database`). We do not directly use
|
||||
this, but store a reference to it as long as
|
||||
this Directory object lives. This keeps the
|
||||
parent object alive.
|
||||
"""
|
||||
self._path = path
|
||||
self._dir_p = dir_p
|
||||
self._parent = parent
|
||||
|
||||
def set_mtime(self, mtime):
|
||||
"""Sets the mtime value of this directory in the database
|
||||
|
||||
The intention is for the caller to use the mtime to allow efficient
|
||||
identification of new messages to be added to the database. The
|
||||
recommended usage is as follows:
|
||||
|
||||
* Read the mtime of a directory from the filesystem
|
||||
|
||||
* Call :meth:`Database.add_message` for all mail files in
|
||||
the directory
|
||||
|
||||
* Call notmuch_directory_set_mtime with the mtime read from the
|
||||
filesystem. Then, when wanting to check for updates to the
|
||||
directory in the future, the client can call :meth:`get_mtime`
|
||||
and know that it only needs to add files if the mtime of the
|
||||
directory and files are newer than the stored timestamp.
|
||||
|
||||
.. note::
|
||||
|
||||
:meth:`get_mtime` function does not allow the caller to
|
||||
distinguish a timestamp of 0 from a non-existent timestamp. So
|
||||
don't store a timestamp of 0 unless you are comfortable with
|
||||
that.
|
||||
|
||||
:param mtime: A (time_t) timestamp
|
||||
:raises: :exc:`XapianError` a Xapian exception occurred, mtime
|
||||
not stored
|
||||
:raises: :exc:`ReadOnlyDatabaseError` the database was opened
|
||||
in read-only mode so directory mtime cannot be modified
|
||||
:raises: :exc:`NotInitializedError` the directory object has not
|
||||
been initialized
|
||||
"""
|
||||
self._assert_dir_is_initialized()
|
||||
status = Directory._set_mtime(self._dir_p, mtime)
|
||||
|
||||
if status != STATUS.SUCCESS:
|
||||
raise NotmuchError(status)
|
||||
|
||||
def get_mtime(self):
|
||||
"""Gets the mtime value of this directory in the database
|
||||
|
||||
Retrieves a previously stored mtime for this directory.
|
||||
|
||||
:param mtime: A (time_t) timestamp
|
||||
:raises: :exc:`NotmuchError`:
|
||||
|
||||
:attr:`STATUS`.NOT_INITIALIZED
|
||||
The directory has not been initialized
|
||||
"""
|
||||
self._assert_dir_is_initialized()
|
||||
return Directory._get_mtime(self._dir_p)
|
||||
|
||||
# Make mtime attribute a property of Directory()
|
||||
mtime = property(get_mtime, set_mtime, doc="""Property that allows getting
|
||||
and setting of the Directory *mtime* (read-write)
|
||||
|
||||
See :meth:`get_mtime` and :meth:`set_mtime` for usage and
|
||||
possible exceptions.""")
|
||||
|
||||
def get_child_files(self):
|
||||
"""Gets a Filenames iterator listing all the filenames of
|
||||
messages in the database within the given directory.
|
||||
|
||||
The returned filenames will be the basename-entries only (not
|
||||
complete paths.
|
||||
"""
|
||||
self._assert_dir_is_initialized()
|
||||
files_p = Directory._get_child_files(self._dir_p)
|
||||
return Filenames(files_p, self)
|
||||
|
||||
def get_child_directories(self):
|
||||
"""Gets a :class:`Filenames` iterator listing all the filenames of
|
||||
sub-directories in the database within the given directory
|
||||
|
||||
The returned filenames will be the basename-entries only (not
|
||||
complete paths.
|
||||
"""
|
||||
self._assert_dir_is_initialized()
|
||||
files_p = Directory._get_child_directories(self._dir_p)
|
||||
return Filenames(files_p, self)
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
"""Returns the absolute path of this Directory (read-only)"""
|
||||
return self._path
|
||||
|
||||
def __repr__(self):
|
||||
"""Object representation"""
|
||||
return "<notmuch Directory object '%s'>" % self._path
|
||||
|
||||
_destroy = nmlib.notmuch_directory_destroy
|
||||
_destroy.argtypes = [NotmuchDirectoryP]
|
||||
_destroy.argtypes = None
|
||||
|
||||
def __del__(self):
|
||||
"""Close and free the Directory"""
|
||||
if self._dir_p is not None:
|
||||
self._destroy(self._dir_p)
|
||||
|
||||
|
||||
class Filenames(object):
|
||||
"""An iterator over File- or Directory names stored in the database"""
|
||||
|
||||
#notmuch_filenames_get
|
||||
_get = nmlib.notmuch_filenames_get
|
||||
_get.argtypes = [NotmuchFilenamesP]
|
||||
_get.restype = c_char_p
|
||||
|
||||
def __init__(self, files_p, parent):
|
||||
"""
|
||||
:param files_p: The pointer to an internal notmuch_filenames_t object.
|
||||
:param parent: The object this Directory is derived from
|
||||
(usually a Directory()). We do not directly use
|
||||
this, but store a reference to it as long as
|
||||
this Directory object lives. This keeps the
|
||||
parent object alive.
|
||||
"""
|
||||
self._files_p = files_p
|
||||
self._parent = parent
|
||||
|
||||
def __iter__(self):
|
||||
""" Make Filenames an iterator """
|
||||
return self
|
||||
|
||||
_valid = nmlib.notmuch_filenames_valid
|
||||
_valid.argtypes = [NotmuchFilenamesP]
|
||||
_valid.restype = bool
|
||||
|
||||
_move_to_next = nmlib.notmuch_filenames_move_to_next
|
||||
_move_to_next.argtypes = [NotmuchFilenamesP]
|
||||
_move_to_next.restype = None
|
||||
|
||||
def __next__(self):
|
||||
if not self._files_p:
|
||||
raise NotInitializedError()
|
||||
|
||||
if not self._valid(self._files_p):
|
||||
self._files_p = None
|
||||
raise StopIteration
|
||||
|
||||
file_ = Filenames._get(self._files_p)
|
||||
self._move_to_next(self._files_p)
|
||||
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
|
||||
|
||||
.. note::
|
||||
|
||||
As this iterates over the files, we will not be able to
|
||||
iterate over them again! So this will fail::
|
||||
|
||||
#THIS FAILS
|
||||
files = Database().get_directory('').get_child_files()
|
||||
if len(files) > 0: # this 'exhausts' msgs
|
||||
# next line raises
|
||||
# NotmuchError(:attr:`STATUS`.NOT_INITIALIZED)
|
||||
for file in files: print file
|
||||
"""
|
||||
if not self._files_p:
|
||||
raise NotInitializedError()
|
||||
|
||||
i = 0
|
||||
while self._valid(self._files_p):
|
||||
self._move_to_next(self._files_p)
|
||||
i += 1
|
||||
self._files_p = None
|
||||
return i
|
||||
|
||||
_destroy = nmlib.notmuch_filenames_destroy
|
||||
_destroy.argtypes = [NotmuchFilenamesP]
|
||||
_destroy.restype = None
|
||||
|
||||
def __del__(self):
|
||||
"""Close and free Filenames"""
|
||||
if self._files_p is not None:
|
||||
self._destroy(self._files_p)
|
||||
|
|
183
bindings/python/notmuch/directory.py
Normal file
183
bindings/python/notmuch/directory.py
Normal file
|
@ -0,0 +1,183 @@
|
|||
"""
|
||||
This file is part of notmuch.
|
||||
|
||||
Notmuch is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation, either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
Notmuch is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with notmuch. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'
|
||||
"""
|
||||
|
||||
from ctypes import c_uint, c_long
|
||||
from notmuch.globals import (
|
||||
nmlib,
|
||||
STATUS,
|
||||
NotmuchError,
|
||||
NotInitializedError,
|
||||
NotmuchDirectoryP,
|
||||
NotmuchFilenamesP
|
||||
)
|
||||
from .filename import Filenames
|
||||
|
||||
class Directory(object):
|
||||
"""Represents a directory entry in the notmuch directory
|
||||
|
||||
Modifying attributes of this object will modify the
|
||||
database, not the real directory attributes.
|
||||
|
||||
The Directory object is usually derived from another object
|
||||
e.g. via :meth:`Database.get_directory`, and will automatically be
|
||||
become invalid whenever that parent is deleted. You should
|
||||
therefore initialized this object handing it a reference to the
|
||||
parent, preventing the parent from automatically being garbage
|
||||
collected.
|
||||
"""
|
||||
|
||||
"""notmuch_directory_get_mtime"""
|
||||
_get_mtime = nmlib.notmuch_directory_get_mtime
|
||||
_get_mtime.argtypes = [NotmuchDirectoryP]
|
||||
_get_mtime.restype = c_long
|
||||
|
||||
"""notmuch_directory_set_mtime"""
|
||||
_set_mtime = nmlib.notmuch_directory_set_mtime
|
||||
_set_mtime.argtypes = [NotmuchDirectoryP, c_long]
|
||||
_set_mtime.restype = c_uint
|
||||
|
||||
"""notmuch_directory_get_child_files"""
|
||||
_get_child_files = nmlib.notmuch_directory_get_child_files
|
||||
_get_child_files.argtypes = [NotmuchDirectoryP]
|
||||
_get_child_files.restype = NotmuchFilenamesP
|
||||
|
||||
"""notmuch_directory_get_child_directories"""
|
||||
_get_child_directories = nmlib.notmuch_directory_get_child_directories
|
||||
_get_child_directories.argtypes = [NotmuchDirectoryP]
|
||||
_get_child_directories.restype = NotmuchFilenamesP
|
||||
|
||||
def _assert_dir_is_initialized(self):
|
||||
"""Raises a NotmuchError(:attr:`STATUS`.NOT_INITIALIZED)
|
||||
if dir_p is None"""
|
||||
if not self._dir_p:
|
||||
raise NotInitializedError()
|
||||
|
||||
def __init__(self, path, dir_p, parent):
|
||||
"""
|
||||
:param path: The absolute path of the directory object.
|
||||
:param dir_p: The pointer to an internal notmuch_directory_t object.
|
||||
:param parent: The object this Directory is derived from
|
||||
(usually a :class:`Database`). We do not directly use
|
||||
this, but store a reference to it as long as
|
||||
this Directory object lives. This keeps the
|
||||
parent object alive.
|
||||
"""
|
||||
self._path = path
|
||||
self._dir_p = dir_p
|
||||
self._parent = parent
|
||||
|
||||
def set_mtime(self, mtime):
|
||||
"""Sets the mtime value of this directory in the database
|
||||
|
||||
The intention is for the caller to use the mtime to allow efficient
|
||||
identification of new messages to be added to the database. The
|
||||
recommended usage is as follows:
|
||||
|
||||
* Read the mtime of a directory from the filesystem
|
||||
|
||||
* Call :meth:`Database.add_message` for all mail files in
|
||||
the directory
|
||||
|
||||
* Call notmuch_directory_set_mtime with the mtime read from the
|
||||
filesystem. Then, when wanting to check for updates to the
|
||||
directory in the future, the client can call :meth:`get_mtime`
|
||||
and know that it only needs to add files if the mtime of the
|
||||
directory and files are newer than the stored timestamp.
|
||||
|
||||
.. note::
|
||||
|
||||
:meth:`get_mtime` function does not allow the caller to
|
||||
distinguish a timestamp of 0 from a non-existent timestamp. So
|
||||
don't store a timestamp of 0 unless you are comfortable with
|
||||
that.
|
||||
|
||||
:param mtime: A (time_t) timestamp
|
||||
:raises: :exc:`XapianError` a Xapian exception occurred, mtime
|
||||
not stored
|
||||
:raises: :exc:`ReadOnlyDatabaseError` the database was opened
|
||||
in read-only mode so directory mtime cannot be modified
|
||||
:raises: :exc:`NotInitializedError` the directory object has not
|
||||
been initialized
|
||||
"""
|
||||
self._assert_dir_is_initialized()
|
||||
status = Directory._set_mtime(self._dir_p, mtime)
|
||||
|
||||
if status != STATUS.SUCCESS:
|
||||
raise NotmuchError(status)
|
||||
|
||||
def get_mtime(self):
|
||||
"""Gets the mtime value of this directory in the database
|
||||
|
||||
Retrieves a previously stored mtime for this directory.
|
||||
|
||||
:param mtime: A (time_t) timestamp
|
||||
:raises: :exc:`NotmuchError`:
|
||||
|
||||
:attr:`STATUS`.NOT_INITIALIZED
|
||||
The directory has not been initialized
|
||||
"""
|
||||
self._assert_dir_is_initialized()
|
||||
return Directory._get_mtime(self._dir_p)
|
||||
|
||||
# Make mtime attribute a property of Directory()
|
||||
mtime = property(get_mtime, set_mtime, doc="""Property that allows getting
|
||||
and setting of the Directory *mtime* (read-write)
|
||||
|
||||
See :meth:`get_mtime` and :meth:`set_mtime` for usage and
|
||||
possible exceptions.""")
|
||||
|
||||
def get_child_files(self):
|
||||
"""Gets a Filenames iterator listing all the filenames of
|
||||
messages in the database within the given directory.
|
||||
|
||||
The returned filenames will be the basename-entries only (not
|
||||
complete paths.
|
||||
"""
|
||||
self._assert_dir_is_initialized()
|
||||
files_p = Directory._get_child_files(self._dir_p)
|
||||
return Filenames(files_p, self)
|
||||
|
||||
def get_child_directories(self):
|
||||
"""Gets a :class:`Filenames` iterator listing all the filenames of
|
||||
sub-directories in the database within the given directory
|
||||
|
||||
The returned filenames will be the basename-entries only (not
|
||||
complete paths.
|
||||
"""
|
||||
self._assert_dir_is_initialized()
|
||||
files_p = Directory._get_child_directories(self._dir_p)
|
||||
return Filenames(files_p, self)
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
"""Returns the absolute path of this Directory (read-only)"""
|
||||
return self._path
|
||||
|
||||
def __repr__(self):
|
||||
"""Object representation"""
|
||||
return "<notmuch Directory object '%s'>" % self._path
|
||||
|
||||
_destroy = nmlib.notmuch_directory_destroy
|
||||
_destroy.argtypes = [NotmuchDirectoryP]
|
||||
_destroy.argtypes = None
|
||||
|
||||
def __del__(self):
|
||||
"""Close and free the Directory"""
|
||||
if self._dir_p is not None:
|
||||
self._destroy(self._dir_p)
|
|
@ -78,10 +78,14 @@ class Filenames(Python3StringMixIn):
|
|||
if not files_p:
|
||||
raise NullPointerError()
|
||||
|
||||
self._files = files_p
|
||||
self._files_p = files_p
|
||||
#save reference to parent object so we keep it alive
|
||||
self._parent = parent
|
||||
|
||||
def __iter__(self):
|
||||
""" Make Filenames an iterator """
|
||||
return self
|
||||
|
||||
_valid = nmlib.notmuch_filenames_valid
|
||||
_valid.argtypes = [NotmuchFilenamesP]
|
||||
_valid.restype = bool
|
||||
|
@ -90,19 +94,30 @@ class Filenames(Python3StringMixIn):
|
|||
_move_to_next.argtypes = [NotmuchFilenamesP]
|
||||
_move_to_next.restype = None
|
||||
|
||||
def __next__(self):
|
||||
if not self._files_p:
|
||||
raise NotInitializedError()
|
||||
|
||||
if not self._valid(self._files_p):
|
||||
self._files_p = None
|
||||
raise StopIteration
|
||||
|
||||
file_ = Filenames._get(self._files_p)
|
||||
self._move_to_next(self._files_p)
|
||||
return file_.decode('utf-8', 'ignore')
|
||||
next = __next__ # python2.x iterator protocol compatibility
|
||||
|
||||
def as_generator(self):
|
||||
"""Return generator of Filenames
|
||||
|
||||
This is the main function that will usually be used by the
|
||||
user."""
|
||||
if not self._files:
|
||||
raise NotInitializedError()
|
||||
user.
|
||||
|
||||
while self._valid(self._files):
|
||||
yield Filenames._get(self._files).decode('utf-8', 'ignore')
|
||||
self._move_to_next(self._files)
|
||||
|
||||
self._files = None
|
||||
.. deprecated:: 0.12
|
||||
:class:`Filenames` objects implement the
|
||||
iterator protocol.
|
||||
"""
|
||||
return self
|
||||
|
||||
def __unicode__(self):
|
||||
"""Represent Filenames() as newline-separated list of full paths
|
||||
|
@ -123,5 +138,30 @@ class Filenames(Python3StringMixIn):
|
|||
|
||||
def __del__(self):
|
||||
"""Close and free the notmuch filenames"""
|
||||
if self._files is not None:
|
||||
self._destroy(self._files)
|
||||
if self._files_p is not None:
|
||||
self._destroy(self._files_p)
|
||||
|
||||
def __len__(self):
|
||||
"""len(:class:`Filenames`) returns the number of contained files
|
||||
|
||||
.. note::
|
||||
|
||||
As this iterates over the files, we will not be able to
|
||||
iterate over them again! So this will fail::
|
||||
|
||||
#THIS FAILS
|
||||
files = Database().get_directory('').get_child_files()
|
||||
if len(files) > 0: # this 'exhausts' msgs
|
||||
# next line raises
|
||||
# NotmuchError(:attr:`STATUS`.NOT_INITIALIZED)
|
||||
for file in files: print file
|
||||
"""
|
||||
if not self._files_p:
|
||||
raise NotInitializedError()
|
||||
|
||||
i = 0
|
||||
while self._valid(self._files_p):
|
||||
self._move_to_next(self._files_p)
|
||||
i += 1
|
||||
self._files_p = None
|
||||
return i
|
||||
|
|
Loading…
Reference in a new issue