diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c
index 5e600daa96ae2159512b366b41197c31383ee7f8..8108cfce2c045d49b8a9cd5e716a7831cad9a95a 100644
--- a/src/pl/plpython/plpython.c
+++ b/src/pl/plpython/plpython.c
@@ -4510,6 +4510,14 @@ get_source_line(const char *src, int lineno)
 	if (next == NULL)
 		return pstrdup(s);
 
+	/*
+	 * Sanity check, next < s if the line was all-whitespace, which should
+	 * never happen if Python reported a frame created on that line, but
+	 * check anyway.
+	 */
+	if (next < s)
+		return NULL;
+
 	return pnstrdup(s, next - s);
 }
 
@@ -4606,6 +4614,7 @@ PLy_traceback(char **xmsg, char **tbmsg, int *tb_depth)
 		PyObject   *volatile code = NULL;
 		PyObject   *volatile name = NULL;
 		PyObject   *volatile lineno = NULL;
+		PyObject   *volatile filename = NULL;
 
 		PG_TRY();
 		{
@@ -4624,6 +4633,10 @@ PLy_traceback(char **xmsg, char **tbmsg, int *tb_depth)
 			name = PyObject_GetAttrString(code, "co_name");
 			if (name == NULL)
 				elog(ERROR, "could not get function name from Python code object");
+
+			filename = PyObject_GetAttrString(code, "co_filename");
+			if (filename == NULL)
+				elog(ERROR, "could not get file name from Python code object");
 		}
 		PG_CATCH();
 		{
@@ -4631,6 +4644,7 @@ PLy_traceback(char **xmsg, char **tbmsg, int *tb_depth)
 			Py_XDECREF(code);
 			Py_XDECREF(name);
 			Py_XDECREF(lineno);
+			Py_XDECREF(filename);
 			PG_RE_THROW();
 		}
 		PG_END_TRY();
@@ -4641,6 +4655,7 @@ PLy_traceback(char **xmsg, char **tbmsg, int *tb_depth)
 			char	   *proname;
 			char	   *fname;
 			char	   *line;
+			char	   *plain_filename;
 			long		plain_lineno;
 
 			/*
@@ -4653,6 +4668,7 @@ PLy_traceback(char **xmsg, char **tbmsg, int *tb_depth)
 				fname = PyString_AsString(name);
 
 			proname = PLy_procedure_name(PLy_curr_procedure);
+			plain_filename = PyString_AsString(filename);
 			plain_lineno = PyInt_AsLong(lineno);
 
 			if (proname == NULL)
@@ -4664,7 +4680,9 @@ PLy_traceback(char **xmsg, char **tbmsg, int *tb_depth)
 					&tbstr, "\n  PL/Python function \"%s\", line %ld, in %s",
 								 proname, plain_lineno - 1, fname);
 
-			if (PLy_curr_procedure)
+			/* function code object was compiled with "<string>" as the filename */
+			if (PLy_curr_procedure && plain_filename != NULL &&
+				strcmp(plain_filename, "<string>") == 0)
 			{
 				/*
 				 * If we know the current procedure, append the exact line
@@ -4672,7 +4690,8 @@ PLy_traceback(char **xmsg, char **tbmsg, int *tb_depth)
 				 * module behavior.  We could store the already line-split
 				 * source to avoid splitting it every time, but producing a
 				 * traceback is not the most important scenario to optimize
-				 * for.
+				 * for.  But we do not go as far as traceback.py in reading
+				 * the source of imported modules.
 				 */
 				line = get_source_line(PLy_curr_procedure->src, plain_lineno);
 				if (line)
@@ -4687,6 +4706,7 @@ PLy_traceback(char **xmsg, char **tbmsg, int *tb_depth)
 		Py_DECREF(code);
 		Py_DECREF(name);
 		Py_DECREF(lineno);
+		Py_DECREF(filename);
 
 		/* Release the current frame and go to the next one. */
 		tb_prev = tb;