util.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #
  2. # Module providing various facilities to other parts of the package
  3. #
  4. # billiard/util.py
  5. #
  6. # Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
  7. # Licensed to PSF under a Contributor Agreement.
  8. #
  9. from __future__ import absolute_import
  10. import sys
  11. import errno
  12. import functools
  13. import atexit
  14. try:
  15. from subprocess import _args_from_interpreter_flags # noqa
  16. except ImportError: # pragma: no cover
  17. def _args_from_interpreter_flags(): # noqa
  18. """Return a list of command-line arguments reproducing the current
  19. settings in sys.flags and sys.warnoptions."""
  20. flag_opt_map = {
  21. 'debug': 'd',
  22. 'optimize': 'O',
  23. 'dont_write_bytecode': 'B',
  24. 'no_user_site': 's',
  25. 'no_site': 'S',
  26. 'ignore_environment': 'E',
  27. 'verbose': 'v',
  28. 'bytes_warning': 'b',
  29. 'hash_randomization': 'R',
  30. 'py3k_warning': '3',
  31. }
  32. args = []
  33. for flag, opt in flag_opt_map.items():
  34. v = getattr(sys.flags, flag)
  35. if v > 0:
  36. args.append('-' + opt * v)
  37. for opt in sys.warnoptions:
  38. args.append('-W' + opt)
  39. return args
  40. from multiprocessing.util import ( # noqa
  41. _afterfork_registry,
  42. _afterfork_counter,
  43. _exit_function,
  44. _finalizer_registry,
  45. _finalizer_counter,
  46. Finalize,
  47. ForkAwareLocal,
  48. ForkAwareThreadLock,
  49. get_temp_dir,
  50. is_exiting,
  51. register_after_fork,
  52. _run_after_forkers,
  53. _run_finalizers,
  54. )
  55. from .compat import get_errno
  56. __all__ = [
  57. 'sub_debug', 'debug', 'info', 'sub_warning', 'get_logger',
  58. 'log_to_stderr', 'get_temp_dir', 'register_after_fork',
  59. 'is_exiting', 'Finalize', 'ForkAwareThreadLock', 'ForkAwareLocal',
  60. 'SUBDEBUG', 'SUBWARNING',
  61. ]
  62. #
  63. # Logging
  64. #
  65. NOTSET = 0
  66. SUBDEBUG = 5
  67. DEBUG = 10
  68. INFO = 20
  69. SUBWARNING = 25
  70. ERROR = 40
  71. LOGGER_NAME = 'multiprocessing'
  72. DEFAULT_LOGGING_FORMAT = '[%(levelname)s/%(processName)s] %(message)s'
  73. _logger = None
  74. _log_to_stderr = False
  75. def sub_debug(msg, *args, **kwargs):
  76. if _logger:
  77. _logger.log(SUBDEBUG, msg, *args, **kwargs)
  78. def debug(msg, *args, **kwargs):
  79. if _logger:
  80. _logger.log(DEBUG, msg, *args, **kwargs)
  81. def info(msg, *args, **kwargs):
  82. if _logger:
  83. _logger.log(INFO, msg, *args, **kwargs)
  84. def sub_warning(msg, *args, **kwargs):
  85. if _logger:
  86. _logger.log(SUBWARNING, msg, *args, **kwargs)
  87. def error(msg, *args, **kwargs):
  88. if _logger:
  89. _logger.log(ERROR, msg, *args, **kwargs)
  90. def get_logger():
  91. '''
  92. Returns logger used by multiprocessing
  93. '''
  94. global _logger
  95. import logging
  96. logging._acquireLock()
  97. try:
  98. if not _logger:
  99. _logger = logging.getLogger(LOGGER_NAME)
  100. _logger.propagate = 0
  101. logging.addLevelName(SUBDEBUG, 'SUBDEBUG')
  102. logging.addLevelName(SUBWARNING, 'SUBWARNING')
  103. # XXX multiprocessing should cleanup before logging
  104. if hasattr(atexit, 'unregister'):
  105. atexit.unregister(_exit_function)
  106. atexit.register(_exit_function)
  107. else:
  108. atexit._exithandlers.remove((_exit_function, (), {}))
  109. atexit._exithandlers.append((_exit_function, (), {}))
  110. finally:
  111. logging._releaseLock()
  112. return _logger
  113. def log_to_stderr(level=None):
  114. '''
  115. Turn on logging and add a handler which prints to stderr
  116. '''
  117. global _log_to_stderr
  118. import logging
  119. logger = get_logger()
  120. formatter = logging.Formatter(DEFAULT_LOGGING_FORMAT)
  121. handler = logging.StreamHandler()
  122. handler.setFormatter(formatter)
  123. logger.addHandler(handler)
  124. if level:
  125. logger.setLevel(level)
  126. _log_to_stderr = True
  127. return _logger
  128. def _eintr_retry(func):
  129. '''
  130. Automatic retry after EINTR.
  131. '''
  132. @functools.wraps(func)
  133. def wrapped(*args, **kwargs):
  134. while 1:
  135. try:
  136. return func(*args, **kwargs)
  137. except OSError as exc:
  138. if get_errno(exc) != errno.EINTR:
  139. raise
  140. return wrapped