PageRenderTime 61ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

/pypy/config/pypyoption.py

https://bitbucket.org/pypy/pypy/
Python | 299 lines | 233 code | 43 blank | 23 comment | 20 complexity | 78eba98facd1404512214617a8d3b3da MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import os
  2. import sys
  3. import py
  4. from rpython.config.config import (OptionDescription, BoolOption, IntOption,
  5. ChoiceOption, StrOption, to_optparse)
  6. from rpython.config.translationoption import IS_64_BITS
  7. modulepath = py.path.local(__file__).dirpath().dirpath().join("module")
  8. all_modules = [p.basename for p in modulepath.listdir()
  9. if p.check(dir=True, dotfile=False)
  10. and p.join('__init__.py').check()
  11. and not p.basename.startswith('test')]
  12. essential_modules = set([
  13. "exceptions", "_file", "sys", "__builtin__", "posix", "_warnings",
  14. "itertools"
  15. ])
  16. default_modules = essential_modules.copy()
  17. default_modules.update([
  18. "_codecs", "gc", "_weakref", "marshal", "errno", "imp", "math", "cmath",
  19. "_sre", "_pickle_support", "operator", "parser", "symbol", "token", "_ast",
  20. "_io", "_random", "__pypy__", "_testing", "time"
  21. ])
  22. # --allworkingmodules
  23. working_modules = default_modules.copy()
  24. working_modules.update([
  25. "_socket", "unicodedata", "mmap", "fcntl", "_locale", "pwd",
  26. "select", "zipimport", "_lsprof", "crypt", "signal", "_rawffi", "termios",
  27. "zlib", "bz2", "struct", "_hashlib", "_md5", "_sha", "_minimal_curses",
  28. "cStringIO", "thread", "itertools", "pyexpat", "_ssl", "cpyext", "array",
  29. "binascii", "_multiprocessing", '_warnings', "_collections",
  30. "_multibytecodec", "micronumpy", "_continuation", "_cffi_backend",
  31. "_csv", "cppyy", "_pypyjson", "_jitlog"
  32. ])
  33. from rpython.jit.backend import detect_cpu
  34. try:
  35. if detect_cpu.autodetect().startswith('x86'):
  36. working_modules.add('_vmprof')
  37. except detect_cpu.ProcessorAutodetectError:
  38. pass
  39. translation_modules = default_modules.copy()
  40. translation_modules.update([
  41. "fcntl", "time", "select", "signal", "_rawffi", "zlib", "struct", "_md5",
  42. "cStringIO", "array", "binascii",
  43. # the following are needed for pyrepl (and hence for the
  44. # interactive prompt/pdb)
  45. "termios", "_minimal_curses",
  46. ])
  47. # XXX this should move somewhere else, maybe to platform ("is this posixish"
  48. # check or something)
  49. if sys.platform == "win32":
  50. working_modules.add("_winreg")
  51. # unix only modules
  52. for name in ["crypt", "fcntl", "pwd", "termios", "_minimal_curses"]:
  53. working_modules.remove(name)
  54. if name in translation_modules:
  55. translation_modules.remove(name)
  56. if "cppyy" in working_modules:
  57. working_modules.remove("cppyy") # not tested on win32
  58. # The _locale module is needed by site.py on Windows
  59. default_modules.add("_locale")
  60. if sys.platform == "sunos5":
  61. working_modules.remove('fcntl') # LOCK_NB not defined
  62. working_modules.remove("_minimal_curses")
  63. working_modules.remove("termios")
  64. if "cppyy" in working_modules:
  65. working_modules.remove("cppyy") # depends on ctypes
  66. #if sys.platform.startswith("linux"):
  67. # _mach = os.popen('uname -m', 'r').read().strip()
  68. # if _mach.startswith(...):
  69. # working_modules.remove("_continuation")
  70. module_dependencies = {
  71. '_multiprocessing': [('objspace.usemodules.time', True),
  72. ('objspace.usemodules.thread', True)],
  73. 'cpyext': [('objspace.usemodules.array', True)],
  74. 'cppyy': [('objspace.usemodules.cpyext', True)],
  75. }
  76. module_suggests = {
  77. # the reason you want _rawffi is for ctypes, which
  78. # itself needs the interp-level struct module
  79. # because 'P' is missing from the app-level one
  80. "_rawffi": [("objspace.usemodules.struct", True)],
  81. "cpyext": [("translation.secondaryentrypoints", "cpyext,main")],
  82. }
  83. if sys.platform == "win32":
  84. module_suggests["cpyext"].append(("translation.shared", True))
  85. # NOTE: this dictionary is not used any more
  86. module_import_dependencies = {
  87. # no _rawffi if importing rpython.rlib.clibffi raises ImportError
  88. # or CompilationError or py.test.skip.Exception
  89. "_rawffi" : ["rpython.rlib.clibffi"],
  90. "zlib" : ["rpython.rlib.rzlib"],
  91. "bz2" : ["pypy.module.bz2.interp_bz2"],
  92. "pyexpat" : ["pypy.module.pyexpat.interp_pyexpat"],
  93. "_ssl" : ["pypy.module._ssl.interp_ssl"],
  94. "_hashlib" : ["pypy.module._ssl.interp_ssl"],
  95. "_minimal_curses": ["pypy.module._minimal_curses.fficurses"],
  96. "_continuation": ["rpython.rlib.rstacklet"],
  97. "_vmprof" : ["pypy.module._vmprof.interp_vmprof"],
  98. }
  99. def get_module_validator(modname):
  100. # NOTE: this function is not used any more
  101. if modname in module_import_dependencies:
  102. modlist = module_import_dependencies[modname]
  103. def validator(config):
  104. from rpython.rtyper.tool.rffi_platform import CompilationError
  105. try:
  106. for name in modlist:
  107. __import__(name)
  108. except (ImportError, CompilationError, py.test.skip.Exception) as e:
  109. errcls = e.__class__.__name__
  110. raise Exception(
  111. "The module %r is disabled\n" % (modname,) +
  112. "because importing %s raised %s\n" % (name, errcls) +
  113. str(e))
  114. return validator
  115. else:
  116. return None
  117. pypy_optiondescription = OptionDescription("objspace", "Object Space Options", [
  118. OptionDescription("usemodules", "Which Modules should be used", [
  119. BoolOption(modname, "use module %s" % (modname, ),
  120. default=modname in default_modules,
  121. cmdline="--withmod-%s" % (modname, ),
  122. requires=module_dependencies.get(modname, []),
  123. suggests=module_suggests.get(modname, []),
  124. negation=modname not in essential_modules,
  125. ) #validator=get_module_validator(modname))
  126. for modname in all_modules]),
  127. BoolOption("allworkingmodules", "use as many working modules as possible",
  128. # NB. defaults to True, but in py.py this is overridden by
  129. # a False suggestion because it takes a while to start up.
  130. # Actual module enabling only occurs if
  131. # enable_allworkingmodules() is called, and it depends
  132. # on the selected backend.
  133. default=True,
  134. cmdline="--allworkingmodules",
  135. negation=True),
  136. StrOption("extmodules",
  137. "Comma-separated list of third-party builtin modules",
  138. cmdline="--ext",
  139. default=None),
  140. BoolOption("translationmodules",
  141. "use only those modules that are needed to run translate.py on pypy",
  142. default=False,
  143. cmdline="--translationmodules",
  144. suggests=[("objspace.allworkingmodules", False)]),
  145. BoolOption("lonepycfiles", "Import pyc files with no matching py file",
  146. default=False),
  147. StrOption("soabi",
  148. "Tag to differentiate extension modules built for different Python interpreters",
  149. cmdline="--soabi",
  150. default=None),
  151. BoolOption("honor__builtins__",
  152. "Honor the __builtins__ key of a module dictionary",
  153. default=False),
  154. BoolOption("disable_call_speedhacks",
  155. "make sure that all calls go through space.call_args",
  156. default=False),
  157. OptionDescription("std", "Standard Object Space Options", [
  158. BoolOption("withtproxy", "support transparent proxies",
  159. default=True),
  160. BoolOption("withprebuiltint", "prebuild commonly used int objects",
  161. default=False),
  162. IntOption("prebuiltintfrom", "lowest integer which is prebuilt",
  163. default=-5, cmdline="--prebuiltintfrom"),
  164. IntOption("prebuiltintto", "highest integer which is prebuilt",
  165. default=100, cmdline="--prebuiltintto"),
  166. BoolOption("withsmalllong", "use a version of 'long' in a C long long",
  167. default=False),
  168. BoolOption("withstrbuf", "use strings optimized for addition (ver 2)",
  169. default=False),
  170. BoolOption("withspecialisedtuple",
  171. "use specialised tuples",
  172. default=False),
  173. BoolOption("withcelldict",
  174. "use dictionaries that are optimized for being used as module dicts",
  175. default=False,
  176. requires=[("objspace.honor__builtins__", False)]),
  177. BoolOption("withliststrategies",
  178. "enable optimized ways to store lists of primitives ",
  179. default=True),
  180. BoolOption("withmethodcachecounter",
  181. "try to cache methods and provide a counter in __pypy__. "
  182. "for testing purposes only.",
  183. default=False),
  184. IntOption("methodcachesizeexp",
  185. " 2 ** methodcachesizeexp is the size of the of the method cache ",
  186. default=11),
  187. BoolOption("intshortcut",
  188. "special case addition and subtraction of two integers in BINARY_ADD/"
  189. "/BINARY_SUBTRACT and their inplace counterparts",
  190. default=False),
  191. BoolOption("optimized_list_getitem",
  192. "special case the 'list[integer]' expressions",
  193. default=False),
  194. BoolOption("newshortcut",
  195. "cache and shortcut calling __new__ from builtin types",
  196. default=False),
  197. ]),
  198. ])
  199. def get_pypy_config(overrides=None, translating=False):
  200. from rpython.config.translationoption import get_combined_translation_config
  201. return get_combined_translation_config(
  202. pypy_optiondescription, overrides=overrides,
  203. translating=translating)
  204. def set_pypy_opt_level(config, level):
  205. """Apply PyPy-specific optimization suggestions on the 'config'.
  206. The optimizations depend on the selected level and possibly on the backend.
  207. """
  208. # all the good optimizations for PyPy should be listed here
  209. if level in ['2', '3', 'jit']:
  210. config.objspace.std.suggest(intshortcut=True)
  211. config.objspace.std.suggest(optimized_list_getitem=True)
  212. #config.objspace.std.suggest(newshortcut=True)
  213. config.objspace.std.suggest(withspecialisedtuple=True)
  214. #if not IS_64_BITS:
  215. # config.objspace.std.suggest(withsmalllong=True)
  216. # extra costly optimizations only go in level 3
  217. if level == '3':
  218. config.translation.suggest(profopt=
  219. "-c 'from richards import main;main(); "
  220. "from test import pystone; pystone.main()'")
  221. # memory-saving optimizations
  222. if level == 'mem':
  223. config.objspace.std.suggest(withprebuiltint=True)
  224. config.objspace.std.suggest(withliststrategies=True)
  225. if not IS_64_BITS:
  226. config.objspace.std.suggest(withsmalllong=True)
  227. # extra optimizations with the JIT
  228. if level == 'jit':
  229. config.objspace.std.suggest(withcelldict=True)
  230. def enable_allworkingmodules(config):
  231. modules = working_modules.copy()
  232. if config.translation.sandbox:
  233. modules = default_modules
  234. # ignore names from 'essential_modules', notably 'exceptions', which
  235. # may not be present in config.objspace.usemodules at all
  236. modules = [name for name in modules if name not in essential_modules]
  237. config.objspace.usemodules.suggest(**dict.fromkeys(modules, True))
  238. def enable_translationmodules(config):
  239. modules = translation_modules
  240. modules = [name for name in modules if name not in essential_modules]
  241. config.objspace.usemodules.suggest(**dict.fromkeys(modules, True))
  242. if __name__ == '__main__':
  243. config = get_pypy_config()
  244. print config.getpaths()
  245. parser = to_optparse(config) #, useoptions=["translation.*"])
  246. option, args = parser.parse_args()
  247. print config