def _generate(self, source, name, filename, defer_init=False): """Internal hook that can be overridden to hook a different generate method in. .. versionadded:: 2.5 """ return generate(source, self, name, filename, defer_init=defer_init)
def compile(self, source, name=None, filename=None, raw=False): """Compile a node or template source code. The `name` parameter is the load name of the template after it was joined using :meth:`join_path` if necessary, not the filename on the file system. the `filename` parameter is the estimated filename of the template on the file system. If the template came from a database or memory this can be omitted. The return value of this method is a python code object. If the `raw` parameter is `True` the return value will be a string with python code equivalent to the bytecode returned otherwise. This method is mainly used internally. """ if isinstance(source, basestring): source = self.parse(source, name, filename) if self.optimized: source = optimize(source, self) source = generate(source, self, name, filename) if raw: return source if filename is None: filename = '<template>' elif isinstance(filename, unicode): filename = filename.encode('utf-8') return compile(source, filename, 'exec')
def compile(self, source, name=None, filename=None, raw=False): """Compile a node or template source code. The `name` parameter is the load name of the template after it was joined using :meth:`join_path` if necessary, not the filename on the file system. the `filename` parameter is the estimated filename of the template on the file system. If the template came from a database or memory this can be omitted. The return value of this method is a python code object. If the `raw` parameter is `True` the return value will be a string with python code equivalent to the bytecode returned otherwise. This method is mainly used internally. """ if isinstance(source, basestring): source = self.parse(source, name, filename) if self.optimized: node = optimize(source, self) source = generate(node, self, name, filename) if raw: return source if filename is None: filename = '<template>' elif isinstance(filename, unicode): filename = filename.encode('utf-8') return compile(source, filename, 'exec')
def compile(self, source, name=None, filename=None, raw=False): """Compile a node or template source code. The `name` parameter is the load name of the template after it was joined using :meth:`join_path` if necessary, not the filename on the file system. the `filename` parameter is the estimated filename of the template on the file system. If the template came from a database or memory this can be omitted. The return value of this method is a python code object. If the `raw` parameter is `True` the return value will be a string with python code equivalent to the bytecode returned otherwise. This method is mainly used internally. """ source_hint = None try: if isinstance(source, basestring): source_hint = source source = self._parse(source, name, filename) if self.optimized: source = optimize(source, self) source = generate(source, self, name, filename) if raw: return source if filename is None: filename = '<template>' else: filename = _encode_filename(filename) return compile(source, filename, 'exec') except TemplateSyntaxError: exc_info = sys.exc_info() self.handle_exception(exc_info, source_hint=source)
def _check_conditional(self, conditional, templar, all_vars): ''' This method does the low-level evaluation of each conditional set on this object, using jinja2 to wrap the conditionals for evaluation. ''' original = conditional if conditional is None or conditional == '': return True # this allows for direct boolean assignments to conditionals "when: False" if isinstance(conditional, bool): return conditional if templar.is_template(conditional): display.warning('when statements should not include jinja2 ' 'templating delimiters such as {{ }} or {%% %%}. ' 'Found: %s' % conditional) # pull the "bare" var out, which allows for nested conditionals # and things like: # - assert: # that: # - item # with_items: # - 1 == 1 if conditional in all_vars and VALID_VAR_REGEX.match(conditional): conditional = all_vars[conditional] # make sure the templar is using the variables specified with this method templar.set_available_variables(variables=all_vars) try: # if the conditional is "unsafe", disable lookups disable_lookups = hasattr(conditional, '__UNSAFE__') conditional = templar.template(conditional, disable_lookups=disable_lookups) if not isinstance(conditional, text_type) or conditional == "": return conditional # update the lookups flag, as the string returned above may now be unsafe # and we don't want future templating calls to do unsafe things disable_lookups |= hasattr(conditional, '__UNSAFE__') # First, we do some low-level jinja2 parsing involving the AST format of the # statement to ensure we don't do anything unsafe (using the disable_lookup flag above) class CleansingNodeVisitor(ast.NodeVisitor): def generic_visit(self, node, inside_call=False, inside_yield=False): if isinstance(node, ast.Call): inside_call = True elif isinstance(node, ast.Yield): inside_yield = True elif isinstance(node, ast.Str): if disable_lookups: if inside_call and node.s.startswith("__"): # calling things with a dunder is generally bad at this point... raise AnsibleError( "Invalid access found in the conditional: '%s'" % conditional ) elif inside_yield: # we're inside a yield, so recursively parse and traverse the AST # of the result to catch forbidden syntax from executing parsed = ast.parse(node.s, mode='exec') cnv = CleansingNodeVisitor() cnv.visit(parsed) # iterate over all child nodes for child_node in ast.iter_child_nodes(node): self.generic_visit( child_node, inside_call=inside_call, inside_yield=inside_yield ) try: e = templar.environment.overlay() e.filters.update(templar._get_filters(e.filters)) e.tests.update(templar._get_tests()) res = e._parse(conditional, None, None) res = generate(res, e, None, None) parsed = ast.parse(res, mode='exec') cnv = CleansingNodeVisitor() cnv.visit(parsed) except Exception as e: raise AnsibleError("Invalid conditional detected: %s" % to_native(e)) # and finally we generate and template the presented string and look at the resulting string presented = "{%% if %s %%} True {%% else %%} False {%% endif %%}" % conditional val = templar.template(presented, disable_lookups=disable_lookups).strip() if val == "True": return True elif val == "False": return False else: raise AnsibleError("unable to evaluate conditional: %s" % original) except (AnsibleUndefinedVariable, UndefinedError) as e: # the templating failed, meaning most likely a variable was undefined. If we happened # to be looking for an undefined variable, return True, otherwise fail try: # first we extract the variable name from the error message var_name = re.compile(r"'(hostvars\[.+\]|[\w_]+)' is undefined").search(str(e)).groups()[0] # next we extract all defined/undefined tests from the conditional string def_undef = self.extract_defined_undefined(conditional) # then we loop through these, comparing the error variable name against # each def/undef test we found above. If there is a match, we determine # whether the logic/state mean the variable should exist or not and return # the corresponding True/False for (du_var, logic, state) in def_undef: # when we compare the var names, normalize quotes because something # like hostvars['foo'] may be tested against hostvars["foo"] if var_name.replace("'", '"') == du_var.replace("'", '"'): # the should exist is a xor test between a negation in the logic portion # against the state (defined or undefined) should_exist = ('not' in logic) != (state == 'defined') if should_exist: return False else: return True # as nothing above matched the failed var name, re-raise here to # trigger the AnsibleUndefinedVariable exception again below raise except Exception as new_e: raise AnsibleUndefinedVariable("error while evaluating conditional (%s): %s" % (original, e))
def _generate(self, source, name, filename, defer_init = False): return generate(source, self, name, filename, defer_init=defer_init)
def _check_conditional(self, conditional, templar, all_vars): ''' This method does the low-level evaluation of each conditional set on this object, using jinja2 to wrap the conditionals for evaluation. ''' original = conditional if conditional is None or conditional == '': return True if templar.is_template(conditional): display.warning('when statements should not include jinja2 ' 'templating delimiters such as {{ }} or {%% %%}. ' 'Found: %s' % conditional) # pull the "bare" var out, which allows for nested conditionals # and things like: # - assert: # that: # - item # with_items: # - 1 == 1 if conditional in all_vars and VALID_VAR_REGEX.match(conditional): conditional = all_vars[conditional] # make sure the templar is using the variables specified with this method templar.set_available_variables(variables=all_vars) try: # if the conditional is "unsafe", disable lookups disable_lookups = hasattr(conditional, '__UNSAFE__') conditional = templar.template(conditional, disable_lookups=disable_lookups) if not isinstance(conditional, text_type) or conditional == "": return conditional # update the lookups flag, as the string returned above may now be unsafe # and we don't want future templating calls to do unsafe things disable_lookups |= hasattr(conditional, '__UNSAFE__') # First, we do some low-level jinja2 parsing involving the AST format of the # statement to ensure we don't do anything unsafe (using the disable_lookup flag above) class CleansingNodeVisitor(ast.NodeVisitor): def generic_visit(self, node, inside_call=False, inside_yield=False): if isinstance(node, ast.Call): inside_call = True elif isinstance(node, ast.Yield): inside_yield = True elif isinstance(node, ast.Str): if disable_lookups: if inside_call and node.s.startswith("__"): # calling things with a dunder is generally bad at this point... raise AnsibleError( "Invalid access found in the conditional: '%s'" % conditional ) elif inside_yield: # we're inside a yield, so recursively parse and traverse the AST # of the result to catch forbidden syntax from executing parsed = ast.parse(node.s, mode='exec') cnv = CleansingNodeVisitor() cnv.visit(parsed) # iterate over all child nodes for child_node in ast.iter_child_nodes(node): self.generic_visit( child_node, inside_call=inside_call, inside_yield=inside_yield ) try: e = templar.environment.overlay() e.filters.update(templar._get_filters()) e.tests.update(templar._get_tests()) res = e._parse(conditional, None, None) res = generate(res, e, None, None) parsed = ast.parse(res, mode='exec') cnv = CleansingNodeVisitor() cnv.visit(parsed) except Exception as e: raise AnsibleError("Invalid conditional detected: %s" % to_native(e)) # and finally we generate and template the presented string and look at the resulting string presented = "{%% if %s %%} True {%% else %%} False {%% endif %%}" % conditional val = templar.template(presented, disable_lookups=disable_lookups).strip() if val == "True": return True elif val == "False": return False else: raise AnsibleError("unable to evaluate conditional: %s" % original) except (AnsibleUndefinedVariable, UndefinedError) as e: # the templating failed, meaning most likely a variable was undefined. If we happened # to be looking for an undefined variable, return True, otherwise fail try: # first we extract the variable name from the error message var_name = re.compile(r"'(hostvars\[.+\]|[\w_]+)' is undefined").search(str(e)).groups()[0] # next we extract all defined/undefined tests from the conditional string def_undef = self.extract_defined_undefined(conditional) # then we loop through these, comparing the error variable name against # each def/undef test we found above. If there is a match, we determine # whether the logic/state mean the variable should exist or not and return # the corresponding True/False for (du_var, logic, state) in def_undef: # when we compare the var names, normalize quotes because something # like hostvars['foo'] may be tested against hostvars["foo"] if var_name.replace("'", '"') == du_var.replace("'", '"'): # the should exist is a xor test between a negation in the logic portion # against the state (defined or undefined) should_exist = ('not' in logic) != (state == 'defined') if should_exist: return False else: return True # as nothing above matched the failed var name, re-raise here to # trigger the AnsibleUndefinedVariable exception again below raise except Exception as new_e: raise AnsibleUndefinedVariable("error while evaluating conditional (%s): %s" % (original, e))
def _check_conditional(self, conditional, templar, all_vars): ''' This method does the low-level evaluation of each conditional set on this object, using jinja2 to wrap the conditionals for evaluation. ''' original = conditional if templar.is_template(conditional): display.warning('conditional statements should not include jinja2 ' 'templating delimiters such as {{ }} or {%% %%}. ' 'Found: %s' % conditional) # make sure the templar is using the variables specified with this method templar.available_variables = all_vars try: # if the conditional is "unsafe", disable lookups disable_lookups = hasattr(conditional, '__UNSAFE__') conditional = templar.template(conditional, disable_lookups=disable_lookups) if not isinstance(conditional, text_type) or conditional == "": return conditional # update the lookups flag, as the string returned above may now be unsafe # and we don't want future templating calls to do unsafe things disable_lookups |= hasattr(conditional, '__UNSAFE__') # First, we do some low-level jinja2 parsing involving the AST format of the # statement to ensure we don't do anything unsafe (using the disable_lookup flag above) class CleansingNodeVisitor(ast.NodeVisitor): def generic_visit(self, node, inside_call=False, inside_yield=False): if isinstance(node, ast.Call): inside_call = True elif isinstance(node, ast.Yield): inside_yield = True elif isinstance(node, ast.Str): if disable_lookups: if inside_call and node.s.startswith("__"): # calling things with a dunder is generally bad at this point... raise AnsibleError( "Invalid access found in the conditional: '%s'" % conditional ) elif inside_yield: # we're inside a yield, so recursively parse and traverse the AST # of the result to catch forbidden syntax from executing parsed = ast.parse(node.s, mode='exec') cnv = CleansingNodeVisitor() cnv.visit(parsed) # iterate over all child nodes for child_node in ast.iter_child_nodes(node): self.generic_visit( child_node, inside_call=inside_call, inside_yield=inside_yield ) try: res = templar.environment.parse(conditional, None, None) res = generate(res, templar.environment, None, None) parsed = ast.parse(res, mode='exec') cnv = CleansingNodeVisitor() cnv.visit(parsed) except Exception as e: raise AnsibleError("Invalid conditional detected: %s" % to_native(e)) # and finally we generate and template the presented string and look at the resulting string # NOTE The spaces around True and False are intentional to short-circuit literal_eval for # jinja2_native=False and avoid its expensive calls. presented = "{%% if %s %%} True {%% else %%} False {%% endif %%}" % conditional # NOTE Convert the result to text to account for both native and non-native jinja. # NOTE The templated result of `presented` is string on native jinja as well prior to Python 3.10. # ast.literal_eval on Python 3.10 removes leading whitespaces so " True " becomes bool True # as opposed to Python 3.9 and lower where the same would result in IndentationError and # string " True " would be returned by Templar. val = to_text(templar.template(presented, disable_lookups=disable_lookups)).strip() if val == "True": return True elif val == "False": return False else: raise AnsibleError("unable to evaluate conditional: %s" % original) except (AnsibleUndefinedVariable, UndefinedError) as e: # the templating failed, meaning most likely a variable was undefined. If we happened # to be looking for an undefined variable, return True, otherwise fail try: # first we extract the variable name from the error message var_name = re.compile(r"'(hostvars\[.+\]|[\w_]+)' is undefined").search(str(e)).groups()[0] # next we extract all defined/undefined tests from the conditional string def_undef = self.extract_defined_undefined(conditional) # then we loop through these, comparing the error variable name against # each def/undef test we found above. If there is a match, we determine # whether the logic/state mean the variable should exist or not and return # the corresponding True/False for (du_var, logic, state) in def_undef: # when we compare the var names, normalize quotes because something # like hostvars['foo'] may be tested against hostvars["foo"] if var_name.replace("'", '"') == du_var.replace("'", '"'): # the should exist is a xor test between a negation in the logic portion # against the state (defined or undefined) should_exist = ('not' in logic) != (state == 'defined') if should_exist: return False else: return True # as nothing above matched the failed var name, re-raise here to # trigger the AnsibleUndefinedVariable exception again below raise except Exception: raise AnsibleUndefinedVariable("error while evaluating conditional (%s): %s" % (original, e))
def _generate(self, source, name, filename, defer_init=False): return generate(source, self, name, filename, defer_init=defer_init)
def _check_conditional(self, conditional, templar, all_vars): ''' This method does the low-level evaluation of each conditional set on this object, using jinja2 to wrap the conditionals for evaluation. ''' original = conditional if conditional is None or conditional == '': return True # pull the "bare" var out, which allows for nested conditionals # and things like: # - assert: # that: # - item # with_items: # - 1 == 1 if conditional in all_vars and VALID_VAR_REGEX.match(conditional): conditional = all_vars[conditional] # make sure the templar is using the variables specified with this method templar.set_available_variables(variables=all_vars) try: # if the conditional is "unsafe", disable lookups disable_lookups = hasattr(conditional, '__UNSAFE__') conditional = templar.template(conditional, disable_lookups=disable_lookups) if not isinstance(conditional, text_type) or conditional == "": return conditional # update the lookups flag, as the string returned above may now be unsafe # and we don't want future templating calls to do unsafe things disable_lookups |= hasattr(conditional, '__UNSAFE__') # now we generated the "presented" string, which is a jinja2 if/else block # used to evaluate the conditional. First, we do some low-level jinja2 parsing # involving the AST format of the statement to ensure we don't do anything # unsafe (using the disable_lookup flag above) e = templar.environment.overlay() e.filters.update(templar._get_filters()) e.tests.update(templar._get_tests()) presented = "{%% if %s %%} True {%% else %%} False {%% endif %%}" % conditional res = e._parse(presented, None, None) res = generate(res, e, None, None) parsed = ast.parse(res, mode='exec') class CleansingNodeVisitor(ast.NodeVisitor): def generic_visit(self, node, inside_call=False): if isinstance(node, ast.Call): inside_call = True elif isinstance(node, ast.Str): # calling things with a dunder is generally bad at this point... if inside_call and disable_lookups and node.s.startswith("__"): raise AnsibleError("Invalid access found in the presented conditional: '%s'" % conditional) # iterate over all child nodes for child_node in ast.iter_child_nodes(node): self.generic_visit(child_node, inside_call=inside_call) cnv = CleansingNodeVisitor() cnv.visit(parsed) # and finally we templated the presented string and look at the resulting string val = templar.template(presented, disable_lookups=disable_lookups).strip() if val == "True": return True elif val == "False": return False else: raise AnsibleError("unable to evaluate conditional: %s" % original) except (AnsibleUndefinedVariable, UndefinedError) as e: # the templating failed, meaning most likely a # variable was undefined. If we happened to be # looking for an undefined variable, return True, # otherwise fail if "is undefined" in original or "is not defined" in original or "not is defined" in original: return True elif "is defined" in original or "is not undefined" in original or "not is undefined" in original: return False else: raise AnsibleUndefinedVariable("error while evaluating conditional (%s): %s" % (original, e))
| default("hesus") %} {% set suggested_ext_path ="suggestion" %} {% set repository_path = tmp_repo_path | codepath() | default (suggested_ext_path) %} """ text = """" Hi {{ surname | description("Please enter surname") }} and welcome back Mrs {{ surname }} """ env = EMTemplatesEnv().make_env( "/home/dgarcia/dev/python/em_automation/sql_gen/templates") # t =env.from_string(text) # t = env.get_template("dynamic.sql") t = env.get_template("add_dynamic_content_verb.sql") # t = Template(text) print("***printing template rendered****") print(t.render({"entity_name": "ContactED"})) # text = env.loader.get_source(env,"dynamic.sql")[0] # text = env.loader.get_source(env,"entity_def.sql")[0] text = env.loader.get_source(env, "add_dynamic_content_verb.sql")[0] # self.env.parse(template_source_text) tree = t.environment.parse(text) print("***printing tree****") # TreeDrawer().print_node(tree) print("****Generated root function****") print(generate(tree, t.environment, "pedro", "<<ast>>")) context = t.new_context({}) # rendered_text =concat(t.root_render_func(context)) print("context looks like " + str(context)) print("context vars looks like " + str(context.vars))