1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 """Encapsulates functions used in osh commands such as C{f} and C{select}.
19
20 osh function syntax::
21
22 [[lambda] ARGS:] EXPRESSION
23
24 C{ARGS}: Comma-separated list of function arguments, optionally preceded by keyword
25 C{lambda}. C{ARGS} may be omitted only for a function with no arguments.
26
27 C{EXPRESSION}: A Python expression written in terms of the function arguments.
28
29 Example::
30
31 x: max(x, 10)
32 """
33
34 import copy
35 import sys
36 import types
37
38 import core
39
40 _LAMBDA = 'lambda '
41 _LAMBDA_COLON = 'lambda:'
42
43
45 """Represents a function for use by osh commands with function arguments,
46 e.g., select.
47 """
48
49 _function = None
50 _function_id = None
51
52 - def __init__(self, function_spec, namespace = core.__dict__):
53 """Creates a Function.
54 - function_spec: String specification of a function. Uses lambda notation,
55 but the 'lambda' keyword is optional.
56 - namespace: The default is reasonable; there's been no need to
57 override it so far.
58 """
59 if type(function_spec) in (types.FunctionType, types.BuiltinFunctionType):
60 self._function = function_spec
61 else:
62 lambda_expression = self.parse(function_spec.strip())
63
64 namespace = copy.copy(namespace)
65 namespace.update(core.namespace())
66 self._function = eval(lambda_expression, namespace)
67
69 return self._function(*args)
70
71 - def parse(self, function_spec):
72
73
74
75
76
77
78
79 if function_spec.startswith(_LAMBDA) or function_spec.startswith(_LAMBDA_COLON):
80
81 pass
82 else:
83 fixed_function_spec = '%s: %s' % (_LAMBDA, function_spec)
84 try:
85 eval(fixed_function_spec)
86 function_spec = fixed_function_spec
87 except:
88 fixed_function_spec = '%s %s' % (_LAMBDA, function_spec)
89 try:
90 eval(fixed_function_spec)
91 function_spec = fixed_function_spec
92 except:
93 raise Exception('Illegal function spec: %s' % function_spec)
94 return function_spec
95