~ubuntu-branches/ubuntu/precise/python3.2/precise-proposed

« back to all changes in this revision

Viewing changes to Lib/inspect.py

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2012-03-09 18:40:39 UTC
  • mfrom: (30.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20120309184039-j3yk2emxr1plyo21
Tags: 3.2.3~rc1-1
* Python 3.2.3 release candidate 1.
* Update to 20120309 from the 3.2 branch.
* Fix libpython.a symlink. Closes: #660146.
* Build-depend on xauth.
* Run the gdb tests for the debug build only.

Show diffs side-by-side

added added

removed removed

Lines of Context:
100
100
    tests return false from the ismethoddescriptor() test, simply because
101
101
    the other tests promise more -- you can, e.g., count on having the
102
102
    __func__ attribute (etc) when an object passes ismethod()."""
103
 
    return (hasattr(object, "__get__")
104
 
            and not hasattr(object, "__set__") # else it's a data descriptor
105
 
            and not ismethod(object)           # mutual exclusion
106
 
            and not isfunction(object)
107
 
            and not isclass(object))
 
103
    if isclass(object) or ismethod(object) or isfunction(object):
 
104
        # mutual exclusion
 
105
        return False
 
106
    tp = type(object)
 
107
    return hasattr(tp, "__get__") and not hasattr(tp, "__set__")
108
108
 
109
109
def isdatadescriptor(object):
110
110
    """Return true if the object is a data descriptor.
114
114
    Typically, data descriptors will also have __name__ and __doc__ attributes
115
115
    (properties, getsets, and members have both of these attributes), but this
116
116
    is not guaranteed."""
117
 
    return (hasattr(object, "__set__") and hasattr(object, "__get__"))
 
117
    if isclass(object) or ismethod(object) or isfunction(object):
 
118
        # mutual exclusion
 
119
        return False
 
120
    tp = type(object)
 
121
    return hasattr(tp, "__set__") and hasattr(tp, "__get__")
118
122
 
119
123
if hasattr(types, 'MemberDescriptorType'):
120
124
    # CPython and equivalent
254
258
def getmembers(object, predicate=None):
255
259
    """Return all members of an object as (name, value) pairs sorted by name.
256
260
    Optionally, only return members that satisfy a given predicate."""
 
261
    if isclass(object):
 
262
        mro = (object,) + getmro(object)
 
263
    else:
 
264
        mro = ()
257
265
    results = []
258
266
    for key in dir(object):
259
 
        try:
260
 
            value = getattr(object, key)
261
 
        except AttributeError:
262
 
            continue
 
267
        # First try to get the value via __dict__. Some descriptors don't
 
268
        # like calling their __get__ (see bug #1785).
 
269
        for base in mro:
 
270
            if key in base.__dict__:
 
271
                value = base.__dict__[key]
 
272
                break
 
273
        else:
 
274
            try:
 
275
                value = getattr(object, key)
 
276
            except AttributeError:
 
277
                continue
263
278
        if not predicate or predicate(value):
264
279
            results.append((key, value))
265
280
    results.sort()
295
310
    names = dir(cls)
296
311
    result = []
297
312
    for name in names:
298
 
        # Get the object associated with the name.
 
313
        # Get the object associated with the name, and where it was defined.
299
314
        # Getting an obj from the __dict__ sometimes reveals more than
300
315
        # using getattr.  Static and class methods are dramatic examples.
301
 
        if name in cls.__dict__:
302
 
            obj = cls.__dict__[name]
 
316
        # Furthermore, some objects may raise an Exception when fetched with
 
317
        # getattr(). This is the case with some descriptors (bug #1785).
 
318
        # Thus, we only use getattr() as a last resort.
 
319
        homecls = None
 
320
        for base in (cls,) + mro:
 
321
            if name in base.__dict__:
 
322
                obj = base.__dict__[name]
 
323
                homecls = base
 
324
                break
303
325
        else:
304
326
            obj = getattr(cls, name)
305
 
 
306
 
        # Figure out where it was defined.
307
 
        homecls = getattr(obj, "__objclass__", None)
308
 
        if homecls is None:
309
 
            # search the dicts.
310
 
            for base in mro:
311
 
                if name in base.__dict__:
312
 
                    homecls = base
313
 
                    break
314
 
 
315
 
        # Get the object again, in order to get it from the defining
316
 
        # __dict__ instead of via getattr (if possible).
317
 
        if homecls is not None and name in homecls.__dict__:
318
 
            obj = homecls.__dict__[name]
319
 
 
320
 
        # Also get the object via getattr.
321
 
        obj_via_getattr = getattr(cls, name)
 
327
            homecls = getattr(obj, "__objclass__", homecls)
322
328
 
323
329
        # Classify the object.
324
330
        if isinstance(obj, staticmethod):
327
333
            kind = "class method"
328
334
        elif isinstance(obj, property):
329
335
            kind = "property"
330
 
        elif (isfunction(obj_via_getattr) or
331
 
              ismethoddescriptor(obj_via_getattr)):
 
336
        elif ismethoddescriptor(obj):
332
337
            kind = "method"
333
 
        else:
 
338
        elif isdatadescriptor(obj):
334
339
            kind = "data"
 
340
        else:
 
341
            obj_via_getattr = getattr(cls, name)
 
342
            if (isfunction(obj_via_getattr) or
 
343
                ismethoddescriptor(obj_via_getattr)):
 
344
                kind = "method"
 
345
            else:
 
346
                kind = "data"
 
347
            obj = obj_via_getattr
335
348
 
336
349
        result.append(Attribute(name, kind, homecls, obj))
337
350
 
483
496
        return sys.modules.get(modulesbyfile[file])
484
497
    # Update the filename to module name cache and check yet again
485
498
    # Copy sys.modules in order to cope with changes while iterating
486
 
    for modname, module in sys.modules.items():
 
499
    for modname, module in list(sys.modules.items()):
487
500
        if ismodule(module) and hasattr(module, '__file__'):
488
501
            f = module.__file__
489
502
            if f == _filesbymodname.get(modname, None):
1084
1097
 
1085
1098
def _check_class(klass, attr):
1086
1099
    for entry in _static_getmro(klass):
1087
 
        if not _shadowed_dict(type(entry)):
 
1100
        if _shadowed_dict(type(entry)) is _sentinel:
1088
1101
            try:
1089
1102
                return entry.__dict__[attr]
1090
1103
            except KeyError:
1109
1122
            if not (type(class_dict) is types.GetSetDescriptorType and
1110
1123
                    class_dict.__name__ == "__dict__" and
1111
1124
                    class_dict.__objclass__ is entry):
1112
 
                return True
1113
 
    return False
 
1125
                return class_dict
 
1126
    return _sentinel
1114
1127
 
1115
1128
def getattr_static(obj, attr, default=_sentinel):
1116
1129
    """Retrieve attributes without triggering dynamic lookup via the
1126
1139
    instance_result = _sentinel
1127
1140
    if not _is_type(obj):
1128
1141
        klass = type(obj)
1129
 
        if not _shadowed_dict(klass):
 
1142
        dict_attr = _shadowed_dict(klass)
 
1143
        if (dict_attr is _sentinel or
 
1144
            type(dict_attr) is types.MemberDescriptorType):
1130
1145
            instance_result = _check_instance(obj, attr)
1131
1146
    else:
1132
1147
        klass = obj
1146
1161
    if obj is klass:
1147
1162
        # for types we check the metaclass too
1148
1163
        for entry in _static_getmro(type(klass)):
1149
 
            try:
1150
 
                return entry.__dict__[attr]
1151
 
            except KeyError:
1152
 
                pass
 
1164
            if _shadowed_dict(type(entry)) is _sentinel:
 
1165
                try:
 
1166
                    return entry.__dict__[attr]
 
1167
                except KeyError:
 
1168
                    pass
1153
1169
    if default is not _sentinel:
1154
1170
        return default
1155
1171
    raise AttributeError(attr)