python: Handle slight differences between Python 2 and 3.
* lang/python/helpers.c (pyDataWriteCb): Handle Python integers being returned on Python 2. (pyDataSeekCb): Likewise. * lang/python/pyme/core.py (Data.__init__): Fix testing for string argument. (Data.new_from_filepart): Likewise. * lang/python/pyme/util.py (is_a_string): New function. * lang/python/tests/t-encrypt-large.py (read_cb): Force evaluation of generator. * lang/python/tests/t-idiomatic.py: Partly skip test on Python 2. * lang/python/tests/t-verify.py (check_result): Here, the difference between 2 and 3 really matters. We cannot change the char * conversion in Python 2 without breaking all existing applications, and using bytestrings in Python 3 would be very inconvenient. Signed-off-by: Justus Winter <justus@g10code.com>
This commit is contained in:
parent
4abff7d750
commit
70a3be27a5
@ -833,17 +833,21 @@ static ssize_t pyDataWriteCb(void *hook, const void *buffer, size_t size)
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (! PyLong_Check(retval)) {
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
if (PyInt_Check(retval))
|
||||
result = PyInt_AsSsize_t(retval);
|
||||
else
|
||||
#endif
|
||||
if (PyLong_Check(retval))
|
||||
result = PyLong_AsSsize_t(retval);
|
||||
else {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"expected int from read callback, got %s",
|
||||
"expected int from write callback, got %s",
|
||||
retval->ob_type->tp_name);
|
||||
_pyme_stash_callback_exception(self);
|
||||
result = -1;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
result = PyLong_AsSsize_t(retval);
|
||||
|
||||
leave:
|
||||
Py_XDECREF(retval);
|
||||
return result;
|
||||
@ -894,20 +898,24 @@ static off_t pyDataSeekCb(void *hook, off_t offset, int whence)
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (! PyLong_Check(retval)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"expected int from read callback, got %s",
|
||||
retval->ob_type->tp_name);
|
||||
_pyme_stash_callback_exception(self);
|
||||
result = -1;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
if (PyInt_Check(retval))
|
||||
result = PyInt_AsLong(retval);
|
||||
else
|
||||
#endif
|
||||
if (PyLong_Check(retval))
|
||||
#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64
|
||||
result = PyLong_AsLongLong(retval);
|
||||
#else
|
||||
result = PyLong_AsLong(retval);
|
||||
#endif
|
||||
else {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"expected int from seek callback, got %s",
|
||||
retval->ob_type->tp_name);
|
||||
_pyme_stash_callback_exception(self);
|
||||
result = -1;
|
||||
}
|
||||
|
||||
leave:
|
||||
Py_XDECREF(retval);
|
||||
|
@ -884,7 +884,7 @@ class Data(GpgmeWrapper):
|
||||
elif file != None and offset != None and length != None:
|
||||
self.new_from_filepart(file, offset, length)
|
||||
elif file != None:
|
||||
if type(file) == type("x"):
|
||||
if util.is_a_string(file):
|
||||
self.new_from_file(file, copy)
|
||||
else:
|
||||
self.new_from_fd(file)
|
||||
@ -961,7 +961,7 @@ class Data(GpgmeWrapper):
|
||||
filename = None
|
||||
fp = None
|
||||
|
||||
if type(file) == type("x"):
|
||||
if util.is_a_string(file):
|
||||
filename = file
|
||||
else:
|
||||
fp = gpgme.fdopen(file.fileno(), file.mode)
|
||||
|
@ -16,6 +16,8 @@
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
import sys
|
||||
|
||||
def process_constants(prefix, scope):
|
||||
"""Called by the constant modules to load up the constants from the C
|
||||
library starting with PREFIX. Matching constants will be inserted
|
||||
@ -36,3 +38,13 @@ def percent_escape(s):
|
||||
'%{0:2x}'.format(ord(c))
|
||||
if c == '+' or c == '"' or c == '%' or ord(c) <= 0x20 else c
|
||||
for c in s)
|
||||
|
||||
# Python2/3 compatibility
|
||||
if sys.version_info[0] == 3:
|
||||
# Python3
|
||||
def is_a_string(x):
|
||||
return isinstance(x, str)
|
||||
else:
|
||||
# Python2
|
||||
def is_a_string(x):
|
||||
return isinstance(x, basestring)
|
||||
|
@ -37,7 +37,7 @@ def read_cb(amount):
|
||||
ntoread -= chunk
|
||||
assert ntoread >= 0
|
||||
assert chunk >= 0
|
||||
return bytes(random.randrange(256) for i in range(chunk))
|
||||
return bytes(bytearray(random.randrange(256) for i in range(chunk)))
|
||||
|
||||
nwritten = 0
|
||||
def write_cb(data):
|
||||
|
@ -17,6 +17,7 @@
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import tempfile
|
||||
@ -60,6 +61,10 @@ with tempfile.TemporaryFile() as source, \
|
||||
|
||||
sign_and_verify(source, signed, sink)
|
||||
|
||||
if sys.version_info[0] == 3:
|
||||
# Python2's io.BytesIO does not implement the buffer interface,
|
||||
# hence we cannot use it as sink.
|
||||
|
||||
# XXX: Python's io.BytesIo.truncate does not work as advertised.
|
||||
# http://bugs.python.org/issue27261
|
||||
bio = io.BytesIO()
|
||||
|
@ -17,6 +17,7 @@
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import sys
|
||||
import os
|
||||
import pyme
|
||||
from pyme import core, constants, errors
|
||||
@ -67,8 +68,11 @@ def check_result(result, summary, validity, fpr, status, notation):
|
||||
|
||||
if notation:
|
||||
expected_notations = {
|
||||
"bar": b"\xc3\xb6\xc3\xa4\xc3\xbc\xc3\x9f".decode() +
|
||||
" das waren Umlaute und jetzt ein prozent%-Zeichen",
|
||||
"bar": (b"\xc3\xb6\xc3\xa4\xc3\xbc\xc3\x9f" +
|
||||
b" das waren Umlaute und jetzt ein prozent%-Zeichen"
|
||||
if sys.version_info[0] < 3 else
|
||||
b"\xc3\xb6\xc3\xa4\xc3\xbc\xc3\x9f".decode() +
|
||||
" das waren Umlaute und jetzt ein prozent%-Zeichen"),
|
||||
"foobar.1": "this is a notation data with 2 lines",
|
||||
None: "http://www.gu.org/policy/",
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user