Re: Consistent exception handling in templates.

2011-07-08 Thread Tai Lee


On Jul 9, 12:24 pm, Karen Tracey  wrote:
> I'm strongly against that idea. Swallowing errors makes it incredibly
> difficult to debug errors. I would prefer for the `TEMPLATE_DEBUG` setting to
> turn off much of the error-silencing currently done in template processing.
> Yes, that means different behavior during development compared to
> production. But running with DEBUG (template or otherwise) on IS different
> from production, that's a given. And it this case it would allow for more
> effective development since errors wouldn't be hidden away in nearly
> impossible-to-find places. In my mind that's a tradeoff well worth making.
>
> See ticket #13167 for one example of where "template errors" have not been
> silenced since before 1.0. If that case is to be be "fixed" now, I would
> very much want that silencing to ONLY happen when TEMPLATE_DEBUG is False.
> In my opinion silencing these during development would be a huge step
> backwards.

I think we are in agreement here. Swallowing errors makes it
incredible difficult to debug errors. I would like to see the
circumstances when exceptions are swallowed be more clearly defined,
and ensure that only exceptions that are expected to be swallowed, are
swallowed. If we can do that, then there should be no need for the
behaviour to change based on the `TEMPLATE_DEBUG` setting.

The problem with the inconsistent behaviour associated with this
setting is exceptions that are expected to be swallowed, that we want
to be swallowed, are not being swallowed in some cases when
`TEMPLATE_DEBUG = True`. This can make it impossible to access some
URLs on a website where such a condition is present, even though there
is no actual error and the exception is expected to be silenced. It
also results in some exceptions being transformed into
`TemplateSyntaxError` sometimes, and the true exception raised other
times.

See ticket #16147 for an example where `TemplateDoesNotExist` is
raised when the template DOES exist, because a template tag inside the
template being loaded raises `TemplateDoesNotExist` at compile time,
only when `TEMPLATE_DEBUG = True`.

This can make it impractical to develop locally with `TEMPLATE_DEBUG =
True`, because it can prevent access to working pages, which means you
miss out on all the enhanced debugging that `TEMPLATE_DEBUG = True`
provides when you encounter an actual error that needs developer
attention.

With the intent being that template authors should not be able to
trigger HTTP 500 errors on a production site, couldn't we achieve that
by silencing exceptions raised when an invalid argument was passed to
a template tag (e.g. `ValueError` or `TypeError` in the template tag
code), but allowing exceptions raised in the code for the object that
was passed in to the template tag as an argument?

For example, if an object that calculates and returns a number when
evaluated is passed to `{% widthratio %}`, but there is a bug in the
code of that object and it raises some kind of exception when
evaluated, that should not be silenced. It should bubble up so that
the developer is alerted to a problem in the code for that object (not
an error that the template author has made by passing an invalid
argument). However, if there was no exception raised in evaluating the
object, but it simply returned something other than a number, then
that should behave the same as if an empty string or missing template
variable was passed in and no exception should be raised.

I think that a `TemplateSyntaxError` should be raised at compile time
if an invalid template tag is used (unknown, too few or too many
arguments). The `render()` function for a template tag should silence
exceptions raised when arguments with the incorrect type or value are
provided, but should not silence exceptions raised when evaluating the
arguments themselves (or properties on the arguments).

Cheers.
Tai.

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



Re: Consistent exception handling in templates.

2011-07-08 Thread Karen Tracey
On Fri, Jul 8, 2011 at 9:55 PM, Tai Lee  wrote:

> Secondly, there is the inconsistent behaviour between production and
> development environments related to the `TEMPLATE_DEBUG` setting. I
> think that if an exception is intentionally silenced in production, it
> should also be intentionally silenced with `TEMPLATE_DEBUG = True`, to
> allow for consistent behaviour during development.
>

I'm strongly against that idea. Swallowing errors makes it incredibly
difficult to debug errors. I would prefer for the TEMPLATE_DEBUG setting to
turn off much of the error-silencing currently done in template processing.
Yes, that means different behavior during development compared to
production. But running with DEBUG (template or otherwise) on IS different
from production, that's a given. And it this case it would allow for more
effective development since errors wouldn't be hidden away in nearly
impossible-to-find places. In my mind that's a tradeoff well worth making.

See ticket #13167 for one example of where "template errors" have not been
silenced since before 1.0. If that case is to be be "fixed" now, I would
very much want that silencing to ONLY happen when TEMPLATE_DEBUG is False.
In my opinion silencing these during development would be a huge step
backwards.

Karen

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



Re: Consistent exception handling in templates.

2011-07-08 Thread Tai Lee


On Jul 8, 11:31 pm, Jacob Kaplan-Moss  wrote:
> > [...] but some of Django's own template tags (e.g. `widthratio`) don't 
> > adhere to
> > this policy.
>
> These are bugs, and should be fixed.

Thanks for this clarification. I will try to review the built-in tags
and submit some patches to fix these bugs. For added clarity, should a
template tag behave the same when a string or variable is passed as
it's argument?

E.g. if the first argument to a template tag is expected to be a
number, we can validate that and raise a `TemplateSyntaxError` at
compile time if it is passed in as a literal, but we can only validate
it and fail silently at render time if it is passed in as a template
variable. I believe that this behaviour is inconsistent and confusing,
and can lead to unexpected and difficult to trace problems.

To avoid this, should the validation of arguments to template tags
that can be passed in as either literals or template variables be
limited to checking that an argument was passed, and delay type or
value checking until render time, which will always fail silently?


> I'm against this, for a whole host of reasons — the crux of which
> comes down to the philosophy that templates are *not* a programming
> language, and introducing a try/except concept into them is about
> seven steps too far.
>
> The point of the template language is to give front end designers and
> developers the space to explore without the persnicketiness a
> so-called "real" programming language introduces. What you're asking
> for here is to fundamentally change the philosophy of the template
> language. If you disagree that fundamentally with the ideas behind the
> template language I really think you'll be better off finding another
> one than trying to swim upstream.

I agree that what I suggested would be a fundamental change, and not
likely to be adopted in full. However, I would still like to hear
other ideas from the community about smaller steps that we could take
that would make exception handling more consistent and selective,
without changing the fundamental philosophy of the template language.

Firstly, Jonathan Slenders makes the point that perhaps not ALL
exceptions should be silenced.

Secondly, there is the inconsistent behaviour between production and
development environments related to the `TEMPLATE_DEBUG` setting. I
think that if an exception is intentionally silenced in production, it
should also be intentionally silenced with `TEMPLATE_DEBUG = True`, to
allow for consistent behaviour during development.

If an exception IS worth raising when `TEMPLATE_DEBUG = True`, it
should also raise in production, and these types of exceptions should
be caused by an underlying problem in the template tag or the
evaluation of an object passed to the template tag, rather than
something that a template author is likely to trigger because they are
not programmers.

Does anybody else have ideas or suggestions about these two issues, or
other small improvements we could make to exception handling in
templates without fundamentally changing the philosophy of the
template language?

Cheers.
Tai

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



Re: Form Rendering API Proposal

2011-07-08 Thread Carl Meyer
Hi Chris,

On 07/08/2011 04:00 PM, Chris Beaven wrote:
> On Saturday, July 9, 2011 12:19:44 AM UTC+12, Gregor Müllegger wrote:
> [...] So we decided to skip changing a widget totally in the form
> rendering.
> Displaying a form and anything else that happens in the template has a
> representational purpose, so we saw it would be out of scope for the
> project.
> However changing the template that is used to render a widget will
> of course
> still be possible (also passing in extra arguments etc.)
> 
> 
> Fair enough, I understand the concern with giving HTML power over choice
> of rendered widget (not sure I totally agree, but concede that it's
> easier to not have to worry about it).

We can always revisit additional features later if needed, but scope
creep is a GSoC-killer.

I think most of the use cases for replacing widgets in the template are
really purely representational, they don't change the server-side data
handling at all. In cases where it would, the existing proposal was
already inadequate. And the majority of cases, when it wouldn't, can be
handled just by swapping in a different template; there's no need to
care about the widget class. If the form officially is using a TextInput
widget on the Python side and you swap in a template for that field that
renders a select dropdown, the Python code won't care; it still gets a
name and a value in request.POST.

> I guess this means that rendering a field as "hidden" in the template is
> also out, since this needs to modify more than just the field's
> representation (specifically, non_field_errors).

Yes. I mean, you're fully free to render a field as hidden yourself (via
template), but anytime you make a change in the HTML that implies any
change in server-side data handling, you're on your own to figure out
the right solution for your case (which is no different than now).

> Now that we drop the idea of exchanging widgets we also don't longer
> need the
> widgets template variable that holds the possible widget
> implementations you
> can drop in. But the formfields var would be left to decide cases like:
> 
> {% formconfig widget using "textarea.html" for formfields.CharField %} 
> 
>  [or]
> 
> {% formconfig widget using "textarea.html" for "CharField" %}
> 
> I'm not sure I see the importance of overriding a widget's template, to
> be honest. IMO it seems much more likely that you'll be worried with
> alternate rendering for different fields rather than all widgets.

Seems like there might be a small misunderstanding here. The shown
syntax is for overriding the widget template used for any instances of a
given _field_ type, not a given _widget_ type. I agree that a more
common use case is probably changing things up for a particular field in
your form, but having this allows the possibility of reusable form
layouts that can do interesting things with representations of
particular field types.

> btw I also plan to use "field" as argument for formconfig instead of
> "widget"
> to match more the {% form[row|field] %} tags:
> 
> {% formconfig field using "textarea.html" with placeholder="type here
> …" for "CharField" %}
> 
> I worry that we're introducing two meanings of what 'for' represents.
> Again, it seems to make more sense in my mind that it'd be in context of
> a field, not a widget.

I think it's actually pretty intuitive in practice that the operand of
"for" can be either the name of a specific field, or the name of a field
class. Ambiguity isn't an issue; specific field names take precedence
(and capitalization conventions should prevent ambiguity anyway). And
like I said above, I think the latter is useful for reusable form layouts.

> Now to your django-forms implementation that has the "extends"
> argument for
> the {% form %} tag. I still totally like the idea behind that, but
> like I
> already said in the other message -- it might be confusing to have two
> different meanings of the block tag. Carl has the same opinion here
> so we
> won't include that into our implementation.
> 
> (Note that 'extends' also applies the formconfig, row and field tags too)
> 
> I understand the potential for confusion, but I think it really does
> bring something big to the table which is unfortunate to miss out on.
> For example, if I just want to customize one field template on a form
> then without this I have to redefine the whole form template.
> It also allows for complex redefinition of a field's label and help text
> without having to redefine the entire field template.

Why would you otherwise have to redefine the whole form template? A form
template is a normal template; you can put blocks in it and have another
form template extend it and override those blocks. I don't think it's
onerous (in fact, I think it's clearer and more maintainable) to do this
in a separate file rather than "inline" as your proposal does. And I'

Re: Form Rendering API Proposal

2011-07-08 Thread Chris Beaven


On Saturday, July 9, 2011 12:19:44 AM UTC+12, Gregor Müllegger wrote:
>
> [...] So we decided to skip changing a widget totally in the form 
> rendering.
> Displaying a form and anything else that happens in the template has a
> representational purpose, so we saw it would be out of scope for the 
> project.
> However changing the template that is used to render a widget will of 
> course
> still be possible (also passing in extra arguments etc.)
>

Fair enough, I understand the concern with giving HTML power over choice of 
rendered widget (not sure I totally agree, but concede that it's easier to 
not have to worry about it).

I guess this means that rendering a field as "hidden" in the template is 
also out, since this needs to modify more than just the field's 
representation (specifically, non_field_errors).


> Now that we drop the idea of exchanging widgets we also don't longer need 
> the
> widgets template variable that holds the possible widget implementations 
> you
> can drop in. But the formfields var would be left to decide cases like:
>
> {% formconfig widget using "textarea.html" for formfields.CharField %} 
>
 [or]
>
{% formconfig widget using "textarea.html" for "CharField" %}
>
I'm not sure I see the importance of overriding a widget's template, to be 
honest. IMO it seems much more likely that you'll be worried with alternate 
rendering for different fields rather than all widgets.
 

> We justified it because this concept of matching a string to python 
> structure
> already exists. Examples are {% load mytemplatelib %} that loads a file 
> named
> after the argument, or some app.Model arguments used in third party libs.
>
That's a bit of a far-reaching justification, but I'm indifferent about the 
whole widget template bit of the proposal, so roll with whatever makes most 
sense.
 

> btw I also plan to use "field" as argument for formconfig instead of 
> "widget"
> to match more the {% form[row|field] %} tags:
>
> {% formconfig field using "textarea.html" with placeholder="type here
> …" for "CharField" %}
>
I worry that we're introducing two meanings of what 'for' represents. Again, 
it seems to make more sense in my mind that it'd be in context of a field, 
not a widget.
 

> Now to your django-forms implementation that has the "extends" argument for
> the {% form %} tag. I still totally like the idea behind that, but like I
> already said in the other message -- it might be confusing to have two
> different meanings of the block tag. Carl has the same opinion here so we
> won't include that into our implementation.
>
(Note that 'extends' also applies the formconfig, row and field tags too)

I understand the potential for confusion, but I think it really does bring 
something big to the table which is unfortunate to miss out on.
For example, if I just want to customize one field template on a form then 
without this I have to redefine the whole form template.
It also allows for complex redefinition of a field's label and help text 
without having to redefine the entire field template.

We're already bringing a new concept of inline sub-template definition via 
the 'using' argument.
I don't see that it's much more of a push to simultaneously introduce inline 
sub-template extension via the 'extends' argument.


Here's real-life example off the top of my head we had the other day. A 
client had a multi-step registration form. Usually, our rows show a * next 
to the label of required fields but all of the first step was required so 
the client didn't want the stars to show. I envision this would look like 
this in django-forms (lets assume we've customised 'forms/field/base.html' 
to conditionally conditionally change the label class or just conditionally 
add the * after it):

{% form form extends "forms/p.html" %}
{% block config %}
{% formconfig field with required=0 %}
{% endblock %}
{% endform %}

What would this look like with the current form proposal?

>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/django-developers/-/rkqDXMP8x6AJ.
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.



Re: Consistent exception handling in templates.

2011-07-08 Thread Jonas H.

On 07/08/2011 05:24 PM, Jonathan Slenders wrote:

My feeling is that we should silence TypeError, AttributeError and
KeyError in _resolve_lookup, but only when they occur one frame deep.


I agree with what you propose but AFAIK it's not easy to solve without 
doing frame analysis (I'd say that feature is not worth doing such 
hacks).  That's because of the way `hasattr` is implemented:


  def hasattr(obj, attr):
  try:
  getattr(obj, attr)
  return True
  except AttributeError:
  return False

This code directly mirrors the code found in CPython and implies that 
/hasattr "executes" properties/.


So there's no way to figure out whether an attribute exists without 
executing the code of properties.


Jonas

--
Django + MongoDB: http://django-mongodb.org

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



Re: Consistent exception handling in templates.

2011-07-08 Thread Jonathan Slenders
Something related I was wondering about...

Errors in templates should be silenced -- I agree with that -- but
only when they are caused by an error in the template.
Variable.resolve can fail silent because that's caused by the template
author, who is referring to non-existing variables.

However, sometimes, it happens to me that the template calls a
@property of some object, which acesses at his turn an non existing
attribute of another object. An AttributeError is raised, but because
that's somewhere in Variable.resolve, it's silently ignored. It's
clear that at that point, it's not something in the template, but a
hard-to-find bug in the @property.

My feeling is that we should silence TypeError, AttributeError and
KeyError in _resolve_lookup, but only when they occur one frame deep.

Maybe I am wrong here, it's also just an opinion, and I have no real
solution... (Except for writing better unit-tests for the application
logic.)

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



Re: Consistent exception handling in templates.

2011-07-08 Thread Jacob Kaplan-Moss
On Thu, Jul 7, 2011 at 8:37 PM, Tai Lee  wrote:
> The docs say that when writing custom template tags, the `render()`
> function should never raise `TemplateSyntaxError`, [...]

This rule is the correct one, and I'm very much against changing it.

> [...] but some of Django's own template tags (e.g. `widthratio`) don't adhere 
> to
> this policy.

These are bugs, and should be fixed.

> I'd like to see a move towards consistent exception handling in
> templates for template tags and filters. I'd like to see no exceptions
> silenced by default, but provide a way for template authors to
> conditionally silence exceptions in fragments of their templates.
> Perhaps with a block tag.

I'm against this, for a whole host of reasons — the crux of which
comes down to the philosophy that templates are *not* a programming
language, and introducing a try/except concept into them is about
seven steps too far.

The point of the template language is to give front end designers and
developers the space to explore without the persnicketiness a
so-called "real" programming language introduces. What you're asking
for here is to fundamentally change the philosophy of the template
language. If you disagree that fundamentally with the ideas behind the
template language I really think you'll be better off finding another
one than trying to swim upstream.

> Should built-in template tags follow the advice given in the docs, and
> never raise `TemplateSyntaxError` in their `render()` function?

Yes; the two instances you mentioned are bugs and should be fixed.

Jacob

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



Re: Form Rendering API Proposal

2011-07-08 Thread Gregor Müllegger
Hi Chris,

2011/6/29 Chris Beaven :
>>
>> I think thats conceptually not possible. We simply can change the widget
>> during
>> template rendering time, which makes it impossible to decide in the python
>> code with which widget we end up. And theoretically we could even render
>> the
>> form twice with different widgets. Or throw the rendered template away
>> without
>> using the widget at all.
>
> In this case, why do we even have this format: {% formconfig widget
> widgets.Textarea for "comment" %} and the terminology of widgets?
> It seems like that should really just boil down to {% formconfig field using
> "some/textarea.html" for "comment" %} and just referring to fields only. A
> widget to me encompasses the backend logic of decoding the data, etc.
> I think it'd be a great plus if we *could* make it work for different
> widgets. This would really give power to change forms dynamically at the
> template layer.
> I remember thinking a while ago about some kind of widget repository
> available to the templates, combined with a hidden input per field that
> could notify the python form of the alternate widget used (the hidden input
> only used if the widget differed than the default for that field). This
> would allow for the same form to be used with different templates which used
> completely different widgets.

So I spoke to Carl yesterday about some of the ideas you brought up and we
agreed on how we want to handle them :-)


You've mentioned if being able to change the widget in the template it would
be cool to let the python source also know which widget should then be used to
parse the data. My concern about this was that an HTML data value should not
be allowed to exchange code parts on the server. Sure we would limit that to
specific widget classes, but with that power in HTML you would be able to
break the server side code, either by being evil or not understanding widgets
in total.
The same of course is true if we just change the widget without letting the
python form know what is happening, this makes it also possible to break the
server … we talked then about what a widget actually is: It has two purposes,
first is parsing the data making it usable for the field, second is
representational -- rendering an HTML input that is compatible with the
widget's data format.

So we decided to skip changing a widget totally in the form rendering.
Displaying a form and anything else that happens in the template has a
representational purpose, so we saw it would be out of scope for the project.
However changing the template that is used to render a widget will of course
still be possible (also passing in extra arguments etc.)


Now that we drop the idea of exchanging widgets we also don't longer need the
widgets template variable that holds the possible widget implementations you
can drop in. But the formfields var would be left to decide cases like:

{% formconfig widget using "textarea.html" for formfields.CharField %}

We decided to drop that variable as well, replacing it with a string that can
match the class name of a field:

{% formconfig widget using "textarea.html" for "CharField" %}

We justified it because this concept of matching a string to python structure
already exists. Examples are {% load mytemplatelib %} that loads a file named
after the argument, or some app.Model arguments used in third party libs.
There might be the concern that "CharField" is ambiguous if some else also
implements a "CharField". But this might be even a feature … if someone
implements also a CharField it might be very similar to django's built-in
one, otherwise you would name it differently.

btw I also plan to use "field" as argument for formconfig instead of "widget"
to match more the {% form[row|field] %} tags:

{% formconfig field using "textarea.html" with placeholder="type here
…" for "CharField" %}


Now to your django-forms implementation that has the "extends" argument for
the {% form %} tag. I still totally like the idea behind that, but like I
already said in the other message -- it might be confusing to have two
different meanings of the block tag. Carl has the same opinion here so we
won't include that into our implementation.


Thanks a lot again for your input, it created some vital think processes for
me and resulted in good improvements on the proposal (hope you see it the
same). Keep posting.

--
Servus,
Gregor Müllegger

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