X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d14a1e28567de23c586bc80017073d0c39f8d18f..bb9e79c05e26cbb3cdf3799910e69cea359efef3:/wxPython/wx/py/introspect.py?ds=sidebyside diff --git a/wxPython/wx/py/introspect.py b/wxPython/wx/py/introspect.py index 3bdff3a460..4ba2c4dc88 100644 --- a/wxPython/wx/py/introspect.py +++ b/wxPython/wx/py/introspect.py @@ -5,19 +5,12 @@ __author__ = "Patrick K. O'Brien " __cvsid__ = "$Id$" __revision__ = "$Revision$"[11:-2] -from __future__ import nested_scopes - import cStringIO import inspect import sys import tokenize import types - -try: - True -except NameError: - True = 1==1 - False = 1==0 +import wx def getAutoCompleteList(command='', locals=None, includeMagic=1, includeSingle=1, includeDouble=1): @@ -45,31 +38,47 @@ def getAttributeNames(object, includeMagic=1, includeSingle=1, attributes = [] dict = {} if not hasattrAlwaysReturnsTrue(object): - # Add some attributes that don't always get picked up. If - # they don't apply, they'll get filtered out at the end. - attributes += ['__bases__', '__class__', '__dict__', '__name__', - 'func_closure', 'func_code', 'func_defaults', - 'func_dict', 'func_doc', 'func_globals', 'func_name'] + # Add some attributes that don't always get picked up. + special_attrs = ['__bases__', '__class__', '__dict__', '__name__', + 'func_closure', 'func_code', 'func_defaults', + 'func_dict', 'func_doc', 'func_globals', 'func_name'] + attributes += [attr for attr in special_attrs \ + if hasattr(object, attr)] if includeMagic: try: attributes += object._getAttributeNames() except: pass # Get all attribute names. - attrdict = getAllAttributeNames(object) - for attrlist in attrdict.values(): - attributes += attrlist + str_type = str(type(object)) + if str_type == "": + attributes += dir(object) + else: + attrdict = getAllAttributeNames(object) + # Store the object's dir. + object_dir = dir(object) + for (obj_type_name, technique, count), attrlist in attrdict.items(): + # This complexity is necessary to avoid accessing all the + # attributes of the object. This is very handy for objects + # whose attributes are lazily evaluated. + if type(object).__name__ == obj_type_name and technique == 'dir': + attributes += attrlist + else: + attributes += [attr for attr in attrlist \ + if attr not in object_dir and hasattr(object, attr)] + # Remove duplicates from the attribute list. for item in attributes: dict[item] = None attributes = dict.keys() + # new-style swig wrappings can result in non-string attributes + # e.g. ITK http://www.itk.org/ + attributes = [attribute for attribute in attributes \ + if type(attribute) == str] attributes.sort(lambda x, y: cmp(x.upper(), y.upper())) if not includeSingle: attributes = filter(lambda item: item[0]!='_' \ - or item[1]=='_', attributes) + or item[1:2]=='_', attributes) if not includeDouble: attributes = filter(lambda item: item[:2]!='__', attributes) - # Make sure we haven't picked up any bogus attributes somehow. - attributes = [attribute for attribute in attributes \ - if hasattr(object, attribute)] return attributes def hasattrAlwaysReturnsTrue(object): @@ -87,10 +96,9 @@ def getAllAttributeNames(object): # They always return true for hasattr(). # !!! try: - # Yes, this can fail if object is an instance of a class with - # __str__ (or __repr__) having a bug or raising an - # exception. :-( - key = str(object) + # This could(?) fail if the type is poorly defined without + # even a name. + key = type(object).__name__ except: key = 'anonymous' # Wake up sleepy objects - a hack for ZODB objects in "ghost" state. @@ -169,6 +177,8 @@ def getCallTip(command='', locals=None): temp = argspec.split(',') if len(temp) == 1: # No other arguments. argspec = '()' + elif temp[0][:2] == '(*': # first param is like *args, not self + pass else: # Drop the first argument. argspec = '(' + ','.join(temp[1:]).lstrip() tip1 = name + argspec @@ -184,7 +194,7 @@ def getCallTip(command='', locals=None): # tip3 is the rest of the docstring, like: # "The call tip information will be based on ... firstline = doc.split('\n')[0].lstrip() - if tip1 == firstline: + if tip1 == firstline or firstline[:len(name)+1] == name+'(': tip1 = '' else: tip1 += '\n\n' @@ -280,7 +290,14 @@ def getRoot(command, terminator=None): def getTokens(command): """Return list of token tuples for command.""" - command = str(command) # In case the command is unicode, which fails. + + # In case the command is unicode try encoding it + if type(command) == unicode: + try: + command = command.encode(wx.GetDefaultPyEncoding()) + except UnicodeEncodeError: + pass # otherwise leave it alone + f = cStringIO.StringIO(command) # tokens is a list of token tuples, each looking like: # (type, string, (srow, scol), (erow, ecol), line)