misc.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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 python2.4.
  19. These utilities can all be deleted when dulwich decides it wants to stop
  20. support for python 2.4.
  21. '''
  22. try:
  23. import hashlib
  24. except ImportError:
  25. import sha
  26. import struct
  27. class defaultdict(dict):
  28. '''A python 2.4 equivalent of collections.defaultdict.'''
  29. def __init__(self, default_factory=None, *a, **kw):
  30. if (default_factory is not None and
  31. not hasattr(default_factory, '__call__')):
  32. raise TypeError('first argument must be callable')
  33. dict.__init__(self, *a, **kw)
  34. self.default_factory = default_factory
  35. def __getitem__(self, key):
  36. try:
  37. return dict.__getitem__(self, key)
  38. except KeyError:
  39. return self.__missing__(key)
  40. def __missing__(self, key):
  41. if self.default_factory is None:
  42. raise KeyError(key)
  43. self[key] = value = self.default_factory()
  44. return value
  45. def __reduce__(self):
  46. if self.default_factory is None:
  47. args = tuple()
  48. else:
  49. args = self.default_factory,
  50. return type(self), args, None, None, self.items()
  51. def copy(self):
  52. return self.__copy__()
  53. def __copy__(self):
  54. return type(self)(self.default_factory, self)
  55. def __deepcopy__(self, memo):
  56. import copy
  57. return type(self)(self.default_factory,
  58. copy.deepcopy(self.items()))
  59. def __repr__(self):
  60. return 'defaultdict(%s, %s)' % (self.default_factory,
  61. dict.__repr__(self))
  62. def make_sha(source=''):
  63. '''A python2.4 workaround for the sha/hashlib module fiasco.'''
  64. if hashlib:
  65. return hashlib.sha1(source)
  66. else:
  67. sha1 = sha.sha()
  68. sha1.update(source)
  69. return sha.hexdigest()
  70. def unpack_from(fmt, buf, offset=0):
  71. '''A python2.4 workaround for struct missing unpack_from.'''
  72. try:
  73. return struct.unpack_from(fmt, buf, offset)
  74. except AttributeError:
  75. b = buf[offset:offset+struct.calcsize(fmt)]
  76. return struct.unpack(fmt, b)