PROTON-1325: Python mapping for 'buffer' and/or 'memoryview'

Use whichever is available, memoryview is 3.x and some later 2.x, buffer is
older 2.x. Some have both.
diff --git a/proton-c/bindings/python/proton/__init__.py b/proton-c/bindings/python/proton/__init__.py
index 1478d38..516daf1 100644
--- a/proton-c/bindings/python/proton/__init__.py
+++ b/proton-c/bindings/python/proton/__init__.py
@@ -2229,14 +2229,18 @@
     list: put_sequence,
     tuple: put_sequence,
     dict: put_dict,
-    buffer: put_binary,
     Described: put_py_described,
     Array: put_py_array
     }
   # for python 3.x, long is merely an alias for int, but for python 2.x
   # we need to add an explicit int since it is a different type
   if int not in put_mappings:
-      put_mappings[int] = put_int
+    put_mappings[int] = put_int
+  # For python 3.x use 'memoryview', for <=2.5 use 'buffer'. Python >=2.6 has both.
+  if getattr(__builtins__, 'memoryview', None):
+    put_mappings[memoryview] = put_binary
+  if getattr(__builtins__, 'buffer', None):
+    put_mappings[buffer] = put_binary
 
   get_mappings = {
     NULL: lambda s: None,
diff --git a/tests/python/proton_tests/codec.py b/tests/python/proton_tests/codec.py
index b7bb04d..4d3d906 100644
--- a/tests/python/proton_tests/codec.py
+++ b/tests/python/proton_tests/codec.py
@@ -357,14 +357,25 @@
     copy = data.get_object()
     assert copy == obj, (copy, obj)
 
-  def testBuffer(self):
-    self.data.put_object(buffer("foo"))
-    data = Data()
-    data.decode(self.data.encode())
-    data.rewind()
-    assert data.next()
-    assert data.type() == Data.BINARY
-    assert data.get_object() == "foo"
+  if getattr(__builtins__, 'buffer', None):
+    def testBuffer(self):
+      self.data.put_object(buffer("foo"))
+      data = Data()
+      data.decode(self.data.encode())
+      data.rewind()
+      assert data.next()
+      assert data.type() == Data.BINARY
+      assert data.get_object() == "foo"
+
+  if getattr(__builtins__, 'memoryview', None):
+    def testBuffer(self):
+      self.data.put_object(memoryview("foo"))
+      data = Data()
+      data.decode(self.data.encode())
+      data.rewind()
+      assert data.next()
+      assert data.type() == Data.BINARY
+      assert data.get_object() == "foo"
 
   def testLookup(self):
     obj = {symbol("key"): str2unicode("value"),