Re: [PATCH] fix broken Python3 support

2011-06-15 Fir de Conversatie lilydjwg
On Tue, Jun 14, 2011 at 06:06:51AM +0200, Bram Moolenaar wrote:
 Thanks for the update.  I'll check it out later.
 
 I have this remark in the todo list, I suppose this patch is fixing it:
 
Python3 interface doesn't handle utf-8 correctly? (Nov 2010, lilydjwg)
 

Yes.

-- 
Best regards,
lilydjwg

Linux Vim Python 我的博客
http://bit.ly/lilydjwg or http://goo.gl/y4Gsy

-- 
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


Re: [PATCH] fix broken Python3 support

2011-06-13 Fir de Conversatie lilydjwg
On Mon, Jun 13, 2011 at 03:54:04AM +0200, Bram Moolenaar wrote:
 I have included the patch, but on my Ubuntu system I get this error:
 
   E448: Could not load library function PyUnicode_UCSX_*
 
 when doing something simple as :py3 print('hello')
 
 Can you fix that?
 

Yes, just a typo preventing Python symbols from loading.

Later a user found that there was heavy memory leakage, and I tried hard
to fix them. It was partly introduced by my code, and I believe partly
had been there before. Attached patch should fix this too.

-- 
Best regards,
lilydjwg

-- 
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 f78eccb..72ec8b0 100644
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -65,10 +65,10 @@ static struct PyMethodDef OutputMethods[] = {
 OutputWrite(PyObject *self, PyObject *args)
 {
 int len;
-char *str;
+char *str = NULL;
 int error = ((OutputObject *)(self))-error;
 
-if (!PyArg_ParseTuple(args, s#, str, len))
+if (!PyArg_ParseTuple(args, es#, p_enc, str, len))
return NULL;
 
 Py_BEGIN_ALLOW_THREADS
@@ -76,6 +76,7 @@ OutputWrite(PyObject *self, PyObject *args)
 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,10 +105,10 @@ OutputWritelines(PyObject *self, PyObject *args)
 for (i = 0; i  n; ++i)
 {
PyObject *line = PyList_GetItem(list, i);
-   char *str;
+   char *str = NULL;
PyInt len;
 
-   if (!PyArg_Parse(line, s#, str, len)) {
+   if (!PyArg_Parse(line, es#, p_enc, str, len)) {
PyErr_SetString(PyExc_TypeError, _(writelines() requires list of 
strings));
Py_DECREF(list);
return NULL;
@@ -118,6 +119,7 @@ OutputWritelines(PyObject *self, PyObject *args)
writer((writefn)(error ? emsg : msg), (char_u *)str, len);
Python_Release_Vim();
Py_END_ALLOW_THREADS
+   PyMem_Free(str);
 }
 
 Py_DECREF(list);
@@ -681,6 +683,7 @@ StringToLine(PyObject *obj)
 {
 const char *str;
 char *save;
+PyObject *bytes;
 PyInt len;
 PyInt i;
 char *p;
@@ -691,8 +694,9 @@ StringToLine(PyObject *obj)
return NULL;
 }
 
-str = PyString_AsString(obj);
-len = PyString_Size(obj);
+bytes = PyString_AsBytes(obj);
+str = PyString_AsString(bytes);
+len = PyString_Size(bytes);
 
 /*
  * Error checking: String must not contain newlines, as we
@@ -731,6 +735,7 @@ StringToLine(PyObject *obj)
 }
 
 save[i] = '\0';
+PyString_FreeBytes(bytes);
 
 return save;
 }
@@ -908,6 +913,193 @@ SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt 
*len_change)
 }
 }
 
+/* Replace a range of lines in the specified buffer. The line numbers are in
+ * Vim format (1-based). The range is from lo up to, but not including, hi.
+ * The replacement lines are given as a Python list of string objects. The
+ * list is checked for validity and correct format. Errors are returned as a
+ * value of FAIL.  The return value is OK on success.
+ * If OK is returned and len_change is not NULL, *len_change
+ * is set to the change in the buffer length.
+ */
+static int
+SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt 
*len_change)
+{
+/* First of all, we check the thpe of the supplied Python object.
+ * There are three cases:
+ *   1. NULL, or None - this is a deletion.
+ *   2. A list- this is a replacement.
+ *   3. Anything else - this is an error.
+ */
+if (list == Py_None || list == NULL)
+{
+   PyInt   i;
+   PyInt   n = (int)(hi - lo);
+   buf_T   *savebuf = curbuf;
+
+   PyErr_Clear();
+   curbuf = buf;
+
+   if (u_savedel((linenr_T)lo, (long)n) == FAIL)
+   PyErr_SetVim(_(cannot save undo information));
+   else
+   {
+   for (i = 0; i  n; ++i)
+   {
+   if (ml_delete((linenr_T)lo, FALSE) == FAIL)
+   {
+   PyErr_SetVim(_(cannot delete line));
+   break;
+   }
+   }
+   if (buf == curwin-w_buffer)
+   py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
+   deleted_lines_mark((linenr_T)lo, (long)i);
+   }
+
+   curbuf = savebuf;
+
+   if (PyErr_Occurred() || VimErrorCheck())
+   return FAIL;
+
+   if (len_change)
+   *len_change = -n;
+
+   return OK;
+}
+else if (PyList_Check(list))
+{
+   PyInt   i;
+   PyInt   new_len = PyList_Size(list);
+   PyInt   old_len = hi - lo;
+   PyInt   extra = 0;  /* lines added to text, can be negative */
+   char**array;
+   buf_T   *savebuf;
+
+   if (new_len 

Re: [PATCH] fix broken Python3 support

2011-06-13 Fir de Conversatie Bram Moolenaar

lilydjwg wronte:

 On Mon, Jun 13, 2011 at 03:54:04AM +0200, Bram Moolenaar wrote:
  I have included the patch, but on my Ubuntu system I get this error:
  
E448: Could not load library function PyUnicode_UCSX_*
  
  when doing something simple as :py3 print('hello')
  
  Can you fix that?
  
 
 Yes, just a typo preventing Python symbols from loading.
 
 Later a user found that there was heavy memory leakage, and I tried hard
 to fix them. It was partly introduced by my code, and I believe partly
 had been there before. Attached patch should fix this too.

Thanks for the update.  I'll check it out later.

I have this remark in the todo list, I suppose this patch is fixing it:

   Python3 interface doesn't handle utf-8 correctly? (Nov 2010, lilydjwg)

-- 
hundred-and-one symptoms of being an internet addict:
179. You wonder why your household garbage can doesn't have an
 empty recycle bin button.

 /// Bram Moolenaar -- b...@moolenaar.net -- http://www.Moolenaar.net   \\\
///sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org///
 \\\help me help AIDS victims -- http://ICCF-Holland.org///

-- 
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


Re: [PATCH] fix broken Python3 support

2011-06-12 Fir de Conversatie Bram Moolenaar

lilydjwg wrote:

 I made a patch to fix some bugs related to Vim's Python3 support. The
 bugs I found are:
 
 * 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 exchange 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
 
 The patch works on my Ubuntu Linux 32bit and Windows XP SP3 and should
 apply to any Vim 7.3+ version.

I have included the patch, but on my Ubuntu system I get this error:

  E448: Could not load library function PyUnicode_UCSX_*

when doing something simple as :py3 print('hello')

Can you fix that?

-- 
If Microsoft would build a car...
... Occasionally your car would die on the freeway for no
reason. You would have to pull over to the side of the road,
close all of the car windows, shut it off, restart it, and
reopen the windows before you could continue. For some reason
you would simply accept this.

 /// Bram Moolenaar -- b...@moolenaar.net -- http://www.Moolenaar.net   \\\
///sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org///
 \\\help me help AIDS victims -- http://ICCF-Holland.org///

-- 
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


Re: [PATCH] fix broken Python3 support

2011-02-25 Fir de Conversatie Bram Moolenaar

Lilydjwg wrote:

 I made a patch to fix some bugs related to Vim's Python3 support. The
 bugs I found are:
 
 * 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 exchange 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
 
 The patch works on my Ubuntu Linux 32bit and Windows XP SP3 and should
 apply to any Vim 7.3+ version.

Sounds good.

Can a few people try this out?

-- 
Apologies for taking up the bandwidth with the apology.  Anything else I
can apologise for .. er no can't think of anything, sorry about that.
Andy Hunt (Member of British Olympic Apology Squad)

 /// Bram Moolenaar -- b...@moolenaar.net -- http://www.Moolenaar.net   \\\
///sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org///
 \\\help me help AIDS victims -- http://ICCF-Holland.org///

-- 
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


Re: [PATCH] fix broken Python3 support

2011-02-24 Fir de Conversatie lilydjwg
Sorry, I forgot the attachment.

-- 
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 e435e3e..2e701a8 100644
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -63,10 +63,10 @@ static struct PyMethodDef OutputMethods[] = {
 OutputWrite(PyObject *self, PyObject *args)
 {
 int len;
-char *str;
+char *str = NULL;
 int error = ((OutputObject *)(self))-error;
 
-if (!PyArg_ParseTuple(args, s#, str, len))
+if (!PyArg_ParseTuple(args, es#, p_enc, str, len))
 	return NULL;
 
 Py_BEGIN_ALLOW_THREADS
@@ -74,6 +74,7 @@ OutputWrite(PyObject *self, PyObject *args)
 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;
@@ -102,10 +103,10 @@ OutputWritelines(PyObject *self, PyObject *args)
 for (i = 0; i  n; ++i)
 {
 	PyObject *line = PyList_GetItem(list, i);
-	char *str;
+	char *str = NULL;
 	PyInt len;
 
-	if (!PyArg_Parse(line, s#, str, len)) {
+	if (!PyArg_Parse(line, es#, p_enc, str, len)) {
 	PyErr_SetString(PyExc_TypeError, _(writelines() requires list of strings));
 	Py_DECREF(list);
 	return NULL;
@@ -116,6 +117,7 @@ OutputWritelines(PyObject *self, PyObject *args)
 	writer((writefn)(error ? emsg : msg), (char_u *)str, len);
 	Python_Release_Vim();
 	Py_END_ALLOW_THREADS
+	PyMem_Free(str);
 }
 
 Py_DECREF(list);
@@ -897,6 +899,193 @@ SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
 }
 }
 
+/* Replace a range of lines in the specified buffer. The line numbers are in
+ * Vim format (1-based). The range is from lo up to, but not including, hi.
+ * The replacement lines are given as a Python list of string objects. The
+ * list is checked for validity and correct format. Errors are returned as a
+ * value of FAIL.  The return value is OK on success.
+ * If OK is returned and len_change is not NULL, *len_change
+ * is set to the change in the buffer length.
+ */
+static int
+SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_change)
+{
+/* First of all, we check the thpe of the supplied Python object.
+ * There are three cases:
+ *	  1. NULL, or None - this is a deletion.
+ *	  2. A list	   - this is a replacement.
+ *	  3. Anything else - this is an error.
+ */
+if (list == Py_None || list == NULL)
+{
+	PyInt	i;
+	PyInt	n = (int)(hi - lo);
+	buf_T	*savebuf = curbuf;
+
+	PyErr_Clear();
+	curbuf = buf;
+
+	if (u_savedel((linenr_T)lo, (long)n) == FAIL)
+	PyErr_SetVim(_(cannot save undo information));
+	else
+	{
+	for (i = 0; i  n; ++i)
+	{
+		if (ml_delete((linenr_T)lo, FALSE) == FAIL)
+		{
+		PyErr_SetVim(_(cannot delete line));
+		break;
+		}
+	}
+	if (buf == curwin-w_buffer)
+		py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
+	deleted_lines_mark((linenr_T)lo, (long)i);
+	}
+
+	curbuf = savebuf;
+
+	if (PyErr_Occurred() || VimErrorCheck())
+	return FAIL;
+
+	if (len_change)
+	*len_change = -n;
+
+	return OK;
+}
+else if (PyList_Check(list))
+{
+	PyInt	i;
+	PyInt	new_len = PyList_Size(list);
+	PyInt	old_len = hi - lo;
+	PyInt	extra = 0;	/* lines added to text, can be negative */
+	char	**array;
+	buf_T	*savebuf;
+
+	if (new_len == 0)	/* avoid allocating zero bytes */
+	array = NULL;
+	else
+	{
+	array = (char **)alloc((unsigned)(new_len * sizeof(char *)));
+	if (array == NULL)
+	{
+		PyErr_NoMemory();
+		return FAIL;
+	}
+	}
+
+	for (i = 0; i  new_len; ++i)
+	{
+	PyObject *line = PyList_GetItem(list, i);
+
+	array[i] = StringToLine(line);
+	if (array[i] == NULL)
+	{
+		while (i)
+		vim_free(array[--i]);
+		vim_free(array);
+		return FAIL;
+	}
+	}
+
+	savebuf = curbuf;
+
+	PyErr_Clear();
+	curbuf = buf;
+
+	if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
+	PyErr_SetVim(_(cannot save undo information));
+
+	/* If the size of the range is reducing (ie, new_len  old_len) we
+	 * need to delete some old_len. We do this at the start, by
+	 * repeatedly deleting line lo.
+	 */
+	if (!PyErr_Occurred())
+	{
+	for (i = 0; i  old_len - new_len; ++i)
+		if (ml_delete((linenr_T)lo, FALSE) == FAIL)
+		{
+		PyErr_SetVim(_(cannot delete line));
+		break;
+		}
+	extra -= i;
+	}
+
+	/* For as long as possible, replace the existing old_len with the
+	 * new old_len. This is a more efficient operation, as it requires
+	 * less memory allocation and freeing.
+	 */
+	if (!PyErr_Occurred())
+	{
+	for (i = 0; i  old_len  i  new_len; ++i)
+		if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
+  == FAIL)
+		{
+		PyErr_SetVim(_(cannot replace line));

[PATCH] fix broken Python3 support

2011-02-24 Fir de Conversatie lilydjwg
Hi there,

I made a patch to fix some bugs related to Vim's Python3 support. The
bugs I found are:

* 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 exchange 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

The patch works on my Ubuntu Linux 32bit and Windows XP SP3 and should
apply to any Vim 7.3+ version.

-- 
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