python: Fix type translation.
* lang/python/gpgme.i: Adjust to Python3's string type being 'Unicode', not 'bytes'. Fix type checking. * lang/python/core.py (Data.write): Add docstring mentioning the expected type of parameter 'buffer'. (Data.read): Adjust read loop. Also, use a saner chunk size, and join all chunks at the end instead of adding them. * lang/python/examples/simple.py: Adjust example. Signed-off-by: Justus Winter <justus@gnupg.org>
This commit is contained in:
parent
bbeee5e1a0
commit
d60deb8a12
@ -25,7 +25,7 @@ core.check_version(None)
|
|||||||
|
|
||||||
# Set up our input and output buffers.
|
# Set up our input and output buffers.
|
||||||
|
|
||||||
plain = core.Data(b'This is my message.')
|
plain = core.Data('This is my message.')
|
||||||
cipher = core.Data()
|
cipher = core.Data()
|
||||||
|
|
||||||
# Initialize our context.
|
# Initialize our context.
|
||||||
@ -38,7 +38,7 @@ c.set_armor(1)
|
|||||||
sys.stdout.write("Enter name of your recipient: ")
|
sys.stdout.write("Enter name of your recipient: ")
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
name = sys.stdin.readline().strip()
|
name = sys.stdin.readline().strip()
|
||||||
c.op_keylist_start(name.encode(), 0)
|
c.op_keylist_start(name, 0)
|
||||||
r = c.op_keylist_next()
|
r = c.op_keylist_next()
|
||||||
|
|
||||||
if r == None:
|
if r == None:
|
||||||
@ -48,6 +48,6 @@ else:
|
|||||||
try:
|
try:
|
||||||
c.op_encrypt([r], 1, plain, cipher)
|
c.op_encrypt([r], 1, plain, cipher)
|
||||||
cipher.seek(0,0)
|
cipher.seek(0,0)
|
||||||
print(cipher.read())
|
sys.stdout.buffer.write(cipher.read())
|
||||||
except errors.GPGMEError as ex:
|
except errors.GPGMEError as ex:
|
||||||
print(ex.getstring())
|
print(ex.getstring())
|
||||||
|
@ -24,16 +24,18 @@
|
|||||||
// Generate doc strings for all methods.
|
// Generate doc strings for all methods.
|
||||||
%feature("autodoc", "0");
|
%feature("autodoc", "0");
|
||||||
|
|
||||||
// Allow use of None for strings.
|
/* Allow use of Unicode objects, bytes, and None for strings. */
|
||||||
|
|
||||||
%typemap(in) const char * {
|
%typemap(in) const char * {
|
||||||
if ($input == Py_None)
|
if ($input == Py_None)
|
||||||
$1 = NULL;
|
$1 = NULL;
|
||||||
|
else if (PyUnicode_Check($input))
|
||||||
|
$1 = PyUnicode_AsUTF8($input);
|
||||||
else if (PyBytes_Check($input))
|
else if (PyBytes_Check($input))
|
||||||
$1 = PyBytes_AsString($input);
|
$1 = PyBytes_AsString($input);
|
||||||
else {
|
else {
|
||||||
PyErr_Format(PyExc_TypeError,
|
PyErr_Format(PyExc_TypeError,
|
||||||
"arg %d: expected string or None, got %s",
|
"arg %d: expected str, bytes, or None, got %s",
|
||||||
$argnum, $input->ob_type->tp_name);
|
$argnum, $input->ob_type->tp_name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -49,20 +51,27 @@
|
|||||||
PyObject* object_to_gpgme_t(PyObject* input, const char* objtype, int argnum) {
|
PyObject* object_to_gpgme_t(PyObject* input, const char* objtype, int argnum) {
|
||||||
PyObject *pyname = NULL, *pypointer = NULL;
|
PyObject *pyname = NULL, *pypointer = NULL;
|
||||||
pyname = PyObject_CallMethod(input, "_getctype", NULL);
|
pyname = PyObject_CallMethod(input, "_getctype", NULL);
|
||||||
if (pyname == NULL) {
|
if (pyname && PyUnicode_Check(pyname))
|
||||||
PyErr_Format(PyExc_TypeError,
|
{
|
||||||
"arg %d: Expected an instance of type %s, but got %s",
|
if (strcmp(PyUnicode_AsUTF8(pyname), objtype) != 0)
|
||||||
argnum, objtype,
|
{
|
||||||
input == Py_None ? "None" : input->ob_type->tp_name);
|
PyErr_Format(PyExc_TypeError,
|
||||||
return NULL;
|
"arg %d: Expected value of type %s, but got %s",
|
||||||
}
|
argnum, objtype, PyUnicode_AsUTF8(pyname));
|
||||||
if (strcmp(PyBytes_AsString(pyname), objtype) != 0) {
|
Py_DECREF(pyname);
|
||||||
PyErr_Format(PyExc_TypeError,
|
return NULL;
|
||||||
"arg %d: Expected value of type %s, but got %s",
|
}
|
||||||
argnum, objtype, PyBytes_AsString(pyname));
|
}
|
||||||
Py_DECREF(pyname);
|
else
|
||||||
return NULL;
|
{
|
||||||
}
|
PyErr_Format(PyExc_TypeError,
|
||||||
|
"Protocol violation: Expected an instance of type str "
|
||||||
|
"from _getctype, but got %s",
|
||||||
|
pyname == NULL ? "NULL"
|
||||||
|
: (pyname == Py_None ? "None" : pyname->ob_type->tp_name));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
Py_DECREF(pyname);
|
Py_DECREF(pyname);
|
||||||
pypointer = PyObject_GetAttrString(input, "wrapped");
|
pypointer = PyObject_GetAttrString(input, "wrapped");
|
||||||
if (pypointer == NULL) {
|
if (pypointer == NULL) {
|
||||||
@ -243,7 +252,7 @@ gpgme_error_t pyEditCb(void *opaque, gpgme_status_code_t status,
|
|||||||
}
|
}
|
||||||
|
|
||||||
PyTuple_SetItem(pyargs, 0, PyLong_FromLong((long) status));
|
PyTuple_SetItem(pyargs, 0, PyLong_FromLong((long) status));
|
||||||
PyTuple_SetItem(pyargs, 1, PyBytes_FromString(args));
|
PyTuple_SetItem(pyargs, 1, PyUnicode_FromString(args));
|
||||||
if (dataarg) {
|
if (dataarg) {
|
||||||
Py_INCREF(dataarg); /* Because GetItem doesn't give a ref but SetItem taketh away */
|
Py_INCREF(dataarg); /* Because GetItem doesn't give a ref but SetItem taketh away */
|
||||||
PyTuple_SetItem(pyargs, 2, dataarg);
|
PyTuple_SetItem(pyargs, 2, dataarg);
|
||||||
@ -254,8 +263,12 @@ gpgme_error_t pyEditCb(void *opaque, gpgme_status_code_t status,
|
|||||||
if (PyErr_Occurred()) {
|
if (PyErr_Occurred()) {
|
||||||
err_status = pygpgme_exception2code();
|
err_status = pygpgme_exception2code();
|
||||||
} else {
|
} else {
|
||||||
if (fd>=0 && retval) {
|
if (fd>=0 && retval && PyUnicode_Check(retval)) {
|
||||||
write(fd, PyBytes_AsString(retval), PyBytes_Size(retval));
|
const char *buffer;
|
||||||
|
Py_ssize_t size;
|
||||||
|
|
||||||
|
buffer = PyUnicode_AsUTF8AndSize(retval, &size);
|
||||||
|
write(fd, buffer, size);
|
||||||
write(fd, "\n", 1);
|
write(fd, "\n", 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -377,10 +377,11 @@ class Data(GpgmeWrapper):
|
|||||||
self.new_from_fd(file)
|
self.new_from_fd(file)
|
||||||
|
|
||||||
def write(self, buffer):
|
def write(self, buffer):
|
||||||
|
"""Write buffer given as bytes."""
|
||||||
errorcheck(pygpgme.gpgme_data_write(self.wrapped, buffer, len(buffer)))
|
errorcheck(pygpgme.gpgme_data_write(self.wrapped, buffer, len(buffer)))
|
||||||
|
|
||||||
def read(self, size = -1):
|
def read(self, size = -1):
|
||||||
"""Read at most size bytes, returned as a string.
|
"""Read at most size bytes, returned as bytes.
|
||||||
|
|
||||||
If the size argument is negative or omitted, read until EOF is reached.
|
If the size argument is negative or omitted, read until EOF is reached.
|
||||||
|
|
||||||
@ -393,13 +394,13 @@ class Data(GpgmeWrapper):
|
|||||||
if size > 0:
|
if size > 0:
|
||||||
return pygpgme.gpgme_data_read(self.wrapped, size)
|
return pygpgme.gpgme_data_read(self.wrapped, size)
|
||||||
else:
|
else:
|
||||||
retval = ''
|
chunks = []
|
||||||
while 1:
|
while 1:
|
||||||
result = pygpgme.gpgme_data_read(self.wrapped, 10240)
|
result = pygpgme.gpgme_data_read(self.wrapped, 4096)
|
||||||
if len(result) == 0:
|
if len(result) == 0:
|
||||||
break
|
break
|
||||||
retval += result
|
chunks.append(result)
|
||||||
return retval
|
return b''.join(chunks)
|
||||||
|
|
||||||
def pubkey_algo_name(algo):
|
def pubkey_algo_name(algo):
|
||||||
return pygpgme.gpgme_pubkey_algo_name(algo)
|
return pygpgme.gpgme_pubkey_algo_name(algo)
|
||||||
|
Loading…
Reference in New Issue
Block a user