mandatory or type error raised

This commit is contained in:
gwen 2012-09-12 10:38:41 +02:00
parent c6ad86bd81
commit e2bcac1c01
5 changed files with 237 additions and 234 deletions

View File

@ -1,258 +1,258 @@
#just a proof of concept with a lot of options and option groups ##just a proof of concept with a lot of options and option groups
import autopath #import autopath
from tiramisu.config import * #from tiramisu.config import *
from tiramisu.option import * #from tiramisu.option import *
all_modules = ['amon', 'sphynx', 'zephir'] #all_modules = ['amon', 'sphynx', 'zephir']
example__optiondescription = OptionDescription("objspace", "Object Space Options", [ #example__optiondescription = OptionDescription("objspace", "Object Space Options", [
ChoiceOption("name", "Object Space name", # ChoiceOption("name", "Object Space name",
["std", "flow", "thunk", "dump", "taint"], # ["std", "flow", "thunk", "dump", "taint"],
"std"), # "std"),
OptionDescription("opcodes", "opcodes to enable in the interpreter", [ # OptionDescription("opcodes", "opcodes to enable in the interpreter", [
BoolOption("CALL_LIKELY_BUILTIN", "emit a special bytecode for likely calls to builtin functions", # BoolOption("CALL_LIKELY_BUILTIN", "emit a special bytecode for likely calls to builtin functions",
default=False, # default=False,
requires=[("translation.stackless", False)]), # requires=[("translation.stackless", False)]),
BoolOption("CALL_METHOD", "emit a special bytecode for expr.name()", # BoolOption("CALL_METHOD", "emit a special bytecode for expr.name()",
default=False), # default=False),
]), # ]),
BoolOption("nofaking", "disallow faking in the object space", # BoolOption("nofaking", "disallow faking in the object space",
default=False, # default=False,
requires=[ # requires=[
("objspace.usemodules.posix", True), # ("objspace.usemodules.posix", True),
("objspace.usemodules.time", True), # ("objspace.usemodules.time", True),
("objspace.usemodules.errno", True)], # ("objspace.usemodules.errno", True)],
), # ),
OptionDescription("usemodules", "Which Modules should be used", [ # OptionDescription("usemodules", "Which Modules should be used", [
BoolOption(modname, "use module %s" % (modname, ), # BoolOption(modname, "use module %s" % (modname, ),
default=True, # default=True,
requires= ['amon'], # requires= [('amon', False)],
) # )
for modname in all_modules]), # for modname in all_modules]),
BoolOption("allworkingmodules", "use as many working modules as possible", # BoolOption("allworkingmodules", "use as many working modules as possible",
default=True, # default=True,
), # ),
BoolOption("translationmodules", # BoolOption("translationmodules",
"use only those modules that are needed to run translate.py on pypy", # "use only those modules that are needed to run translate.py on pypy",
default=False, # default=False,
), # ),
BoolOption("geninterp", "specify whether geninterp should be used", # BoolOption("geninterp", "specify whether geninterp should be used",
default=True), # default=True),
BoolOption("logbytecodes", # BoolOption("logbytecodes",
"keep track of bytecode usage", # "keep track of bytecode usage",
default=False), # default=False),
BoolOption("usepycfiles", "Write and read pyc files when importing", # BoolOption("usepycfiles", "Write and read pyc files when importing",
default=True), # default=True),
BoolOption("lonepycfiles", "Import pyc files with no matching py file", # BoolOption("lonepycfiles", "Import pyc files with no matching py file",
default=False, # default=False,
requires=[("objspace.usepycfiles", True)]), # requires=[("objspace.usepycfiles", True)]),
StrOption("soabi", # StrOption("soabi",
"Tag to differentiate extension modules built for different Python interpreters", # "Tag to differentiate extension modules built for different Python interpreters",
default=None), # default=None),
BoolOption("honor__builtins__", # BoolOption("honor__builtins__",
"Honor the __builtins__ key of a module dictionary", # "Honor the __builtins__ key of a module dictionary",
default=False), # default=False),
BoolOption("disable_call_speedhacks", # BoolOption("disable_call_speedhacks",
"make sure that all calls go through space.call_args", # "make sure that all calls go through space.call_args",
default=False), # default=False),
BoolOption("timing", # BoolOption("timing",
"timing of various parts of the interpreter (simple profiling)", # "timing of various parts of the interpreter (simple profiling)",
default=False), # default=False),
OptionDescription("std", "Standard Object Space Options", [ # OptionDescription("std", "Standard Object Space Options", [
BoolOption("withtproxy", "support transparent proxies", # BoolOption("withtproxy", "support transparent proxies",
default=True), # default=True),
BoolOption("withsmallint", "use tagged integers", # BoolOption("withsmallint", "use tagged integers",
default=False, # default=False,
requires=[("objspace.std.withprebuiltint", False), # requires=[("objspace.std.withprebuiltint", False),
("translation.taggedpointers", True)]), # ("translation.taggedpointers", True)]),
BoolOption("withprebuiltint", "prebuild commonly used int objects", # BoolOption("withprebuiltint", "prebuild commonly used int objects",
default=False), # default=False),
IntOption("prebuiltintfrom", "lowest integer which is prebuilt", # IntOption("prebuiltintfrom", "lowest integer which is prebuilt",
default=-5), # default=-5),
IntOption("prebuiltintto", "highest integer which is prebuilt", # IntOption("prebuiltintto", "highest integer which is prebuilt",
default=100), # default=100),
BoolOption("withstrjoin", "use strings optimized for addition", # BoolOption("withstrjoin", "use strings optimized for addition",
default=False), # default=False),
BoolOption("withstrslice", "use strings optimized for slicing", # BoolOption("withstrslice", "use strings optimized for slicing",
default=False), # default=False),
BoolOption("withstrbuf", "use strings optimized for addition (ver 2)", # BoolOption("withstrbuf", "use strings optimized for addition (ver 2)",
default=False), # default=False),
BoolOption("withprebuiltchar", # BoolOption("withprebuiltchar",
"use prebuilt single-character string objects", # "use prebuilt single-character string objects",
default=False), # default=False),
BoolOption("sharesmallstr", # BoolOption("sharesmallstr",
"always reuse the prebuilt string objects " # "always reuse the prebuilt string objects "
"(the empty string and potentially single-char strings)", # "(the empty string and potentially single-char strings)",
default=False), # default=False),
BoolOption("withrope", "use ropes as the string implementation", # BoolOption("withrope", "use ropes as the string implementation",
default=False, # default=False,
requires=[("objspace.std.withstrslice", False), # requires=[("objspace.std.withstrslice", False),
("objspace.std.withstrjoin", False), # ("objspace.std.withstrjoin", False),
("objspace.std.withstrbuf", False)], # ("objspace.std.withstrbuf", False)],
), # ),
BoolOption("withropeunicode", "use ropes for the unicode implementation", # BoolOption("withropeunicode", "use ropes for the unicode implementation",
default=False, # default=False,
requires=[("objspace.std.withrope", True)]), # requires=[("objspace.std.withrope", True)]),
BoolOption("withcelldict", # BoolOption("withcelldict",
"use dictionaries that are optimized for being used as module dicts", # "use dictionaries that are optimized for being used as module dicts",
default=False, # default=False,
requires=[("objspace.opcodes.CALL_LIKELY_BUILTIN", False), # requires=[("objspace.opcodes.CALL_LIKELY_BUILTIN", False),
("objspace.honor__builtins__", False)]), # ("objspace.honor__builtins__", False)]),
BoolOption("withdictmeasurement", # BoolOption("withdictmeasurement",
"create huge files with masses of information " # "create huge files with masses of information "
"about dictionaries", # "about dictionaries",
default=False), # default=False),
BoolOption("withmapdict", # BoolOption("withmapdict",
"make instances really small but slow without the JIT", # "make instances really small but slow without the JIT",
default=False, # default=False,
requires=[("objspace.std.getattributeshortcut", True), # requires=[("objspace.std.getattributeshortcut", True),
("objspace.std.withtypeversion", True), # ("objspace.std.withtypeversion", True),
]), # ]),
BoolOption("withrangelist", # BoolOption("withrangelist",
"enable special range list implementation that does not " # "enable special range list implementation that does not "
"actually create the full list until the resulting " # "actually create the full list until the resulting "
"list is mutated", # "list is mutated",
default=False), # default=False),
BoolOption("withtypeversion", # BoolOption("withtypeversion",
"version type objects when changing them", # "version type objects when changing them",
default=False, # default=False,
# weakrefs needed, because of get_subclasses() # # weakrefs needed, because of get_subclasses()
requires=[("translation.rweakref", True)]), # requires=[("translation.rweakref", True)]),
BoolOption("withmethodcache", # BoolOption("withmethodcache",
"try to cache method lookups", # "try to cache method lookups",
default=False, # default=False,
requires=[("objspace.std.withtypeversion", True), # requires=[("objspace.std.withtypeversion", True),
("translation.rweakref", True)]), # ("translation.rweakref", True)]),
BoolOption("withmethodcachecounter", # BoolOption("withmethodcachecounter",
"try to cache methods and provide a counter in __pypy__. " # "try to cache methods and provide a counter in __pypy__. "
"for testing purposes only.", # "for testing purposes only.",
default=False, # default=False,
requires=[("objspace.std.withmethodcache", True)]), # requires=[("objspace.std.withmethodcache", True)]),
IntOption("methodcachesizeexp", # IntOption("methodcachesizeexp",
" 2 ** methodcachesizeexp is the size of the of the method cache ", # " 2 ** methodcachesizeexp is the size of the of the method cache ",
default=11), # default=11),
BoolOption("optimized_int_add", # BoolOption("optimized_int_add",
"special case the addition of two integers in BINARY_ADD", # "special case the addition of two integers in BINARY_ADD",
default=False), # default=False),
BoolOption("optimized_comparison_op", # BoolOption("optimized_comparison_op",
"special case the comparison of integers", # "special case the comparison of integers",
default=False), # default=False),
BoolOption("optimized_list_getitem", # BoolOption("optimized_list_getitem",
"special case the 'list[integer]' expressions", # "special case the 'list[integer]' expressions",
default=False), # default=False),
BoolOption("builtinshortcut", # BoolOption("builtinshortcut",
"a shortcut for operations between built-in types", # "a shortcut for operations between built-in types",
default=False), # default=False),
BoolOption("getattributeshortcut", # BoolOption("getattributeshortcut",
"track types that override __getattribute__", # "track types that override __getattribute__",
default=False), # default=False),
BoolOption("newshortcut", # BoolOption("newshortcut",
"cache and shortcut calling __new__ from builtin types", # "cache and shortcut calling __new__ from builtin types",
default=False), # default=False),
BoolOption("logspaceoptypes", # BoolOption("logspaceoptypes",
"a instrumentation option: before exit, print the types seen by " # "a instrumentation option: before exit, print the types seen by "
"certain simpler bytecodes", # "certain simpler bytecodes",
default=False), # default=False),
ChoiceOption("multimethods", "the multimethod implementation to use", # ChoiceOption("multimethods", "the multimethod implementation to use",
["doubledispatch", "mrd"], # ["doubledispatch", "mrd"],
default="mrd"), # default="mrd"),
BoolOption("immutable_builtintypes", # BoolOption("immutable_builtintypes",
"Forbid the changing of builtin types", default=True), # "Forbid the changing of builtin types", default=True),
]), # ]),
]) #])
# ____________________________________________________________ ## ____________________________________________________________
def get_combined_translation_config(other_optdescr=None, #def get_combined_translation_config(other_optdescr=None,
existing_config=None, # existing_config=None,
overrides=None, # overrides=None,
translating=False): # translating=False):
if overrides is None: # if overrides is None:
overrides = {} # overrides = {}
d = BoolOption("translating", # d = BoolOption("translating",
"indicates whether we are translating currently", # "indicates whether we are translating currently",
default=False) # default=False)
if other_optdescr is None: # if other_optdescr is None:
children = [] # children = []
newname = "" # newname = ""
else: # else:
children = [other_optdescr] # children = [other_optdescr]
newname = other_optdescr._name # newname = other_optdescr._name
descr = OptionDescription("eole", "all options", children) # descr = OptionDescription("eole", "all options", children)
config = Config(descr, **overrides) # config = Config(descr, **overrides)
if translating: # if translating:
config.translating = True # config.translating = True
if existing_config is not None: # if existing_config is not None:
for child in existing_config._cfgimpl_descr._children: # for child in existing_config._cfgimpl_descr._children:
if child._name == newname: # if child._name == newname:
continue # continue
value = getattr(existing_config, child._name) # value = getattr(existing_config, child._name)
config._cfgimpl_values[child._name] = value # config._cfgimpl_values[child._name] = value
return config # return config
def get_example_config(overrides=None, translating=False): #def get_example_config(overrides=None, translating=False):
return get_combined_translation_config( # return get_combined_translation_config(
example__optiondescription, overrides=overrides, # example__optiondescription, overrides=overrides,
translating=translating) # translating=translating)
# ____________________________________________________________ ## ____________________________________________________________
def test_example_option(): #def test_example_option():
config = get_example_config() # config = get_example_config()
result = ['objspace.name', 'objspace.opcodes.CALL_LIKELY_BUILTIN', # result = ['objspace.name', 'objspace.opcodes.CALL_LIKELY_BUILTIN',
'objspace.opcodes.CALL_METHOD', 'objspace.nofaking', # 'objspace.opcodes.CALL_METHOD', 'objspace.nofaking',
'objspace.usemodules.amon', 'objspace.usemodules.sphynx', # 'objspace.usemodules.amon', 'objspace.usemodules.sphynx',
'objspace.usemodules.zephir', 'objspace.allworkingmodules', # 'objspace.usemodules.zephir', 'objspace.allworkingmodules',
'objspace.translationmodules', 'objspace.geninterp', # 'objspace.translationmodules', 'objspace.geninterp',
'objspace.logbytecodes', 'objspace.usepycfiles', 'objspace.lonepycfiles', # 'objspace.logbytecodes', 'objspace.usepycfiles', 'objspace.lonepycfiles',
'objspace.soabi', 'objspace.honor__builtins__', # 'objspace.soabi', 'objspace.honor__builtins__',
'objspace.disable_call_speedhacks', 'objspace.timing', # 'objspace.disable_call_speedhacks', 'objspace.timing',
'objspace.std.withtproxy', 'objspace.std.withsmallint', # 'objspace.std.withtproxy', 'objspace.std.withsmallint',
'objspace.std.withprebuiltint', 'objspace.std.prebuiltintfrom', # 'objspace.std.withprebuiltint', 'objspace.std.prebuiltintfrom',
'objspace.std.prebuiltintto', 'objspace.std.withstrjoin', # 'objspace.std.prebuiltintto', 'objspace.std.withstrjoin',
'objspace.std.withstrslice', 'objspace.std.withstrbuf', # 'objspace.std.withstrslice', 'objspace.std.withstrbuf',
'objspace.std.withprebuiltchar', 'objspace.std.sharesmallstr', # 'objspace.std.withprebuiltchar', 'objspace.std.sharesmallstr',
'objspace.std.withrope', 'objspace.std.withropeunicode', # 'objspace.std.withrope', 'objspace.std.withropeunicode',
'objspace.std.withcelldict', 'objspace.std.withdictmeasurement', # 'objspace.std.withcelldict', 'objspace.std.withdictmeasurement',
'objspace.std.withmapdict', 'objspace.std.withrangelist', # 'objspace.std.withmapdict', 'objspace.std.withrangelist',
'objspace.std.withtypeversion', 'objspace.std.withmethodcache', # 'objspace.std.withtypeversion', 'objspace.std.withmethodcache',
'objspace.std.withmethodcachecounter', 'objspace.std.methodcachesizeexp', # 'objspace.std.withmethodcachecounter', 'objspace.std.methodcachesizeexp',
'objspace.std.optimized_int_add', 'objspace.std.optimized_comparison_op', # 'objspace.std.optimized_int_add', 'objspace.std.optimized_comparison_op',
'objspace.std.optimized_list_getitem', 'objspace.std.builtinshortcut', # 'objspace.std.optimized_list_getitem', 'objspace.std.builtinshortcut',
'objspace.std.getattributeshortcut', 'objspace.std.newshortcut', # 'objspace.std.getattributeshortcut', 'objspace.std.newshortcut',
'objspace.std.logspaceoptypes', 'objspace.std.multimethods', # 'objspace.std.logspaceoptypes', 'objspace.std.multimethods',
'objspace.std.immutable_builtintypes'] # 'objspace.std.immutable_builtintypes']
assert config.getpaths(allpaths=True) == result # assert config.getpaths(allpaths=True) == result

View File

@ -71,15 +71,16 @@ def test_has_callback():
# here the owner is 'default' # here the owner is 'default'
config = Config(descr, bool=False) config = Config(descr, bool=False)
# because dummy has a callback # because dummy has a callback
raises(ConflictConfigError, "config.gc.dummy = True") raises(TypeError, "config.gc.dummy = True")
#____________________________________________________________ #____________________________________________________________
def test_has_callback_with_setoption(): def test_has_callback_with_setoption():
descr = make_description() descr = make_description()
config = Config(descr, bool=False) config = Config(descr, bool=False)
raises(ConflictConfigError, "config.gc.setoption('dummy', True, 'gen_config')") raises(TypeError, "config.gc.setoption('dummy', True, 'gen_config')")
def test_cannot_override_special_owners(): def test_cannot_override():
descr = make_description() descr = make_description()
config = Config(descr, bool=False) config = Config(descr, bool=False)
raises(ConflictConfigError, "config.override({'gc.dummy': True})") raises(TypeError, "config.override({'gc.dummy': True})")

View File

@ -67,7 +67,7 @@ def test_freeze_one_option():
#freeze only one option #freeze only one option
conf.gc._cfgimpl_descr.dummy.freeze() conf.gc._cfgimpl_descr.dummy.freeze()
assert conf.gc.dummy == False assert conf.gc.dummy == False
raises(ConflictConfigError, "conf.gc.dummy = True") raises(TypeError, "conf.gc.dummy = True")
def test_frozen_value(): def test_frozen_value():
"setattr a frozen value at the config level" "setattr a frozen value at the config level"
@ -75,14 +75,14 @@ def test_frozen_value():
descr = OptionDescription("options", "", [s]) descr = OptionDescription("options", "", [s])
config = Config(descr) config = Config(descr)
s.freeze() s.freeze()
raises(ConfigError, 'config.string = "egg"') raises(TypeError, 'config.string = "egg"')
def test_freeze(): def test_freeze():
"freeze a whole configuration object" "freeze a whole configuration object"
descr = make_description() descr = make_description()
conf = Config(descr) conf = Config(descr)
conf.cfgimpl_freeze() conf.cfgimpl_freeze()
raises(ConfigError, "conf.gc.name = 'try to modify'") raises(TypeError, "conf.gc.name = 'try to modify'")
# ____________________________________________________________ # ____________________________________________________________
def test_is_hidden(): def test_is_hidden():
descr = make_description() descr = make_description()

View File

@ -189,10 +189,10 @@ class Config(object):
if self.is_frozen() and getattr(self, name) != value: if self.is_frozen() and getattr(self, name) != value:
raise TypeError("trying to change a value in a frozen config" raise TypeError("trying to change a value in a frozen config"
": {0} {1}".format(name, value)) ": {0} {1}".format(name, value))
if self.is_mandatory() and value == None: # if self.is_mandatory() and value == None:
raise MandatoryError("trying to reset option: {0} wich lives in a" # raise MandatoryError("trying to reset option: {0} wich lives in a"
" mandatory group: {1}".format(name, # " mandatory group: {1}".format(name,
self._cfgimpl_descr._name)) # self._cfgimpl_descr._name))
if type(getattr(self._cfgimpl_descr, name)) != SymLinkOption: if type(getattr(self._cfgimpl_descr, name)) != SymLinkOption:
self._validate(name, getattr(self._cfgimpl_descr, name)) self._validate(name, getattr(self._cfgimpl_descr, name))
self.setoption(name, value, self._cfgimpl_owner) self.setoption(name, value, self._cfgimpl_owner)

View File

@ -190,12 +190,11 @@ class Option(HiddenBaseType, DisabledBaseType):
def setoption(self, config, value, who): def setoption(self, config, value, who):
"who is **not necessarily** a owner because it cannot be a list" "who is **not necessarily** a owner because it cannot be a list"
name = self._name name = self._name
# the value cannot be changed if a callback is defined
if self.has_callback():
raise TypeError("trying to change an option with callback: %s" % name)
# we want the possibility to reset everything # we want the possibility to reset everything
if who == "default" and value is None: if not (who == "default" and value is None) and not self.validate(value):
self.default = None
return
if not self.validate(value):
raise ConfigError('invalid value %s for option %s' % (value, name)) raise ConfigError('invalid value %s for option %s' % (value, name))
if self.is_mandatory(): if self.is_mandatory():
# value shall not be '' for a mandatory option # value shall not be '' for a mandatory option
@ -208,6 +207,9 @@ class Option(HiddenBaseType, DisabledBaseType):
(not self.is_multi() and value is None)): (not self.is_multi() and value is None)):
raise MandatoryError('cannot override value to %s for ' raise MandatoryError('cannot override value to %s for '
'option %s' % (value, name)) 'option %s' % (value, name))
if who == "default" and value is None:
self.default = None
return
if name not in config._cfgimpl_values: if name not in config._cfgimpl_values:
raise AttributeError('unknown option %s' % (name)) raise AttributeError('unknown option %s' % (name))
if config.is_frozen() and (self.has_callback() or self.isfrozen()): if config.is_frozen() and (self.has_callback() or self.isfrozen()):