a805d4bd.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. """
  2. a805d4bd
  3. This module fixes a bug with pickling and relative imports in Python < 2.6.
  4. The problem is with pickling an e.g. ``exceptions.KeyError`` instance.
  5. As SQLAlchemy has its own ``exceptions`` module, pickle will try to
  6. lookup ``KeyError`` in the wrong module, resulting in this exception::
  7. cPickle.PicklingError: Can't pickle <type 'exceptions.KeyError'>:
  8. attribute lookup exceptions.KeyError failed
  9. doing ``import exceptions`` just before the dump in ``sqlalchemy.types``
  10. reveals the source of the bug::
  11. EXCEPTIONS: <module 'sqlalchemy.exc' from '/var/lib/hudson/jobs/celery/
  12. workspace/buildenv/lib/python2.5/site-packages/sqlalchemy/exc.pyc'>
  13. Hence the random module name "a805d5bd" is taken to decrease the chances of
  14. a collision.
  15. """
  16. from sqlalchemy.types import PickleType as _PickleType
  17. class PickleType(_PickleType):
  18. def bind_processor(self, dialect):
  19. impl_processor = self.impl.bind_processor(dialect)
  20. dumps = self.pickler.dumps
  21. protocol = self.protocol
  22. if impl_processor:
  23. def process(value):
  24. if value is not None:
  25. value = dumps(value, protocol)
  26. return impl_processor(value)
  27. else:
  28. def process(value):
  29. if value is not None:
  30. value = dumps(value, protocol)
  31. return value
  32. return process
  33. def result_processor(self, dialect, coltype):
  34. impl_processor = self.impl.result_processor(dialect, coltype)
  35. loads = self.pickler.loads
  36. if impl_processor:
  37. def process(value):
  38. value = impl_processor(value)
  39. if value is None:
  40. return None
  41. return loads(value)
  42. else:
  43. def process(value):
  44. if value is None:
  45. return None
  46. return loads(value)
  47. return process
  48. def copy_value(self, value):
  49. if self.mutable:
  50. return self.pickler.loads(self.pickler.dumps(value, self.protocol))
  51. else:
  52. return value