root/galaxy-central/eggs/twill-0.9-py2.6.egg/twill/parse.py

リビジョン 3, 7.4 KB (コミッタ: kohda, 14 年 前)

Install Unix tools  http://hannonlab.cshl.edu/galaxy_unix_tools/galaxy.html

行番号 
1"""
2Code parsing and evaluation for the twill mini-language.
3"""
4
5import sys
6from cStringIO import StringIO
7
8from errors import TwillAssertionError, TwillNameError
9from pyparsing import OneOrMore, Word, printables, quotedString, Optional, \
10     alphas, alphanums, ParseException, ZeroOrMore, restOfLine, Combine, \
11     Literal, Group, removeQuotes, CharsNotIn
12
13import twill.commands as commands
14import namespaces
15import re
16
17### pyparsing stuff
18
19# basically, a valid Python identifier:
20command = Word(alphas + "_", alphanums + "_")
21command = command.setResultsName('command')
22command.setName("command")
23
24# arguments to it.
25
26# we need to reimplement all this junk from pyparsing because pcre's
27# idea of escapable characters contains a lot more than the C-like
28# thing pyparsing implements
29_bslash = "\\"
30_sglQuote = Literal("'")
31_dblQuote = Literal('"')
32_escapables = printables
33_escapedChar = Word(_bslash, _escapables, exact=2)
34dblQuotedString = Combine( _dblQuote + ZeroOrMore( CharsNotIn('\\"\n\r') | _escapedChar | '""' ) + _dblQuote ).streamline().setName("string enclosed in double quotes")
35sglQuotedString = Combine( _sglQuote + ZeroOrMore( CharsNotIn("\\'\n\r") | _escapedChar | "''" ) + _sglQuote ).streamline().setName("string enclosed in single quotes")
36quotedArg = ( dblQuotedString | sglQuotedString )
37quotedArg.setParseAction(removeQuotes)
38quotedArg.setName("quotedArg")
39
40plainArgChars = printables.replace('#', '').replace('"', '').replace("'", "")
41plainArg = Word(plainArgChars)
42plainArg.setName("plainArg")
43
44arguments = Group(ZeroOrMore(quotedArg | plainArg))
45arguments = arguments.setResultsName('arguments')
46arguments.setName("arguments")
47
48# comment line.
49comment = Literal('#') + restOfLine
50comment = comment.suppress()
51comment.setName('comment')
52
53full_command = (
54    comment
55    | (command + arguments + Optional(comment))
56    )
57full_command.setName('full_command')
58
59###
60
61command_list = []           # filled in by namespaces.init_global_dict().
62
63### command/argument handling.
64
65def process_args(args, globals_dict, locals_dict):
66    """
67    Take a list of string arguments parsed via pyparsing and evaluate
68    the special variables ('__*').
69
70    Return a new list.
71    """
72    newargs = []
73    for arg in args:
74        # __variable substitution.
75        if arg.startswith('__'):
76            try:
77                val = eval(arg, globals_dict, locals_dict)
78            except NameError:           # not in dictionary; don't interpret.
79                val = arg
80
81
82            print '*** VAL IS', val, 'FOR', arg
83           
84            if isinstance(val, str):
85                newargs.append(val)
86            else:
87                newargs.extend(val)
88               
89        # $variable substitution
90        elif arg.startswith('$') and not arg.startswith('${'):
91            try:
92                val = eval(arg[1:], globals_dict, locals_dict)
93            except NameError:           # not in dictionary; don't interpret.
94                val = arg
95            newargs.append(val)
96        else:
97            newargs.append(variable_substitution(arg, globals_dict, locals_dict))
98
99    newargs = [ i.replace('\\n', '\n') for i in newargs ]
100
101    return newargs
102
103###
104
105def execute_command(cmd, args, globals_dict, locals_dict, cmdinfo):
106    """
107    Actually execute the command.
108
109    Side effects: __args__ is set to the argument tuple, __cmd__ is set to
110    the command.
111    """
112    global command_list                 # all supported commands:
113    # execute command.
114    locals_dict['__cmd__'] = cmd
115    locals_dict['__args__'] = args
116
117    if cmd not in command_list:
118        raise TwillNameError("unknown twill command: '%s'" % (cmd,))
119
120    eval_str = "%s(*__args__)" % (cmd,)
121
122    # compile the code object so that we can get 'cmdinfo' into the
123    # error tracebacks.
124    codeobj = compile(eval_str, cmdinfo, 'eval')
125
126    # eval the codeobj in the appropriate dictionary.
127    result = eval(codeobj, globals_dict, locals_dict)
128   
129    # set __url__
130    locals_dict['__url__'] = commands.browser.get_url()
131
132    return result
133
134###
135
136_print_commands = False
137
138def parse_command(line, globals_dict, locals_dict):
139    """
140    Parse command.
141    """
142    res = full_command.parseString(line)
143    if res:
144        if _print_commands:
145            print>>commands.OUT, "twill: executing cmd '%s'" % (line.strip(),)
146           
147        args = process_args(res.arguments.asList(), globals_dict, locals_dict)
148        return (res.command, args)
149
150    return None, None                   # e.g. a comment
151
152###
153
154def execute_string(buf, **kw):
155    """
156    Execute commands from a string buffer.
157    """
158    fp = StringIO(buf)
159   
160    kw['source'] = ['<string buffer>']
161    if not kw.has_key('no_reset'):
162       kw['no_reset'] = True
163   
164    _execute_script(fp, **kw)
165
166def execute_file(filename, **kw):
167    """
168    Execute commands from a file.
169    """
170    # read the input lines
171    if filename == "-":
172        inp = sys.stdin
173    else:
174        inp = open(filename)
175
176    kw['source'] = filename
177
178    _execute_script(inp, **kw)
179   
180def _execute_script(inp, **kw):
181    """
182    Execute lines taken from a file-like iterator.
183    """
184    # initialize new local dictionary & get global + current local
185    namespaces.new_local_dict()
186    globals_dict, locals_dict = namespaces.get_twill_glocals()
187   
188    locals_dict['__url__'] = commands.browser.get_url()
189
190    # reset browser
191    if not kw.get('no_reset'):
192        commands.reset_browser()
193
194    # go to a specific URL?
195    init_url = kw.get('initial_url')
196    if init_url:
197        commands.go(init_url)
198        locals_dict['__url__'] = commands.browser.get_url()
199
200    # should we catch exceptions on failure?
201    catch_errors = False
202    if kw.get('never_fail'):
203        catch_errors = True
204
205    # sourceinfo stuff
206    sourceinfo = kw.get('source', "<input>")
207   
208    try:
209
210        for n, line in enumerate(inp):
211            if not line.strip():            # skip empty lines
212                continue
213
214            cmdinfo = "%s:%d" % (sourceinfo, n,)
215            print 'AT LINE:', cmdinfo
216
217            cmd, args = parse_command(line, globals_dict, locals_dict)
218            if cmd is None:
219                continue
220
221            try:
222                execute_command(cmd, args, globals_dict, locals_dict, cmdinfo)
223            except SystemExit:
224                # abort script execution, if a SystemExit is raised.
225                return
226            except TwillAssertionError, e:
227                print>>commands.ERR, '''\
228Oops!  Twill assertion error on line %d of '%s' while executing
229
230  >> %s
231
232%s
233''' % (n, sourceinfo, line.strip(), e)
234                if not catch_errors:
235                    raise
236            except Exception, e:
237                print>>commands.ERR, '''\
238EXCEPTION raised at line %d of '%s'
239
240      %s
241
242Error message: '%s'
243
244''' % (n, sourceinfo, line.strip(),str(e).strip(),)
245
246                if not catch_errors:
247                    raise
248
249    finally:
250        namespaces.pop_local_dict()
251
252###
253
254def debug_print_commands(flag):
255    """
256    Turn on/off printing of commands as they are executed.  'flag' is bool.
257    """
258    global _print_commands
259    _print_commands = bool(flag)
260       
261
262variable_expression = re.compile("\${(.*?)}")
263
264def variable_substitution(raw_str, globals_dict, locals_dict):
265    str=''
266    pos = 0
267    for m in variable_expression.finditer(raw_str):
268        str = str+raw_str[pos:m.start()]
269        try:
270            str = str + eval(m.group(1), globals_dict, locals_dict)
271        except NameError:
272            str = str + m.group()
273        pos = m.end()
274
275    str = str+raw_str[pos:]
276
277    return str
278
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。