comparison MoinMoin/wikiutil.py @ 2540:fa4252cb4077

move macro invoker to wikiutil
author Johannes Berg <johannes AT sipsolutions DOT net>
date Mon, 23 Jul 2007 19:35:49 +0200
parents 070294763d3e
children 07ac71a1d9d2
comparison
equal deleted inserted replaced
2539:9dd4a7a164e4 2540:fa4252cb4077
17 import time 17 import time
18 import urllib 18 import urllib
19 19
20 from MoinMoin import config 20 from MoinMoin import config
21 from MoinMoin.util import pysupport, lock 21 from MoinMoin.util import pysupport, lock
22 from inspect import getargspec
23 from types import MethodType
24
22 25
23 # Exceptions 26 # Exceptions
24 class InvalidFileNameError(Exception): 27 class InvalidFileNameError(Exception):
25 """ Called when we find an invalid file name """ 28 """ Called when we find an invalid file name """
26 pass 29 pass
1479 '", "'.join(choices), arg)) 1482 '", "'.join(choices), arg))
1480 1483
1481 return arg 1484 return arg
1482 1485
1483 1486
1487 def invoke_extension_function(request, function, args, fixed_args=[]):
1488 """
1489 Parses arguments for an extension call and calls the extension
1490 function with the arguments.
1491
1492 If the macro function has a default value that is a bool,
1493 int, long, float or unicode object, then the given value
1494 is converted to the type of that default value before passing
1495 it to the macro function. That way, macros need not call the
1496 wikiutil.get_* functions for any arguments that have a default.
1497
1498 @param request: the request object
1499 @param function: the function to invoke
1500 @param args: unicode string with arguments (or evaluating to False)
1501 @param fixed_args: fixed arguments to pass as the first arguments
1502 @returns: the return value from the function called
1503 """
1504
1505 def _convert_arg(request, value, default, name=None):
1506 """
1507 Using the get_* functions, convert argument to the type of the default
1508 if that is any of bool, int, long, float or unicode; if the default
1509 is the type itself then convert to that type (keeps None) or if the
1510 default is a list require one of the list items.
1511
1512 In other cases return the value itself.
1513 """
1514 if isinstance(default, bool):
1515 return get_bool(request, value, name, default)
1516 elif isinstance(default, int) or isinstance(default, long):
1517 return get_int(request, value, name, default)
1518 elif isinstance(default, float):
1519 return get_float(request, value, name, default)
1520 elif isinstance(default, unicode):
1521 return get_unicode(request, value, name, default)
1522 elif isinstance(default, tuple) or isinstance(default, list):
1523 return get_choice(request, value, name, default)
1524 elif default is bool:
1525 return get_bool(request, value, name)
1526 elif default is int or default is long:
1527 return get_int(request, value, name)
1528 elif default is float:
1529 return get_float(request, value, name)
1530 return value
1531
1532 assert isinstance(fixed_args, list) or isinstance(fixed_args, tuple)
1533
1534 if args:
1535 assert isinstance(args, unicode)
1536
1537 positional, keyword, trailing = \
1538 parse_quoted_separated(args)
1539
1540 kwargs = {}
1541 nonascii = {}
1542 for kw in keyword:
1543 try:
1544 kwargs[str(kw)] = keyword[kw]
1545 except UnicodeEncodeError:
1546 nonascii[kw] = keyword[kw]
1547
1548 # add trailing args as keyword argument if present,
1549 # otherwise remove if the user entered some
1550 # (so macros don't get a string where they expect a list)
1551 if trailing:
1552 kwargs['_trailing_args'] = trailing
1553 elif '_trailing_args' in kwargs:
1554 del kwargs['_trailing_args']
1555
1556 # add nonascii args as keyword argument if present,
1557 # otherwise remove if the user entered some
1558 # (so macros don't get a string where they expect a list)
1559 if nonascii:
1560 kwargs['_non_ascii_kwargs'] = nonascii
1561 elif '_non_ascii_kwargs' in kwargs:
1562 del kwargs['_non_ascii_kwargs']
1563
1564 else:
1565 positional = []
1566 kwargs = {}
1567
1568 argnames, varargs, varkw, defaultlist = getargspec(function)
1569 # self is implicit!
1570 if isinstance(function, MethodType):
1571 argnames = argnames[1:]
1572 fixed_argc = len(fixed_args)
1573 argnames = argnames[fixed_argc:]
1574 argc = len(argnames)
1575 if not defaultlist:
1576 defaultlist = []
1577
1578 # if the fixed parameters have defaults too...
1579 if argc < len(defaultlist):
1580 defaultlist = defaultlist[fixed_argc:]
1581 defstart = argc - len(defaultlist)
1582
1583 defaults = {}
1584 # convert all arguments to keyword arguments,
1585 # fill all arguments that weren't given with None
1586 for idx in range(argc):
1587 if idx < len(positional):
1588 kwargs[argnames[idx]] = positional[idx]
1589 if not (argnames[idx] in kwargs):
1590 kwargs[argnames[idx]] = None
1591 if idx >= defstart:
1592 defaults[argnames[idx]] = defaultlist[idx - defstart]
1593
1594 # type-convert all keyword arguments to the type
1595 # that the default value indicates
1596 for argname in defaults:
1597 default = defaults[argname]
1598
1599 # the value of 'argname' from kwargs will be put into the
1600 # macro's 'argname' argument, so convert that giving the
1601 # name to the converter so the user is told which argument
1602 # went wrong (if it does)
1603 kwargs[argname] = _convert_arg(request, kwargs[argname],
1604 default, argname)
1605
1606 return function(*fixed_args, **kwargs)
1607
1608
1484 def parseAttributes(request, attrstring, endtoken=None, extension=None): 1609 def parseAttributes(request, attrstring, endtoken=None, extension=None):
1485 """ 1610 """
1486 Parse a list of attributes and return a dict plus a possible 1611 Parse a list of attributes and return a dict plus a possible
1487 error message. 1612 error message.
1488 If extension is passed, it has to be a callable that returns 1613 If extension is passed, it has to be a callable that returns