unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* [python] RFC: supporting python 2 and 3 with one codebase
@ 2011-12-14 10:58 Justus Winter
  2011-12-14 10:58 ` [PATCH 1/7] py3k: The execfile built-in has been removed in python 3 Justus Winter
                   ` (6 more replies)
  0 siblings, 7 replies; 17+ messages in thread
From: Justus Winter @ 2011-12-14 10:58 UTC (permalink / raw)
  To: notmuch

Hi everyone :)

attached is a patch series that makes the notmuch python bindings
compatible with both python 2.x and python 3.x.

There are some workarounds, but those are mostly in globals.py and in
my opinion the benefit of supporting both versions with one codebase
is totally worth it.

Patch seven adds missing unicode conversions that should be applied
even if the rest of the patchset is not.

Cheers,
Justus

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

* [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

* [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

* [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

* [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

* 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 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 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

* 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

* 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

end of thread, other threads:[~2012-01-08 14:06 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [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
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 ` [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
2012-01-08 14:04       ` Justus Winter
2012-01-08 14:06         ` [PATCH] " Justus Winter
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
2011-12-14 13:04       ` Justus Winter
2011-12-14 10:58 ` [PATCH 7/7] python: add missing conversions from and to utf-8 Justus Winter

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).