configuration.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. """
  2. Configuration settings.
  3. Pyro - Python Remote Objects. Copyright by Irmen de Jong (irmen@razorvine.net).
  4. """
  5. # Env vars used at package import time (see __init__.py):
  6. # PYRO_LOGLEVEL (enable Pyro log config and set level)
  7. # PYRO_LOGFILE (the name of the logfile if you don't like the default)
  8. import os
  9. import platform
  10. import pickle
  11. import socket
  12. import Pyro4.constants
  13. class Configuration(object):
  14. __slots__ = ("HOST", "NS_HOST", "NS_PORT", "NS_BCPORT", "NS_BCHOST", "NS_AUTOCLEAN",
  15. "COMPRESSION", "SERVERTYPE", "COMMTIMEOUT",
  16. "POLLTIMEOUT", "THREADING2", "ONEWAY_THREADED",
  17. "DETAILED_TRACEBACK", "SOCK_REUSE", "SOCK_NODELAY", "PREFER_IP_VERSION",
  18. "THREADPOOL_SIZE", "THREADPOOL_SIZE_MIN", "AUTOPROXY", "PICKLE_PROTOCOL_VERSION",
  19. "BROADCAST_ADDRS", "NATHOST", "NATPORT", "MAX_MESSAGE_SIZE",
  20. "FLAME_ENABLED", "SERIALIZER", "SERIALIZERS_ACCEPTED", "LOGWIRE",
  21. "METADATA", "REQUIRE_EXPOSE", "USE_MSG_WAITALL", "JSON_MODULE",
  22. "MAX_RETRIES", "DILL_PROTOCOL_VERSION", "ITER_STREAMING", "ITER_STREAM_LIFETIME",
  23. "ITER_STREAM_LINGER")
  24. def __init__(self):
  25. self.reset()
  26. def reset(self, useenvironment=True):
  27. """
  28. Set default config items.
  29. If useenvironment is False, won't read environment variables settings (useful if you can't trust your env).
  30. """
  31. self.HOST = "localhost" # don't expose us to the outside world by default
  32. self.NS_HOST = self.HOST
  33. self.NS_PORT = 9090 # tcp
  34. self.NS_BCPORT = 9091 # udp
  35. self.NS_BCHOST = None
  36. self.NS_AUTOCLEAN = 0.0
  37. self.NATHOST = None
  38. self.NATPORT = 0
  39. self.COMPRESSION = False
  40. self.SERVERTYPE = "thread"
  41. self.COMMTIMEOUT = 0.0
  42. self.POLLTIMEOUT = 2.0 # seconds
  43. self.SOCK_REUSE = True # so_reuseaddr on server sockets?
  44. self.SOCK_NODELAY = False # tcp_nodelay on socket?
  45. self.THREADING2 = False # use threading2 if available?
  46. self.ONEWAY_THREADED = True # oneway calls run in their own thread
  47. self.DETAILED_TRACEBACK = False
  48. self.THREADPOOL_SIZE = 40
  49. self.THREADPOOL_SIZE_MIN = 4
  50. self.AUTOPROXY = True
  51. self.MAX_MESSAGE_SIZE = 0 # 0 = unlimited
  52. self.BROADCAST_ADDRS = "<broadcast>, 0.0.0.0" # comma separated list of broadcast addresses
  53. self.FLAME_ENABLED = False
  54. self.PREFER_IP_VERSION = 4 # 4, 6 or 0 (let OS choose according to RFC 3484)
  55. self.SERIALIZER = "serpent"
  56. self.SERIALIZERS_ACCEPTED = "serpent,marshal,json" # these are the 'safe' serializers
  57. self.LOGWIRE = False # log wire-level messages
  58. self.PICKLE_PROTOCOL_VERSION = pickle.HIGHEST_PROTOCOL
  59. try:
  60. import platform
  61. if platform.python_implementation() in ('PyPy', 'IronPython'):
  62. raise ImportError('Currently dill is not supported with PyPy and IronPython')
  63. import dill
  64. self.DILL_PROTOCOL_VERSION = dill.HIGHEST_PROTOCOL # Highest protocol
  65. except ImportError:
  66. self.DILL_PROTOCOL_VERSION = -1
  67. self.METADATA = True # get metadata from server on proxy connect
  68. self.REQUIRE_EXPOSE = True # require @expose to make members remotely accessible (if False, everything is accessible)
  69. self.USE_MSG_WAITALL = hasattr(socket, "MSG_WAITALL") and platform.system() != "Windows" # not reliable on windows even though it is defined
  70. self.JSON_MODULE = "json"
  71. self.MAX_RETRIES = 0
  72. self.ITER_STREAMING = True
  73. self.ITER_STREAM_LIFETIME = 0.0
  74. self.ITER_STREAM_LINGER = 30.0
  75. if useenvironment:
  76. # process environment variables
  77. PREFIX = "PYRO_"
  78. for symbol in self.__slots__:
  79. if PREFIX + symbol in os.environ:
  80. value = getattr(self, symbol)
  81. envvalue = os.environ[PREFIX + symbol]
  82. if value is not None:
  83. valuetype = type(value)
  84. if valuetype is bool:
  85. # booleans are special
  86. envvalue = envvalue.lower()
  87. if envvalue in ("0", "off", "no", "false"):
  88. envvalue = False
  89. elif envvalue in ("1", "yes", "on", "true"):
  90. envvalue = True
  91. else:
  92. raise ValueError("invalid boolean value: %s%s=%s" % (PREFIX, symbol, envvalue))
  93. else:
  94. envvalue = valuetype(envvalue) # just cast the value to the appropriate type
  95. setattr(self, symbol, envvalue)
  96. self.SERIALIZERS_ACCEPTED = set(self.SERIALIZERS_ACCEPTED.split(','))
  97. def asDict(self):
  98. """returns the current config as a regular dictionary"""
  99. result = {}
  100. for item in self.__slots__:
  101. result[item] = getattr(self, item)
  102. return result
  103. def parseAddressesString(self, addresses):
  104. """
  105. Parses the addresses string which contains one or more ip addresses separated by a comma.
  106. Returns a sequence of these addresses. '' is replaced by the empty string.
  107. """
  108. result = []
  109. for addr in addresses.split(','):
  110. addr = addr.strip()
  111. if addr == "''":
  112. addr = ""
  113. result.append(addr)
  114. return result
  115. def dump(self):
  116. # easy config diagnostics
  117. from Pyro4.constants import VERSION
  118. import inspect
  119. if hasattr(platform, "python_implementation"):
  120. implementation = platform.python_implementation()
  121. else:
  122. implementation = "???"
  123. config = self.asDict()
  124. config["LOGFILE"] = os.environ.get("PYRO_LOGFILE")
  125. config["LOGLEVEL"] = os.environ.get("PYRO_LOGLEVEL")
  126. result = ["Pyro version: %s" % VERSION,
  127. "Loaded from: %s" % os.path.abspath(os.path.split(inspect.getfile(Configuration))[0]),
  128. "Python version: %s %s (%s, %s)" % (implementation, platform.python_version(), platform.system(), os.name),
  129. "Protocol version: %d" % Pyro4.constants.PROTOCOL_VERSION,
  130. "Currently active configuration settings:"]
  131. for n, v in sorted(config.items()):
  132. result.append("%s = %s" % (n, v))
  133. return "\n".join(result)
  134. def configuration_dump():
  135. print(Configuration().dump())
  136. if __name__ == "__main__":
  137. configuration_dump()