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.

-- 
James
GPG Key: 1024D/61326D40 2003-09-02 James Vega <[email protected]>

Attachment: signature.asc
Description: Digital signature

Raspunde prin e-mail lui