mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-12-23 03:02:52 +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):
|
||||
try:
|
||||
i = _int(args[0])
|
||||
if p is not None:
|
||||
if not p(i):
|
||||
raise ValueError
|
||||
state.args.append(i)
|
||||
del args[0]
|
||||
except ValueError:
|
||||
@ -477,7 +474,7 @@ wrappers = ircutils.IrcDict({
|
||||
'lowered': getLowered,
|
||||
'anything': anything,
|
||||
'something': getSomething,
|
||||
'filename': getSomething,
|
||||
'filename': getSomething, # XXX Check for validity.
|
||||
'commandName': getCommandName,
|
||||
'text': anything,
|
||||
'somethingWithoutSpaces': getSomethingNoSpaces,
|
||||
@ -537,6 +534,10 @@ class context(object):
|
||||
self.converter = getConverter(spec)
|
||||
|
||||
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)
|
||||
self.converter(irc, msg, args, state, *self.args)
|
||||
log.debug('args after %r: %r', self, args)
|
||||
@ -571,21 +572,21 @@ class optional(additional):
|
||||
|
||||
class any(context):
|
||||
def __call__(self, irc, msg, args, state):
|
||||
originalStateArgs = state.args
|
||||
state.args = []
|
||||
st = state.essence()
|
||||
st.types = ["something so context.__call__ won't combineRest."]
|
||||
try:
|
||||
try:
|
||||
while args:
|
||||
super(any, self).__call__(irc, msg, args, state)
|
||||
except IndexError:
|
||||
originalStateArgs.append(state.args)
|
||||
finally:
|
||||
state.args = originalStateArgs
|
||||
while args:
|
||||
super(any, self).__call__(irc, msg, args, st)
|
||||
except IndexError:
|
||||
pass
|
||||
state.args.append(st.args)
|
||||
|
||||
class many(any):
|
||||
def __call__(self, irc, msg, args, state):
|
||||
context.__call__(self, 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):
|
||||
"""The empty string indicates that no argument is taken; None indicates
|
||||
@ -623,54 +624,67 @@ class getopts(context):
|
||||
args[:] = rest
|
||||
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.
|
||||
###
|
||||
|
||||
class State(object):
|
||||
log = log
|
||||
def __init__(self):
|
||||
def __init__(self, types):
|
||||
self.args = []
|
||||
self.kwargs = {}
|
||||
self.types = types
|
||||
self.channel = None
|
||||
|
||||
def essence(self):
|
||||
st = State()
|
||||
st = State(self.types)
|
||||
for (attr, value) in self.__dict__.iteritems():
|
||||
if attr not in ('args', 'kwargs', 'channel'):
|
||||
setattr(st, attr, value)
|
||||
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.
|
||||
###
|
||||
class Spec(object):
|
||||
def _state(self, attrs={}):
|
||||
st = State()
|
||||
def _state(self, types, attrs={}):
|
||||
st = State(types)
|
||||
st.__dict__.update(attrs)
|
||||
return st
|
||||
|
||||
def __init__(self, types, allowExtra=False, combineRest=True):
|
||||
def __init__(self, types, allowExtra=False):
|
||||
self.types = types
|
||||
self.allowExtra = allowExtra
|
||||
self.combineRest = combineRest
|
||||
utils.mapinto(contextify, self.types)
|
||||
|
||||
def __call__(self, irc, msg, args, stateAttrs={}):
|
||||
state = self._state(stateAttrs)
|
||||
if self.types:
|
||||
types = self.types[:]
|
||||
while types:
|
||||
if len(types) == 1 and self.combineRest and args:
|
||||
break
|
||||
context = types.pop(0)
|
||||
state = self._state(self.types[:], stateAttrs)
|
||||
while state.types:
|
||||
context = state.types.pop(0)
|
||||
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:
|
||||
log.debug('args and not self.allowExtra: %r', args)
|
||||
raise callbacks.ArgumentError
|
||||
return state
|
||||
|
||||
@ -690,7 +704,7 @@ def wrap(f, specList=[], decorators=None, **kw):
|
||||
return newf
|
||||
|
||||
|
||||
__all__ = ['wrap', 'context', 'additional', 'optional', 'any',
|
||||
__all__ = ['wrap', 'context', 'additional', 'optional', 'any', 'compose','Spec',
|
||||
'many', 'getopts', 'getConverter', 'addConverter', 'callConverter']
|
||||
|
||||
if world.testing:
|
||||
|
@ -72,11 +72,27 @@ class CommandsTestCase(SupyTestCase):
|
||||
['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):
|
||||
## self.assertState([None, any('int'), None],
|
||||
## ['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:
|
||||
|
Loading…
Reference in New Issue
Block a user