>> Variable and FilterExpression will be deprecated as they require the
>> caller to know the length of the expression in advance.
>
> I'm not sure I follow this assertion. I have no problem believing
> FilterExpression can be made cleaner, but Variable takes an expression
> like 'article.section', plus a context, and resolves it into a string.
> In itself, it seems like a well built and stable piece of API.

To get this  expression string in the first place you have to split  
Token.contents somehow. smart_split() does that well for space  
delimited expressions.
But if you try to parse something like {% url %} you have to split its  
results again: "foo.bar,baz|filter:arg,42" won't do it. The current {%  
url %} parser now resorts to `str.split(",")` and
        {% url viewname list|join:"," %}
will break it. Of course that's a corner case and could be fixed with  
something like `smart_split(delim=",")`. But it would be much more  
elegant if you could just read an expression from a stream of tokens.  
That's what I meant when I said "the {% url %} parser is broken by  
design". I didn't mean to sound harsh - {% url %}'s parser is a  
reasonable tradeoff between simplicity and correctness.

> As best as I can make out, you are correct. FilterExpression appears
> to be an internal, so isn't covered by our backwards compatibility
> guarantees. However, Variable is documented API.

Variable and FilterExpression would still be around - compatible  
versions live in `django.template.compat` - and import paths remain  
functional.

>> 1.) Currently `Variable("unresolvable")` and
>> `FilterExpression("unresolvable", p)` resolve differently: Variable
>> raises VariableDoesNotExist and FilterExpression returns
>> TEMPLATE_STRING_IF_INVALID. Except when `ignore_failures=True` is
>> given. But `FilterExpression("foo|cut:unresolvable", p)` will again
>> raise VariableDoesNotExist - regardless of `ignore_failures=True`.
>>
>> My Expression implementation unifies these behaviours: If any part of
>> an expression is unresolvable a LookupError will be raised.
>> `ignore_failures` will be deprecated but there's a resolve_safe()
>> method on the Expression base class that reads:
>>
>>     def resolve_safe(self, context, default=None):
>>         try:
>>             return self.resolve(context)
>>         except LookupError:
>>             return default
>>
>> This would be a small backwards incompatible change. I have one
>> failing test (exception02) because the ExtendsNode implementation
>> depends on the current FilterExpression behaviour.
>
> It's either backwards compatible or it isn't. Backwards compatibility
> is a requirement, not an optional extra.

If FilterExpression is not part of the public API this is a non-issue.  
The problem was that unresolvable variables were treated differently  
from unresolvable filter arguments.

>> 3.) Numeric literals ending with "." are currently treated as
>> Variables. The following test (ifequal-numeric07) succeds because
>> `ignore_failures=True` in IfEqualNode suppresses the inevitable
>> VariableDoesNotExist exception and then compares None to 2: ('{%
>> ifequal x 2. %}yes{% endifequal %}', {'x': 2}, ''). My current
>> implementation raises a TemplateSyntaxError as soon as it  
>> encounters a
>> numeric literal with a trailing dot. This could easily be made
>> backwards compatible if it's considered worth it.
>
> Sorry, but this one can't change. "2." is a tested format for handling
> floats; the fact that this is inconvenient to your parser is
> irrelevant.

The problem is probably in bug in Variable:

 >>> from django.template import Variable, Context
 >>> Variable("2.").resolve(Context())
Traceback (most recent call last):
...
raise VariableDoesNotExist("Failed lookup for key [%s] in %r", (bit,  
current)) # missing attribute
 >>> Variable("2.").resolve(Context({"2": {"": "foo"}}))
'foo'

I originally wanted to parse "2." as a numeric literal. But there's  
currently code that explicitly attempts to reject such literals: 
http://code.djangoproject.com/browser/django/trunk/django/template/__init__.py#L663

And here's how I fixed it in my branch (as mentioned in my second post  
in this thread): 
http://github.com/emulbreh/django/commit/73bc93b4dbf251968e062825439033de33597b08

>> * {% url ... %}, {% ssi ... %} currently accept unquoted literal
>> strings. This will continue to work but the preferred syntax will use
>> properly quoted strings. This may one day allow for viewnames and ssi
>> paths that come from expressions.
>
> At this point, this sort of fix can't happen until v2.0. It's would be
> a major change at this point. It's nice to know that the template
> parsing tools will handle it when the time comes, but I would expect
> that to be true of _any_ rework of the parser.

The proposed change is fully backwards-compatible. Both tags only gain  
a new syntax variant. By documenting the unquoted variant as  
deprecated means that newly written templates will already be  
compatible when (in some distant future) expression will be allowed as  
viewnames.

>> * {% if not %} would fail with my current implementation. This is
>> fixable. But I'm not sure it's worth it: not/and/or should be  
>> keywords
>> in the context of boolean expressions.
>
> I'm unclear what you're proposing here. {% if not %} is a well
> documented API, so it can't be deprecated.

The problem was that "{% if not %}" (without any further expression;  
the variable is called "not") failed. However, I fixed this already  
(as mentioned in my followup post).

> I don't want to sound dismissive of the work you're done here, but
> your comments in this post haven't inspired me to go looking deeper.
> You've been a little cavalier with the term "backwards incompatible"
> on a couple of occasions, which is something that simply isn't
> acceptable in something as prominent and well documented as Django's
> template language.

Criticism is welcome. If FilterExpression is not public API ,  
everything should be backwards compatible now. That was the goal from  
the beginning.
The {% if not %} and Variable("2.") fixes are ugly but compact.
All tests pass (with two minor corrections: {% foo | bar %} is now  
valid and FilterExpression internals have changed).

> There are bugs in the template system. Many of these are caused by
> inconsistent handling of parsing, especially of variables. If you can
> point at something that you think is a bug (such as the handlng of
> foo._attrib), then it's no longer covered by backwards compatibility.
> However, you don't get that accommodation simply because something
> doesn't fit into your nice new parsing scheme.
>
> Now, some of this might just be a misunderstanding on my part -
> especially with regards to what is partially implemented, what you
> intend to fix, and what you think can't (or shouldn't) be fixed.
> You've spent a lot of time describing your new parsing API, but not a
> lot of time describing why the new API is required. To that end, I'm
> not entirely sure how much of this patch is intended to cover the "fix
> the inconsistencies in the template system" problem, and how much is
> intended to fix the "make template tags easier to write" problem. If
> you're proposing a major rework of internals with the goal of fixing
> bugs, explaining exactly what is broken and how it is broken is an
> important part of your proposal. If the goal is to improve the
> usability of the public API, explaining the use cases you're trying to
> make easier is important.

It's both: making the API friendlier and fixing bugs (by using the  
higher level API).
I thought that motivation and scope were mostly clear and approved.  
Let me refer you to the two previous threads for now:

http://groups.google.com/group/django-developers/browse_thread/thread/fb246422fa4e23d8
http://groups.google.com/group/django-developers/browse_thread/thread/4f5b01719e497325


> I'm also intrigued to know how this proposal intersects with Mike
> Malone's patch to introduce template caching (#6262).

There will be merge conflicts but I'm neither touching loader.py nor  
context.py so that should be managable.

> Please don't let this discourage you - I am keen to see improvements
> in the template system. However, any widespread changes are going to
> get _very_ thorough investigation, and before I invest the time
> tearing down the code, I want to make sure the fundamentals
> underpinning the patch are well understood and well founded.


__
Johannes


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to