Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #71503 > unrolled thread

Exception problem with module

Started by"Joseph L. Casale" <jcasale@activenetwerx.com>
First post2014-05-13 16:59 +0000
Last post2014-05-19 23:48 +0000
Articles 6 — 3 participants

Back to article view | Back to comp.lang.python


Contents

  Exception problem with module "Joseph L. Casale" <jcasale@activenetwerx.com> - 2014-05-13 16:59 +0000
    Re: Exception problem with module Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-05-14 00:02 +0000
      RE: Exception problem with module "Joseph L. Casale" <jcasale@activenetwerx.com> - 2014-05-14 09:21 +0000
        Re: Exception problem with module Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-05-14 13:08 +0000
          Re: Exception problem with module Chris Angelico <rosuav@gmail.com> - 2014-05-14 23:17 +1000
          RE: Exception problem with module "Joseph L. Casale" <jcasale@activenetwerx.com> - 2014-05-19 23:48 +0000

#71503 — Exception problem with module

From"Joseph L. Casale" <jcasale@activenetwerx.com>
Date2014-05-13 16:59 +0000
SubjectException problem with module
Message-ID<mailman.9975.1400000510.18130.python-list@python.org>
I am working with a module that I am seeing some odd behavior.

A module.foo builds a custom exception, module.foo.MyError, its done right
afaict.

Another module, module.bar imports this and calls bar.__setattr__('a_new_name', MyError).

Now, not in all but in some cases when I catch a_new_name, my code raises a new
exception:

During handling of the above exception, another exception occurred:

  File "C:/dir/test.py", line 12, in <module>
    except a_new_name as exc:
TypeError: catching classes that do not inherit from BaseException is not allowed

So, I wont suggest the assignment in bar added anything, nor would I do this, but
its what I am working with. Why might this happen? MyError subclasses Exception
and calls super passing back args.

This has something to do with the assignment in bar, catching MyError obviously works.

Any ideas?
jlc

[toc] | [next] | [standalone]


#71516

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2014-05-14 00:02 +0000
Message-ID<5372b2ae$0$29977$c3e8da3$5496439d@news.astraweb.com>
In reply to#71503
On Tue, 13 May 2014 16:59:46 +0000, Joseph L. Casale wrote:

> I am working with a module that I am seeing some odd behavior.
> 
> A module.foo builds a custom exception, module.foo.MyError, its done
> right afaict.
> 
> Another module, module.bar imports this and calls
> bar.__setattr__('a_new_name', MyError).

I see that you've solved your immediate problem, but you shouldn't call 
__setattr__ directly. That should actually be written

    setattr(bar, 'a_new_name', MyError)

But really, since bar is (apparently) a module, and it is *bar itself* 
setting the attribute, the better way is

a_new_name = MyError

or even 

from module.foo import MyError as a_new_name



-- 
Steven D'Aprano
http://import-that.dreamwidth.org/

[toc] | [prev] | [next] | [standalone]


#71542

From"Joseph L. Casale" <jcasale@activenetwerx.com>
Date2014-05-14 09:21 +0000
Message-ID<mailman.9994.1400059319.18130.python-list@python.org>
In reply to#71516
> I see that you've solved your immediate problem, but you shouldn't call 
> __setattr__ directly. That should actually be written
>
>     setattr(bar, 'a_new_name', MyError)
>
> But really, since bar is (apparently) a module, and it is *bar itself* 
> setting the attribute, the better way is
>
> a_new_name = MyError
>
> or even 
>
> from module.foo import MyError as a_new_name

Well I am not sure what advantage this has for the user, not my code as
I don't advocate the import to begin with it, its fine spelled as it was from
where it was... I'll look back at this and see if that resolves the issue as it
had manifested.

jlc

[toc] | [prev] | [next] | [standalone]


#71555

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2014-05-14 13:08 +0000
Message-ID<53736acb$0$29977$c3e8da3$5496439d@news.astraweb.com>
In reply to#71542
On Wed, 14 May 2014 09:21:50 +0000, Joseph L. Casale wrote:

>> I see that you've solved your immediate problem, but you shouldn't call
>> __setattr__ directly. That should actually be written
>>
>>     setattr(bar, 'a_new_name', MyError)
>>
>> But really, since bar is (apparently) a module, and it is *bar itself*
>> setting the attribute, the better way is
>>
>> a_new_name = MyError
>>
>> or even
>>
>> from module.foo import MyError as a_new_name
> 
> Well I am not sure what advantage this has for the user, not my code as
> I don't advocate the import to begin with it, its fine spelled as it was
> from where it was... 

The advantage for the user is:

- it avoids module bar needing to get a reference to itself;

- it avoids the distraction of unnecessarily calling a dunder
  method;

- it is idiomatic Python code that should be instantly 
  understandable by any even moderately experienced 
  Python coder;

- prevents the reader from puzzling over why the code does
  something so unusual ("but why does he do this...?");

- and avoids the inevitable anger and/or contempt when the
  reader works out that there is no good reason to write 
  such unidiomatic code.

One should code as if the next person who reads your program is an easily 
upset psychotic axe-murderer who knows where you live. You wouldn't 
condone writing y = x.__add__(1) instead of y = x + 1, you shouldn't 
condone writing module.__setattr__ directly either.


> I'll look back at this and see if that resolves the
> issue as it had manifested.

I doubt it. Not unless module bar has done something weird, like define a 
function called __setattr__ that shadows the actual method and wraps the 
exception in another object. More likely, I think you'll find that the 
original MyError doesn't inherit from Exception.




-- 
Steven D'Aprano
http://import-that.dreamwidth.org/

[toc] | [prev] | [next] | [standalone]


#71557

FromChris Angelico <rosuav@gmail.com>
Date2014-05-14 23:17 +1000
Message-ID<mailman.10005.1400073467.18130.python-list@python.org>
In reply to#71555
On Wed, May 14, 2014 at 11:08 PM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> One should code as if the next person who reads your program is an easily
> upset psychotic axe-murderer who knows where you live. You wouldn't
> condone writing y = x.__add__(1) instead of y = x + 1, you shouldn't
> condone writing module.__setattr__ directly either.

Oddly enough, I was referencing that first half earlier this evening :)

There's a difference between x.__add__(1) and x + 1, though. The
latter might end up calling (1).__radd__(x), which (obviously) the
first won't. I can imagine there might be some use-case where you
specifically DON'T want the reflected method to be silently called
(maybe for introspection or debugging??). But it falls under code
smell, the sort of thing where you absolutely MUST have a comment -
like where I have a call to set_foreground(bg), because that could so
easily be an error, yet in this case isn't.

ChrisA

[toc] | [prev] | [next] | [standalone]


#71779

From"Joseph L. Casale" <jcasale@activenetwerx.com>
Date2014-05-19 23:48 +0000
Message-ID<mailman.10144.1400543373.18130.python-list@python.org>
In reply to#71555
>> Well I am not sure what advantage this has for the user, not my code as
>> I don't advocate the import to begin with it, its fine spelled as it was
>> from where it was... 
>
> The advantage for the user is:

/snip

Hey Steven,
Sorry for the late reply (travelling). My comment wasn't clear, I was ranting against
the import of the exception in the second module, non the less how it was imported
and not why it was not ok.

Basically, it was no better than leaving it where it was, spelled as it was and
requiring the user to import it from where it was defined. It turned out to be
some faulty logic in the second module where the __setattr__ call was made
that was preventing it from being set...

jlc

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web