unofficial mirror of notmuch@notmuchmail.org
 help / color / Atom feed
* python-cffi: add missing tagset methods
@ 2020-06-14 18:33 Floris Bruynooghe
  2020-06-14 18:33 ` [PATCH] Add missing set methods to tagsets Floris Bruynooghe
  0 siblings, 1 reply; 3+ messages in thread
From: Floris Bruynooghe @ 2020-06-14 18:33 UTC (permalink / raw)
  To: notmuch

This issue was found by alot's porting efforts.  It seems these
were simply missing.


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH] Add missing set methods to tagsets
  2020-06-14 18:33 python-cffi: add missing tagset methods Floris Bruynooghe
@ 2020-06-14 18:33 ` Floris Bruynooghe
  2020-06-15 15:41   ` David Bremner
  0 siblings, 1 reply; 3+ messages in thread
From: Floris Bruynooghe @ 2020-06-14 18:33 UTC (permalink / raw)
  To: notmuch

Even though we use collections.abc.Set which implements all these
methods under their operator names, the actual named variations of
these methods are shockingly missing.  So let's add them manually.
---
 bindings/python-cffi/notmuch2/_tags.py  | 21 +++++++++
 bindings/python-cffi/tests/test_tags.py | 62 +++++++++++++++++++++++++
 2 files changed, 83 insertions(+)

diff --git a/bindings/python-cffi/notmuch2/_tags.py b/bindings/python-cffi/notmuch2/_tags.py
index 212852a8..3b14c981 100644
--- a/bindings/python-cffi/notmuch2/_tags.py
+++ b/bindings/python-cffi/notmuch2/_tags.py
@@ -110,6 +110,27 @@ class ImmutableTagSet(base.NotmuchObject, collections.abc.Set):
     def __eq__(self, other):
         return tuple(sorted(self.iter())) == tuple(sorted(other.iter()))
 
+    def issubset(self, other):
+        return self <= other
+
+    def issuperset(self, other):
+        return self >= other
+
+    def union(self, other):
+        return self | other
+
+    def intersection(self, other):
+        return self & other
+
+    def difference(self, other):
+        return self - other
+
+    def symmetric_difference(self, other):
+        return self ^ other
+
+    def copy(self):
+        return set(self)
+
     def __hash__(self):
         return hash(tuple(self.iter()))
 
diff --git a/bindings/python-cffi/tests/test_tags.py b/bindings/python-cffi/tests/test_tags.py
index f12fa1e6..faf3947b 100644
--- a/bindings/python-cffi/tests/test_tags.py
+++ b/bindings/python-cffi/tests/test_tags.py
@@ -50,6 +50,22 @@ class TestImmutable:
         assert 'unread' in tagset
         assert 'foo' not in tagset
 
+    def test_isdisjoint(self, tagset):
+        assert tagset.isdisjoint(set(['spam', 'ham']))
+        assert not tagset.isdisjoint(set(['inbox']))
+
+    def test_issubset(self, tagset):
+        assert {'inbox'} <= tagset
+        assert {'inbox'}.issubset(tagset)
+        assert tagset <= {'inbox', 'unread', 'spam'}
+        assert tagset.issubset({'inbox', 'unread', 'spam'})
+
+    def test_issuperset(self, tagset):
+        assert {'inbox', 'unread', 'spam'} >= tagset
+        assert {'inbox', 'unread', 'spam'}.issuperset(tagset)
+        assert tagset >= {'inbox'}
+        assert tagset.issuperset({'inbox'})
+
     def test_iter(self, tagset):
         expected = sorted(['unread', 'inbox'])
         found = []
@@ -78,18 +94,30 @@ class TestImmutable:
         assert isinstance(common, set)
         assert isinstance(common, collections.abc.Set)
         assert common == {'unread'}
+        common = tagset.intersection({'unread'})
+        assert isinstance(common, set)
+        assert isinstance(common, collections.abc.Set)
+        assert common == {'unread'}
 
     def test_or(self, tagset):
         res = tagset | {'foo'}
         assert isinstance(res, set)
         assert isinstance(res, collections.abc.Set)
         assert res == {'unread', 'inbox', 'foo'}
+        res = tagset.union({'foo'})
+        assert isinstance(res, set)
+        assert isinstance(res, collections.abc.Set)
+        assert res == {'unread', 'inbox', 'foo'}
 
     def test_sub(self, tagset):
         res = tagset - {'unread'}
         assert isinstance(res, set)
         assert isinstance(res, collections.abc.Set)
         assert res == {'inbox'}
+        res = tagset.difference({'unread'})
+        assert isinstance(res, set)
+        assert isinstance(res, collections.abc.Set)
+        assert res == {'inbox'}
 
     def test_rsub(self, tagset):
         res = {'foo', 'unread'} - tagset
@@ -102,6 +130,10 @@ class TestImmutable:
         assert isinstance(res, set)
         assert isinstance(res, collections.abc.Set)
         assert res == {'inbox', 'foo'}
+        res = tagset.symmetric_difference({'unread', 'foo'})
+        assert isinstance(res, set)
+        assert isinstance(res, collections.abc.Set)
+        assert res == {'inbox', 'foo'}
 
     def test_rxor(self, tagset):
         res = {'unread', 'foo'} ^ tagset
@@ -109,6 +141,12 @@ class TestImmutable:
         assert isinstance(res, collections.abc.Set)
         assert res == {'inbox', 'foo'}
 
+    def test_copy(self, tagset):
+        res = tagset.copy()
+        assert isinstance(res, set)
+        assert isinstance(res, collections.abc.Set)
+        assert res == {'inbox', 'unread'}
+
 
 class TestMutableTagset:
 
@@ -175,3 +213,27 @@ class TestMutableTagset:
             msg.tags.to_maildir_flags()
             flags = msg.path.name.split(',')[-1]
             assert 'F' not in flags
+
+    def test_isdisjoint(self, tagset):
+        assert tagset.isdisjoint(set(['spam', 'ham']))
+        assert not tagset.isdisjoint(set(['inbox']))
+
+    def test_issubset(self, tagset):
+        assert {'inbox'} <= tagset
+        assert {'inbox'}.issubset(tagset)
+        assert not {'spam'} <= tagset
+        assert not {'spam'}.issubset(tagset)
+        assert tagset <= {'inbox', 'unread', 'spam'}
+        assert tagset.issubset({'inbox', 'unread', 'spam'})
+        assert not {'inbox', 'unread', 'spam'} <= tagset
+        assert not {'inbox', 'unread', 'spam'}.issubset(tagset)
+
+    def test_issuperset(self, tagset):
+        assert {'inbox', 'unread', 'spam'} >= tagset
+        assert {'inbox', 'unread', 'spam'}.issuperset(tagset)
+        assert tagset >= {'inbox'}
+        assert tagset.issuperset({'inbox'})
+
+    def test_union(self, tagset):
+        assert {'spam'}.union(tagset) == {'inbox', 'unread', 'spam'}
+        assert tagset.union({'spam'}) == {'inbox', 'unread', 'spam'}
-- 
2.27.0

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Add missing set methods to tagsets
  2020-06-14 18:33 ` [PATCH] Add missing set methods to tagsets Floris Bruynooghe
@ 2020-06-15 15:41   ` David Bremner
  0 siblings, 0 replies; 3+ messages in thread
From: David Bremner @ 2020-06-15 15:41 UTC (permalink / raw)
  To: Floris Bruynooghe, notmuch

Floris Bruynooghe <flub@devork.be> writes:

> Even though we use collections.abc.Set which implements all these
> methods under their operator names, the actual named variations of
> these methods are shockingly missing.  So let's add them manually.

merged to release and master.

d

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, back to index

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-14 18:33 python-cffi: add missing tagset methods Floris Bruynooghe
2020-06-14 18:33 ` [PATCH] Add missing set methods to tagsets Floris Bruynooghe
2020-06-15 15:41   ` David Bremner

unofficial mirror of notmuch@notmuchmail.org

Archives are clonable:
	git clone --mirror https://yhetil.org/notmuch/0 notmuch/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 notmuch notmuch/ https://yhetil.org/notmuch \
		notmuch@notmuchmail.org
	public-inbox-index notmuch

Example config snippet for mirrors

Newsgroups are available over NNTP:
	nntp://news.yhetil.org/yhetil.mail.notmuch.general
	nntp://news.gmane.io/gmane.mail.notmuch.general


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git