#Checkpointing X/Emacs 20'fication of this mode.
diff --git a/Misc/python-mode.el b/Misc/python-mode.el
index bdeaa2b..2905006 100644
--- a/Misc/python-mode.el
+++ b/Misc/python-mode.el
@@ -9,6 +9,9 @@
 ;; Version:       3.0
 ;; Keywords: python languages oop
 
+(defconst py-version "3.0"
+  "`python-mode' version number.")
+
 ;; This software is provided as-is, without express or implied
 ;; warranty.  Permission to use, copy, modify, distribute or sell this
 ;; software, without fee, for any purpose and by any individual or
@@ -27,7 +30,7 @@
 ;; 18 support.  But all in all, the mode works exceedingly well, and
 ;; I've simply been tweaking it as I go along.  Ain't it wonderful
 ;; that Python has a much more sane syntax than C? (or <shudder> C++?!
-;; :-).  I can say that; I maintain cc-mode!
+;; :-).  I can say that; I maintain CC Mode!
 
 ;; The following statements, placed in your .emacs file or
 ;; site-init.el, will cause this file to be autoloaded, and
@@ -96,36 +99,51 @@
 
 ;;; Code:
 
+(require 'custom)
+
 
 ;; user definable variables
 ;; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
 
-(defvar py-python-command "python"
-  "*Shell command used to start Python interpreter.")
+(defgroup python nil
+  "Support for the Python programming language, <http://www.python.org/>"
+  :group 'languages)
 
-(defvar py-indent-offset 4
-  "*Indentation increment.
+(defcustom py-python-command "python"
+  "*Shell command used to start Python interpreter."
+  :type 'string
+  :group 'python)
+
+(defcustom py-indent-offset 4
+  "*Amount of offset per level of indentation
 Note that `\\[py-guess-indent-offset]' can usually guess a good value
-when you're editing someone else's Python code.")
+when you're editing someone else's Python code."
+  :type 'integer
+  :group 'python)
 
-(defvar py-align-multiline-strings-p t
-  "*Flag describing how multiline triple quoted strings are aligned.
+(defcustom py-align-multiline-strings-p t
+  "*Flag describing how multi-line triple quoted strings are aligned.
 When this flag is non-nil, continuation lines are lined up under the
 preceding line's indentation.  When this flag is nil, continuation
-lines are aligned to column zero.")
+lines are aligned to column zero."
+  :type '(choice (const :tag "Align under preceding line" t)
+		 (const :tag "Align to column zero" nil))
+  :group 'python)
 
-(defvar py-block-comment-prefix "## "
+(defcustom py-block-comment-prefix "## "
   "*String used by \\[comment-region] to comment out a block of code.
 This should follow the convention for non-indenting comment lines so
 that the indentation commands won't get confused (i.e., the string
 should be of the form `#x...' where `x' is not a blank or a tab, and
-`...' is arbitrary).")
+`...' is arbitrary)."
+  :type 'string
+  :group 'python)
 
-(defvar py-honor-comment-indentation t
+(defcustom py-honor-comment-indentation t
   "*Controls how comment lines influence subsequent indentation.
 
 When nil, all comment lines are skipped for indentation purposes, and
-in Emacs 19, a faster algorithm is used.
+if possible, a faster algorithm is used (i.e. X/Emacs 19 and beyond).
 
 When t, lines that begin with a single `#' are a hint to subsequent
 line indentation.  If the previous line is such a comment line (as
@@ -135,9 +153,15 @@
 purposes.
 
 When not nil or t, comment lines that begin with a `#' are used as
-indentation hints, unless the comment character is in column zero.")
+indentation hints, unless the comment character is in column zero."
+  :type '(choice
+	  (const :tag "Skip all comment lines (fast)" nil)
+	  (const :tag "Single # `sets' indentation for next line" t)
+	  (const :tag "Single # `sets' indentation except at column zero" other)
+	  )
+  :group 'python)
 
-(defvar py-scroll-process-buffer t
+(defcustom py-scroll-process-buffer t
   "*Scroll Python process buffer as output arrives.
 If nil, the Python process buffer acts, with respect to scrolling, like
 Shell-mode buffers normally act.  This is surprisingly complicated and
@@ -175,7 +199,9 @@
 
 Obscure:  `End of buffer' above should really say `at or beyond the
 process mark', but if you know what that means you didn't need to be
-told <grin>.")
+told <grin>."
+  :type 'boolean
+  :group 'python)
 
 (defvar py-temp-directory
   (let ((ok '(lambda (x)
@@ -193,7 +219,9 @@
   "*Directory used for temp files created by a *Python* process.
 By default, the first directory from this list that exists and that you
 can write into:  the value (if any) of the environment variable TMPDIR,
-/usr/tmp, /tmp, or the current directory.")
+/usr/tmp, /tmp, or the current directory."
+  :type 'string
+  :group 'python)
 
 (defvar py-beep-if-tab-change t
   "*Ring the bell if tab-width is changed.
@@ -205,7 +233,34 @@
 current value of (the general Emacs variable) `tab-width' does not
 equal <number>, `tab-width' is set to <number>, a message saying so is
 displayed in the echo area, and if `py-beep-if-tab-change' is non-nil
-the Emacs bell is also rung as a warning.")
+the Emacs bell is also rung as a warning."
+  :type 'boolean
+  :group 'python)
+
+
+;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+;; NO USER DEFINABLE VARIABLES BEYOND THIS POINT
+
+;; As of 30-Jan-1997, Emacs 19.34 works but XEmacs 19.15b90 and
+;; previous does not.  It is suspected that Emacsen before 19.34 are
+;; also broken.
+(defvar py-parse-partial-sexp-works-p
+  (let ((buf (get-buffer-create " ---*---pps---*---"))
+	state status)
+    (save-excursion
+      (set-buffer buf)
+      (erase-buffer)
+      (insert "(line1\n line2)\nline3")
+      (lisp-mode)
+      (goto-char (point-min))
+      (setq state (parse-partial-sexp (point) (save-excursion
+						(forward-line 1)
+						(point))))
+      (parse-partial-sexp (point) (point-max) 0 nil state)
+      (setq status (not (= (point) (point-max))))
+      (kill-buffer buf)
+      status))
+  "Does `parse-partial-sexp' work in this Emacs?")
 
 (defvar python-font-lock-keywords
   (let* ((keywords '("and"        "break"      "class"
@@ -240,29 +295,98 @@
   "*Controls echoing of arguments of functions & methods in the imenu buffer.
 When non-nil, arguments are printed.")
 
-
-
-;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-;; NO USER DEFINABLE VARIABLES BEYOND THIS POINT
-
 (make-variable-buffer-local 'py-indent-offset)
 
-;; Differentiate between Emacs 18, Lucid Emacs, and Emacs 19.  This
-;; seems to be the standard way of checking this.
-;; BAW - This is *not* the right solution.  When at all possible,
-;; instead of testing for the version of Emacs, use feature tests.
-
-(setq py-this-is-lucid-emacs-p (string-match "Lucid\\|XEmacs" emacs-version))
-(setq py-this-is-emacs-19-p
-      (and
-       (not py-this-is-lucid-emacs-p)
-       (string-match "^19\\." emacs-version)))
-
 ;; have to bind py-file-queue before installing the kill-emacs hook
 (defvar py-file-queue nil
   "Queue of Python temp files awaiting execution.
 Currently-active file is at the head of the list.")
 
+(defvar py-delete-function 'backward-delete-char-untabify
+  "*Function called by `py-delete-char' when deleting characters.")
+
+(defvar py-backspace-function 'backward-delete-char-untabify
+  "*Function called by `py-backspace-command' when deleting characters.")
+
+
+;; Constants
+
+;; Regexp matching a Python string literal
+(defconst py-stringlit-re
+  (concat
+   "'\\([^'\n\\]\\|\\\\.\\)*'"		; single-quoted
+   "\\|"				; or
+   "\"\\([^\"\n\\]\\|\\\\.\\)*\""))	; double-quoted
+
+;; Regexp matching Python lines that are continued via backslash.
+;; This is tricky because a trailing backslash does not mean
+;; continuation if it's in a comment
+(defconst py-continued-re
+  (concat
+   "\\(" "[^#'\"\n\\]" "\\|" py-stringlit-re "\\)*"
+   "\\\\$"))
+  
+;; Regexp matching blank or comment lines.
+(defconst py-blank-or-comment-re "[ \t]*\\($\\|#\\)")
+
+;; Regexp matching clauses to be outdented one level.
+(defconst py-outdent-re
+  (concat "\\(" (mapconcat 'identity
+			   '("else:"
+			     "except\\(\\s +.*\\)?:"
+			     "finally:"
+			     "elif\\s +.*:")
+			   "\\|")
+	  "\\)"))
+  
+
+;; Regexp matching lines to not outdent after.
+(defconst py-no-outdent-re
+  (concat "\\(" (mapconcat 'identity
+			   '("try:"
+			     "except\\(\\s +.*\\)?:"
+			     "while\\s +.*:"
+			     "for\\s +.*:"
+			     "if\\s +.*:"
+			     "elif\\s +.*:"
+			     "\\(return\\|break\\|raise\\|continue\\)[ \t\n]"
+			     )
+			   "\\|")
+	  "\\)"))
+
+;; Regexp matching a function, method or variable assignment.  If you
+;; change this, you probably have to change `py-current-defun' as
+;; well.  This is only used by `py-current-defun' to find the name for
+;; add-log.el.
+(defvar py-defun-start-re
+  "^\\([ \t]*\\)def[ \t]+\\([a-zA-Z_0-9]+\\)\\|\\(^[a-zA-Z_0-9]+\\)[ \t]*=")
+
+;; Regexp for finding a class name.  If you change this, you probably
+;; have to change `py-current-defun' as well.  This is only used by
+;; `py-current-defun' to find the name for add-log.el.
+(defvar py-class-start-re "^class[ \t]*\\([a-zA-Z_0-9]+\\)")
+
+
+
+;; Utilities
+
+(defmacro py-safe (&rest body)
+  ;; safely execute BODY, return nil if an error occurred
+  (` (condition-case nil
+	 (progn (,@ body))
+       (error nil))))
+
+(defsubst py-keep-region-active ()
+  ;; Do whatever is necessary to keep the region active in XEmacs.
+  ;; Ignore byte-compiler warnings you might see.  Also note that
+  ;; FSF's Emacs 19 does it differently; its policy doesn't require us
+  ;; to take explicit action.
+  (and (boundp 'zmacs-region-stays)
+       (setq zmacs-region-stays t)))
+
+
+;; Major mode boilerplate
+
 ;; define a mode-specific abbrev table for those who use such things
 (defvar python-mode-abbrev-table nil
   "Abbrev table in use in `python-mode' buffers.")
@@ -276,14 +400,10 @@
 (and (fboundp 'make-obsolete-variable)
      (make-obsolete-variable 'py-mode-hook 'python-mode-hook))
 
-(defvar py-delete-function 'backward-delete-char-untabify
-  "*Function called by `py-delete-char' when deleting characters.")
-
 (defvar py-mode-map ()
   "Keymap used in `python-mode' buffers.")
-
 (if py-mode-map
-    ()
+    nil
   (setq py-mode-map (make-sparse-keymap))
 
   ;; shadow global bindings for newline-and-indent w/ the py- version.
@@ -328,148 +448,81 @@
 
 (defvar py-mode-syntax-table nil
   "Syntax table used in `python-mode' buffers.")
-
 (if py-mode-syntax-table
-    ()
+    nil
   (setq py-mode-syntax-table (make-syntax-table))
-  ;; BAW - again, blech.
-  (mapcar (function
-	   (lambda (x) (modify-syntax-entry
-			(car x) (cdr x) py-mode-syntax-table)))
-	  '(( ?\( . "()" ) ( ?\) . ")(" )
-	    ( ?\[ . "(]" ) ( ?\] . ")[" )
-	    ( ?\{ . "(}" ) ( ?\} . "){" )
-	    ;; fix operator symbols misassigned in the std table
-	    ( ?\$ . "." ) ( ?\% . "." ) ( ?\& . "." )
-	    ( ?\* . "." ) ( ?\+ . "." ) ( ?\- . "." )
-	    ( ?\/ . "." ) ( ?\< . "." ) ( ?\= . "." )
-	    ( ?\> . "." ) ( ?\| . "." )
-	    ;; for historical reasons, underscore is word class
-	    ;; instead of symbol class.  it should be symbol class,
-	    ;; but if you're tempted to change it, try binding M-f and
-	    ;; M-b to py-forward-into-nomenclature and
-	    ;; py-backward-into-nomenclature instead. -baw
-	    ( ?\_ . "w" )	; underscore is legit in words
-	    ( ?\' . "\"")	; single quote is string quote
-	    ( ?\" . "\"" )	; double quote is string quote too
-	    ( ?\` . "$")	; backquote is open and close paren
-	    ( ?\# . "<")	; hash starts comment
-	    ( ?\n . ">"))))	; newline ends comment
+  (modify-syntax-entry ?\( "()" py-mode-syntax-table)
+  (modify-syntax-entry ?\) ")(" py-mode-syntax-table)
+  (modify-syntax-entry ?\[ "(]" py-mode-syntax-table)
+  (modify-syntax-entry ?\] ")[" py-mode-syntax-table)
+  (modify-syntax-entry ?\{ "(}" py-mode-syntax-table)
+  (modify-syntax-entry ?\} "){" py-mode-syntax-table)
+  ;; Add operator symbols misassigned in the std table
+  (modify-syntax-entry ?\$ "."  py-mode-syntax-table)
+  (modify-syntax-entry ?\% "."  py-mode-syntax-table)
+  (modify-syntax-entry ?\& "."  py-mode-syntax-table)
+  (modify-syntax-entry ?\* "."  py-mode-syntax-table)
+  (modify-syntax-entry ?\+ "."  py-mode-syntax-table)
+  (modify-syntax-entry ?\- "."  py-mode-syntax-table)
+  (modify-syntax-entry ?\/ "."  py-mode-syntax-table)
+  (modify-syntax-entry ?\< "."  py-mode-syntax-table)
+  (modify-syntax-entry ?\= "."  py-mode-syntax-table)
+  (modify-syntax-entry ?\> "."  py-mode-syntax-table)
+  (modify-syntax-entry ?\| "."  py-mode-syntax-table)
+  ;; For historical reasons, underscore is word class instead of
+  ;; symbol class.  GNU conventions say it should be symbol class, but
+  ;; there's a natural conflict between what major mode authors want
+  ;; and what users expect from `forward-word' and `backward-word'.
+  ;; Guido and I have hashed this out and have decided to keep
+  ;; underscore in word class.  If you're tempted to change it, try
+  ;; binding M-f and M-b to py-forward-into-nomenclature and
+  ;; py-backward-into-nomenclature instead.
+  (modify-syntax-entry ?\_ "w"  py-mode-syntax-table)
+  ;; Both single quote and double quote are string delimiters
+  (modify-syntax-entry ?\' "\"" py-mode-syntax-table)
+  (modify-syntax-entry ?\" "\"" py-mode-syntax-table)
+  ;; backquote is open and close paren
+  (modify-syntax-entry ?\` "$"  py-mode-syntax-table)
+  ;; comment delimiters
+  (modify-syntax-entry ?\# "<"  py-mode-syntax-table)
+  (modify-syntax-entry ?\n ">"  py-mode-syntax-table)
+  )
 
-(defconst py-stringlit-re
-  (concat
-   "'\\([^'\n\\]\\|\\\\.\\)*'"		; single-quoted
-   "\\|"				; or
-   "\"\\([^\"\n\\]\\|\\\\.\\)*\"")	; double-quoted
-  "Regexp matching a Python string literal.")
-
-;; this is tricky because a trailing backslash does not mean
-;; continuation if it's in a comment
-(defconst py-continued-re
-  (concat
-   "\\(" "[^#'\"\n\\]" "\\|" py-stringlit-re "\\)*"
-   "\\\\$")
-  "Regexp matching Python lines that are continued via backslash.")
-
-(defconst py-blank-or-comment-re "[ \t]*\\($\\|#\\)"
-  "Regexp matching blank or comment lines.")
-
-(defconst py-outdent-re
-  (concat "\\(" (mapconcat 'identity
-			   '("else:"
-			     "except\\(\\s +.*\\)?:"
-			     "finally:"
-			     "elif\\s +.*:")
-			   "\\|")
-	  "\\)")
-  "Regexp matching clauses to be outdented one level.")
-
-(defconst py-no-outdent-re
-  (concat "\\(" (mapconcat 'identity
-			   '("try:"
-			     "except\\(\\s +.*\\)?:"
-			     "while\\s +.*:"
-			     "for\\s +.*:"
-			     "if\\s +.*:"
-			     "elif\\s +.*:"
-			     "\\(return\\|break\\|raise\\|continue\\)[ \t\n]"
-			     )
-			   "\\|")
-	  "\\)")
-  "Regexp matching lines to not outdent after.")
-
-(defvar py-defun-start-re
-  "^\\([ \t]*\\)def[ \t]+\\([a-zA-Z_0-9]+\\)\\|\\(^[a-zA-Z_0-9]+\\)[ \t]*="
-  "Regexp matching a function, method or variable assignment.
-
-If you change this, you probably have to change `py-current-defun' as well.
-This is only used by `py-current-defun' to find the name for add-log.el.")
-
-(defvar py-class-start-re "^class[ \t]*\\([a-zA-Z_0-9]+\\)"
-  "Regexp for finding a class name.
-
-If you change this, you probably have to change `py-current-defun' as well.
-This is only used by `py-current-defun' to find the name for add-log.el.")
-
-;; As of 30-Jan-1997, Emacs 19.34 works but XEmacs 19.15b90 and
-;; previous does not.  It is suspected that Emacsen before 19.34 are
-;; also broken.
-(defvar py-parse-partial-sexp-works-p
-  (let ((buf (get-buffer-create " ---*---pps---*---"))
-	state status)
-    (save-excursion
-      (set-buffer buf)
-      (erase-buffer)
-      (insert "(line1\n line2)\nline3")
-      (lisp-mode)
-      (goto-char (point-min))
-      (setq state (parse-partial-sexp (point) (save-excursion
-						(forward-line 1)
-						(point))))
-      (parse-partial-sexp (point) (point-max) 0 nil state)
-      (setq status (not (= (point) (point-max))))
-      (kill-buffer buf)
-      status))
-  "Does `parse-partial-sexp' work in this Emacs?")
 
 
 ;; Menu definitions, only relevent if you have the easymenu.el package
 ;; (standard in the latest Emacs 19 and XEmacs 19 distributions).
 (defvar py-menu nil
   "Menu for Python Mode.
+This menu will get created automatically if you have the `easymenu'
+package.  Note that the latest X/Emacs releases contain this package.")
 
-This menu will get created automatically if you have the easymenu
-package.  Note that the latest XEmacs 19 and Emacs 19 versions contain
-this package.")
-
-(if (condition-case nil
-	(require 'easymenu)
-      (error nil))
-    (easy-menu-define
-     py-menu py-mode-map "Python Mode menu"
-     '("Python"
-       ["Comment Out Region"   py-comment-region  (mark)]
-       ["Uncomment Region"     (py-comment-region (point) (mark) '(4)) (mark)]
-       "-"
-       ["Mark current block"   py-mark-block t]
-       ["Mark current def"     mark-python-def-or-class t]
-       ["Mark current class"   (mark-python-def-or-class t) t]
-       "-"
-       ["Shift region left"    py-shift-region-left (mark)]
-       ["Shift region right"   py-shift-region-right (mark)]
-       "-"
-       ["Execute buffer"       py-execute-buffer t]
-       ["Execute region"       py-execute-region (mark)]
-       ["Start interpreter..." py-shell t]
-       "-"
-       ["Go to start of block" py-goto-block-up t]
-       ["Go to start of class" (beginning-of-python-def-or-class t) t]
-       ["Move to end of class" (end-of-python-def-or-class t) t]
-       ["Move to start of def" beginning-of-python-def-or-class t]
-       ["Move to end of def"   end-of-python-def-or-class t]
-       "-"
-       ["Describe mode"        py-describe-mode t]
-       )))
+(and (py-safe (require 'easymenu) t)
+     (easy-menu-define
+      py-menu py-mode-map "Python Mode menu"
+      '("Python"
+	["Comment Out Region"   py-comment-region  (mark)]
+	["Uncomment Region"     (py-comment-region (point) (mark) '(4)) (mark)]
+	"-"
+	["Mark current block"   py-mark-block t]
+	["Mark current def"     mark-python-def-or-class t]
+	["Mark current class"   (mark-python-def-or-class t) t]
+	"-"
+	["Shift region left"    py-shift-region-left (mark)]
+	["Shift region right"   py-shift-region-right (mark)]
+	"-"
+	["Execute buffer"       py-execute-buffer t]
+	["Execute region"       py-execute-region (mark)]
+	["Start interpreter..." py-shell t]
+	"-"
+	["Go to start of block" py-goto-block-up t]
+	["Go to start of class" (beginning-of-python-def-or-class t) t]
+	["Move to end of class" (end-of-python-def-or-class t) t]
+	["Move to start of def" beginning-of-python-def-or-class t]
+	["Move to end of def"   end-of-python-def-or-class t]
+	"-"
+	["Describe mode"        py-describe-mode t]
+	)))
 
 
 
@@ -734,7 +787,7 @@
   (if py-menu
       (easy-menu-add py-menu))
   ;; Emacs 19 requires this
-  (if (or py-this-is-lucid-emacs-p py-this-is-emacs-19-p)
+  (if (boundp 'comment-multi-line)
       (setq comment-multi-line nil))
   ;; hack to allow overriding the tabsize in the file (see tokenizer.c)
   ;;
@@ -774,15 +827,6 @@
     (run-hooks 'py-mode-hook)))
 
 
-(defun py-keep-region-active ()
-  ;; do whatever is necessary to keep the region active in XEmacs.
-  ;; Ignore byte-compiler warnings you might see.  Also note that
-  ;; FSF's Emacs 19 does it differently and doesn't its policy doesn't
-  ;; require us to take explicit action.
-  (and (boundp 'zmacs-region-stays)
-       (setq zmacs-region-stays t)))
-
-
 ;; electric characters
 (defun py-outdent-p ()
   ;; returns non-nil if the current line should outdent one level
@@ -796,7 +840,6 @@
 		(not (looking-at py-no-outdent-re)))
 	 )))
       
-
 (defun py-electric-colon (arg)
   "Insert a colon.
 In certain cases the line is outdented appropriately.  If a numeric
@@ -2352,13 +2395,9 @@
 
 (defun py-kill-emacs-hook ()
   ;; delete our temp files
-  (while py-file-queue
-    (py-delete-file-silently (car py-file-queue))
-    (setq py-file-queue (cdr py-file-queue)))
-  (if (not (or py-this-is-lucid-emacs-p py-this-is-emacs-19-p))
-      ;; run the hook we inherited, if any
-      (and py-inherited-kill-emacs-hook
-	   (funcall py-inherited-kill-emacs-hook))))
+  (py-safe (while py-file-queue
+	     (py-delete-file-silently (car py-file-queue))
+	     (setq py-file-queue (cdr py-file-queue)))))
 
 ;; make PROCESS's buffer visible, append STRING to it, and force
 ;; display; also make shell-mode believe the user typed this string,
@@ -2371,13 +2410,7 @@
     (set-buffer pbuf)
     (goto-char (point-max))
     (move-marker (process-mark process) (point))
-    (if (not (or py-this-is-emacs-19-p
-		 py-this-is-lucid-emacs-p))
-	(move-marker last-input-start (point))) ; muck w/ shell-mode
     (funcall (process-filter process) process string)
-    (if (not (or py-this-is-emacs-19-p
-		 py-this-is-lucid-emacs-p))
-	(move-marker last-input-end (point))) ; muck w/ shell-mode
     (set-buffer cbuf))
   (sit-for 0))
 
@@ -2403,8 +2436,6 @@
       nil)))
 
 
-(defconst py-version "$Revision$"
-  "`python-mode' version number.")
 (defconst py-help-address "python-mode@python.org"
   "Address accepting submission of bug reports.")
 
@@ -2453,17 +2484,7 @@
 
 
 ;; arrange to kill temp files when Emacs exists
-(if (or py-this-is-emacs-19-p py-this-is-lucid-emacs-p)
-    (add-hook 'kill-emacs-hook 'py-kill-emacs-hook)
-  ;; have to trust that other people are as respectful of our hook
-  ;; fiddling as we are of theirs
-  (if (boundp 'py-inherited-kill-emacs-hook)
-      ;; we were loaded before -- trust others not to have screwed us
-      ;; in the meantime (no choice, really)
-      nil
-    ;; else arrange for our hook to run theirs
-    (setq py-inherited-kill-emacs-hook kill-emacs-hook)
-    (setq kill-emacs-hook 'py-kill-emacs-hook)))
+(add-hook 'kill-emacs-hook 'py-kill-emacs-hook)