Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

utils.py 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. from __future__ import absolute_import
  2. import sys
  3. try:
  4. import fcntl
  5. except ImportError:
  6. fcntl = None # noqa
  7. class promise(object):
  8. if not hasattr(sys, 'pypy_version_info'):
  9. __slots__ = tuple(
  10. 'fun args kwargs value ready failed '
  11. ' on_success on_error calls'.split()
  12. )
  13. def __init__(self, fun, args=(), kwargs=(),
  14. on_success=None, on_error=None):
  15. self.fun = fun
  16. self.args = args
  17. self.kwargs = kwargs
  18. self.ready = False
  19. self.failed = False
  20. self.on_success = on_success
  21. self.on_error = on_error
  22. self.value = None
  23. self.calls = 0
  24. def __repr__(self):
  25. return '<$: {0.fun.__name__}(*{0.args!r}, **{0.kwargs!r})'.format(
  26. self,
  27. )
  28. def __call__(self, *args, **kwargs):
  29. try:
  30. self.value = self.fun(
  31. *self.args + args if self.args else args,
  32. **dict(self.kwargs, **kwargs) if self.kwargs else kwargs
  33. )
  34. except Exception as exc:
  35. self.set_error_state(exc)
  36. else:
  37. if self.on_success:
  38. self.on_success(self.value)
  39. finally:
  40. self.ready = True
  41. self.calls += 1
  42. def then(self, callback=None, on_error=None):
  43. self.on_success = callback
  44. self.on_error = on_error
  45. return callback
  46. def set_error_state(self, exc):
  47. self.failed = True
  48. if self.on_error is None:
  49. raise
  50. self.on_error(exc)
  51. def throw(self, exc):
  52. try:
  53. raise exc
  54. except exc.__class__ as with_cause:
  55. self.set_error_state(with_cause)
  56. def noop():
  57. return promise(lambda *a, **k: None)
  58. try:
  59. from os import set_cloexec # Python 3.4?
  60. except ImportError:
  61. def set_cloexec(fd, cloexec): # noqa
  62. try:
  63. FD_CLOEXEC = fcntl.FD_CLOEXEC
  64. except AttributeError:
  65. raise NotImplementedError(
  66. 'close-on-exec flag not supported on this platform',
  67. )
  68. flags = fcntl.fcntl(fd, fcntl.F_GETFD)
  69. if cloexec:
  70. flags |= FD_CLOEXEC
  71. else:
  72. flags &= ~FD_CLOEXEC
  73. return fcntl.fcntl(fd, fcntl.F_SETFD, flags)
  74. def get_errno(exc):
  75. """:exc:`socket.error` and :exc:`IOError` first got
  76. the ``.errno`` attribute in Py2.7"""
  77. try:
  78. return exc.errno
  79. except AttributeError:
  80. try:
  81. # e.args = (errno, reason)
  82. if isinstance(exc.args, tuple) and len(exc.args) == 2:
  83. return exc.args[0]
  84. except AttributeError:
  85. pass
  86. return 0