提交 d62503f3 authored 作者: Olivier Delalleau's avatar Olivier Delalleau

Fix to avoid a bad default value of a config option from causing trouble:

The 'filter' method of a ConfigParam object is not called anymore on the default value when the ConfigParam is created. Added a test case to test this new behavior.
上级 c792e289
...@@ -194,7 +194,9 @@ def AddConfigVar(name, doc, configparam, root=config, in_c_key=True): ...@@ -194,7 +194,9 @@ def AddConfigVar(name, doc, configparam, root=config, in_c_key=True):
setattr(root.__class__, sections[0], configparam) setattr(root.__class__, sections[0], configparam)
_config_var_list.append(configparam) _config_var_list.append(configparam)
class ConfigParam(object): class ConfigParam(object):
def __init__(self, default, filter=None, allow_override=True): def __init__(self, default, filter=None, allow_override=True):
""" """
If allow_override is False, we can't change the value after the import of Theano. If allow_override is False, we can't change the value after the import of Theano.
...@@ -207,9 +209,11 @@ class ConfigParam(object): ...@@ -207,9 +209,11 @@ class ConfigParam(object):
# self.fullname # set by AddConfigVar # self.fullname # set by AddConfigVar
# self.doc # set by AddConfigVar # self.doc # set by AddConfigVar
# Check that default is a valid value # Note that we do not call `self.filter` on the default value: this
if self.filter: # will be done automatically in AddConfigVar, potentially with a
self.filter(self.default) # more appropriate user-provided default value.
# Calling `filter` here may actually be harmful if the default value is
# invalid and causes a crash or has unwanted side effects.
def __get__(self, *args): def __get__(self, *args):
#print "GETTING PARAM", self.fullname, self, args #print "GETTING PARAM", self.fullname, self, args
...@@ -223,7 +227,7 @@ class ConfigParam(object): ...@@ -223,7 +227,7 @@ class ConfigParam(object):
return self.val return self.val
def __set__(self, cls, val): def __set__(self, cls, val):
if not self.allow_override and hasattr(self,'val'): if not self.allow_override and hasattr(self, 'val'):
raise Exception("Can't change the value of this config parameter after initialization!") raise Exception("Can't change the value of this config parameter after initialization!")
#print "SETTING PARAM", self.fullname,(cls), val #print "SETTING PARAM", self.fullname,(cls), val
if self.filter: if self.filter:
...@@ -231,7 +235,9 @@ class ConfigParam(object): ...@@ -231,7 +235,9 @@ class ConfigParam(object):
else: else:
self.val = val self.val = val
deleter=None # TODO What is this for?
deleter = None
class EnumStr(ConfigParam): class EnumStr(ConfigParam):
def __init__(self, default, *options, **kwargs): def __init__(self, default, *options, **kwargs):
......
"""
Test config options.
"""
import unittest
from theano import config
from theano.configparser import AddConfigVar, ConfigParam, THEANO_FLAGS_DICT
class T_config(unittest.TestCase):
def test_invalid_default(self):
# Ensure an invalid default value found in the Theano code only causes
# a crash if it is not overridden by the user.
# TODO Note that currently, an invalid default value may still cause a
# crash if the user intends to override it inside the Python code with
# ``config.option = new_value``, instead of e.g. in the .theanorc. We
# may want to improve on this in the future.
def filter(val):
if val == 'invalid':
raise ValueError()
else:
return val
try:
# This should raise a ValueError because the default value is
# invalid.
AddConfigVar(
'T_config.test_invalid_default_a',
doc='unittest',
configparam=ConfigParam('invalid', filter=filter),
in_c_key=False)
assert False
except ValueError:
pass
try:
THEANO_FLAGS_DICT['T_config.test_invalid_default_b'] = 'ok'
# This should succeed since we defined a proper value, even
# though the default was invalid.
AddConfigVar(
'T_config.test_invalid_default_b',
doc='unittest',
configparam=ConfigParam('invalid', filter=filter),
in_c_key=False)
finally:
# Dicionary clean-up.
del THEANO_FLAGS_DICT['T_config.test_invalid_default_b']
# TODO We should remove these dummy options on test exit.
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论