comparison env/lib/python3.9/site-packages/galaxy/util/template.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4f3585e2f14b
1 """Entry point for the usage of Cheetah templating within Galaxy."""
2
3 import traceback
4 from lib2to3.refactor import RefactoringTool
5
6 import packaging.version
7 from Cheetah.Compiler import Compiler
8 from Cheetah.NameMapper import NotFound
9 from Cheetah.Parser import ParseError
10 from Cheetah.Template import Template
11 from past.translation import myfixes
12
13 from . import unicodify
14
15 # Skip libpasteurize fixers, which make sure code is py2 and py3 compatible.
16 # This is not needed, we only translate code on py3.
17 myfixes = [f for f in myfixes if not f.startswith('libpasteurize')]
18 refactoring_tool = RefactoringTool(myfixes, {'print_function': True})
19
20
21 class FixedModuleCodeCompiler(Compiler):
22
23 module_code = None
24
25 def getModuleCode(self):
26 self._moduleDef = self.module_code
27 return self._moduleDef
28
29
30 def create_compiler_class(module_code):
31
32 class CustomCompilerClass(FixedModuleCodeCompiler):
33 pass
34
35 CustomCompilerClass.module_code = module_code
36 return CustomCompilerClass
37
38
39 def fill_template(template_text,
40 context=None,
41 retry=10,
42 compiler_class=Compiler,
43 first_exception=None,
44 futurized=False,
45 python_template_version='3',
46 **kwargs):
47 """Fill a cheetah template out for specified context.
48
49 If template_text is None, an exception will be thrown, if context
50 is None (the default) - keyword arguments to this function will be used
51 as the context.
52 """
53 if template_text is None:
54 raise TypeError("Template text specified as None to fill_template.")
55 if not context:
56 context = kwargs
57 if isinstance(python_template_version, str):
58 python_template_version = packaging.version.parse(python_template_version)
59 try:
60 klass = Template.compile(source=template_text, compilerClass=compiler_class)
61 except ParseError as e:
62 # Might happen on invalid syntax within a cheetah statement, like `#if $smxsize <> 128.0`
63 if first_exception is None:
64 first_exception = e
65 if python_template_version.release[0] < 3 and retry > 0:
66 module_code = Template.compile(source=template_text, compilerClass=compiler_class, returnAClass=False).decode('utf-8')
67 module_code = futurize_preprocessor(module_code)
68 compiler_class = create_compiler_class(module_code)
69 return fill_template(
70 template_text=template_text,
71 context=context,
72 retry=retry - 1,
73 compiler_class=compiler_class,
74 first_exception=first_exception,
75 python_template_version=python_template_version,
76 )
77 raise first_exception or e
78 t = klass(searchList=[context])
79 try:
80 return unicodify(t, log_exception=False)
81 except NotFound as e:
82 if first_exception is None:
83 first_exception = e
84 if python_template_version.release[0] < 3 and retry > 0:
85 tb = e.__traceback__
86 last_stack = traceback.extract_tb(tb)[-1]
87 if last_stack.name == '<listcomp>':
88 # On python 3 list, dict and set comprehensions as well as generator expressions
89 # have their own local scope, which prevents accessing frame variables in cheetah.
90 # We can work around this by replacing `$var` with `var`, but we only do this for
91 # list comprehensions, as this has never worked for dict or set comprehensions or
92 # generator expressions in Cheetah.
93 var_not_found = e.args[0].split("'")[1]
94 replace_str = 'VFFSL(SL,"%s",True)' % var_not_found
95 lineno = last_stack.lineno - 1
96 module_code = t._CHEETAH_generatedModuleCode.splitlines()
97 module_code[lineno] = module_code[lineno].replace(replace_str, var_not_found)
98 module_code = "\n".join(module_code)
99 compiler_class = create_compiler_class(module_code)
100 return fill_template(template_text=template_text,
101 context=context,
102 retry=retry - 1,
103 compiler_class=compiler_class,
104 first_exception=first_exception,
105 python_template_version=python_template_version,
106 )
107 raise first_exception or e
108 except Exception as e:
109 if first_exception is None:
110 first_exception = e
111 if python_template_version.release[0] < 3 and not futurized:
112 # Possibly an error caused by attempting to run python 2
113 # template code on python 3. Run the generated module code
114 # through futurize and hope for the best.
115 module_code = t._CHEETAH_generatedModuleCode
116 module_code = futurize_preprocessor(module_code)
117 compiler_class = create_compiler_class(module_code)
118 return fill_template(template_text=template_text,
119 context=context,
120 retry=retry,
121 compiler_class=compiler_class,
122 first_exception=first_exception,
123 futurized=True,
124 python_template_version=python_template_version,
125 )
126 raise first_exception or e
127
128
129 def futurize_preprocessor(source):
130 source = str(refactoring_tool.refactor_string(source, name='auto_translate_cheetah'))
131 # libfuturize.fixes.fix_unicode_keep_u' breaks from Cheetah.compat import unicode
132 source = source.replace('from Cheetah.compat import str', 'from Cheetah.compat import unicode')
133 return source