* [PATCH 1/7] py3k: The execfile built-in has been removed in python 3
2011-12-14 10:58 [python] RFC: supporting python 2 and 3 with one codebase Justus Winter
@ 2011-12-14 10:58 ` Justus Winter
2011-12-14 10:58 ` [PATCH 2/7] py3k: The ConfigParser module has been renamed to configparser Justus Winter
` (5 subsequent siblings)
6 siblings, 0 replies; 17+ messages in thread
From: Justus Winter @ 2011-12-14 10:58 UTC (permalink / raw)
To: notmuch
---
bindings/python/setup.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/bindings/python/setup.py b/bindings/python/setup.py
index 286fd19..2e58dab 100644
--- a/bindings/python/setup.py
+++ b/bindings/python/setup.py
@@ -7,7 +7,7 @@ from distutils.core import setup
# get the notmuch version number without importing the notmuch module
version_file = os.path.join(os.path.dirname(os.path.abspath(__file__)),
'notmuch', 'version.py')
-execfile(version_file)
+exec(compile(open(version_file).read(), version_file, 'exec'))
assert __VERSION__, 'Failed to read the notmuch binding version number'
setup(name='notmuch',
--
1.7.7.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 2/7] py3k: The ConfigParser module has been renamed to configparser
2011-12-14 10:58 [python] RFC: supporting python 2 and 3 with one codebase Justus Winter
2011-12-14 10:58 ` [PATCH 1/7] py3k: The execfile built-in has been removed in python 3 Justus Winter
@ 2011-12-14 10:58 ` Justus Winter
2011-12-14 10:58 ` [PATCH 3/7] py3k: All strings are unicode strings in py3k Justus Winter
` (4 subsequent siblings)
6 siblings, 0 replies; 17+ messages in thread
From: Justus Winter @ 2011-12-14 10:58 UTC (permalink / raw)
To: notmuch
---
bindings/python/notmuch.py | 7 ++++++-
bindings/python/notmuch/database.py | 8 +++++++-
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/bindings/python/notmuch.py b/bindings/python/notmuch.py
index 8d11859..3ff53ec 100755
--- a/bindings/python/notmuch.py
+++ b/bindings/python/notmuch.py
@@ -17,7 +17,12 @@ import stat
import email
from notmuch import Database, Query, NotmuchError, STATUS
-from ConfigParser import SafeConfigParser
+try:
+ # python3.x
+ from configparser import SafeConfigParser
+except ImportError:
+ # python2.x
+ from ConfigParser import SafeConfigParser
from cStringIO import StringIO
PREFIX = re.compile('(\w+):(.*$)')
diff --git a/bindings/python/notmuch/database.py b/bindings/python/notmuch/database.py
index 7923f76..9318368 100644
--- a/bindings/python/notmuch/database.py
+++ b/bindings/python/notmuch/database.py
@@ -543,7 +543,13 @@ class Database(object):
""" 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'))
--
1.7.7.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 3/7] py3k: All strings are unicode strings in py3k
2011-12-14 10:58 [python] RFC: supporting python 2 and 3 with one codebase Justus Winter
2011-12-14 10:58 ` [PATCH 1/7] py3k: The execfile built-in has been removed in python 3 Justus Winter
2011-12-14 10:58 ` [PATCH 2/7] py3k: The ConfigParser module has been renamed to configparser Justus Winter
@ 2011-12-14 10:58 ` Justus Winter
2011-12-14 12:17 ` Tomi Ollila
2011-12-14 10:58 ` [PATCH 4/7] py3k: Rename .next() to __next__(), add python2.x compatibility alias Justus Winter
` (3 subsequent siblings)
6 siblings, 1 reply; 17+ messages in thread
From: Justus Winter @ 2011-12-14 10:58 UTC (permalink / raw)
To: notmuch
---
bindings/python/notmuch/globals.py | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/bindings/python/notmuch/globals.py b/bindings/python/notmuch/globals.py
index 54a49b2..99e6a10 100644
--- a/bindings/python/notmuch/globals.py
+++ b/bindings/python/notmuch/globals.py
@@ -51,7 +51,7 @@ class Status(Enum):
"""Get a (unicode) string representation of a notmuch_status_t value."""
# define strings for custom error messages
if status == STATUS.NOT_INITIALIZED:
- return u"Operation on uninitialized object impossible."
+ return "Operation on uninitialized object impossible."
return unicode(Status._status2str(status))
STATUS = Status(['SUCCESS',
@@ -142,7 +142,7 @@ class NotmuchError(Exception):
elif self.status is not None:
return STATUS.status2str(self.status)
else:
- return u'Unknown error'
+ return 'Unknown error'
# List of Subclassed exceptions that correspond to STATUS values and are
--
1.7.7.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 3/7] py3k: All strings are unicode strings in py3k
2011-12-14 10:58 ` [PATCH 3/7] py3k: All strings are unicode strings in py3k Justus Winter
@ 2011-12-14 12:17 ` Tomi Ollila
2011-12-14 12:52 ` Justus Winter
0 siblings, 1 reply; 17+ messages in thread
From: Tomi Ollila @ 2011-12-14 12:17 UTC (permalink / raw)
To: Justus Winter, notmuch
On Wed, 14 Dec 2011 11:58:21 +0100, Justus Winter <4winter@informatik.uni-hamburg.de> wrote:
> ---
> bindings/python/notmuch/globals.py | 4 ++--
> 1 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/bindings/python/notmuch/globals.py b/bindings/python/notmuch/globals.py
> index 54a49b2..99e6a10 100644
> --- a/bindings/python/notmuch/globals.py
> +++ b/bindings/python/notmuch/globals.py
> @@ -51,7 +51,7 @@ class Status(Enum):
> """Get a (unicode) string representation of a notmuch_status_t value."""
> # define strings for custom error messages
> if status == STATUS.NOT_INITIALIZED:
> - return u"Operation on uninitialized object impossible."
> + return "Operation on uninitialized object impossible."
> return unicode(Status._status2str(status))
>
> STATUS = Status(['SUCCESS',
> @@ -142,7 +142,7 @@ class NotmuchError(Exception):
> elif self.status is not None:
> return STATUS.status2str(self.status)
> else:
> - return u'Unknown error'
> + return 'Unknown error'
Is this u -prefix unnecessary in python 2 too ? Grepping
'u"' and "u'" in **/*.py in puthon bindings source resulted
some more u-prefixed strings in docs/source/conf.py. Should
these be changed in some future patch ?
> # List of Subclassed exceptions that correspond to STATUS values and are
> --
> 1.7.7.3
Tomi
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 3/7] py3k: All strings are unicode strings in py3k
2011-12-14 12:17 ` Tomi Ollila
@ 2011-12-14 12:52 ` Justus Winter
0 siblings, 0 replies; 17+ messages in thread
From: Justus Winter @ 2011-12-14 12:52 UTC (permalink / raw)
To: Tomi Ollila, notmuch
[-- Attachment #1: Type: text/plain, Size: 1803 bytes --]
Hi Tomi :)
Quoting Tomi Ollila (2011-12-14 13:17:41)
>On Wed, 14 Dec 2011 11:58:21 +0100, Justus Winter <4winter@informatik.uni-hamburg.de> wrote:
>> ---
>> bindings/python/notmuch/globals.py | 4 ++--
>> 1 files changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/bindings/python/notmuch/globals.py b/bindings/python/notmuch/globals.py
>> index 54a49b2..99e6a10 100644
>> --- a/bindings/python/notmuch/globals.py
>> +++ b/bindings/python/notmuch/globals.py
>> @@ -51,7 +51,7 @@ class Status(Enum):
>> """Get a (unicode) string representation of a notmuch_status_t value."""
>> # define strings for custom error messages
>> if status == STATUS.NOT_INITIALIZED:
>> - return u"Operation on uninitialized object impossible."
>> + return "Operation on uninitialized object impossible."
>> return unicode(Status._status2str(status))
>>
>> STATUS = Status(['SUCCESS',
>> @@ -142,7 +142,7 @@ class NotmuchError(Exception):
>> elif self.status is not None:
>> return STATUS.status2str(self.status)
>> else:
>> - return u'Unknown error'
>> + return 'Unknown error'
>
>Is this u -prefix unnecessary in python 2 too ? Grepping
>'u"' and "u'" in **/*.py in puthon bindings source resulted
>some more u-prefixed strings in docs/source/conf.py. Should
>these be changed in some future patch ?
Well, since the string literal contains no non-ascii characters it is
perfectly safe to just use a (python2.x) string literal and it will be
automatically coerced to unicode if it is used in a unicode context.
OTOH it is possible to use
from __future__ import unicode_literals
to turn all string literals to unicode literals in python 2.x.
Justus
[-- Attachment #2: .signature --]
[-- Type: application/octet-stream, Size: 17 bytes --]
love u alot @,@
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 4/7] py3k: Rename .next() to __next__(), add python2.x compatibility alias
2011-12-14 10:58 [python] RFC: supporting python 2 and 3 with one codebase Justus Winter
` (2 preceding siblings ...)
2011-12-14 10:58 ` [PATCH 3/7] py3k: All strings are unicode strings in py3k Justus Winter
@ 2011-12-14 10:58 ` Justus Winter
2011-12-14 10:58 ` [PATCH 5/7] py3k: the basestring and unicode types are removed in python 3 Justus Winter
` (2 subsequent siblings)
6 siblings, 0 replies; 17+ messages in thread
From: Justus Winter @ 2011-12-14 10:58 UTC (permalink / raw)
To: notmuch
---
bindings/python/notmuch/database.py | 3 ++-
bindings/python/notmuch/message.py | 3 ++-
bindings/python/notmuch/tag.py | 3 ++-
bindings/python/notmuch/thread.py | 3 ++-
4 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/bindings/python/notmuch/database.py b/bindings/python/notmuch/database.py
index 9318368..3f6e04d 100644
--- a/bindings/python/notmuch/database.py
+++ b/bindings/python/notmuch/database.py
@@ -925,7 +925,7 @@ class Filenames(object):
_move_to_next.argtypes = [NotmuchFilenamesP]
_move_to_next.restype = None
- def next(self):
+ def __next__(self):
if self._files_p is None:
raise NotmuchError(STATUS.NOT_INITIALIZED)
@@ -936,6 +936,7 @@ class Filenames(object):
file = Filenames._get(self._files_p)
self._move_to_next(self._files_p)
return file
+ next = __next__ # python2.x iterator protocol compatibility
def __len__(self):
"""len(:class:`Filenames`) returns the number of contained files
diff --git a/bindings/python/notmuch/message.py b/bindings/python/notmuch/message.py
index ce8e718..bf0c4da 100644
--- a/bindings/python/notmuch/message.py
+++ b/bindings/python/notmuch/message.py
@@ -158,7 +158,7 @@ class Messages(object):
_move_to_next.argtypes = [NotmuchMessagesP]
_move_to_next.restype = None
- def next(self):
+ def __next__(self):
if self._msgs is None:
raise NotmuchError(STATUS.NOT_INITIALIZED)
@@ -169,6 +169,7 @@ class Messages(object):
msg = Message(Messages._get(self._msgs), self)
self._move_to_next(self._msgs)
return msg
+ next = __next__ # python2.x iterator protocol compatibility
def __nonzero__(self):
"""
diff --git a/bindings/python/notmuch/tag.py b/bindings/python/notmuch/tag.py
index 2fb7d32..d42ba77 100644
--- a/bindings/python/notmuch/tag.py
+++ b/bindings/python/notmuch/tag.py
@@ -89,7 +89,7 @@ class Tags(object):
_move_to_next.argtypes = [NotmuchTagsP]
_move_to_next.restype = None
- def next(self):
+ def __next__(self):
if self._tags is None:
raise NotmuchError(STATUS.NOT_INITIALIZED)
if not self._valid(self._tags):
@@ -98,6 +98,7 @@ class Tags(object):
tag = Tags._get(self._tags).decode('UTF-8')
self._move_to_next(self._tags)
return tag
+ next = __next__ # python2.x iterator protocol compatibility
def __nonzero__(self):
"""Implement bool(Tags) check that can be repeatedly used
diff --git a/bindings/python/notmuch/thread.py b/bindings/python/notmuch/thread.py
index 5058846..39285d6 100644
--- a/bindings/python/notmuch/thread.py
+++ b/bindings/python/notmuch/thread.py
@@ -116,7 +116,7 @@ class Threads(object):
_move_to_next.argtypes = [NotmuchThreadsP]
_move_to_next.restype = None
- def next(self):
+ def __next__(self):
if self._threads is None:
raise NotmuchError(STATUS.NOT_INITIALIZED)
@@ -127,6 +127,7 @@ class Threads(object):
thread = Thread(Threads._get(self._threads), self)
self._move_to_next(self._threads)
return thread
+ next = __next__ # python2.x iterator protocol compatibility
def __len__(self):
"""len(:class:`Threads`) returns the number of contained Threads
--
1.7.7.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 5/7] py3k: the basestring and unicode types are removed in python 3
2011-12-14 10:58 [python] RFC: supporting python 2 and 3 with one codebase Justus Winter
` (3 preceding siblings ...)
2011-12-14 10:58 ` [PATCH 4/7] py3k: Rename .next() to __next__(), add python2.x compatibility alias Justus Winter
@ 2011-12-14 10:58 ` Justus Winter
2012-01-02 15:15 ` Sebastian Spaeth
2011-12-14 10:58 ` [PATCH 6/7] py3k: Add and use a mixin class that implements __str__ Justus Winter
2011-12-14 10:58 ` [PATCH 7/7] python: add missing conversions from and to utf-8 Justus Winter
6 siblings, 1 reply; 17+ messages in thread
From: Justus Winter @ 2011-12-14 10:58 UTC (permalink / raw)
To: notmuch
---
bindings/python/notmuch/globals.py | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/bindings/python/notmuch/globals.py b/bindings/python/notmuch/globals.py
index 99e6a10..c52790c 100644
--- a/bindings/python/notmuch/globals.py
+++ b/bindings/python/notmuch/globals.py
@@ -17,6 +17,7 @@ along with notmuch. If not, see <http://www.gnu.org/licenses/>.
Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'
"""
+import sys
from ctypes import CDLL, c_char_p, c_int, Structure, POINTER
#-----------------------------------------------------------------------------
@@ -200,9 +201,9 @@ def _str(value):
C++ code expects strings to be well formatted and
unicode strings to have no null bytes."""
- if not isinstance(value, basestring):
+ if not isinstance(value, basestring if sys.version_info[0] == 2 else str):
raise TypeError("Expected str or unicode, got %s" % str(type(value)))
- if isinstance(value, unicode):
+ if sys.version_info[0] == 3 or isinstance(value, unicode):
return value.encode('UTF-8')
return value
--
1.7.7.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 5/7] py3k: the basestring and unicode types are removed in python 3
2011-12-14 10:58 ` [PATCH 5/7] py3k: the basestring and unicode types are removed in python 3 Justus Winter
@ 2012-01-02 15:15 ` Sebastian Spaeth
2012-01-04 18:07 ` Tomi Ollila
0 siblings, 1 reply; 17+ messages in thread
From: Sebastian Spaeth @ 2012-01-02 15:15 UTC (permalink / raw)
To: Justus Winter, notmuch
[-- Attachment #1: Type: text/plain, Size: 806 bytes --]
Happy new year. Pushed patches 1-4 of this series so far. Looking fine,
but ugh, the below seems like a rather ugly hack in a function that is
probably called quite often.
Isn't there a more pretty variant avoiding these sys.version_info checks
all over the place?
> @@ -200,9 +201,9 @@ def _str(value):
>
> C++ code expects strings to be well formatted and
> unicode strings to have no null bytes."""
> - if not isinstance(value, basestring):
> + if not isinstance(value, basestring if sys.version_info[0] == 2 else str):
> raise TypeError("Expected str or unicode, got %s" % str(type(value)))
> - if isinstance(value, unicode):
> + if sys.version_info[0] == 3 or isinstance(value, unicode):
> return value.encode('UTF-8')
> return value
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 5/7] py3k: the basestring and unicode types are removed in python 3
2012-01-02 15:15 ` Sebastian Spaeth
@ 2012-01-04 18:07 ` Tomi Ollila
2012-01-08 14:04 ` Justus Winter
0 siblings, 1 reply; 17+ messages in thread
From: Tomi Ollila @ 2012-01-04 18:07 UTC (permalink / raw)
To: Sebastian Spaeth, Justus Winter, notmuch
On Mon, 02 Jan 2012 16:15:58 +0100, Sebastian Spaeth <Sebastian@SSpaeth.de> wrote:
> Happy new year. Pushed patches 1-4 of this series so far. Looking fine,
> but ugh, the below seems like a rather ugly hack in a function that is
> probably called quite often.
>
> Isn't there a more pretty variant avoiding these sys.version_info checks
> all over the place?
>
> > @@ -200,9 +201,9 @@ def _str(value):
> >
> > C++ code expects strings to be well formatted and
> > unicode strings to have no null bytes."""
> > - if not isinstance(value, basestring):
> > + if not isinstance(value, basestring if sys.version_info[0] == 2 else str):
> > raise TypeError("Expected str or unicode, got %s" % str(type(value)))
> > - if isinstance(value, unicode):
> > + if sys.version_info[0] == 3 or isinstance(value, unicode):
> > return value.encode('UTF-8')
> > return value
Does the Python3StringMixIn stuff in later patches already handle this
patch -- and making this obsolete ?
Tomi
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 5/7] py3k: the basestring and unicode types are removed in python 3
2012-01-04 18:07 ` Tomi Ollila
@ 2012-01-08 14:04 ` Justus Winter
2012-01-08 14:06 ` [PATCH] " Justus Winter
0 siblings, 1 reply; 17+ messages in thread
From: Justus Winter @ 2012-01-08 14:04 UTC (permalink / raw)
To: Tomi Ollila, Sebastian Spaeth, notmuch
Hi Tomi, Hi Sebastian :)
Quoting Tomi Ollila (2012-01-04 19:07:11)
>On Mon, 02 Jan 2012 16:15:58 +0100, Sebastian Spaeth <Sebastian@SSpaeth.de> wrote:
>> Happy new year. Pushed patches 1-4 of this series so far. Looking fine,
nice, thanks.
>> but ugh, the below seems like a rather ugly hack in a function that is
>> probably called quite often.
>>
>> Isn't there a more pretty variant avoiding these sys.version_info checks
>> all over the place?
Well, I rebased and updated this patch. There are now two different
implementations of _str like there are two Python3StringMixIn
classes. I'll send this patch as reply to this message.
>Does the Python3StringMixIn stuff in later patches already handle this
>patch -- and making this obsolete ?
No, that only handles the __str__ and __unicode__ stuff.
Cheers,
Justus
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH] py3k: the basestring and unicode types are removed in python 3
2012-01-08 14:04 ` Justus Winter
@ 2012-01-08 14:06 ` Justus Winter
0 siblings, 0 replies; 17+ messages in thread
From: Justus Winter @ 2012-01-08 14:06 UTC (permalink / raw)
To: notmuch
---
bindings/python/notmuch/globals.py | 34 ++++++++++++++++++++++------------
1 files changed, 22 insertions(+), 12 deletions(-)
diff --git a/bindings/python/notmuch/globals.py b/bindings/python/notmuch/globals.py
index 32ed9ae..4138460 100644
--- a/bindings/python/notmuch/globals.py
+++ b/bindings/python/notmuch/globals.py
@@ -31,12 +31,34 @@ if sys.version_info[0] == 2:
class Python3StringMixIn(object):
def __str__(self):
return unicode(self).encode('utf-8')
+
+
+ def _str(value):
+ """Ensure a nicely utf-8 encoded string to pass to libnotmuch
+
+ C++ code expects strings to be well formatted and
+ unicode strings to have no null bytes."""
+ if not isinstance(value, basestring):
+ raise TypeError("Expected str or unicode, got %s" % type(value))
+ if isinstance(value, unicode):
+ return value.encode('UTF-8')
+ return value
else:
class Python3StringMixIn(object):
def __str__(self):
return self.__unicode__()
+ def _str(value):
+ """Ensure a nicely utf-8 encoded string to pass to libnotmuch
+
+ C++ code expects strings to be well formatted and
+ unicode strings to have no null bytes."""
+ if not isinstance(value, str):
+ raise TypeError("Expected str, got %s" % type(value))
+ return value.encode('UTF-8')
+
+
class Enum(object):
"""Provides ENUMS as "code=Enum(['a','b','c'])" where code.a=0 etc..."""
def __init__(self, names):
@@ -202,18 +224,6 @@ class NotInitializedError(NotmuchError):
status = STATUS.NOT_INITIALIZED
-def _str(value):
- """Ensure a nicely utf-8 encoded string to pass to libnotmuch
-
- C++ code expects strings to be well formatted and
- unicode strings to have no null bytes."""
- if not isinstance(value, basestring):
- raise TypeError("Expected str or unicode, got %s" % str(type(value)))
- if isinstance(value, unicode):
- return value.encode('UTF-8')
- return value
-
-
class NotmuchDatabaseS(Structure):
pass
NotmuchDatabaseP = POINTER(NotmuchDatabaseS)
--
1.7.7.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 6/7] py3k: Add and use a mixin class that implements __str__
2011-12-14 10:58 [python] RFC: supporting python 2 and 3 with one codebase Justus Winter
` (4 preceding siblings ...)
2011-12-14 10:58 ` [PATCH 5/7] py3k: the basestring and unicode types are removed in python 3 Justus Winter
@ 2011-12-14 10:58 ` Justus Winter
2011-12-14 12:26 ` Tomi Ollila
2011-12-14 10:58 ` [PATCH 7/7] python: add missing conversions from and to utf-8 Justus Winter
6 siblings, 1 reply; 17+ messages in thread
From: Justus Winter @ 2011-12-14 10:58 UTC (permalink / raw)
To: notmuch
---
bindings/python/notmuch/filename.py | 7 ++-----
bindings/python/notmuch/globals.py | 15 +++++++++++----
bindings/python/notmuch/message.py | 8 +++-----
bindings/python/notmuch/tag.py | 7 ++-----
bindings/python/notmuch/thread.py | 6 +++---
5 files changed, 21 insertions(+), 22 deletions(-)
diff --git a/bindings/python/notmuch/filename.py b/bindings/python/notmuch/filename.py
index a7cd7e6..969931a 100644
--- a/bindings/python/notmuch/filename.py
+++ b/bindings/python/notmuch/filename.py
@@ -18,10 +18,10 @@ Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'
"""
from ctypes import c_char_p
from notmuch.globals import (nmlib, STATUS, NotmuchError,
- NotmuchFilenamesP, NotmuchMessageP)
+ NotmuchFilenamesP, NotmuchMessageP, _str, Python3StringMixIn)
-class Filenames(object):
+class Filenames(Python3StringMixIn):
"""Represents a list of filenames as returned by notmuch
This object contains the Filenames iterator. The main function is
@@ -98,9 +98,6 @@ class Filenames(object):
self._files = None
- def __str__(self):
- return unicode(self).encode('utf-8')
-
def __unicode__(self):
"""Represent Filenames() as newline-separated list of full paths
diff --git a/bindings/python/notmuch/globals.py b/bindings/python/notmuch/globals.py
index c52790c..2111b86 100644
--- a/bindings/python/notmuch/globals.py
+++ b/bindings/python/notmuch/globals.py
@@ -28,6 +28,16 @@ except:
raise ImportError("Could not find shared 'notmuch' library.")
+if sys.version_info[0] == 2:
+ class Python3StringMixIn(object):
+ def __str__(self):
+ return unicode(self).encode('utf-8')
+else:
+ class Python3StringMixIn(object):
+ def __str__(self):
+ return self.__unicode__()
+
+
class Enum(object):
"""Provides ENUMS as "code=Enum(['a','b','c'])" where code.a=0 etc..."""
def __init__(self, names):
@@ -90,7 +100,7 @@ argument to receive a human readable string"""
STATUS.__name__ = 'STATUS'
-class NotmuchError(Exception):
+class NotmuchError(Exception, Python3StringMixIn):
"""Is initiated with a (notmuch.STATUS[, message=None]). It will not
return an instance of the class NotmuchError, but a derived instance
of a more specific Error Message, e.g. OutOfMemoryError. Each status
@@ -134,9 +144,6 @@ class NotmuchError(Exception):
self.status = status
self.message = message
- def __str__(self):
- return unicode(self).encode('utf-8')
-
def __unicode__(self):
if self.message is not None:
return self.message
diff --git a/bindings/python/notmuch/message.py b/bindings/python/notmuch/message.py
index bf0c4da..955382d 100644
--- a/bindings/python/notmuch/message.py
+++ b/bindings/python/notmuch/message.py
@@ -21,7 +21,8 @@ Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'
from ctypes import c_char_p, c_long, c_uint, c_int
from datetime import date
-from notmuch.globals import (nmlib, STATUS, NotmuchError, Enum, _str,
+from notmuch.globals import (
+ nmlib, STATUS, NotmuchError, Enum, _str, Python3StringMixIn,
NotmuchTagsP, NotmuchMessagesP, NotmuchMessageP, NotmuchFilenamesP)
from notmuch.tag import Tags
from notmuch.filename import Filenames
@@ -239,7 +240,7 @@ class Messages(object):
sys.stdout.write(set_end)
-class Message(object):
+class Message(Python3StringMixIn):
"""Represents a single Email message
Technically, this wraps the underlying *notmuch_message_t*
@@ -796,9 +797,6 @@ class Message(object):
"""Represent a Message() object by str()"""
return self.__str__()
- def __str__(self):
- return unicode(self).encode('utf-8')
-
def __unicode__(self):
format = "%s (%s) (%s)"
return format % (self.get_header('from'),
diff --git a/bindings/python/notmuch/tag.py b/bindings/python/notmuch/tag.py
index d42ba77..ceb7244 100644
--- a/bindings/python/notmuch/tag.py
+++ b/bindings/python/notmuch/tag.py
@@ -17,10 +17,10 @@ along with notmuch. If not, see <http://www.gnu.org/licenses/>.
Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'
"""
from ctypes import c_char_p
-from notmuch.globals import nmlib, STATUS, NotmuchError, NotmuchTagsP
+from notmuch.globals import nmlib, STATUS, NotmuchError, NotmuchTagsP, _str, Python3StringMixIn
-class Tags(object):
+class Tags(Python3StringMixIn):
"""Represents a list of notmuch tags
This object provides an iterator over a list of notmuch tags (which
@@ -111,9 +111,6 @@ class Tags(object):
left."""
return self._valid(self._tags) > 0
- def __str__(self):
- return unicode(self).encode('utf-8')
-
def __unicode__(self):
"""string representation of :class:`Tags`: a space separated list of tags
diff --git a/bindings/python/notmuch/thread.py b/bindings/python/notmuch/thread.py
index 39285d6..3912957 100644
--- a/bindings/python/notmuch/thread.py
+++ b/bindings/python/notmuch/thread.py
@@ -20,13 +20,13 @@ Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'
from ctypes import c_char_p, c_long, c_int
from notmuch.globals import (nmlib, STATUS,
NotmuchError, NotmuchThreadP, NotmuchThreadsP, NotmuchMessagesP,
- NotmuchTagsP,)
+ NotmuchTagsP, Python3StringMixIn)
from notmuch.message import Messages
from notmuch.tag import Tags
from datetime import date
-class Threads(object):
+class Threads(Python3StringMixIn):
"""Represents a list of notmuch threads
This object provides an iterator over a list of notmuch threads
@@ -393,7 +393,7 @@ class Thread(object):
return Tags(tags_p, self)
def __str__(self):
- return unicode(self).encode('utf-8')
+ return self.__unicode__().encode('utf-8')
def __unicode__(self):
frm = "thread:%s %12s [%d/%d] %s; %s (%s)"
--
1.7.7.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 6/7] py3k: Add and use a mixin class that implements __str__
2011-12-14 10:58 ` [PATCH 6/7] py3k: Add and use a mixin class that implements __str__ Justus Winter
@ 2011-12-14 12:26 ` Tomi Ollila
2011-12-14 12:56 ` Justus Winter
0 siblings, 1 reply; 17+ messages in thread
From: Tomi Ollila @ 2011-12-14 12:26 UTC (permalink / raw)
To: Justus Winter, notmuch
On Wed, 14 Dec 2011 11:58:24 +0100, Justus Winter <4winter@informatik.uni-hamburg.de> wrote:
> ---
[ ... snip ... ]
>
> -class Filenames(object):
> +class Filenames(Python3StringMixIn):
> """Represents a list of filenames as returned by notmuch
>
> This object contains the Filenames iterator. The main function is
> @@ -98,9 +98,6 @@ class Filenames(object):
>
> self._files = None
>
> - def __str__(self):
> - return unicode(self).encode('utf-8')
> -
> def __unicode__(self):
> """Represent Filenames() as newline-separated list of full paths
>
> diff --git a/bindings/python/notmuch/globals.py b/bindings/python/notmuch/globals.py
> index c52790c..2111b86 100644
> --- a/bindings/python/notmuch/globals.py
> +++ b/bindings/python/notmuch/globals.py
> @@ -28,6 +28,16 @@ except:
> raise ImportError("Could not find shared 'notmuch' library.")
>
>
> +if sys.version_info[0] == 2:
> + class Python3StringMixIn(object):
> + def __str__(self):
> + return unicode(self).encode('utf-8')
> +else:
> + class Python3StringMixIn(object):
> + def __str__(self):
> + return self.__unicode__()
> +
> +
[ ... snip ... ]
> -class Threads(object):
> +class Threads(Python3StringMixIn):
> """Represents a list of notmuch threads
>
> This object provides an iterator over a list of notmuch threads
> @@ -393,7 +393,7 @@ class Thread(object):
> return Tags(tags_p, self)
>
> def __str__(self):
> - return unicode(self).encode('utf-8')
> + return self.__unicode__().encode('utf-8')
>
> def __unicode__(self):
> frm = "thread:%s %12s [%d/%d] %s; %s (%s)"
Is this class special case ? in all other classes
the __str__() function has been removed (using inherited
function) ?
> --
> 1.7.7.3
Otherwise LGTM -- pretty simple and effective (all 7 patches).
Tomi
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 6/7] py3k: Add and use a mixin class that implements __str__
2011-12-14 12:26 ` Tomi Ollila
@ 2011-12-14 12:56 ` Justus Winter
2011-12-14 13:04 ` Justus Winter
0 siblings, 1 reply; 17+ messages in thread
From: Justus Winter @ 2011-12-14 12:56 UTC (permalink / raw)
To: Tomi Ollila, notmuch
[-- Attachment #1: Type: text/plain, Size: 2311 bytes --]
Quoting Tomi Ollila (2011-12-14 13:26:38)
>On Wed, 14 Dec 2011 11:58:24 +0100, Justus Winter <4winter@informatik.uni-hamburg.de> wrote:
>> ---
>[ ... snip ... ]
>
>>
>> -class Filenames(object):
>> +class Filenames(Python3StringMixIn):
>> """Represents a list of filenames as returned by notmuch
>>
>> This object contains the Filenames iterator. The main function is
>> @@ -98,9 +98,6 @@ class Filenames(object):
>>
>> self._files = None
>>
>> - def __str__(self):
>> - return unicode(self).encode('utf-8')
>> -
>> def __unicode__(self):
>> """Represent Filenames() as newline-separated list of full paths
>>
>> diff --git a/bindings/python/notmuch/globals.py b/bindings/python/notmuch/globals.py
>> index c52790c..2111b86 100644
>> --- a/bindings/python/notmuch/globals.py
>> +++ b/bindings/python/notmuch/globals.py
>> @@ -28,6 +28,16 @@ except:
>> raise ImportError("Could not find shared 'notmuch' library.")
>>
>>
>> +if sys.version_info[0] == 2:
>> + class Python3StringMixIn(object):
>> + def __str__(self):
>> + return unicode(self).encode('utf-8')
>> +else:
>> + class Python3StringMixIn(object):
>> + def __str__(self):
>> + return self.__unicode__()
>> +
>> +
>
>[ ... snip ... ]
>
>> -class Threads(object):
>> +class Threads(Python3StringMixIn):
>> """Represents a list of notmuch threads
>>
>> This object provides an iterator over a list of notmuch threads
>> @@ -393,7 +393,7 @@ class Thread(object):
>> return Tags(tags_p, self)
>>
>> def __str__(self):
>> - return unicode(self).encode('utf-8')
>> + return self.__unicode__().encode('utf-8')
>>
>> def __unicode__(self):
>> frm = "thread:%s %12s [%d/%d] %s; %s (%s)"
>
>Is this class special case ? in all other classes
>the __str__() function has been removed (using inherited
>function) ?
Damn, I missed that one... that was my first approach but that
obviously didn't worked out... I'll send an updated patch.
>Otherwise LGTM -- pretty simple and effective (all 7 patches).
Thanks :)
Note that I do not know how complete the port is. But the stuff used
by my tagging application (afew) works.
Justus
[-- Attachment #2: .signature --]
[-- Type: application/octet-stream, Size: 17 bytes --]
love u alot @,@
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 6/7] py3k: Add and use a mixin class that implements __str__
2011-12-14 12:56 ` Justus Winter
@ 2011-12-14 13:04 ` Justus Winter
0 siblings, 0 replies; 17+ messages in thread
From: Justus Winter @ 2011-12-14 13:04 UTC (permalink / raw)
To: notmuch
---
bindings/python/notmuch/filename.py | 7 ++-----
bindings/python/notmuch/globals.py | 15 +++++++++++----
bindings/python/notmuch/message.py | 8 +++-----
bindings/python/notmuch/tag.py | 7 ++-----
bindings/python/notmuch/thread.py | 7 ++-----
5 files changed, 20 insertions(+), 24 deletions(-)
diff --git a/bindings/python/notmuch/filename.py b/bindings/python/notmuch/filename.py
index a7cd7e6..969931a 100644
--- a/bindings/python/notmuch/filename.py
+++ b/bindings/python/notmuch/filename.py
@@ -18,10 +18,10 @@ Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'
"""
from ctypes import c_char_p
from notmuch.globals import (nmlib, STATUS, NotmuchError,
- NotmuchFilenamesP, NotmuchMessageP)
+ NotmuchFilenamesP, NotmuchMessageP, _str, Python3StringMixIn)
-class Filenames(object):
+class Filenames(Python3StringMixIn):
"""Represents a list of filenames as returned by notmuch
This object contains the Filenames iterator. The main function is
@@ -98,9 +98,6 @@ class Filenames(object):
self._files = None
- def __str__(self):
- return unicode(self).encode('utf-8')
-
def __unicode__(self):
"""Represent Filenames() as newline-separated list of full paths
diff --git a/bindings/python/notmuch/globals.py b/bindings/python/notmuch/globals.py
index c52790c..2111b86 100644
--- a/bindings/python/notmuch/globals.py
+++ b/bindings/python/notmuch/globals.py
@@ -28,6 +28,16 @@ except:
raise ImportError("Could not find shared 'notmuch' library.")
+if sys.version_info[0] == 2:
+ class Python3StringMixIn(object):
+ def __str__(self):
+ return unicode(self).encode('utf-8')
+else:
+ class Python3StringMixIn(object):
+ def __str__(self):
+ return self.__unicode__()
+
+
class Enum(object):
"""Provides ENUMS as "code=Enum(['a','b','c'])" where code.a=0 etc..."""
def __init__(self, names):
@@ -90,7 +100,7 @@ argument to receive a human readable string"""
STATUS.__name__ = 'STATUS'
-class NotmuchError(Exception):
+class NotmuchError(Exception, Python3StringMixIn):
"""Is initiated with a (notmuch.STATUS[, message=None]). It will not
return an instance of the class NotmuchError, but a derived instance
of a more specific Error Message, e.g. OutOfMemoryError. Each status
@@ -134,9 +144,6 @@ class NotmuchError(Exception):
self.status = status
self.message = message
- def __str__(self):
- return unicode(self).encode('utf-8')
-
def __unicode__(self):
if self.message is not None:
return self.message
diff --git a/bindings/python/notmuch/message.py b/bindings/python/notmuch/message.py
index bf0c4da..955382d 100644
--- a/bindings/python/notmuch/message.py
+++ b/bindings/python/notmuch/message.py
@@ -21,7 +21,8 @@ Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'
from ctypes import c_char_p, c_long, c_uint, c_int
from datetime import date
-from notmuch.globals import (nmlib, STATUS, NotmuchError, Enum, _str,
+from notmuch.globals import (
+ nmlib, STATUS, NotmuchError, Enum, _str, Python3StringMixIn,
NotmuchTagsP, NotmuchMessagesP, NotmuchMessageP, NotmuchFilenamesP)
from notmuch.tag import Tags
from notmuch.filename import Filenames
@@ -239,7 +240,7 @@ class Messages(object):
sys.stdout.write(set_end)
-class Message(object):
+class Message(Python3StringMixIn):
"""Represents a single Email message
Technically, this wraps the underlying *notmuch_message_t*
@@ -796,9 +797,6 @@ class Message(object):
"""Represent a Message() object by str()"""
return self.__str__()
- def __str__(self):
- return unicode(self).encode('utf-8')
-
def __unicode__(self):
format = "%s (%s) (%s)"
return format % (self.get_header('from'),
diff --git a/bindings/python/notmuch/tag.py b/bindings/python/notmuch/tag.py
index d42ba77..ceb7244 100644
--- a/bindings/python/notmuch/tag.py
+++ b/bindings/python/notmuch/tag.py
@@ -17,10 +17,10 @@ along with notmuch. If not, see <http://www.gnu.org/licenses/>.
Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'
"""
from ctypes import c_char_p
-from notmuch.globals import nmlib, STATUS, NotmuchError, NotmuchTagsP
+from notmuch.globals import nmlib, STATUS, NotmuchError, NotmuchTagsP, _str, Python3StringMixIn
-class Tags(object):
+class Tags(Python3StringMixIn):
"""Represents a list of notmuch tags
This object provides an iterator over a list of notmuch tags (which
@@ -111,9 +111,6 @@ class Tags(object):
left."""
return self._valid(self._tags) > 0
- def __str__(self):
- return unicode(self).encode('utf-8')
-
def __unicode__(self):
"""string representation of :class:`Tags`: a space separated list of tags
diff --git a/bindings/python/notmuch/thread.py b/bindings/python/notmuch/thread.py
index 39285d6..7393097 100644
--- a/bindings/python/notmuch/thread.py
+++ b/bindings/python/notmuch/thread.py
@@ -20,13 +20,13 @@ Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'
from ctypes import c_char_p, c_long, c_int
from notmuch.globals import (nmlib, STATUS,
NotmuchError, NotmuchThreadP, NotmuchThreadsP, NotmuchMessagesP,
- NotmuchTagsP,)
+ NotmuchTagsP, Python3StringMixIn)
from notmuch.message import Messages
from notmuch.tag import Tags
from datetime import date
-class Threads(object):
+class Threads(Python3StringMixIn):
"""Represents a list of notmuch threads
This object provides an iterator over a list of notmuch threads
@@ -392,9 +392,6 @@ class Thread(object):
raise NotmuchError(STATUS.NULL_POINTER)
return Tags(tags_p, self)
- def __str__(self):
- return unicode(self).encode('utf-8')
-
def __unicode__(self):
frm = "thread:%s %12s [%d/%d] %s; %s (%s)"
--
1.7.7.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 7/7] python: add missing conversions from and to utf-8
2011-12-14 10:58 [python] RFC: supporting python 2 and 3 with one codebase Justus Winter
` (5 preceding siblings ...)
2011-12-14 10:58 ` [PATCH 6/7] py3k: Add and use a mixin class that implements __str__ Justus Winter
@ 2011-12-14 10:58 ` Justus Winter
6 siblings, 0 replies; 17+ messages in thread
From: Justus Winter @ 2011-12-14 10:58 UTC (permalink / raw)
To: notmuch
---
bindings/python/notmuch/database.py | 6 +++---
bindings/python/notmuch/filename.py | 2 +-
bindings/python/notmuch/message.py | 8 ++++----
bindings/python/notmuch/thread.py | 2 +-
4 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/bindings/python/notmuch/database.py b/bindings/python/notmuch/database.py
index 3f6e04d..2eae69e 100644
--- a/bindings/python/notmuch/database.py
+++ b/bindings/python/notmuch/database.py
@@ -430,7 +430,7 @@ class Database(object):
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
@@ -933,9 +933,9 @@ class Filenames(object):
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', errors='ignore')
next = __next__ # python2.x iterator protocol compatibility
def __len__(self):
diff --git a/bindings/python/notmuch/filename.py b/bindings/python/notmuch/filename.py
index 969931a..0c2e0d5 100644
--- a/bindings/python/notmuch/filename.py
+++ b/bindings/python/notmuch/filename.py
@@ -93,7 +93,7 @@ class Filenames(Python3StringMixIn):
raise NotmuchError(STATUS.NOT_INITIALIZED)
while self._valid(self._files):
- yield Filenames._get(self._files)
+ yield Filenames._get(self._files).decode('utf-8', errors='ignore')
self._move_to_next(self._files)
self._files = None
diff --git a/bindings/python/notmuch/message.py b/bindings/python/notmuch/message.py
index 955382d..245e814 100644
--- a/bindings/python/notmuch/message.py
+++ b/bindings/python/notmuch/message.py
@@ -338,7 +338,7 @@ class Message(Python3StringMixIn):
"""
if self._msg is None:
raise NotmuchError(STATUS.NOT_INITIALIZED)
- return Message._get_message_id(self._msg)
+ return Message._get_message_id(self._msg).decode('utf-8', errors='ignore')
def get_thread_id(self):
"""Returns the thread ID
@@ -356,7 +356,7 @@ class Message(Python3StringMixIn):
if self._msg is None:
raise NotmuchError(STATUS.NOT_INITIALIZED)
- return Message._get_thread_id(self._msg)
+ return Message._get_thread_id(self._msg).decode('utf-8', errors='ignore')
def get_replies(self):
"""Gets all direct replies to this message as :class:`Messages`
@@ -426,7 +426,7 @@ class Message(Python3StringMixIn):
raise NotmuchError(STATUS.NOT_INITIALIZED)
#Returns NULL if any error occurs.
- header = Message._get_header(self._msg, header)
+ header = Message._get_header(self._msg, _str(header))
if header == None:
raise NotmuchError(STATUS.NULL_POINTER)
return header.decode('UTF-8', errors='ignore')
@@ -440,7 +440,7 @@ class Message(Python3StringMixIn):
"""
if self._msg is None:
raise NotmuchError(STATUS.NOT_INITIALIZED)
- return Message._get_filename(self._msg)
+ return Message._get_filename(self._msg).decode('utf-8', errors='ignore')
def get_filenames(self):
"""Get all filenames for the email corresponding to 'message'
diff --git a/bindings/python/notmuch/thread.py b/bindings/python/notmuch/thread.py
index 3912957..2ed7db0 100644
--- a/bindings/python/notmuch/thread.py
+++ b/bindings/python/notmuch/thread.py
@@ -246,7 +246,7 @@ class Thread(object):
"""
if self._thread is None:
raise NotmuchError(STATUS.NOT_INITIALIZED)
- return Thread._get_thread_id(self._thread)
+ return Thread._get_thread_id(self._thread).decode('utf-8', errors='ignore')
_get_total_messages = nmlib.notmuch_thread_get_total_messages
_get_total_messages.argtypes = [NotmuchThreadP]
--
1.7.7.3
^ permalink raw reply related [flat|nested] 17+ messages in thread