registry: Don't use an internal state for Regexp, it breaks net- and chan- specific values.

This commit is contained in:
Valentin Lorentz 2020-09-05 21:40:40 +02:00
parent f3f628ddba
commit 6a3be33fcd
2 changed files with 85 additions and 22 deletions

View File

@ -39,7 +39,7 @@ def random_string():
class ConfigTestCase(ChannelPluginTestCase):
# We add utilities so there's something in supybot.plugins.
plugins = ('Config', 'User', 'Utilities')
plugins = ('Config', 'User', 'Utilities', 'Web')
prefix1 = 'somethingElse!user@host1.tld'
prefix2 = 'EvensomethingElse!user@host2.tld'
@ -437,6 +437,77 @@ class ConfigTestCase(ChannelPluginTestCase):
self.assertFalse(
conf.supybot.reply.whenAddressedBy.strings.get(':test')._wasSet)
def testResetRegexpChannel(self):
"""Specifically tests resetting a Regexp value, as they have an extra
internal state that needs to be reset; see the comment in plugin.py"""
self.assertResponse(
'config plugins.Web.nonSnarfingRegexp',
'Global: ; #test @ test: '
)
self.assertResponse(
'config plugins.Web.nonSnarfingRegexp m/foo/',
'The operation succeeded.'
)
self.assertResponse(
'config channel plugins.Web.nonSnarfingRegexp m/bar/',
'The operation succeeded.'
)
self.assertResponse(
'config plugins.Web.nonSnarfingRegexp',
'Global: m/foo/; #test @ test: m/bar/'
)
self.assertResponse(
'config reset channel plugins.Web.nonSnarfingRegexp',
'The operation succeeded.'
)
self.assertResponse('config plugins.Web.nonSnarfingRegexp',
'Global: m/foo/; #test @ test: m/foo/'
)
self.assertResponse(
'config plugins.Web.nonSnarfingRegexp ""',
'The operation succeeded.'
)
self.assertResponse(
'config plugins.Web.nonSnarfingRegexp',
'Global: ; #test @ test: '
)
def testResetRegexpNetwork(self):
"""Specifically tests resetting a Regexp value, as they have an extra
internal state that needs to be reset; see the comment in plugin.py"""
self.assertResponse(
'config plugins.Web.nonSnarfingRegexp',
'Global: ; #test @ test: '
)
self.assertResponse(
'config plugins.Web.nonSnarfingRegexp m/foo/',
'The operation succeeded.'
)
self.assertResponse(
'config network plugins.Web.nonSnarfingRegexp m/bar/',
'The operation succeeded.'
)
self.assertResponse(
'config plugins.Web.nonSnarfingRegexp',
'Global: m/foo/; #test @ test: m/bar/'
)
self.assertResponse(
'config reset network plugins.Web.nonSnarfingRegexp',
'The operation succeeded.'
)
self.assertResponse('config plugins.Web.nonSnarfingRegexp',
'Global: m/foo/; #test @ test: m/foo/'
)
self.assertResponse(
'config plugins.Web.nonSnarfingRegexp ""',
'The operation succeeded.'
)
self.assertResponse(
'config plugins.Web.nonSnarfingRegexp',
'Global: ; #test @ test: '
)
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

View File

@ -749,14 +749,7 @@ class StringWithSpaceOnRight(String):
class Regexp(Value):
"""Value must be a valid regular expression."""
__slots__ = ('sr', 'value', '__parent')
errormsg = _('Value must be a valid regular expression, not %r.')
def __init__(self, *args, **kwargs):
kwargs['setDefault'] = False
self.sr = ''
self.value = None
self.__parent = super(Regexp, self)
self.__parent.__init__(*args, **kwargs)
def error(self, e):
s = 'Value must be a regexp of the form m/.../ or /.../. %s' % e
@ -767,26 +760,25 @@ class Regexp(Value):
def set(self, s):
try:
if s:
self.setValue(utils.str.perlReToPythonRe(s), sr=s)
# We need to preserve the original string, as it's shown in
# the user interface and the config file.
# It might be tempting to set the original string as an
# attribute, but doing so would result in inconsistent states
# for childs of this variable, should they be reset, or the
# value of there parent change.
v = (s, utils.str.perlReToPythonRe(s))
else:
self.setValue(None)
v = ('', '')
except ValueError as e:
self.error(e)
def setValue(self, v, sr=None):
if v is None:
self.sr = ''
self.__parent.setValue(None)
elif sr is not None:
self.sr = sr
self.__parent.setValue(v)
else:
raise InvalidRegistryValue('Can\'t setValue a regexp, there would be an inconsistency '\
'between the regexp and the recorded string value.')
super().set(v)
def __call__(self):
return self.value[1]
def __str__(self):
self() # Gotta update if we've been reloaded.
return self.sr
return self.value[0]
class SeparatedListOf(Value):
__slots__ = ()