opt
/
hc_python
/
lib
/
python3.12
/
site-packages
/
mako
/
Go to Home Directory
+
Upload
Create File
root@0UT1S:~$
Execute
By Order of Mr.0UT1S
[DIR] ..
N/A
[DIR] __pycache__
N/A
[DIR] ext
N/A
[DIR] testing
N/A
__init__.py
242 bytes
Rename
Delete
_ast_util.py
19.77 KB
Rename
Delete
ast.py
6.49 KB
Rename
Delete
cache.py
7.50 KB
Rename
Delete
cmd.py
2.75 KB
Rename
Delete
codegen.py
46.62 KB
Rename
Delete
compat.py
1.78 KB
Rename
Delete
exceptions.py
12.24 KB
Rename
Delete
filters.py
4.55 KB
Rename
Delete
lexer.py
15.94 KB
Rename
Delete
lookup.py
12.14 KB
Rename
Delete
parsetree.py
18.58 KB
Rename
Delete
pygen.py
10.17 KB
Rename
Delete
pyparser.py
7.30 KB
Rename
Delete
runtime.py
27.15 KB
Rename
Delete
template.py
23.01 KB
Rename
Delete
util.py
10.39 KB
Rename
Delete
# mako/lexer.py # Copyright 2006-2025 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php """provides the Lexer class for parsing template strings into parse trees.""" import codecs import re from mako import exceptions from mako import parsetree from mako.pygen import adjust_whitespace _regexp_cache = {} class Lexer: def __init__( self, text, filename=None, input_encoding=None, preprocessor=None ): self.text = text self.filename = filename self.template = parsetree.TemplateNode(self.filename) self.matched_lineno = 1 self.matched_charpos = 0 self.lineno = 1 self.match_position = 0 self.tag = [] self.control_line = [] self.ternary_stack = [] self.encoding = input_encoding if preprocessor is None: self.preprocessor = [] elif not hasattr(preprocessor, "__iter__"): self.preprocessor = [preprocessor] else: self.preprocessor = preprocessor @property def exception_kwargs(self): return { "source": self.text, "lineno": self.matched_lineno, "pos": self.matched_charpos, "filename": self.filename, } def match(self, regexp, flags=None): """compile the given regexp, cache the reg, and call match_reg().""" try: reg = _regexp_cache[(regexp, flags)] except KeyError: reg = re.compile(regexp, flags) if flags else re.compile(regexp) _regexp_cache[(regexp, flags)] = reg return self.match_reg(reg) def match_reg(self, reg): """match the given regular expression object to the current text position. if a match occurs, update the current text and line position. """ mp = self.match_position match = reg.match(self.text, self.match_position) if match: (start, end) = match.span() self.match_position = end + 1 if end == start else end self.matched_lineno = self.lineno cp = mp - 1 if cp >= 0 and cp < self.textlength: cp = self.text[: cp + 1].rfind("\n") self.matched_charpos = mp - cp self.lineno += self.text[mp : self.match_position].count("\n") return match def parse_until_text(self, watch_nesting, *text): startpos = self.match_position text_re = r"|".join(text) brace_level = 0 paren_level = 0 bracket_level = 0 while True: match = self.match(r"#.*\n") if match: continue match = self.match( r"(\"\"\"|\'\'\'|\"|\')[^\\]*?(\\.[^\\]*?)*\1", re.S ) if match: continue match = self.match(r"(%s)" % text_re) if match and not ( watch_nesting and (brace_level > 0 or paren_level > 0 or bracket_level > 0) ): return ( self.text[ startpos : self.match_position - len(match.group(1)) ], match.group(1), ) elif not match: match = self.match(r"(.*?)(?=\"|\'|#|%s)" % text_re, re.S) if match: brace_level += match.group(1).count("{") brace_level -= match.group(1).count("}") paren_level += match.group(1).count("(") paren_level -= match.group(1).count(")") bracket_level += match.group(1).count("[") bracket_level -= match.group(1).count("]") continue raise exceptions.SyntaxException( "Expected: %s" % ",".join(text), **self.exception_kwargs ) def append_node(self, nodecls, *args, **kwargs): kwargs.setdefault("source", self.text) kwargs.setdefault("lineno", self.matched_lineno) kwargs.setdefault("pos", self.matched_charpos) kwargs["filename"] = self.filename node = nodecls(*args, **kwargs) if len(self.tag): self.tag[-1].nodes.append(node) else: self.template.nodes.append(node) # build a set of child nodes for the control line # (used for loop variable detection) # also build a set of child nodes on ternary control lines # (used for determining if a pass needs to be auto-inserted if self.control_line: control_frame = self.control_line[-1] control_frame.nodes.append(node) if ( not ( isinstance(node, parsetree.ControlLine) and control_frame.is_ternary(node.keyword) ) and self.ternary_stack and self.ternary_stack[-1] ): self.ternary_stack[-1][-1].nodes.append(node) if isinstance(node, parsetree.Tag): if len(self.tag): node.parent = self.tag[-1] self.tag.append(node) elif isinstance(node, parsetree.ControlLine): if node.isend: self.control_line.pop() self.ternary_stack.pop() elif node.is_primary: self.control_line.append(node) self.ternary_stack.append([]) elif self.control_line and self.control_line[-1].is_ternary( node.keyword ): self.ternary_stack[-1].append(node) elif self.control_line and not self.control_line[-1].is_ternary( node.keyword ): raise exceptions.SyntaxException( "Keyword '%s' not a legal ternary for keyword '%s'" % (node.keyword, self.control_line[-1].keyword), **self.exception_kwargs, ) _coding_re = re.compile(r"#.*coding[:=]\s*([-\w.]+).*\r?\n") def decode_raw_stream(self, text, decode_raw, known_encoding, filename): """given string/unicode or bytes/string, determine encoding from magic encoding comment, return body as unicode or raw if decode_raw=False """ if isinstance(text, str): m = self._coding_re.match(text) encoding = m and m.group(1) or known_encoding or "utf-8" return encoding, text if text.startswith(codecs.BOM_UTF8): text = text[len(codecs.BOM_UTF8) :] parsed_encoding = "utf-8" m = self._coding_re.match(text.decode("utf-8", "ignore")) if m is not None and m.group(1) != "utf-8": raise exceptions.CompileException( "Found utf-8 BOM in file, with conflicting " "magic encoding comment of '%s'" % m.group(1), text.decode("utf-8", "ignore"), 0, 0, filename, ) else: m = self._coding_re.match(text.decode("utf-8", "ignore")) parsed_encoding = m.group(1) if m else known_encoding or "utf-8" if decode_raw: try: text = text.decode(parsed_encoding) except UnicodeDecodeError: raise exceptions.CompileException( "Unicode decode operation of encoding '%s' failed" % parsed_encoding, text.decode("utf-8", "ignore"), 0, 0, filename, ) return parsed_encoding, text def parse(self): self.encoding, self.text = self.decode_raw_stream( self.text, True, self.encoding, self.filename ) for preproc in self.preprocessor: self.text = preproc(self.text) # push the match marker past the # encoding comment. self.match_reg(self._coding_re) self.textlength = len(self.text) while True: if self.match_position > self.textlength: break if self.match_end(): break if self.match_expression(): continue if self.match_control_line(): continue if self.match_comment(): continue if self.match_tag_start(): continue if self.match_tag_end(): continue if self.match_python_block(): continue if self.match_percent(): continue if self.match_text(): continue if self.match_position > self.textlength: break # TODO: no coverage here raise exceptions.MakoException("assertion failed") if len(self.tag): raise exceptions.SyntaxException( "Unclosed tag: <%%%s>" % self.tag[-1].keyword, **self.exception_kwargs, ) if len(self.control_line): raise exceptions.SyntaxException( "Unterminated control keyword: '%s'" % self.control_line[-1].keyword, self.text, self.control_line[-1].lineno, self.control_line[-1].pos, self.filename, ) return self.template def match_tag_start(self): reg = r""" \<% # opening tag ([\w\.\:]+) # keyword ((?:\s+\w+|\s*=\s*|"[^"]*?"|'[^']*?'|\s*,\s*)*) # attrname, = \ # sign, string expression # comma is for backwards compat # identified in #366 \s* # more whitespace (/)?> # closing """ match = self.match( reg, re.I | re.S | re.X, ) if not match: return False keyword, attr, isend = match.groups() self.keyword = keyword attributes = {} if attr: for att in re.findall( r"\s*(\w+)\s*=\s*(?:'([^']*)'|\"([^\"]*)\")", attr ): key, val1, val2 = att text = val1 or val2 text = text.replace("\r\n", "\n") attributes[key] = text self.append_node(parsetree.Tag, keyword, attributes) if isend: self.tag.pop() elif keyword == "text": match = self.match(r"(.*?)(?=\</%text>)", re.S) if not match: raise exceptions.SyntaxException( "Unclosed tag: <%%%s>" % self.tag[-1].keyword, **self.exception_kwargs, ) self.append_node(parsetree.Text, match.group(1)) return self.match_tag_end() return True def match_tag_end(self): match = self.match(r"\</%[\t ]*([^\t ]+?)[\t ]*>") if match: if not len(self.tag): raise exceptions.SyntaxException( "Closing tag without opening tag: </%%%s>" % match.group(1), **self.exception_kwargs, ) elif self.tag[-1].keyword != match.group(1): raise exceptions.SyntaxException( "Closing tag </%%%s> does not match tag: <%%%s>" % (match.group(1), self.tag[-1].keyword), **self.exception_kwargs, ) self.tag.pop() return True else: return False def match_end(self): match = self.match(r"\Z", re.S) if not match: return False string = match.group() if string: return string else: return True def match_percent(self): match = self.match(r"(?<=^)(\s*)%%(%*)", re.M) if match: self.append_node( parsetree.Text, match.group(1) + "%" + match.group(2) ) return True else: return False def match_text(self): match = self.match( r""" (.*?) # anything, followed by: ( (?<=\n)(?=[ \t]*(?=%|\#\#)) # an eval or line-based # comment, preceded by a # consumed newline and whitespace | (?=\${) # an expression | (?=</?%) # a substitution or block or call start or end # - don't consume | (\\\r?\n) # an escaped newline - throw away | \Z # end of string )""", re.X | re.S, ) if match: text = match.group(1) if text: self.append_node(parsetree.Text, text) return True else: return False def match_python_block(self): match = self.match(r"<%(!)?") if match: line, pos = self.matched_lineno, self.matched_charpos text, end = self.parse_until_text(False, r"%>") # the trailing newline helps # compiler.parse() not complain about indentation text = adjust_whitespace(text) + "\n" self.append_node( parsetree.Code, text, match.group(1) == "!", lineno=line, pos=pos, ) return True else: return False def match_expression(self): match = self.match(r"\${") if not match: return False line, pos = self.matched_lineno, self.matched_charpos text, end = self.parse_until_text(True, r"\|", r"}") if end == "|": escapes, end = self.parse_until_text(True, r"}") else: escapes = "" text = text.replace("\r\n", "\n") self.append_node( parsetree.Expression, text, escapes.strip(), lineno=line, pos=pos, ) return True def match_control_line(self): match = self.match( r"(?<=^)[\t ]*(%(?!%)|##)[\t ]*((?:(?:\\\r?\n)|[^\r\n])*)" r"(?:\r?\n|\Z)", re.M, ) if not match: return False operator = match.group(1) text = match.group(2) if operator == "%": m2 = re.match(r"(end)?(\w+)\s*(.*)", text) if not m2: raise exceptions.SyntaxException( "Invalid control line: '%s'" % text, **self.exception_kwargs, ) isend, keyword = m2.group(1, 2) isend = isend is not None if isend: if not len(self.control_line): raise exceptions.SyntaxException( "No starting keyword '%s' for '%s'" % (keyword, text), **self.exception_kwargs, ) elif self.control_line[-1].keyword != keyword: raise exceptions.SyntaxException( "Keyword '%s' doesn't match keyword '%s'" % (text, self.control_line[-1].keyword), **self.exception_kwargs, ) self.append_node(parsetree.ControlLine, keyword, isend, text) else: self.append_node(parsetree.Comment, text) return True def match_comment(self): """matches the multiline version of a comment""" match = self.match(r"<%doc>(.*?)</%doc>", re.S) if match: self.append_node(parsetree.Comment, match.group(1)) return True else: return False
Save