Re: ImportError catching in urlresolvers.py

2011-06-16 Thread Russell Keith-Magee
On Thu, Jun 16, 2011 at 3:09 PM, Bas Peschier  wrote:
> For reference, I added a patch to https://code.djangoproject.com/ticket/10802
> which takes Russell's approach.

Looks good to me! I've just marked to RFC. Thanks for the patch Bas!

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.



Re: ImportError catching in urlresolvers.py

2011-06-16 Thread Bas Peschier
For reference, I added a patch to https://code.djangoproject.com/ticket/10802
which takes Russell's approach.

-- 
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: ImportError catching in urlresolvers.py

2011-06-15 Thread Thomas Guettler
On 14.06.2011 22:19, Michael Blume wrote:
> In RegexURLPattern._get_callback, we attempt to fetch the callable named
> by the URL pattern, and catch a possible ImportError if this fails. If
> so, we raise ViewDoesNotExist.
> 
> try:
> self._callback = get_callable(self._callback_str)
> except ImportError, e:
> mod_name, _ = get_mod_func(self._callback_str)
> raise ViewDoesNotExist("Could not import %s. Error was: %s"
> % (mod_name, str(e)))

I uncomment the try...except part in my local django version (and the 
AttributeError). I want to see the original
exception. It would be nice to have a better solution in django. Maybe a 
settings variable CATCH_EXCEPTIONS?

  Thomas

-- 
Thomas Guettler, http://www.thomas-guettler.de/
E-Mail: guettli (*) thomas-guettler + de

-- 
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: ImportError catching in urlresolvers.py

2011-06-15 Thread Bas Peschier


On 15 jun, 07:36, Russell Keith-Magee  wrote:
> In this case, the underlying problem is that ImportError is actually
> catching 2 different errors:
>  1) The view specified doesn't exist
>  2) The module containing the view contains an error.

Agreed, in this case this information is lost in get_callable, where
the code does know the difference between 1) and 2), but the exception
raised does not convey that.

It might be a better idea to move the ViewDoesNotExist into the
get_callable function, which get triggered with an AttributeException
or an ImportError when the owning module can be imported. All other
conditions are not caught.

Bas

-- 
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: ImportError catching in urlresolvers.py

2011-06-14 Thread Russell Keith-Magee
On Wed, Jun 15, 2011 at 1:31 PM, burc...@gmail.com  wrote:
> Hi Russell,
>
> and what do you say about showing call stack properly?
>
> The problem is not ViewDoesNotExist itself, but throwing away useful 
> traceback.
>
> If we do instead:
>    import sys
>    try:
>        self._callback = get_callable(self._callback_str)
>    except ImportError, e:
>        mod_name, _ = get_mod_func(self._callback_str)
>        raise ViewDoesNotExist("Could not import %s. Error was: %s" %
> (mod_name, str(e))), None, sys.exc_info()[2]
>
> This way we will not only see not only exception where was required
> module that was not imported, but also how it was attempted to be
> imported -- often there's cyclic imports, few other imports or
> initializations causing other imports, which are hidden with simple
> raise.

To my mind, this isn't the right approach -- it's papering over the
problem, not fixing it.

In this case, the underlying problem is that ImportError is actually
catching 2 different errors:
 1) The view specified doesn't exist
 2) The module containing the view contains an error.

The current implementation catches both errors, and turns them into a
ViewDoesNotExist error. You don't fix this problem by providing better
stack trace information on a ViewDoesNotExist error -- you fix the
problem by actually separating the two errors, making (1) return
ViewDoesNotExist, and (2) return ImportError. That way, you'll get a
meaningful error message *and* reliable stack trace data.

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.



Re: ImportError catching in urlresolvers.py

2011-06-14 Thread burc...@gmail.com
Hi Russell,

and what do you say about showing call stack properly?

The problem is not ViewDoesNotExist itself, but throwing away useful traceback.

If we do instead:
import sys
try:
self._callback = get_callable(self._callback_str)
except ImportError, e:
mod_name, _ = get_mod_func(self._callback_str)
raise ViewDoesNotExist("Could not import %s. Error was: %s" %
(mod_name, str(e))), None, sys.exc_info()[2]

This way we will not only see not only exception where was required
module that was not imported, but also how it was attempted to be
imported -- often there's cyclic imports, few other imports or
initializations causing other imports, which are hidden with simple
raise.

Few exceptions wrappers patched in my fork:
https://github.com/buriy/django/commit/72b7a7350022a4a0a9cb1f01be62b117dedf89e2.

On Wed, Jun 15, 2011 at 11:46 AM, Russell Keith-Magee
 wrote:
> On Wed, Jun 15, 2011 at 11:51 AM, David Cramer  wrote:
>> This is currently a problem all over in the Django codebase, and I'd
>> love to see a generic/reusable approach at solving this everywhere.
>
> We already have a generic/reusable approach -- it's just not used
> everywhere that it could be used.
>
> Almost all the places that we are catching ImportError, we're using it
> as part of an implementation of module discovery or dynamic loading.
> In the case of RegexURLPattern, it's the resolution of a string-based
> view specification to a view callable. Catching ImportError is the
> easiest way to establish that a named module doesn't exist, and
> assuming that the code is otherwise sound, it's 100% accurate.
> However, that's a big assumption that doesn't play out in reality, and
> so "couldn't import module due to error in code" errors get confused
> with "module does not exist" errors, leading to the confusion reported
> by the original message.
>
> This is a case where we need to do better at eating our own dogfood.
> Wherever we are using the ImportError trick to catch 'specified module
> does not exist', we should be using a combination of
> django.utils.module_loading.module_has_submodule and
> django.utils.importlib.import_module. Any patch implementing this
> pattern (wherever it occurs) would be looked upon favourably for
> trunk.
>
> 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.
>
>



-- 
Best regards, Yuri V. Baburov, Skype: yuri.baburov, MSN: bu...@live.com

-- 
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: ImportError catching in urlresolvers.py

2011-06-14 Thread Russell Keith-Magee
On Wed, Jun 15, 2011 at 11:51 AM, David Cramer  wrote:
> This is currently a problem all over in the Django codebase, and I'd
> love to see a generic/reusable approach at solving this everywhere.

We already have a generic/reusable approach -- it's just not used
everywhere that it could be used.

Almost all the places that we are catching ImportError, we're using it
as part of an implementation of module discovery or dynamic loading.
In the case of RegexURLPattern, it's the resolution of a string-based
view specification to a view callable. Catching ImportError is the
easiest way to establish that a named module doesn't exist, and
assuming that the code is otherwise sound, it's 100% accurate.
However, that's a big assumption that doesn't play out in reality, and
so "couldn't import module due to error in code" errors get confused
with "module does not exist" errors, leading to the confusion reported
by the original message.

This is a case where we need to do better at eating our own dogfood.
Wherever we are using the ImportError trick to catch 'specified module
does not exist', we should be using a combination of
django.utils.module_loading.module_has_submodule and
django.utils.importlib.import_module. Any patch implementing this
pattern (wherever it occurs) would be looked upon favourably for
trunk.

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.



Re: ImportError catching in urlresolvers.py

2011-06-14 Thread David Cramer
This is currently a problem all over in the Django codebase, and I'd
love to see a generic/reusable approach at solving this everywhere.

On Jun 14, 1:19 pm, Michael Blume  wrote:
> In RegexURLPattern._get_callback, we attempt to fetch the callable named by
> the URL pattern, and catch a possible ImportError if this fails. If so, we
> raise ViewDoesNotExist.
>
>         try:
>             self._callback = get_callable(self._callback_str)
>         except ImportError, e:
>             mod_name, _ = get_mod_func(self._callback_str)
>             raise ViewDoesNotExist("Could not import %s. Error was: %s" %
> (mod_name, str(e)))
>
> The trouble is that the view we're importing may indeed exist, and may
> *itself* make a failed import (say of a model, or some library function), in
> which case ViewDoesNotExist becomes a badly misleading exception name, and
> the resulting traceback is cut unhelpfully short. I've noodled a bit trying
> to come up with a patch, but been stymied by the lack of information bubbled
> up by python's ImportError extension (at least in 2.6).
>
> Personally, I don't think catching ImportError/raising ViewDoesNotExist adds
> much value (we do catch it once in contrib/admindocs/views), so unless we
> can come up with a way to ensure that it only triggers when the top-level
> import fails, I'd recommend eliminating it.

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



ImportError catching in urlresolvers.py

2011-06-14 Thread Michael Blume
In RegexURLPattern._get_callback, we attempt to fetch the callable named by
the URL pattern, and catch a possible ImportError if this fails. If so, we
raise ViewDoesNotExist.

try:
self._callback = get_callable(self._callback_str)
except ImportError, e:
mod_name, _ = get_mod_func(self._callback_str)
raise ViewDoesNotExist("Could not import %s. Error was: %s" %
(mod_name, str(e)))

The trouble is that the view we're importing may indeed exist, and may
*itself* make a failed import (say of a model, or some library function), in
which case ViewDoesNotExist becomes a badly misleading exception name, and
the resulting traceback is cut unhelpfully short. I've noodled a bit trying
to come up with a patch, but been stymied by the lack of information bubbled
up by python's ImportError extension (at least in 2.6).

Personally, I don't think catching ImportError/raising ViewDoesNotExist adds
much value (we do catch it once in contrib/admindocs/views), so unless we
can come up with a way to ensure that it only triggers when the top-level
import fails, I'd recommend eliminating it.

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