diff --git a/7.3.966 b/7.3.966
new file mode 100644
index 0000000..6dc6950
--- /dev/null
+++ b/7.3.966
@@ -0,0 +1,301 @@
+To: vim_dev@googlegroups.com
+Subject: Patch 7.3.966
+Fcc: outbox
+From: Bram Moolenaar <Bram@moolenaar.net>
+Mime-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+------------
+
+Patch 7.3.966
+Problem:    There is ":py3do" but no ":pydo".
+Solution:   Add the ":pydo" command. (Lilydjwg)
+Files:	    runtime/doc/if_pyth.txt, src/ex_cmds.h, src/ex_docmd.c,
+	    src/if_py_both.h, src/if_python.c, src/if_python3.c,
+	    src/proto/if_python.pro
+
+
+*** ../vim-7.3.965/runtime/doc/if_pyth.txt	2013-05-17 16:18:27.000000000 +0200
+--- runtime/doc/if_pyth.txt	2013-05-17 16:34:28.000000000 +0200
+***************
+*** 57,62 ****
+--- 57,78 ----
+  Note: Python is very sensitive to the indenting.  Make sure the "class" line
+  and "EOF" do not have any indent.
+  
++ 							*:pydo*
++ :[range]pydo {body}	Execute Python function "def _vim_pydo(line, linenr):
++ 			{body}" for each line in the [range], with the
++ 			function arguments being set to the text of each line
++ 			in turn, without a trailing <EOL>, and the current
++ 			line number. The function should return a string or
++ 			None. If a string is returned, it becomes the text of
++ 			the line in the current turn. The default for [range]
++ 			is the whole file: "1,$".
++ 			{not in Vi}
++ 
++ Examples:
++ >
++ 	:pydo return "%s\t%d" % (line[::-1], len(line))
++ 	:pydo if line: return "%4d: %s" % (linenr, line)
++ <
+  							*:pyfile* *:pyf*
+  :[range]pyf[ile] {file}
+  			Execute the Python script in {file}.  The whole
+***************
+*** 485,511 ****
+  8. Python 3						*python3*
+  
+  							*:py3* *:python3*
+! The |:py3| and |:python3| commands work similar to |:python|.  A simple check
+  if the `:py3` command is working: >
+  	:py3 print("Hello")
+  <							*:py3file*
+! The |:py3file| command works similar to |:pyfile|.
+! 
+  							*:py3do* *E863*
+! :[range]py3do {body}	Execute Python function "def _vim_pydo(line, linenr):
+! 			{body}" for each line in the [range], with the
+! 			function arguments being set to the text of each line
+! 			in turn, without a trailing <EOL>, and the current
+! 			line number. The function should return a string or
+! 			None. If a string is returned, it becomes the text of
+! 			the line in the current turn. The default for [range]
+! 			is the whole file: "1,$".
+! 			{not in Vi}
+  
+- Examples:
+- >
+- 	:py3do return "%s\t%d" % (line[::-1], len(line))
+- 	:py3do if line: return "%4d: %s" % (linenr, line)
+  
+  Vim can be built in four ways (:version output):
+  1. No Python support	    (-python, -python3)
+--- 501,514 ----
+  8. Python 3						*python3*
+  
+  							*:py3* *:python3*
+! The `:py3` and `:python3` commands work similar to `:python`.  A simple check
+  if the `:py3` command is working: >
+  	:py3 print("Hello")
+  <							*:py3file*
+! The `:py3file` command works similar to `:pyfile`.
+  							*:py3do* *E863*
+! The `:py3do` command works similar to `:pydo`.
+  
+  
+  Vim can be built in four ways (:version output):
+  1. No Python support	    (-python, -python3)
+*** ../vim-7.3.965/src/ex_cmds.h	2013-05-15 18:28:08.000000000 +0200
+--- src/ex_cmds.h	2013-05-17 16:29:38.000000000 +0200
+***************
+*** 739,744 ****
+--- 739,746 ----
+  			TRLBAR|CMDWIN),
+  EX(CMD_python,		"python",	ex_python,
+  			RANGE|EXTRA|NEEDARG|CMDWIN),
++ EX(CMD_pydo,		"pydo",		ex_pydo,
++ 			RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN),
+  EX(CMD_pyfile,		"pyfile",	ex_pyfile,
+  			RANGE|FILE1|NEEDARG|CMDWIN),
+  EX(CMD_py3,		"py3",		ex_py3,
+*** ../vim-7.3.965/src/ex_docmd.c	2013-05-15 18:28:08.000000000 +0200
+--- src/ex_docmd.c	2013-05-17 16:29:38.000000000 +0200
+***************
+*** 268,273 ****
+--- 268,274 ----
+  #endif
+  #ifndef FEAT_PYTHON
+  # define ex_python		ex_script_ni
++ # define ex_pydo		ex_ni
+  # define ex_pyfile		ex_ni
+  #endif
+  #ifndef FEAT_PYTHON3
+*** ../vim-7.3.965/src/if_py_both.h	2013-05-17 16:24:27.000000000 +0200
+--- src/if_py_both.h	2013-05-17 16:29:38.000000000 +0200
+***************
+*** 22,27 ****
+--- 22,28 ----
+  #else
+  # define ENC_OPT "latin1"
+  #endif
++ #define DOPY_FUNC "_vim_pydo"
+  
+  #define PyErr_SetVim(str) PyErr_SetString(VimError, str)
+  
+*** ../vim-7.3.965/src/if_python.c	2013-05-17 16:18:27.000000000 +0200
+--- src/if_python.c	2013-05-17 16:29:38.000000000 +0200
+***************
+*** 198,203 ****
+--- 198,206 ----
+  # define PyModule_GetDict dll_PyModule_GetDict
+  # define PyRun_SimpleString dll_PyRun_SimpleString
+  # define PyRun_String dll_PyRun_String
++ # define PyObject_GetAttrString dll_PyObject_GetAttrString
++ # define PyObject_SetAttrString dll_PyObject_SetAttrString
++ # define PyObject_CallFunctionObjArgs dll_PyObject_CallFunctionObjArgs
+  # define PyString_AsString dll_PyString_AsString
+  # define PyString_AsStringAndSize dll_PyString_AsStringAndSize
+  # define PyString_FromString dll_PyString_FromString
+***************
+*** 303,308 ****
+--- 306,314 ----
+  static PyObject*(*dll_PyModule_GetDict)(PyObject *);
+  static int(*dll_PyRun_SimpleString)(char *);
+  static PyObject *(*dll_PyRun_String)(char *, int, PyObject *, PyObject *);
++ static PyObject* (*dll_PyObject_GetAttrString)(PyObject *, const char *);
++ static PyObject* (*dll_PyObject_SetAttrString)(PyObject *, const char *, PyObject *);
++ static PyObject* (*dll_PyObject_CallFunctionObjArgs)(PyObject *, ...);
+  static char*(*dll_PyString_AsString)(PyObject *);
+  static int(*dll_PyString_AsStringAndSize)(PyObject *, char **, int *);
+  static PyObject*(*dll_PyString_FromString)(const char *);
+***************
+*** 440,445 ****
+--- 446,454 ----
+      {"PyModule_GetDict", (PYTHON_PROC*)&dll_PyModule_GetDict},
+      {"PyRun_SimpleString", (PYTHON_PROC*)&dll_PyRun_SimpleString},
+      {"PyRun_String", (PYTHON_PROC*)&dll_PyRun_String},
++     {"PyObject_GetAttrString", (PYTHON_PROC*)&dll_PyObject_GetAttrString},
++     {"PyObject_SetAttrString", (PYTHON_PROC*)&dll_PyObject_SetAttrString},
++     {"PyObject_CallFunctionObjArgs", (PYTHON_PROC*)&dll_PyObject_CallFunctionObjArgs},
+      {"PyString_AsString", (PYTHON_PROC*)&dll_PyString_AsString},
+      {"PyString_AsStringAndSize", (PYTHON_PROC*)&dll_PyString_AsStringAndSize},
+      {"PyString_FromString", (PYTHON_PROC*)&dll_PyString_FromString},
+***************
+*** 995,1000 ****
+--- 1004,1096 ----
+      DoPythonCommand(eap, buffer, NULL);
+  }
+  
++     void
++ ex_pydo(exarg_T *eap)
++ {
++     linenr_T		i;
++     const char		*code_hdr = "def " DOPY_FUNC "(line, linenr):\n ";
++     const char		*s = (const char *) eap->arg;
++     size_t		len;
++     char		*code;
++     int			status;
++     PyObject		*pyfunc, *pymain;
++     PyGILState_STATE	pygilstate;
++ 
++     if (Python_Init())
++         return;
++ 
++     if (u_save(eap->line1 - 1, eap->line2 + 1) != OK)
++     {
++ 	EMSG(_("cannot save undo information"));
++ 	return;
++     }
++     len = strlen(code_hdr) + strlen(s);
++     code = malloc(len + 1);
++     STRCPY(code, code_hdr);
++     STRNCAT(code, s, len + 1);
++     pygilstate = PyGILState_Ensure();
++     status = PyRun_SimpleString(code);
++     vim_free(code);
++     if (status)
++     {
++ 	EMSG(_("failed to run the code"));
++ 	return;
++     }
++     status = 0; /* good */
++     pymain = PyImport_AddModule("__main__");
++     pyfunc = PyObject_GetAttrString(pymain, DOPY_FUNC);
++     PyGILState_Release(pygilstate);
++ 
++     for (i = eap->line1; i <= eap->line2; i++)
++     {
++ 	const char *line;
++ 	PyObject *pyline, *pylinenr, *pyret;
++ 
++ 	line = (char *)ml_get(i);
++ 	pygilstate = PyGILState_Ensure();
++ 	pyline = PyString_FromStringAndSize(line, strlen(line));
++ 	pylinenr = PyLong_FromLong(i);
++ 	pyret = PyObject_CallFunctionObjArgs(pyfunc, pyline, pylinenr, NULL);
++ 	Py_DECREF(pyline);
++ 	Py_DECREF(pylinenr);
++ 	if (!pyret)
++ 	{
++ 	    PyErr_PrintEx(0);
++ 	    PythonIO_Flush();
++ 	    status = 1;
++ 	    goto out;
++ 	}
++ 
++ 	if (pyret && pyret != Py_None)
++ 	{
++ 	    if (!PyString_Check(pyret))
++ 	    {
++ 		EMSG(_("E863: return value must be an instance of str"));
++ 		Py_XDECREF(pyret);
++ 		status = 1;
++ 		goto out;
++ 	    }
++ 	    ml_replace(i, (char_u *) PyString_AsString(pyret), 1);
++ 	    changed();
++ #ifdef SYNTAX_HL
++ 	    syn_changed(i); /* recompute syntax hl. for this line */
++ #endif
++ 	}
++ 	Py_XDECREF(pyret);
++ 	PythonIO_Flush();
++ 	PyGILState_Release(pygilstate);
++     }
++     pygilstate = PyGILState_Ensure();
++ out:
++     Py_DECREF(pyfunc);
++     PyObject_SetAttrString(pymain, DOPY_FUNC, NULL);
++     PyGILState_Release(pygilstate);
++     if (status)
++ 	return;
++     check_cursor();
++     update_curbuf(NOT_VALID);
++ }
++ 
+  /******************************************************
+   * 2. Python output stream: writes output via [e]msg().
+   */
+*** ../vim-7.3.965/src/if_python3.c	2013-05-17 16:18:27.000000000 +0200
+--- src/if_python3.c	2013-05-17 16:29:38.000000000 +0200
+***************
+*** 76,82 ****
+  #else
+  # define CODEC_ERROR_HANDLER NULL
+  #endif
+- #define DOPY_FUNC "_vim_pydo"
+  
+  /* Python 3 does not support CObjects, always use Capsules */
+  #define PY_USE_CAPSULE
+--- 76,81 ----
+*** ../vim-7.3.965/src/proto/if_python.pro	2013-05-15 15:12:25.000000000 +0200
+--- src/proto/if_python.pro	2013-05-17 16:29:38.000000000 +0200
+***************
+*** 3,8 ****
+--- 3,9 ----
+  void python_end __ARGS((void));
+  int python_loaded __ARGS((void));
+  void ex_python __ARGS((exarg_T *eap));
++ void ex_pydo __ARGS((exarg_T *eap));
+  void ex_pyfile __ARGS((exarg_T *eap));
+  void python_buffer_free __ARGS((buf_T *buf));
+  void python_window_free __ARGS((win_T *win));
+*** ../vim-7.3.965/src/version.c	2013-05-17 16:24:27.000000000 +0200
+--- src/version.c	2013-05-17 16:39:19.000000000 +0200
+***************
+*** 730,731 ****
+--- 730,733 ----
+  {   /* Add new patch number below this line */
++ /**/
++     966,
+  /**/
+
+-- 
+A hamburger walks into a bar, and the bartender says: "I'm sorry,
+but we don't serve food here."
+
+ /// Bram Moolenaar -- Bram@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    ///