[PATCH] debian: Add packaging for python3-notmuch2
Ship a new debian package for the notmuch2 CFFI-based Python interface to notmuch. Unlike the notmuch python module, the new notmuch2 module is no longer arch-independent, because it builds and ships a shared object in addition to the python code. This patch encourages new downstream development to rely on notmuch2 instead of on notmuch, to get the benefits of the new module. I welcome any suggested improvements to this packaging, but it appears to me to be sufficient to get "import notmuch2" to work and do some basic tests. --- debian/control | 24 +++- debian/rules | 11 ++- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/debian/control b/debian/control index fb2b31c1..a1371fc8 100644 --- a/debian/control +++ b/debian/control @@ -98,6 +98,25 @@ Depends: libnotmuch5 (>= ${source:Version}), ${misc:Depends}, ${python3:Depends}, +Description: Python 3 legacy interface to the notmuch mail search and index library + Notmuch is a system for indexing, searching, reading, and tagging + large collections of email messages in maildir or mh format. It uses + the Xapian library to provide fast, full-text search with a very + convenient search syntax. + . + This package provides a legacy Python 3 interface to the notmuch + functionality, directly interfacing with a shared notmuch library. + . + New projects are encouraged to use python3-notmuch2 instead. + +Package: python3-notmuch2 +Architecture: any +Section: python +Depends: + libnotmuch5 (>= ${source:Version}), + ${misc:Depends}, + ${python3:Depends}, + ${shlibs:Depends}, Description: Python 3 interface to the notmuch mail search and index library Notmuch is a system for indexing, searching, reading, and tagging large collections of email messages in maildir or mh format. It uses @@ -105,7 +124,10 @@ Description: Python 3 interface to the notmuch mail search and index library convenient search syntax. . This package provides a Python 3 interface to the notmuch - functionality, directly interfacing with a shared notmuch library. + functionality using CFFI bindings, which interface with a shared + notmuch library. + . + This is the preferred way to use notmuch via Python. Package: ruby-notmuch Architecture: any diff --git a/debian/rules b/debian/rules index bf9d0bbd..8de49d0f 100755 --- a/debian/rules +++ b/debian/rules @@ -1,7 +1,5 @@ #!/usr/bin/make -f -export PYBUILD_NAME=notmuch - export DEB_BUILD_MAINT_OPTIONS = hardening=+all %: @@ -19,17 +17,20 @@ override_dh_auto_configure: override_dh_auto_build: dh_auto_build -- V=1 - dh_auto_build --buildsystem=pybuild --sourcedirectory bindings/python + PYBUILD_NAME=notmuch dh_auto_build --buildsystem=pybuild --sourcedirectory bindings/python + PYBUILD_NAME=notmuch2 dh_auto_build --buildsystem=pybuild --sourcedirectory bindings/python-cffi $(MAKE) -C contrib/notmuch-mutt override_dh_auto_clean: dh_auto_clean - dh_auto_clean --buildsystem=pybuild --sourcedirectory bindings/python + PYBUILD_NAME=notmuch dh_auto_clean --buildsystem=pybuild --sourcedirectory bindings/python + PYBUILD_NAME=notmuch2 dh_auto_clean --buildsystem=pybuild --sourcedirectory bindings/python-cffi dh_auto_clean --sourcedirectory bindings/ruby $(MAKE) -C contrib/notmuch-mutt clean override_dh_auto_install: dh_auto_install - dh_auto_install --buildsystem=pybuild --sourcedirectory bindings/python + PYBUILD_NAME=notmuch dh_auto_install --buildsystem=pybuild --sourcedirectory bindings/python + PYBUILD_NAME=notmuch2 dh_auto_install --buildsystem=pybuild --sourcedirectory bindings/python-cffi $(MAKE) -C contrib/notmuch-mutt DESTDIR=$(CURDIR)/debian/tmp install dh_auto_install --sourcedirectory bindings/ruby -- 2.24.0 ___ notmuch mailing list notmuch@notmuchmail.org https://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH] python/notmuch2: fix typo for "destroyed"
Daniel Kahn Gillmor writes: > Another fix to the docstrings, this time for the English part of the > docstrings, not the Python class name. No functional changes here. > > Signed-off-by: Daniel Kahn Gillmor pushed, d ___ notmuch mailing list notmuch@notmuchmail.org https://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH] python/notmuch2: fix typo for ObjectDestroyedError
Daniel Kahn Gillmor writes: > There is no functional change here, just a fix to a typo in the > docstrings. > > Signed-off-by: Daniel Kahn Gillmor pushed. d ___ notmuch mailing list notmuch@notmuchmail.org https://notmuchmail.org/mailman/listinfo/notmuch
[PATCH] debian: Override lintian suggestion to move elpa-notmuch to Section: lisp
Signed-off-by: Daniel Kahn Gillmor --- debian/elpa-notmuch.lintian-overrides | 4 1 file changed, 4 insertions(+) create mode 100644 debian/elpa-notmuch.lintian-overrides diff --git a/debian/elpa-notmuch.lintian-overrides b/debian/elpa-notmuch.lintian-overrides new file mode 100644 index ..aa275eda --- /dev/null +++ b/debian/elpa-notmuch.lintian-overrides @@ -0,0 +1,4 @@ +# elpa-notmuch is an elisp plugin for dealing with e-mail. We can +# already tell from the package name that it is an elisp package, so +# it belongs in Section: mail, and lintian is being too strict here. +elpa-notmuch: wrong-section-according-to-package-name elpa-notmuch => lisp -- 2.24.0 ___ notmuch mailing list notmuch@notmuchmail.org https://notmuchmail.org/mailman/listinfo/notmuch
[PATCH] python/notmuch2: fix typo for "destroyed"
Another fix to the docstrings, this time for the English part of the docstrings, not the Python class name. No functional changes here. Signed-off-by: Daniel Kahn Gillmor --- bindings/python-cffi/notmuch2/_database.py | 28 +++--- bindings/python-cffi/notmuch2/_errors.py | 2 +- bindings/python-cffi/notmuch2/_message.py | 24 +-- bindings/python-cffi/notmuch2/_thread.py | 20 4 files changed, 37 insertions(+), 37 deletions(-) diff --git a/bindings/python-cffi/notmuch2/_database.py b/bindings/python-cffi/notmuch2/_database.py index 7ef4fe17..95f59ca0 100644 --- a/bindings/python-cffi/notmuch2/_database.py +++ b/bindings/python-cffi/notmuch2/_database.py @@ -262,7 +262,7 @@ class Database(base.NotmuchObject): This is returned as a :class:`pathlib.Path` instance. -:raises ObjectDestroyedError: if used after destoryed. +:raises ObjectDestroyedError: if used after destroyed. """ try: return self._cache_path @@ -277,7 +277,7 @@ class Database(base.NotmuchObject): This is a positive integer. -:raises ObjectDestroyedError: if used after destoryed. +:raises ObjectDestroyedError: if used after destroyed. """ try: return self._cache_version @@ -296,7 +296,7 @@ class Database(base.NotmuchObject): A read-only database will never be upgradable. -:raises ObjectDestroyedError: if used after destoryed. +:raises ObjectDestroyedError: if used after destroyed. """ ret = capi.lib.notmuch_database_needs_upgrade(self._db_p) return bool(ret) @@ -320,7 +320,7 @@ class Database(base.NotmuchObject): not imply durability, it only ensures the changes are performed atomically. -:raises ObjectDestroyedError: if used after destoryed. +:raises ObjectDestroyedError: if used after destroyed. """ ctx = AtomicContext(self, '_db_p') return ctx @@ -330,7 +330,7 @@ class Database(base.NotmuchObject): Returned as a ``(revision, uuid)`` namedtuple. -:raises ObjectDestroyedError: if used after destoryed. +:raises ObjectDestroyedError: if used after destroyed. """ raw_uuid = capi.ffi.new('char**') rev = capi.lib.notmuch_database_get_revision(self._db_p, raw_uuid) @@ -387,7 +387,7 @@ class Database(base.NotmuchObject): READ_ONLY mode. :raises UpgradeRequiredError: The database must be upgraded first. -:raises ObjectDestroyedError: if used after destoryed. +:raises ObjectDestroyedError: if used after destroyed. """ if not hasattr(os, 'PathLike') and isinstance(filename, pathlib.Path): filename = bytes(filename) @@ -426,7 +426,7 @@ class Database(base.NotmuchObject): READ_ONLY mode. :raises UpgradeRequiredError: The database must be upgraded first. -:raises ObjectDestroyedError: if used after destoryed. +:raises ObjectDestroyedError: if used after destroyed. """ if not hasattr(os, 'PathLike') and isinstance(filename, pathlib.Path): filename = bytes(filename) @@ -458,7 +458,7 @@ class Database(base.NotmuchObject): :raises OutOfMemoryError: When there is no memory to allocate the message instance. :raises XapianError: A Xapian exception ocurred. -:raises ObjectDestroyedError: if used after destoryed. +:raises ObjectDestroyedError: if used after destroyed. """ msg_pp = capi.ffi.new('notmuch_message_t **') ret = capi.lib.notmuch_database_find_message(self._db_p, @@ -489,7 +489,7 @@ class Database(base.NotmuchObject): :raises OutOfMemoryError: When there is no memory to allocate the message instance. :raises XapianError: A Xapian exception ocurred. -:raises ObjectDestroyedError: if used after destoryed. +:raises ObjectDestroyedError: if used after destroyed. """ if not hasattr(os, 'PathLike') and isinstance(filename, pathlib.Path): filename = bytes(filename) @@ -522,7 +522,7 @@ class Database(base.NotmuchObject): :rtype: ImmutableTagSet -:raises ObjectDestroyedError: if used after destoryed. +:raises ObjectDestroyedError: if used after destroyed. """ try: ref = self._cached_tagset @@ -570,7 +570,7 @@ class Database(base.NotmuchObject): :raises OutOfMemoryError: if no memory is available to allocate the query. -:raises ObjectDestroyedError: if used after destoryed. +:raises ObjectDestroyedError: if used after destroyed. """ query = self._create_query(query, omit_excluded=omit_excluded, @@ -587,7 +587,7 @@ class Database(base.NotmuchObject):
[PATCH] python/notmuch2: fix typo for ObjectDestroyedError
There is no functional change here, just a fix to a typo in the docstrings. Signed-off-by: Daniel Kahn Gillmor --- bindings/python-cffi/notmuch2/__init__.py | 2 +- bindings/python-cffi/notmuch2/_database.py | 4 ++-- bindings/python-cffi/notmuch2/_tags.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bindings/python-cffi/notmuch2/__init__.py b/bindings/python-cffi/notmuch2/__init__.py index 4d76ec15..613317e0 100644 --- a/bindings/python-cffi/notmuch2/__init__.py +++ b/bindings/python-cffi/notmuch2/__init__.py @@ -13,7 +13,7 @@ Errors All errors occuring due to errors from the underlying notmuch database are subclasses of the :exc:`NotmuchError`. Due to memory management it is possible to try and use an object after it has been freed. In -this case a :exc:`ObjectDestoryedError` will be raised. +this case a :exc:`ObjectDestroyedError` will be raised. Memory Management = diff --git a/bindings/python-cffi/notmuch2/_database.py b/bindings/python-cffi/notmuch2/_database.py index a1c624a7..7ef4fe17 100644 --- a/bindings/python-cffi/notmuch2/_database.py +++ b/bindings/python-cffi/notmuch2/_database.py @@ -342,7 +342,7 @@ class Database(base.NotmuchObject): def default_indexopts(self): """Returns default index options for the database. -:raises ObjectDestoryedError: if used after destroyed. +:raises ObjectDestroyedError: if used after destroyed. :returns: :class:`IndexOptions`. """ @@ -770,7 +770,7 @@ class IndexOptions(base.NotmuchObject): You can change this policy by assigning a new :class:`DecryptionPolicy` to this property. -:raises ObjectDestoryedError: if used after destroyed. +:raises ObjectDestroyedError: if used after destroyed. :returns: A :class:`DecryptionPolicy` enum instance. """ diff --git a/bindings/python-cffi/notmuch2/_tags.py b/bindings/python-cffi/notmuch2/_tags.py index fe422a79..212852a8 100644 --- a/bindings/python-cffi/notmuch2/_tags.py +++ b/bindings/python-cffi/notmuch2/_tags.py @@ -277,7 +277,7 @@ class TagsIter(base.NotmuchObject, collections.abc.Iterator): :param errors: If using a codec, this is the error handler. See :func:`str.decode` to which this is passed on. -:raises ObjectDestoryedError: if used after destroyed. +:raises ObjectDestroyedError: if used after destroyed. """ _tags_p = base.MemoryPointer() -- 2.24.0 ___ notmuch mailing list notmuch@notmuchmail.org https://notmuchmail.org/mailman/listinfo/notmuch
[PATCH] debian: add Build-Depends-Package for libnotmuch5.symbols
See lintian informational tag symbols-file-missing-build-depends-package-field for hints about this minor metadata update. Signed-off-by: Daniel Kahn Gillmor --- debian/libnotmuch5.symbols | 1 + 1 file changed, 1 insertion(+) diff --git a/debian/libnotmuch5.symbols b/debian/libnotmuch5.symbols index 308567b8..2ae73dad 100644 --- a/debian/libnotmuch5.symbols +++ b/debian/libnotmuch5.symbols @@ -1,4 +1,5 @@ libnotmuch.so.5 libnotmuch5 #MINVER# +* Build-Depends-Package: libnotmuch-dev notmuch_built_with@Base 0.23~rc0 notmuch_config_list_destroy@Base 0.23~rc0 notmuch_config_list_key@Base 0.23~rc0 -- 2.24.0 ___ notmuch mailing list notmuch@notmuchmail.org https://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 1/2] legacy-display: accept text/plain legacy display parts
https://www.ietf.org/id/draft-autocrypt-lamps-protected-headers-02.html Makes it clear that the "Legacy Display" part of an encrypted message with protected headers can (and indeed, should) be of content-type text/plain, though some clients still generate the Legacy Display part as content-type text/rfc822-headers. Notmuch should recognize the part whichever of the two content-types it uses. See also discussion in https://github.com/autocrypt/protected-headers/issues/23 for why the community of implementers is moving in the direction of text/plain. Signed-off-by: Daniel Kahn Gillmor --- util/repair.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/util/repair.c b/util/repair.c index 9fba97b7..4385d16f 100644 --- a/util/repair.c +++ b/util/repair.c @@ -49,8 +49,10 @@ _notmuch_crypto_payload_has_legacy_display (GMimeObject *payload) if (g_mime_multipart_get_count (mpayload) != 2) return false; first = g_mime_multipart_get_part (mpayload, 0); -if (! g_mime_content_type_is_type (g_mime_object_get_content_type (first), - "text", "rfc822-headers")) +if (! (g_mime_content_type_is_type (g_mime_object_get_content_type (first), + "text", "plain") || + g_mime_content_type_is_type (g_mime_object_get_content_type (first), + "text", "rfc822-headers"))) return false; protected_header_parameter = g_mime_object_get_content_type_parameter (first, "protected-headers"); if ((! protected_header_parameter) || strcmp (protected_header_parameter, "v1")) -- 2.24.0 ___ notmuch mailing list notmuch@notmuchmail.org https://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 2/2] legacy-display: drop tests that try to match headers in a Legacy Display part
These tests were an attempt to establish that the content of the "Legacy Display" part is the same as the actual protected headers of the message. But this is more conservative than we need to be. https://www.ietf.org/id/draft-autocrypt-lamps-protected-headers-02.html section 5.3 makes clear that the Legacy Display part is purely decorative, and section 5.2.1 clarifies that the detection can be done purely by MIME structure and Content-Type alone. Furthermore, now that we're accepting text/plain Legacy Display parts, it's not clear the lines in the Legacy Display part should be interpreted as needing an exact string match (e.g. "real" headers are likely to be RFC 2047 encoded, but the text/plain Legacy Display part probably should not be). The concerns that motivated this test in the past were twofold: that we might accidentally hide some information from the reader of the message that they should have available to them, or that we could introduce a covert channel that would be invisible to other clients. I no longer think these are significant concerns: a) There will be no accidental misidentification of a Legacy Display part. The identification of the Legacy Display part is unambiguous due to MIME structure and Content-Type. MIME structure MUST be the first child part of a two-part multipart/mixed Cryptographic Payload. And the protected-headers=v1 content-type parameter must be present on both the cryptographic payload and the legacy display part, so no one would accidentally generate this structure and have it be accidentally matched. b) As for creating a covert channel, many such channels already exist. For example, non-standard e-mail headers, custom MIME types, unusual MIME structures, etc, all make it possible to ship some content in a message that will be visible in some MUAs but not in others. This doesn't make the situation demonstrably worse. Signed-off-by: Daniel Kahn Gillmor --- util/repair.c | 60 ++- 1 file changed, 2 insertions(+), 58 deletions(-) diff --git a/util/repair.c b/util/repair.c index 4385d16f..6c13601d 100644 --- a/util/repair.c +++ b/util/repair.c @@ -27,13 +27,7 @@ _notmuch_crypto_payload_has_legacy_display (GMimeObject *payload) { GMimeMultipart *mpayload; const char *protected_header_parameter; -GMimeTextPart *legacy_display; -char *legacy_display_header_text = NULL; -GMimeStream *stream = NULL; -GMimeParser *parser = NULL; -GMimeObject *legacy_header_object = NULL, *first; -GMimeHeaderList *legacy_display_headers = NULL, *protected_headers = NULL; -bool ret = false; +GMimeObject *first; if (! g_mime_content_type_is_type (g_mime_object_get_content_type (payload), "multipart", "mixed")) @@ -60,57 +54,7 @@ _notmuch_crypto_payload_has_legacy_display (GMimeObject *payload) if (! GMIME_IS_TEXT_PART (first)) return false; -/* ensure that the headers in the first part all match the values - * found in the payload's own protected headers! if they don't, - * we should not treat this as a valid "legacy-display" part. - * - * Crafting a GMimeHeaderList object from the content of the - * text/rfc822-headers part is pretty clumsy; we should probably - * push something into GMime that makes this a one-shot - * operation. */ -if ((protected_headers = g_mime_object_get_header_list (payload), protected_headers) && - (legacy_display = GMIME_TEXT_PART (first), legacy_display) && - (legacy_display_header_text = g_mime_text_part_get_text (legacy_display), legacy_display_header_text) && - (stream = g_mime_stream_mem_new_with_buffer (legacy_display_header_text, strlen (legacy_display_header_text)), stream) && - (g_mime_stream_write (stream, "\r\n\r\n", 4) == 4) && - (g_mime_stream_seek (stream, 0, GMIME_STREAM_SEEK_SET) == 0) && - (parser = g_mime_parser_new_with_stream (stream), parser) && - (legacy_header_object = g_mime_parser_construct_part (parser, NULL), legacy_header_object) && - (legacy_display_headers = g_mime_object_get_header_list (legacy_header_object), legacy_display_headers)) { - /* walk through legacy_display_headers, comparing them against -* their values in the protected_headers: */ - ret = true; - for (int i = 0; i < g_mime_header_list_get_count (legacy_display_headers); i++) { - GMimeHeader *dh = g_mime_header_list_get_header_at (legacy_display_headers, i); - if (dh == NULL) { - ret = false; - goto DONE; - } - GMimeHeader *ph = g_mime_header_list_get_header (protected_headers, g_mime_header_get_name (dh)); - if (ph == NULL) { - ret = false; - goto DONE; - } - const char *dhv = g_mime_header_get_value (dh); -