473,659 Members | 3,494 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

@property decorator doesn't raise exceptions

Hi,

I've encountered a problem which is making debugging less obvious than
it should be. The @property decorator doesn't always raise exceptions.
It seems like it is bound to the class but ignored when called. I can
see the attribute using dir(self.__clas s__) on an instance, but when
called, python enters __getattr__. If I correct the bug, the attribute
calls work as expected and do not call __getattr__.

I can't seem to make a simple repro. Can anyone offer any clues as to
what might cause this so I can try to prove it?
Cheers,

- Rafe
Oct 24 '08 #1
14 4339
Rafe wrote:
Hi,

I've encountered a problem which is making debugging less obvious than
it should be. The @property decorator doesn't always raise exceptions.
It seems like it is bound to the class but ignored when called. I can
see the attribute using dir(self.__clas s__) on an instance, but when
called, python enters __getattr__. If I correct the bug, the attribute
calls work as expected and do not call __getattr__.

I can't seem to make a simple repro. Can anyone offer any clues as to
what might cause this so I can try to prove it?
You must subclass from "object" to get a new style class. properties
don't work correctly on old style classes.

Christian

Oct 24 '08 #2
On Oct 24, 2:21 am, Christian Heimes <li...@cheimes. dewrote:
Rafewrote:
Hi,
I've encountered a problem which is making debugging less obvious than
it should be. The @property decorator doesn't always raise exceptions.
It seems like it is bound to the class but ignored when called. I can
see the attribute using dir(self.__clas s__) on an instance, but when
called, python enters __getattr__. If I correct the bug, the attribute
calls work as expected and do not call __getattr__.
I can't seem to make a simple repro. Can anyone offer any clues as to
what might cause this so I can try to prove it?

You must subclass from "object" to get a new style class. properties
don't work correctly on old style classes.

Christian
All classes are a sub-class of object. Any other ideas?

- Rafe
Oct 24 '08 #3
Rafe wrote:
On Oct 24, 2:21 am, Christian Heimes <li...@cheimes. dewrote:
>Rafewrote:
Hi,
I've encountered a problem which is making debugging less obvious than
it should be. The @property decorator doesn't always raise exceptions.
It seems like it is bound to the class but ignored when called. I can
see the attribute using dir(self.__clas s__) on an instance, but when
called, python enters __getattr__. If I correct the bug, the attribute
calls work as expected and do not call __getattr__.
I can't seem to make a simple repro. Can anyone offer any clues as to
what might cause this so I can try to prove it?

You must subclass from "object" to get a new style class. properties
don't work correctly on old style classes.

Christian

All classes are a sub-class of object. Any other ideas?
Hard to tell when you don't give any code.
>>class A(object):
.... @property
.... def attribute(self) :
.... raise AttributeError
.... def __getattr__(sel f, name):
.... return "nobody expects the spanish inquisition"
....
>>A().attribu te
'nobody expects the spanish inquisition'

Do you mean something like this? I don't think the __getattr__() call can be
avoided here.

Peter
Oct 24 '08 #4
On Fri, 24 Oct 2008 09:34:36 -0700, Rafe wrote:
>You must subclass from "object" to get a new style class. properties
don't work correctly on old style classes.

Christian

All classes are a sub-class of object. Any other ideas?
Only in Python 3. If you are relying on that to be true in Python 2.x,
you're going to disappointed:
>>class A():
.... pass
....
>>issubclass( A, object)
False
There are a lot of classic classes in the standard library. If you
inherit from them, your class will also be a classic class and properties
will fail to work correctly.
Earlier, you wrote:

"I've encountered a problem which is making debugging less obvious than
it should be. The @property decorator doesn't always raise exceptions."

Are you expecting it to raise an exception when the class is defined, or
when the property is called? e.g.

class Fail(object):
@property
"this should raise an exception"

Works for me -- I get a syntax error, as expected.
"It seems like it is bound to the class but ignored when called. I can
see the attribute using dir(self.__clas s__) on an instance, but when
called, python enters __getattr__. If I correct the bug, the attribute
calls work as expected and do not call __getattr__."
Perhaps you can give us a minimal example showing the code with the bug,
then how you corrected the bug? That might give as a hint as to what is
going on. I know that's hard, when you can't reproduce the problem, but
it's just as hard for us to solve your problem without more information.

--
Steven
Oct 24 '08 #5
On Fri, 24 Oct 2008 01:47:10 -0700, Rafe wrote:
Hi,

I've encountered a problem which is making debugging less obvious than
it should be. The @property decorator doesn't always raise exceptions.
I don't think that's the problem. I think properties do correctly raise
all exceptions that occur inside them, at least built-in exceptions.

I wrote a test that raises exceptions inside properties and they (almost)
all are raised normally.

Whatever your problem is, it isn't that properties don't raise exceptions.

For those who are interested, the test program I used follows.
# test module

def get_exceptions( ):
import __builtin__
list_of_excepti ons = []
for key in dir(__builtin__ ):
# do not use __builtins__ -- note the 's'.
obj = getattr(__built in__, key)
if not isinstance(obj, type):
continue
if issubclass(obj, Exception):
list_of_excepti ons.append(obj)
return list_of_excepti ons

def builder(list_of _exceptions):
class PropertyTester( object):
"""Do properties raise exceptions? Let's find out."""
for exception in list_of_excepti ons:
name = exception.__nam e__
@property
def func(self, exception=excep tion):
# Make sure we bind a local copy to exception.
raise exception
setattr(Propert yTester, name, func)
return PropertyTester( )

def testRaises(obj, exception_type, verbose):
"""Test that appropriate exception is raised when accessing an
attribute."""
name = exception_type. __name__
try:
getattr(obj, name)
except exception_type:
if verbose:
print "Passed: expected exception %s raised correctly" \
% exception_type
except Exception, e:
print "Failed: expected %s but got %r" % (exception_type , e)
else:
print "Failed: expected %s but got no exception at all" \
% exception_type

if __name__ == '__main__':
import sys
if sys.argv[1:] == ['verbose']:
verbose = True
else:
verbose = False
exceptions = get_exceptions( )
tester = builder(excepti ons)
for exception in exceptions:
testRaises(test er, exception, verbose)

--
Steven
Oct 25 '08 #6
On Oct 24, 9:58*am, Peter Otten <__pete...@web. dewrote:
Rafe wrote:
On Oct 24, 2:21 am, Christian Heimes <li...@cheimes. dewrote:
Rafewrote:
Hi,
I've encountered a problem which is making debugging less obvious than
it should be. The @property decorator doesn't always raise exceptions.
It seems like it is bound to the class but ignored when called. I can
see the attribute using dir(self.__clas s__) on an instance, but when
called, python enters __getattr__. If I correct the bug, the attribute
calls work as expected and do not call __getattr__.
I can't seem to make a simple repro. Can anyone offer any clues as to
what might cause this so I can try to prove it?
You must subclass from "object" to get a new style class. properties
don't work correctly on old style classes.
Christian
All classes are a sub-class of object. Any other ideas?

Hard to tell when you don't give any code.
>class A(object):

... * * @property
... * * def attribute(self) :
... * * * * * * raise AttributeError
... * * def __getattr__(sel f, name):
... * * * * * * return "nobody expects the spanish inquisition"
...>>A().attrib ute

'nobody expects the spanish inquisition'

Do you mean something like this? I don't think the __getattr__() call canbe
avoided here.

Peter
You nailed it Peter! I thought __getattr__ was a symptom, not the
cause of the misleading errors. Here is the repro (pretty much
regurgitated):

The expected behavior...
>>class A(object):
.... @property
.... def attribute(self) :
.... raise AttributeError( "Correct Error.")
>>A().attribu te
Traceback (most recent call last):
File "<console>" , line 0, in <module>
File "<console>" , line 0, in attribute
AttributeError: Correct Error.
The unexpected and misleading exception...
>>class A(object):
.... @property
.... def attribute(self) :
.... raise AttributeError( "Correct Error.")
.... def __getattr__(sel f, name):
.... cls_name = self.__class__. __name__
.... msg = "%s has no attribute '%s'." % (cls_name, name)
.... raise AttributeError( msg)
Traceback (most recent call last):
File "<console>" , line 0, in <module>
File "<console>" , line 0, in __getattr__
AttributeError: A has no attribute 'attribute'.
The docs state:
"Called when an attribute lookup has not found the attribute in the
usual places (i.e. it is not an instance attribute nor is it found in
the class tree for self). name is the attribute name. This method
should return the (computed) attribute value or raise an
AttributeError exception."

Can anyone explain why this is happening? I can hack a work-around,
but even then I could use some tips on how to raise the 'real'
exception so debugging isn't guesswork.
Cheers,

- Rafe
Oct 25 '08 #7
On Oct 24, 9:58*am, Peter Otten <__pete...@web. dewrote:
Rafe wrote:
On Oct 24, 2:21 am, Christian Heimes <li...@cheimes. dewrote:
Rafewrote:
Hi,
I've encountered a problem which is making debugging less obvious than
it should be. The @property decorator doesn't always raise exceptions.
It seems like it is bound to the class but ignored when called. I can
see the attribute using dir(self.__clas s__) on an instance, but when
called, python enters __getattr__. If I correct the bug, the attribute
calls work as expected and do not call __getattr__.
I can't seem to make a simple repro. Can anyone offer any clues as to
what might cause this so I can try to prove it?
You must subclass from "object" to get a new style class. properties
don't work correctly on old style classes.
Christian
All classes are a sub-class of object. Any other ideas?

Hard to tell when you don't give any code.
>class A(object):

... * * @property
... * * def attribute(self) :
... * * * * * * raise AttributeError
... * * def __getattr__(sel f, name):
... * * * * * * return "nobody expects the spanish inquisition"
...>>A().attrib ute

'nobody expects the spanish inquisition'

Do you mean something like this? I don't think the __getattr__() call canbe
avoided here.

Peter

Peter nailed it, thanks! I thought __getattr__ was a symptom, not a
cause of the misleading exceptions. Here is a complete repro:
The expected behavior...
>>class A(object):
.... @property
.... def attribute(self) :
.... raise AttributeError( "Correct Error.")
>>A().attribu te
Traceback (most recent call last):
File "<console>" , line 0, in <module>
File "<console>" , line 0, in attribute
AttributeError: Correct Error.
The misleading/unexpected behavior...
>>class A(object):
.... @property
.... def attribute(self) :
.... raise AttributeError( "Correct Error.")
.... def __getattr__(sel f, name):
.... cls_name = self.__class__. __name__
.... msg = "%s has no attribute '%s'." % (cls_name, name)
.... raise AttributeError( msg)
>>A().attribu te
Traceback (most recent call last):
File "<console>" , line 0, in <module>
File "<console>" , line 0, in __getattr__
AttributeError: A has no attribute 'attribute'.
Removing @property works as expected...
>>class A(object):
.... def attribute(self) :
.... raise AttributeError( "Correct Error.")
.... def __getattr__(sel f, name):
.... cls_name = self.__class__. __name__
.... msg = "%s has no attribute '%s'." % (cls_name, name)
.... raise AttributeError( msg)
>>A().attribute () # Note the '()'
Traceback (most recent call last):
File "<console>" , line 0, in <module>
File "<console>" , line 0, in attribute
AttributeError: Correct Error.
The docs seem to suggest this is impossible:
"Called when an attribute lookup has not found the attribute in the
usual places (i.e. it is not an instance attribute nor is it found in
the class tree for self). name is the attribute name. This method
should return the (computed) attribute value or raise an
AttributeError exception."

Can anyone explain why this is happening? Is it a bug? I can write a
workaround to detect this by comparing the attribute name passed
__getattr__ with dir(self.__clas s__) = self.__dict__.k eys(), but how
can I raise the expected exception?
Thanks,

- Rafe
Oct 25 '08 #8
Rafe wrote:
The docs seem to suggest this is impossible:
"Called when an attribute lookup has not found the attribute in the
usual places (i.e. it is not an instance attribute nor is it found in
the class tree for self).
Getting an AttributeError is the way that the interpreter
machinery tells that the attribute wasn't found. So when
your property raises an AttributeError, this is
indistinguishab le from the case where the property wasn't
there at all.

To avoid this you would have to raise some exception
that doesn't derive from AttributeError.

--
Greg
Oct 26 '08 #9
On Oct 24, 1:47*am, Rafe <rafesa...@gmai l.comwrote:
Hi,

I've encountered a problem which is making debugging less obvious than
it should be. The @property decorator doesn't always raise exceptions.
It seems like it is bound to the class but ignored when called. I can
see the attribute using dir(self.__clas s__) on an instance, but when
called, python enters __getattr__. If I correct the bug, the attribute
calls work as expected and do not call __getattr__.

I can't seem to make a simple repro. Can anyone offer any clues as to
what might cause this so I can try to prove it?

Cheers,

- Rafe

Peter Oten pointed me in the right direction. I tried to reply to his
post 2 times and in spite of GoogleGroups reporting the post was
successful, it never showed up. Here is the repro:

The expected behavior...
>>class A(object):
.... @property
.... def attribute(self) :
.... raise AttributeError( "Correct Error.")
>>A().attribu te
Traceback (most recent call last):
File "<console>" , line 0, in <module>
File "<console>" , line 0, in attribute
AttributeError: Correct Error.
The misleading/unexpected behavior...
>>class A(object):
.... @property
.... def attribute(self) :
.... raise AttributeError( "Correct Error.")
.... def __getattr__(sel f, name):
.... cls_name = self.__class__. __name__
.... msg = "%s has no attribute '%s'." % (cls_name, name)
.... raise AttributeError( msg)
>>A().attribu te
Traceback (most recent call last):
File "<console>" , line 0, in <module>
File "<console>" , line 0, in __getattr__
AttributeError: A has no attribute 'attribute'.
Removing @property works as expected...
>>class A(object):
.... def attribute(self) :
.... raise AttributeError( "Correct Error.")
.... def __getattr__(sel f, name):
.... cls_name = self.__class__. __name__
.... msg = "%s has no attribute '%s'." % (cls_name, name)
.... raise AttributeError( msg)
>>A().attribute () # Note the '()'
Traceback (most recent call last):
File "<console>" , line 0, in <module>
File "<console>" , line 0, in attribute
AttributeError: Correct Error.
I never suspected __getattr__ was the cause and not just a symptom.
The docs seem to indicate __gettattr__ should never be called when the
attribute exisits in the class:
"Called when an attribute lookup has not found the attribute in the
usual places (i.e. it is not an instance attribute nor is it found in
the class tree for self). name is the attribute name. This method
should return the (computed) attribute value or raise an
AttributeError exception."

Is this a bug? Any idea why this happens? I can write a hack in to
__getattr__ in my class which will detect this, but I'm not sure how
to raise the expected exception.
Cheers,

- Rafe
Oct 26 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
2020
by: Andrew | last post by:
Hi, To satisfy my curiosity I was wondering if anyone knew if this behaviour was intentional? Is there a specific reason why exceptions are not allowed to be new style classes? Python 2.3 (#46, Jul 29 2003, 18:54:32) on win32 >>> class OldException: pass >>> raise OldException()
1
1592
by: Dominic | last post by:
Just in case someone is interested. I came up with this solution since my previous posting. Maybe you've got some other ideas or critcism. I'll listen ;-) Ciao, Dominic P.S. Python is really powerful!
2
1675
by: Jeffrey Froman | last post by:
Consider the following class: class Node(object): def __init__(self, name, parent=None): self.name = name self.parent = parent def _ancestors(self, ants=None): if ants is None: ants =
2
2375
by: Torsten Bronger | last post by:
Hallöchen! I write a module, and so I must raise exceptions at several points. The PEP 8 says that a module should define their own exceptions base class, derived from "Exception", and derivatives of that. However, the build-in exceptions cover most of the error types that occur in a standard program. For example, my module communicates with measurement instruments, so any communication error would fit perfectly to the build-in...
2
2544
by: Sam Miller | last post by:
Normally the debugger (visual studio .net environment) is good at pointing out the line of code that caused an exception.... except when that code is executed as part of a timer handler. In the case of the code below the exception is handled by a little dialog that tries to tell me how to switch on jitDebugging. (which, if I am doing it correctly doesn't seem to help). All three options are checked under...
5
1204
by: Thomas Lotze | last post by:
Hi, I wonder how to solve the following problem the most pythonic way: Suppose you have a function f which, as part of its protocol, raises some standard exception E under certain, well-defined circumstances. Suppose further that f calls other functions which may also raise E. How to best distinguish whether an exception E raised by f has the meaning defined by the protocol or just comes from details of the implementation?
4
1569
by: Alex G | last post by:
Does anyone know how I would go about conditionally raising an exception in a decorator (or any returned function for that matter)? For example: def decorator(arg): def raise_exception(fn): raise Exception return raise_exception class some_class(object):
0
922
by: Ben Finney | last post by:
Daniel <millerdev@gmail.comwrites: The fact that the 'property' function works as a decorator (in, as you point out, some cases only) is a happy accident. The 'property' function isn't *designed* to be used as a decorator, it just happens to work that way.
8
2733
by: Bryan | last post by:
I want my business objects to be able to do this: class Person(base): def __init__(self): self.name = None @base.validator def validate_name(self): if not self.name: return
0
8337
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8851
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8628
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6181
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5650
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4175
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
2754
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1978
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1739
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.