Skip to content

Commit

Permalink
Merge pull request #222 from Yelp/no_auto_self_part_2
Browse files Browse the repository at this point in the history
No auto self: Part 2 - add a setting to disable auto-self
  • Loading branch information
Buck Evan committed Jun 1, 2016
2 parents a951e70 + 1bef078 commit 23942dd
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 4 deletions.
16 changes: 12 additions & 4 deletions Cheetah/legacy_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
# All #import statements are hoisted to the top of the module
'useLegacyImportMode': True,
'gettextTokens': ['_', 'gettext', 'ngettext', 'pgettext', 'npgettext'],
# Can $foo mean both self.foo and NS['foo']?
'enable_auto_self': True,
}

CLASS_NAME = 'YelpCheetahTemplate'
Expand All @@ -47,10 +49,13 @@ def genPlainVar(nameChunks):
return '.'.join(name + rest for name, rest in nameChunks)


def genNameMapperVar(nameChunks):
def genNameMapperVar(nameChunks, auto_self):
name, remainder = nameChunks[0]
namept1, dot, rest = name.partition('.')
start = 'VFFSL("{}", locals(), globals(), self, NS){}{}{}'.format(namept1, dot, rest, remainder)
if auto_self:
start = 'VFFSL("{}", locals(), globals(), self, NS){}{}{}'.format(namept1, dot, rest, remainder)
else:
start = 'VFFNS("{}", locals(), globals(), NS){}{}{}'.format(namept1, dot, rest, remainder)
tail = genPlainVar(nameChunks[1:])
return start + ('.' if tail else '') + tail

Expand Down Expand Up @@ -437,10 +442,11 @@ def __init__(self, source, settings=None):
)
self._importStatements = [
'import io',
'from Cheetah.NameMapper import value_from_frame_or_namespace as VFFNS',
'from Cheetah.NameMapper import value_from_frame_or_search_list as VFFSL',
'from Cheetah.Template import NO_CONTENT',
]
self._global_vars = {'io', 'NO_CONTENT', 'VFFSL'}
self._global_vars = {'io', 'NO_CONTENT', 'VFFNS', 'VFFSL'}

self._gettext_scannables = []

Expand Down Expand Up @@ -492,7 +498,9 @@ def genCheetahVar(self, nameChunks, lineCol):
if plain:
return genPlainVar(nameChunks)
else:
return genNameMapperVar(nameChunks)
return genNameMapperVar(
nameChunks, auto_self=self.setting('enable_auto_self'),
)

def addGetTextVar(self, nameChunks, lineCol):
"""Output something that gettext can recognize.
Expand Down
7 changes: 7 additions & 0 deletions bench/bench_lookup_builtin_no_auto_self.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from Cheetah.compile import compile_to_class
from constants import BUILTIN_SRC
from constants import NO_AUTO_SELF


tmpl = compile_to_class(NO_AUTO_SELF + BUILTIN_SRC)()
run = tmpl.respond
11 changes: 11 additions & 0 deletions bench/bench_lookup_dotted_sl_no_auto_self.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from Cheetah.compile import compile_to_class
from constants import DOTTED_SL_SRC
from constants import NO_AUTO_SELF


class fooobj:
bar = 'baz'


tmpl = compile_to_class(NO_AUTO_SELF + DOTTED_SL_SRC)({'foo': fooobj})
run = tmpl.respond
7 changes: 7 additions & 0 deletions bench/bench_lookup_global_no_auto_self.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from Cheetah.compile import compile_to_class
from constants import GLOBAL_SRC
from constants import NO_AUTO_SELF


tmpl = compile_to_class(NO_AUTO_SELF + GLOBAL_SRC)()
run = tmpl.respond
7 changes: 7 additions & 0 deletions bench/bench_lookup_local_no_auto_self.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from Cheetah.compile import compile_to_class
from constants import LOCAL_SRC
from constants import NO_AUTO_SELF


tmpl = compile_to_class(NO_AUTO_SELF + LOCAL_SRC)()
run = tmpl.respond
7 changes: 7 additions & 0 deletions bench/bench_lookup_sl_no_auto_self.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from Cheetah.compile import compile_to_class
from constants import NO_AUTO_SELF
from constants import SL_SRC


tmpl = compile_to_class(NO_AUTO_SELF + SL_SRC)({'foo': 'bar'})
run = tmpl.respond
7 changes: 7 additions & 0 deletions bench/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,10 @@
'$x\n'
'#end for\n'
)


NO_AUTO_SELF = (
'#compiler-settings\n'
'enable_auto_self = False\n'
'#end compiler-settings\n'
)
31 changes: 31 additions & 0 deletions bench/log/2016-06-01_14:55:33.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
================================================================================
SHA = 8029956fa22330c173246082860ea99d4a0c6820
BEST_OF = 5
ITERATIONS = 10
TIME_PER_TEST = 200
bogomips : 5400.00
bogomips : 5400.00
bogomips : 5400.00
bogomips : 5400.00
bogomips : 5400.00
bogomips : 5400.00
--------------------------------------------------------------------------------
lookup_builtin_no_auto_self 135387 iterations
lookup_builtin_opt_on 138447 iterations
lookup_dotted_sl_no_auto_self 17749 iterations
lookup_dotted_sl_opt_on 15045 iterations
lookup_global_no_auto_self 139531 iterations
lookup_global_opt_on 135761 iterations
lookup_local_no_auto_self 121347 iterations
lookup_local_opt_on 125481 iterations
lookup_sl_no_auto_self 21191 iterations
lookup_sl_opt_on 16228 iterations
vffns_frame 40882 iterations
vffns_sl 22944 iterations
vffns_template 22382 iterations
vffsl_frame 38382 iterations
vffsl_sl 18030 iterations
vffsl_template 17824 iterations
write_markup 13481 iterations
write_text 8009 iterations
--------------------------------------------------------------------------------
23 changes: 23 additions & 0 deletions tests/SyntaxAndOutput_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from Cheetah import filters
from Cheetah.compile import compile_to_class
from Cheetah.legacy_parser import ParseError
from Cheetah.NameMapper import NotFound


def dummydecorator(func):
Expand Down Expand Up @@ -1696,3 +1697,25 @@ def test_allow_getvar_of_underscored_things():
# Regression test for v0.11.0
cls = compile_to_class('$self.getVar("foo_BAR1")')
assert cls({'foo_BAR1': 'baz'}).respond() == 'baz'


def test_allows_autoself():
cls = compile_to_class(
'#def foo():\n'
'ohai\n'
'#end def\n'
'$foo()\n',
)
assert cls().respond() == 'ohai\n\n'


def test_does_not_allow_autoself():
cls = compile_to_class(
'#def foo():\n'
'ohai\n'
'#end def\n'
'$foo()\n',
settings={'enable_auto_self': False},
)
with pytest.raises(NotFound):
cls().respond()

0 comments on commit 23942dd

Please sign in to comment.