diff --git a/src/pl/plpython/expected/plpython_error.out b/src/pl/plpython/expected/plpython_error.out
index 96bbdfb9586..42003ffd69b 100644
--- a/src/pl/plpython/expected/plpython_error.out
+++ b/src/pl/plpython/expected/plpython_error.out
@@ -458,3 +458,13 @@ ERROR:  error fetching next item from iterator
 DETAIL:  spiexceptions.InvalidDatetimeFormat: invalid value "xy" for "DD"
 CONTEXT:  Traceback (most recent call last):
 PL/Python function "python_error_detail"
+/* test the presently-unsupported case of polymorphic functions
+ */
+CREATE FUNCTION python_poly_ret(x anyelement) RETURNS anyelement AS $$
+  return x
+$$ LANGUAGE plpython3u;
+ERROR:  PL/Python functions cannot return type anyelement
+CREATE FUNCTION python_poly_arg(x anyelement) RETURNS int AS $$
+  return x
+$$ LANGUAGE plpython3u;
+ERROR:  PL/Python functions cannot accept type anyelement
diff --git a/src/pl/plpython/plpy_main.c b/src/pl/plpython/plpy_main.c
index df08d3fbd1b..2a9c2e6d85c 100644
--- a/src/pl/plpython/plpy_main.c
+++ b/src/pl/plpython/plpy_main.c
@@ -10,6 +10,7 @@
 #include "commands/event_trigger.h"
 #include "commands/trigger.h"
 #include "executor/spi.h"
+#include "funcapi.h"
 #include "miscadmin.h"
 #include "plpy_elog.h"
 #include "plpy_exec.h"
@@ -17,7 +18,9 @@
 #include "plpy_plpymodule.h"
 #include "plpy_subxactobject.h"
 #include "plpy_util.h"
+#include "utils/builtins.h"
 #include "utils/guc.h"
+#include "utils/lsyscache.h"
 #include "utils/memutils.h"
 #include "utils/syscache.h"
 
@@ -111,6 +114,11 @@ plpython3_validator(PG_FUNCTION_ARGS)
 	Oid			funcoid = PG_GETARG_OID(0);
 	HeapTuple	tuple;
 	Form_pg_proc procStruct;
+	Oid			rettype;
+	Oid		   *argtypes;
+	char	  **argnames,
+			   *argmodes;
+	int			nargs;
 	PLyTrigType is_trigger;
 	TriggerData trigdata;
 	EventTriggerData etrigdata;
@@ -120,19 +128,56 @@ plpython3_validator(PG_FUNCTION_ARGS)
 	if (!CheckFunctionValidatorAccess(fcinfo->flinfo->fn_oid, funcoid))
 		PG_RETURN_VOID();
 
-	if (!check_function_bodies)
-		PG_RETURN_VOID();
-
 	/* Get the new function's pg_proc entry */
 	tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcoid));
 	if (!HeapTupleIsValid(tuple))
 		elog(ERROR, "cache lookup failed for function %u", funcoid);
 	procStruct = (Form_pg_proc) GETSTRUCT(tuple);
 
+	/* Disallow pseudotype result, except for void or record */
+	rettype = procStruct->prorettype;
+	if (get_typtype(rettype) == TYPTYPE_PSEUDO)
+	{
+		if (rettype == VOIDOID || rettype == RECORDOID)
+			 /* okay */ ;
+		else if (rettype == TRIGGEROID || rettype == EVENT_TRIGGEROID)
+			 /* okay */ ;
+		else
+			ereport(ERROR,
+					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+					 errmsg("PL/Python functions cannot return type %s",
+							format_type_be(rettype))));
+	}
+
+	/* Disallow pseudotype arguments */
+	nargs = get_func_arg_info(tuple, &argtypes, &argnames, &argmodes);
+	for (int i = 0; i < nargs; i++)
+	{
+		if (get_typtype(argtypes[i]) == TYPTYPE_PSEUDO)
+		{
+			if (argmodes &&
+				(argmodes[i] == PROARGMODE_OUT ||
+				 argmodes[i] == PROARGMODE_TABLE))
+				ereport(ERROR,
+						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+						 errmsg("PL/Python functions cannot return type %s",
+								format_type_be(argtypes[i]))));
+			else
+				ereport(ERROR,
+						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+						 errmsg("PL/Python functions cannot accept type %s",
+								format_type_be(argtypes[i]))));
+		}
+	}
+
 	is_trigger = PLy_procedure_is_trigger(procStruct);
 
 	ReleaseSysCache(tuple);
 
+	/* The rest is not needed/wanted if check_function_bodies is off */
+	if (!check_function_bodies)
+		PG_RETURN_VOID();
+
 	/*
 	 * Set up a fake flinfo/fcinfo with just enough info to satisfy
 	 * PLy_procedure_get().  That function derives the call context (plain
diff --git a/src/pl/plpython/plpy_procedure.c b/src/pl/plpython/plpy_procedure.c
index acfc0d8f0f0..ce8b1e099e9 100644
--- a/src/pl/plpython/plpy_procedure.c
+++ b/src/pl/plpython/plpy_procedure.c
@@ -217,36 +217,16 @@ PLy_procedure_create(PLyProcedure *proc,
 		if (is_trigger == PLPY_NOT_TRIGGER)
 		{
 			Oid			rettype = procStruct->prorettype;
-			HeapTuple	rvTypeTup;
-			Form_pg_type rvTypeStruct;
 
-			rvTypeTup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(rettype));
-			if (!HeapTupleIsValid(rvTypeTup))
-				elog(ERROR, "cache lookup failed for type %u", rettype);
-			rvTypeStruct = (Form_pg_type) GETSTRUCT(rvTypeTup);
-
-			/* Disallow pseudotype result, except for void or record */
-			if (rvTypeStruct->typtype == TYPTYPE_PSEUDO)
-			{
-				if (rettype == VOIDOID ||
-					rettype == RECORDOID)
-					 /* okay */ ;
-				else if (rettype == TRIGGEROID || rettype == EVENT_TRIGGEROID)
-					ereport(ERROR,
-							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-							 errmsg("trigger functions can only be called as triggers")));
-				else
-					ereport(ERROR,
-							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-							 errmsg("PL/Python functions cannot return type %s",
-									format_type_be(rettype))));
-			}
+			/* reject if function is in fact a trigger function */
+			if (rettype == TRIGGEROID || rettype == EVENT_TRIGGEROID)
+				ereport(ERROR,
+						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+						 errmsg("trigger functions can only be called as triggers")));
 
 			/* set up output function for procedure result */
 			PLy_output_setup_func(&proc->result, proc->mcxt,
 								  rettype, -1, proc);
-
-			ReleaseSysCache(rvTypeTup);
 		}
 		else
 		{
@@ -296,9 +276,6 @@ PLy_procedure_create(PLyProcedure *proc,
 
 			for (i = pos = 0; i < total; i++)
 			{
-				HeapTuple	argTypeTup;
-				Form_pg_type argTypeStruct;
-
 				if (modes &&
 					(modes[i] == PROARGMODE_OUT ||
 					 modes[i] == PROARGMODE_TABLE))
@@ -306,19 +283,6 @@ PLy_procedure_create(PLyProcedure *proc,
 
 				Assert(types[i] == procStruct->proargtypes.values[pos]);
 
-				argTypeTup = SearchSysCache1(TYPEOID,
-											 ObjectIdGetDatum(types[i]));
-				if (!HeapTupleIsValid(argTypeTup))
-					elog(ERROR, "cache lookup failed for type %u", types[i]);
-				argTypeStruct = (Form_pg_type) GETSTRUCT(argTypeTup);
-
-				/* disallow pseudotype arguments */
-				if (argTypeStruct->typtype == TYPTYPE_PSEUDO)
-					ereport(ERROR,
-							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-							 errmsg("PL/Python functions cannot accept type %s",
-									format_type_be(types[i]))));
-
 				/* set up I/O function info */
 				PLy_input_setup_func(&proc->args[pos], proc->mcxt,
 									 types[i], -1,	/* typmod not known */
@@ -327,8 +291,6 @@ PLy_procedure_create(PLyProcedure *proc,
 				/* get argument name */
 				proc->argnames[pos] = names ? pstrdup(names[i]) : NULL;
 
-				ReleaseSysCache(argTypeTup);
-
 				pos++;
 			}
 		}
diff --git a/src/pl/plpython/sql/plpython_error.sql b/src/pl/plpython/sql/plpython_error.sql
index 9bb1c0b085a..35dd16440c4 100644
--- a/src/pl/plpython/sql/plpython_error.sql
+++ b/src/pl/plpython/sql/plpython_error.sql
@@ -355,3 +355,13 @@ CREATE FUNCTION python_error_detail() RETURNS SETOF text AS $$
 $$ LANGUAGE plpython3u;
 
 SELECT python_error_detail();
+
+/* test the presently-unsupported case of polymorphic functions
+ */
+CREATE FUNCTION python_poly_ret(x anyelement) RETURNS anyelement AS $$
+  return x
+$$ LANGUAGE plpython3u;
+
+CREATE FUNCTION python_poly_arg(x anyelement) RETURNS int AS $$
+  return x
+$$ LANGUAGE plpython3u;
