coroutines.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. __all__ = 'iscoroutinefunction', 'iscoroutine'
  2. import collections.abc
  3. import inspect
  4. import os
  5. import sys
  6. import types
  7. def _is_debug_mode():
  8. # See: https://docs.python.org/3/library/asyncio-dev.html#asyncio-debug-mode.
  9. return sys.flags.dev_mode or (not sys.flags.ignore_environment and
  10. bool(os.environ.get('PYTHONASYNCIODEBUG')))
  11. # A marker for iscoroutinefunction.
  12. _is_coroutine = object()
  13. def iscoroutinefunction(func):
  14. """Return True if func is a decorated coroutine function."""
  15. return (inspect.iscoroutinefunction(func) or
  16. getattr(func, '_is_coroutine', None) is _is_coroutine)
  17. # Prioritize native coroutine check to speed-up
  18. # asyncio.iscoroutine.
  19. _COROUTINE_TYPES = (types.CoroutineType, collections.abc.Coroutine)
  20. _iscoroutine_typecache = set()
  21. def iscoroutine(obj):
  22. """Return True if obj is a coroutine object."""
  23. if type(obj) in _iscoroutine_typecache:
  24. return True
  25. if isinstance(obj, _COROUTINE_TYPES):
  26. # Just in case we don't want to cache more than 100
  27. # positive types. That shouldn't ever happen, unless
  28. # someone stressing the system on purpose.
  29. if len(_iscoroutine_typecache) < 100:
  30. _iscoroutine_typecache.add(type(obj))
  31. return True
  32. else:
  33. return False
  34. def _format_coroutine(coro):
  35. assert iscoroutine(coro)
  36. def get_name(coro):
  37. # Coroutines compiled with Cython sometimes don't have
  38. # proper __qualname__ or __name__. While that is a bug
  39. # in Cython, asyncio shouldn't crash with an AttributeError
  40. # in its __repr__ functions.
  41. if hasattr(coro, '__qualname__') and coro.__qualname__:
  42. coro_name = coro.__qualname__
  43. elif hasattr(coro, '__name__') and coro.__name__:
  44. coro_name = coro.__name__
  45. else:
  46. # Stop masking Cython bugs, expose them in a friendly way.
  47. coro_name = f'<{type(coro).__name__} without __name__>'
  48. return f'{coro_name}()'
  49. def is_running(coro):
  50. try:
  51. return coro.cr_running
  52. except AttributeError:
  53. try:
  54. return coro.gi_running
  55. except AttributeError:
  56. return False
  57. coro_code = None
  58. if hasattr(coro, 'cr_code') and coro.cr_code:
  59. coro_code = coro.cr_code
  60. elif hasattr(coro, 'gi_code') and coro.gi_code:
  61. coro_code = coro.gi_code
  62. coro_name = get_name(coro)
  63. if not coro_code:
  64. # Built-in types might not have __qualname__ or __name__.
  65. if is_running(coro):
  66. return f'{coro_name} running'
  67. else:
  68. return coro_name
  69. coro_frame = None
  70. if hasattr(coro, 'gi_frame') and coro.gi_frame:
  71. coro_frame = coro.gi_frame
  72. elif hasattr(coro, 'cr_frame') and coro.cr_frame:
  73. coro_frame = coro.cr_frame
  74. # If Cython's coroutine has a fake code object without proper
  75. # co_filename -- expose that.
  76. filename = coro_code.co_filename or '<empty co_filename>'
  77. lineno = 0
  78. if coro_frame is not None:
  79. lineno = coro_frame.f_lineno
  80. coro_repr = f'{coro_name} running at {filename}:{lineno}'
  81. else:
  82. lineno = coro_code.co_firstlineno
  83. coro_repr = f'{coro_name} done, defined at {filename}:{lineno}'
  84. return coro_repr