On Tue, Sep 29, 2009 at 12:44 AM, Johannes Dollinger
<johannes.dollin...@einfallsreich.net> wrote:
>
>>> 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.

Sure - that explains why FilterExpression is a problem, but I don't
see why Variable is affected. Once you've parsed your expression into
tokens, those tokens that are known to be variables need to convert
'foo.bar' into something derived from context.

>>> 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.

While FilterExpression isn't part of the public API, the effects of
using FilterExpression _are_ part of public API. If I have code that
currently fails silently because of a badly named variable, *that
behaviour cannot change*. The fact that FilterExpression raises (or
doesn't raise) an exception is irrelevant. How that expression is
surfaced to the end-user is _very_ relevant.

>> 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).

The changes to internals don't especially concern me. However, I'm
unconvinced that "foo | bar" is a desirable change. I can see how it
would make your life easier, but unfortunately, that isn't the
criteria here :-)

>> 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

Herein lies the problem. The message you appear to have taken from
those threads doesn't match with what I see. I see:

 * Agreement that work is needed on templates
 * A long debate about a blog post comparing Jinga and Django's templates.
 * Some very specific comments from Malcolm addressing your approach
to backwards compatibility [1]
 * Agreement that this is a very large body of work
 * Agreement that the API for custom tags is too verbose.
 * Comments that the process of fixing bugs should be independent of
improving API [2]

[1] http://groups.google.com/group/django-developers/msg/97d32ac923b1f700
[2] http://groups.google.com/group/django-developers/msg/100e70150f37c172

On these points, you won't get any argument from me.

What I don't see is any specific endorsement of your approach, beyond
a general "looks like you're going the right way" comment from Jacob
[3]. However, that comment could be leveled at _any_ attempt to
rewrite the parser - after all, it's the parser that is the problem.
Your approach specifically _doesn't_ address Malcolm's concerns [2].

[3] http://groups.google.com/group/django-developers/msg/6e03c7c1a5b3d946

Your code also seems to be a moving target. My original impression was
that you were calling for a major review of a potentially trunk-ready
patch. Deeper reading revealed that there were potentially lots of
backwards incompatibilities. Reading subsequent messages reveals that
maybe those backwards incompatibilities don't exist any more. At this
point, I'm straight up confused as to the state of this patch - is it
trunk ready, or a work in progress? Are you looking for a design
review or a final review? If it's a design review, what aspects of the
design do you want feedback on?

Reviewing this code will be a big job. If you want this to move
forward, you need to make it easy and obvious for me (and/or the other
core developers) to make the decision to commit to reviewing your
code. This is one of those situations that has almost nothing to do
with the code, and everything to do with effective communication. What
have you done? Why have you done it that way? What alternatives did
you consider? What tradeoffs exist? What potential problems exists?

You need to convince me that it's worth spending the time to review
your code. You don't have an extensive collection of smaller patches
or a history of engaging in design discussions on django-dev, so all I
can use to establish your code design credentials is your ability to
communicate your ideas about this ticket on the mailing list. If I
have to spend a lot of time working out what is going on before I even
get to the code, that doesn't bode well.

Again - please don't be discouraged. I want to see the template system
improved. If you're sufficiently enthused to pursue the topic, I
encourage you to do so. But you need to effectively communicate what
you have done along the way.

Yours,
Russ Magee %-)

--~--~---------~--~----~------------~-------~--~----~
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