aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRonny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>2012-06-12 21:35:21 +0200
committerRonny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>2012-06-12 21:35:21 +0200
commit211f018fc46165eb7f7cc0cc86bae4d6c110cebf (patch)
tree0dd242fe22ead75bde685e8910591136a685567a /lib-python/2.7/inspect.py
parentadd the 3.2.3 version of the stdlib in lib-python/3.2 (diff)
downloadpypy-211f018fc46165eb7f7cc0cc86bae4d6c110cebf.tar.gz
pypy-211f018fc46165eb7f7cc0cc86bae4d6c110cebf.tar.bz2
pypy-211f018fc46165eb7f7cc0cc86bae4d6c110cebf.zip
upgrade python 2 stdlib to 2.7.3
Diffstat (limited to 'lib-python/2.7/inspect.py')
-rw-r--r--lib-python/2.7/inspect.py52
1 files changed, 27 insertions, 25 deletions
diff --git a/lib-python/2.7/inspect.py b/lib-python/2.7/inspect.py
index b0b2d3a8f5..66d5186573 100644
--- a/lib-python/2.7/inspect.py
+++ b/lib-python/2.7/inspect.py
@@ -288,30 +288,21 @@ def classify_class_attrs(cls):
names = dir(cls)
result = []
for name in names:
- # Get the object associated with the name.
+ # Get the object associated with the name, and where it was defined.
# Getting an obj from the __dict__ sometimes reveals more than
# using getattr. Static and class methods are dramatic examples.
- if name in cls.__dict__:
- obj = cls.__dict__[name]
+ # Furthermore, some objects may raise an Exception when fetched with
+ # getattr(). This is the case with some descriptors (bug #1785).
+ # Thus, we only use getattr() as a last resort.
+ homecls = None
+ for base in (cls,) + mro:
+ if name in base.__dict__:
+ obj = base.__dict__[name]
+ homecls = base
+ break
else:
obj = getattr(cls, name)
-
- # Figure out where it was defined.
- homecls = getattr(obj, "__objclass__", None)
- if homecls is None:
- # search the dicts.
- for base in mro:
- if name in base.__dict__:
- homecls = base
- break
-
- # Get the object again, in order to get it from the defining
- # __dict__ instead of via getattr (if possible).
- if homecls is not None and name in homecls.__dict__:
- obj = homecls.__dict__[name]
-
- # Also get the object via getattr.
- obj_via_getattr = getattr(cls, name)
+ homecls = getattr(obj, "__objclass__", homecls)
# Classify the object.
if isinstance(obj, staticmethod):
@@ -320,11 +311,18 @@ def classify_class_attrs(cls):
kind = "class method"
elif isinstance(obj, property):
kind = "property"
- elif (ismethod(obj_via_getattr) or
- ismethoddescriptor(obj_via_getattr)):
+ elif ismethoddescriptor(obj):
kind = "method"
- else:
+ elif isdatadescriptor(obj):
kind = "data"
+ else:
+ obj_via_getattr = getattr(cls, name)
+ if (ismethod(obj_via_getattr) or
+ ismethoddescriptor(obj_via_getattr)):
+ kind = "method"
+ else:
+ kind = "data"
+ obj = obj_via_getattr
result.append(Attribute(name, kind, homecls, obj))
@@ -524,9 +522,13 @@ def findsource(object):
or code object. The source code is returned as a list of all the lines
in the file and the line number indexes a line in that list. An IOError
is raised if the source code cannot be retrieved."""
- file = getsourcefile(object)
- if not file:
+
+ file = getfile(object)
+ sourcefile = getsourcefile(object)
+ if not sourcefile and file[0] + file[-1] != '<>':
raise IOError('source code not available')
+ file = sourcefile if sourcefile else file
+
module = getmodule(object, file)
if module:
lines = linecache.getlines(file, module.__dict__)