New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"caller" should not be defined for a regular def call even if youre nested in a <%call>'ed def #28

Closed
sqlalchemy-bot opened this Issue Mar 14, 2007 · 3 comments

Comments

Projects
None yet
1 participant
@sqlalchemy-bot

sqlalchemy-bot commented Mar 14, 2007

Migrated issue, originally created by Michael Bayer (@zzzeek)

easier to illustrate:

<%def name="a()">
%	if caller:
${ caller.body() }\
%	endif
AAA
${ b() }
</%def>

<%def name="b()">
%	if caller:
${ caller.body() }\
%	endif
BBB
${ c() }
</%def>

<%def name="c()">
%	if caller:
${ caller.body() }\
%	endif
CCC
</%def>

<%call expr="a()">
CALL
</%call>

result:

CALL AAA CALL BBB CALL CCC

should be:

CALL AAA BBB CCC
@sqlalchemy-bot

This comment has been minimized.

sqlalchemy-bot commented Apr 14, 2007

Michael Bayer (@zzzeek) wrote:

im not really sure if theres a fix for this...it may be more or less a rewrite of how all function calls work, which while it shouldnt be ruled out, would most likely add a significant layer of interpretation to Mako and slow it down at least a little bit, but maybe more than we'd like (i want this thing to stay really fast).

Mako has no runtime "stack frame" that is actually tracking callers or anything else about the call stack. theres some extra tricks used in the case of the <%call> tag to propigate the caller around, but theres nothing going on in the case of normal <%def> calls to track the caller in those cases; so it stays set to what the caller already was from the last <%call>. what we're looking at is pushing/popping caller context for every def call not just <%call>s, thereby implementing an interpreted callstack. hopefully all the wacky unit tests we have would still all work (i made some attempts just now and they didnt...so this will be a lot of work to get it going).

i have in the past tried hanging on to Python's own stack frame system but did not have good results (since the stack frames do not line up cleanly with actual <%defs> and <%calls>).

@sqlalchemy-bot

This comment has been minimized.

sqlalchemy-bot commented Apr 14, 2007

Michael Bayer (@zzzeek) wrote:

OK, I added the call stack and as expected everything works great, but also the speed diference, at least in the basic.py speed test which has three def calls per run, the difference in execution time is negligible. in a page with a lot of def calls, it probably makes more of a difference, but its still tiny overhead compared to a more heavily interpreted language. we also get heavier generated modules since most defs have a stack/push/pop step fed into a try/finally.

the call stack code makes the whole callable system a lot simpler and transparent, with the new CallerStack being very simple without all the weirdness that _StackFacade had. so because its much simpler now i was also able to get better control of 'caller' scope within the callables that are actually within the <%call> tag - the body uses the caller that was already in scope, the other callables pull from the context...anyway, the approach is more stable so itll stay, in [changeset:257].

@sqlalchemy-bot

This comment has been minimized.

sqlalchemy-bot commented Apr 14, 2007

Changes by Michael Bayer (@zzzeek):

  • changed status to closed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment