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