#---------------------------------------------------------------------------- # Name: objutils.py # Purpose: Object Utilities # # Author: Alan Mullendore # # Created: 5/10/05 # CVS-ID: $Id$ # Copyright: (c) 2004-2005 ActiveGrid, Inc. # License: wxWindows License #---------------------------------------------------------------------------- import logging import traceback import sys import os import __builtin__ import types import activegrid.util.utillang as utillang import activegrid.util.datetimeparser as datetimeparser from types import * from activegrid.util.lang import * FUNCTION_HAS_ATTR = '_hasAttr' FUNCTION_GET_ATTR = '_getAttr' FUNCTION_SET_ATTR = '_setAttr' FUNCTION_DEL_ATTR = '_delAttr' def hasRawAttr(obj, name): if obj == None: return False if name != FUNCTION_HAS_ATTR and hasattr(obj, FUNCTION_HAS_ATTR): return obj._hasAttr(name) return obj.__dict__.has_key(name) def getRawAttr(obj, name): if name != FUNCTION_GET_ATTR and hasattr(obj, FUNCTION_GET_ATTR): return obj._getAttr(name) return obj.__dict__.get(name) def setRawAttr(obj, name, value): if name != FUNCTION_SET_ATTR and hasattr(obj, FUNCTION_SET_ATTR): obj._setAttr(name, value) else: obj.__dict__[name] = value def delRawAttr(obj, name): if name != FUNCTION_DEL_ATTR and hasattr(obj, FUNCTION_DEL_ATTR): obj._delAttr(name) else: del obj.__dict__[name] def getStaticAttr(obj, attr): if (isinstance(obj, types.TypeType)): classDesc = obj else: classDesc = obj.__class__ if (hasattr(classDesc, attr)): return getattr(classDesc, attr) return None def setStaticAttr(obj, attr, value): if (isinstance(obj, types.TypeType)): classDesc = obj else: classDesc = obj.__class__ setattr(classDesc, attr, value) def hasAttrFast(obj, name): if hasRawAttr(obj, name): return True if hasattr(obj, '_complexType'): complexType=obj._complexType element=complexType.findElement(name) if element: return True if hasattr(obj, name): return True return False def moduleForName(moduleName): module = None pathList = moduleName.split('.') if (len(moduleName) > 0): module = __import__(moduleName) for name in pathList[1:]: if (name in module.__dict__): module = module.__dict__[name] else: module = None break return module def typeForName(typeName): i = typeName.rfind('.') if (i >= 0): module = moduleForName(typeName[:i]) if (module != None): name = typeName[i+1:] if (name in module.__dict__): return module.__dict__[name] elif __builtin__.__dict__.has_key(typeName): return __builtin__.__dict__[typeName] return None def functionForName(functionName): ftype = typeForName(functionName) if (isinstance(ftype, (types.FunctionType, types.MethodType, types.BuiltinFunctionType, types.BuiltinMethodType))): return ftype return None def classForName(className): ctype = typeForName(className) if (isinstance(ctype, (types.ClassType, types.TypeType))): return ctype return None def newInstance(className, objargs=None): "dynamically create an object based on the className and return it." if not isinstance(objargs, list): objargs = [objargs] if className == "None": return None elif className == "bool": if ((len(objargs) < 1) or (objargs[0].lower() == "false") or (not objargs[0])): return False return True if className == "str" or className == "unicode": # don't strip: blanks are significant if len(objargs) > 0: try: return utillang.unescape(objargs[0]).encode() except: return "?" else: return "" if className == "date": return datetimeparser.parse(objargs[0], asdate=True) if className == "datetime": return datetimeparser.parse(objargs[0]) if className == "time": return datetimeparser.parse(objargs[0], astime=True) classtype = classForName(className) if (classtype == None): raise Exception("Could not find class %s" % className) if (len(objargs) > 0): return classtype(*objargs) else: return classtype() def getClassProperty(classType, propertyName): return getattr(classType, propertyName) def toDiffableRepr(value, maxLevel=None): if (value == None): return "None" if (maxLevel == None): maxLevel = 8 maxLevel -= 1 if (maxLevel < 0): return typeToString(value, PRINT_OBJ_DIFFABLE) ## if ((exclude != None) and not isinstance(value, (basestring, int))): ## for v in exclude: ## if (v is value): ## return "" ## exclude.append(value) ## elif (isinstance(value, ObjectType) and hasattr(value, "__dict__")): ## if (exclude == None): ## exclude = [] ## s = "%s(%s)" % (type(value), toDiffableString(value.__dict__, exclude)) if (not isinstance(value, (BooleanType, ClassType, ComplexType, DictType, DictionaryType, FloatType, IntType, ListType, LongType, StringType, TupleType, UnicodeType, BufferType, BuiltinFunctionType, BuiltinMethodType, CodeType, FrameType, FunctionType, GeneratorType, InstanceType, LambdaType, MethodType, ModuleType, SliceType, TracebackType, TypeType, XRangeType))): if (hasattr(value, "_toDiffableString")): s = value._toDiffableString(maxLevel) elif (hasattr(value, "__str__")): s = str(value) elif (hasattr(value, "__dict__")): s = "%s(%s)" % (type(value), toDiffableString(value.__dict__, maxLevel)) else: s = str(type(value)) ix2 = s.find(" object at 0x") if (ix2 > 0): ix = s.rfind(".") if (ix > 0): s = "" %s[ix+1:ix2] elif (isinstance(value, bool)): if (value): return "True" else: return "False" elif (isinstance(value, (tuple, list))): items = [] for v in value: if (isinstance(v, basestring)): if (v.find("'") >= 0): items.append('"%s"' % v) else: items.append("'%s'" % v) else: items.append(toDiffableString(v, maxLevel)) s = "[" + ", ".join(items) + "]" elif (isinstance(value, dict)): items = [] for key, val in value.iteritems(): if (isinstance(val, UnicodeType)): items.append("'%s': u'%s'" % (key, toDiffableString(val, maxLevel))) elif (isinstance(val, basestring)): items.append("'%s': '%s'" % (key, toDiffableString(val, maxLevel))) else: items.append("'%s': %s" % (key, toDiffableString(val, maxLevel))) s = "{" + ", ".join(items) + "}" else: s = str(value) return s def toDiffableString(value, maxLevel=None): ## if (value == None): ## return "None" ## if ((exclude != None) and not isinstance(value, (basestring, int))): ## for v in exclude: ## if (v is value): ## return "" ## exclude.append(value) s = toDiffableRepr(value, maxLevel) ds = "" i = s.find(" at 0x") start = 0 while (i >= 0): j = s.find(">", i) if (j < i): break ds += s[start:i] start = j i = s.find(" at 0x", start) ds = ds + s[start:] i = ds.find("\\src\\") if (i < 0): i = ds.find("/src/") else: ds = ds.replace("\\", "/") if (i > 0): i += 4 if (ds[i:i+5] == "\\php\\"): i += 4 elif (ds[i:i+8] == "\\python\\"): i += 7 ds = "filepath: ..." + ds[i:] return ds def toString(value, options=0): if ((options & PRINT_OBJ_DIFFABLE) > 0): return toDiffableString(value) elif (not isinstance(value, basestring)): return str(value) return value def typeToString(obj, options=0): if (isinstance(obj, BooleanType)): return "bool" elif (isinstance(obj, UnicodeType)): if ((options & PRINT_OBJ_DIFFABLE) > 0): return "string" return "unicode" elif (isinstance(obj, basestring)): return "string" elif (isinstance(obj, IntType)): return "int" elif (isinstance(obj, LongType)): if ((options & PRINT_OBJ_DIFFABLE) > 0): return "int" return "long" elif (isinstance(obj, FloatType)): return "float" elif (type(obj) == ListType): return "list" elif (isinstance(obj, DictType)): return "dict" elif (isinstance(obj, TupleType)): return "tuple" elif (isinstance(obj, InstanceType)): ## ds = str(type(obj)) ds = " " % (obj.__module__, obj.__class__.__name__) else: ds = str(type(obj)) if (options == 0): import activegrid.util.aglogging options = activegrid.util.aglogging.testMode(0, PRINT_OBJ_DIFFABLE) if ((options & PRINT_OBJ_DIFFABLE) > 0): if (ds.startswith(" 0): ix = name.find("__") if ((ix > 1) and name.startswith("_")): name = name[ix:] return toDiffableString(name) return name PRINT_OBJ_GETATTR = 1 PRINT_OBJ_HIDE_INTERNAL = 2 PRINT_OBJ_COMPACT = 4 PRINT_OBJ_NONONE = 8 PRINT_OBJ_DIFFABLE = 16 PRINT_OBJ_HIDE_EXCLUDED = 32 PRINT_OBJ_INTERNAL = 512 def printObject(out, object, name=None, indent=0, flags=0, exclude=None, remove=None, maxIndent=30): if (name == None): name = "" ## elif (name.endswith("_") and not name.endswith("__")): ## name = name[:-1] if ((remove != None) and (name in asDict(remove))): return False if ((maxIndent != None) and (indent > maxIndent)): print >> out, " "*indent, "%s: %s" % (name, toString(str(object), flags)), if ((flags & PRINT_OBJ_INTERNAL) == 0): print >> out return True finalNewLine = False printed = True if ((flags & (PRINT_OBJ_COMPACT | PRINT_OBJ_HIDE_EXCLUDED)) > 0): if ((exclude != None) and ((object in exclude) or (name in exclude))): return if ((flags & PRINT_OBJ_COMPACT) > 0): indent = 0 if ((flags & PRINT_OBJ_INTERNAL) == 0): finalNewLine = True flags |= PRINT_OBJ_INTERNAL if (object is None): if (flags & PRINT_OBJ_NONONE) == 0: print >> out, " "*indent, name, " = None", else: finalNewLine = False printed = False elif (name.startswith("_") and ((flags & PRINT_OBJ_HIDE_INTERNAL) > 0) and not name.startswith("_v_")): finalNewLine = False printed = False elif (isinstance(object, (list, tuple))): if ((exclude != None) and object in exclude): print >> out, " "*indent, name, " : ", typeToString(object, flags), " of length = ", len(object), " (already printed)", elif ((exclude != None) and name in exclude): print >> out, " "*indent, name, " : ", typeToString(object, flags), " of length = ", len(object), " (excluded)", else: if ((exclude != None) and (len(object) > 0)): exclude.append(object) print >> out, " "*indent, name, " : ", typeToString(object, flags), " of length = %d" % len(object), for i, o in enumerate(object): print >> out printObject(out, o, name="[%d]" % i, indent=indent+2, flags=flags, exclude=exclude, remove=remove, maxIndent=maxIndent) elif (isinstance(object, dict)): if ((exclude != None) and object in exclude): print >> out, " "*indent, name, " : ", typeToString(object, flags), " (already printed)", else: if ((exclude != None) and (len(object) > 0)): exclude.append(object) if (len(name) > 0): print >> out, " "*indent, name, if ((flags & PRINT_OBJ_COMPACT) == 0): print >> out indent += 2 print >> out, " "*indent, "{", if ((flags & PRINT_OBJ_COMPACT) == 0): print >> out keys = object.keys() keys.sort() for key in keys: if (key != None): n = key if (not (isinstance(n, basestring))): n = str(n) else: n = nameToString(n, flags) if ((not n.startswith("_") or ((flags & PRINT_OBJ_HIDE_INTERNAL) == 0))): if printObject(out, object[key], name=n, indent=indent+2, flags=(flags | PRINT_OBJ_INTERNAL), exclude=exclude, remove=remove, maxIndent=maxIndent): if ((flags & PRINT_OBJ_COMPACT) == 0): print >> out else: print >> out, ",", print >> out, " "*indent, "}", elif (hasattr(object, "__dict__")): if (name.startswith("_")): ## and ((flags & PRINT_OBJ_HIDE_INTERNAL) > 0)): print >> out, " "*indent, name, " : ", typeToString(object, flags), elif ((exclude != None) and ((object in exclude) or (object.__dict__ in exclude))): print >> out, " "*indent, name, " : ", typeToString(object, flags), " (already printed)", else: if (exclude != None): exclude.append(object) print >> out, " "*indent, name, " : ", typeToString(object, flags), if ((flags & PRINT_OBJ_GETATTR) == 0): if ((flags & PRINT_OBJ_COMPACT) == 0): print >> out printObject(out, object.__dict__, indent=indent, flags=flags, exclude=exclude, remove=remove, maxIndent=maxIndent) else: if ((flags & PRINT_OBJ_COMPACT) == 0): print >> out ## indent += 2 print >> out, " "*indent, "{", keys = object.__dict__.keys() keys.sort() printed = True for key in keys: if ((exclude != None) and (key in exclude)): continue if (printed and ((flags & PRINT_OBJ_COMPACT) == 0)): print >> out n = nameToString(key, flags) printed = printObject(out, getattr(object, n), name=n, indent=indent+2, flags=flags, exclude=exclude, remove=remove, maxIndent=maxIndent) if ((flags & PRINT_OBJ_COMPACT) == 0): print >> out print >> out, " "*indent, "}", elif (indent < 0): print >> out, object, elif isinstance(object, basestring): if ((exclude != None) and name in exclude): print >> out, " "*indent, name, " : ", typeToString(object, flags), " of length = ", len(object), " (excluded)", elif (len(object) > 100): object = toString(object, flags) print >> out, " "*indent, name, ":", typeToString(object, flags), "[%d] = %s...%s" % (len(object), object[:50], object[-50:]), else: print >> out, " "*indent, name, ":", typeToString(object, flags), "=", toString(object, flags), ## elif (isinstance(object, float)): ## val = str(object) ## if (len(val) > 17): ## val = val[:17] ## print >> out, " "*indent, name, ":", type(object), "=", val, else: print >> out, " "*indent, name, ":", typeToString(object, flags), "=", toString(object, flags), if (finalNewLine): print >> out return printed