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;

Raspunde prin e-mail lui