提交 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):
setattr(root.__class__, sections[0], configparam)
_config_var_list.append(configparam)
class ConfigParam(object):
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.
......@@ -207,9 +209,11 @@ class ConfigParam(object):
# self.fullname # set by AddConfigVar
# self.doc # set by AddConfigVar
# Check that default is a valid value
if self.filter:
self.filter(self.default)
# Note that we do not call `self.filter` on the default value: this
# will be done automatically in AddConfigVar, potentially with a
# 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):
#print "GETTING PARAM", self.fullname, self, args
......@@ -223,7 +227,7 @@ class ConfigParam(object):
return self.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!")
#print "SETTING PARAM", self.fullname,(cls), val
if self.filter:
......@@ -231,7 +235,9 @@ class ConfigParam(object):
else:
self.val = val
deleter=None
# TODO What is this for?
deleter = None
class EnumStr(ConfigParam):
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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论