Cleaned up/simplified error-handling:
  - DistutilsOptionError is now documented as it's actually used, ie.
    to indicate bogus option values (usually user options, eg. from
    the command-line)
  - added DistutilsSetupError to indicate errors that definitely arise
    in the setup script
  - got rid of DistutilsValueError, and changed all usage of it to
    either DistutilsSetupError or ValueError as appropriate
  - simplified a bunch of option get/set methods in Command and
    Distribution classes -- just pass on AttributeError most of
    the time, rather than turning it into something else
diff --git a/Lib/distutils/cmd.py b/Lib/distutils/cmd.py
index b3d1664..d8e4137 100644
--- a/Lib/distutils/cmd.py
+++ b/Lib/distutils/cmd.py
@@ -161,38 +161,28 @@
 
     def get_option (self, option):
         """Return the value of a single option for this command.  Raise
-           DistutilsOptionError if 'option' is not known."""
-        try:
-            return getattr (self, option)
-        except AttributeError:
-            raise DistutilsOptionError, \
-                  "command %s: no such option %s" % \
-                  (self.get_command_name(), option)
+           AttributeError if 'option' is not known."""
+        return getattr (self, option)
 
 
     def get_options (self, *options):
         """Return (as a tuple) the values of several options for this
-           command.  Raise DistutilsOptionError if any of the options in
+           command.  Raise AttributeError if any of the options in
            'options' are not known."""
 
         values = []
-        try:
-            for opt in options:
-                values.append (getattr (self, opt))
-        except AttributeError, name:
-            raise DistutilsOptionError, \
-                  "command %s: no such option %s" % \
-                  (self.get_command_name(), name)
-            
+        for opt in options:
+            values.append (getattr (self, opt))
+
         return tuple (values)
-    
+
 
     def set_option (self, option, value):
         """Set the value of a single option for this command.  Raise
-           DistutilsOptionError if 'option' is not known."""
+           AttributeError if 'option' is not known."""
 
         if not hasattr (self, option):
-            raise DistutilsOptionError, \
+            raise AttributeError, \
                   "command '%s': no such option '%s'" % \
                   (self.get_command_name(), option)
         if value is not None:
@@ -200,7 +190,7 @@
 
     def set_options (self, **optval):
         """Set the values of several options for this command.  Raise
-           DistutilsOptionError if any of the options specified as
+           AttributeError if any of the options specified as
            keyword arguments are not known."""
 
         for k in optval.keys():
@@ -236,14 +226,10 @@
 
         src_cmd_obj = self.distribution.find_command_obj (src_cmd)
         src_cmd_obj.ensure_ready ()
-        try:
-            for (src_option, dst_option) in option_pairs:
-                if getattr (self, dst_option) is None:
-                    self.set_option (dst_option,
-                                     src_cmd_obj.get_option (src_option))
-        except AttributeError, name:
-            # duh, which command?
-            raise DistutilsOptionError, "unknown option %s" % name
+        for (src_option, dst_option) in option_pairs:
+            if getattr (self, dst_option) is None:
+                self.set_option (dst_option,
+                                 src_cmd_obj.get_option (src_option))
 
 
     def find_peer (self, command, create=1):
diff --git a/Lib/distutils/command/build_clib.py b/Lib/distutils/command/build_clib.py
index 2311187..3117073 100644
--- a/Lib/distutils/command/build_clib.py
+++ b/Lib/distutils/command/build_clib.py
@@ -115,33 +115,33 @@
         """Ensure that the list of libraries (presumably provided as a
            command option 'libraries') is valid, i.e. it is a list of
            2-tuples, where the tuples are (library_name, build_info_dict).
-           Raise DistutilsValueError if the structure is invalid anywhere;
+           Raise DistutilsSetupError if the structure is invalid anywhere;
            just returns otherwise."""
 
         # Yechh, blecch, ackk: this is ripped straight out of build_ext.py,
         # with only names changed to protect the innocent!
 
         if type (libraries) is not ListType:
-            raise DistutilsValueError, \
+            raise DistutilsSetupError, \
                   "'libraries' option must be a list of tuples"
 
         for lib in libraries:
             if type (lib) is not TupleType and len (lib) != 2:
-                raise DistutilsValueError, \
+                raise DistutilsSetupError, \
                       "each element of 'libraries' must a 2-tuple"
 
             if type (lib[0]) is not StringType:
-                raise DistutilsValueError, \
+                raise DistutilsSetupError, \
                       "first element of each tuple in 'libraries' " + \
                       "must be a string (the library name)"
             if '/' in lib[0] or (os.sep != '/' and os.sep in lib[0]):
-                raise DistutilsValueError, \
+                raise DistutilsSetupError, \
                       ("bad library name '%s': " + 
                        "may not contain directory separators") % \
                       lib[0]
 
             if type (lib[1]) is not DictionaryType:
-                raise DistutilsValueError, \
+                raise DistutilsSetupError, \
                       "second element of each tuple in 'libraries' " + \
                       "must be a dictionary (build info)"
         # for lib
@@ -171,7 +171,7 @@
         for (lib_name, build_info) in libraries:
             sources = build_info.get ('sources')
             if sources is None or type (sources) not in (ListType, TupleType):
-                raise DistutilsValueError, \
+                raise DistutilsSetupError, \
                       ("in 'libraries' option (library '%s'), " +
                        "'sources' must be present and must be " +
                        "a list of source filenames") % lib_name
diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py
index f08c97e..422b8ca 100644
--- a/Lib/distutils/command/build_ext.py
+++ b/Lib/distutils/command/build_ext.py
@@ -205,26 +205,26 @@
         """Ensure that the list of extensions (presumably provided as a
            command option 'extensions') is valid, i.e. it is a list of
            2-tuples, where the tuples are (extension_name, build_info_dict).
-           Raise DistutilsValueError if the structure is invalid anywhere;
+           Raise DistutilsSetupError if the structure is invalid anywhere;
            just returns otherwise."""
 
         if type (extensions) is not ListType:
-            raise DistutilsValueError, \
+            raise DistutilsSetupError, \
                   "'ext_modules' option must be a list of tuples"
         
         for ext in extensions:
             if type (ext) is not TupleType and len (ext) != 2:
-                raise DistutilsValueError, \
+                raise DistutilsSetupError, \
                       "each element of 'ext_modules' option must be a 2-tuple"
 
             if not (type (ext[0]) is StringType and
                     extension_name_re.match (ext[0])):
-                raise DistutilsValueError, \
+                raise DistutilsSetupError, \
                       "first element of each tuple in 'ext_modules' " + \
                       "must be the extension name (a string)"
 
             if type (ext[1]) is not DictionaryType:
-                raise DistutilsValueError, \
+                raise DistutilsSetupError, \
                       "second element of each tuple in 'ext_modules' " + \
                       "must be a dictionary (build info)"
 
@@ -274,7 +274,7 @@
         for (extension_name, build_info) in self.extensions:
             sources = build_info.get ('sources')
             if sources is None or type (sources) not in (ListType, TupleType):
-                raise DistutilsValueError, \
+                raise DistutilsSetupError, \
                       ("in 'ext_modules' option (extension '%s'), " +
                        "'sources' must be present and must be " +
                        "a list of source filenames") % extension_name
diff --git a/Lib/distutils/dist.py b/Lib/distutils/dist.py
index cb18031..408b9f5 100644
--- a/Lib/distutils/dist.py
+++ b/Lib/distutils/dist.py
@@ -152,7 +152,7 @@
                 if hasattr (self, key):
                     setattr (self, key, val)
                 else:
-                    raise DistutilsOptionError, \
+                    raise DistutilsSetupError, \
                           "invalid distribution option '%s'" % key
 
     # __init__ ()
@@ -447,27 +447,18 @@
 
     def get_option (self, option):
         """Return the value of a distribution option.  Raise
-           DistutilsOptionError if 'option' is not known."""
-
-        try:
-            return getattr (self, opt)
-        except AttributeError:
-            raise DistutilsOptionError, \
-                  "unknown distribution option %s" % option
+           AttributeError if 'option' is not known."""
+        return getattr (self, opt)
 
 
     def get_options (self, *options):
         """Return (as a tuple) the values of several distribution
-           options.  Raise DistutilsOptionError if any element of
+           options.  Raise AttributeError if any element of
            'options' is not known."""
         
         values = []
-        try:
-            for opt in options:
-                values.append (getattr (self, opt))
-        except AttributeError, name:
-            raise DistutilsOptionError, \
-                  "unknown distribution option %s" % name
+        for opt in options:
+            values.append (getattr (self, opt))
 
         return tuple (values)
 
@@ -498,17 +489,12 @@
     def get_command_option (self, command, option):
         """Create a command object for 'command' if necessary, ensure that
            its option values are all set to their final values, and return
-           the value of its 'option' option.  Raise DistutilsOptionError if
+           the value of its 'option' option.  Raise AttributeError if
            'option' is not known for that 'command'."""
 
         cmd_obj = self.find_command_obj (command)
         cmd_obj.ensure_ready ()
         return cmd_obj.get_option (option)
-        try:
-            return getattr (cmd_obj, option)
-        except AttributeError:
-            raise DistutilsOptionError, \
-                  "command %s: no such option %s" % (command, option)
 
 
     def get_command_options (self, command, *options):
@@ -521,12 +507,8 @@
         cmd_obj = self.find_command_obj (command)
         cmd_obj.ensure_ready ()
         values = []
-        try:
-            for opt in options:
-                values.append (getattr (cmd_obj, option))
-        except AttributeError, name:
-            raise DistutilsOptionError, \
-                  "command %s: no such option %s" % (command, name)
+        for opt in options:
+            values.append (getattr (cmd_obj, option))
 
         return tuple (values)
 
diff --git a/Lib/distutils/errors.py b/Lib/distutils/errors.py
index f9d5c8d..61cdb72 100644
--- a/Lib/distutils/errors.py
+++ b/Lib/distutils/errors.py
@@ -46,15 +46,18 @@
     class DistutilsFileError (DistutilsError):
         pass
 
-    # DistutilsOptionError is raised anytime an attempt is made to access
-    # (get or set) an option that does not exist for a particular command
-    # (or for the distribution itself).
+    # DistutilsOptionError is raised for syntactic/semantic errors in
+    # command options, such as use of mutually conflicting options, or
+    # inconsistent options, badly-spelled values, etc.  No distinction is
+    # made between option values originating in the setup script, the
+    # command line, config files, or what-have-you.
     class DistutilsOptionError (DistutilsError):
         pass
 
-    # DistutilsValueError is raised anytime an option value (presumably
-    # provided by setup.py) is invalid.
-    class DistutilsValueError (DistutilsError):
+    # DistutilsSetupError is raised for errors that can be definitely
+    # blamed on the setup script, such as invalid keyword arguments to
+    # 'setup()'.
+    class DistutilsSetupError (DistutilsError):
         pass
 
     # DistutilsPlatformError is raised when we find that we don't
@@ -82,7 +85,6 @@
     DistutilsArgError = 'DistutilsArgError'
     DistutilsFileError = 'DistutilsFileError'
     DistutilsOptionError = 'DistutilsOptionError'
-    DistutilsValueError = 'DistutilsValueError'
     DistutilsPlatformError = 'DistutilsPlatformError'
     DistutilsExecError = 'DistutilsExecError'
     DistutilsInternalError = 'DistutilsInternalError'
diff --git a/Lib/distutils/msvccompiler.py b/Lib/distutils/msvccompiler.py
index 43a8596..c7a69c3 100644
--- a/Lib/distutils/msvccompiler.py
+++ b/Lib/distutils/msvccompiler.py
@@ -360,6 +360,9 @@
             if extra_postargs:
                 ld_args.extend (extra_postargs)
 
+            print "link_shared_object():"
+            print "  output_filename =", output_filename
+            print "  mkpath'ing:", os.path.dirname (output_filename)
             self.mkpath (os.path.dirname (output_filename))
             self.spawn ([self.link] + ld_args)
 
diff --git a/Lib/distutils/util.py b/Lib/distutils/util.py
index ddcf0d2..be3a1d6 100644
--- a/Lib/distutils/util.py
+++ b/Lib/distutils/util.py
@@ -40,16 +40,16 @@
        using the current directory separator.  Needed because filenames in
        the setup script are always supplied in Unix style, and have to be
        converted to the local convention before we can actually use them in
-       the filesystem.  Raises DistutilsValueError if 'pathname' is
+       the filesystem.  Raises ValueError if 'pathname' is
        absolute (starts with '/') or contains local directory separators
        (unless the local separator is '/', of course)."""
 
     if pathname[0] == '/':
-        raise DistutilsValueError, "path '%s' cannot be absolute" % pathname
+        raise ValueError, "path '%s' cannot be absolute" % pathname
     if pathname[-1] == '/':
-        raise DistutilsValueError, "path '%s' cannot end with '/'" % pathname
+        raise ValueError, "path '%s' cannot end with '/'" % pathname
     if os.sep != '/' and os.sep in pathname:
-        raise DistutilsValueError, \
+        raise ValueError, \
               "path '%s' cannot contain '%c' character" % \
               (pathname, os.sep)