On Mon, Aug 22, 2011 at 04:37:34PM -0400, James Vega wrote:
> On Sun, Jun 19, 2011 at 12:28:17AM +0200, Bram Moolenaar wrote:
> >
> > Patch 7.3.220
> > Problem: Python 3: vim.error is a 'str' instead of an 'Exception' object,
> > so 'except' or 'raise' it causes a 'SystemError' exception.
> > Buffer objects do not support slice assignment.
> > When exchanging text between Vim and Python, multibyte texts
> > become
> > gabage or cause Unicode Expceptions, etc.
> > 'py3file' tries to read in the file as Unicode, sometimes causes
> > UnicodeDecodeException
> > Solution: Fix the problems. (lilydjwg)
> > Files: src/if_py_both.h, src/if_python.c, src/if_python3.c
> >
> >
> > *** ../mercurial/vim73/src/if_py_both.h 2011-03-22 15:47:18.000000000
> > +0100
> > --- src/if_py_both.h 2011-06-18 23:54:25.000000000 +0200
> > ***************
> > *** 65,74 ****
> > OutputWrite(PyObject *self, PyObject *args)
> > {
> > int len;
> > ! char *str;
> > int error = ((OutputObject *)(self))->error;
> >
> > ! if (!PyArg_ParseTuple(args, "s#", &str, &len))
> > return NULL;
> >
> > Py_BEGIN_ALLOW_THREADS
> > --- 65,74 ----
> > OutputWrite(PyObject *self, PyObject *args)
> > {
> > int len;
> > ! char *str = NULL;
> > int error = ((OutputObject *)(self))->error;
> >
> > ! if (!PyArg_ParseTuple(args, "es#", p_enc, &str, &len))
> > return NULL;
> >
> > Py_BEGIN_ALLOW_THREADS
> > ***************
> > *** 76,81 ****
> > --- 76,82 ----
> > writer((writefn)(error ? emsg : msg), (char_u *)str, len);
> > Python_Release_Vim();
> > Py_END_ALLOW_THREADS
> > + PyMem_Free(str);
> >
> > Py_INCREF(Py_None);
> > return Py_None;
> > ***************
> > *** 104,113 ****
> > for (i = 0; i < n; ++i)
> > {
> > PyObject *line = PyList_GetItem(list, i);
> > ! char *str;
> > PyInt len;
> >
> > ! if (!PyArg_Parse(line, "s#", &str, &len)) {
> > PyErr_SetString(PyExc_TypeError, _("writelines() requires list of
> > strings"));
> > Py_DECREF(list);
> > return NULL;
> > --- 105,114 ----
> > for (i = 0; i < n; ++i)
> > {
> > PyObject *line = PyList_GetItem(list, i);
> > ! char *str = NULL;
> > PyInt len;
> >
> > ! if (!PyArg_Parse(line, "es#", p_enc, &str, &len)) {
> > PyErr_SetString(PyExc_TypeError, _("writelines() requires list of
> > strings"));
> > Py_DECREF(list);
> > return NULL;
>
> The above changes to PyArg_Parse break simple scenarios, like the ones
> below:
>
> 1) Print a string with non-ascii bytes:
> :set enc?
> encoding=utf-8
> :py print '\xc3\xb3'
> Traceback (most recent call last):
> File "<string>", line 1, in <module>
> UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0:
> ordinal not in range(128)
>
> 2) Print a properly encoded line from the buffer:
> :set enc?
> encoding=utf-8
> :call setline(1, nr2char(243))
> :py import vim
> :py print vim.current.buffer[0]
> Traceback (most recent call last):
> File "<string>", line 1, in <module>
> UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0:
> ordinal not in range(128)
>
> Changing "es#" to "et#" appears to fix the problem, but I'm not positive
> that's the correct fix.
>
It seems to fix the problem, except that it makes `sys.stdout.write` can
accept bytes with Python 3, but I don't think it harms.
Still another difference from the Python interpreter is, with Python 2,
printing Unicodes will be incorrect. Should this be fixed?
--
Best regards,
lilydjwg
Linux Vim Python 我的博客
http://lilydjwg.is-programmer.com/
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
diff --git a/src/if_py_both.h b/src/if_py_both.h
index c7870bc..53c2167 100644
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -74,7 +74,7 @@ OutputWrite(PyObject *self, PyObject *args)
char *str = NULL;
int error = ((OutputObject *)(self))->error;
- if (!PyArg_ParseTuple(args, "es#", ENC_OPT, &str, &len))
+ if (!PyArg_ParseTuple(args, "et#", ENC_OPT, &str, &len))
return NULL;
Py_BEGIN_ALLOW_THREADS
@@ -114,7 +114,7 @@ OutputWritelines(PyObject *self, PyObject *args)
char *str = NULL;
PyInt len;
- if (!PyArg_Parse(line, "es#", ENC_OPT, &str, &len)) {
+ if (!PyArg_Parse(line, "et#", ENC_OPT, &str, &len)) {
PyErr_SetString(PyExc_TypeError, _("writelines() requires list of
strings"));
Py_DECREF(list);
return NULL;