misc.py 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. # misc.py -- For dealing with python2.4 oddness
  2. # Copyright (C) 2008 Canonical Ltd.
  3. #
  4. # This program is free software; you can redistribute it and/or
  5. # modify it under the terms of the GNU General Public License
  6. # as published by the Free Software Foundation; version 2
  7. # of the License or (at your option) a later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  17. # MA 02110-1301, USA.
  18. """Misc utilities to work with python <2.6.
  19. These utilities can all be deleted when dulwich decides it wants to stop
  20. support for python <2.6.
  21. """
  22. try:
  23. import hashlib
  24. except ImportError:
  25. import sha
  26. try:
  27. from urlparse import parse_qs
  28. except ImportError:
  29. from cgi import parse_qs
  30. import struct
  31. class defaultdict(dict):
  32. """A python 2.4 equivalent of collections.defaultdict."""
  33. def __init__(self, default_factory=None, *a, **kw):
  34. if (default_factory is not None and
  35. not hasattr(default_factory, '__call__')):
  36. raise TypeError('first argument must be callable')
  37. dict.__init__(self, *a, **kw)
  38. self.default_factory = default_factory
  39. def __getitem__(self, key):
  40. try:
  41. return dict.__getitem__(self, key)
  42. except KeyError:
  43. return self.__missing__(key)
  44. def __missing__(self, key):
  45. if self.default_factory is None:
  46. raise KeyError(key)
  47. self[key] = value = self.default_factory()
  48. return value
  49. def __reduce__(self):
  50. if self.default_factory is None:
  51. args = tuple()
  52. else:
  53. args = self.default_factory,
  54. return type(self), args, None, None, self.items()
  55. def copy(self):
  56. return self.__copy__()
  57. def __copy__(self):
  58. return type(self)(self.default_factory, self)
  59. def __deepcopy__(self, memo):
  60. import copy
  61. return type(self)(self.default_factory,
  62. copy.deepcopy(self.items()))
  63. def __repr__(self):
  64. return 'defaultdict(%s, %s)' % (self.default_factory,
  65. dict.__repr__(self))
  66. def make_sha(source=''):
  67. """A python2.4 workaround for the sha/hashlib module fiasco."""
  68. try:
  69. return hashlib.sha1(source)
  70. except NameError:
  71. sha1 = sha.sha(source)
  72. return sha1
  73. def unpack_from(fmt, buf, offset=0):
  74. """A python2.4 workaround for struct missing unpack_from."""
  75. try:
  76. return struct.unpack_from(fmt, buf, offset)
  77. except AttributeError:
  78. b = buf[offset:offset+struct.calcsize(fmt)]
  79. return struct.unpack(fmt, b)