--- a/mercurial/keepalive.py	Fri Apr 04 22:41:17 2008 +0200
+++ b/mercurial/keepalive.py	Fri Apr 04 22:36:40 2008 +0200
@@ -19,6 +19,8 @@
 
 # Modified by Benoit Boissinot:
 #  - fix for digest auth (inspired from urllib2.py @ Python v2.4)
+# Modified by Dirkjan Ochtman:
+#  - import md5 function from a local util module
 
 """An HTTP handler for urllib2 that supports HTTP 1.1 and keepalive.
 
@@ -450,7 +452,7 @@
     keepalive_handler.close_all()
 
 def continuity(url):
-    import md5
+    from util import md5
     format = '%25s: %s'
 
     # first fetch the file with the normal http handler
--- a/mercurial/mdiff.py	Fri Apr 04 22:41:17 2008 +0200
+++ b/mercurial/mdiff.py	Fri Apr 04 22:36:40 2008 +0200
@@ -6,7 +6,7 @@
 # of the GNU General Public License, incorporated herein by reference.
 
 from i18n import _
-import bdiff, mpatch, re, struct, util, md5
+import bdiff, mpatch, re, struct, util
 
 def splitnewlines(text):
     '''like str.splitlines, but only split on newlines.'''
@@ -80,7 +80,7 @@
     if not opts.text and (util.binary(a) or util.binary(b)):
         def h(v):
             # md5 is used instead of sha1 because md5 is supposedly faster
-            return md5.new(v).digest()
+            return util.md5(v).digest()
         if a and b and len(a) == len(b) and h(a) == h(b):
             return ""
         l = ['Binary file %s has changed\n' % fn1]
--- a/mercurial/patch.py	Fri Apr 04 22:41:17 2008 +0200
+++ b/mercurial/patch.py	Fri Apr 04 22:36:40 2008 +0200
@@ -9,7 +9,7 @@
 from i18n import _
 from node import hex, nullid, short
 import base85, cmdutil, mdiff, util, context, revlog, diffhelpers, copies
-import cStringIO, email.Parser, os, popen2, re, sha, errno
+import cStringIO, email.Parser, os, popen2, re, errno
 import sys, tempfile, zlib
 
 class PatchError(Exception):
@@ -1120,7 +1120,7 @@
         if not text:
             return '0' * 40
         l = len(text)
-        s = sha.new('blob %d\0' % l)
+        s = util.sha1('blob %d\0' % l)
         s.update(text)
         return s.hexdigest()
 
--- a/mercurial/revlog.py	Fri Apr 04 22:41:17 2008 +0200
+++ b/mercurial/revlog.py	Fri Apr 04 22:36:40 2008 +0200
@@ -13,13 +13,13 @@
 from node import bin, hex, nullid, nullrev, short
 from i18n import _
 import changegroup, errno, ancestor, mdiff
-import sha, struct, util, zlib
+import struct, util, zlib
 
 _pack = struct.pack
 _unpack = struct.unpack
 _compress = zlib.compress
 _decompress = zlib.decompress
-_sha = sha.new
+_sha = util.sha1
 
 # revlog flags
 REVLOGV0 = 0
--- a/mercurial/util.py	Fri Apr 04 22:41:17 2008 +0200
+++ b/mercurial/util.py	Fri Apr 04 22:36:40 2008 +0200
@@ -17,12 +17,38 @@
 import os, stat, threading, time, calendar, ConfigParser, locale, glob, osutil
 import urlparse
 
+# Python compatibility
+
 try:
     set = set
     frozenset = frozenset
 except NameError:
     from sets import Set as set, ImmutableSet as frozenset
 
+_md5 = None
+def md5(s):
+    global _md5
+    if _md5 is None:
+        try:
+            import hashlib
+            _md5 = hashlib.md5
+        except ImportError:
+            import md5
+            _md5 = md5.md5
+    return _md5(s)
+
+_sha1 = None
+def sha1(s):
+    global _sha1
+    if _sha1 is None:
+        try:
+            import hashlib
+            _sha1 = hashlib.sha1
+        except ImportError:
+            import sha
+            _sha1 = sha.sha
+    return _sha1(s)
+
 try:
     _encoding = os.environ.get("HGENCODING")
     if sys.platform == 'darwin' and not _encoding:
--- a/tests/md5sum.py	Fri Apr 04 22:41:17 2008 +0200
+++ b/tests/md5sum.py	Fri Apr 04 22:36:40 2008 +0200
@@ -7,7 +7,11 @@
 # GPL-compatible.
 
 import sys
-import md5
+
+try:
+    from hashlib import md5
+except ImportError:
+    from md5 import md5
 
 for filename in sys.argv[1:]:
     try:
@@ -16,7 +20,7 @@
         sys.stderr.write('%s: Can\'t open: %s\n' % (filename, msg))
         sys.exit(1)
 
-    m = md5.new()
+    m = md5()
     try:
         while 1:
             data = fp.read(8192)

--- a/mercurial/commands.py	Fri Apr 04 22:18:38 2008 +0200
+++ b/mercurial/commands.py	Fri Apr 04 22:41:17 2008 +0200
@@ -1047,6 +1047,9 @@
             self.colstart = colstart
             self.colend = colend
 
+        def __hash__(self):
+            return hash((self.linenum, self.line))
+
         def __eq__(self, other):
             return self.line == other.line
 
--- a/mercurial/context.py	Fri Apr 04 22:18:38 2008 +0200
+++ b/mercurial/context.py	Fri Apr 04 22:41:17 2008 +0200
@@ -34,6 +34,12 @@
     def __repr__(self):
         return "<changectx %s>" % str(self)
 
+    def __hash__(self):
+        try:
+            return hash(self._rev)
+        except AttributeError:
+            return id(self)
+
     def __eq__(self, other):
         try:
             return self._rev == other._rev
@@ -210,6 +216,12 @@
     def __repr__(self):
         return "<filectx %s>" % str(self)
 
+    def __hash__(self):
+        try:
+            return hash((self._path, self._fileid))
+        except AttributeError:
+            return id(self)
+
     def __eq__(self, other):
         try:
             return (self._path == other._path

--- a/mercurial/archival.py	Mon Apr 07 13:16:11 2008 +0200
+++ b/mercurial/archival.py	Tue Apr 08 15:42:43 2008 +0200
@@ -52,7 +52,8 @@
         def _write_gzip_header(self):
             self.fileobj.write('\037\213')             # magic header
             self.fileobj.write('\010')                 # compression method
-            fname = self.filename[:-3]
+            # Python 2.6 deprecates self.filename
+            fname = getattr(self, 'name', None) or self.filename 
             flags = 0
             if fname:
                 flags = gzip.FNAME

--- a/tests/test-archive	Tue Apr 08 15:42:43 2008 +0200
+++ b/tests/test-archive	Tue Apr 08 15:41:21 2008 +0200
@@ -40,10 +40,11 @@
 gzip -dc test-$QTIP.tar.gz | tar tf - | sed "s/$QTIP/TIP/"
 
 cat > md5comp.py <<EOF
-import md5, sys
+from mercurial.util import md5
+import sys
 f1, f2 = sys.argv[1:3]
-h1 = md5.md5(file(f1, 'rb').read()).hexdigest()
-h2 = md5.md5(file(f2, 'rb').read()).hexdigest()
+h1 = md5(file(f1, 'rb').read()).hexdigest()
+h2 = md5(file(f2, 'rb').read()).hexdigest()
 print h1 == h2 or "md5 differ: " + repr((h1, h2))
 EOF
 
--- a/hgext/convert/cvs.py	Fri Oct 17 17:34:25 2008 +0200
+++ b/hgext/convert/cvs.py	Sun Oct 05 21:35:26 2008 +0200
@@ -252,7 +252,7 @@
             # popen2 does not support argument lists under Windows
             cmd = [util.shellquote(arg) for arg in cmd]
             cmd = util.quotecommand(' '.join(cmd))
-            self.writep, self.readp = os.popen2(cmd, 'b')
+            self.writep, self.readp = util.popen2(cmd, 'b')
 
         self.realroot = root
 
--- a/hgext/convert/subversion.py	Fri Oct 17 17:34:25 2008 +0200
+++ b/hgext/convert/subversion.py	Sun Oct 05 21:35:26 2008 +0200
@@ -914,7 +914,7 @@
         arg = encodeargs(args)
         hgexe = util.hgexecutable()
         cmd = '%s debugsvnlog' % util.shellquote(hgexe)
-        stdin, stdout = os.popen2(cmd, 'b')
+        stdin, stdout = util.popen2(cmd, 'b')
         stdin.write(arg)
         stdin.close()
         return logstream(stdout)
--- a/mercurial/patch.py	Fri Oct 17 17:34:25 2008 +0200
+++ b/mercurial/patch.py	Sun Oct 05 21:35:26 2008 +0200
@@ -9,7 +9,7 @@
 from i18n import _
 from node import hex, nullid, short
 import base85, cmdutil, mdiff, util, context, revlog, diffhelpers, copies
-import cStringIO, email.Parser, os, popen2, re, errno
+import cStringIO, email.Parser, os, re, errno
 import sys, tempfile, zlib
 
 class PatchError(Exception):
@@ -1308,7 +1308,7 @@
         return
     fd, name = tempfile.mkstemp(prefix="hg-patchbomb-", suffix=".txt")
     try:
-        p = popen2.Popen3('diffstat -p1 -w79 2>/dev/null > ' + name)
+        p = util.Popen3('diffstat -p1 -w79 2>/dev/null > ' + name)
         try:
             for line in patchlines:
                 p.tochild.write(line + "\n")
--- a/mercurial/sshrepo.py	Fri Oct 17 17:34:25 2008 +0200
+++ b/mercurial/sshrepo.py	Sun Oct 05 21:35:26 2008 +0200
@@ -61,7 +61,7 @@
 
         cmd = util.quotecommand(cmd)
         ui.note('running %s\n' % cmd)
-        self.pipeo, self.pipei, self.pipee = os.popen3(cmd, 'b')
+        self.pipeo, self.pipei, self.pipee = util.popen3(cmd, 'b')
 
         # skip any noise generated by remote shell
         self.do_cmd("hello")
--- a/mercurial/util.py	Fri Oct 17 17:34:25 2008 +0200
+++ b/mercurial/util.py	Sun Oct 05 21:35:26 2008 +0200
@@ -50,6 +50,33 @@
     return _sha1(s)
 
 try:
+    import subprocess
+    def popen2(cmd, mode='t', bufsize=-1):
+        p = subprocess.Popen(cmd, shell=True, bufsize=bufsize, close_fds=True,
+                             stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+        return p.stdin, p.stdout
+    def popen3(cmd, mode='t', bufsize=-1):
+        p = subprocess.Popen(cmd, shell=True, bufsize=bufsize, close_fds=True,
+                             stdin=subprocess.PIPE, stdout=subprocess.PIPE,
+                             stderr=subprocess.PIPE)
+        return p.stdin, p.stdout, p.stderr
+    def Popen3(cmd, capturestderr=False, bufsize=-1):
+        stderr = capturestderr and subprocess.PIPE or None
+        p = subprocess.Popen(cmd, shell=True, bufsize=bufsize, close_fds=True,
+                             stdin=subprocess.PIPE, stdout=subprocess.PIPE,
+                             stderr=stderr)
+        p.fromchild = p.stdout
+        p.tochild = p.stdin
+        p.childerr = p.stderr
+        return p
+except ImportError:
+    subprocess = None
+    import popen2 as _popen2
+    popen2 = _popen2.popen2
+    Popen3 = _popen2.Popen3
+
+
+try:
     _encoding = os.environ.get("HGENCODING")
     if sys.platform == 'darwin' and not _encoding:
         # On darwin, getpreferredencoding ignores the locale environment and
@@ -183,7 +210,7 @@
 
 def pipefilter(s, cmd):
     '''filter string S through command CMD, returning its output'''
-    (pin, pout) = os.popen2(cmd, 'b')
+    (pin, pout) = popen2(cmd, 'b')
     def writer():
         try:
             pin.write(s)

