comparison MoinMoin/wikiutil.py @ 3133:88033682e5a5

add generic IEFArgument/UnitArgument
author Johannes Berg <johannes AT sipsolutions DOT net>
date Wed, 27 Feb 2008 14:48:38 +0100
parents ea5383222f2f
children 16ae95df840a
comparison
equal deleted inserted replaced
3132:89f0c9a80f8a 3133:88033682e5a5
1576 '", "'.join(choices), arg)) 1576 '", "'.join(choices), arg))
1577 1577
1578 return arg 1578 return arg
1579 1579
1580 1580
1581 class IEFArgument:
1582 """
1583 Base class for new argument parsers for
1584 invoke_extension_function.
1585 """
1586 def __init__(self):
1587 pass
1588
1589 def parse_argument(self, s):
1590 """
1591 Parse the argument given in s (a string) and return
1592 the argument for the extension function.
1593 """
1594 raise NotImplementedError
1595
1596 def get_default(self):
1597 """
1598 Return the default for this argument.
1599 """
1600 raise NotImplementedError
1601
1602
1603 class UnitArgument(IEFArgument):
1604 """
1605 Argument class for invoke_extension_function that forces
1606 having any of the specified units given for a value.
1607
1608 Note that the default unit is "mm".
1609
1610 Use, for example, "UnitArgument('7mm', float, ['%', 'mm'])".
1611 """
1612 def __init__(self, default, argtype, units=['mm']):
1613 """
1614 Initialise a UnitArgument giving the default,
1615 argument type and the permitted units.
1616 """
1617 IEFArgument.__init__(self)
1618 self._units = list(units)
1619 self._units.sort(cmp=lambda x, y: len(y) - len(x))
1620 self._type = argtype
1621 self._default = self.parse_argument(default)
1622
1623 def parse_argument(self, s):
1624 for unit in self._units:
1625 if s.endswith(unit):
1626 ret = (self._type(s[:len(s) - len(unit)]), unit)
1627 return ret
1628 ## XXX: how can we translate this?
1629 raise ValueError("Invalid unit in value %s" % s)
1630
1631 def get_default(self):
1632 return self._default
1633
1634
1581 class required_arg: 1635 class required_arg:
1582 """ 1636 """
1583 Wrap a type in this class and give it as default argument 1637 Wrap a type in this class and give it as default argument
1584 for a function passed to invoke_extension_function() in 1638 for a function passed to invoke_extension_function() in
1585 order to get generic checking that the argument is given. 1639 order to get generic checking that the argument is given.
1587 def __init__(self, argtype): 1641 def __init__(self, argtype):
1588 """ 1642 """
1589 Initialise a required_arg 1643 Initialise a required_arg
1590 @param argtype: the type the argument should have 1644 @param argtype: the type the argument should have
1591 """ 1645 """
1592 if not argtype in (bool, int, long, float, complex, unicode): 1646 if not (argtype in (bool, int, long, float, complex, unicode) or
1647 isinstance(argtype, IEFArgument)):
1593 raise TypeError("argtype must be a valid type") 1648 raise TypeError("argtype must be a valid type")
1594 self.argtype = argtype 1649 self.argtype = argtype
1595 1650
1596 1651
1597 def invoke_extension_function(request, function, args, fixed_args=[]): 1652 def invoke_extension_function(request, function, args, fixed_args=[]):
1640 return get_int(request, value, name) 1695 return get_int(request, value, name)
1641 elif default is float: 1696 elif default is float:
1642 return get_float(request, value, name) 1697 return get_float(request, value, name)
1643 elif default is complex: 1698 elif default is complex:
1644 return get_complex(request, value, name) 1699 return get_complex(request, value, name)
1700 elif isinstance(default, IEFArgument):
1701 # defaults handled later
1702 if value is None:
1703 return None
1704 return default.parse_argument(value)
1645 elif isinstance(default, required_arg): 1705 elif isinstance(default, required_arg):
1646 return _convert_arg(request, value, default.argtype, name) 1706 return _convert_arg(request, value, default.argtype, name)
1647 return value 1707 return value
1648 1708
1649 assert isinstance(fixed_args, (list, tuple)) 1709 assert isinstance(fixed_args, (list, tuple))
1734 # macro's 'argname' argument, so convert that giving the 1794 # macro's 'argname' argument, so convert that giving the
1735 # name to the converter so the user is told which argument 1795 # name to the converter so the user is told which argument
1736 # went wrong (if it does) 1796 # went wrong (if it does)
1737 kwargs[argname] = _convert_arg(request, kwargs[argname], 1797 kwargs[argname] = _convert_arg(request, kwargs[argname],
1738 defaults[argname], argname) 1798 defaults[argname], argname)
1739 if (kwargs[argname] is None 1799 if kwargs[argname] is None:
1740 and isinstance(defaults[argname], required_arg)): 1800 if isinstance(defaults[argname], required_arg):
1741 raise ValueError(_('Argument "%s" is required') % argname) 1801 raise ValueError(_('Argument "%s" is required') % argname)
1802 if isinstance(defaults[argname], IEFArgument):
1803 kwargs[argname] = defaults[argname].get_default()
1742 1804
1743 if not argname in argnames: 1805 if not argname in argnames:
1744 # move argname into _kwargs parameter 1806 # move argname into _kwargs parameter
1745 kwargs_to_pass[argname] = kwargs[argname] 1807 kwargs_to_pass[argname] = kwargs[argname]
1746 del kwargs[argname] 1808 del kwargs[argname]