]> git.cworth.org Git - notmuch/commitdiff
Merge branch 'release'
authorDavid Bremner <david@tethera.net>
Sat, 4 Dec 2021 13:27:30 +0000 (09:27 -0400)
committerDavid Bremner <david@tethera.net>
Sat, 4 Dec 2021 13:27:30 +0000 (09:27 -0400)
12 files changed:
bindings/python-cffi/notmuch2/_build.py
bindings/python-cffi/notmuch2/_database.py
doc/Makefile.local
doc/conf.py
doc/man1/notmuch-config.rst
lib/config.cc
lib/database-private.h
lib/open.cc
test/T055-path-config.sh
test/T391-python-cffi.sh
test/T590-libconfig.sh
test/test-lib.sh

index 24df939e4235ac1c8f9d302fccb6fc79a437b02d..f6184b97be773ff8f885b66dc312c1dfeda889f6 100644 (file)
@@ -103,20 +103,18 @@ ffibuilder.cdef(
     notmuch_status_to_string (notmuch_status_t status);
 
     notmuch_status_t
-    notmuch_database_create_verbose (const char *path,
-                                     notmuch_database_t **database,
-                                     char **error_message);
-    notmuch_status_t
-    notmuch_database_create (const char *path, notmuch_database_t **database);
-    notmuch_status_t
-    notmuch_database_open_verbose (const char *path,
-                                   notmuch_database_mode_t mode,
-                                   notmuch_database_t **database,
-                                   char **error_message);
-    notmuch_status_t
-    notmuch_database_open (const char *path,
-                           notmuch_database_mode_t mode,
-                           notmuch_database_t **database);
+    notmuch_database_create_with_config (const char *database_path,
+                                         const char *config_path,
+                                         const char *profile,
+                                         notmuch_database_t **database,
+                                         char **error_message);
+    notmuch_status_t
+    notmuch_database_open_with_config (const char *database_path,
+                                       notmuch_database_mode_t mode,
+                                       const char *config_path,
+                                       const char *profile,
+                                       notmuch_database_t **database,
+                                       char **error_message);
     notmuch_status_t
     notmuch_database_close (notmuch_database_t *database);
     notmuch_status_t
index 868f4408cb18f2b00196d6314e1d4f3fe34ade5d..14a8f15c6b654e0f02da62fff93959cb906f9546 100644 (file)
@@ -31,6 +31,9 @@ class Mode(enum.Enum):
     READ_ONLY = capi.lib.NOTMUCH_DATABASE_MODE_READ_ONLY
     READ_WRITE = capi.lib.NOTMUCH_DATABASE_MODE_READ_WRITE
 
+class ConfigFile(enum.Enum):
+    EMPTY = b''
+    SEARCH = capi.ffi.NULL
 
 class QuerySortOrder(enum.Enum):
     OLDEST_FIRST = capi.lib.NOTMUCH_SORT_OLDEST_FIRST
@@ -71,6 +74,9 @@ class Database(base.NotmuchObject):
     :cvar EXCLUDE: Which messages to exclude from queries, ``TRUE``,
        ``FLAG``, ``FALSE`` or ``ALL``.  See the query documentation
        for details.
+    :cvar CONFIG: Control loading of config file. Enumeration of
+       ``EMPTY`` (don't load a config file), and ``SEARCH`` (search as
+       in :ref:`config_search`)
     :cvar AddedMessage: A namedtuple ``(msg, dup)`` used by
        :meth:`add` as return value.
     :cvar STR_MODE_MAP: A map mapping strings to :attr:`MODE` items.
@@ -81,9 +87,8 @@ class Database(base.NotmuchObject):
        still open.
 
     :param path: The directory of where the database is stored.  If
-       ``None`` the location will be read from the user's
-       configuration file, respecting the ``NOTMUCH_CONFIG``
-       environment variable if set.
+       ``None`` the location will be searched according to
+       :ref:`database`
     :type path: str, bytes, os.PathLike or pathlib.Path
     :param mode: The mode to open the database in.  One of
        :attr:`MODE.READ_ONLY` OR :attr:`MODE.READ_WRITE`.  For
@@ -91,6 +96,8 @@ class Database(base.NotmuchObject):
        :attr:`MODE.READ_ONLY` and ``rw`` for :attr:`MODE.READ_WRITE`.
     :type mode: :attr:`MODE` or str.
 
+    :param config: Where to load the configuration from, if any.
+    :type config: :attr:`CONFIG.EMPTY`, :attr:`CONFIG.SEARCH`, str, bytes, os.PathLike, pathlib.Path
     :raises KeyError: if an unknown mode string is used.
     :raises OSError: or subclasses if the configuration file can not
        be opened.
@@ -102,6 +109,7 @@ class Database(base.NotmuchObject):
     MODE = Mode
     SORT = QuerySortOrder
     EXCLUDE = QueryExclude
+    CONFIG = ConfigFile
     AddedMessage = collections.namedtuple('AddedMessage', ['msg', 'dup'])
     _db_p = base.MemoryPointer()
     STR_MODE_MAP = {
@@ -109,18 +117,40 @@ class Database(base.NotmuchObject):
         'rw': MODE.READ_WRITE,
     }
 
-    def __init__(self, path=None, mode=MODE.READ_ONLY):
+    @staticmethod
+    def _cfg_path_encode(path):
+        if isinstance(path,ConfigFile):
+            path = path.value
+        elif path is None:
+            path = capi.ffi.NULL
+        elif not hasattr(os, 'PathLike') and isinstance(path, pathlib.Path):
+            path = bytes(path)
+        else:
+            path = os.fsencode(path)
+        return path
+
+    @staticmethod
+    def _db_path_encode(path):
+        if path is None:
+            path = capi.ffi.NULL
+        elif not hasattr(os, 'PathLike') and isinstance(path, pathlib.Path):
+            path = bytes(path)
+        else:
+            path = os.fsencode(path)
+        return path
+
+    def __init__(self, path=None, mode=MODE.READ_ONLY, config=CONFIG.EMPTY):
         if isinstance(mode, str):
             mode = self.STR_MODE_MAP[mode]
         self.mode = mode
-        if path is None:
-            path = self.default_path()
-        if not hasattr(os, 'PathLike') and isinstance(path, pathlib.Path):
-            path = bytes(path)
+
         db_pp = capi.ffi.new('notmuch_database_t **')
         cmsg = capi.ffi.new('char**')
-        ret = capi.lib.notmuch_database_open_verbose(os.fsencode(path),
-                                                     mode.value, db_pp, cmsg)
+        ret = capi.lib.notmuch_database_open_with_config(self._db_path_encode(path),
+                                                         mode.value,
+                                                         self._cfg_path_encode(config),
+                                                         capi.ffi.NULL,
+                                                         db_pp, cmsg)
         if cmsg[0]:
             msg = capi.ffi.string(cmsg[0]).decode(errors='replace')
             capi.lib.free(cmsg[0])
@@ -132,18 +162,20 @@ class Database(base.NotmuchObject):
         self.closed = False
 
     @classmethod
-    def create(cls, path=None):
+    def create(cls, path=None, config=ConfigFile.EMPTY):
         """Create and open database in READ_WRITE mode.
 
         This is creates a new notmuch database and returns an opened
         instance in :attr:`MODE.READ_WRITE` mode.
 
-        :param path: The directory of where the database is stored.  If
-           ``None`` the location will be read from the user's
-           configuration file, respecting the ``NOTMUCH_CONFIG``
-           environment variable if set.
+        :param path: The directory of where the database is stored.
+           If ``None`` the location will be read searched by the
+           notmuch library (see notmuch(3)::notmuch_open_with_config).
         :type path: str, bytes or os.PathLike
 
+        :param config: The pathname of the notmuch configuration file.
+        :type config: :attr:`CONFIG.EMPTY`, :attr:`CONFIG.SEARCH`, str, bytes, os.PathLike, pathlib.Path
+
         :raises OSError: or subclasses if the configuration file can not
            be opened.
         :raises configparser.Error: or subclasses if the configuration
@@ -154,14 +186,13 @@ class Database(base.NotmuchObject):
 
         :returns: The newly created instance.
         """
-        if path is None:
-            path = cls.default_path()
-        if not hasattr(os, 'PathLike') and isinstance(path, pathlib.Path):
-            path = bytes(path)
+
         db_pp = capi.ffi.new('notmuch_database_t **')
         cmsg = capi.ffi.new('char**')
-        ret = capi.lib.notmuch_database_create_verbose(os.fsencode(path),
-                                                       db_pp, cmsg)
+        ret = capi.lib.notmuch_database_create_with_config(cls._db_path_encode(path),
+                                                           cls._cfg_path_encode(config),
+                                                           capi.ffi.NULL,
+                                                           db_pp, cmsg)
         if cmsg[0]:
             msg = capi.ffi.string(cmsg[0]).decode(errors='replace')
             capi.lib.free(cmsg[0])
@@ -176,7 +207,7 @@ class Database(base.NotmuchObject):
         ret = capi.lib.notmuch_database_destroy(db_pp[0])
         if ret != capi.lib.NOTMUCH_STATUS_SUCCESS:
             raise errors.NotmuchError(ret)
-        return cls(path, cls.MODE.READ_WRITE)
+        return cls(path, cls.MODE.READ_WRITE, config=config)
 
     @staticmethod
     def default_path(cfg_path=None):
@@ -187,8 +218,8 @@ class Database(base.NotmuchObject):
 
         :param cfg_path: The pathname of the notmuch configuration file.
            If not specified tries to use the pathname provided in the
-           :env:`NOTMUCH_CONFIG` environment variable and falls back
-           to :file:`~/.notmuch-config.
+           :envvar:`NOTMUCH_CONFIG` environment variable and falls back
+           to :file:`~/.notmuch-config`.
         :type cfg_path: str, bytes, os.PathLike or pathlib.Path.
 
         :returns: The path of the database, which does not necessarily
@@ -198,8 +229,11 @@ class Database(base.NotmuchObject):
            be opened.
         :raises configparser.Error: or subclasses if the configuration
            file can not be parsed.
-        :raises NotmuchError if the config file does not have the
+        :raises NotmuchError: if the config file does not have the
            database.path setting.
+
+        .. deprecated:: 0.35
+           Use the ``config`` parameter to :meth:`__init__` or :meth:`__create__` instead.
         """
         if not cfg_path:
             cfg_path = _config_pathname()
index f476d1da46c990e3b2a6bc45a4cb3e5097b9aa09..730ad4fb5a7b433cc1bd85c1c59a8a4ba44ed32e 100644 (file)
@@ -4,7 +4,7 @@ dir := doc
 
 # You can set these variables from the command line.
 SPHINXOPTS    := -q
-SPHINXBUILD   = sphinx-build
+SPHINXBUILD   = env LD_LIBRARY_PATH=${NOTMUCH_BUILDDIR}/lib sphinx-build
 DOCBUILDDIR      := $(dir)/_build
 
 # Internal variables.
@@ -35,7 +35,7 @@ endif
 
 INFO_INFO_FILES := $(INFO_TEXI_FILES:.texi=.info)
 
-.PHONY: sphinx-html sphinx-texinfo sphinx-info
+.PHONY: sphinx-html sphinx-texinfo sphinx-info doc-prereqs
 
 .PHONY: install-man build-man apidocs install-apidocs
 
@@ -46,15 +46,19 @@ ifeq ($(WITH_EMACS),1)
 $(DOCBUILDDIR)/.roff.stamp $(DOCBUILDDIR)/.html.stamp $(DOCBUILDDIR)/.texi.stamp : docstring.stamp
 endif
 
+ifeq ($(HAVE_PYTHON3_CFFI),1)
+doc-prereqs: python-cffi-bindings
+endif
+
 sphinx-html: $(DOCBUILDDIR)/.html.stamp
 
-$(DOCBUILDDIR)/.html.stamp: $(ALL_RST_FILES)
+$(DOCBUILDDIR)/.html.stamp: $(ALL_RST_FILES) doc-prereqs
        $(SPHINXBUILD) -b html -d $(DOCBUILDDIR)/html_doctrees $(ALLSPHINXOPTS) $(DOCBUILDDIR)/html
        touch $@
 
 sphinx-texinfo: $(DOCBUILDDIR)/.texi.stamp
 
-$(DOCBUILDDIR)/.texi.stamp: $(ALL_RST_FILES)
+$(DOCBUILDDIR)/.texi.stamp: $(ALL_RST_FILES) doc-prereqs
        $(SPHINXBUILD) -b texinfo -d $(DOCBUILDDIR)/texinfo_doctrees $(ALLSPHINXOPTS) $(DOCBUILDDIR)/texinfo
        touch $@
 
index 1fbd102bd30c23029fddf8f9d0c265f00544b584..c7fd8f5acec84807e2738dfae00a0d3c709e8393 100644 (file)
@@ -25,7 +25,7 @@ for pathdir in ['.', '..']:
             version=infile.read().replace('\n','')
 
 # for autodoc
-sys.path.insert(0, os.path.join(location, '..', 'bindings', 'python-cffi', 'notmuch2'))
+sys.path.insert(0, os.path.join(location, '..', 'bindings', 'python-cffi', 'build', 'stage'))
 
 # read generated config
 for pathdir in ['.', '..']:
index 6f12c773aa160d6734e30697eb966965a431c40c..ed188a25c61829dbce315959e664375e8947478b 100644 (file)
@@ -259,6 +259,8 @@ squery.<name>
 FILES
 =====
 
+.. _config_search:
+
 CONFIGURATION
 -------------
 
index 8775b00af8396280792e4af7049973b873f35586..e502858d623db091628e4945d7736c0db2d5b2cd 100644 (file)
@@ -259,7 +259,15 @@ _notmuch_config_load_from_database (notmuch_database_t *notmuch)
 
     for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
        const char *key = notmuch_config_list_key (list);
-       char *normalized_val = _expand_path (list, key, notmuch_config_list_value (list));
+       char *normalized_val = NULL;
+
+       /* If we opened from a given path, do not overwrite it */
+       if (strcmp (key, "database.path") == 0 &&
+           (notmuch->params & NOTMUCH_PARAM_DATABASE) &&
+           notmuch->xapian_db)
+           continue;
+
+       normalized_val = _expand_path (list, key, notmuch_config_list_value (list));
        _notmuch_string_map_append (notmuch->config, key, normalized_val);
        talloc_free (normalized_val);
     }
@@ -432,6 +440,13 @@ _notmuch_config_load_from_file (notmuch_database_t *notmuch,
                status = NOTMUCH_STATUS_FILE_ERROR;
                goto DONE;
            }
+
+           /* If we opened from a given path, do not overwrite it */
+           if (strcmp (absolute_key, "database.path") == 0 &&
+               (notmuch->params & NOTMUCH_PARAM_DATABASE) &&
+               notmuch->xapian_db)
+               continue;
+
            normalized_val = _expand_path (notmuch, absolute_key, val);
            _notmuch_string_map_set (notmuch->config, absolute_key, normalized_val);
            g_free (val);
index 7a0450515f4466cf26d877178412f2628a4c2d14..8133e36415d85a58b381ef999791c2961caa54df 100644 (file)
@@ -190,6 +190,39 @@ operator& (notmuch_field_flag_t a, notmuch_field_flag_t b)
                                    Xapian::QueryParser::FLAG_WILDCARD | \
                                    Xapian::QueryParser::FLAG_PURE_NOT)
 
+/*
+ * Which parameters were explicit when the database was opened */
+typedef enum {
+    NOTMUCH_PARAM_NONE         = 0,
+    NOTMUCH_PARAM_DATABASE     = 1 << 0,
+    NOTMUCH_PARAM_CONFIG       = 1 << 1,
+    NOTMUCH_PARAM_PROFILE      = 1 << 2,
+} notmuch_open_param_t;
+
+/*
+ * define bitwise operators to hide casts */
+
+inline notmuch_open_param_t
+operator| (notmuch_open_param_t a, notmuch_open_param_t b)
+{
+    return static_cast<notmuch_open_param_t>(
+       static_cast<unsigned>(a) | static_cast<unsigned>(b));
+}
+
+inline notmuch_open_param_t&
+operator|= (notmuch_open_param_t &a, notmuch_open_param_t b)
+{
+    a = a | b;
+    return a;
+}
+
+inline notmuch_open_param_t
+operator& (notmuch_open_param_t a, notmuch_open_param_t b)
+{
+    return static_cast<notmuch_open_param_t>(
+       static_cast<unsigned>(a) & static_cast<unsigned>(b));
+}
+
 struct _notmuch_database {
     bool exception_reported;
 
@@ -249,6 +282,9 @@ struct _notmuch_database {
 
     /* Cached and possibly overridden configuration */
     notmuch_string_map_t *config;
+
+    /* Track what parameters were specified when opening */
+    notmuch_open_param_t params;
 };
 
 /* Prior to database version 3, features were implied by the database
index 46a0154534886b77e446604219023e5de5c790d4..c2cb281865e7beccbe9a3046c8f911855820a436 100644 (file)
@@ -246,7 +246,7 @@ _choose_database_path (void *ctx,
 }
 
 static notmuch_database_t *
-_alloc_notmuch ()
+_alloc_notmuch (const char *database_path, const char *config_path, const char *profile)
 {
     notmuch_database_t *notmuch;
 
@@ -262,6 +262,15 @@ _alloc_notmuch ()
     notmuch->transaction_count = 0;
     notmuch->transaction_threshold = 0;
     notmuch->view = 1;
+
+    notmuch->params = NOTMUCH_PARAM_NONE;
+    if (database_path)
+       notmuch->params |= NOTMUCH_PARAM_DATABASE;
+    if (config_path)
+       notmuch->params |= NOTMUCH_PARAM_CONFIG;
+    if (profile)
+       notmuch->params |= NOTMUCH_PARAM_PROFILE;
+
     return notmuch;
 }
 
@@ -509,7 +518,7 @@ notmuch_database_open_with_config (const char *database_path,
 
     _notmuch_init ();
 
-    notmuch = _alloc_notmuch ();
+    notmuch = _alloc_notmuch (database_path, config_path, profile);
     if (! notmuch) {
        status = NOTMUCH_STATUS_OUT_OF_MEMORY;
        goto DONE;
@@ -609,7 +618,7 @@ notmuch_database_create_with_config (const char *database_path,
 
     _notmuch_init ();
 
-    notmuch = _alloc_notmuch ();
+    notmuch = _alloc_notmuch (database_path, config_path, profile);
     if (! notmuch) {
        status = NOTMUCH_STATUS_OUT_OF_MEMORY;
        goto DONE;
@@ -811,7 +820,7 @@ notmuch_database_load_config (const char *database_path,
 
     _notmuch_init ();
 
-    notmuch = _alloc_notmuch ();
+    notmuch = _alloc_notmuch (database_path, config_path, profile);
     if (! notmuch) {
        status = NOTMUCH_STATUS_OUT_OF_MEMORY;
        goto DONE;
index 38f72e5e3bee85cad71ee414518459cd84a5154c..f0ce55dac93a494d51ab3eab9cb1c9bbcdb9c9a7 100755 (executable)
@@ -306,7 +306,23 @@ EOF
           output2=$(notmuch --config='' config get ${key})
           notmuch config set ${key}
           test_expect_equal "${output}+${output2}" "${value}+"
-          ;;
+          ;&
+       split)
+          test_begin_subtest "'to' header does not crash (python-cffi) ($config)"
+          echo 'notmuch@notmuchmail.org' > EXPECTED
+          test_python <<EOF
+from notmuch2 import Database
+db=Database(config=Database.CONFIG.SEARCH)
+m=db.find('20091117232137.GA7669@griffis1.net')
+to=m.header('To')
+print(to)
+EOF
+          test_expect_equal_file EXPECTED OUTPUT
+          ;& # fall through
+   esac
+
+   case $config in
+       split|XDG*)
    esac
    restore_config
    rm -rf home/.local
index d54bad279e12dfb1444ac365c4ac45b84bbc5572..30872af0b9816a4e00da45a5f63b74844bcc84b2 100755 (executable)
@@ -7,8 +7,14 @@ if [ $NOTMUCH_HAVE_PYTHON3_CFFI -eq 0 -o $NOTMUCH_HAVE_PYTHON3_PYTEST -eq 0 ]; t
 fi
 
 
-test_begin_subtest "python cffi tests"
+test_begin_subtest "python cffi tests (NOTMUCH_CONFIG set)"
 pytest_dir=$NOTMUCH_BUILDDIR/bindings/python-cffi/build/stage
 printf "[pytest]\nminversion = 3.0\naddopts = -ra\n" > $pytest_dir/pytest.ini
 test_expect_success "(cd $pytest_dir && ${NOTMUCH_PYTHON} -m pytest --verbose --log-file=$TMP_DIRECTORY/test.output)"
+
+test_begin_subtest "python cffi tests (NOTMUCH_CONFIG unset)"
+pytest_dir=$NOTMUCH_BUILDDIR/bindings/python-cffi/build/stage
+printf "[pytest]\nminversion = 3.0\naddopts = -ra\n" > $pytest_dir/pytest.ini
+unset NOTMUCH_CONFIG
+test_expect_success "(cd $pytest_dir && ${NOTMUCH_PYTHON} -m pytest --verbose --log-file=$TMP_DIRECTORY/test.output)"
 test_done
index 8db51ed043753e8408cdfc519921dc1bc92dccb8..9fa51fc010c4da643194f4079e5015678b6b783c 100755 (executable)
@@ -876,13 +876,13 @@ test_expect_equal_file EXPECTED OUTPUT
 
 test_begin_subtest "open: database set to null on missing config (env)"
 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
-NOTMUCH_CONFIG="/nonexistent"
+export NOTMUCH_CONFIG="/nonexistent"
 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
   notmuch_status_t st = notmuch_database_open_with_config(argv[1],
                                                          NOTMUCH_DATABASE_MODE_READ_ONLY,
                                                          NULL, NULL, &db, NULL);
 EOF
-NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
+export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
 cat <<EOF> EXPECTED
 == stdout ==
 db == NULL: 1
@@ -903,12 +903,12 @@ test_expect_equal_file EXPECTED OUTPUT
 
 test_begin_subtest "create: database set to null on missing config (env)"
 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
-NOTMUCH_CONFIG="/nonexistent"
+export NOTMUCH_CONFIG="/nonexistent"
 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
   notmuch_status_t st = notmuch_database_create_with_config(argv[1],
                                                          NULL, NULL, &db, NULL);
 EOF
-NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
+export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
 cat <<EOF> EXPECTED
 == stdout ==
 db == NULL: 1
@@ -929,11 +929,11 @@ test_expect_equal_file EXPECTED OUTPUT
 
 test_begin_subtest "load_config: database non-null on missing config (env)"
 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
-NOTMUCH_CONFIG="/nonexistent"
+export NOTMUCH_CONFIG="/nonexistent"
 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
   notmuch_status_t st = notmuch_database_load_config(argv[1], NULL, NULL, &db, NULL);
 EOF
-NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
+export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
 cat <<EOF> EXPECTED
 == stdout ==
 db == NULL: 0
@@ -952,4 +952,25 @@ db == NULL: 1
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
+test_begin_subtest "open: database parameter overrides implicit config"
+notmuch config set database.path ${MAIL_DIR}/nonexistent
+cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
+  const char *path = NULL;
+  notmuch_status_t st = notmuch_database_open_with_config(argv[1],
+                                                         NOTMUCH_DATABASE_MODE_READ_ONLY,
+                                                         NULL, NULL, &db, NULL);
+  printf ("status: %d\n", st);
+  path = notmuch_database_get_path (db);
+  printf ("path: %s\n", path ? path : "(null)");
+EOF
+cat <<EOF> EXPECTED
+== stdout ==
+status: 0
+path: MAIL_DIR
+db == NULL: 0
+== stderr ==
+EOF
+notmuch_dir_sanitize < OUTPUT > OUTPUT.clean
+test_expect_equal_file EXPECTED OUTPUT.clean
+
 test_done
index 32f710a58576a52f8ad62ae3429ec4bbe37a0c94..e476a69b2a50f9c06f4b673881ee4024d464e6ab 100644 (file)
@@ -909,7 +909,7 @@ test_done () {
 test_python () {
     # Note: if there is need to print debug information from python program,
     # use stdout = os.fdopen(6, 'w') or stderr = os.fdopen(7, 'w')
-    PYTHONPATH="$NOTMUCH_SRCDIR/bindings/python${PYTHONPATH:+:$PYTHONPATH}" \
+    PYTHONPATH="$NOTMUCH_BUILDDIR/bindings/python-cffi/build/stage:$NOTMUCH_SRCDIR/bindings/python${PYTHONPATH:+:$PYTHONPATH}" \
        $NOTMUCH_PYTHON -B - > OUTPUT
 }