473,385 Members | 1,863 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

getattr() woes

Hello

I've found out about a fundamental problem of attribute lookup, the
hard way.

asyncore.py uses the following code:

class dispatcher:
# ...
def __getattr__(self, attr):
return getattr(self.socket, attr)

Now suppose that I'm asking for some attribute not provided by
dispatcher: The lookup mechanism will apparently try to find it
directly and fail, generating an AttributeError; next it will call
__getattr__ to find the attribute. So far, no problems.

But I used a property much like this:
import asyncore
class Peer(asyncore.dispatcher): .... def _get_foo(self):
.... # caused by a bug, several stack levels deeper
.... raise AttributeError('hidden!')
.... foo = property(_get_foo)
....

and as the error message suggests, the original AttributeError is
hidden by the lookup mechanism:
Peer().foo

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "/usr/lib/python2.4/asyncore.py", line 366, in __getattr__
return getattr(self.socket, attr)
AttributeError: 'NoneType' object has no attribute 'foo'

Is there anything that can be done about this? If there are no better
solutions, perhaps the documentation for property() could point out
this pitfall?

- Thomas

--
If you want to reply by mail, substitute my first and last name for
'foo' and 'bar', respectively, and remove '.invalid'.
Jul 18 '05 #1
4 1661
In article <87************@thomas.local>,
Thomas Rast <fo*****@freesurf.ch.invalid> wrote:

I've found out about a fundamental problem of attribute lookup, the
hard way.
Maybe.
asyncore.py uses the following code:

class dispatcher:
# ...
def __getattr__(self, attr):
return getattr(self.socket, attr)

Now suppose that I'm asking for some attribute not provided by
dispatcher: The lookup mechanism will apparently try to find it
directly and fail, generating an AttributeError; next it will call
__getattr__ to find the attribute. So far, no problems.

But I used a property much like this:
import asyncore
class Peer(asyncore.dispatcher):

... def _get_foo(self):
... # caused by a bug, several stack levels deeper
... raise AttributeError('hidden!')
... foo = property(_get_foo)
...


You're not supposed to use properties with classic classes.
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

"19. A language that doesn't affect the way you think about programming,
is not worth knowing." --Alan Perlis
Jul 18 '05 #2
aa**@pythoncraft.com (Aahz) writes:
In article <87************@thomas.local>,
Thomas Rast <fo*****@freesurf.ch.invalid> wrote:

class dispatcher:
# ...
def __getattr__(self, attr):
return getattr(self.socket, attr)
> import asyncore
> class Peer(asyncore.dispatcher):

... def _get_foo(self):
... # caused by a bug, several stack levels deeper
... raise AttributeError('hidden!')
... foo = property(_get_foo)
...


You're not supposed to use properties with classic classes.


Even if dispatcher was a new-style class, you still get the same
behaviour (or misbehaviour) -- Peer().foo still raises AttributeError
with the wrong message.

A simple workaround is to put a try ... except AttributeError block in
his _get_foo(), which would re-raise with a different error that
wouldn't be caught by getattr. You could even write a property
replacement for that:
class HiddenAttributeError(Exception): .... pass def robustprop(fget):

.... def wrapped_fget(self):
.... try:
.... return fget(self)
.... except AttributeError, e:
.... raise HiddenAttributeError(*e.args)
.... return property(fget=wrapped_fget)

Ideally, I think the better way is if getattr, when raising
AttributeError, somehow reused the old traceback (which would point
out the original problem). I don't know how to do that, though.

--
|>|\/|<
/--------------------------------------------------------------------------\
|David M. Cooke
|cookedm(at)physics(dot)mcmaster(dot)ca
Jul 18 '05 #3
David M. Cooke wrote:
Ideally, I think the better way is if getattr, when raising
AttributeError, somehow reused the old traceback (which would point
out the original problem). I don't know how to do that, though.


Maybe a solution could be to put the attribute name in the
AttributeError exception object, and use it in getattr; if the name
doesn't match, the exception is re-raised. It's still not flawless, but
would reduce risk of errors.

Nicolas
Jul 18 '05 #4
Thomas Rast wrote:
I've found out about a fundamental problem of attribute lookup, the
hard way... Is there anything that can be done about this?


It seems to me that the main problem is you're raising an AttributeError
when an attribute is private. AttributeError is only raised when an
attribute is not found. If you found it, but it's private, that's a
different problem. Try raising a custom exception instead of an
AttributeError, if you can.

Jul 18 '05 #5

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

Similar topics

3
by: Johnny | last post by:
Hi, I wonder what is the difference between the built-in function getattr() and the normal call of a function of a class. Here is the details: getattr( object, name) Return the value of...
8
by: Steven D'Aprano | last post by:
I came across this unexpected behaviour of getattr for new style classes. Example: >>> class Parrot(object): .... thing = .... >>> getattr(Parrot, "thing") is Parrot.thing True >>>...
13
by: Pierre | last post by:
Hi, Sorry in advance, english is not my main language :/ I'd like to customize the result obtained by getattr on an object : if the object has the requested property then return it BUT if the...
4
by: Hole | last post by:
Hi There! I'm trying to use Zope and the product OpenFlow. I got the following error while I was using the built-in function getattr() to retrieve an OpenFlow object: attribute name must be...
4
by: Emin | last post by:
Dear experts, I got some unexpected behavior in getattr and copy.deepcopy (see transcript below). I'm not sure if this is actually a bug in copy.deepcopy or if I'm doing something too magical...
3
by: Jm lists | last post by:
Hello, Since I can write the statement like: Test whether a path is a directory Why do I still need the getattr() func as below? Test whether a path is a directory
1
by: Sergio Correia | last post by:
This works: # Module spam.py import eggs print getattr(eggs, 'omelet')(100) That is, I just call the function omelet inside the module eggs and evaulate it with the argument 100.
3
numberwhun
by: numberwhun | last post by:
Hello everyone! I am presently going through the "Dive Into Python" tutorial which I obtained from their website. No, this is not for any class, I am self-learning the Python language. I am in...
8
by: Gregor Horvath | last post by:
Hi, class A(object): test = "test" class B(object): a = A() In : B.a.test
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

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.