diff options
author | Federico Caselli <cfederico87@gmail.com> | 2021-09-13 23:09:06 +0200 |
---|---|---|
committer | Federico Caselli <cfederico87@gmail.com> | 2021-10-23 11:11:48 +0200 |
commit | a1d70afb5974125a1a65f590418c7c371bbdb3e6 (patch) | |
tree | 0f4d4ef4170e963aa6784a222e192d16ba753e21 /mako | |
parent | 09cf4f68a7f7f63c2f249d61d7cc6600afe12c1a (diff) | |
download | mako-a1d70afb5974125a1a65f590418c7c371bbdb3e6.tar.gz |
Modernize codeworkflow_test_initial_1_2
- remove python 2 support
- add github workflows
- remove disable unicode
- cleanup compat file
- modernize setup
- use pep517
Change-Id: Ic38dbf478046cec5d0815b468f0c235b4ea5e20c
Diffstat (limited to 'mako')
-rw-r--r-- | mako/__init__.py | 2 | ||||
-rw-r--r-- | mako/_ast_util.py | 2 | ||||
-rw-r--r-- | mako/ast.py | 11 | ||||
-rw-r--r-- | mako/cache.py | 7 | ||||
-rw-r--r-- | mako/codegen.py | 27 | ||||
-rw-r--r-- | mako/compat.py | 109 | ||||
-rw-r--r-- | mako/exceptions.py | 21 | ||||
-rw-r--r-- | mako/ext/babelplugin.py | 2 | ||||
-rw-r--r-- | mako/ext/extract.py | 14 | ||||
-rw-r--r-- | mako/ext/linguaplugin.py | 23 | ||||
-rw-r--r-- | mako/ext/pygmentplugin.py | 7 | ||||
-rw-r--r-- | mako/ext/turbogears.py | 4 | ||||
-rw-r--r-- | mako/filters.py | 33 | ||||
-rw-r--r-- | mako/lexer.py | 14 | ||||
-rw-r--r-- | mako/lookup.py | 4 | ||||
-rw-r--r-- | mako/parsetree.py | 2 | ||||
-rw-r--r-- | mako/pygen.py | 2 | ||||
-rw-r--r-- | mako/pyparser.py | 51 | ||||
-rw-r--r-- | mako/runtime.py | 26 | ||||
-rw-r--r-- | mako/template.py | 61 | ||||
-rw-r--r-- | mako/util.py | 24 |
21 files changed, 133 insertions, 313 deletions
diff --git a/mako/__init__.py b/mako/__init__.py index df2ae48..d595275 100644 --- a/mako/__init__.py +++ b/mako/__init__.py @@ -5,4 +5,4 @@ # the MIT License: http://www.opensource.org/licenses/mit-license.php -__version__ = "1.1.6" +__version__ = "1.2.0" diff --git a/mako/_ast_util.py b/mako/_ast_util.py index bdcdbf6..21a60fc 100644 --- a/mako/_ast_util.py +++ b/mako/_ast_util.py @@ -104,7 +104,7 @@ def iter_fields(node): pass -class NodeVisitor(object): +class NodeVisitor: """ Walks the abstract syntax tree and call visitor functions for every node diff --git a/mako/ast.py b/mako/ast.py index cfae280..5e52e02 100644 --- a/mako/ast.py +++ b/mako/ast.py @@ -9,12 +9,11 @@ code, as well as generating Python from AST nodes""" import re -from mako import compat from mako import exceptions from mako import pyparser -class PythonCode(object): +class PythonCode: """represents information about a string containing Python code""" @@ -39,7 +38,7 @@ class PythonCode(object): # - AST is less likely to break with version changes # (for example, the behavior of co_names changed a little bit # in python version 2.5) - if isinstance(code, compat.string_types): + if isinstance(code, str): expr = pyparser.parse(code.lstrip(), "exec", **exception_kwargs) else: expr = code @@ -48,7 +47,7 @@ class PythonCode(object): f.visit(expr) -class ArgumentList(object): +class ArgumentList: """parses a fragment of code as a comma-separated list of expressions""" @@ -57,7 +56,7 @@ class ArgumentList(object): self.args = [] self.declared_identifiers = set() self.undeclared_identifiers = set() - if isinstance(code, compat.string_types): + if isinstance(code, str): if re.match(r"\S", code) and not re.match(r",\s*$", code): # if theres text and no trailing comma, insure its parsed # as a tuple by adding a trailing comma @@ -111,7 +110,7 @@ class PythonFragment(PythonCode): super(PythonFragment, self).__init__(code, **exception_kwargs) -class FunctionDecl(object): +class FunctionDecl: """function declaration""" diff --git a/mako/cache.py b/mako/cache.py index 26aa93e..c382aea 100644 --- a/mako/cache.py +++ b/mako/cache.py @@ -4,7 +4,6 @@ # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php -from mako import compat from mako import util _cache_plugins = util.PluginLoader("mako.cache") @@ -13,7 +12,7 @@ register_plugin = _cache_plugins.register register_plugin("beaker", "mako.ext.beaker_cache", "BeakerCacheImpl") -class Cache(object): +class Cache: """Represents a data content cache made available to the module space of a specific :class:`.Template` object. @@ -66,7 +65,7 @@ class Cache(object): def __init__(self, template, *args): # check for a stale template calling the # constructor - if isinstance(template, compat.string_types) and args: + if isinstance(template, str) and args: return self.template = template self.id = template.module.__name__ @@ -181,7 +180,7 @@ class Cache(object): return tmpl_kw -class CacheImpl(object): +class CacheImpl: """Provide a cache implementation for use by :class:`.Cache`.""" diff --git a/mako/codegen.py b/mako/codegen.py index a9ae55b..415d274 100644 --- a/mako/codegen.py +++ b/mako/codegen.py @@ -39,7 +39,6 @@ def compile( # noqa future_imports=None, source_encoding=None, generate_magic_comment=True, - disable_unicode=False, strict_undefined=False, enable_loop=True, reserved_names=frozenset(), @@ -47,13 +46,6 @@ def compile( # noqa """Generate module source code given a parsetree node, uri, and optional source filename""" - # if on Py2K, push the "source_encoding" string to be - # a bytestring itself, as we will be embedding it into - # the generated source and we don't want to coerce the - # result into a unicode object, in "disable_unicode" mode - if not compat.py3k and isinstance(source_encoding, compat.text_type): - source_encoding = source_encoding.encode(source_encoding) - buf = util.FastEncodingBuffer() printer = PythonPrinter(buf) @@ -68,7 +60,6 @@ def compile( # noqa future_imports, source_encoding, generate_magic_comment, - disable_unicode, strict_undefined, enable_loop, reserved_names, @@ -78,7 +69,7 @@ def compile( # noqa return buf.getvalue() -class _CompileContext(object): +class _CompileContext: def __init__( self, uri, @@ -89,7 +80,6 @@ class _CompileContext(object): future_imports, source_encoding, generate_magic_comment, - disable_unicode, strict_undefined, enable_loop, reserved_names, @@ -102,13 +92,12 @@ class _CompileContext(object): self.future_imports = future_imports self.source_encoding = source_encoding self.generate_magic_comment = generate_magic_comment - self.disable_unicode = disable_unicode self.strict_undefined = strict_undefined self.enable_loop = enable_loop self.reserved_names = reserved_names -class _GenerateRenderMethod(object): +class _GenerateRenderMethod: """A template visitor object which generates the full module source for a template. @@ -196,7 +185,7 @@ class _GenerateRenderMethod(object): self.compiler.pagetag = None - class FindTopLevel(object): + class FindTopLevel: def visitInheritTag(s, node): inherit.append(node) @@ -392,7 +381,7 @@ class _GenerateRenderMethod(object): identifiers = self.compiler.identifiers.branch(node) self.in_def = True - class NSDefVisitor(object): + class NSDefVisitor: def visitDefTag(s, node): s.visitDefOrBase(node) @@ -794,8 +783,6 @@ class _GenerateRenderMethod(object): def locate_encode(name): if re.match(r"decode\..+", name): return "filters." + name - elif self.compiler.disable_unicode: - return filters.NON_UNICODE_ESCAPES.get(name, name) else: return filters.DEFAULT_ESCAPES.get(name, name) @@ -969,7 +956,7 @@ class _GenerateRenderMethod(object): self.identifier_stack.append(body_identifiers) - class DefVisitor(object): + class DefVisitor: def visitDefTag(s, node): s.visitDefOrBase(node) @@ -1025,7 +1012,7 @@ class _GenerateRenderMethod(object): ) -class _Identifiers(object): +class _Identifiers: """tracks the status of identifier names as template code is rendered.""" @@ -1293,7 +1280,7 @@ def mangle_mako_loop(node, printer): return text -class LoopVariable(object): +class LoopVariable: """A node visitor which looks for the name 'loop' within undeclared identifiers.""" diff --git a/mako/compat.py b/mako/compat.py index 06bb8d9..4baa479 100644 --- a/mako/compat.py +++ b/mako/compat.py @@ -5,13 +5,10 @@ # the MIT License: http://www.opensource.org/licenses/mit-license.php import collections +from importlib import util import inspect import sys -py3k = sys.version_info >= (3, 0) -py2k = sys.version_info < (3,) -py27 = sys.version_info >= (2, 7) -jython = sys.platform.startswith("java") win32 = sys.platform.startswith("win") pypy = hasattr(sys, "pypy_version_info") @@ -34,7 +31,7 @@ def inspect_getargspec(func): nargs = co.co_argcount names = co.co_varnames - nkwargs = co.co_kwonlyargcount if py3k else 0 + nkwargs = co.co_kwonlyargcount args = list(names[:nargs]) nargs += nkwargs @@ -49,99 +46,23 @@ def inspect_getargspec(func): return ArgSpec(args, varargs, varkw, func.__defaults__) -if py3k: - from io import StringIO - import builtins as compat_builtins - from urllib.parse import quote_plus, unquote_plus - from html.entities import codepoint2name, name2codepoint +def octal(lit): + return eval("0o" + lit) - string_types = (str,) - binary_type = bytes - text_type = str - from io import BytesIO as byte_buffer +def load_module(module_id, path): + spec = util.spec_from_file_location(module_id, path) + module = util.module_from_spec(spec) + spec.loader.exec_module(module) + return module - def u(s): - return s - def b(s): - return s.encode("latin-1") - - def octal(lit): - return eval("0o" + lit) - - -else: - import __builtin__ as compat_builtins # noqa - - try: - from cStringIO import StringIO - except: - from StringIO import StringIO - - byte_buffer = StringIO - - from urllib import quote_plus, unquote_plus # noqa - from htmlentitydefs import codepoint2name, name2codepoint # noqa - - string_types = (basestring,) # noqa - binary_type = str - text_type = unicode # noqa - - def u(s): - return unicode(s, "utf-8") # noqa - - def b(s): - return s - - def octal(lit): - return eval("0" + lit) - - -if py3k: - from importlib import machinery, util - - if hasattr(util, 'module_from_spec'): - # Python 3.5+ - def load_module(module_id, path): - spec = util.spec_from_file_location(module_id, path) - module = util.module_from_spec(spec) - spec.loader.exec_module(module) - return module - else: - def load_module(module_id, path): - module = machinery.SourceFileLoader(module_id, path).load_module() - del sys.modules[module_id] - return module - -else: - import imp - - def load_module(module_id, path): - fp = open(path, "rb") - try: - module = imp.load_source(module_id, path, fp) - del sys.modules[module_id] - return module - finally: - fp.close() - - -if py3k: - - def reraise(tp, value, tb=None, cause=None): - if cause is not None: - value.__cause__ = cause - if value.__traceback__ is not tb: - raise value.with_traceback(tb) - raise value - - -else: - exec( - "def reraise(tp, value, tb=None, cause=None):\n" - " raise tp, value, tb\n" - ) +def reraise(tp, value, tb=None, cause=None): + if cause is not None: + value.__cause__ = cause + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value def exception_as(): diff --git a/mako/exceptions.py b/mako/exceptions.py index ea7b20d..a5f9370 100644 --- a/mako/exceptions.py +++ b/mako/exceptions.py @@ -68,7 +68,7 @@ class TopLevelLookupException(TemplateLookupException): pass -class RichTraceback(object): +class RichTraceback: """Pull the current exception from the ``sys`` traceback and extracts Mako-specific template information. @@ -106,7 +106,7 @@ class RichTraceback(object): def _init_message(self): """Find a unicode representation of self.error""" try: - self.message = compat.text_type(self.error) + self.message = str(self.error) except UnicodeError: try: self.message = str(self.error) @@ -114,8 +114,8 @@ class RichTraceback(object): # Fallback to args as neither unicode nor # str(Exception(u'\xe6')) work in Python < 2.6 self.message = self.error.args[0] - if not isinstance(self.message, compat.text_type): - self.message = compat.text_type(self.message, "ascii", "replace") + if not isinstance(self.message, str): + self.message = str(self.message, "ascii", "replace") def _get_reformatted_records(self, records): for rec in records: @@ -170,17 +170,6 @@ class RichTraceback(object): ) except KeyError: # A normal .py file (not a Template) - if not compat.py3k: - try: - fp = open(filename, "rb") - encoding = util.parse_encoding(fp) - fp.close() - except IOError: - encoding = None - if encoding: - line = line.decode(encoding) - else: - line = line.decode("ascii", "replace") new_trcback.append( ( filename, @@ -238,7 +227,7 @@ class RichTraceback(object): # A normal .py file (not a Template) fp = open(new_trcback[-1][0], "rb") encoding = util.parse_encoding(fp) - if compat.py3k and not encoding: + if not encoding: encoding = "utf-8" fp.seek(0) self.source = fp.read() diff --git a/mako/ext/babelplugin.py b/mako/ext/babelplugin.py index 76bbc5b..d5c6b4b 100644 --- a/mako/ext/babelplugin.py +++ b/mako/ext/babelplugin.py @@ -15,7 +15,7 @@ class BabelMakoExtractor(MessageExtractor): self.keywords = keywords self.options = options self.config = { - "comment-tags": u" ".join(comment_tags), + "comment-tags": " ".join(comment_tags), "encoding": options.get( "input_encoding", options.get("encoding", None) ), diff --git a/mako/ext/extract.py b/mako/ext/extract.py index ad2348a..66e3c19 100644 --- a/mako/ext/extract.py +++ b/mako/ext/extract.py @@ -4,14 +4,17 @@ # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php +from io import BytesIO +from io import StringIO import re -from mako import compat from mako import lexer from mako import parsetree -class MessageExtractor(object): +class MessageExtractor: + use_bytes = True + def process_file(self, fileobj): template_node = lexer.Lexer( fileobj.read(), input_encoding=self.config["encoding"] @@ -90,7 +93,7 @@ class MessageExtractor(object): comment[1] for comment in translator_comments ] - if isinstance(code, compat.text_type): + if isinstance(code, str) and self.use_bytes: code = code.encode(input_encoding, "backslashreplace") used_translator_comments = False @@ -99,7 +102,10 @@ class MessageExtractor(object): # input string of the input is non-ascii) # Also, because we added it, we have to subtract one from # node.lineno - code = compat.byte_buffer(compat.b("\n") + code) + if self.use_bytes: + code = BytesIO(b"\n" + code) + else: + code = StringIO("\n" + code) for message in self.process_python( code, node.lineno - 1, translator_strings diff --git a/mako/ext/linguaplugin.py b/mako/ext/linguaplugin.py index c40fa74..438258e 100644 --- a/mako/ext/linguaplugin.py +++ b/mako/ext/linguaplugin.py @@ -10,14 +10,13 @@ from lingua.extractors import Extractor from lingua.extractors import get_extractor from lingua.extractors import Message -from mako import compat from mako.ext.extract import MessageExtractor class LinguaMakoExtractor(Extractor, MessageExtractor): - """Mako templates""" + use_bytes = False extensions = [".mako"] default_config = {"encoding": "utf-8", "comment-tags": ""} @@ -26,7 +25,7 @@ class LinguaMakoExtractor(Extractor, MessageExtractor): self.filename = filename self.python_extractor = get_extractor("x.py") if fileobj is None: - fileobj = open(filename, "rb") + fileobj = open(filename, "r") must_close = True else: must_close = False @@ -39,16 +38,16 @@ class LinguaMakoExtractor(Extractor, MessageExtractor): def process_python(self, code, code_lineno, translator_strings): source = code.getvalue().strip() - if source.endswith(compat.b(":")): + if source.endswith(":"): if source in ( - compat.b("try:"), - compat.b("else:"), - ) or source.startswith(compat.b("except")): - source = compat.b("") # Ignore try/except and else - elif source.startswith(compat.b("elif")): + "try:", + "else:", + ) or source.startswith("except"): + source = "" # Ignore try/except and else + elif source.startswith("elif"): source = source[2:] # Replace "elif" with "if" - source += compat.b("pass") - code = io.BytesIO(source) + source += "pass" + code = io.StringIO(source) for msg in self.python_extractor( self.filename, self.options, code, code_lineno - 1 ): @@ -58,7 +57,7 @@ class LinguaMakoExtractor(Extractor, MessageExtractor): msg.msgid, msg.msgid_plural, msg.flags, - compat.u(" ").join(translator_strings + [msg.comment]), + " ".join(translator_strings + [msg.comment]), msg.tcomment, msg.location, ) diff --git a/mako/ext/pygmentplugin.py b/mako/ext/pygmentplugin.py index 943a67a..dcfe5c4 100644 --- a/mako/ext/pygmentplugin.py +++ b/mako/ext/pygmentplugin.py @@ -25,8 +25,6 @@ from pygments.token import Other from pygments.token import String from pygments.token import Text -from mako import compat - class MakoLexer(RegexLexer): name = "Mako" @@ -144,10 +142,7 @@ pygments_html_formatter = HtmlFormatter( def syntax_highlight(filename="", language=None): mako_lexer = MakoLexer() - if compat.py3k: - python_lexer = Python3Lexer() - else: - python_lexer = PythonLexer() + python_lexer = Python3Lexer() if filename.startswith("memory:") or language == "mako": return lambda string: highlight( string, mako_lexer, pygments_html_formatter diff --git a/mako/ext/turbogears.py b/mako/ext/turbogears.py index 722a6b4..e37349e 100644 --- a/mako/ext/turbogears.py +++ b/mako/ext/turbogears.py @@ -9,7 +9,7 @@ from mako.lookup import TemplateLookup from mako.template import Template -class TGPlugin(object): +class TGPlugin: """TurboGears compatible Template Plugin.""" @@ -51,7 +51,7 @@ class TGPlugin(object): def render( self, info, format="html", fragment=False, template=None # noqa ): - if isinstance(template, compat.string_types): + if isinstance(template, str): template = self.load_template(template) # Load extra vars func if provided diff --git a/mako/filters.py b/mako/filters.py index 0ae33ff..d6323b9 100644 --- a/mako/filters.py +++ b/mako/filters.py @@ -6,13 +6,11 @@ import codecs +from html.entities import codepoint2name +from html.entities import name2codepoint import re - -from mako import compat -from mako.compat import codepoint2name -from mako.compat import name2codepoint -from mako.compat import quote_plus -from mako.compat import unquote_plus +from urllib.parse import quote_plus +from urllib.parse import unquote_plus xml_escapes = { "&": "&", @@ -70,15 +68,15 @@ def trim(string): return string.strip() -class Decode(object): +class Decode: def __getattr__(self, key): def decode(x): - if isinstance(x, compat.text_type): + if isinstance(x, str): return x - elif not isinstance(x, compat.binary_type): + elif not isinstance(x, bytes): return decode(str(x)) else: - return compat.text_type(x, encoding=key) + return str(x, encoding=key) return decode @@ -96,11 +94,11 @@ def is_ascii_str(text): ################################################################ -class XMLEntityEscaper(object): +class XMLEntityEscaper: def __init__(self, codepoint2name, name2codepoint): self.codepoint2entity = dict( [ - (c, compat.text_type("&%s;" % n)) + (c, str("&%s;" % n)) for c, n in codepoint2name.items() ] ) @@ -111,7 +109,7 @@ class XMLEntityEscaper(object): Only characters corresponding to a named entity are replaced. """ - return compat.text_type(text).translate(self.codepoint2entity) + return str(text).translate(self.codepoint2entity) def __escape(self, m): codepoint = ord(m.group()) @@ -132,7 +130,7 @@ class XMLEntityEscaper(object): The return value is guaranteed to be ASCII. """ return self.__escapable.sub( - self.__escape, compat.text_type(text) + self.__escape, str(text) ).encode("ascii") # XXX: This regexp will not match all valid XML entity names__. @@ -190,7 +188,7 @@ def htmlentityreplace_errors(ex): # Handle encoding errors bad_text = ex.object[ex.start : ex.end] text = _html_entities_escaper.escape(bad_text) - return (compat.text_type(text), ex.end) + return (str(text), ex.end) raise ex @@ -205,15 +203,12 @@ DEFAULT_ESCAPES = { "u": "filters.url_escape", "trim": "filters.trim", "entity": "filters.html_entities_escape", - "unicode": "unicode", + "unicode": "str", "decode": "decode", "str": "str", "n": "n", } -if compat.py3k: - DEFAULT_ESCAPES.update({"unicode": "str"}) - NON_UNICODE_ESCAPES = DEFAULT_ESCAPES.copy() NON_UNICODE_ESCAPES["h"] = "filters.legacy_html_escape" NON_UNICODE_ESCAPES["u"] = "filters.legacy_url_escape" diff --git a/mako/lexer.py b/mako/lexer.py index 6226e26..05aa2d9 100644 --- a/mako/lexer.py +++ b/mako/lexer.py @@ -9,7 +9,6 @@ import codecs import re -from mako import compat from mako import exceptions from mako import parsetree from mako.pygen import adjust_whitespace @@ -17,12 +16,11 @@ from mako.pygen import adjust_whitespace _regexp_cache = {} -class Lexer(object): +class Lexer: def __init__( self, text, filename=None, - disable_unicode=False, input_encoding=None, preprocessor=None, ): @@ -36,14 +34,8 @@ class Lexer(object): self.tag = [] self.control_line = [] self.ternary_stack = [] - self.disable_unicode = disable_unicode self.encoding = input_encoding - if compat.py3k and disable_unicode: - raise exceptions.UnsupportedError( - "Mako for Python 3 does not " "support disabling Unicode" - ) - if preprocessor is None: self.preprocessor = [] elif not hasattr(preprocessor, "__iter__"): @@ -199,7 +191,7 @@ class Lexer(object): or raw if decode_raw=False """ - if isinstance(text, compat.text_type): + 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 @@ -241,7 +233,7 @@ class Lexer(object): def parse(self): self.encoding, self.text = self.decode_raw_stream( - self.text, not self.disable_unicode, self.encoding, self.filename + self.text, True, self.encoding, self.filename ) for preproc in self.preprocessor: diff --git a/mako/lookup.py b/mako/lookup.py index 476326d..57d0de4 100644 --- a/mako/lookup.py +++ b/mako/lookup.py @@ -19,7 +19,7 @@ except: import dummy_threading as threading -class TemplateCollection(object): +class TemplateCollection: """Represent a collection of :class:`.Template` objects, identifiable via URI. @@ -161,7 +161,6 @@ class TemplateLookup(TemplateCollection): collection_size=-1, format_exceptions=False, error_handler=None, - disable_unicode=False, bytestring_passthrough=False, output_encoding=None, encoding_errors="strict", @@ -207,7 +206,6 @@ class TemplateLookup(TemplateCollection): "format_exceptions": format_exceptions, "error_handler": error_handler, "include_error_handler": include_error_handler, - "disable_unicode": disable_unicode, "bytestring_passthrough": bytestring_passthrough, "output_encoding": output_encoding, "cache_impl": cache_impl, diff --git a/mako/parsetree.py b/mako/parsetree.py index 801e48a..54aaa56 100644 --- a/mako/parsetree.py +++ b/mako/parsetree.py @@ -15,7 +15,7 @@ from mako import filters from mako import util -class Node(object): +class Node: """base class for a Node in the parse tree.""" diff --git a/mako/pygen.py b/mako/pygen.py index 947721f..bae285a 100644 --- a/mako/pygen.py +++ b/mako/pygen.py @@ -11,7 +11,7 @@ import re from mako import exceptions -class PythonPrinter(object): +class PythonPrinter: def __init__(self, stream): # indentation counter self.indent = 0 diff --git a/mako/pyparser.py b/mako/pyparser.py index b16672d..b441132 100644 --- a/mako/pyparser.py +++ b/mako/pyparser.py @@ -20,20 +20,12 @@ from mako import exceptions from mako import util from mako.compat import arg_stringname -if compat.py3k: - # words that cannot be assigned to (notably - # smaller than the total keys in __builtins__) - reserved = set(["True", "False", "None", "print"]) +# words that cannot be assigned to (notably +# smaller than the total keys in __builtins__) +reserved = set(["True", "False", "None", "print"]) - # the "id" attribute on a function node - arg_id = operator.attrgetter("arg") -else: - # words that cannot be assigned to (notably - # smaller than the total keys in __builtins__) - reserved = set(["True", "False", "None"]) - - # the "id" attribute on a function node - arg_id = operator.attrgetter("id") +# the "id" attribute on a function node +arg_id = operator.attrgetter("arg") util.restore__ast(_ast) @@ -85,18 +77,16 @@ class FindIdentifiers(_ast_util.NodeVisitor): self.visit(n) self.in_assign_targets = in_a - if compat.py3k: - - # ExceptHandler is in Python 2, but this block only works in - # Python 3 (and is required there) + # ExceptHandler is in Python 2, but this block only works in + # Python 3 (and is required there) - def visit_ExceptHandler(self, node): - if node.name is not None: - self._add_declared(node.name) - if node.type is not None: - self.visit(node.type) - for statement in node.body: - self.visit(statement) + def visit_ExceptHandler(self, node): + if node.name is not None: + self._add_declared(node.name) + if node.type is not None: + self.visit(node.type) + for statement in node.body: + self.visit(statement) def visit_Lambda(self, node, *args): self._visit_function(node, True) @@ -215,25 +205,18 @@ class ParseFunc(_ast_util.NodeVisitor): if node.args.vararg: argnames.append(arg_stringname(node.args.vararg)) - if compat.py2k: - # kw-only args don't exist in Python 2 - kwargnames = [] - else: - kwargnames = [arg_id(arg) for arg in node.args.kwonlyargs] + kwargnames = [arg_id(arg) for arg in node.args.kwonlyargs] if node.args.kwarg: kwargnames.append(arg_stringname(node.args.kwarg)) self.listener.argnames = argnames self.listener.defaults = node.args.defaults # ast self.listener.kwargnames = kwargnames - if compat.py2k: - self.listener.kwdefaults = [] - else: - self.listener.kwdefaults = node.args.kw_defaults + self.listener.kwdefaults = node.args.kw_defaults self.listener.varargs = node.args.vararg self.listener.kwargs = node.args.kwarg -class ExpressionGenerator(object): +class ExpressionGenerator: def __init__(self, astnode): self.generator = _ast_util.SourceGenerator(" " * 4) self.generator.visit(astnode) diff --git a/mako/runtime.py b/mako/runtime.py index 465908e..bf31d28 100644 --- a/mako/runtime.py +++ b/mako/runtime.py @@ -7,16 +7,17 @@ """provides runtime services for templates, including Context, Namespace, and various helper functions.""" +import builtins import functools +from io import StringIO import sys from mako import compat from mako import exceptions from mako import util -from mako.compat import compat_builtins -class Context(object): +class Context: """Provides runtime namespace, output buffer, and various callstacks for templates. @@ -103,7 +104,7 @@ class Context(object): if key in self._data: return self._data[key] else: - return compat_builtins.__dict__[key] + return builtins.__dict__[key] def _push_writer(self): """push a capturing buffer onto this Context and return @@ -135,7 +136,7 @@ class Context(object): def get(self, key, default=None): """Return a value from this :class:`.Context`.""" - return self._data.get(key, compat_builtins.__dict__.get(key, default)) + return self._data.get(key, builtins.__dict__.get(key, default)) def write(self, string): """Write a string to this :class:`.Context` object's @@ -216,7 +217,7 @@ class CallerStack(list): self.nextcaller = self.pop() -class Undefined(object): +class Undefined: """Represents an undefined value in a template. @@ -240,7 +241,7 @@ UNDEFINED = Undefined() STOP_RENDERING = "" -class LoopStack(object): +class LoopStack: """a stack for LoopContexts that implements the context manager protocol to automatically pop off the top of the stack on context exit @@ -280,7 +281,7 @@ class LoopStack(object): return iter(self._top) -class LoopContext(object): +class LoopContext: """A magic loop variable. Automatically accessible in any ``% for`` block. @@ -346,7 +347,7 @@ class LoopContext(object): return values[self.index % len(values)] -class _NSAttr(object): +class _NSAttr: def __init__(self, parent): self.__parent = parent @@ -360,7 +361,7 @@ class _NSAttr(object): raise AttributeError(key) -class Namespace(object): +class Namespace: """Provides access to collections of rendering methods, which can be local, from other templates, or from imported modules. @@ -862,12 +863,11 @@ def _render(template, callable_, args, data, as_unicode=False): output of the given template and template callable.""" if as_unicode: - buf = util.FastEncodingBuffer(as_unicode=True) + buf = util.FastEncodingBuffer() elif template.bytestring_passthrough: - buf = compat.StringIO() + buf = StringIO() else: buf = util.FastEncodingBuffer( - as_unicode=as_unicode, encoding=template.output_encoding, errors=template.encoding_errors, ) @@ -956,7 +956,7 @@ def _render_error(template, context, error): error_template = exceptions.html_error_template() if context._outputting_as_unicode: context._buffer_stack[:] = [ - util.FastEncodingBuffer(as_unicode=True) + util.FastEncodingBuffer() ] else: context._buffer_stack[:] = [ diff --git a/mako/template.py b/mako/template.py index 5ed2320..1f11e73 100644 --- a/mako/template.py +++ b/mako/template.py @@ -25,7 +25,7 @@ from mako import util from mako.lexer import Lexer -class Template(object): +class Template: r"""Represents a compiled template. @@ -55,11 +55,10 @@ class Template(object): :param bytestring_passthrough: When ``True``, and ``output_encoding`` is set to ``None``, and :meth:`.Template.render` is used to render, - the `StringIO` or `cStringIO` buffer will be used instead of the + the `StringIO` buffer will be used instead of the default "fast" buffer. This allows raw bytestrings in the output stream, such as in expressions, to pass straight - through to the buffer. This flag is forced - to ``True`` if ``disable_unicode`` is also configured. + through to the buffer. .. versionadded:: 0.4 Added to provide the same behavior as that of the previous series. @@ -94,9 +93,6 @@ class Template(object): :param default_filters: List of string filter names that will be applied to all expressions. See :ref:`filtering_default_filters`. - :param disable_unicode: Disables all awareness of Python Unicode - objects. See :ref:`unicode_disabled`. - :param enable_loop: When ``True``, enable the ``loop`` context variable. This can be set to ``False`` to support templates that may be making usage of the name "``loop``". Individual templates can @@ -255,7 +251,6 @@ class Template(object): cache_url=None, module_filename=None, input_encoding=None, - disable_unicode=False, module_writer=None, bytestring_passthrough=False, default_filters=None, @@ -294,26 +289,13 @@ class Template(object): self.input_encoding = input_encoding self.output_encoding = output_encoding self.encoding_errors = encoding_errors - self.disable_unicode = disable_unicode - self.bytestring_passthrough = bytestring_passthrough or disable_unicode + self.bytestring_passthrough = bytestring_passthrough self.enable_loop = enable_loop self.strict_undefined = strict_undefined self.module_writer = module_writer - if compat.py3k and disable_unicode: - raise exceptions.UnsupportedError( - "Mako for Python 3 does not " "support disabling Unicode" - ) - elif output_encoding and disable_unicode: - raise exceptions.UnsupportedError( - "output_encoding must be set to " - "None when disable_unicode is used." - ) if default_filters is None: - if compat.py3k or self.disable_unicode: - self.default_filters = ["str"] - else: - self.default_filters = ["unicode"] + self.default_filters = ["str"] else: self.default_filters = default_filters self.buffer_filters = buffer_filters @@ -463,7 +445,7 @@ class Template(object): If the template specifies an output encoding, the string will be encoded accordingly, else the output is raw (raw - output uses `cStringIO` and can't handle multibyte + output uses `StringIO` and can't handle multibyte characters). A :class:`.Context` object is created corresponding to the given data. Arguments that are explicitly declared by this template's internal rendering method are also @@ -541,7 +523,6 @@ class ModuleTemplate(Template): template_source=None, output_encoding=None, encoding_errors="strict", - disable_unicode=False, bytestring_passthrough=False, format_exceptions=False, error_handler=None, @@ -559,20 +540,9 @@ class ModuleTemplate(Template): self.input_encoding = module._source_encoding self.output_encoding = output_encoding self.encoding_errors = encoding_errors - self.disable_unicode = disable_unicode - self.bytestring_passthrough = bytestring_passthrough or disable_unicode + self.bytestring_passthrough = bytestring_passthrough self.enable_loop = module._enable_loop - if compat.py3k and disable_unicode: - raise exceptions.UnsupportedError( - "Mako for Python 3 does not " "support disabling Unicode" - ) - elif output_encoding and disable_unicode: - raise exceptions.UnsupportedError( - "output_encoding must be set to " - "None when disable_unicode is used." - ) - self.module = module self.filename = template_filename ModuleInfo( @@ -622,7 +592,7 @@ class DefTemplate(Template): return self.parent.get_def(name) -class ModuleInfo(object): +class ModuleInfo: """Stores information about a module currently loaded into memory, provides reverse lookups of template source, module @@ -683,7 +653,7 @@ class ModuleInfo(object): def source(self): if self.template_source is not None: if self.module._source_encoding and not isinstance( - self.template_source, compat.text_type + self.template_source, str ): return self.template_source.decode( self.module._source_encoding @@ -702,7 +672,6 @@ def _compile(template, text, filename, generate_magic_comment): lexer = template.lexer_cls( text, filename, - disable_unicode=template.disable_unicode, input_encoding=template.input_encoding, preprocessor=template.preprocessor, ) @@ -717,7 +686,6 @@ def _compile(template, text, filename, generate_magic_comment): future_imports=template.future_imports, source_encoding=lexer.encoding, generate_magic_comment=generate_magic_comment, - disable_unicode=template.disable_unicode, strict_undefined=template.strict_undefined, enable_loop=template.enable_loop, reserved_names=template.reserved_names, @@ -731,12 +699,10 @@ def _compile_text(template, text, filename): template, text, filename, - generate_magic_comment=template.disable_unicode, + generate_magic_comment=False, ) cid = identifier - if not compat.py3k and isinstance(cid, compat.text_type): - cid = cid.encode() module = types.ModuleType(cid) code = compile(source, cid, "exec") @@ -750,7 +716,7 @@ def _compile_module_file(template, text, filename, outputpath, module_writer): template, text, filename, generate_magic_comment=True ) - if isinstance(source, compat.text_type): + if isinstance(source, str): source = source.encode(lexer.encoding or "ascii") if module_writer: @@ -767,10 +733,7 @@ def _compile_module_file(template, text, filename, outputpath, module_writer): def _get_module_info_from_callable(callable_): - if compat.py3k: - return _get_module_info(callable_.__globals__["__name__"]) - else: - return _get_module_info(callable_.func_globals["__name__"]) + return _get_module_info(callable_.__globals__["__name__"]) def _get_module_info(filename): diff --git a/mako/util.py b/mako/util.py index 16e3c72..a34a8c1 100644 --- a/mako/util.py +++ b/mako/util.py @@ -3,8 +3,6 @@ # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php -from __future__ import absolute_import - from ast import parse import codecs import collections @@ -22,7 +20,7 @@ def update_wrapper(decorated, fn): return decorated -class PluginLoader(object): +class PluginLoader: def __init__(self, group): self.group = group self.impls = {} @@ -76,7 +74,7 @@ def to_list(x, default=None): return x -class memoized_property(object): +class memoized_property: """A read-only @property that is only evaluated once.""" @@ -92,7 +90,7 @@ class memoized_property(object): return result -class memoized_instancemethod(object): +class memoized_instancemethod: """Decorate a method memoize its return value. @@ -140,19 +138,15 @@ class SetLikeDict(dict): return x -class FastEncodingBuffer(object): +class FastEncodingBuffer: """a very rudimentary buffer that is faster than StringIO, - but doesn't crash on unicode data like cStringIO.""" + and supports unicode data.""" - def __init__(self, encoding=None, errors="strict", as_unicode=False): + def __init__(self, encoding=None, errors="strict"): self.data = collections.deque() self.encoding = encoding - if as_unicode: - self.delim = compat.u("") - else: - self.delim = "" - self.as_unicode = as_unicode + self.delim = "" self.errors = errors self.write = self.data.append @@ -179,7 +173,7 @@ class LRUCache(dict): is inexact. """ - class _Item(object): + class _Item: def __init__(self, key, value): self.key = key self.value = value @@ -308,7 +302,7 @@ def restore__ast(_ast): m = compile( """\ def foo(): pass -class Bar(object): pass +class Bar: pass if False: pass baz = 'mako' 1 + 2 - 3 * 4 / 5 |