Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
number of tests, all because of the codecs/_multibytecodecs issue described
here (it's not a Py3K issue, just something Py3K discovers):
http://mail.python.org/pipermail/python-dev/2006-April/064051.html

Hye-Shik Chang promised to look for a fix, so no need to fix it here. The
tests that are expected to break are:

test_codecencodings_cn
test_codecencodings_hk
test_codecencodings_jp
test_codecencodings_kr
test_codecencodings_tw
test_codecs
test_multibytecodec

This merge fixes an actual test failure (test_weakref) in this branch,
though, so I believe merging is the right thing to do anyway.
diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py
index 6ea5d57..5771252 100644
--- a/Lib/distutils/command/build_ext.py
+++ b/Lib/distutils/command/build_ext.py
@@ -185,7 +185,9 @@
 
         # for extensions under Cygwin and AtheOS Python's library directory must be
         # appended to library_dirs
-        if sys.platform[:6] == 'cygwin' or sys.platform[:6] == 'atheos':
+        if sys.platform[:6] == 'cygwin' or sys.platform[:6] == 'atheos' or \
+               (sys.platform.startswith('linux') and
+                sysconfig.get_config_var('Py_ENABLE_SHARED')):
             if string.find(sys.executable, sys.exec_prefix) != -1:
                 # building third party extensions
                 self.library_dirs.append(os.path.join(sys.prefix, "lib",
@@ -688,6 +690,13 @@
             # extensions, it is a reference to the original list
             return ext.libraries + [pythonlib, "m"] + extra
         else:
-            return ext.libraries
+            from distutils import sysconfig
+            if sysconfig.get_config_var('Py_ENABLE_SHARED'):
+                template = "python%d.%d"
+                pythonlib = (template %
+                             (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
+                return ext.libraries + [pythonlib]
+            else:
+                return ext.libraries
 
 # class build_ext
diff --git a/Lib/distutils/command/install.py b/Lib/distutils/command/install.py
index 7723761..453151d 100644
--- a/Lib/distutils/command/install.py
+++ b/Lib/distutils/command/install.py
@@ -601,6 +601,7 @@
                     ('install_headers', has_headers),
                     ('install_scripts', has_scripts),
                     ('install_data',    has_data),
+                    ('install_egg_info', lambda self:True),
                    ]
 
 # class install
diff --git a/Lib/distutils/command/install_egg_info.py b/Lib/distutils/command/install_egg_info.py
new file mode 100644
index 0000000..c31ac29
--- /dev/null
+++ b/Lib/distutils/command/install_egg_info.py
@@ -0,0 +1,75 @@
+"""distutils.command.install_egg_info
+
+Implements the Distutils 'install_egg_info' command, for installing
+a package's PKG-INFO metadata."""
+
+
+from distutils.cmd import Command
+from distutils import log, dir_util
+import os, sys, re
+
+class install_egg_info(Command):
+    """Install an .egg-info file for the package"""
+
+    description = "Install package's PKG-INFO metadata as an .egg-info file"
+    user_options = [
+        ('install-dir=', 'd', "directory to install to"),
+    ]
+
+    def initialize_options(self):
+        self.install_dir = None
+
+    def finalize_options(self):
+        self.set_undefined_options('install_lib',('install_dir','install_dir'))
+        basename = "%s-%s-py%s.egg-info" % (
+            to_filename(safe_name(self.distribution.get_name())),
+            to_filename(safe_version(self.distribution.get_version())),
+            sys.version[:3]
+        )
+        self.target = os.path.join(self.install_dir, basename)
+        self.outputs = [self.target]
+
+    def run(self):
+        target = self.target
+        if os.path.isdir(target) and not os.path.islink(target):
+            dir_util.remove_tree(target, dry_run=self.dry_run)
+        elif os.path.exists(target):
+            self.execute(os.unlink,(self.target,),"Removing "+target)
+        log.info("Writing %s", target)
+        if not self.dry_run:
+            f = open(target, 'w')
+            self.distribution.metadata.write_pkg_file(f)
+            f.close()
+
+    def get_outputs(self):
+        return self.outputs
+
+
+# The following routines are taken from setuptools' pkg_resources module and
+# can be replaced by importing them from pkg_resources once it is included
+# in the stdlib.
+
+def safe_name(name):
+    """Convert an arbitrary string to a standard distribution name
+
+    Any runs of non-alphanumeric/. characters are replaced with a single '-'.
+    """
+    return re.sub('[^A-Za-z0-9.]+', '-', name)
+
+
+def safe_version(version):
+    """Convert an arbitrary string to a standard version string
+
+    Spaces become dots, and all other non-alphanumeric characters become
+    dashes, with runs of multiple dashes condensed to a single dash.
+    """
+    version = version.replace(' ','.')
+    return re.sub('[^A-Za-z0-9.]+', '-', version)
+
+
+def to_filename(name):
+    """Convert a project or version name to its filename-escaped form
+
+    Any '-' characters are currently replaced with '_'.
+    """
+    return name.replace('-','_')
diff --git a/Lib/distutils/command/upload.py b/Lib/distutils/command/upload.py
index 62767a3..6f4ce81 100644
--- a/Lib/distutils/command/upload.py
+++ b/Lib/distutils/command/upload.py
@@ -29,6 +29,7 @@
          'display full response text from server'),
         ('sign', 's',
          'sign files to upload using gpg'),
+        ('identity=', 'i', 'GPG identity used to sign files'),
         ]
     boolean_options = ['show-response', 'sign']
 
@@ -38,8 +39,13 @@
         self.repository = ''
         self.show_response = 0
         self.sign = False
+        self.identity = None
 
     def finalize_options(self):
+        if self.identity and not self.sign:
+            raise DistutilsOptionError(
+                "Must use --sign for --identity to have meaning"
+            )
         if os.environ.has_key('HOME'):
             rc = os.path.join(os.environ['HOME'], '.pypirc')
             if os.path.exists(rc):
@@ -67,7 +73,10 @@
     def upload_file(self, command, pyversion, filename):
         # Sign if requested
         if self.sign:
-            spawn(("gpg", "--detach-sign", "-a", filename),
+            gpg_args = ["gpg", "--detach-sign", "-a", filename]
+            if self.identity:
+                gpg_args[2:2] = ["--local-user", self.identity]
+            spawn(gpg_args,
                   dry_run=self.dry_run)
 
         # Fill in the data - send all the meta-data in case we need to
diff --git a/Lib/distutils/log.py b/Lib/distutils/log.py
index cf3ee13..95d4c1c 100644
--- a/Lib/distutils/log.py
+++ b/Lib/distutils/log.py
@@ -20,7 +20,12 @@
 
     def _log(self, level, msg, args):
         if level >= self.threshold:
-            print msg % args
+            if not args:
+                # msg may contain a '%'. If args is empty,
+                # don't even try to string-format
+                print msg
+            else:
+                print msg % args
             sys.stdout.flush()
 
     def log(self, level, msg, *args):
diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py
index dc603be..49536f0 100644
--- a/Lib/distutils/sysconfig.py
+++ b/Lib/distutils/sysconfig.py
@@ -31,7 +31,7 @@
 
 python_build = os.path.isfile(landmark)
 
-del argv0_path, landmark
+del landmark
 
 
 def get_python_version():
@@ -185,7 +185,7 @@
 def get_config_h_filename():
     """Return full pathname of installed pyconfig.h file."""
     if python_build:
-        inc_dir = os.curdir
+        inc_dir = argv0_path
     else:
         inc_dir = get_python_inc(plat_specific=1)
     if get_python_version() < '2.2':
@@ -213,8 +213,8 @@
     """
     if g is None:
         g = {}
-    define_rx = re.compile("#define ([A-Z][A-Z0-9_]+) (.*)\n")
-    undef_rx = re.compile("/[*] #undef ([A-Z][A-Z0-9_]+) [*]/\n")
+    define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n")
+    undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n")
     #
     while 1:
         line = fp.readline()
@@ -351,6 +351,17 @@
 
         raise DistutilsPlatformError(my_msg)
 
+    # load the installed pyconfig.h:
+    try:
+        filename = get_config_h_filename()
+        parse_config_h(file(filename), g)
+    except IOError, msg:
+        my_msg = "invalid Python installation: unable to open %s" % filename
+        if hasattr(msg, "strerror"):
+            my_msg = my_msg + " (%s)" % msg.strerror
+
+        raise DistutilsPlatformError(my_msg)
+
     # On MacOSX we need to check the setting of the environment variable
     # MACOSX_DEPLOYMENT_TARGET: configure bases some choices on it so
     # it needs to be compatible.
@@ -361,7 +372,7 @@
         if cur_target == '':
             cur_target = cfg_target
             os.putenv('MACOSX_DEPLOYMENT_TARGET', cfg_target)
-        if cfg_target != cur_target:
+        elif map(int, cfg_target.split('.')) > map(int, cur_target.split('.')):
             my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: now "%s" but "%s" during configure'
                 % (cur_target, cfg_target))
             raise DistutilsPlatformError(my_msg)