mirror of
https://github.com/Mikaela/Limnoria.git
synced 2025-01-10 20:22:36 +01:00
Not completely working, but tests pass (for what's expected to pass).
This commit is contained in:
parent
1fe3a5423b
commit
e720f46a5a
@ -169,9 +169,6 @@ def _int(s):
|
|||||||
def getInt(irc, msg, args, state, type='integer', p=None):
|
def getInt(irc, msg, args, state, type='integer', p=None):
|
||||||
try:
|
try:
|
||||||
i = _int(args[0])
|
i = _int(args[0])
|
||||||
if p is not None:
|
|
||||||
if not p(i):
|
|
||||||
raise ValueError
|
|
||||||
state.args.append(i)
|
state.args.append(i)
|
||||||
del args[0]
|
del args[0]
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@ -477,7 +474,7 @@ wrappers = ircutils.IrcDict({
|
|||||||
'lowered': getLowered,
|
'lowered': getLowered,
|
||||||
'anything': anything,
|
'anything': anything,
|
||||||
'something': getSomething,
|
'something': getSomething,
|
||||||
'filename': getSomething,
|
'filename': getSomething, # XXX Check for validity.
|
||||||
'commandName': getCommandName,
|
'commandName': getCommandName,
|
||||||
'text': anything,
|
'text': anything,
|
||||||
'somethingWithoutSpaces': getSomethingNoSpaces,
|
'somethingWithoutSpaces': getSomethingNoSpaces,
|
||||||
@ -537,6 +534,10 @@ class context(object):
|
|||||||
self.converter = getConverter(spec)
|
self.converter = getConverter(spec)
|
||||||
|
|
||||||
def __call__(self, irc, msg, args, state):
|
def __call__(self, irc, msg, args, state):
|
||||||
|
if not state.types and args:
|
||||||
|
# We're the last context/type, we should combine the remaining
|
||||||
|
# arguments into one string.
|
||||||
|
args[:] = [' '.join(args)]
|
||||||
log.debug('args before %r: %r', self, args)
|
log.debug('args before %r: %r', self, args)
|
||||||
self.converter(irc, msg, args, state, *self.args)
|
self.converter(irc, msg, args, state, *self.args)
|
||||||
log.debug('args after %r: %r', self, args)
|
log.debug('args after %r: %r', self, args)
|
||||||
@ -571,21 +572,21 @@ class optional(additional):
|
|||||||
|
|
||||||
class any(context):
|
class any(context):
|
||||||
def __call__(self, irc, msg, args, state):
|
def __call__(self, irc, msg, args, state):
|
||||||
originalStateArgs = state.args
|
st = state.essence()
|
||||||
state.args = []
|
st.types = ["something so context.__call__ won't combineRest."]
|
||||||
try:
|
try:
|
||||||
try:
|
while args:
|
||||||
while args:
|
super(any, self).__call__(irc, msg, args, st)
|
||||||
super(any, self).__call__(irc, msg, args, state)
|
except IndexError:
|
||||||
except IndexError:
|
pass
|
||||||
originalStateArgs.append(state.args)
|
state.args.append(st.args)
|
||||||
finally:
|
|
||||||
state.args = originalStateArgs
|
|
||||||
|
|
||||||
class many(any):
|
class many(any):
|
||||||
def __call__(self, irc, msg, args, state):
|
def __call__(self, irc, msg, args, state):
|
||||||
context.__call__(self, irc, msg, args, state)
|
|
||||||
super(many, self).__call__(irc, msg, args, state)
|
super(many, self).__call__(irc, msg, args, state)
|
||||||
|
if not state.args[-1]:
|
||||||
|
state.args.pop()
|
||||||
|
raise callbacks.ArgumentError
|
||||||
|
|
||||||
class getopts(context):
|
class getopts(context):
|
||||||
"""The empty string indicates that no argument is taken; None indicates
|
"""The empty string indicates that no argument is taken; None indicates
|
||||||
@ -623,54 +624,67 @@ class getopts(context):
|
|||||||
args[:] = rest
|
args[:] = rest
|
||||||
log.debug('args after %r: %r', self, args)
|
log.debug('args after %r: %r', self, args)
|
||||||
|
|
||||||
|
# XXX Not ready.
|
||||||
|
class compose(context):
|
||||||
|
def __init__(self, *specs):
|
||||||
|
self.spec = specs
|
||||||
|
self.specs = list(specs)
|
||||||
|
utils.mapinto(contextify, self.specs)
|
||||||
|
|
||||||
|
def __call__(self, irc, msg, args, state):
|
||||||
|
st = state.essence()
|
||||||
|
for context in self.specs:
|
||||||
|
context(irc, msg, args, st)
|
||||||
|
args = st.args
|
||||||
|
state.args.extend(st.args)
|
||||||
|
|
||||||
###
|
###
|
||||||
# This is our state object, passed to converters along with irc, msg, and args.
|
# This is our state object, passed to converters along with irc, msg, and args.
|
||||||
###
|
###
|
||||||
|
|
||||||
class State(object):
|
class State(object):
|
||||||
log = log
|
log = log
|
||||||
def __init__(self):
|
def __init__(self, types):
|
||||||
self.args = []
|
self.args = []
|
||||||
self.kwargs = {}
|
self.kwargs = {}
|
||||||
|
self.types = types
|
||||||
self.channel = None
|
self.channel = None
|
||||||
|
|
||||||
def essence(self):
|
def essence(self):
|
||||||
st = State()
|
st = State(self.types)
|
||||||
for (attr, value) in self.__dict__.iteritems():
|
for (attr, value) in self.__dict__.iteritems():
|
||||||
if attr not in ('args', 'kwargs', 'channel'):
|
if attr not in ('args', 'kwargs', 'channel'):
|
||||||
setattr(st, attr, value)
|
setattr(st, attr, value)
|
||||||
return st
|
return st
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return '%s(args=%r, kwargs=%r, channel=%r)' % (self.__class__.__name__,
|
||||||
|
self.args, self.kwargs,
|
||||||
|
self.channel)
|
||||||
|
|
||||||
|
|
||||||
###
|
###
|
||||||
# This is a compiled Spec object.
|
# This is a compiled Spec object.
|
||||||
###
|
###
|
||||||
class Spec(object):
|
class Spec(object):
|
||||||
def _state(self, attrs={}):
|
def _state(self, types, attrs={}):
|
||||||
st = State()
|
st = State(types)
|
||||||
st.__dict__.update(attrs)
|
st.__dict__.update(attrs)
|
||||||
return st
|
return st
|
||||||
|
|
||||||
def __init__(self, types, allowExtra=False, combineRest=True):
|
def __init__(self, types, allowExtra=False):
|
||||||
self.types = types
|
self.types = types
|
||||||
self.allowExtra = allowExtra
|
self.allowExtra = allowExtra
|
||||||
self.combineRest = combineRest
|
|
||||||
utils.mapinto(contextify, self.types)
|
utils.mapinto(contextify, self.types)
|
||||||
|
|
||||||
def __call__(self, irc, msg, args, stateAttrs={}):
|
def __call__(self, irc, msg, args, stateAttrs={}):
|
||||||
state = self._state(stateAttrs)
|
|
||||||
if self.types:
|
if self.types:
|
||||||
types = self.types[:]
|
state = self._state(self.types[:], stateAttrs)
|
||||||
while types:
|
while state.types:
|
||||||
if len(types) == 1 and self.combineRest and args:
|
context = state.types.pop(0)
|
||||||
break
|
|
||||||
context = types.pop(0)
|
|
||||||
context(irc, msg, args, state)
|
context(irc, msg, args, state)
|
||||||
if types and args:
|
|
||||||
assert self.combineRest
|
|
||||||
args[:] = [' '.join(args)]
|
|
||||||
types[0](irc, msg, args, state)
|
|
||||||
if args and not self.allowExtra:
|
if args and not self.allowExtra:
|
||||||
|
log.debug('args and not self.allowExtra: %r', args)
|
||||||
raise callbacks.ArgumentError
|
raise callbacks.ArgumentError
|
||||||
return state
|
return state
|
||||||
|
|
||||||
@ -690,7 +704,7 @@ def wrap(f, specList=[], decorators=None, **kw):
|
|||||||
return newf
|
return newf
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['wrap', 'context', 'additional', 'optional', 'any',
|
__all__ = ['wrap', 'context', 'additional', 'optional', 'any', 'compose','Spec',
|
||||||
'many', 'getopts', 'getConverter', 'addConverter', 'callConverter']
|
'many', 'getopts', 'getConverter', 'addConverter', 'callConverter']
|
||||||
|
|
||||||
if world.testing:
|
if world.testing:
|
||||||
|
@ -72,11 +72,27 @@ class CommandsTestCase(SupyTestCase):
|
|||||||
['12', '--foo', 'baz', '--bar', '13', '15'],
|
['12', '--foo', 'baz', '--bar', '13', '15'],
|
||||||
[12, [('foo', 'baz'), ('bar', 13)], 15])
|
[12, [('foo', 'baz'), ('bar', 13)], 15])
|
||||||
|
|
||||||
|
def testCompose(self):
|
||||||
|
spec = [compose('somethingWithoutSpaces', 'lowered')]
|
||||||
|
self.assertState(spec, ['FOO'], ['foo'])
|
||||||
|
self.assertRaises(callbacks.Error,
|
||||||
|
self.assertState, spec, ['foo bar'], ['asdf'])
|
||||||
|
|
||||||
|
def testAny(self):
|
||||||
|
self.assertState([any('int')], ['1', '2', '3'], [[1, 2, 3]])
|
||||||
|
self.assertState([None, any('int')], ['1', '2', '3'], ['1', [2, 3]])
|
||||||
|
|
||||||
## def testAny(self):
|
## def testAny(self):
|
||||||
## self.assertState([None, any('int'), None],
|
## self.assertState([None, any('int'), None],
|
||||||
## ['foo', 'bar'],
|
## ['foo', 'bar'],
|
||||||
## ['foo', [], 'bar'])
|
## ['foo', [], 'bar'])
|
||||||
|
|
||||||
|
def testMany(self):
|
||||||
|
spec = [many('int')]
|
||||||
|
self.assertState(spec, ['1', '2', '3'], [[1, 2, 3]])
|
||||||
|
self.assertRaises(callbacks.Error,
|
||||||
|
self.assertState, spec, [], ['asdf'])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:
|
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:
|
||||||
|
Loading…
Reference in New Issue
Block a user