From 1eb56ef02a7fa825be99ddfb95f217a07dab1cdf Mon Sep 17 00:00:00 2001 From: Mike Bayer <mike_mp@zzzcomputing.com> Date: Sun, 11 Nov 2012 14:38:56 -0500 Subject: [PATCH] - first pass at running a py3k compatible base in py2k as well. having some weird unicode issues I can't debug; the meaning of str.encode() seems to be changing globally somehow --- mako/_ast_util.py | 2 +- mako/ast.py | 6 +- mako/cache.py | 2 +- mako/codegen.py | 32 +- mako/exceptions.py | 16 +- mako/ext/babelplugin.py | 11 +- mako/ext/beaker_cache.py | 2 +- mako/ext/pygmentplugin.py | 4 +- mako/ext/turbogears.py | 4 +- mako/filters.py | 69 +-- mako/lexer.py | 11 +- mako/parsetree.py | 22 +- mako/pygen.py | 3 +- mako/pyparser.py | 16 +- mako/runtime.py | 56 ++- mako/template.py | 29 +- mako/util.py | 107 +---- test/__init__.py | 11 +- test/templates/foo/modtest.html.py | 2 +- test/templates/subdir/foo/modtest.html.py | 2 +- test/test_ast.py | 4 +- test/test_babelplugin.py | 40 +- test/test_block.py | 14 +- test/test_cache.py | 2 +- test/test_call.py | 63 ++- test/test_decorators.py | 2 +- test/test_def.py | 8 +- test/test_exceptions.py | 63 ++- test/test_filters.py | 6 +- test/test_inheritance.py | 37 +- test/test_lexer.py | 542 +++++++++++----------- test/test_lookup.py | 4 +- test/test_loop.py | 10 +- test/test_lru.py | 61 +-- test/test_namespace.py | 2 +- test/test_pygen.py | 24 +- test/test_template.py | 188 ++++---- test/test_tgplugin.py | 2 +- test/test_util.py | 6 +- 39 files changed, 718 insertions(+), 767 deletions(-) diff --git a/mako/_ast_util.py b/mako/_ast_util.py index a1bd54c..af29506 100644 --- a/mako/_ast_util.py +++ b/mako/_ast_util.py @@ -693,7 +693,7 @@ class SourceGenerator(NodeVisitor): def visit_Dict(self, node): self.write('{') - for idx, (key, value) in enumerate(zip(node.keys, node.values)): + for idx, (key, value) in enumerate(list(zip(node.keys, node.values))): if idx: self.write(', ') self.visit(key) diff --git a/mako/ast.py b/mako/ast.py index 76311e9..0298a11 100644 --- a/mako/ast.py +++ b/mako/ast.py @@ -7,7 +7,7 @@ """utilities for analyzing expressions and blocks of Python code, as well as generating Python from AST nodes""" -from mako import exceptions, pyparser, util +from mako import exceptions, pyparser, compat import re class PythonCode(object): @@ -33,7 +33,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, basestring): + if isinstance(code, compat.string_types): expr = pyparser.parse(code.lstrip(), "exec", **exception_kwargs) else: expr = code @@ -48,7 +48,7 @@ class ArgumentList(object): self.args = [] self.declared_identifiers = set() self.undeclared_identifiers = set() - if isinstance(code, basestring): + if isinstance(code, compat.string_types): 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 diff --git a/mako/cache.py b/mako/cache.py index f50ce58..c60f0e8 100644 --- a/mako/cache.py +++ b/mako/cache.py @@ -64,7 +64,7 @@ class Cache(object): def __init__(self, template, *args): # check for a stale template calling the # constructor - if isinstance(template, basestring) and args: + if isinstance(template, str) and args: return self.template = template self.id = template.module.__name__ diff --git a/mako/codegen.py b/mako/codegen.py index 25265fa..f876db8 100644 --- a/mako/codegen.py +++ b/mako/codegen.py @@ -11,6 +11,8 @@ import time import re from mako.pygen import PythonPrinter from mako import util, ast, parsetree, filters, exceptions +from mako import compat + MAGIC_NUMBER = 8 @@ -40,7 +42,7 @@ def compile(node, # 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 util.py3k and isinstance(source_encoding, unicode): + if not compat.py3k and isinstance(source_encoding, compat.text_type): source_encoding = source_encoding.encode(source_encoding) @@ -230,7 +232,7 @@ class _GenerateRenderMethod(object): self.compiler.identifiers = module_identifiers self.printer.writeline("_exports = %r" % [n.name for n in - main_identifiers.topleveldefs.values()] + list(main_identifiers.topleveldefs.values())] ) self.printer.write("\n\n") @@ -243,7 +245,7 @@ class _GenerateRenderMethod(object): elif len(namespaces): self.write_namespaces(namespaces) - return main_identifiers.topleveldefs.values() + return list(main_identifiers.topleveldefs.values()) def write_render_callable(self, node, name, args, buffered, filtered, cached): @@ -327,8 +329,8 @@ class _GenerateRenderMethod(object): self.printer.writeline("def _mako_generate_namespaces(context):") - for node in namespaces.values(): - if node.attributes.has_key('import'): + for node in list(namespaces.values()): + if 'import' in node.attributes: self.compiler.has_ns_imports = True self.write_source_comment(node) if len(node.nodes): @@ -436,7 +438,7 @@ class _GenerateRenderMethod(object): # write closure functions for closures that we define # right here to_write = to_write.union( - [c.funcname for c in identifiers.closuredefs.values()]) + [c.funcname for c in list(identifiers.closuredefs.values())]) # remove identifiers that are declared in the argument # signature of the callable @@ -463,8 +465,8 @@ class _GenerateRenderMethod(object): if toplevel and getattr(self.compiler, 'has_ns_imports', False): self.printer.writeline("_import_ns = {}") self.compiler.has_imports = True - for ident, ns in self.compiler.namespaces.iteritems(): - if ns.attributes.has_key('import'): + for ident, ns in self.compiler.namespaces.items(): + if 'import' in ns.attributes: self.printer.writeline( "_mako_get_namespace(context, %r)."\ "_populate(_import_ns, %r)" % @@ -699,7 +701,7 @@ class _GenerateRenderMethod(object): "%s, lambda:__M_%s(%s), context, %s__M_defname=%r)" % \ (cachekey, name, ','.join(pass_args), ''.join(["%s=%s, " % (k,v) - for k, v in cache_args.items()]), + for k, v in list(cache_args.items())]), name ) # apply buffer_filters @@ -713,7 +715,7 @@ class _GenerateRenderMethod(object): "%s, lambda:__M_%s(%s), context, %s__M_defname=%r))" % (cachekey, name, ','.join(pass_args), ''.join(["%s=%s, " % (k,v) - for k, v in cache_args.items()]), + for k, v in list(cache_args.items())]), name, ), "return ''", @@ -791,10 +793,10 @@ class _GenerateRenderMethod(object): # and end control lines, and # 3) any control line with no content other than comments if not children or ( - util.all(isinstance(c, (parsetree.Comment, + compat.all(isinstance(c, (parsetree.Comment, parsetree.ControlLine)) for c in children) and - util.all((node.is_ternary(c.keyword) or c.isend) + compat.all((node.is_ternary(c.keyword) or c.isend) for c in children if isinstance(c, parsetree.ControlLine))): self.printer.writeline("pass") @@ -966,7 +968,7 @@ class _Identifiers(object): # things that have already been declared # in an enclosing namespace (i.e. names we can just use) self.declared = set(parent.declared).\ - union([c.name for c in parent.closuredefs.values()]).\ + union([c.name for c in list(parent.closuredefs.values())]).\ union(parent.locally_declared).\ union(parent.argument_declared) @@ -1037,8 +1039,8 @@ class _Identifiers(object): list(self.declared), list(self.locally_declared), list(self.undeclared), - [c.name for c in self.topleveldefs.values()], - [c.name for c in self.closuredefs.values()], + [c.name for c in list(self.topleveldefs.values())], + [c.name for c in list(self.closuredefs.values())], self.argument_declared) def check_declared(self, node): diff --git a/mako/exceptions.py b/mako/exceptions.py index b8d5ef3..fb9b3e6 100644 --- a/mako/exceptions.py +++ b/mako/exceptions.py @@ -6,8 +6,10 @@ """exception classes""" -import traceback, sys, re -from mako import util +import traceback +import sys +import re +from mako import util, compat class MakoException(Exception): pass @@ -84,12 +86,12 @@ class RichTraceback(object): @property def errorname(self): - return util.exception_name(self.error) + return compat.exception_name(self.error) def _init_message(self): """Find a unicode representation of self.error""" try: - self.message = unicode(self.error) + self.message = compat.text_type(self.error) except UnicodeError: try: self.message = str(self.error) @@ -97,8 +99,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, unicode): - self.message = unicode(self.message, 'ascii', 'replace') + if not isinstance(self.message, compat.text_type): + self.message = compat.text_type(self.message, 'ascii', 'replace') def _get_reformatted_records(self, records): for rec in records: @@ -150,7 +152,7 @@ class RichTraceback(object): template_filename = info.template_filename or filename except KeyError: # A normal .py file (not a Template) - if not util.py3k: + if not compat.py3k: try: fp = open(filename, 'rb') encoding = util.parse_encoding(fp) diff --git a/mako/ext/babelplugin.py b/mako/ext/babelplugin.py index 085938d..b620631 100644 --- a/mako/ext/babelplugin.py +++ b/mako/ext/babelplugin.py @@ -5,11 +5,10 @@ # the MIT License: http://www.opensource.org/licenses/mit-license.php """gettext message extraction via Babel: http://babel.edgewall.org/""" -from StringIO import StringIO - from babel.messages.extract import extract_python - -from mako import lexer, parsetree, util +from mako.compat import StringIO +from mako import compat +from mako import lexer, parsetree def extract(fileobj, keywords, comment_tags, options): """Extract messages from Mako templates. @@ -78,7 +77,7 @@ def extract_nodes(nodes, keywords, comment_tags, options): code = node.body_decl.code elif isinstance(node, parsetree.CallNamespaceTag): attribs = ', '.join(['%s=%s' % (key, val) - for key, val in node.attributes.iteritems()]) + for key, val in node.attributes.items()]) code = '{%s}' % attribs child_nodes = node.nodes elif isinstance(node, parsetree.ControlLine): @@ -108,7 +107,7 @@ def extract_nodes(nodes, keywords, comment_tags, options): translator_comments = \ [comment[1] for comment in translator_comments] - if not util.py3k and isinstance(code, unicode): + if not compat.py3k and isinstance(code, str): code = code.encode('ascii', 'backslashreplace') code = StringIO(code) for lineno, funcname, messages, python_translator_comments \ diff --git a/mako/ext/beaker_cache.py b/mako/ext/beaker_cache.py index f0b50fa..ed1a31c 100644 --- a/mako/ext/beaker_cache.py +++ b/mako/ext/beaker_cache.py @@ -19,7 +19,7 @@ class BeakerCacheImpl(CacheImpl): if _beaker_cache is None: try: from beaker import cache as beaker_cache - except ImportError, e: + except ImportError as e: raise exceptions.RuntimeException( "the Beaker package is required to use cache " "functionality.") diff --git a/mako/ext/pygmentplugin.py b/mako/ext/pygmentplugin.py index 773f47a..6fd683a 100644 --- a/mako/ext/pygmentplugin.py +++ b/mako/ext/pygmentplugin.py @@ -13,7 +13,7 @@ from pygments.token import \ Text, Comment, Operator, Keyword, Name, String, Other from pygments.formatters.html import HtmlFormatter from pygments import highlight -from mako import util +from mako import compat class MakoLexer(RegexLexer): name = 'Mako' @@ -110,7 +110,7 @@ pygments_html_formatter = HtmlFormatter(cssclass='syntax-highlighted', linenos=True) def syntax_highlight(filename='', language=None): mako_lexer = MakoLexer() - if util.py3k: + if compat.py3k: python_lexer = Python3Lexer() else: python_lexer = PythonLexer() diff --git a/mako/ext/turbogears.py b/mako/ext/turbogears.py index e453ada..74fcd8a 100644 --- a/mako/ext/turbogears.py +++ b/mako/ext/turbogears.py @@ -19,7 +19,7 @@ class TGPlugin(object): # Pull the options out and initialize the lookup lookup_options = {} - for k, v in options.iteritems(): + for k, v in options.items(): if k.startswith('mako.'): lookup_options[k[5:]] = v elif k in ['directories', 'filesystem_checks', 'module_directory']: @@ -46,7 +46,7 @@ class TGPlugin(object): return self.lookup.get_template(templatename) def render(self, info, format="html", fragment=False, template=None): - if isinstance(template, basestring): + 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 b4f2684..bf2f136 100644 --- a/mako/filters.py +++ b/mako/filters.py @@ -5,16 +5,20 @@ # the MIT License: http://www.opensource.org/licenses/mit-license.php -import re, urllib, htmlentitydefs, codecs -from StringIO import StringIO -from mako import util +import re +import codecs + +from mako.compat import quote_plus, unquote_plus, codepoint2name, \ + name2codepoint + +from mako import compat xml_escapes = { - '&' : '&', - '>' : '>', - '<' : '<', - '"' : '"', # also " in html-only - "'" : ''' # also ' in html-only + '&': '&', + '>': '>', + '<': '<', + '"': '"', # also " in html-only + "'": ''' # also ' in html-only } # XXX: " is valid in HTML and XML @@ -40,10 +44,10 @@ def xml_escape(string): def url_escape(string): # convert into a list of octets string = string.encode("utf8") - return urllib.quote_plus(string) + return quote_plus(string) def url_unescape(string): - text = urllib.unquote_plus(string) + text = unquote_plus(string) if not is_ascii_str(text): text = text.decode("utf8") return text @@ -55,12 +59,12 @@ def trim(string): class Decode(object): def __getattr__(self, key): def decode(x): - if isinstance(x, unicode): + if isinstance(x, compat.text_type): return x - elif not isinstance(x, str): - return unicode(str(x), encoding=key) + elif not isinstance(x, compat.binary_type): + return compat.text_type(str(x), encoding=key) else: - return unicode(x, encoding=key) + return compat.text_type(x, encoding=key) return decode decode = Decode() @@ -74,8 +78,8 @@ def is_ascii_str(text): class XMLEntityEscaper(object): def __init__(self, codepoint2name, name2codepoint): - self.codepoint2entity = dict([(c, u'&%s;' % n) - for c,n in codepoint2name.iteritems()]) + self.codepoint2entity = dict([(c, '&%s;' % n) + for c, n in codepoint2name.items()]) self.name2codepoint = name2codepoint def escape_entities(self, text): @@ -83,7 +87,7 @@ class XMLEntityEscaper(object): Only characters corresponding to a named entity are replaced. """ - return unicode(text).translate(self.codepoint2entity) + return str(text).translate(self.codepoint2entity) def __escape(self, m): codepoint = ord(m.group()) @@ -104,7 +108,7 @@ class XMLEntityEscaper(object): The return value is guaranteed to be ASCII. """ - return self.__escapable.sub(self.__escape, unicode(text) + return self.__escapable.sub(self.__escape, compat.text_type(text) ).encode('ascii') # XXX: This regexp will not match all valid XML entity names__. @@ -129,7 +133,7 @@ class XMLEntityEscaper(object): # U+FFFD = "REPLACEMENT CHARACTER" if codepoint < 128: return chr(codepoint) - return unichr(codepoint) + return chr(codepoint) def unescape(self, text): """Unescape character references. @@ -140,8 +144,7 @@ class XMLEntityEscaper(object): return self.__characterrefs.sub(self.__unescape, text) -_html_entities_escaper = XMLEntityEscaper(htmlentitydefs.codepoint2name, - htmlentitydefs.name2codepoint) +_html_entities_escaper = XMLEntityEscaper(codepoint2name, name2codepoint) html_entities_escape = _html_entities_escaper.escape_entities html_entities_unescape = _html_entities_escaper.unescape @@ -161,7 +164,7 @@ def htmlentityreplace_errors(ex): # Handle encoding errors bad_text = ex.object[ex.start:ex.end] text = _html_entities_escaper.escape(bad_text) - return (unicode(text), ex.end) + return (str(text), ex.end) raise ex codecs.register_error('htmlentityreplace', htmlentityreplace_errors) @@ -170,20 +173,20 @@ codecs.register_error('htmlentityreplace', htmlentityreplace_errors) # TODO: options to make this dynamic per-compilation will be added in a later # release DEFAULT_ESCAPES = { - 'x':'filters.xml_escape', - 'h':'filters.html_escape', - 'u':'filters.url_escape', - 'trim':'filters.trim', - 'entity':'filters.html_entities_escape', - 'unicode':'unicode', - 'decode':'decode', - 'str':'str', - 'n':'n' + 'x': 'filters.xml_escape', + 'h': 'filters.html_escape', + 'u': 'filters.url_escape', + 'trim': 'filters.trim', + 'entity': 'filters.html_entities_escape', + 'unicode': 'unicode', + 'decode': 'decode', + 'str': 'str', + 'n': 'n' } -if util.py3k: +if compat.py3k: DEFAULT_ESCAPES.update({ - 'unicode':'str' + 'unicode': 'str' }) NON_UNICODE_ESCAPES = DEFAULT_ESCAPES.copy() diff --git a/mako/lexer.py b/mako/lexer.py index 267c0d1..26d1596 100644 --- a/mako/lexer.py +++ b/mako/lexer.py @@ -6,8 +6,9 @@ """provides the Lexer class for parsing template strings into parse trees.""" -import re, codecs -from mako import parsetree, exceptions, util +import re +import codecs +from mako import parsetree, exceptions, compat from mako.pygen import adjust_whitespace _regexp_cache = {} @@ -29,7 +30,7 @@ class Lexer(object): self.disable_unicode = disable_unicode self.encoding = input_encoding - if util.py3k and disable_unicode: + if compat.py3k and disable_unicode: raise exceptions.UnsupportedError( "Mako for Python 3 does not " "support disabling Unicode") @@ -173,7 +174,7 @@ class Lexer(object): or raw if decode_raw=False """ - if isinstance(text, unicode): + if isinstance(text, compat.text_type): m = self._coding_re.match(text) encoding = m and m.group(1) or known_encoding or 'ascii' return encoding, text @@ -198,7 +199,7 @@ class Lexer(object): if decode_raw: try: text = text.decode(parsed_encoding) - except UnicodeDecodeError, e: + except UnicodeDecodeError: raise exceptions.CompileException( "Unicode decode operation of encoding '%s' failed" % parsed_encoding, diff --git a/mako/parsetree.py b/mako/parsetree.py index b5247f1..3db8c6b 100644 --- a/mako/parsetree.py +++ b/mako/parsetree.py @@ -6,7 +6,7 @@ """defines the parse tree components for Mako templates.""" -from mako import exceptions, ast, util, filters +from mako import exceptions, ast, util, filters, compat import re class Node(object): @@ -20,8 +20,8 @@ class Node(object): @property def exception_kwargs(self): - return {'source':self.source, 'lineno':self.lineno, - 'pos':self.pos, 'filename':self.filename} + return {'source': self.source, 'lineno': self.lineno, + 'pos': self.pos, 'filename': self.filename} def get_children(self): return [] @@ -204,9 +204,9 @@ class _TagMeta(type): _classmap = {} def __init__(cls, clsname, bases, dict): - if cls.__keyword__ is not None: + if getattr(cls, '__keyword__', None) is not None: cls._classmap[cls.__keyword__] = cls - super(_TagMeta, cls).__init__(clsname, bases, dict) + super(_TagMeta, cls).__init__(clsname, bases, dict) def __call__(cls, keyword, attributes, **kwargs): if ":" in keyword: @@ -226,7 +226,7 @@ class _TagMeta(type): ) return type.__call__(cls, keyword, attributes, **kwargs) -class Tag(Node): +class Tag(compat.with_metaclass(_TagMeta, Node)): """abstract base class for tags. <%sometag/> @@ -236,8 +236,6 @@ class Tag(Node): </%someothertag> """ - - __metaclass__ = _TagMeta __keyword__ = None def __init__(self, keyword, attributes, expressions, @@ -396,7 +394,7 @@ class TextTag(Tag): def undeclared_identifiers(self): return self.filter_args.\ undeclared_identifiers.\ - difference(filters.DEFAULT_ESCAPES.keys()).union( + difference(list(filters.DEFAULT_ESCAPES.keys())).union( self.expression_undeclared_identifiers ) @@ -449,7 +447,7 @@ class DefTag(Tag): return set(res).union( self.filter_args.\ undeclared_identifiers.\ - difference(filters.DEFAULT_ESCAPES.keys()) + difference(list(filters.DEFAULT_ESCAPES.keys())) ).union( self.expression_undeclared_identifiers ).difference( @@ -509,7 +507,7 @@ class BlockTag(Tag): def undeclared_identifiers(self): return (self.filter_args.\ undeclared_identifiers.\ - difference(filters.DEFAULT_ESCAPES.keys()) + difference(list(filters.DEFAULT_ESCAPES.keys())) ).union(self.expression_undeclared_identifiers) @@ -547,7 +545,7 @@ class CallNamespaceTag(Tag): namespace, defname, ",".join(["%s=%s" % (k, v) for k, v in - self.parsed_attributes.iteritems() + self.parsed_attributes.items() if k != 'args']) ) self.code = ast.PythonCode(self.expression, **self.exception_kwargs) diff --git a/mako/pygen.py b/mako/pygen.py index e946de5..e46edff 100644 --- a/mako/pygen.py +++ b/mako/pygen.py @@ -6,8 +6,7 @@ """utilities for generating and formatting literal Python code.""" -import re, string -from StringIO import StringIO +import re from mako import exceptions class PythonPrinter(object): diff --git a/mako/pyparser.py b/mako/pyparser.py index 984c0d2..7dde1f9 100644 --- a/mako/pyparser.py +++ b/mako/pyparser.py @@ -10,11 +10,11 @@ Parsing to AST is done via _ast on Python > 2.5, otherwise the compiler module is used. """ -from StringIO import StringIO -from mako import exceptions, util +from mako import exceptions, util, compat +from mako.compat import StringIO import operator -if util.py3k: +if compat.py3k: # words that cannot be assigned to (notably # smaller than the total keys in __builtins__) reserved = set(['True', 'False', 'None', 'print']) @@ -33,7 +33,7 @@ else: try: import _ast util.restore__ast(_ast) - import _ast_util + from . import _ast_util except ImportError: _ast = None from compiler import parse as compiler_parse @@ -48,10 +48,10 @@ def parse(code, mode='exec', **exception_kwargs): if _ast: return _ast_util.parse(code, '<unknown>', mode) else: - if isinstance(code, unicode): + if isinstance(code, compat.text_types): code = code.encode('ascii', 'backslashreplace') return compiler_parse(code, mode) - except Exception, e: + except Exception as e: raise exceptions.SyntaxException( "(%s) %s (%r)" % ( e.__class__.__name__, @@ -92,7 +92,7 @@ if _ast: self.visit(n) self.in_assign_targets = in_a - if util.py3k: + if compat.py3k: # ExceptHandler is in Python 2, but this block only works in # Python 3 (and is required there) @@ -544,7 +544,7 @@ else: class walker(visitor.ASTVisitor): def dispatch(self, node, *args): - print 'Node:', str(node) + print('Node:', str(node)) # print "dir:", dir(node) diff --git a/mako/runtime.py b/mako/runtime.py index f890c80..51e04d6 100644 --- a/mako/runtime.py +++ b/mako/runtime.py @@ -7,8 +7,11 @@ """provides runtime services for templates, including Context, Namespace, and various helper functions.""" -from mako import exceptions, util -import __builtin__, inspect, sys +from mako import exceptions, util, compat +from mako.compat import compat_builtins +import inspect +import sys +import collections class Context(object): @@ -32,7 +35,7 @@ class Context(object): # "capture" function which proxies to the # generic "capture" function - self._data['capture'] = util.partial(capture, self) + self._data['capture'] = compat.partial(capture, self) # "caller" stack used by def calls with content self.caller_stack = self._data['caller'] = CallerStack() @@ -77,13 +80,13 @@ class Context(object): def keys(self): """Return a list of all names established in this :class:`.Context`.""" - return self._data.keys() + return list(self._data.keys()) def __getitem__(self, key): if key in self._data: return self._data[key] else: - return __builtin__.__dict__[key] + return compat_builtins.__dict__[key] def _push_writer(self): """push a capturing buffer onto this Context and return @@ -116,7 +119,7 @@ class Context(object): """Return a value from this :class:`.Context`.""" return self._data.get(key, - __builtin__.__dict__.get(key, default) + compat_builtins.__dict__.get(key, default) ) def write(self, string): @@ -165,8 +168,13 @@ class Context(object): class CallerStack(list): def __init__(self): self.nextcaller = None + def __nonzero__(self): + return self.__bool__() + + def __bool__(self): return self._get_caller() and True or False + def _get_caller(self): # this method can be removed once # codegen MAGIC_NUMBER moves past 7 @@ -192,7 +200,11 @@ class Undefined(object): """ def __str__(self): raise NameError("Undefined") + def __nonzero__(self): + return self.__bool__() + + def __bool__(self): return False UNDEFINED = Undefined() @@ -336,7 +348,7 @@ class Namespace(object): self.context = context self.inherits = inherits if callables is not None: - self.callables = dict([(c.func_name, c) for c in callables]) + self.callables = dict([(c.__name__, c) for c in callables]) callables = () @@ -502,7 +514,7 @@ class TemplateNamespace(Namespace): self.context = context self.inherits = inherits if callables is not None: - self.callables = dict([(c.func_name, c) for c in callables]) + self.callables = dict([(c.__name__, c) for c in callables]) if templateuri is not None: self.template = _lookup_template(context, templateuri, @@ -554,7 +566,7 @@ class TemplateNamespace(Namespace): yield (key, self.callables[key]) def get(key): callable_ = self.template._get_def_callable(key) - return util.partial(callable_, self.context) + return compat.partial(callable_, self.context) for k in self.template.module._exports: yield (k, get(k)) @@ -563,7 +575,7 @@ class TemplateNamespace(Namespace): val = self.callables[key] elif self.template.has_def(key): callable_ = self.template._get_def_callable(key) - val = util.partial(callable_, self.context) + val = compat.partial(callable_, self.context) elif self.inherits: val = getattr(self.inherits, key) @@ -584,7 +596,7 @@ class ModuleNamespace(Namespace): self.context = context self.inherits = inherits if callables is not None: - self.callables = dict([(c.func_name, c) for c in callables]) + self.callables = dict([(c.__name__, c) for c in callables]) mod = __import__(module) for token in module.split('.')[1:]: @@ -604,7 +616,7 @@ class ModuleNamespace(Namespace): yield (key, self.callables[key]) def get(key): callable_ = getattr(self.module, key) - return util.partial(callable_, self.context) + return compat.partial(callable_, self.context) for k in dir(self.module): if k[0] != '_': yield (k, get(k)) @@ -614,7 +626,7 @@ class ModuleNamespace(Namespace): val = self.callables[key] elif hasattr(self.module, key): callable_ = getattr(self.module, key) - val = util.partial(callable_, self.context) + val = compat.partial(callable_, self.context) elif self.inherits: val = getattr(self.inherits, key) else: @@ -648,7 +660,7 @@ def capture(context, callable_, *args, **kwargs): """ - if not callable(callable_): + if not isinstance(callable_, collections.Callable): raise exceptions.RuntimeException( "capture() function expects a callable as " "its argument (i.e. capture(func, *args, **kwargs))" @@ -730,7 +742,7 @@ def _lookup_template(context, uri, relativeto): uri = lookup.adjust_uri(uri, relativeto) try: return lookup.get_template(uri) - except exceptions.TopLevelLookupException, e: + except exceptions.TopLevelLookupException as e: raise exceptions.TemplateLookupException(str(e)) def _populate_self_namespace(context, template, self_ns=None): @@ -750,12 +762,12 @@ def _render(template, callable_, args, data, as_unicode=False): output of the given template and template callable.""" if as_unicode: - buf = util.FastEncodingBuffer(unicode=True) + buf = util.FastEncodingBuffer(as_unicode=True) elif template.bytestring_passthrough: - buf = util.StringIO() + buf = compat.StringIO() else: buf = util.FastEncodingBuffer( - unicode=as_unicode, + as_unicode=as_unicode, encoding=template.output_encoding, errors=template.encoding_errors) context = Context(buf, **data) @@ -767,7 +779,7 @@ def _render(template, callable_, args, data, as_unicode=False): return context._pop_buffer().getvalue() def _kwargs_for_callable(callable_, data): - argspec = util.inspect_func_args(callable_) + argspec = compat.inspect_func_args(callable_) # for normal pages, **pageargs is usually present if argspec[2]: return data @@ -781,7 +793,7 @@ def _kwargs_for_callable(callable_, data): return kwargs def _kwargs_for_include(callable_, data, **kwargs): - argspec = util.inspect_func_args(callable_) + argspec = compat.inspect_func_args(callable_) namedargs = argspec[0] + [v for v in argspec[1:3] if v is not None] for arg in namedargs: if arg != 'context' and arg in data and arg not in kwargs: @@ -815,7 +827,7 @@ def _exec_template(callable_, context, args=None, kwargs=None): error = None try: callable_(context, *args, **kwargs) - except Exception, e: + except Exception as e: _render_error(template, context, e) except: e = sys.exc_info()[0] @@ -831,7 +843,7 @@ def _render_error(template, context, error): else: error_template = exceptions.html_error_template() if context._outputting_as_unicode: - context._buffer_stack[:] = [util.FastEncodingBuffer(unicode=True)] + context._buffer_stack[:] = [util.FastEncodingBuffer(as_unicode=True)] else: context._buffer_stack[:] = [util.FastEncodingBuffer( error_template.output_encoding, diff --git a/mako/template.py b/mako/template.py index 84d1ebb..d32e465 100644 --- a/mako/template.py +++ b/mako/template.py @@ -8,8 +8,15 @@ template strings, as well as template runtime operations.""" from mako.lexer import Lexer -from mako import runtime, util, exceptions, codegen, cache -import os, re, shutil, stat, sys, tempfile, types, weakref +from mako import runtime, util, exceptions, codegen, cache, compat +import os +import re +import shutil +import stat +import sys +import tempfile +import types +import weakref class Template(object): @@ -258,7 +265,7 @@ class Template(object): self.strict_undefined = strict_undefined self.module_writer = module_writer - if util.py3k and disable_unicode: + if compat.py3k and disable_unicode: raise exceptions.UnsupportedError( "Mako for Python 3 does not " "support disabling Unicode") @@ -267,7 +274,7 @@ class Template(object): "output_encoding must be set to " "None when disable_unicode is used.") if default_filters is None: - if util.py3k or self.disable_unicode: + if compat.py3k or self.disable_unicode: self.default_filters = ['str'] else: self.default_filters = ['unicode'] @@ -317,7 +324,7 @@ class Template(object): cache_impl, cache_enabled, cache_args, cache_type, cache_dir, cache_url ) - + @util.memoized_property def reserved_names(self): @@ -507,7 +514,7 @@ class ModuleTemplate(Template): self.bytestring_passthrough = bytestring_passthrough or disable_unicode self.enable_loop = module._enable_loop - if util.py3k and disable_unicode: + if compat.py3k and disable_unicode: raise exceptions.UnsupportedError( "Mako for Python 3 does not " "support disabling Unicode") @@ -588,7 +595,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, unicode): + not isinstance(self.template_source, compat.text_type): return self.template_source.decode( self.module._source_encoding) else: @@ -628,11 +635,11 @@ def _compile_text(template, text, filename): generate_magic_comment=template.disable_unicode) cid = identifier - if not util.py3k and isinstance(cid, unicode): + if not compat.py3k and isinstance(cid, compat.text_type): cid = cid.encode() module = types.ModuleType(cid) code = compile(source, cid, 'exec') - exec code in module.__dict__, module.__dict__ + exec(code, module.__dict__, module.__dict__) return (source, module) def _compile_module_file(template, text, filename, outputpath, module_writer): @@ -640,7 +647,7 @@ def _compile_module_file(template, text, filename, outputpath, module_writer): source, lexer = _compile(template, text, filename, generate_magic_comment=True) - if isinstance(source, unicode): + if isinstance(source, compat.text_type): source = source.encode(lexer.encoding or 'ascii') if module_writer: @@ -656,7 +663,7 @@ def _compile_module_file(template, text, filename, outputpath, module_writer): shutil.move(name, outputpath) def _get_module_info_from_callable(callable_): - return _get_module_info(callable_.func_globals['__name__']) + return _get_module_info(callable_.__globals__['__name__']) def _get_module_info(filename): return ModuleInfo._modules[filename] diff --git a/mako/util.py b/mako/util.py index 4b88ae5..b71c380 100644 --- a/mako/util.py +++ b/mako/util.py @@ -5,38 +5,12 @@ # the MIT License: http://www.opensource.org/licenses/mit-license.php import imp -import sys - - -py3k = getattr(sys, 'py3kwarning', False) or sys.version_info >= (3, 0) -py26 = sys.version_info >= (2, 6) -py25 = sys.version_info >= (2, 5) -jython = sys.platform.startswith('java') -win32 = sys.platform.startswith('win') -pypy = hasattr(sys, 'pypy_version_info') - -if py3k: - from io import StringIO -else: - try: - from cStringIO import StringIO - except: - from StringIO import StringIO - -import codecs, re, weakref, os, time, operator +import re import collections - -try: - import threading - import thread -except ImportError: - import dummy_threading as threading - import dummy_thread as thread - -if win32 or jython: - time_func = time.clock -else: - time_func = time.time +import codecs +import os +from mako import compat +import operator def function_named(fn, name): """Return a function with a given __name__. @@ -48,34 +22,6 @@ def function_named(fn, name): fn.__name__ = name return fn -try: - from functools import partial -except: - def partial(func, *args, **keywords): - def newfunc(*fargs, **fkeywords): - newkeywords = keywords.copy() - newkeywords.update(fkeywords) - return func(*(args + fargs), **newkeywords) - return newfunc - -if not py25: - def all(iterable): - for i in iterable: - if not i: - return False - return True - - def exception_name(exc): - try: - return exc.__class__.__name__ - except AttributeError: - return exc.__name__ -else: - all = all - - def exception_name(exc): - return exc.__class__.__name__ - class PluginLoader(object): def __init__(self, group): @@ -114,7 +60,7 @@ def verify_directory(dir): while not os.path.exists(dir): try: tries += 1 - os.makedirs(dir, 0775) + os.makedirs(dir, 0o775) except: if tries > 5: raise @@ -182,14 +128,14 @@ class FastEncodingBuffer(object): """a very rudimentary buffer that is faster than StringIO, but doesn't crash on unicode data like cStringIO.""" - def __init__(self, encoding=None, errors='strict', unicode=False): + def __init__(self, encoding=None, errors='strict', as_unicode=False): self.data = collections.deque() self.encoding = encoding - if unicode: - self.delim = u'' + if as_unicode: + self.delim = compat.u('') else: self.delim = '' - self.unicode = unicode + self.as_unicode = as_unicode self.errors = errors self.write = self.data.append @@ -217,7 +163,7 @@ class LRUCache(dict): def __init__(self, key, value): self.key = key self.value = value - self.timestamp = time_func() + self.timestamp = compat.time_func() def __repr__(self): return repr(self.value) @@ -227,7 +173,7 @@ class LRUCache(dict): def __getitem__(self, key): item = dict.__getitem__(self, key) - item.timestamp = time_func() + item.timestamp = compat.time_func() return item.value def values(self): @@ -302,9 +248,8 @@ def parse_encoding(fp): if has_bom: if m: - raise SyntaxError, \ - "python refuses to compile code with both a UTF8" \ - " byte-order-mark and a magic encoding comment" + raise SyntaxError("python refuses to compile code with both a UTF8" \ + " byte-order-mark and a magic encoding comment") return 'utf_8' elif m: return m.group(1) @@ -319,7 +264,7 @@ def sorted_dict_repr(d): Used by the lexer unit test to compare parse trees based on strings. """ - keys = d.keys() + keys = list(d.keys()) keys.sort() return "{" + ", ".join(["%r: %r" % (k, d[k]) for k in keys]) + "}" @@ -399,28 +344,6 @@ mako in baz not in mako""", '<unknown>', 'exec', _ast.PyCF_ONLY_AST) _ast.NotIn = type(m.body[12].value.ops[1]) -try: - from inspect import CO_VARKEYWORDS, CO_VARARGS - def inspect_func_args(fn): - co = fn.func_code - - nargs = co.co_argcount - names = co.co_varnames - args = list(names[:nargs]) - - varargs = None - if co.co_flags & CO_VARARGS: - varargs = co.co_varnames[nargs] - nargs = nargs + 1 - varkw = None - if co.co_flags & CO_VARKEYWORDS: - varkw = co.co_varnames[nargs] - - return args, varargs, varkw, fn.func_defaults -except ImportError: - import inspect - def inspect_func_args(fn): - return inspect.getargspec(fn) def read_file(path, mode='rb'): fp = open(path, mode) diff --git a/test/__init__.py b/test/__init__.py index ded1a5d..c983c5d 100644 --- a/test/__init__.py +++ b/test/__init__.py @@ -1,6 +1,7 @@ from mako.template import Template -import unittest, os -from mako.util import py3k, py26, py25 +import unittest +import os +from mako.compat import py3k, py26, py25 from mako.util import function_named import re from mako.cache import CacheImpl, register_plugin @@ -64,7 +65,7 @@ def assert_raises(except_cls, callable_, *args, **kw): try: callable_(*args, **kw) success = False - except except_cls, e: + except except_cls as e: success = True # assert outside the block so it works for AssertionError too ! @@ -74,9 +75,9 @@ def assert_raises_message(except_cls, msg, callable_, *args, **kwargs): try: callable_(*args, **kwargs) assert False, "Callable did not raise an exception" - except except_cls, e: + except except_cls as e: assert re.search(msg, str(e)), "%r !~ %s" % (msg, e) - print str(e) + print(str(e)) def skip_if(predicate, reason=None): """Skip a test if predicate is true.""" diff --git a/test/templates/foo/modtest.html.py b/test/templates/foo/modtest.html.py index c5fb76a..e6fc8d8 100644 --- a/test/templates/foo/modtest.html.py +++ b/test/templates/foo/modtest.html.py @@ -17,7 +17,7 @@ def render_body(context,**pageargs): __M_locals = __M_dict_builtin(pageargs=pageargs) __M_writer = context.writer() # SOURCE LINE 1 - __M_writer(u'this is a test') + __M_writer('this is a test') return '' finally: context.caller_stack._pop_frame() diff --git a/test/templates/subdir/foo/modtest.html.py b/test/templates/subdir/foo/modtest.html.py index ca6f37b..b0f50c7 100644 --- a/test/templates/subdir/foo/modtest.html.py +++ b/test/templates/subdir/foo/modtest.html.py @@ -17,7 +17,7 @@ def render_body(context,**pageargs): __M_locals = __M_dict_builtin(pageargs=pageargs) __M_writer = context.writer() # SOURCE LINE 1 - __M_writer(u'this is a test') + __M_writer('this is a test') return '' finally: context.caller_stack._pop_frame() diff --git a/test/test_ast.py b/test/test_ast.py index 8e02811..84508c7 100644 --- a/test/test_ast.py +++ b/test/test_ast.py @@ -1,6 +1,6 @@ import unittest -from mako import ast, exceptions, pyparser, util +from mako import ast, exceptions, pyparser, util, compat from test import eq_, requires_python_2 exception_kwargs = { @@ -237,7 +237,7 @@ import x as bar parsed = ast.PythonFragment("try:", **exception_kwargs) - if util.py3k: + if compat.py3k: parsed = ast.PythonFragment( "except MyException as e:", **exception_kwargs) else: diff --git a/test/test_babelplugin.py b/test/test_babelplugin.py index 8769da0..55be33f 100644 --- a/test/test_babelplugin.py +++ b/test/test_babelplugin.py @@ -19,26 +19,26 @@ class ExtractMakoTestCase(TemplateTest): 'ungettext': (1, 2)}, ['TRANSLATOR:'], {})) expected = \ - [(1, '_', u'Page arg 1', []), - (1, '_', u'Page arg 2', []), - (10, 'gettext', u'Begin', []), - (14, '_', u'Hi there!', [u'TRANSLATOR: Hi there!']), - (19, '_', u'Hello', []), - (22, '_', u'Welcome', []), - (25, '_', u'Yo', []), - (36, '_', u'The', [u'TRANSLATOR: Ensure so and', u'so, thanks']), - (36, 'ungettext', (u'bunny', u'bunnies', None), []), - (41, '_', u'Goodbye', [u'TRANSLATOR: Good bye']), - (44, '_', u'Babel', []), - (45, 'ungettext', (u'hella', u'hellas', None), []), - (62, '_', u'The', [u'TRANSLATOR: Ensure so and', u'so, thanks']), - (62, 'ungettext', (u'bunny', u'bunnies', None), []), - (68, '_', u'Goodbye, really!', [u'TRANSLATOR: HTML comment']), - (71, '_', u'P.S. byebye', []), - (77, '_', u'Top', []), - (83, '_', u'foo', []), - (83, '_', u'baz', []), - (85, '_', u'bar', []) + [(1, '_', 'Page arg 1', []), + (1, '_', 'Page arg 2', []), + (10, 'gettext', 'Begin', []), + (14, '_', 'Hi there!', ['TRANSLATOR: Hi there!']), + (19, '_', 'Hello', []), + (22, '_', 'Welcome', []), + (25, '_', 'Yo', []), + (36, '_', 'The', ['TRANSLATOR: Ensure so and', 'so, thanks']), + (36, 'ungettext', ('bunny', 'bunnies', None), []), + (41, '_', 'Goodbye', ['TRANSLATOR: Good bye']), + (44, '_', 'Babel', []), + (45, 'ungettext', ('hella', 'hellas', None), []), + (62, '_', 'The', ['TRANSLATOR: Ensure so and', 'so, thanks']), + (62, 'ungettext', ('bunny', 'bunnies', None), []), + (68, '_', 'Goodbye, really!', ['TRANSLATOR: HTML comment']), + (71, '_', 'P.S. byebye', []), + (77, '_', 'Top', []), + (83, '_', 'foo', []), + (83, '_', 'baz', []), + (85, '_', 'bar', []) ] self.assertEqual(expected, messages) diff --git a/test/test_block.py b/test/test_block.py index e70b79c..0f5cf17 100644 --- a/test/test_block.py +++ b/test/test_block.py @@ -2,7 +2,7 @@ from mako.template import Template from mako.lookup import TemplateLookup from mako import exceptions from test import TemplateTest, assert_raises, assert_raises_message -from util import flatten_result, result_lines +from .util import flatten_result, result_lines @@ -361,7 +361,7 @@ class BlockTest(TemplateTest): <html> </%block> """) - self._do_test(template, [u'<html>'], + self._do_test(template, ['<html>'], filters=result_lines) def test_anon_in_named(self): @@ -506,7 +506,7 @@ class BlockTest(TemplateTest): """) self._do_test( l.get_template("caller"), - [u'foob, 3, 4'], + ['foob, 3, 4'], filters=result_lines ) @@ -518,7 +518,7 @@ class BlockTest(TemplateTest): """) self._do_test( t, - [u'foob, 3, 4'], + ['foob, 3, 4'], template_args={'val1':3, 'val2':4}, filters=result_lines ) @@ -532,7 +532,7 @@ class BlockTest(TemplateTest): """) self._do_test( t, - [u'foob, 3, 4'], + ['foob, 3, 4'], template_args={'val1':3, 'val2':4}, filters=result_lines ) @@ -545,7 +545,7 @@ class BlockTest(TemplateTest): """) self._do_test( t, - [u'foob, 3, 4'], + ['foob, 3, 4'], template_args={'val1':3, 'val2':4}, filters=result_lines ) @@ -564,6 +564,6 @@ class BlockTest(TemplateTest): """) self._do_test( l.get_template("caller"), - [u'foob, 3, 4'], + ['foob, 3, 4'], filters=result_lines ) \ No newline at end of file diff --git a/test/test_cache.py b/test/test_cache.py index bd8cf47..40539fb 100644 --- a/test/test_cache.py +++ b/test/test_cache.py @@ -2,7 +2,7 @@ from mako.template import Template from mako.lookup import TemplateLookup from mako import lookup import shutil, unittest, os, time -from util import result_lines +from .util import result_lines from test import TemplateTest, template_base, module_base from test import eq_ diff --git a/test/test_call.py b/test/test_call.py index 0bb6079..e735a72 100644 --- a/test/test_call.py +++ b/test/test_call.py @@ -1,6 +1,6 @@ from mako.template import Template from mako import util -from util import result_lines, flatten_result +from .util import result_lines, flatten_result from test import TemplateTest, eq_ class CallTest(TemplateTest): @@ -9,7 +9,7 @@ class CallTest(TemplateTest): <%def name="foo()"> hi im foo ${caller.body(y=5)} </%def> - + <%call expr="foo()" args="y, **kwargs"> this is the body, y is ${y} </%call> @@ -23,16 +23,16 @@ class CallTest(TemplateTest): <%def name="bar()"> this is bar </%def> - + <%def name="comp1()"> this comp1 should not be called </%def> - + <%def name="foo()"> foo calling comp1: ${caller.comp1(x=5)} foo calling body: ${caller.body()} </%def> - + <%call expr="foo()"> <%def name="comp1(x)"> this is comp1, ${x} @@ -46,10 +46,10 @@ class CallTest(TemplateTest): def test_new_syntax(self): """test foo:bar syntax, including multiline args and expression eval.""" - + # note the trailing whitespace in the bottom ${} expr, need to strip # that off < python 2.7 - + t = Template(""" <%def name="foo(x, y, q, z)"> ${x} @@ -57,26 +57,26 @@ class CallTest(TemplateTest): ${q} ${",".join("%s->%s" % (a, b) for a, b in z)} </%def> - + <%self:foo x="this is x" y="${'some ' + 'y'}" q=" this is q" - + z="${[ (1, 2), (3, 4), (5, 6) ] - + }"/> """) - + eq_( result_lines(t.render()), ['this is x', 'some y', 'this', 'is', 'q', '1->2,3->4,5->6'] ) - + def test_ccall_caller(self): t = Template(""" <%def name="outer_func()"> @@ -104,7 +104,7 @@ class CallTest(TemplateTest): "INNER END", "OUTER END", ] - + def test_stack_pop(self): t = Template(""" <%def name="links()" buffered="True"> @@ -130,7 +130,7 @@ class CallTest(TemplateTest): "</h1>", "Some links" ] - + def test_conditional_call(self): """test that 'caller' is non-None only if the immediate <%def> was called via <%call>""" @@ -169,12 +169,12 @@ class CallTest(TemplateTest): "BBB", "CCC" ] - + def test_chained_call(self): """test %calls that are chained through their targets""" t = Template(""" <%def name="a()"> - this is a. + this is a. <%call expr="b()"> this is a's ccall. heres my body: ${caller.body()} </%call> @@ -184,11 +184,11 @@ class CallTest(TemplateTest): whats in the body's caller's body ? ${context.caller_stack[-2].body()} </%def> - + <%call expr="a()"> heres the main templ call </%call> - + """) assert result_lines(t.render()) == [ 'this is a.', @@ -225,7 +225,7 @@ class CallTest(TemplateTest): "bar:", "this is bar body: 10" ] - + def test_nested_call_2(self): t = Template(""" x is ${x} @@ -240,13 +240,13 @@ class CallTest(TemplateTest): <%call expr="foo()"> <%def name="foosub(x)"> this is foo body: ${x} - + <%call expr="bar()"> <%def name="barsub()"> this is bar body: ${x} </%def> </%call> - + </%def> </%call> @@ -278,7 +278,7 @@ class CallTest(TemplateTest): ''') assert flatten_result(template.render()) == "foo" - + def test_nested_call_4(self): base = """ <%def name="A()"> @@ -340,7 +340,7 @@ class CallTest(TemplateTest): t = Template(""" <%def name="embedded()"> <%def name="a()"> - this is a. + this is a. <%call expr="b()"> this is a's ccall. heres my body: ${caller.body()} </%call> @@ -366,7 +366,7 @@ class CallTest(TemplateTest): "whats in the body's caller's body ?", 'heres the main templ call' ] - + def test_call_in_nested(self): t = Template(""" <%def name="a()"> @@ -407,7 +407,7 @@ class CallTest(TemplateTest): context.write("a is done") return '' %> - + <%def name="b()"> this is b our body: ${caller.body()} @@ -430,8 +430,7 @@ class CallTest(TemplateTest): </%call> - """) - #print t.code + """) assert result_lines(t.render()) == [ "test 1", "this is a", @@ -452,7 +451,7 @@ class CallTest(TemplateTest): "this is aa is done", "this is aa is done" ] - + def test_call_in_nested_2(self): t = Template(""" <%def name="a()"> @@ -483,14 +482,14 @@ class CallTest(TemplateTest): class SelfCacheTest(TemplateTest): """this test uses a now non-public API.""" - + def test_basic(self): t = Template(""" <%! cached = None %> <%def name="foo()"> - <% + <% global cached if cached: return "cached: " + cached @@ -503,7 +502,7 @@ class SelfCacheTest(TemplateTest): return cached %> </%def> - + ${foo()} ${foo()} """) @@ -512,4 +511,4 @@ class SelfCacheTest(TemplateTest): "cached:", "this is foo" ] - + diff --git a/test/test_decorators.py b/test/test_decorators.py index fc8768b..74e674c 100644 --- a/test/test_decorators.py +++ b/test/test_decorators.py @@ -1,7 +1,7 @@ from mako.template import Template from mako import lookup import unittest -from util import flatten_result, result_lines +from .util import flatten_result, result_lines class DecoratorTest(unittest.TestCase): def test_toplevel(self): diff --git a/test/test_def.py b/test/test_def.py index 5c7608f..73c1091 100644 --- a/test/test_def.py +++ b/test/test_def.py @@ -1,7 +1,7 @@ from mako.template import Template from mako import lookup from test import TemplateTest -from util import flatten_result, result_lines +from .util import flatten_result, result_lines from test import eq_, assert_raises class DefTest(TemplateTest): @@ -63,8 +63,8 @@ class DefTest(TemplateTest): </%def> """) # check that "a" is declared in "b", but not in "c" - assert "a" not in template.module.render_c.func_code.co_varnames - assert "a" in template.module.render_b.func_code.co_varnames + assert "a" not in template.module.render_c.__code__.co_varnames + assert "a" in template.module.render_b.__code__.co_varnames # then test output eq_( @@ -390,7 +390,7 @@ class ScopeTest(TemplateTest): ${enclosing()} """) try: - print t.render() + print(t.render()) assert False except UnboundLocalError: assert True diff --git a/test/test_exceptions.py b/test/test_exceptions.py index 5503a1f..d7feb9a 100644 --- a/test/test_exceptions.py +++ b/test/test_exceptions.py @@ -1,12 +1,12 @@ # -*- coding: utf-8 -*- import sys -import unittest -from mako import exceptions, util +from mako import exceptions, compat from mako.template import Template from mako.lookup import TemplateLookup -from util import result_lines -from test import template_base, module_base, TemplateTest +from mako.compat import u +from test.util import result_lines +from test import TemplateTest from test import requires_pygments_14, requires_no_pygments, \ requires_python_25_or_greater @@ -21,7 +21,7 @@ class ExceptionsTest(TemplateTest): template = Template(code) template.render_unicode() assert False - except exceptions.CompileException, ce: + except exceptions.CompileException as ce: html_error = exceptions.html_error_template().render_unicode() assert ("CompileException: Fragment 'i = 0' is not " "a partial control statement at line: 2 char: 1") in html_error @@ -50,7 +50,7 @@ class ExceptionsTest(TemplateTest): template = Template(code) template.render_unicode() assert False - except exceptions.CompileException, ce: + except exceptions.CompileException as ce: text_error = exceptions.text_error_template().render_unicode() assert 'Traceback (most recent call last):' in text_error assert ("CompileException: Fragment 'i = 0' is not a partial " @@ -61,7 +61,7 @@ class ExceptionsTest(TemplateTest): """test the html_error_template with a Template containing utf8 chars""" - if util.py3k: + if compat.py3k: code = """# -*- coding: utf-8 -*- % if 2 == 2: /an error ${'привет'} @@ -76,9 +76,9 @@ ${u'привет'} try: template = Template(code) template.render_unicode() - except exceptions.CompileException, ce: + except exceptions.CompileException as ce: html_error = exceptions.html_error_template().render() - if util.py3k: + if compat.py3k: assert ("CompileException: Fragment 'if 2 == 2: /an " "error' is not a partial control statement " "at line: 2 char: 1").encode(sys.getdefaultencoding(), 'htmlentityreplace') in \ @@ -89,11 +89,11 @@ ${u'привет'} "at line: 2 char: 1") in \ html_error - if util.py3k: - assert u"".encode(sys.getdefaultencoding(), + if compat.py3k: + assert "".encode(sys.getdefaultencoding(), 'htmlentityreplace') in html_error else: - assert u'<pre>3</pre></div></td><td class="code">'\ + assert '<pre>3</pre></div></td><td class="code">'\ '<div class="syntax-highlighted"><pre><span '\ 'class="cp">${</span><span class="s">u''\ 'привет'\ @@ -109,7 +109,7 @@ ${u'привет'} """test the html_error_template with a Template containing utf8 chars""" - if util.py3k: + if compat.py3k: code = """# -*- coding: utf-8 -*- % if 2 == 2: /an error ${'привет'} @@ -124,9 +124,9 @@ ${u'привет'} try: template = Template(code) template.render_unicode() - except exceptions.CompileException, ce: + except exceptions.CompileException as ce: html_error = exceptions.html_error_template().render() - if util.py3k: + if compat.py3k: assert ("CompileException: Fragment 'if 2 == 2: /an " "error' is not a partial control statement " "at line: 2 char: 1").encode(sys.getdefaultencoding(), 'htmlentityreplace') in \ @@ -137,11 +137,11 @@ ${u'привет'} "at line: 2 char: 1") in \ html_error - if util.py3k: - assert u"${'привет'}".encode(sys.getdefaultencoding(), + if compat.py3k: + assert "${'привет'}".encode(sys.getdefaultencoding(), 'htmlentityreplace') in html_error else: - assert u"${u'привет'}".encode(sys.getdefaultencoding(), + assert "${u'привет'}".encode(sys.getdefaultencoding(), 'htmlentityreplace') in html_error else: assert False, ("This function should trigger a CompileException, " @@ -149,9 +149,8 @@ ${u'привет'} def test_format_closures(self): try: - exec "def foo():"\ - " raise RuntimeError('test')"\ - in locals() + exec("def foo():"\ + " raise RuntimeError('test')", locals()) foo() except: html_error = exceptions.html_error_template().render() @@ -160,23 +159,23 @@ ${u'привет'} @requires_python_25_or_greater def test_py_utf8_html_error_template(self): try: - foo = u'日本' + foo = '日本' raise RuntimeError('test') except: html_error = exceptions.html_error_template().render() - if util.py3k: + if compat.py3k: assert 'RuntimeError: test' in html_error.decode('utf-8') - assert u"foo = '日本'" in html_error.decode('utf-8') + assert "foo = '日本'" in html_error.decode('utf-8') else: assert 'RuntimeError: test' in html_error assert "foo = u'日本'" in html_error def test_py_unicode_error_html_error_template(self): try: - raise RuntimeError(u'日本') + raise RuntimeError(u('日本')) except: html_error = exceptions.html_error_template().render() - assert u"RuntimeError: 日本".encode('ascii', 'ignore') in html_error + assert u("RuntimeError: 日本").encode('ascii', 'ignore') in html_error @requires_pygments_14 def test_format_exceptions_pygments(self): @@ -220,12 +219,12 @@ ${foobar} exceptions reported with format_exceptions=True""" l = TemplateLookup(format_exceptions=True) - if util.py3k: + if compat.py3k: l.put_string("foo.html", """# -*- coding: utf-8 -*-\n${'привет' + foobar}""") else: l.put_string("foo.html", """# -*- coding: utf-8 -*-\n${u'привет' + foobar}""") - if util.py3k: + if compat.py3k: assert '<table class="error syntax-highlightedtable"><tr><td '\ 'class="linenos"><div class="linenodiv"><pre>2</pre>'\ '</div></td><td class="code"><div class="error '\ @@ -251,13 +250,13 @@ ${foobar} exceptions reported with format_exceptions=True""" l = TemplateLookup(format_exceptions=True) - if util.py3k: + if compat.py3k: l.put_string("foo.html", """# -*- coding: utf-8 -*-\n${'привет' + foobar}""") else: l.put_string("foo.html", """# -*- coding: utf-8 -*-\n${u'привет' + foobar}""") - if util.py3k: - assert u'<div class="sourceline">${'привет' + foobar}</div>'\ + if compat.py3k: + assert '<div class="sourceline">${'привет' + foobar}</div>'\ in result_lines(l.get_template("foo.html").render().decode('utf-8')) else: assert '${u'приве'\ @@ -290,7 +289,7 @@ ${foobar} except: t, v, tback = sys.exc_info() - if not util.py3k: + if not compat.py3k: # blow away tracebaack info sys.exc_clear() diff --git a/test/test_filters.py b/test/test_filters.py index 658715f..d2a6d6f 100644 --- a/test/test_filters.py +++ b/test/test_filters.py @@ -3,7 +3,7 @@ from mako.template import Template import unittest from test import TemplateTest, eq_, requires_python_2 -from util import result_lines, flatten_result +from .util import result_lines, flatten_result class FilterTest(TemplateTest): def test_basic(self): @@ -87,7 +87,7 @@ class FilterTest(TemplateTest): some stuff.... ${x} """, default_filters=['decode.utf8']) #print t.code - assert t.render_unicode(x="voix m’a réveillé").strip() == u"some stuff.... voix m’a réveillé" + assert t.render_unicode(x="voix m’a réveillé").strip() == "some stuff.... voix m’a réveillé" def test_custom_default(self): t = Template(""" @@ -311,7 +311,7 @@ class BufferTest(unittest.TestCase): """) try: - print template.render() + print(template.render()) assert False except TypeError: assert True diff --git a/test/test_inheritance.py b/test/test_inheritance.py index a953847..08a46b3 100644 --- a/test/test_inheritance.py +++ b/test/test_inheritance.py @@ -1,7 +1,6 @@ -from mako.template import Template -from mako import lookup, util +from mako import lookup, compat import unittest -from util import flatten_result, result_lines +from test.util import result_lines class InheritanceTest(unittest.TestCase): def test_basic(self): @@ -52,7 +51,7 @@ main_body ${parent.d()} full stack from the top: ${self.name} ${parent.name} ${parent.context['parent'].name} ${parent.context['parent'].context['parent'].name} """) - + collection.put_string('layout', """ <%inherit file="general"/> <%def name="d()">layout_d</%def> @@ -94,11 +93,11 @@ ${next.body()} 'full stack from the top:', 'self:main self:layout self:general self:base' ] - + def test_includes(self): """test that an included template also has its full hierarchy invoked.""" collection = lookup.TemplateLookup() - + collection.put_string("base", """ <%def name="a()">base_a</%def> This is the base. @@ -120,7 +119,7 @@ ${next.body()} """) assert result_lines(collection.get_template("index").render()) == [ - 'This is the base.', + 'This is the base.', 'this is index.', 'a is: base_a', 'This is the base.', @@ -134,7 +133,7 @@ ${next.body()} """test that templates used via <%namespace> have access to an inheriting 'self', and that the full 'self' is also exported.""" collection = lookup.TemplateLookup() - + collection.put_string("base", """ <%def name="a()">base_a</%def> <%def name="b()">base_b</%def> @@ -194,7 +193,7 @@ ${next.body()} <%def name="foo()"> ${next.body(**context.kwargs)} </%def> - + ${foo()} """) collection.put_string("index", """ @@ -202,8 +201,8 @@ ${next.body()} <%page args="x, y, z=7"/> print ${x}, ${y}, ${z} """) - - if util.py3k: + + if compat.py3k: assert result_lines(collection.get_template('index').render_unicode(x=5,y=10)) == [ "this is the base.", "pageargs: (type: <class 'dict'>) [('x', 5), ('y', 10)]", @@ -215,14 +214,14 @@ ${next.body()} "pageargs: (type: <type 'dict'>) [('x', 5), ('y', 10)]", "print 5, 10, 7" ] - + def test_pageargs_2(self): collection = lookup.TemplateLookup() collection.put_string("base", """ this is the base. - + ${next.body(**context.kwargs)} - + <%def name="foo(**kwargs)"> ${next.body(**kwargs)} </%def> @@ -245,7 +244,7 @@ ${next.body()} "pageargs: 12, 15, 8", "pageargs: 5, 10, 16" ] - + def test_pageargs_err(self): collection = lookup.TemplateLookup() collection.put_string("base", """ @@ -258,11 +257,11 @@ ${next.body()} print ${x}, ${y}, ${z} """) try: - print collection.get_template('index').render(x=5,y=10) + print(collection.get_template('index').render(x=5,y=10)) assert False except TypeError: assert True - + def test_toplevel(self): collection = lookup.TemplateLookup() collection.put_string("base", """ @@ -305,7 +304,7 @@ ${next.body()} 'this is the base.', 'this is index.' ] - + def test_in_call(self): collection = lookup.TemplateLookup() collection.put_string("/layout.html",""" @@ -332,7 +331,7 @@ ${next.body()} </%def> <%inherit file="/layout.html"/> """) - + collection.put_string("/subdir/renderedtemplate.html",""" Holy smokes! <%inherit file="/subdir/layout.html"/> diff --git a/test/test_lexer.py b/test/test_lexer.py index 61204ff..f6be383 100644 --- a/test/test_lexer.py +++ b/test/test_lexer.py @@ -1,11 +1,9 @@ -import unittest - from mako.lexer import Lexer -from mako import exceptions, util -from util import flatten_result, result_lines +from mako import exceptions, util, compat +from test.util import flatten_result from mako.template import Template import re -from test import TemplateTest, template_base, skip_if, eq_, assert_raises_message +from test import TemplateTest, eq_, assert_raises_message # create fake parsetree classes which are constructed # exactly as the repr() of a real parsetree object. @@ -18,21 +16,31 @@ def repr_arg(x): else: return repr(x) +def _as_unicode(arg): + if isinstance(arg, compat.string_types): + return compat.text_type(arg) + elif isinstance(arg, dict): + return dict( + (_as_unicode(k), _as_unicode(v)) + for k, v in arg.items() + ) + else: + return arg from mako import parsetree -for cls in parsetree.__dict__.values(): +for cls in list(parsetree.__dict__.values()): if isinstance(cls, type) and \ issubclass(cls, parsetree.Node): clsname = cls.__name__ - exec (""" + exec((""" class %s(object): def __init__(self, *args): - self.args = args + self.args = [_as_unicode(arg) for arg in args] def __repr__(self): return "%%s(%%s)" %% ( self.__class__.__name__, ", ".join(repr_arg(x) for x in self.args) ) -""" % clsname) in locals() +""" % clsname), locals()) # NOTE: most assertion expressions were generated, then formatted # by PyTidy, hence the dense formatting. @@ -48,28 +56,28 @@ class LexerTest(TemplateTest): <%def name="foo()"> this is a def. </%def> - + and some more text. """ node = Lexer(template).parse() self._compare(node, TemplateNode({}, - [Text(u'''\n<b>Hello world</b>\n ''', (1, - 1)), DefTag(u'def', {u'name': u'foo()'}, (3, 9), - [Text(u'''\n this is a def.\n ''', + [Text('''\n<b>Hello world</b>\n ''', (1, + 1)), DefTag('def', {'name': 'foo()'}, (3, 9), + [Text('''\n this is a def.\n ''', (3, 28))]), - Text(u'''\n \n and some more text.\n''', + Text('''\n\n and some more text.\n''', (5, 16))])) def test_unclosed_tag(self): template = """ - + <%def name="foo()"> other text """ try: nodes = Lexer(template).parse() assert False - except exceptions.SyntaxException, e: + except exceptions.SyntaxException as e: assert str(e) == "Unclosed tag: <%def> at line: 5 char: 9" def test_onlyclosed_tag(self): @@ -78,9 +86,9 @@ class LexerTest(TemplateTest): <%def name="foo()"> foo </%def> - + </%namespace> - + hi. """ self.assertRaises(exceptions.SyntaxException, @@ -102,8 +110,8 @@ class LexerTest(TemplateTest): foo </%namespace> </%def> - - + + hi. """ self.assertRaises(exceptions.SyntaxException, @@ -121,7 +129,7 @@ class LexerTest(TemplateTest): """ <%DEF name="foo()"> </%def> - + """ self.assertRaises(exceptions.CompileException, Lexer(template).parse) @@ -129,7 +137,7 @@ class LexerTest(TemplateTest): def test_percent_escape(self): template = \ """ - + %% some whatever. %% more some whatever @@ -137,12 +145,12 @@ class LexerTest(TemplateTest): % endif """ node = Lexer(template).parse() - self._compare(node, TemplateNode({}, [Text(u'''\n \n''', - (1, 1)), Text(u'''% some whatever.\n\n''', (3, 2)), - Text(u' %% more some whatever\n', (5, 2)), - ControlLine(u'if', u'if foo:', False, (6, 1)), - ControlLine(u'if', u'endif', True, (7, 1)), - Text(u' ', (8, 1))])) + self._compare(node, TemplateNode({}, [Text('''\n\n''', + (1, 1)), Text('''% some whatever.\n\n''', (3, 2)), + Text(' %% more some whatever\n', (5, 2)), + ControlLine('if', 'if foo:', False, (6, 1)), + ControlLine('if', 'endif', True, (7, 1)), + Text(' ', (8, 1))])) def test_text_tag(self): template = \ @@ -153,44 +161,40 @@ class LexerTest(TemplateTest): % endif <%text> # more code - + % more code <%illegal compionent>/></> <%def name="laal()">def</%def> - - + + </%text> <%def name="foo()">this is foo</%def> - + % if bar: code % endif """ node = Lexer(template).parse() - self._compare(node, - TemplateNode({}, [Text(u'\n', (1, 1)), - Comment(u'comment', (2, 1)), - ControlLine(u'if', u'if foo:', False, (3, 1)), - Text(u' hi\n', (4, 1)), - ControlLine(u'if', u'endif', True, (5, 1)), - Text(u' ', (6, 1)), TextTag(u'text', {}, - (6, 9), - [Text(u'''\n # more code\n ''' - '''\n % more code\n ''' - '''<%illegal compionent>/></>\n ''' - '''<%def name="laal()">def</%def>\n ''' - ''' \n \n ''', - (6, 16))]), Text(u''' - - ''', (14, 17)), - DefTag(u'def', {u'name': u'foo()'}, (16, 9), - [Text(u'this is foo', (16, 28))]), - Text(u'''\n \n''', (16, 46)), - ControlLine(u'if', u'if bar:', False, (18, 1)), - Text(u' code\n', (19, 1)), - ControlLine(u'if', u'endif', True, (20, 1)), - Text(u' ', (21, 1))])) + self._compare(node, + TemplateNode({}, [Text('\n', (1, 1)), + Comment('comment', (2, 1)), + ControlLine('if', 'if foo:', False, (3, 1)), + Text(' hi\n', (4, 1)), + ControlLine('if', 'endif', True, (5, 1)), + Text(' ', (6, 1)), + TextTag('text', {}, (6, 9), + [Text('\n # more code\n\n ' + ' % more code\n <%illegal compionent>/></>\n' + ' <%def name="laal()">def</%def>\n\n\n ', + (6, 16))]), Text('\n\n ', (14, 17)), + DefTag('def', {'name': 'foo()'}, (16, 9), + [Text('this is foo', (16, 28))]), Text('\n\n', (16, 46)), + ControlLine('if', 'if bar:', False, (18, 1)), + Text(' code\n', (19, 1)), + ControlLine('if', 'endif', True, (20, 1)), + Text(' ', (21, 1))]) + ) def test_def_syntax(self): template = \ @@ -220,26 +224,26 @@ class LexerTest(TemplateTest): </%def> """ node = Lexer(template).parse() - self._compare(node, TemplateNode({}, [Text(u'\n ', - (1, 1)), DefTag(u'def', {u'name': u'adef()'}, (2, + self._compare(node, TemplateNode({}, [Text('\n ', + (1, 1)), DefTag('def', {'name': 'adef()'}, (2, 13), - [Text(u'''\n adef\n ''', - (2, 36))]), Text(u'\n ', (4, 20))])) + [Text('''\n adef\n ''', + (2, 36))]), Text('\n ', (4, 20))])) def test_ns_tag_closed(self): template = \ """ - + <%self:go x="1" y="2" z="${'hi' + ' ' + 'there'}"/> """ nodes = Lexer(template).parse() self._compare(nodes, TemplateNode({}, - [Text(u''' - + [Text(''' + ''', (1, 1)), - CallNamespaceTag(u'self:go', {u'x': u'1', u'y' - : u'2', u'z': u"${'hi' + ' ' + 'there'}"}, (3, - 13), []), Text(u'\n ', (3, 64))])) + CallNamespaceTag('self:go', {'x': '1', 'y' + : '2', 'z': "${'hi' + ' ' + 'there'}"}, (3, + 13), []), Text('\n ', (3, 64))])) def test_ns_tag_empty(self): template = \ @@ -247,34 +251,34 @@ class LexerTest(TemplateTest): <%form:option value=""></%form:option> """ nodes = Lexer(template).parse() - self._compare(nodes, TemplateNode({}, [Text(u'\n ', - (1, 1)), CallNamespaceTag(u'form:option', - {u'value': u''}, (2, 13), []), Text(u'\n ' + self._compare(nodes, TemplateNode({}, [Text('\n ', + (1, 1)), CallNamespaceTag('form:option', + {'value': ''}, (2, 13), []), Text('\n ' , (2, 51))])) def test_ns_tag_open(self): template = \ """ - + <%self:go x="1" y="${process()}"> this is the body </%self:go> """ nodes = Lexer(template).parse() self._compare(nodes, TemplateNode({}, - [Text(u''' - + [Text(''' + ''', (1, 1)), - CallNamespaceTag(u'self:go', {u'x': u'1', u'y' - : u'${process()}'}, (3, 13), - [Text(u''' + CallNamespaceTag('self:go', {'x': '1', 'y' + : '${process()}'}, (3, 13), + [Text(''' this is the body ''', - (3, 46))]), Text(u'\n ', (5, 24))])) + (3, 46))]), Text('\n ', (5, 24))])) def test_expr_in_attribute(self): """test some slightly trickier expressions. - + you can still trip up the expression parsing, though, unless we integrated really deeply somehow with AST.""" @@ -284,26 +288,26 @@ class LexerTest(TemplateTest): <%call expr='foo<bar and hoho>lala and "x" + "y"'/> """ nodes = Lexer(template).parse() - self._compare(nodes, TemplateNode({}, [Text(u'\n ', - (1, 1)), CallTag(u'call', {u'expr' - : u"foo>bar and 'lala' or 'hoho'"}, (2, 13), []), - Text(u'\n ', (2, 57)), CallTag(u'call' - , {u'expr': u'foo<bar and hoho>lala and "x" + "y"' - }, (3, 13), []), Text(u'\n ', (3, 64))])) + self._compare(nodes, TemplateNode({}, [Text('\n ', + (1, 1)), CallTag('call', {'expr' + : "foo>bar and 'lala' or 'hoho'"}, (2, 13), []), + Text('\n ', (2, 57)), CallTag('call' + , {'expr': 'foo<bar and hoho>lala and "x" + "y"' + }, (3, 13), []), Text('\n ', (3, 64))])) def test_pagetag(self): template = \ """ <%page cached="True", args="a, b"/> - + some template """ nodes = Lexer(template).parse() - self._compare(nodes, TemplateNode({}, [Text(u'\n ', - (1, 1)), PageTag(u'page', {u'args': u'a, b', - u'cached': u'True'}, (2, 13), []), - Text(u''' - + self._compare(nodes, TemplateNode({}, [Text('\n ', + (1, 1)), PageTag('page', {'args': 'a, b', + 'cached': 'True'}, (2, 13), []), + Text(''' + some template ''', (2, 48))])) @@ -311,31 +315,31 @@ class LexerTest(TemplateTest): def test_nesting(self): template = \ """ - + <%namespace name="ns"> <%def name="lala(hi, there)"> <%call expr="something()"/> </%def> </%namespace> - + """ nodes = Lexer(template).parse() self._compare(nodes, TemplateNode({}, - [Text(u''' - + [Text(''' + ''', (1, 1)), - NamespaceTag(u'namespace', {u'name': u'ns'}, (3, - 9), [Text(u'\n ', (3, 31)), - DefTag(u'def', {u'name': u'lala(hi, there)'}, (4, - 13), [Text(u'\n ', (4, 42)), - CallTag(u'call', {u'expr': u'something()'}, (5, - 17), []), Text(u'\n ', (5, 44))]), - Text(u'\n ', (6, 20))]), - Text(u''' - + NamespaceTag('namespace', {'name': 'ns'}, (3, + 9), [Text('\n ', (3, 31)), + DefTag('def', {'name': 'lala(hi, there)'}, (4, + 13), [Text('\n ', (4, 42)), + CallTag('call', {'expr': 'something()'}, (5, + 17), []), Text('\n ', (5, 44))]), + Text('\n ', (6, 20))]), + Text(''' + ''', (7, 22))])) - if util.py3k: + if compat.py3k: def test_code(self): template = \ """text @@ -350,14 +354,14 @@ more text %> """ nodes = Lexer(template).parse() - self._compare(nodes, + self._compare(nodes, TemplateNode({}, [ - Text(u'text\n ', (1, 1)), - Code(u'\nprint("hi")\nfor x in range(1,5):\n ' - 'print(x)\n \n', False, (2, 5)), - Text(u'\nmore text\n ', (6, 7)), - Code(u'\nimport foo\n \n', True, (8, 5)), - Text(u'\n', (10, 7))]) + Text('text\n ', (1, 1)), + Code('\nprint("hi")\nfor x in range(1,5):\n ' + 'print(x)\n \n', False, (2, 5)), + Text('\nmore text\n ', (6, 7)), + Code('\nimport foo\n \n', True, (8, 5)), + Text('\n', (10, 7))]) ) @@ -377,14 +381,14 @@ more text %> """ nodes = Lexer(template).parse() - self._compare(nodes, + self._compare(nodes, TemplateNode({}, [ - Text(u'text\n ', (1, 1)), - Code(u'\nprint "hi"\nfor x in range(1,5):\n ' - 'print x\n \n', False, (2, 5)), - Text(u'\nmore text\n ', (6, 7)), - Code(u'\nimport foo\n \n', True, (8, 5)), - Text(u'\n', (10, 7))]) + Text('text\n ', (1, 1)), + Code('\nprint "hi"\nfor x in range(1,5):\n ' + 'print x\n \n', False, (2, 5)), + Text('\nmore text\n ', (6, 7)), + Code('\nimport foo\n \n', True, (8, 5)), + Text('\n', (10, 7))]) ) def test_code_and_tags(self): @@ -409,20 +413,20 @@ more text result: <%call expr="foo.x(result)"/> """ nodes = Lexer(template).parse() - self._compare(nodes, TemplateNode({}, [Text(u'\n', (1, 1)), - NamespaceTag(u'namespace', {u'name': u'foo'}, (2, - 1), [Text(u'\n ', (2, 24)), DefTag(u'def', - {u'name': u'x()'}, (3, 5), - [Text(u'''\n this is x\n ''', (3, 22))]), - Text(u'\n ', (5, 12)), DefTag(u'def', {u'name' - : u'y()'}, (6, 5), - [Text(u'''\n this is y\n ''', (6, 22))]), - Text(u'\n', (8, 12))]), Text(u'''\n\n''', (9, 14)), - Code(u'''\nresult = []\ndata = get_data()\n''' + self._compare(nodes, TemplateNode({}, [Text('\n', (1, 1)), + NamespaceTag('namespace', {'name': 'foo'}, (2, + 1), [Text('\n ', (2, 24)), DefTag('def', + {'name': 'x()'}, (3, 5), + [Text('''\n this is x\n ''', (3, 22))]), + Text('\n ', (5, 12)), DefTag('def', {'name' + : 'y()'}, (6, 5), + [Text('''\n this is y\n ''', (6, 22))]), + Text('\n', (8, 12))]), Text('''\n\n''', (9, 14)), + Code('''\nresult = []\ndata = get_data()\n''' '''for x in data:\n result.append(x+7)\n\n''', - False, (11, 1)), Text(u'''\n\n result: ''', (16, - 3)), CallTag(u'call', {u'expr': u'foo.x(result)' - }, (18, 13), []), Text(u'\n', (18, 42))])) + False, (11, 1)), Text('''\n\n result: ''', (16, + 3)), CallTag('call', {'expr': 'foo.x(result)' + }, (18, 13), []), Text('\n', (18, 42))])) def test_expression(self): template = \ @@ -435,77 +439,77 @@ more text """ nodes = Lexer(template).parse() self._compare(nodes, TemplateNode({}, - [Text(u'\n this is some ', (1, 1)), - Expression(u'text', [], (2, 22)), - Text(u' and this is ', (2, 29)), - Expression(u'textwith ', ['escapes', 'moreescapes' - ], (2, 42)), Text(u'\n ', (2, 76)), - DefTag(u'def', {u'name': u'hi()'}, (3, 9), - [Text(u'\n give me ', (3, 27)), - Expression(u'foo()', [], (4, 21)), Text(u' and ', - (4, 29)), Expression(u'bar()', [], (4, 34)), - Text(u'\n ', (4, 42))]), Text(u'\n ' - , (5, 16)), Expression(u'hi()', [], (6, 9)), - Text(u'\n', (6, 16))])) + [Text('\n this is some ', (1, 1)), + Expression('text', [], (2, 22)), + Text(' and this is ', (2, 29)), + Expression('textwith ', ['escapes', 'moreescapes' + ], (2, 42)), Text('\n ', (2, 76)), + DefTag('def', {'name': 'hi()'}, (3, 9), + [Text('\n give me ', (3, 27)), + Expression('foo()', [], (4, 21)), Text(' and ', + (4, 29)), Expression('bar()', [], (4, 34)), + Text('\n ', (4, 42))]), Text('\n ' + , (5, 16)), Expression('hi()', [], (6, 9)), + Text('\n', (6, 16))])) def test_tricky_expression(self): template = """ - + ${x and "|" or "hi"} """ nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [ - Text(u'\n \n ', (1, 1)), - Expression(u'x and "|" or "hi"', [], (3, 13)), - Text(u'\n ', (3, 33)) + Text('\n\n ', (1, 1)), + Expression('x and "|" or "hi"', [], (3, 13)), + Text('\n ', (3, 33)) ]) ) template = """ - + ${hello + '''heres '{|}' text | | }''' | escape1} """ nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [ - Text(u'\n \n ', (1, 1)), - Expression(u"hello + '''heres '{|}' text | | }''' ", - ['escape1'], (3, 13)), - Text(u'\n ', (3, 62)) + Text('\n\n ', (1, 1)), + Expression("hello + '''heres '{|}' text | | }''' ", + ['escape1'], (3, 13)), + Text('\n ', (3, 62)) ]) ) def test_tricky_code(self): - if util.py3k: + if compat.py3k: template = """<% print('hi %>') %>""" nodes = Lexer(template).parse() self._compare(nodes, TemplateNode({}, - [Code(u"print('hi %>') \n", False, (1, 1))])) + [Code("print('hi %>') \n", False, (1, 1))])) else: template = """<% print 'hi %>' %>""" nodes = Lexer(template).parse() self._compare(nodes, TemplateNode({}, - [Code(u"print 'hi %>' \n", False, (1, 1))])) + [Code("print 'hi %>' \n", False, (1, 1))])) def test_tricky_code_2(self): template = \ - """<% + """<% # someone's comment - %> +%> """ nodes = Lexer(template).parse() self._compare(nodes, TemplateNode({}, - [Code(u""" + [Code(""" # someone's comment - + """, - False, (1, 1)), Text(u'\n ', (3, 11))])) + False, (1, 1)), Text('\n ', (3, 3))])) - if util.py3k: + if compat.py3k: def test_tricky_code_3(self): template = \ """<% @@ -517,10 +521,10 @@ more text there ''') # someone else's comment - %> '''and now some text '''""" +%> '''and now some text '''""" nodes = Lexer(template).parse() self._compare(nodes, TemplateNode({}, - [Code(u""" + [Code(""" print('hi') # this is a comment # another comment @@ -529,11 +533,11 @@ print(''' there ''') # someone else's comment - + """, False, (1, 1)), - Text(u" '''and now some text '''", (10, - 11))])) + Text(" '''and now some text '''", (10, + 3))])) else: def test_tricky_code_3(self): template = \ @@ -546,23 +550,23 @@ print(''' there ''' # someone else's comment - %> '''and now some text '''""" +%> '''and now some text '''""" nodes = Lexer(template).parse() self._compare(nodes, TemplateNode({}, - [Code(u"""\nprint 'hi'\n# this is a comment\n""" + [Code("""\nprint 'hi'\n# this is a comment\n""" """# another comment\nx = 7 """ """# someone's '''comment\nprint '''\n """ """there\n '''\n# someone else's """ - """comment\n \n""", + """comment\n\n""", False, (1, 1)), - Text(u" '''and now some text '''", (10,11))])) + Text(" '''and now some text '''", (10, 3))])) def test_tricky_code_4(self): template = \ """<% foo = "\\"\\\\" %>""" nodes = Lexer(template).parse() self._compare(nodes, TemplateNode({}, - [Code(u"""foo = "\\"\\\\" \n""", + [Code("""foo = "\\"\\\\" \n""", False, (1, 1))])) def test_tricky_code_5(self): @@ -570,9 +574,9 @@ print(''' """before ${ {'key': 'value'} } after""" nodes = Lexer(template).parse() self._compare(nodes, TemplateNode({}, - [Text(u'before ', (1, 1)), - Expression(u" {'key': 'value'} ", [], (1, 8)), - Text(u' after', (1, 29))])) + [Text('before ', (1, 1)), + Expression(" {'key': 'value'} ", [], (1, 8)), + Text(' after', (1, 29))])) def test_control_lines(self): template = \ @@ -587,21 +591,21 @@ text text la la tex tesl asdl l is ${l} kfmas d % endfor tetx text - + """ nodes = Lexer(template).parse() self._compare(nodes, TemplateNode({}, - [Text(u'''\ntext text la la\n''', (1, 1)), - ControlLine(u'if', u'if foo():', False, (3, 1)), - Text(u' mroe text la la blah blah\n', (4, 1)), - ControlLine(u'if', u'endif', True, (5, 1)), - Text(u'''\n and osme more stuff\n''', (6, - 1)), ControlLine(u'for', u'for l in range(1,5):', - False, (8, 1)), Text(u' tex tesl asdl l is ', - (9, 1)), Expression(u'l', [], (9, 24)), - Text(u' kfmas d\n', (9, 28)), ControlLine(u'for', - u'endfor', True, (10, 1)), - Text(u''' tetx text\n \n''', (11, 1))])) + [Text('''\ntext text la la\n''', (1, 1)), + ControlLine('if', 'if foo():', False, (3, 1)), + Text(' mroe text la la blah blah\n', (4, 1)), + ControlLine('if', 'endif', True, (5, 1)), + Text('''\n and osme more stuff\n''', (6, + 1)), ControlLine('for', 'for l in range(1,5):', + False, (8, 1)), Text(' tex tesl asdl l is ', + (9, 1)), Expression('l', [], (9, 24)), + Text(' kfmas d\n', (9, 28)), ControlLine('for', + 'endfor', True, (10, 1)), + Text(''' tetx text\n\n''', (11, 1))])) def test_control_lines_2(self): template = \ @@ -610,10 +614,10 @@ text text la la % endfor """ nodes = Lexer(template).parse() - self._compare(nodes, TemplateNode({}, [ControlLine(u'for', - u"for file in requestattr['toc'].filenames:", - False, (1, 1)), Text(u' x\n', (2, 1)), - ControlLine(u'for', u'endfor', True, (3, 1))])) + self._compare(nodes, TemplateNode({}, [ControlLine('for', + "for file in requestattr['toc'].filenames:", + False, (1, 1)), Text(' x\n', (2, 1)), + ControlLine('for', 'endfor', True, (3, 1))])) def test_long_control_lines(self): template = \ @@ -627,13 +631,13 @@ text text la la self._compare( nodes, TemplateNode({}, [ - Text(u'\n', (1, 1)), - ControlLine(u'for', u"for file in \\\n " - "requestattr['toc'].filenames:", - False, (2, 1)), - Text(u' x\n', (4, 1)), - ControlLine(u'for', u'endfor', True, (5, 1)), - Text(u' ', (6, 1)) + Text('\n', (1, 1)), + ControlLine('for', "for file in \\\n " + "requestattr['toc'].filenames:", + False, (2, 1)), + Text(' x\n', (4, 1)), + ControlLine('for', 'endfor', True, (5, 1)), + Text(' ', (6, 1)) ]) ) @@ -692,16 +696,16 @@ text text la la % endif """ nodes = Lexer(template).parse() - self._compare(nodes, TemplateNode({}, [Text(u'\n', (1, 1)), - ControlLine(u'if', u'if x:', False, (2, 1)), - Text(u' hi\n', (3, 1)), - ControlLine(u'elif', u'elif y+7==10:', False, (4, - 1)), Text(u' there\n', (5, 1)), - ControlLine(u'elif', u'elif lala:', False, (6, - 1)), Text(u' lala\n', (7, 1)), - ControlLine(u'else', u'else:', False, (8, 1)), - Text(u' hi\n', (9, 1)), - ControlLine(u'if', u'endif', True, (10, 1))])) + self._compare(nodes, TemplateNode({}, [Text('\n', (1, 1)), + ControlLine('if', 'if x:', False, (2, 1)), + Text(' hi\n', (3, 1)), + ControlLine('elif', 'elif y+7==10:', False, (4, + 1)), Text(' there\n', (5, 1)), + ControlLine('elif', 'elif lala:', False, (6, + 1)), Text(' lala\n', (7, 1)), + ControlLine('else', 'else:', False, (8, 1)), + Text(' hi\n', (9, 1)), + ControlLine('if', 'endif', True, (10, 1))])) def test_integration(self): template = \ @@ -727,27 +731,27 @@ text text la la </table> """ nodes = Lexer(template).parse() - self._compare(nodes, TemplateNode({}, [NamespaceTag(u'namespace' - , {u'file': u'somefile.html', u'name': u'foo'}, - (1, 1), []), Text(u'\n', (1, 46)), - Comment(u'inherit from foobar.html', (2, 1)), - InheritTag(u'inherit', {u'file': u'foobar.html'}, - (3, 1), []), Text(u'''\n\n''', (3, 31)), - DefTag(u'def', {u'name': u'header()'}, (5, 1), - [Text(u'''\n <div>header</div>\n''', (5, - 23))]), Text(u'\n', (7, 8)), DefTag(u'def', - {u'name': u'footer()'}, (8, 1), - [Text(u'''\n <div> footer</div>\n''', (8, - 23))]), Text(u'''\n\n<table>\n''', (10, 8)), - ControlLine(u'for', u'for j in data():', False, - (13, 1)), Text(u' <tr>\n', (14, 1)), - ControlLine(u'for', u'for x in j:', False, (15, - 1)), Text(u' <td>Hello ', (16, 1)), - Expression(u'x', ['h'], (16, 23)), Text(u'</td>\n' - , (16, 30)), ControlLine(u'for', u'endfor', True, - (17, 1)), Text(u' </tr>\n', (18, 1)), - ControlLine(u'for', u'endfor', True, (19, 1)), - Text(u'</table>\n', (20, 1))])) + self._compare(nodes, TemplateNode({}, [NamespaceTag('namespace' + , {'file': 'somefile.html', 'name': 'foo'}, + (1, 1), []), Text('\n', (1, 46)), + Comment('inherit from foobar.html', (2, 1)), + InheritTag('inherit', {'file': 'foobar.html'}, + (3, 1), []), Text('''\n\n''', (3, 31)), + DefTag('def', {'name': 'header()'}, (5, 1), + [Text('''\n <div>header</div>\n''', (5, + 23))]), Text('\n', (7, 8)), DefTag('def', + {'name': 'footer()'}, (8, 1), + [Text('''\n <div> footer</div>\n''', (8, + 23))]), Text('''\n\n<table>\n''', (10, 8)), + ControlLine('for', 'for j in data():', False, + (13, 1)), Text(' <tr>\n', (14, 1)), + ControlLine('for', 'for x in j:', False, (15, + 1)), Text(' <td>Hello ', (16, 1)), + Expression('x', ['h'], (16, 23)), Text('</td>\n' + , (16, 30)), ControlLine('for', 'endfor', True, + (17, 1)), Text(' </tr>\n', (18, 1)), + ControlLine('for', 'endfor', True, (19, 1)), + Text('</table>\n', (20, 1))])) def test_comment_after_statement(self): template = \ @@ -759,12 +763,12 @@ text text la la % endif #end """ nodes = Lexer(template).parse() - self._compare(nodes, TemplateNode({}, [Text(u'\n', (1, 1)), - ControlLine(u'if', u'if x: #comment', False, (2, - 1)), Text(u' hi\n', (3, 1)), - ControlLine(u'else', u'else: #next', False, (4, - 1)), Text(u' hi\n', (5, 1)), - ControlLine(u'if', u'endif #end', True, (6, 1))])) + self._compare(nodes, TemplateNode({}, [Text('\n', (1, 1)), + ControlLine('if', 'if x: #comment', False, (2, + 1)), Text(' hi\n', (3, 1)), + ControlLine('else', 'else: #next', False, (4, + 1)), Text(' hi\n', (5, 1)), + ControlLine('if', 'endif #end', True, (6, 1))])) def test_crlf(self): template = open(self._file_path("crlf.html"), 'rb').read() @@ -772,23 +776,23 @@ text text la la self._compare( nodes, TemplateNode({}, [ - Text(u'<html>\r\n\r\n', (1, 1)), - PageTag(u'page', { - u'args': u"a=['foo',\n 'bar']" - }, (3, 1), []), - Text(u'\r\n\r\nlike the name says.\r\n\r\n', (4, 26)), - ControlLine(u'for', u'for x in [1,2,3]:', False, (8, 1)), - Text(u' ', (9, 1)), - Expression(u'x', [], (9, 9)), - ControlLine(u'for', u'endfor', True, (10, 1)), - Text(u'\r\n', (11, 1)), - Expression(u"trumpeter == 'Miles' and " - "trumpeter or \\\n 'Dizzy'", - [], (12, 1)), - Text(u'\r\n\r\n', (13, 15)), - DefTag(u'def', {u'name': u'hi()'}, (15, 1), [ - Text(u'\r\n hi!\r\n', (15, 19))]), - Text(u'\r\n\r\n</html>\r\n', (17, 8)) + Text('<html>\r\n\r\n', (1, 1)), + PageTag('page', { + 'args': "a=['foo',\n 'bar']" + }, (3, 1), []), + Text('\r\n\r\nlike the name says.\r\n\r\n', (4, 26)), + ControlLine('for', 'for x in [1,2,3]:', False, (8, 1)), + Text(' ', (9, 1)), + Expression('x', [], (9, 9)), + ControlLine('for', 'endfor', True, (10, 1)), + Text('\r\n', (11, 1)), + Expression("trumpeter == 'Miles' and " + "trumpeter or \\\n 'Dizzy'", + [], (12, 1)), + Text('\r\n\r\n', (13, 15)), + DefTag('def', {'name': 'hi()'}, (15, 1), [ + Text('\r\n hi!\r\n', (15, 19))]), + Text('\r\n\r\n</html>\r\n', (17, 8)) ]) ) assert flatten_result(Template(template).render()) \ @@ -806,7 +810,7 @@ text text la la # also not a comment ## this is a comment - + this is ## not a comment <%doc> multiline @@ -817,14 +821,14 @@ hi """ nodes = Lexer(template).parse() self._compare(nodes, TemplateNode({}, - [Text(u'''\n<style>\n #someselector\n # ''' + [Text('''\n<style>\n #someselector\n # ''' '''other non comment stuff\n</style>\n''', - (1, 1)), Comment(u'a comment', (6, 1)), - Text(u'''\n# also not a comment\n\n''', (7, 1)), - Comment(u'this is a comment', (10, 1)), - Text(u''' \nthis is ## not a comment\n\n''', (11, - 1)), Comment(u''' multiline\ncomment\n''', (14, - 1)), Text(u''' + (1, 1)), Comment('a comment', (6, 1)), + Text('''\n# also not a comment\n\n''', (7, 1)), + Comment('this is a comment', (10, 1)), + Text('''\nthis is ## not a comment\n\n''', (11, + 1)), Comment(''' multiline\ncomment\n''', (14, + 1)), Text(''' hi ''', (16, 8))])) @@ -842,17 +846,17 @@ hi </%def> """ nodes = Lexer(template).parse() - self._compare(nodes, - TemplateNode({}, [Text(u'\n ', (1, + self._compare(nodes, + TemplateNode({}, [Text('\n ', (1, 1)), - Comment(u'''\n this is a comment\n ''', - (2, 9)), Text(u'\n ', (4, 16)), - DefTag(u'def', {u'name': u'foo()'}, (5, 9), - [Text(u'\n ', (5, 28)), - Comment(u'''\n this is the foo func\n''' + Comment('''\n this is a comment\n ''', + (2, 9)), Text('\n ', (4, 16)), + DefTag('def', {'name': 'foo()'}, (5, 9), + [Text('\n ', (5, 28)), + Comment('''\n this is the foo func\n''' ''' ''', - (6, 13)), Text(u'\n ', (8, 20))]), - Text(u'\n ', (9, 16))])) + (6, 13)), Text('\n ', (8, 20))]), + Text('\n ', (9, 16))])) def test_preprocess(self): @@ -866,6 +870,6 @@ hi # another comment """ nodes = Lexer(template, preprocessor=preproc).parse() - self._compare(nodes, TemplateNode({}, [Text(u'''\n hi\n''', - (1, 1)), Comment(u'old style comment', (3, 1)), - Comment(u'another comment', (4, 1))])) + self._compare(nodes, TemplateNode({}, [Text('''\n hi\n''', + (1, 1)), Comment('old style comment', (3, 1)), + Comment('another comment', (4, 1))])) diff --git a/test/test_lookup.py b/test/test_lookup.py index 40b9009..4cf82fe 100644 --- a/test/test_lookup.py +++ b/test/test_lookup.py @@ -1,7 +1,7 @@ from mako.template import Template from mako import lookup, exceptions, runtime from mako.util import FastEncodingBuffer -from util import flatten_result, result_lines +from .util import flatten_result, result_lines import unittest import os @@ -46,7 +46,7 @@ class LookupTest(unittest.TestCase): try: t.render() assert False - except exceptions.TemplateLookupException, e: + except exceptions.TemplateLookupException as e: assert str(e) == \ "Template 'memory:%s' has no TemplateLookup associated" % \ hex(id(t)) diff --git a/test/test_loop.py b/test/test_loop.py index 14912ee..acff53f 100644 --- a/test/test_loop.py +++ b/test/test_loop.py @@ -10,7 +10,7 @@ from mako.runtime import LoopStack, LoopContext from mako import exceptions from test import assert_raises_message from test import TemplateTest, eq_ -from util import flatten_result, result_lines +from .util import flatten_result, result_lines class TestLoop(unittest.TestCase): @@ -37,7 +37,7 @@ ${x} code = template.code assert not re.match(r"loop = __M_loop._enter\(:", code), "No need to "\ "generate a loop context if the loop variable wasn't accessed" - print template.render() + print(template.render()) def test_loop_demo(self): template = Template("""x|index|reverse_index|first|last|cycle|even|odd @@ -54,7 +54,7 @@ ${x}|${loop.index}|${loop.reverse_index}|${loop.first}|${loop.last}|${loop.cycle assert "loop = __M_loop._enter(" in code, "Generated a loop context since "\ "the loop variable was accessed" rendered = template.render() - print rendered + print(rendered) for line in expected: assert line in rendered, "Loop variables give information about "\ "the progress of the loop" @@ -101,7 +101,7 @@ ${x} ${loop.index} <- outer loop "b 1 <- parent loop" ] for line in expected: - print code + print(code) assert line in rendered, "The parent attribute of a loop gives "\ "you the previous loop context in the stack" @@ -174,7 +174,7 @@ class TestLoopContext(unittest.TestCase): length = len(self.iterable) expected = tuple([length-i-1 for i in range(length)]) actual = tuple(self.ctx.reverse_index for i in self.ctx) - print expected, actual + print(expected, actual) assert expected == actual, "The reverse_index is the number of "\ "iterations until the end" diff --git a/test/test_lru.py b/test/test_lru.py index ade48a3..cde5601 100644 --- a/test/test_lru.py +++ b/test/test_lru.py @@ -1,7 +1,10 @@ from mako.util import LRUCache -import string, unittest, time, random +import string +import unittest +import time +import random -import thread +from mako.compat import thread class item: def __init__(self, id): @@ -13,19 +16,19 @@ class item: class LRUTest(unittest.TestCase): - def testlru(self): + def testlru(self): l = LRUCache(10, threshold=.2) - + for id in range(1,20): l[id] = item(id) - + # first couple of items should be gone - self.assert_(not l.has_key(1)) - self.assert_(not l.has_key(2)) - + self.assert_(1 not in l) + self.assert_(2 not in l) + # next batch over the threshold of 10 should be present for id in range(11,20): - self.assert_(l.has_key(id)) + self.assert_(id in l) l[12] l[15] @@ -35,25 +38,25 @@ class LRUTest(unittest.TestCase): l[26] = item(26) l[27] = item(27) - self.assert_(not l.has_key(11)) - self.assert_(not l.has_key(13)) - + self.assert_(11 not in l) + self.assert_(13 not in l) + for id in (25, 24, 23, 14, 12, 19, 18, 17, 16, 15): - self.assert_(l.has_key(id)) + self.assert_(id in l) def _disabled_test_threaded(self): size = 100 threshold = .5 all_elems = 2000 - hot_zone = range(30,40) + hot_zone = list(range(30,40)) cache = LRUCache(size, threshold) - + # element to store class Element(object): def __init__(self, id): self.id = id self.regets = 0 - + # return an element. we will favor ids in the relatively small # "hot zone" 25% of the time. def get_elem(): @@ -61,7 +64,7 @@ class LRUTest(unittest.TestCase): return hot_zone[random.randint(0, len(hot_zone) - 1)] else: return random.randint(1, all_elems) - + total = [0] # request thread. def request_elem(): @@ -74,23 +77,23 @@ class LRUTest(unittest.TestCase): except KeyError: e = Element(id) cache[id] = e - + time.sleep(random.random() / 1000) for x in range(0,20): - thread.start_new_thread(request_elem, ()) - + _thread.start_new_thread(request_elem, ()) + # assert size doesn't grow unbounded, doesnt shrink well below size for x in range(0,5): time.sleep(1) - print "size:", len(cache) + print("size:", len(cache)) assert len(cache) < size + size * threshold * 2 assert len(cache) > size - (size * .1) - + # computs the average number of times a range of elements were "reused", # i.e. without being removed from the cache. def average_regets_in_range(start, end): - elem = [e for e in cache.values() if e.id >= start and e.id <= end] + elem = [e for e in list(cache.values()) if e.id >= start and e.id <= end] if len(elem) == 0: return 0 avg = sum([e.regets for e in elem]) / len(elem) @@ -99,13 +102,13 @@ class LRUTest(unittest.TestCase): hotzone_avg = average_regets_in_range(30, 40) control_avg = average_regets_in_range(450,760) total_avg = average_regets_in_range(0, 2000) - + # hotzone should be way above the others - print "total fetches", total[0], "hotzone", \ + print("total fetches", total[0], "hotzone", \ hotzone_avg, "control", \ - control_avg, "total", total_avg - + control_avg, "total", total_avg) + assert hotzone_avg > total_avg * 5 > control_avg * 5 - - + + diff --git a/test/test_namespace.py b/test/test_namespace.py index 3c4c689..5f6d253 100644 --- a/test/test_namespace.py +++ b/test/test_namespace.py @@ -1,6 +1,6 @@ from mako.template import Template from mako import lookup -from util import flatten_result, result_lines +from .util import flatten_result, result_lines from test import TemplateTest, eq_ class NamespaceTest(TemplateTest): diff --git a/test/test_pygen.py b/test/test_pygen.py index 58265ff..7671bd9 100644 --- a/test/test_pygen.py +++ b/test/test_pygen.py @@ -1,7 +1,9 @@ import unittest from mako.pygen import PythonPrinter, adjust_whitespace -from StringIO import StringIO +from mako.compat import StringIO +from test import eq_ + class GeneratePythonTest(unittest.TestCase): def test_generate_normal(self): @@ -48,7 +50,7 @@ if x > 7: print "hi" print "there" foo(lala) - """ +""" stream = StringIO() printer = PythonPrinter(stream) printer.writeline("import lala") @@ -59,7 +61,7 @@ if x > 7: printer.writeline("print y") printer.close() #print "->" + stream.getvalue().replace(' ', '#') + "<-" - assert stream.getvalue() == \ + eq_(stream.getvalue(), """import lala for x in foo: print x @@ -71,9 +73,9 @@ for x in foo: print "hi" print "there" foo(lala) - + print y -""" +""") def test_multi_line(self): block = \ """ @@ -99,7 +101,7 @@ and more block. do_more_stuff(g) """ - + def test_false_unindentor(self): stream = StringIO() printer = PythonPrinter(stream) @@ -114,7 +116,7 @@ and more block. None ]: printer.writeline(line) - + assert stream.getvalue() == \ """try: elsemyvar = 12 @@ -123,8 +125,8 @@ and more block. finally: dosomething """ , stream.getvalue() - - + + def test_backslash_line(self): block = \ """ @@ -167,9 +169,9 @@ print "hi" def test_blank_lines(self): text = """ print "hi" # a comment - + # more comments - + print g """ assert adjust_whitespace(text) == \ diff --git a/test/test_template.py b/test/test_template.py index 2821910..ff82581 100644 --- a/test/test_template.py +++ b/test/test_template.py @@ -4,10 +4,12 @@ from mako.template import Template, ModuleTemplate from mako.lookup import TemplateLookup from mako.ext.preprocessors import convert_comments from mako import exceptions, util, runtime +from mako import compat import re import os from util import flatten_result, result_lines import codecs +from mako.compat import u from test import TemplateTest, eq_, template_base, module_base, \ requires_python_26_or_greater, assert_raises, assert_raises_message, \ requires_python_2 @@ -26,7 +28,7 @@ class EncodingTest(TemplateTest): except: # <h3>Exception: <span style="color:red">Foobar</span></h3> markup = html_error_template().render(full=False, css=False) - if util.py3k: + if compat.py3k: assert '<span style="color:red">Foobar</span></h3>'\ .encode('ascii') not in markup assert '<span style="color:red"'\ @@ -40,35 +42,35 @@ class EncodingTest(TemplateTest): def test_unicode(self): self._do_memory_test( - u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""", - u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""" + u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""), + u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""") ) def test_encoding_doesnt_conflict(self): self._do_memory_test( - u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""", - u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""", + u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""), + u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""), output_encoding='utf-8' ) def test_unicode_arg(self): - val = u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""" + val = u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""") self._do_memory_test( "${val}", - u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""", + u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""), template_args={'val':val} ) def test_unicode_file(self): self._do_file_test( "unicode.html", - u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""" + u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""") ) def test_unicode_file_code(self): self._do_file_test( 'unicode_code.html', - u"""hi, drôle de petite voix m’a réveillé.""", + u("""hi, drôle de petite voix m’a réveillé."""), filters=flatten_result ) @@ -77,24 +79,24 @@ class EncodingTest(TemplateTest): directories=[template_base], output_encoding='utf-8', default_filters=['decode.utf8']) - if util.py3k: + if compat.py3k: template = lookup.get_template('/chs_unicode_py3k.html') else: template = lookup.get_template('/chs_unicode.html') eq_( flatten_result(template.render_unicode(name='毛泽东')), - u'毛泽东 是 æ–°ä¸å›½çš„主å¸<br/> Welcome ä½ to 北京.' + u('毛泽东 是 æ–°ä¸å›½çš„主å¸<br/> Welcome ä½ to 北京.') ) def test_unicode_bom(self): self._do_file_test( 'bom.html', - u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""" + u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""") ) self._do_file_test( 'bommagic.html', - u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""" + u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""") ) self.assertRaises( @@ -104,105 +106,105 @@ class EncodingTest(TemplateTest): ) def test_unicode_memory(self): - val = u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""" + val = u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""") self._do_memory_test( ("## -*- coding: utf-8 -*-\n" + val).encode('utf-8'), - u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""" + u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""") ) def test_unicode_text(self): - val = u"""<%text>Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »</%text>""" + val = u("""<%text>Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »</%text>""") self._do_memory_test( ("## -*- coding: utf-8 -*-\n" + val).encode('utf-8'), - u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""" + u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""") ) def test_unicode_text_ccall(self): - val = u""" + val = u(""" <%def name="foo()"> ${capture(caller.body)} </%def> <%call expr="foo()"> <%text>Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »</%text> - </%call>""" + </%call>""") self._do_memory_test( ("## -*- coding: utf-8 -*-\n" + val).encode('utf-8'), - u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""", + u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""), filters=flatten_result ) def test_unicode_literal_in_expr(self): - if util.py3k: + if compat.py3k: self._do_memory_test( - u"""## -*- coding: utf-8 -*- + u("""## -*- coding: utf-8 -*- ${"Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"} - """.encode('utf-8'), - u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""", + """).encode('utf-8'), + u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""), filters = lambda s:s.strip() ) else: self._do_memory_test( - u"""## -*- coding: utf-8 -*- + u("""## -*- coding: utf-8 -*- ${u"Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"} - """.encode('utf-8'), - u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""", + """).encode('utf-8'), + u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""), filters = lambda s:s.strip() ) def test_unicode_literal_in_expr_file(self): self._do_file_test( 'unicode_expr.html', - u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""", + u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""), lambda t:t.strip() ) def test_unicode_literal_in_code(self): - if util.py3k: + if compat.py3k: self._do_memory_test( - u"""## -*- coding: utf-8 -*- + u("""## -*- coding: utf-8 -*- <% context.write("Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »") %> - """.encode('utf-8'), - u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""", + """).encode('utf-8'), + u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""), filters=lambda s:s.strip() ) else: self._do_memory_test( - u"""## -*- coding: utf-8 -*- + u("""## -*- coding: utf-8 -*- <% context.write(u"Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »") %> - """.encode('utf-8'), - u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""", + """).encode('utf-8'), + u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""), filters=lambda s:s.strip() ) def test_unicode_literal_in_controlline(self): - if util.py3k: + if compat.py3k: self._do_memory_test( - u"""## -*- coding: utf-8 -*- + u("""## -*- coding: utf-8 -*- <% x = "drôle de petite voix m’a réveillé." %> % if x=="drôle de petite voix m’a réveillé.": hi, ${x} % endif - """.encode('utf-8'), - u"""hi, drôle de petite voix m’a réveillé.""", + """).encode('utf-8'), + u("""hi, drôle de petite voix m’a réveillé."""), filters=lambda s:s.strip(), ) else: self._do_memory_test( - u"""## -*- coding: utf-8 -*- + u("""## -*- coding: utf-8 -*- <% x = u"drôle de petite voix m’a réveillé." %> % if x==u"drôle de petite voix m’a réveillé.": hi, ${x} % endif - """.encode('utf-8'), - u"""hi, drôle de petite voix m’a réveillé.""", + """).encode('utf-8'), + u("""hi, drôle de petite voix m’a réveillé."""), filters=lambda s:s.strip(), ) @@ -210,10 +212,10 @@ class EncodingTest(TemplateTest): self._do_file_test( "unicode_arguments.html", [ - u'x is: drôle de petite voix m’a réveillé', - u'x is: drôle de petite voix m’a réveillé', - u'x is: drôle de petite voix m’a réveillé', - u'x is: drôle de petite voix m’a réveillé', + u('x is: drôle de petite voix m’a réveillé'), + u('x is: drôle de petite voix m’a réveillé'), + u('x is: drôle de petite voix m’a réveillé'), + u('x is: drôle de petite voix m’a réveillé'), ], filters=result_lines ) @@ -221,59 +223,59 @@ class EncodingTest(TemplateTest): self._do_memory_test( open(self._file_path("unicode_arguments.html"), 'rb').read(), [ - u'x is: drôle de petite voix m’a réveillé', - u'x is: drôle de petite voix m’a réveillé', - u'x is: drôle de petite voix m’a réveillé', - u'x is: drôle de petite voix m’a réveillé', + u('x is: drôle de petite voix m’a réveillé'), + u('x is: drôle de petite voix m’a réveillé'), + u('x is: drôle de petite voix m’a réveillé'), + u('x is: drôle de petite voix m’a réveillé'), ], filters=result_lines ) def test_unicode_literal_in_def(self): - if util.py3k: + if compat.py3k: self._do_memory_test( - u"""## -*- coding: utf-8 -*- + u("""## -*- coding: utf-8 -*- <%def name="bello(foo, bar)"> Foo: ${ foo } Bar: ${ bar } </%def> <%call expr="bello(foo='árvÃztűrÅ‘ tükörfúrógép', bar='ÃRVÃZTÅ°RÅ TÃœKÖRFÚRÓGÉP')"> - </%call>""".encode('utf-8'), - u"""Foo: árvÃztűrÅ‘ tükörfúrógép Bar: ÃRVÃZTÅ°RÅ TÃœKÖRFÚRÓGÉP""", + </%call>""").encode('utf-8'), + u("""Foo: árvÃztűrÅ‘ tükörfúrógép Bar: ÃRVÃZTÅ°RÅ TÃœKÖRFÚRÓGÉP"""), filters=flatten_result ) self._do_memory_test( - u"""## -*- coding: utf-8 -*- + u("""## -*- coding: utf-8 -*- <%def name="hello(foo='árvÃztűrÅ‘ tükörfúrógép', bar='ÃRVÃZTÅ°RÅ TÃœKÖRFÚRÓGÉP')"> Foo: ${ foo } Bar: ${ bar } </%def> - ${ hello() }""".encode('utf-8'), - u"""Foo: árvÃztűrÅ‘ tükörfúrógép Bar: ÃRVÃZTÅ°RÅ TÃœKÖRFÚRÓGÉP""", + ${ hello() }""").encode('utf-8'), + u("""Foo: árvÃztűrÅ‘ tükörfúrógép Bar: ÃRVÃZTÅ°RÅ TÃœKÖRFÚRÓGÉP"""), filters=flatten_result ) else: self._do_memory_test( - u"""## -*- coding: utf-8 -*- + u("""## -*- coding: utf-8 -*- <%def name="bello(foo, bar)"> Foo: ${ foo } Bar: ${ bar } </%def> <%call expr="bello(foo=u'árvÃztűrÅ‘ tükörfúrógép', bar=u'ÃRVÃZTÅ°RÅ TÃœKÖRFÚRÓGÉP')"> - </%call>""".encode('utf-8'), - u"""Foo: árvÃztűrÅ‘ tükörfúrógép Bar: ÃRVÃZTÅ°RÅ TÃœKÖRFÚRÓGÉP""", + </%call>""").encode('utf-8'), + u("""Foo: árvÃztűrÅ‘ tükörfúrógép Bar: ÃRVÃZTÅ°RÅ TÃœKÖRFÚRÓGÉP"""), filters=flatten_result ) self._do_memory_test( - u"""## -*- coding: utf-8 -*- + u("""## -*- coding: utf-8 -*- <%def name="hello(foo=u'árvÃztűrÅ‘ tükörfúrógép', bar=u'ÃRVÃZTÅ°RÅ TÃœKÖRFÚRÓGÉP')"> Foo: ${ foo } Bar: ${ bar } </%def> - ${ hello() }""".encode('utf-8'), - u"""Foo: árvÃztűrÅ‘ tükörfúrógép Bar: ÃRVÃZTÅ°RÅ TÃœKÖRFÚRÓGÉP""", + ${ hello() }""").encode('utf-8'), + u("""Foo: árvÃztűrÅ‘ tükörfúrógép Bar: ÃRVÃZTÅ°RÅ TÃœKÖRFÚRÓGÉP"""), filters=flatten_result ) @@ -281,31 +283,31 @@ class EncodingTest(TemplateTest): """test the 'input_encoding' flag on Template, and that unicode objects arent double-decoded""" - if util.py3k: + if compat.py3k: self._do_memory_test( - u"hello ${f('Å›lÄ…sk')}", - u"hello Å›lÄ…sk", + u("hello ${f('Å›lÄ…sk')}"), + u("hello Å›lÄ…sk"), input_encoding='utf-8', - template_args={'f':lambda x:x} + template_args={'f': lambda x:x} ) self._do_memory_test( - u"## -*- coding: utf-8 -*-\nhello ${f('Å›lÄ…sk')}", - u"hello Å›lÄ…sk", - template_args={'f':lambda x:x} + u("## -*- coding: utf-8 -*-\nhello ${f('Å›lÄ…sk')}"), + u("hello Å›lÄ…sk"), + template_args={'f': lambda x:x} ) else: self._do_memory_test( - u"hello ${f(u'Å›lÄ…sk')}", - u"hello Å›lÄ…sk", + u("hello ${f(u'Å›lÄ…sk')}"), + u("hello Å›lÄ…sk"), input_encoding='utf-8', - template_args={'f':lambda x:x} + template_args={'f': lambda x:x} ) self._do_memory_test( - u"## -*- coding: utf-8 -*-\nhello ${f(u'Å›lÄ…sk')}", - u"hello Å›lÄ…sk", - template_args={'f':lambda x:x} + u("## -*- coding: utf-8 -*-\nhello ${f(u'Å›lÄ…sk')}"), + u("hello Å›lÄ…sk"), + template_args={'f': lambda x:x} ) def test_raw_strings(self): @@ -315,7 +317,7 @@ class EncodingTest(TemplateTest): """ self._do_memory_test( - u"## -*- coding: utf-8 -*-\nhello ${x}", + u("## -*- coding: utf-8 -*-\nhello ${x}"), "hello Å›lÄ…sk", default_filters=[], template_args={'x':'Å›lÄ…sk'}, @@ -326,23 +328,23 @@ class EncodingTest(TemplateTest): # now, the way you *should* be doing it.... self._do_memory_test( - u"## -*- coding: utf-8 -*-\nhello ${x}", - u"hello Å›lÄ…sk", - template_args={'x':u'Å›lÄ…sk'} + u("## -*- coding: utf-8 -*-\nhello ${x}"), + u("hello Å›lÄ…sk"), + template_args={'x':u('Å›lÄ…sk')} ) def test_encoding(self): self._do_memory_test( - u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""", - u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""".encode('utf-8'), + u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""), + u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""").encode('utf-8'), output_encoding='utf-8', unicode_=False ) def test_encoding_errors(self): self._do_memory_test( - u"""KGB (transliteration of "КГБ") is the Russian-language abbreviation for Committee for State Security, (Russian: КомитÌет ГоÑудÌарÑтвенной БезопÌаÑноÑти (help·info); Komitet Gosudarstvennoy Bezopasnosti)""", - u"""KGB (transliteration of "КГБ") is the Russian-language abbreviation for Committee for State Security, (Russian: КомитÌет ГоÑудÌарÑтвенной БезопÌаÑноÑти (help·info); Komitet Gosudarstvennoy Bezopasnosti)""".encode('iso-8859-1', 'replace'), + u("""KGB (transliteration of "КГБ") is the Russian-language abbreviation for Committee for State Security, (Russian: КомитÌет ГоÑудÌарÑтвенной БезопÌаÑноÑти (help·info); Komitet Gosudarstvennoy Bezopasnosti)"""), + u("""KGB (transliteration of "КГБ") is the Russian-language abbreviation for Committee for State Security, (Russian: КомитÌет ГоÑудÌарÑтвенной БезопÌаÑноÑти (help·info); Komitet Gosudarstvennoy Bezopasnosti)""").encode('iso-8859-1', 'replace'), output_encoding='iso-8859-1', encoding_errors='replace', unicode_=False ) @@ -350,7 +352,7 @@ class EncodingTest(TemplateTest): def test_read_unicode(self): lookup = TemplateLookup(directories=[template_base], filesystem_checks=True, output_encoding='utf-8') - if util.py3k: + if compat.py3k: template = lookup.get_template('/read_unicode_py3k.html') else: template = lookup.get_template('/read_unicode.html') @@ -420,11 +422,7 @@ class PageArgsTest(TemplateTest): assert flatten_result(template.render(x=5, y=10)) == "this is page, 5, 10, 7" assert flatten_result(template.render(x=5, y=10, z=32)) == "this is page, 5, 10, 32" - try: - template.render(y=10) - assert False - except TypeError, e: - assert True + assert_raises(TypeError, template.render, y=10) def test_inherits(self): lookup = TemplateLookup() @@ -1012,11 +1010,11 @@ class RichTracebackTest(TemplateTest): def _do_test_traceback(self, utf8, memory, syntax): if memory: if syntax: - source = u'## coding: utf-8\n<% print "m’a réveillé. '\ - u'Elle disait: « S’il vous plaît… dessine-moi un mouton! » %>' + source = u('## coding: utf-8\n<% print "m’a réveillé. '\ + 'Elle disait: « S’il vous plaît… dessine-moi un mouton! » %>') else: - source = u'## coding: utf-8\n<% print u"m’a réveillé. '\ - u'Elle disait: « S’il vous plaît… dessine-moi un mouton! »" + str(5/0) %>' + source = u('## coding: utf-8\n<% print u"m’a réveillé. '\ + 'Elle disait: « S’il vous plaît… dessine-moi un mouton! »" + str(5/0) %>') if utf8: source = source.encode('utf-8') else: @@ -1036,7 +1034,7 @@ class RichTracebackTest(TemplateTest): if not syntax: template.render_unicode() assert False - except Exception, e: + except Exception: tback = exceptions.RichTraceback() if utf8: assert tback.source == source.decode('utf-8') diff --git a/test/test_tgplugin.py b/test/test_tgplugin.py index 3aa6122..560c2fe 100644 --- a/test/test_tgplugin.py +++ b/test/test_tgplugin.py @@ -1,7 +1,7 @@ import unittest from mako.ext.turbogears import TGPlugin -from util import flatten_result, result_lines +from .util import flatten_result, result_lines from test import TemplateTest, template_base tl = TGPlugin(options=dict(directories=[template_base]), extension='html') diff --git a/test/test_util.py b/test/test_util.py index b875f53..a7da274 100644 --- a/test/test_util.py +++ b/test/test_util.py @@ -2,7 +2,7 @@ import os import unittest -from mako import util, exceptions +from mako import util, exceptions, compat from test import eq_, skip_if, assert_raises_message class UtilTest(unittest.TestCase): @@ -22,7 +22,7 @@ class UtilTest(unittest.TestCase): eq_(buf.getvalue(), "string c string d") def test_fast_buffer_encoded(self): - s = u"drôl m’a rée « S’il" + s = "drôl m’a rée « S’il" buf = util.FastEncodingBuffer(encoding='utf-8') buf.write(s[0:10]) buf.write(s[10:]) @@ -34,7 +34,7 @@ class UtilTest(unittest.TestCase): data = util.read_file(fn, 'rb') self.failUnless('test_util' in str(data)) # str() for py3k - @skip_if(lambda: util.pypy, "Pypy does this differently") + @skip_if(lambda: compat.pypy, "Pypy does this differently") def test_load_module(self): fn = os.path.join(os.path.dirname(__file__), 'test_util.py') module = util.load_module('mako.template', fn) -- GitLab