- reworked the object unpacking code, now supports new-style objects more

or less decently/completely.
- cleaned up a little.
This commit is contained in:
Just van Rossum 2002-12-01 22:10:36 +00:00
parent 6a8c51837a
commit 927bc451c4
1 changed files with 46 additions and 34 deletions

View File

@ -502,33 +502,53 @@ class Browser:
SIMPLE_TYPES = ( SIMPLE_TYPES = (
types.NoneType, type(None),
types.IntType, int,
types.LongType, long,
types.FloatType, float,
types.ComplexType, complex,
types.StringType str,
unicode,
) )
INDEXING_TYPES = ( def get_ivars(obj):
types.TupleType, """Return a list the names of all (potential) instance variables."""
types.ListType, # __mro__ recipe from Guido
types.DictionaryType slots = {}
) # old-style C objects
if hasattr(obj, "__members__"):
for name in obj.__members__:
slots[name] = None
if hasattr(obj, "__methods__"):
for name in obj.__methods__:
slots[name] = None
# generic type
if hasattr(obj, "__dict__"):
slots.update(obj.__dict__)
cls = type(obj)
if hasattr(cls, "__mro__"):
# new-style class, use descriptors
for base in cls.__mro__:
for name, value in base.__dict__.items():
# XXX using callable() is a heuristic which isn't 100%
# foolproof.
if hasattr(value, "__get__") and not callable(value):
slots[name] = None
if "__dict__" in slots:
del slots["__dict__"]
slots = slots.keys()
slots.sort()
return slots
def unpack_object(object, indent = 0): def unpack_object(object, indent = 0):
tp = type(object) tp = type(object)
if tp in SIMPLE_TYPES and tp is not types.NoneType: if isinstance(object, SIMPLE_TYPES) and object is not None:
raise TypeError, "can't browse simple type: %s" % tp.__name__ raise TypeError, "can't browse simple type: %s" % tp.__name__
elif tp == types.DictionaryType: elif isinstance(object, dict):
return unpack_dict(object, indent) return unpack_dict(object, indent)
elif tp in (types.TupleType, types.ListType): elif isinstance(object, (tuple, list)):
return unpack_sequence(object, indent) return unpack_sequence(object, indent)
elif tp == types.InstanceType: elif isinstance(object, types.ModuleType):
return unpack_instance(object, indent)
elif tp == types.ClassType:
return unpack_class(object, indent)
elif tp == types.ModuleType:
return unpack_dict(object.__dict__, indent) return unpack_dict(object.__dict__, indent)
else: else:
return unpack_other(object, indent) return unpack_other(object, indent)
@ -555,23 +575,15 @@ def unpack_class(clss, indent = 0):
return pack_items(items, indent) return pack_items(items, indent)
def unpack_other(object, indent = 0): def unpack_other(object, indent = 0):
attrs = [] attrs = get_ivars(object)
if hasattr(object, '__members__'):
attrs = attrs + object.__members__
if hasattr(object, '__methods__'):
attrs = attrs + object.__methods__
if hasattr(object, '__dict__'):
attrs = attrs + object.__dict__.keys()
if hasattr(object, '__slots__'):
# XXX??
attrs = attrs + object.__slots__
if hasattr(object, "__class__") and "__class__" not in attrs:
attrs.append("__class__")
if hasattr(object, "__doc__") and "__doc__" not in attrs:
attrs.append("__doc__")
items = [] items = []
for attr in attrs: for attr in attrs:
items.append((attr, getattr(object, attr))) try:
value = getattr(object, attr)
except:
pass
else:
items.append((attr, value))
return pack_items(items, indent) return pack_items(items, indent)
def pack_items(items, indent = 0): def pack_items(items, indent = 0):