Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/f2py/auxfuncs.py @ 87:2a2c65a20a8b
Add Python libs and headers
author | Chris Cannam |
---|---|
date | Wed, 25 Feb 2015 14:05:22 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
86:413a9d26189e | 87:2a2c65a20a8b |
---|---|
1 #!/usr/bin/env python | |
2 """ | |
3 | |
4 Auxiliary functions for f2py2e. | |
5 | |
6 Copyright 1999,2000 Pearu Peterson all rights reserved, | |
7 Pearu Peterson <pearu@ioc.ee> | |
8 Permission to use, modify, and distribute this software is given under the | |
9 terms of the NumPy (BSD style) LICENSE. | |
10 | |
11 | |
12 NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. | |
13 $Date: 2005/07/24 19:01:55 $ | |
14 Pearu Peterson | |
15 | |
16 """ | |
17 from __future__ import division, absolute_import, print_function | |
18 | |
19 import pprint | |
20 import sys | |
21 import types | |
22 from functools import reduce | |
23 | |
24 from . import __version__ | |
25 from . import cfuncs | |
26 | |
27 f2py_version = __version__.version | |
28 | |
29 | |
30 errmess=sys.stderr.write | |
31 #outmess=sys.stdout.write | |
32 show=pprint.pprint | |
33 | |
34 options={} | |
35 debugoptions=[] | |
36 wrapfuncs = 1 | |
37 | |
38 | |
39 def outmess(t): | |
40 if options.get('verbose', 1): | |
41 sys.stdout.write(t) | |
42 | |
43 def debugcapi(var): | |
44 return 'capi' in debugoptions | |
45 | |
46 def _isstring(var): | |
47 return 'typespec' in var and var['typespec']=='character' and (not isexternal(var)) | |
48 | |
49 def isstring(var): | |
50 return _isstring(var) and not isarray(var) | |
51 | |
52 def ischaracter(var): | |
53 return isstring(var) and 'charselector' not in var | |
54 | |
55 def isstringarray(var): | |
56 return isarray(var) and _isstring(var) | |
57 | |
58 def isarrayofstrings(var): | |
59 # leaving out '*' for now so that | |
60 # `character*(*) a(m)` and `character a(m,*)` | |
61 # are treated differently. Luckily `character**` is illegal. | |
62 return isstringarray(var) and var['dimension'][-1]=='(*)' | |
63 | |
64 def isarray(var): | |
65 return 'dimension' in var and (not isexternal(var)) | |
66 | |
67 def isscalar(var): | |
68 return not (isarray(var) or isstring(var) or isexternal(var)) | |
69 | |
70 def iscomplex(var): | |
71 return isscalar(var) and var.get('typespec') in ['complex', 'double complex'] | |
72 | |
73 def islogical(var): | |
74 return isscalar(var) and var.get('typespec')=='logical' | |
75 | |
76 def isinteger(var): | |
77 return isscalar(var) and var.get('typespec')=='integer' | |
78 | |
79 def isreal(var): | |
80 return isscalar(var) and var.get('typespec')=='real' | |
81 | |
82 def get_kind(var): | |
83 try: | |
84 return var['kindselector']['*'] | |
85 except KeyError: | |
86 try: | |
87 return var['kindselector']['kind'] | |
88 except KeyError: | |
89 pass | |
90 | |
91 def islong_long(var): | |
92 if not isscalar(var): | |
93 return 0 | |
94 if var.get('typespec') not in ['integer', 'logical']: | |
95 return 0 | |
96 return get_kind(var)=='8' | |
97 | |
98 def isunsigned_char(var): | |
99 if not isscalar(var): | |
100 return 0 | |
101 if var.get('typespec') != 'integer': | |
102 return 0 | |
103 return get_kind(var)=='-1' | |
104 | |
105 def isunsigned_short(var): | |
106 if not isscalar(var): | |
107 return 0 | |
108 if var.get('typespec') != 'integer': | |
109 return 0 | |
110 return get_kind(var)=='-2' | |
111 | |
112 def isunsigned(var): | |
113 if not isscalar(var): | |
114 return 0 | |
115 if var.get('typespec') != 'integer': | |
116 return 0 | |
117 return get_kind(var)=='-4' | |
118 | |
119 def isunsigned_long_long(var): | |
120 if not isscalar(var): | |
121 return 0 | |
122 if var.get('typespec') != 'integer': | |
123 return 0 | |
124 return get_kind(var)=='-8' | |
125 | |
126 def isdouble(var): | |
127 if not isscalar(var): | |
128 return 0 | |
129 if not var.get('typespec')=='real': | |
130 return 0 | |
131 return get_kind(var)=='8' | |
132 | |
133 def islong_double(var): | |
134 if not isscalar(var): | |
135 return 0 | |
136 if not var.get('typespec')=='real': | |
137 return 0 | |
138 return get_kind(var)=='16' | |
139 | |
140 def islong_complex(var): | |
141 if not iscomplex(var): | |
142 return 0 | |
143 return get_kind(var)=='32' | |
144 | |
145 def iscomplexarray(var): | |
146 return isarray(var) and var.get('typespec') in ['complex', 'double complex'] | |
147 | |
148 def isint1array(var): | |
149 return isarray(var) and var.get('typespec')=='integer' \ | |
150 and get_kind(var)=='1' | |
151 | |
152 def isunsigned_chararray(var): | |
153 return isarray(var) and var.get('typespec') in ['integer', 'logical']\ | |
154 and get_kind(var)=='-1' | |
155 | |
156 def isunsigned_shortarray(var): | |
157 return isarray(var) and var.get('typespec') in ['integer', 'logical']\ | |
158 and get_kind(var)=='-2' | |
159 | |
160 def isunsignedarray(var): | |
161 return isarray(var) and var.get('typespec') in ['integer', 'logical']\ | |
162 and get_kind(var)=='-4' | |
163 | |
164 def isunsigned_long_longarray(var): | |
165 return isarray(var) and var.get('typespec') in ['integer', 'logical']\ | |
166 and get_kind(var)=='-8' | |
167 | |
168 def issigned_chararray(var): | |
169 return isarray(var) and var.get('typespec') in ['integer', 'logical']\ | |
170 and get_kind(var)=='1' | |
171 | |
172 def issigned_shortarray(var): | |
173 return isarray(var) and var.get('typespec') in ['integer', 'logical']\ | |
174 and get_kind(var)=='2' | |
175 | |
176 def issigned_array(var): | |
177 return isarray(var) and var.get('typespec') in ['integer', 'logical']\ | |
178 and get_kind(var)=='4' | |
179 | |
180 def issigned_long_longarray(var): | |
181 return isarray(var) and var.get('typespec') in ['integer', 'logical']\ | |
182 and get_kind(var)=='8' | |
183 | |
184 def isallocatable(var): | |
185 return 'attrspec' in var and 'allocatable' in var['attrspec'] | |
186 | |
187 def ismutable(var): | |
188 return not (not 'dimension' in var or isstring(var)) | |
189 | |
190 def ismoduleroutine(rout): | |
191 return 'modulename' in rout | |
192 | |
193 def ismodule(rout): | |
194 return ('block' in rout and 'module'==rout['block']) | |
195 | |
196 def isfunction(rout): | |
197 return ('block' in rout and 'function'==rout['block']) | |
198 | |
199 #def isfunction_wrap(rout): | |
200 # return wrapfuncs and (iscomplexfunction(rout) or isstringfunction(rout)) and (not isexternal(rout)) | |
201 | |
202 def isfunction_wrap(rout): | |
203 if isintent_c(rout): | |
204 return 0 | |
205 return wrapfuncs and isfunction(rout) and (not isexternal(rout)) | |
206 | |
207 def issubroutine(rout): | |
208 return ('block' in rout and 'subroutine'==rout['block']) | |
209 | |
210 def issubroutine_wrap(rout): | |
211 if isintent_c(rout): | |
212 return 0 | |
213 return issubroutine(rout) and hasassumedshape(rout) | |
214 | |
215 def hasassumedshape(rout): | |
216 if rout.get('hasassumedshape'): | |
217 return True | |
218 for a in rout['args']: | |
219 for d in rout['vars'].get(a, {}).get('dimension', []): | |
220 if d==':': | |
221 rout['hasassumedshape'] = True | |
222 return True | |
223 return False | |
224 | |
225 def isroutine(rout): | |
226 return isfunction(rout) or issubroutine(rout) | |
227 | |
228 def islogicalfunction(rout): | |
229 if not isfunction(rout): | |
230 return 0 | |
231 if 'result' in rout: | |
232 a=rout['result'] | |
233 else: | |
234 a=rout['name'] | |
235 if a in rout['vars']: | |
236 return islogical(rout['vars'][a]) | |
237 return 0 | |
238 | |
239 def islong_longfunction(rout): | |
240 if not isfunction(rout): | |
241 return 0 | |
242 if 'result' in rout: | |
243 a=rout['result'] | |
244 else: | |
245 a=rout['name'] | |
246 if a in rout['vars']: | |
247 return islong_long(rout['vars'][a]) | |
248 return 0 | |
249 | |
250 def islong_doublefunction(rout): | |
251 if not isfunction(rout): | |
252 return 0 | |
253 if 'result' in rout: | |
254 a=rout['result'] | |
255 else: | |
256 a=rout['name'] | |
257 if a in rout['vars']: | |
258 return islong_double(rout['vars'][a]) | |
259 return 0 | |
260 | |
261 def iscomplexfunction(rout): | |
262 if not isfunction(rout): | |
263 return 0 | |
264 if 'result' in rout: | |
265 a=rout['result'] | |
266 else: | |
267 a=rout['name'] | |
268 if a in rout['vars']: | |
269 return iscomplex(rout['vars'][a]) | |
270 return 0 | |
271 | |
272 def iscomplexfunction_warn(rout): | |
273 if iscomplexfunction(rout): | |
274 outmess("""\ | |
275 ************************************************************** | |
276 Warning: code with a function returning complex value | |
277 may not work correctly with your Fortran compiler. | |
278 Run the following test before using it in your applications: | |
279 $(f2py install dir)/test-site/{b/runme_scalar,e/runme} | |
280 When using GNU gcc/g77 compilers, codes should work correctly. | |
281 **************************************************************\n""") | |
282 return 1 | |
283 return 0 | |
284 | |
285 def isstringfunction(rout): | |
286 if not isfunction(rout): | |
287 return 0 | |
288 if 'result' in rout: | |
289 a=rout['result'] | |
290 else: | |
291 a=rout['name'] | |
292 if a in rout['vars']: | |
293 return isstring(rout['vars'][a]) | |
294 return 0 | |
295 | |
296 def hasexternals(rout): | |
297 return 'externals' in rout and rout['externals'] | |
298 | |
299 def isthreadsafe(rout): | |
300 return 'f2pyenhancements' in rout and 'threadsafe' in rout['f2pyenhancements'] | |
301 | |
302 def hasvariables(rout): | |
303 return 'vars' in rout and rout['vars'] | |
304 | |
305 def isoptional(var): | |
306 return ('attrspec' in var and 'optional' in var['attrspec'] and 'required' not in var['attrspec']) and isintent_nothide(var) | |
307 | |
308 def isexternal(var): | |
309 return ('attrspec' in var and 'external' in var['attrspec']) | |
310 | |
311 def isrequired(var): | |
312 return not isoptional(var) and isintent_nothide(var) | |
313 | |
314 def isintent_in(var): | |
315 if 'intent' not in var: | |
316 return 1 | |
317 if 'hide' in var['intent']: | |
318 return 0 | |
319 if 'inplace' in var['intent']: | |
320 return 0 | |
321 if 'in' in var['intent']: | |
322 return 1 | |
323 if 'out' in var['intent']: | |
324 return 0 | |
325 if 'inout' in var['intent']: | |
326 return 0 | |
327 if 'outin' in var['intent']: | |
328 return 0 | |
329 return 1 | |
330 | |
331 def isintent_inout(var): | |
332 return 'intent' in var and ('inout' in var['intent'] or 'outin' in var['intent']) and 'in' not in var['intent'] and 'hide' not in var['intent'] and 'inplace' not in var['intent'] | |
333 | |
334 def isintent_out(var): | |
335 return 'out' in var.get('intent', []) | |
336 | |
337 def isintent_hide(var): | |
338 return ('intent' in var and ('hide' in var['intent'] or ('out' in var['intent'] and 'in' not in var['intent'] and (not l_or(isintent_inout, isintent_inplace)(var))))) | |
339 | |
340 def isintent_nothide(var): | |
341 return not isintent_hide(var) | |
342 | |
343 def isintent_c(var): | |
344 return 'c' in var.get('intent', []) | |
345 | |
346 # def isintent_f(var): | |
347 # return not isintent_c(var) | |
348 | |
349 def isintent_cache(var): | |
350 return 'cache' in var.get('intent', []) | |
351 | |
352 def isintent_copy(var): | |
353 return 'copy' in var.get('intent', []) | |
354 | |
355 def isintent_overwrite(var): | |
356 return 'overwrite' in var.get('intent', []) | |
357 | |
358 def isintent_callback(var): | |
359 return 'callback' in var.get('intent', []) | |
360 | |
361 def isintent_inplace(var): | |
362 return 'inplace' in var.get('intent', []) | |
363 | |
364 def isintent_aux(var): | |
365 return 'aux' in var.get('intent', []) | |
366 | |
367 def isintent_aligned4(var): | |
368 return 'aligned4' in var.get('intent', []) | |
369 def isintent_aligned8(var): | |
370 return 'aligned8' in var.get('intent', []) | |
371 def isintent_aligned16(var): | |
372 return 'aligned16' in var.get('intent', []) | |
373 | |
374 isintent_dict = {isintent_in: 'INTENT_IN', isintent_inout: 'INTENT_INOUT', | |
375 isintent_out: 'INTENT_OUT', isintent_hide: 'INTENT_HIDE', | |
376 isintent_cache: 'INTENT_CACHE', | |
377 isintent_c: 'INTENT_C', isoptional: 'OPTIONAL', | |
378 isintent_inplace: 'INTENT_INPLACE', | |
379 isintent_aligned4: 'INTENT_ALIGNED4', | |
380 isintent_aligned8: 'INTENT_ALIGNED8', | |
381 isintent_aligned16: 'INTENT_ALIGNED16', | |
382 } | |
383 | |
384 def isprivate(var): | |
385 return 'attrspec' in var and 'private' in var['attrspec'] | |
386 | |
387 def hasinitvalue(var): | |
388 return '=' in var | |
389 | |
390 def hasinitvalueasstring(var): | |
391 if not hasinitvalue(var): | |
392 return 0 | |
393 return var['='][0] in ['"', "'"] | |
394 | |
395 def hasnote(var): | |
396 return 'note' in var | |
397 | |
398 def hasresultnote(rout): | |
399 if not isfunction(rout): | |
400 return 0 | |
401 if 'result' in rout: | |
402 a=rout['result'] | |
403 else: | |
404 a=rout['name'] | |
405 if a in rout['vars']: | |
406 return hasnote(rout['vars'][a]) | |
407 return 0 | |
408 | |
409 def hascommon(rout): | |
410 return 'common' in rout | |
411 | |
412 def containscommon(rout): | |
413 if hascommon(rout): | |
414 return 1 | |
415 if hasbody(rout): | |
416 for b in rout['body']: | |
417 if containscommon(b): | |
418 return 1 | |
419 return 0 | |
420 | |
421 def containsmodule(block): | |
422 if ismodule(block): | |
423 return 1 | |
424 if not hasbody(block): | |
425 return 0 | |
426 for b in block['body']: | |
427 if containsmodule(b): | |
428 return 1 | |
429 return 0 | |
430 | |
431 def hasbody(rout): | |
432 return 'body' in rout | |
433 | |
434 def hascallstatement(rout): | |
435 return getcallstatement(rout) is not None | |
436 | |
437 def istrue(var): | |
438 return 1 | |
439 | |
440 def isfalse(var): | |
441 return 0 | |
442 | |
443 class F2PYError(Exception): | |
444 pass | |
445 | |
446 class throw_error: | |
447 def __init__(self, mess): | |
448 self.mess = mess | |
449 def __call__(self, var): | |
450 mess = '\n\n var = %s\n Message: %s\n' % (var, self.mess) | |
451 raise F2PYError(mess) | |
452 | |
453 def l_and(*f): | |
454 l, l2='lambda v', [] | |
455 for i in range(len(f)): | |
456 l='%s,f%d=f[%d]'%(l, i, i) | |
457 l2.append('f%d(v)'%(i)) | |
458 return eval('%s:%s'%(l, ' and '.join(l2))) | |
459 | |
460 def l_or(*f): | |
461 l, l2='lambda v', [] | |
462 for i in range(len(f)): | |
463 l='%s,f%d=f[%d]'%(l, i, i) | |
464 l2.append('f%d(v)'%(i)) | |
465 return eval('%s:%s'%(l, ' or '.join(l2))) | |
466 | |
467 def l_not(f): | |
468 return eval('lambda v,f=f:not f(v)') | |
469 | |
470 def isdummyroutine(rout): | |
471 try: | |
472 return rout['f2pyenhancements']['fortranname']=='' | |
473 except KeyError: | |
474 return 0 | |
475 | |
476 def getfortranname(rout): | |
477 try: | |
478 name = rout['f2pyenhancements']['fortranname'] | |
479 if name=='': | |
480 raise KeyError | |
481 if not name: | |
482 errmess('Failed to use fortranname from %s\n'%(rout['f2pyenhancements'])) | |
483 raise KeyError | |
484 except KeyError: | |
485 name = rout['name'] | |
486 return name | |
487 | |
488 def getmultilineblock(rout,blockname,comment=1,counter=0): | |
489 try: | |
490 r = rout['f2pyenhancements'].get(blockname) | |
491 except KeyError: | |
492 return | |
493 if not r: return | |
494 if counter > 0 and isinstance(r, str): | |
495 return | |
496 if isinstance(r, list): | |
497 if counter>=len(r): return | |
498 r = r[counter] | |
499 if r[:3]=="'''": | |
500 if comment: | |
501 r = '\t/* start ' + blockname + ' multiline ('+repr(counter)+') */\n' + r[3:] | |
502 else: | |
503 r = r[3:] | |
504 if r[-3:]=="'''": | |
505 if comment: | |
506 r = r[:-3] + '\n\t/* end multiline ('+repr(counter)+')*/' | |
507 else: | |
508 r = r[:-3] | |
509 else: | |
510 errmess("%s multiline block should end with `'''`: %s\n" \ | |
511 % (blockname, repr(r))) | |
512 return r | |
513 | |
514 def getcallstatement(rout): | |
515 return getmultilineblock(rout, 'callstatement') | |
516 | |
517 def getcallprotoargument(rout,cb_map={}): | |
518 r = getmultilineblock(rout, 'callprotoargument', comment=0) | |
519 if r: return r | |
520 if hascallstatement(rout): | |
521 outmess('warning: callstatement is defined without callprotoargument\n') | |
522 return | |
523 from .capi_maps import getctype | |
524 arg_types, arg_types2 = [], [] | |
525 if l_and(isstringfunction, l_not(isfunction_wrap))(rout): | |
526 arg_types.extend(['char*', 'size_t']) | |
527 for n in rout['args']: | |
528 var = rout['vars'][n] | |
529 if isintent_callback(var): | |
530 continue | |
531 if n in cb_map: | |
532 ctype = cb_map[n]+'_typedef' | |
533 else: | |
534 ctype = getctype(var) | |
535 if l_and(isintent_c, l_or(isscalar, iscomplex))(var): | |
536 pass | |
537 elif isstring(var): | |
538 pass | |
539 #ctype = 'void*' | |
540 else: | |
541 ctype = ctype+'*' | |
542 if isstring(var) or isarrayofstrings(var): | |
543 arg_types2.append('size_t') | |
544 arg_types.append(ctype) | |
545 | |
546 proto_args = ','.join(arg_types+arg_types2) | |
547 if not proto_args: | |
548 proto_args = 'void' | |
549 #print proto_args | |
550 return proto_args | |
551 | |
552 def getusercode(rout): | |
553 return getmultilineblock(rout, 'usercode') | |
554 | |
555 def getusercode1(rout): | |
556 return getmultilineblock(rout, 'usercode', counter=1) | |
557 | |
558 def getpymethoddef(rout): | |
559 return getmultilineblock(rout, 'pymethoddef') | |
560 | |
561 def getargs(rout): | |
562 sortargs, args=[], [] | |
563 if 'args' in rout: | |
564 args=rout['args'] | |
565 if 'sortvars' in rout: | |
566 for a in rout['sortvars']: | |
567 if a in args: sortargs.append(a) | |
568 for a in args: | |
569 if a not in sortargs: | |
570 sortargs.append(a) | |
571 else: sortargs=rout['args'] | |
572 return args, sortargs | |
573 | |
574 def getargs2(rout): | |
575 sortargs, args=[], rout.get('args', []) | |
576 auxvars = [a for a in rout['vars'].keys() if isintent_aux(rout['vars'][a])\ | |
577 and a not in args] | |
578 args = auxvars + args | |
579 if 'sortvars' in rout: | |
580 for a in rout['sortvars']: | |
581 if a in args: sortargs.append(a) | |
582 for a in args: | |
583 if a not in sortargs: | |
584 sortargs.append(a) | |
585 else: sortargs=auxvars + rout['args'] | |
586 return args, sortargs | |
587 | |
588 def getrestdoc(rout): | |
589 if 'f2pymultilines' not in rout: | |
590 return None | |
591 k = None | |
592 if rout['block']=='python module': | |
593 k = rout['block'], rout['name'] | |
594 return rout['f2pymultilines'].get(k, None) | |
595 | |
596 def gentitle(name): | |
597 l=(80-len(name)-6)//2 | |
598 return '/*%s %s %s*/'%(l*'*', name, l*'*') | |
599 | |
600 def flatlist(l): | |
601 if isinstance(l, list): | |
602 return reduce(lambda x,y,f=flatlist:x+f(y), l, []) | |
603 return [l] | |
604 | |
605 def stripcomma(s): | |
606 if s and s[-1]==',': return s[:-1] | |
607 return s | |
608 | |
609 def replace(str,d,defaultsep=''): | |
610 if isinstance(d, list): | |
611 return [replace(str, _m, defaultsep) for _m in d] | |
612 if isinstance(str, list): | |
613 return [replace(_m, d, defaultsep) for _m in str] | |
614 for k in 2*list(d.keys()): | |
615 if k=='separatorsfor': | |
616 continue | |
617 if 'separatorsfor' in d and k in d['separatorsfor']: | |
618 sep=d['separatorsfor'][k] | |
619 else: | |
620 sep=defaultsep | |
621 if isinstance(d[k], list): | |
622 str=str.replace('#%s#'%(k), sep.join(flatlist(d[k]))) | |
623 else: | |
624 str=str.replace('#%s#'%(k), d[k]) | |
625 return str | |
626 | |
627 def dictappend(rd, ar): | |
628 if isinstance(ar, list): | |
629 for a in ar: | |
630 rd=dictappend(rd, a) | |
631 return rd | |
632 for k in ar.keys(): | |
633 if k[0]=='_': | |
634 continue | |
635 if k in rd: | |
636 if isinstance(rd[k], str): | |
637 rd[k]=[rd[k]] | |
638 if isinstance(rd[k], list): | |
639 if isinstance(ar[k], list): | |
640 rd[k]=rd[k]+ar[k] | |
641 else: | |
642 rd[k].append(ar[k]) | |
643 elif isinstance(rd[k], dict): | |
644 if isinstance(ar[k], dict): | |
645 if k=='separatorsfor': | |
646 for k1 in ar[k].keys(): | |
647 if k1 not in rd[k]: | |
648 rd[k][k1]=ar[k][k1] | |
649 else: | |
650 rd[k]=dictappend(rd[k], ar[k]) | |
651 else: | |
652 rd[k]=ar[k] | |
653 return rd | |
654 | |
655 def applyrules(rules,d,var={}): | |
656 ret={} | |
657 if isinstance(rules, list): | |
658 for r in rules: | |
659 rr=applyrules(r, d, var) | |
660 ret=dictappend(ret, rr) | |
661 if '_break' in rr: | |
662 break | |
663 return ret | |
664 if '_check' in rules and (not rules['_check'](var)): | |
665 return ret | |
666 if 'need' in rules: | |
667 res = applyrules({'needs':rules['need']}, d, var) | |
668 if 'needs' in res: | |
669 cfuncs.append_needs(res['needs']) | |
670 | |
671 for k in rules.keys(): | |
672 if k=='separatorsfor': | |
673 ret[k]=rules[k]; continue | |
674 if isinstance(rules[k], str): | |
675 ret[k]=replace(rules[k], d) | |
676 elif isinstance(rules[k], list): | |
677 ret[k]=[] | |
678 for i in rules[k]: | |
679 ar=applyrules({k:i}, d, var) | |
680 if k in ar: | |
681 ret[k].append(ar[k]) | |
682 elif k[0]=='_': | |
683 continue | |
684 elif isinstance(rules[k], dict): | |
685 ret[k]=[] | |
686 for k1 in rules[k].keys(): | |
687 if isinstance(k1, types.FunctionType) and k1(var): | |
688 if isinstance(rules[k][k1], list): | |
689 for i in rules[k][k1]: | |
690 if isinstance(i, dict): | |
691 res=applyrules({'supertext':i}, d, var) | |
692 if 'supertext' in res: | |
693 i=res['supertext'] | |
694 else: i='' | |
695 ret[k].append(replace(i, d)) | |
696 else: | |
697 i=rules[k][k1] | |
698 if isinstance(i, dict): | |
699 res=applyrules({'supertext':i}, d) | |
700 if 'supertext' in res: | |
701 i=res['supertext'] | |
702 else: i='' | |
703 ret[k].append(replace(i, d)) | |
704 else: | |
705 errmess('applyrules: ignoring rule %s.\n'%repr(rules[k])) | |
706 if isinstance(ret[k], list): | |
707 if len(ret[k])==1: | |
708 ret[k]=ret[k][0] | |
709 if ret[k]==[]: | |
710 del ret[k] | |
711 return ret |