diff --git a/src/pl/plpython/plpy_elog.c b/src/pl/plpython/plpy_elog.c
new file mode 100644
index c375ac0..c2b3cb8
*** a/src/pl/plpython/plpy_elog.c
--- b/src/pl/plpython/plpy_elog.c
*************** static char *get_source_line(const char
*** 28,33 ****
--- 28,41 ----
  
  
  /*
+  * Guard agains re-entrant calls to PLy_traceback, which can happen if
+  * traceback formatting functions raise Python errors.
+  */
+ #define TRACEBACK_RECURSION_LIMIT 2
+ static int	recursion_depth = 0;
+ 
+ 
+ /*
   * Emit a PG error or notice, together with any available info about
   * the current Python error, previously set by PLy_exception_set().
   * This should be used to propagate Python errors into PG.	If fmt is
*************** PLy_traceback(char **xmsg, char **tbmsg,
*** 147,166 ****
  	StringInfoData xstr;
  	StringInfoData tbstr;
  
  	/*
  	 * get the current exception
  	 */
  	PyErr_Fetch(&e, &v, &tb);
  
  	/*
! 	 * oops, no exception, return
  	 */
! 	if (e == NULL)
  	{
  		*xmsg = NULL;
  		*tbmsg = NULL;
  		*tb_depth = 0;
  
  		return;
  	}
  
--- 155,177 ----
  	StringInfoData xstr;
  	StringInfoData tbstr;
  
+ 	recursion_depth++;
+ 
  	/*
  	 * get the current exception
  	 */
  	PyErr_Fetch(&e, &v, &tb);
  
  	/*
! 	 * oops, no exception or recursion depth exceeded, return
  	 */
! 	if (e == NULL || recursion_depth > TRACEBACK_RECURSION_LIMIT)
  	{
  		*xmsg = NULL;
  		*tbmsg = NULL;
  		*tb_depth = 0;
  
+ 		recursion_depth--;
  		return;
  	}
  
*************** PLy_traceback(char **xmsg, char **tbmsg,
*** 326,331 ****
--- 337,344 ----
  		(*tb_depth)++;
  	}
  
+ 	recursion_depth--;
+ 
  	/* Return the traceback. */
  	*tbmsg = tbstr.data;
  
diff --git a/src/pl/plpython/plpy_util.c b/src/pl/plpython/plpy_util.c
new file mode 100644
index bf29532..ea4ecdf
*** a/src/pl/plpython/plpy_util.c
--- b/src/pl/plpython/plpy_util.c
*************** PLyUnicode_Bytes(PyObject *unicode)
*** 112,117 ****
--- 112,123 ----
  		case PG_WIN874:
  			serverenc = "cp874";
  			break;
+ 		case PG_KOI8R:
+ 			serverenc = "koi8-r";
+ 			break;
+ 		case PG_KOI8U:
+ 			serverenc = "koi8-u";
+ 			break;
  		default:
  			/* Other encodings have the same name in Python. */
  			serverenc = GetDatabaseEncodingName();
*************** PLyUnicode_Bytes(PyObject *unicode)
*** 120,135 ****
  
  	rv = PyUnicode_AsEncodedString(unicode, serverenc, "strict");
  	if (rv == NULL)
! 	{
! 		/*
! 		 * Use a plain ereport instead of PLy_elog to avoid recursion, if
! 		 * the traceback formatting functions try to do unicode to bytes
! 		 * conversion again.
! 		 */
! 		ereport(ERROR,
! 				(errcode(ERRCODE_INTERNAL_ERROR),
! 				 errmsg("could not convert Python Unicode object to PostgreSQL server encoding")));
! 	}
  	return rv;
  }
  
--- 126,132 ----
  
  	rv = PyUnicode_AsEncodedString(unicode, serverenc, "strict");
  	if (rv == NULL)
! 		PLy_elog(ERROR, "could not convert Python Unicode object to PostgreSQL server encoding");
  	return rv;
  }
  
