#!/usr/bin/env python # # typo.py: Warn of typographical errors in a Python script # # # One of the common annoyances with using Python is that it does # not report typographical errors in variable names at compile time. # # typo.py does a 2-pass interpretive analysis of the script bytecode # looking for undefined variables or attributes. An object is # considered undefined if all the following are true: # # 1. It does not appear on the left-hand-side (LHS) of an assignment # statement within the scope of the reference. # # 2. It is not defined by a def or class statement. # # 3. It is not defined in an imported module. # # 4. It is not defined in an extension or built-in module. # # # It is possible to fool typo.py with dynamically generated code, # e.g., using an exec statement, __getattr__, __setattr__, __import__, etc. # # typo.py is compatible with Python 1.5.2 and Python 2.x. # # # Usage: # python typo.py [-d] myfile.py # # The -d option will disassemble the file # # # Make initial script # 30 Jun 01 Alan E. Klietz (alank@algintech.com) # http://utools.com/typo.htm # # Copyright (c) 2001,2004 Alan E. Klietz # Unlimited redistribution permitted # import os, sys, types, string, py_compile disasm = 0 suffix = (__debug__ and '.pyc' or '.pyo') CO_OPTIMIZED = 1 # CO_OPTIMIZED indicates an optimized function CO_NEWLOCALS = 2 # CO_NEWLOCALS indicates not module level builtin_attrs = { # set object methods (Python 2.4) 'add':1, # yield iterator (Python 2.3) 'next':1, # dict object methods 'clear':1, 'copy':1, 'get':1, 'has_key':1, 'items':1, 'keys':1, 'popitem':1, 'setdefault':1, 'update':1, 'values':1, # list object methods 'append':1, 'count':1, 'extend':1, 'index':1, 'insert':1, 'pop':1, 'remove':1, 'reverse':1, 'sort':1, # string object methods 'capitalize':1, 'center':1, 'count':1, 'encode':1, 'endswith':1, 'expandtabs':1, 'find':1, 'index':1, 'isalnum':1, 'isalpha':1, 'isdigit':1, 'islower':1, 'isspace':1, 'istitle':1, 'isupper':1, 'join':1, 'ljust':1, 'lower':1, 'lstrip':1, 'replace':1, 'rfind':1, 'rindex':1, 'rjust':1, 'rsplit':1, 'rstrip':1, 'strip':1, 'split':1, 'splitlines':1, 'startswith':1, 'strip':1, 'swapcase':1, 'title':1, 'translate':1, 'upper':1, # unicode methods 'encode':1, 'maketrans':1, 'isdecimal':1, 'isnumeric':1, # file object methods 'close':1, 'closed':1, 'fileno':1, 'flush':1, 'isatty':1, 'mode':1, 'name':1, 'read':1, 'readinto':1, 'readline':1, 'readlines':1, 'seek':1, 'softspace':1, 'tell':1, 'truncate':1, 'write':1, 'writelines':1, 'xreadlines':1, # complex object attrs 'conjugate':1, 'real':1, 'imag':1, '__members__':1, # range object attrs 'tolist':1, 'step':1, 'start':1, 'stop':1, '__members__':1, # = ['start','stop','step'] # exception object attrs 'args':1, 'filename':1, 'errno':1, 'strerror':1, 'msg':1, # class object attrs '__dict__':1, # method members '__bases__':1, '__module__':1, '__name__':1, # instance object attrs (also uses class) '__dict__':1, # data members '__class__':1, # instancemethod and unboundmethod object attrs '__name__':1, '__doc__':1, '__dict__':1, '__members__':1, # = ['__doc__','__name__','__self__'] 'im_func':1, 'im_self':1, 'im_class':1, '__name__':1, '__doc__':1, '__dict__':1, # func object attrs 'func_code':1, 'func_globals':1, 'func_name':1, '__name__':1, 'func_closure':1, 'func_defaults':1, 'func_doc':1, '__doc__':1, 'func_dict':1, # code object attrs 'co_argcount':1, 'co_nlocals':1, 'co_stacksize':1, 'co_flags':1, 'co_code':1, 'co_consts':1, 'co_names':1, 'co_varnames':1, 'co_freevars':1, 'co_cellvars':1, 'co_filename':1, 'co_name':1, 'co_firstlineno':1, 'co_lnotab':1, # frame object attrs 'f_back':1, 'f_code':1, 'f_builtins':1, 'f_globals':1, 'f_locals':1, 'f_lasti':1, 'f_lineno':1, 'f_restricted':1, 'f_trace':1, 'f_exc_type':1, 'f_exc_value':1, 'f_exc_traceback':1, 'f_locals':1, # traceback object attrs 'tb_next':1, 'tb_frame':1, 'tb_lasti':1, 'tb_lineno':1, # module object attrs '__file__':1, # symtable object #'id':1, 'name':1, 'symbols':1, 'varnames':1, 'children':1, #'type':1, 'lineno':1, 'optimized':1, 'nested':1, } ##################################################################### # # Explicitly enumerate extension attrs. There is no other way (sigh) # def collect_extension_attrs(modname, attrs): d = None if modname == 'array': d = { 'append':1, 'buffer_info':1, 'byteswap':1, 'count':1, 'extend':1, 'fromfile':1, 'fromlist':1, 'fromstring':1, 'index':1, 'insert':1, 'pop':1, 'read':1, 'remove':1, 'reverse':1, 'tofile':1, 'tolist':1, 'tostring':1, 'write':1, # 'typecode':1, 'itemsize':1, '__members__':1, } elif modname == 'cd': d = { 'allowremoval':1, 'bestreadsize':1, 'close':1, 'eject':1, 'getstatus':1, 'gettrackinfo':1, 'msftoblock':1, 'play':1, 'playabs':1, 'playtrack':1, 'playtrackabs':1, 'preventremoval':1, 'readda':1, 'seek':1, 'seekblock':1, 'seektrack':1, 'stop':1, 'togglepause':1, # 'addcallback':1, 'deleteparser':1, 'parseframe':1, 'removecallback':1, 'resetparser':1, 'setcallback':1, } elif modname == 'cl': d = { 'close':1, 'CloseDecompressor':1, 'Decompress':1, 'GetDefault':1, 'GetMinMax':1, 'GetName':1, 'GetParam':1, 'GetParamID':1, 'GetParams':1, 'ReadHeader':1, 'QueryParams':1, 'QuerySchemeFromHandle':1, 'SetParam':1, 'SetParams':1, } elif modname == 'cPickle': d = { 'dump':1, 'clear_memo':1, 'getvalue':1, # 'persistent_id':1, 'memo':1, 'PicklingError':1, 'binary':1, 'fast':1, 'getvalue':1, # 'load':1, 'noload':1, # 'persistent_load':1, 'find_global':1, 'UnpicklingError':1, } elif modname == 'bsddb': d = { 'close':1, 'keys':1, 'has_key':1, 'set_location':1, 'next':1, 'previous':1, 'first':1, 'last':1, 'sync':1, } elif modname == '_curses': d = { 'addch':1, 'addnstr':1, 'addstr':1, 'attroff':1, 'attron':1, 'attrset':1, 'bkgd':1, 'bkgdset':1, 'border':1, 'box':1, 'clear':1, 'clearok':1, 'clrtobot':1, 'clrtoeol':1, 'cursyncup':1, 'delch':1, 'deleteln':1, 'derwin':1, 'echochar':1, 'enclose':1, 'erase':1, 'getbegyx':1, 'getch':1, 'getkey':1, 'getmaxyx':1, 'getparyx':1, 'getstr':1, 'getyx':1, 'hline':1, 'idcok':1, 'idlok':1, 'immedok':1, 'inch':1, 'insch':1, 'insdelln':1, 'insertln':1, 'insnstr':1, 'insstr':1, 'instr':1, 'is_linetouched':1, 'is_wintouched':1, 'keypad':1, 'leaveok':1, 'move':1, 'mvderwin':1, 'mvwin':1, 'nodelay':1, 'notimeout':1, 'noutrefresh':1, 'overlay':1, 'overwrite':1, 'putwin':1, 'redrawln':1, 'redrawwin':1, 'refresh':1, 'resize':1, 'scroll':1, 'scrollok':1, 'setscrreg':1, 'standend':1, 'standout':1, 'subpad':1, 'subwin':1, 'syncdown':1, 'syncok':1, 'syncup':1, 'timeout':1, 'touchline':1, 'touchwin':1, 'untouchwin':1, 'vline':1, } elif modname == '_curses_panel': d = { 'above':1, 'below':1, 'bottom':1, 'hidden':1, 'hide':1, 'move':1, 'replace':1, 'set_userptr':1, 'show':1, 'top':1, 'userptr':1, 'window':1, } elif modname == 'cStringIO': d = { # same as file plus these 'getvalue':1, 'reset':1, } elif modname == 'dl': d = { 'call':1, 'sym':1, 'close':1, } elif modname == 'fl': d = { 'objclass':1, 'type':1, 'boxtype':1, 'x':1, 'y':1, 'w':1, 'h':1, 'col1':1, 'col2':1, 'align':1, 'lcol':1, 'lsize':1, 'label':1, 'lstyle':1, 'pushed':1, 'focus':1, 'belowmouse':1, 'active':1, 'input':1, 'visible':1, 'radio':1, 'automatic':1, } elif modname == 'fm': d = { 'scalefont':1, 'setfont':1, 'getfontname':1, 'getcomment':1, 'getfontinfo':1, 'getstrwidth':1, } elif modname == 'gdbm': d = { 'firstkey':1, 'nextkey':1, 'reorganize':1, 'sync':1, } elif modname == 'linuxaudiodev': d = { 'read':1, 'write':1, 'setparameters':1, 'bufsize':1, 'obufcount':1, 'obuffree':1, 'flush':1, 'close':1, 'fileno':1, 'getptr':1, } elif modname == 'md5': d = { 'update':1, 'digest':1, 'hexdigest':1, 'copy':1, } elif modname == 'mmap': d = { 'find':1, 'move':1, 'read_byte':1, 'resize':1, 'size':1, 'write_byte':1, } elif modname == 'mpz': d = { 'binary':1, } elif modname == 'parser': d = { 'compile':1, 'isexpr':1, 'issuite':1, 'tolist':1, 'totuple':1, } elif modname == 'pcre': d = { 'match':1, } elif modname == 'pyaelib': # AEK local d = { # pyaeauth.cpp 'DoClientRound':1, 'DoServerRound':1, 'RevertToSelf':1, 'ImpersonateUser':1, 'IsMemberOfGroup':1, 'token':1, 'LoadPassword':1, 'StorePassword':1, # pyaecom.cpp 'GetIObject':1, # pyaedh.cpp 'DoServer':1, 'DoClient':1, 'ComputeFinalKey':1, # pyaeminissl.cpp 'connect':1, 'accept':1, 'send':1, 'recv':1, 'close':1, 'get_peer_guid':1, 'get_version':1, 'get_session_guid':1, 'set_session_guid':1, 'get_cipher_suite':1, # pyaerc4.cpp 'Encrypt':1, 'SetKey':1, # pyaereg.cpp 'QueryValueDword':1, 'QueryValueStr':1, 'SetValueDword':1, 'SetValueStr':1, 'OpenKey':1, 'CreateKey':1, 'HasValue':1, 'HasKey':1, 'DeleteKey':1, 'DeleteValue':1, 'EnumRewind':1, 'EnumKeyNext':1, 'EnumValueNext':1, 'hkey':1, 'hKey':1, # pyaethread.cpp 'handle':1, 'thread_id':1, 'result':1, 'exc_type':1, 'exc_value':1, 'exc_traceback':1, 'is_running':1, 'wait':1, 'snap_trackback':1, 'kill':1, 'grab_lock':1, # PyIMTSActivity.cpp, PyIObjectContext.cpp 'Populate':1, 'Add':1, 'Value':1, 'SaveChanges':1, 'GetCollection':1, 'GetUtilInterface':1, 'ImportComponent':1, 'ImportComponentByName':1, 'Item':1, 'Count':1, 'Remove':1, 'IsInTransaction':1, 'IsSecurityEnabled':1, 'IsCallerInRole':1, 'GetActivityId':1, } elif modname == 'pyexpat': d = { 'ErrorCode':1, 'ErrorLineNumber':1, 'ErrorColumnNumber':1, 'ErrorByteIndex':1, 'ordered_attributes':1, 'returns_unicode':1, 'specified_attributes':1, '__members__':1, # # Note: dynamic attrs from XML tags are not supported! # } elif modname == 'regex': d = { 'match':1, 'search':1, 'group':1, 'last':1, 'groupindex':1, 'regs':1, 'translate':1, 'realpat':1, 'givenpat':1, '__members__':1, } elif modname == 'rotor': d = { 'encrypt':1, 'encryptmore':1, 'decrypt':1, 'decryptmore':1, 'setkey':1, } elif modname == 'select': d = { 'register':1, 'unregister':1, 'poll':1, } elif modname == 'sha': d = { 'digest':1, 'hexdigest':1, 'update':1, } elif modname == 'socket' or modname == '_socket': d = { 'accept':1, 'bind':1, 'close':1, 'connect':1, 'connect_ex':1, 'fileno':1, 'dup':1, 'getpeername':1, 'getsockname':1, 'getsockopt':1, 'listen':1, 'makefile':1, 'recv':1, 'recvfrom':1, 'send':1, 'sendto':1, 'setblocking':1, 'setsockopt':1, 'shutdown':1, # SSL methods 'write':1, 'read':1, 'server':1, 'issuer':1, } elif modname == '_sre': d = { # re object 'match':1, 'search':1, 'sub':1, 'subn':1, 'split':1, 'findall':1, 'scanner':1, # match object 'group':1, 'start':1, 'end':1, 'span':1, 'groups':1, 'groupdict':1, 'expand':1, # scanner object 'pattern':1, 'match':1, 'search':1, } elif modname == 'sunaudiodev': d = { 'ibufcount':1, 'obufcount':1, 'getinfo':1, 'setinfo':1, 'drain':1, 'getdev':1, 'fileno':1, # 'i_sample_rate':1, 'i_channels':1, 'i_precision':1, 'i_encoding':1, 'i_gain':1, 'i_port':1, 'i_samples':1, 'i_eof':1, 'i_pause':1, 'i_error':1, 'i_waiting':1, 'i_open':1, 'i_active':1, 'i_buffer_size':1, 'i_balance':1, 'i_avail_ports':1, 'o_sample_rate':1, 'o_channels':1, 'o_precision':1, 'o_encoding':1, 'o_gain':1, 'o_port':1, 'o_samples':1, 'o_eof':1, 'o_pause':1, 'o_waiting':1, 'o_open':1, 'o_active':1, 'o_buffer_size':1, 'o_balance':1, 'o_avail_ports':1, 'monitor_gain':1, } elif modname == 'sv': d = { 'YUVtoRGB':1, 'RGB8toRGB32':1, 'InterleaveFields':1, 'UnlockCaptureData':1, 'FindVisibleRegion':1, 'GetFields':1, 'YUVtoYUV422DC':1, 'YUVtoYUV422DC_quarter':1, 'YUVtoYUV422DC_sixteenth':1, 'lrectwrite':1, 'writefile':1, # 'BindGLWindow':1, 'EndContinuousCapture':1, 'IsVideoDisplayed':1, 'OutputOffset':1, 'PutFrame':1, 'QuerySize':1, 'SetSize':1, 'SetStdDefaults':1, 'UseExclusive':1, 'WindowOffset':1, 'InitContinuousCapture':1, 'CaptureBurst':1, 'CaptureOneFrame':1, 'GetCaptureData':1, 'CloseVideo':1, 'LoadMap':1, 'GetParam':1, 'GetParamRange':1, 'SetParam':1, } elif modname == 'sys': d = { # These are defined only after a toplevel exception 'last_type':1, 'last_value':1, 'last_traceback':1, # These are defined only during an interactive session 'ps1':1, 'ps2':1, 'gettotalrefcount':1, } elif modname == '_tkinter': d = { 'call':1, 'globalcall':1, 'eval':1, 'globaleval':1, 'evalfile':1, 'record':1, 'adderrorinfo':1, 'setvar':1, 'globalsetvar':1, 'getvar':1, 'globalgetvar':1, 'unsetvar':1, 'globalunsetvar':1, 'getint':1, 'getdouble':1, 'getboolean':1, 'exprstring':1, 'exprlong':1, 'exprdouble':1, 'exprboolean':1, 'splitlist':1, 'split':1, 'merge':1, 'createcommand':1, 'deletecommand':1, 'createfilehandler':1, 'deletefilehandler':1, 'createtimerhandle':1, 'mainloop':1, 'dooneevent':1, 'quit':1, 'interpaddr':1, # 'deletetimerhandler':1, } elif modname == 'thread': d = { 'acquire_lock':1, 'acquire':1, 'release_lock':1, 'release':1, 'locked_lock':1, 'locked':1, } elif modname == 'zlib': d = { 'compress':1, 'decompress':1, 'unused_data':1, } ################################################################## # # win32all\win32 # elif modname == 'dbi': d = { 'value':1, } elif modname == 'mmapfile': d = { 'move':1, 'read_byte':1, 'resize':1, 'write_byte':1, } elif modname == 'odbc': d = { 'error':1, 'setautocommit':1, 'commit':1, 'rollback':1, 'cursor':1, 'close':1, # 'description':1, 'execute':1, 'fetchone':1, 'fetchmany':1, 'fetchall':1, 'setinputsizes':1, 'setoutputsize':1, } elif modname == 'pywintypes': d = { # PyACL.cpp 'Initialize':1, 'AddAccessAllowedAce':1, 'AddAccessDeniedAce':1, # PyHANDLE.cpp 'handle':1, 'Close':1, 'Detach':1, # PyOVERLAPPED.cpp 'hEvent':1, 'object':1, 'Internal':1, 'InternalHigh':1, 'Offset':1, 'OffsetHigh':1, # PySECURITY_ATTRIBUTES.cpp 'Initialize':1, 'SetSecurityDescriptorDacl':1, # PySECURITY_DESCRIPTOR.cpp 'Initialize':1, 'SetSecurityDescriptorDacl':1, 'SetDacl':1, # PySID.cpp 'Initialize':1, 'IsValid':1, 'SetSubAuthority':1, # PyTime.cpp 'Format':1, 'year':1, 'month':1, 'weekday':1, 'day':1, 'hour':1, 'minute':1, 'second':1, 'msec':1, # PyUnicode.cpp 'raw':1, 'upper':1, 'lower':1, } elif modname == 'win2kras': d = { 'szUserName':1, 'userName':1, 'pbEapInfo':1, 'eapInfo':1, } elif modname in ['win32event', 'win32file', 'win32pipe', 'win32security']: d = { # indirect via PyHANDLE.cpp 'handle':1, 'Close':1, 'Detach':1, 'Initialize':1, 'SetSubAuthority':1, } elif modname == 'win32file_comm': d = { 'fBinary':1, 'fParity':1, 'fOutxCtsFlow':1, 'fOutxDrsFlow':1, 'fDtrControl':1, 'fDsrSensitivity':1, 'fTXContinueOnXoff':1, 'fOutX':1, 'fInX':1, 'fErrorChar':1, 'fNull':1, 'fRtsControl':1, 'fAbortOnError':1, 'fDummy2':1, # 'fCtsHold':1, 'fDsrHold':1, 'fRlsdHold':1, 'fXoffHold':1, 'fXoffSent':1, 'fEof':1, 'fTxim':1, 'fReserved':1, # 'BaudRate':1, 'wReserved':1, 'XonLim':1, 'XoffLim':1, 'ByteSize':1, 'Parity':1, 'StopBits':1, 'XonChar':1, 'XoffChar':1, 'ErrorChar':1, 'EofChar':1, 'EvtChar':1, 'wReserved1':1, # 'cbInQue':1, 'cbOutQue':1, } elif modname == 'win32gui': d = { 'style':1, 'cbWndExtra':1, 'hInstance':1, 'hIcon':1, 'hCursor':1, 'hbrBackground':1, 'lpszMenuName':1, 'lpszClassName':1, 'lpfnWndProc':1, # 'lfFaceName':1, 'lfHeight':1, 'lfWidth':1, 'lfEscapement':1, 'lfOrientation':1, 'lfWeight':1, 'lfItalic':1, 'lfUnderline':1, 'lfStrikeOut':1, 'lfCharSet':1, 'lfOutPrecision':1, 'lfClipPrecision':1, 'lfQuality':1, 'lfPitchAndFamily':1, } elif modname == 'win32help': d = { 'typeName':1, 'caption':1, 'toc':1, 'index':1, 'file':1, 'home':1, 'jump1':1, 'jump2':1, 'urlJump1':1, 'urlJump2':1, 'windowPos':1, 'HTMLPos':1, # 'hdr':1, 'url':1, 'curUrl':1, 'winType':1, # 'keywords':1, 'url':1, 'msgText':1, 'msgTitle':1, 'window':1, # 'searchQuery':1, # 'text':1,'font':1,'pt':1,'margins':1, # 'indexOnFail':1, 'uniCodeStrings':1, 'proximity':1, 'stemmedSearch':1, 'titleOnly':1, 'execute':1, 'searchQuery':1, # 'hinst':1, 'idString':1, 'clrForeground':1, 'clrBackground':1, 'text':1, 'font':1, 'pt':1, 'margins':1, # 'validMembers':1, 'winProperties':1, 'exStyles':1, 'showState':1, 'hwndHelp':1, 'hwndCaller':1, 'hwndToolBar':1, 'hwndNavigation':1, 'hwndHTML':1, 'navWidth':1, 'toolBarFlags':1, 'notExpanded':1, 'curNavType':1, 'idNotify':1, 'typename':1, 'caption':1, 'windowPos':1, 'HTMLPos':1, # 'hwndFrom':1, 'idFrom':1, 'code':1, # 'action':1, 'winType':1, } elif modname == 'win32process': d = { 'hStdInput':1, 'hStdOutput':1, 'hStdError':1, 'lpDesktop':1, 'lpTitle':1, 'dwX':1, 'dwY':1, 'dwXSize':1, 'dwYSize':1, 'dwXCountChars':1, 'dwYCountChars':1, 'dwFillAttribute':1, 'dwFlags':1, 'wShowWindow':1, # indirect via PyHANDLE.cpp 'handle':1, 'Close':1, 'Detach':1, } elif modname == 'win32ras': d = { 'dwfOptions':1, 'hwndParent':1, 'reserved':1, 'reserved1':1, 'RasEapInfo':1, } elif modname == 'win32wnet': d = { 'Callname':1, 'Name':1, 'Buffer':1, 'Command':1, 'Retcode':1, 'Lsn':1, 'Num':1, 'Bufflen':1, 'Callname':1, 'Name':1, 'Rto':1, 'Sto':1, 'Lana_num':1, 'Cmd_cplt':1, 'Event':1, 'Post':1, # 'lpProvider':1, 'lpRemoteName':1, 'lpLocalName':1, 'lpComment':1, 'dwScope':1, 'dwType':1, 'dwDisplayType':1, 'dwUsage':1, } # omitted: PerfMon ################################################################## # # win32all\com # elif modname == 'pythoncom': d = { # PyIClassFactory.cpp, 'CreateInstance':1, 'LockServer':1, # PyIUnknown.cpp 'QueryInterface':1, # PyIDispatch.cpp 'Invoke':1, 'InvokeTypes':1, 'GetIDsOfNames':1, 'GetTypeInfo':1, 'GetTypeInfoCount':1, 'GetDispID':1, 'InvokeEx':1, 'DeleteMemberByName':1, 'DeleteMemberByDispID':1, 'GetMemberProperties':1, 'GetMemberName':1, 'GetNextDispID':1, # PyFUNCDESC.cpp 'memid':1, 'scodeArray':1, 'args':1, 'funckind':1, 'invkind':1, 'callconv':1, 'cParamsOpt':1, 'oVft':1, 'rettype':1, 'wFuncFlags':1, # PyTYPEATTR.cpp 'iid':1, 'lcid':1, 'memidConstructor':1, 'memidDestructor':1, 'cbSizeInstance':1, 'typekind':1, 'cFuncs':1, 'cVars':1, 'cImplTypes':1, 'cbSizeVft':1, 'cbAlighment':1, 'wTypeFlags':1, 'wMajorVerNum':1, 'wMinorVerNum':1, 'tdescAlias':1, 'idldescType':1, # PyVARDESC.cpp 'memid':1, 'value':1, 'elemdescVar':1, 'wVarFlags':1, 'varkind':1, } ################################################################## # # win32all\Pythonwin # elif modname == 'win32ui': d = { # pythonpsheet.cpp 'WindowProc':1, 'OnInitDialog':1, 'OnCreate':1, # pythonview.cpp 'OnPrepareDC':1, 'DrawItem':1, # win32app.cpp 'AddDocTemplate':1, 'FindOpenDocument':1, 'GetDocTemplateList':1, 'InitMDIInstance':1, 'InitDlgInstance':1, 'LoadCursor':1, 'LoadStandardCursor':1, 'LoadOEMCursor':1, 'LoadIcon':1, 'LoadStandardIcon':1, 'OpenDocumentFile':1, 'OnFileNew':1, 'OnFileOpen':1, 'RemoveDocTemplate':1, 'Run':1, 'IsInproc':1, # win32assoc.cpp 'AttachObject':1, # win32btmap.cpp 'CreateCompatibleBitmap':1, 'GetSize':1, 'GetHandle':1, 'LoadBitmap':1, 'LoadBitmapFile':1, 'LoadPPMFile':1, 'Paint':1, 'GetInfo':1, 'GetBitmapBits':1, 'SaveBitmapFile':1, # win32brush.cpp 'CreateSolidBrush':1, 'GetSafeHandle':1, # win32cmd.cpp 'BeginWaitCursor':1, 'EndWaitCursor':1, 'HookCommand':1, 'HookCommandUpdate':1, 'HookOleEvent':1, 'HookNotify':1, 'RestoreWaitCursor':1, # win32cmdui.cpp 'Enable':1, 'SetCheck':1, 'SetRadio':1, 'SetText':1, 'ContinueRouting':1, 'm_nIndex':1, 'm_nID':1, # win32control.cpp 'GetBitmap':1, 'SetBitmap':1, 'GetCheck':1, 'SetCheck':1, 'GetState':1, 'SetState':1, 'GetButtonStyle':1, 'SetButtonStyle':1, # 'AddString':1, 'DeleteString':1, 'Dir':1, 'GetCaretIndex':1, 'GetCount':1, 'GetCurSel':1, 'GetItemData':1, 'GetItemValue':1, 'GetSel':1, 'GetSelCount':1, 'GetSelItems':1, 'GetSelTextItems':1, 'GetTopIndex':1, 'GetText':1, 'GetTextLen':1, 'InsertString':1, 'ResetContent':1, 'SetCaretIndex':1, 'SelectString':1, 'SelItemRange':1, 'SetCurSel':1, 'SetItemData':1, 'SetItemValue':1, 'SelSel':1, 'SetTabStops':1, 'SetTopIndex':1, # 'GetEditSel':1, 'GetExtendedUI':1, 'GetLBText':1, 'GetLBTextLen':1, 'LimitText':1, 'SetEditSel':1, 'SetExtendedUI':1, 'ShowDropDown':1, # 'SetRange':1, 'SetPos':1, 'OffsetPos':1, 'SetStep':1, 'StepIt':1, # 'CreateWindow':1, 'GetLineSize':1, 'SetLineSize':1, 'GetPageSize':1, 'SetPageSize':1, 'GetRangeMax':1, 'GetRangeMin':1, 'GetRange':1, 'SetRangeMax':1, 'SetRangeMin':1, 'SetRange':1, 'GetSelection':1, 'SetSelection':1, 'GetChannelRect':1, 'GetThumbRect':1, 'GetPos':1, 'SetPos':1, 'GetNumTics':1, 'GetTicArray':1, 'GetTic':1, 'GetTicPos':1, 'SetTic':1, 'SetTicFreq':1, 'ClearSel':1, 'VerifyPos':1, 'ClearTics':1, # 'GetBorders':1, 'GetParts':1, 'GetTextAttr':1, 'GetTextLength':1, 'SetMinHeight':1, 'SetParts':1, 'SetText':1, # 'SetRange':1, 'SetRange32':1, # win32cltedit.cpp 'Clear':1, 'Copy':1, 'Cut':1, 'FmtLines':1, 'GetFirstVisibleLine':1, 'GetSel':1, 'GetLine':1, 'GetLineCount':1, 'LimitText':1, 'LineFromChar':1, 'LineIndex':1, 'LineScroll':1, 'Paste':1, 'ReplaceSel':1, 'SetReadOnly':1, 'SetSel':1, # win32ctrllList.cpp 'Arrange':1, 'DeleteAllItems':1, 'DeleteItem':1, 'GetTextColor':1, 'SetTextColor':1, 'GetBkColor':1, 'SetBkColor':1, 'GetItemRect':1, 'GetItem':1, 'GetItemCount':1, 'GetEditControl':1, 'EditLabel':1, 'EnsureVisible':1, 'CreateDragImage':1, 'GetImageList':1, 'GetNextItem':1, 'InsertColumn':1, 'InsertItem':1, 'SetImageList':1, 'GetColumn':1, 'GetTextBkColor':1, 'SetTextBkColor':1, 'GetTopIndex':1, 'GetCountPerPage':1, 'GetSelectedCount':1, 'SetItem':1, 'SetItemState':1, 'GetItemState':1, 'SetItemData':1, 'GetItemData':1, 'SetItemCount':1, 'GetItemCount':1, 'SetItemText':1, 'GetItemText':1, 'RedrawItems':1, 'Update':1, 'SetColumn':1, 'DeleteColumn':1, 'GetColumnWidth':1, 'SetColumnWidth':1, 'GetStringWidth':1, 'HitTest':1, 'GetItemPosition':1, # win32ctrlRichEdit.cpp 'Clear':1, 'Copy':1, 'Cut':1, 'FindText':1, 'GetCharPos':1, 'GetDefaultCharFormat':1, 'GetEventMask':1, 'GetSelectionCharFormat':1, 'GetFirstVisibleLine':1, 'GetParaFormat':1, 'GetSel':1, 'GetSelText':1, 'GetTextLength':1, 'GetLine':1, 'GetModify':1, 'GetLineCount':1, 'LimitText':1, 'LineFromChar':1, 'LineIndex':1, 'LineScroll':1, 'Paste':1, 'ReplaceSel':1, 'SetBackgroundColor':1, 'SetDefaultCharFormat':1, 'SetEventMask':1, 'SetSelectionCharFormat':1, 'SetModify':1, 'SetOptions':1, 'SetParaFormat':1, 'SetReadOnly':1, 'SetSel':1, 'SetSelAndCharFormat':1, 'SetTargetDevice':1, 'StreamIn':1, 'StreamOut':1, # win32ctrlTree.cpp 'GetIndent':1, 'SetIndent':1, 'ItemHasChildren':1, 'GetChildItem':1, 'GetNextSiblingItem':1, 'GetPrevSiblingItem':1, 'GetParentItem':1, 'GetFirstVisibleItem':1, 'GetNextVisibleItem':1, 'GetPrevVisibleItem':1, 'GetSelectedItem':1, 'GetDropHilightItem':1, 'GetRootItem':1, 'GetItemState':1, 'SetItemState':1, 'GetItemImage':1, 'SetItemImage':1, 'SetItemText':1, 'GetItemText':1, 'GetItemData':1, 'SetItemData':1, 'GetItemRect':1, 'GetEditControl':1, 'GetVisibleCount':1, 'InsertItem':1, 'DeleteItem':1, 'Expand':1, 'Select':1, 'SelectItem':1, 'SelectDropTarget':1, 'SelectSetFirstVisible':1, 'EditLabel':1, 'CreateDragImage':1, 'SortChildren':1, 'EnsureVisible':1, 'HitTest':1, # win32dc.cpp 'AbortDoc':1, 'Arc':1, 'BeginPath':1, 'BitBlt':1, 'Chord':1, 'CreateCompatibleDC':1, 'CreatePrinterDC':1, 'CreatePrinterDC':1, 'DeleteDC':1, 'DPtoLP':1, 'Draw3dRect':1, 'DrawFocusRect':1, 'DrawFrameControl':1, 'DrawIcon':1, 'DrawText':1, 'Ellipse':1, 'EndDoc':1, 'EndPage':1, 'EndPath':1, 'ExtTextOut':1, 'FillPath':1, 'FillRect':1, 'FillSolidRect':1, 'FrameRect':1, 'GetBrushOrg':1, 'GetClipBox':1, 'GetCurrentPosition':1, 'GetDeviceCaps':1, 'GetHandleAttrib':1, 'GetHandleOutput':1, 'GetMapMode':1, 'GetNearestColor':1, 'GetPixel':1, 'GetSafeHdc':1, 'GetPixel':1, 'GetSafeHdc':1, 'GetTextExtent':1, 'GetTextExtentPoint':1, 'GetTextFace':1, 'GetTextMetrics':1, 'GetViewportExt':1, 'GetViewportOrg':1, 'GetWindowExt':1, 'GetWindowOrg':1, 'IntersectClipRect':1, 'IsPrinting':1, 'LineTo':1, 'LPtoDP':1, 'MoveTo':1, 'OffsetWindowOrg':1, 'OffsetViewportOrg':1, 'PatBlt':1, 'Pie':1, 'PolyBezier':1, 'Polygon':1, 'Polyline':1, 'RealizePalette':1, 'Rectangle':1, 'RectVisible':1, 'RestoreDC':1, 'SaveDC':1, 'ScaleWindowExt':1, 'ScaleViewportExt':1, 'SelectClipRgn':1, 'SelectObject':1, 'SelectPalette':1, 'SetBkColor':1, 'SetBkMode':1, 'SetBrushOrg':1, 'SetGraphicsMode':1, 'SetMapMode':1, 'SetPixel':1, 'SetPolyFillMode':1, 'SetROP2':1, 'SetTextAlign':1, 'SetTextColor':1, 'SetWindowExt':1, 'SetWindowOrg':1, 'SetViewportExt':1, 'SetViewportOrg':1, 'SetWorldTransform':1, 'StartDoc':1, 'StartPage':1, 'StretchBlt':1, 'StrokeAndFinish':1, 'StrokePath':1, 'TextOut':1, # win32dlg.cpp 'data':1, 'datalist':1, 'DoModal':1, 'EndDialog':1, 'GotoDlgCtrl':1, 'MapDialogRect':1, 'OnCancel':1, 'OnOK':1, 'OnInitDialog':1, # 'GetPathName':1, 'GetFileName':1, 'GetFileExt':1, 'GetFileTitle':1, 'GetPathNames':1, 'GetReadOnlyPref':1, 'GetOFNTitle':1, 'SetOFNInitialDir':1, # 'GetCurrentFont':1, 'GetCharFormat':1, 'GetColor':1, 'GetFaceName':1, 'GetStyleName':1, 'GetSize':1, 'GetWeight':1, 'IsStrikeOut':1, 'IsUnderline':1, 'IsBold':1, 'IsItalic':1, # 'GetSavedCustomColors':1, 'SetCurrentColor':1, 'SetCustomColors':1, 'GetCustomColors':1, # win32dll.cpp 'GetFileName':1, 'AttachToMFC':1, # win32doc.cpp 'DeleteContents':1, 'DoSave':1, 'DoFileSave':1, 'GetDocTemplate':1, 'GetAllViews':1, 'GetFirstView':1, 'GetPathName':1, 'GetTitle':1, 'IsModified':1, 'OnChangedViewList':1, 'OnCloseDocument':1, 'OnNewDocument':1, 'OnOpenDocument':1, 'OnSaveDocument':1, 'SetModifiedFlag':1, 'SaveModified':1, 'SetPathName':1, 'SetTitle':1, 'UpdateAllViews':1, # win32ImageList.cpp 'Add':1, 'Destroy':1, 'DeleteImageList':1, 'GetBkColor':1, 'GetSafeHandle':1, 'GetImageCount':1, 'GetImageInfo':1, 'SetBkColor':1, # win32menu.cpp 'AppendMenu':1, 'DeleteMenu':1, 'Detach':1, 'EnableMenuItem':1, 'GetHandle':1, 'GetMenuItemCount':1, 'GetMenuItemID':1, 'GetMenuString':1, 'GetSubMenu':1, 'InsertMenu':1, 'ModifyMenu':1, 'TrackPopupMenu':1, # win32prinfo.cpp 'DocObject':1, 'GetDwFlags':1, 'SetDwFlags':1, 'GetDocOffsetPage':1, 'SetDocOffsetPage':1, 'SetPrintDialog':1, 'GetDirect':1, 'SetDirect':1, 'GetPreview':1, 'SetPreview':1, 'GetContinuePrinting':1, 'SetContinuePrinting':1, 'GetCurPage':1, 'SetCurPage':1, 'GetNumPreviewPages':1, 'SetNumPreviewPages':1, 'GetUserData':1, 'SetUserData':1, 'GetDraw':1, 'SetDraw':1, 'GetPageDesc':1, 'SetPageDesc':1, 'GetMinPage':1, 'SetMinPage':1, 'GetMaxPage':1, 'SetMaxPage':1, 'GetOffsetPage':1, 'GetFromPage':1, 'GetToPage':1, 'SetHDC':1, 'CreatePrinterDC':1, 'GetCopies':1, 'GetDefaults':1, 'FreeDefaults':1, 'GetDeviceNames':1, 'GetDriveName':1, 'GetDlgFromPage':1, 'GetDlgToPage':1, 'GetPortName':1, 'GetPrinterDC':1, 'PrintAll':1, 'PrintCollate':1, 'PrintRange':1, 'PrintSelection':1, 'GetHDC':1, 'GetFlags':1, 'SetFlags':1, 'SetFromPage':1, 'SetToPage':1, 'GetPRINTDLGMinPage':1, 'SetPRINTDLGMinPage':1, 'GetPRINTDLGCopies':1, 'SetPRINTDLGCopies':1, # win32prop.cpp 'AddPage':1, 'EnableStackedTabs':1, 'GetActiveIndex':1, 'GetActivePage':1, 'GetPage':1, 'GetPageIndex':1, 'GetPageCount':1, 'GetTabCtrl':1, 'OnInitDialog':1, 'PressButton':1, 'RemovePage':1, 'SetActivePage':1, 'SetTitle':1, 'SetFinishText':1, 'SetWizardMode':1, 'SetWizardButtons':1, 'SetPSHBit':1, # 'CancelToClose':1, 'OnApply':1, 'OnReset':1, 'OnQueryCancel':1, 'OnWizardBack':1, 'OnWizardNext':1, 'OnWizardFinish':1, 'OnSetActive':1, 'OnKillActive':1, 'SetModified':1, 'SetPSPBit':1, # win32rgn.cpp 'CreateRectRgn':1, 'CombineRgn':1, 'CopyRgn':1, 'GetRgnBox':1, 'DeleteObject':1, # win32RichEdit.cpp 'GetRichEditCtrl':1, 'SetWordWrap':1, 'WrapChanged':1, 'SaveTextFile':1, 'SetPathName':1, # win32RichEditDocTemplate.cpp 'DoCreateRichEditDoc':1, # win32splitter.cpp 'GetPane':1, 'CreatePane':1, 'CreateStatic':1, 'SetColumnInfo':1, 'SetRowInfo':1, 'IdFromRowCol':1, 'DoKeyboardSplit':1, # win32template.cpp 'CreateNewFrame':1, 'DoCreateDoc':1, 'FindOpenDocument':1, 'GetDocString':1, 'GetDocumentList':1, 'GetResourceID':1, 'GetSharedMenu':1, 'InitialUpdateFrame':1, 'SetContainerInfo':1, 'SetDocStrings':1, 'OpenDocumentFile':1, # win32thread.cpp 'CreateThread':1, 'PumpIdle':1, 'PumpMessages':1, 'Run':1, 'SetMainFrame':1, 'SetThreadPriority':1, # win32toolbar.cpp 'EndDrag':1, 'StartDrag':1, 'EndResize':1, 'StartResize':1, 'ToggleDocking':1, # 'dockSite':1, 'dockBar':1, 'dockContext':1, 'dwStyle':1, # 'ptLast':1, 'rectLast':1, 'sizeLast':1, 'bDitherLast':1, 'rectDragHorz':1, 'rectDragVert':1, 'rectFrameDragHorz':1, 'rectFrameDragVert':1, 'dwDockStyle':1, 'dwStyle':1, 'dwOverDockStyle':1, 'bFlip':1, 'bForceFrame':1, 'bDragging':1, 'nHitTest':1, 'uMRUDockID':1, 'rectMRUDockPos':1, 'dwMRUFloatStyle':1, 'dwMRUFLoatPos':1, # 'CalcDynamicLayout':1, 'CalcFixedLayout':1, 'EnableDocking':1, 'EraseNonClient':1, 'GetBarStyle':1, 'GetCount':1, 'GetDockingFrame':1, 'IsFloating':1, 'SetBarStyle':1, 'ShowWindow':1, # 'GetButtonStyle':1, 'GetButtonText':1, 'GetItemID':1, 'GetToolsTips':1, 'GetToolBarCtrl':1, 'LoadBitmap':1, 'LoadToolBar':1, 'SetBarStyle':1, 'SetBitmap':1, 'SetButtonInfo':1, 'SetButtons':1, 'SetButtonStyle':1, 'SetHeight':1, 'SetSizes':1, 'SetToolTips':1, # 'AddButtons':1, 'AddStrings':1, 'AutoSize':1, 'CheckButton':1, 'CommandToIndex':1, 'Customize':1, 'DeleteButton':1, 'EnableButton':1, 'GetBitmapFlags':1, 'GetButton':1, 'GetButtonCount':1, 'GetItemRect':1, 'GetRows':1, 'HideButton':1, 'Indeterminate':1, 'InsertButton':1, 'IsButtonChecked':1, 'IsButtonEnabled':1, 'IsButtonHidden':1, 'IsButtonIndeterminate':1, 'IsButtonPressed':1, 'PressButton':1, 'SetBitmapSize':1, 'SetButtonSize':1, 'SetCmdID':1, 'SetRows':1, # 'SetIndicators':1, # win32tooltip.cpp 'UpdateTipText':1, 'AddTool':1, # win32uimodule.cpp 'GetMethodByType':1, # win32util.cpp 'left':1, 'right':1, 'top':1, 'bottom':1, # win32view.cpp 'CreateWindow':1, 'GetDocument':1, 'OnActivateView':1, 'OnInitialUpdate':1, 'OnMouseActivate':1, 'PreCreateWindow':1, 'OnFilePrint':1, 'OnFilePrintPreview':1, 'DoPreparePrinting':1, 'OnBeginPrinting':1, 'OnEndPrinting':1, # 'GetDeviceScrollPosition':1, 'GetDC':1, 'GetScrollPosition':1, 'GetTotalSize':1, 'OnCommand':1, 'ResizeParentToFit':1, 'SetScaleToFitSize':1, 'ScrollToPosition':1, 'SetScrollSizes':1, 'UpdateBars':1, # 'IsModified':1, 'LoadFile':1, 'SetModifiedFlag':1, 'GetEditCtrl':1, 'PreCreateWindow':1, 'SaveFile':1, 'OnCommand':1, # 'GetListCtrl':1, 'GetTreeCtrl':1, # win32win.cpp 'ActivateFrame':1, 'BringWindowToTop':1, 'BeginPaint':1, 'CalcWindowRect':1, 'CenterWindow':1, 'CheckRadioButton':1, 'ChildWindowFromPoint':1, 'ClientToScreen':1, 'CreateWindow':1, 'CreateWindowEx':1, 'DefWindowProc':1, 'DestroyWindow':1, 'DlgDirList':1, 'DlgDirListComboBox':1, 'DlgDirSelect':1, 'DlgDirSelectComboBox':1, 'DragAcceptFiles':1, 'DrawMenuBar':1, 'EnableWindow':1, 'EndModalLoop':1, 'EndPaint':1, 'GetCheckedRadioButton':1, 'GetClientRect':1, 'GetDC':1, 'GetDCEx':1, 'GetDlgCtrlID':1, 'GetDlgItem':1, 'GetDlgItemInt':1, 'GetDlgItemText':1, 'GetLastActivePopup':1, 'GetMenu':1, 'GetParent':1, 'GetParentFrame':1, 'GetParentOwner':1, 'GetSafeHwnd':1, 'GetScrollInfo':1, 'GetScrollPos':1, 'GetStyle':1, 'GetExStyle':1, 'GetSystemMenu':1, 'GetTopLevelFrame':1, 'GetTopLevelOwner':1, 'GetTopLevelParent':1, 'GetTopWindow':1, 'GetWindow':1, 'GetWindowDC':1, 'GetWindowPlacement':1, 'GetWindowRect':1, 'GetWindowText':1, 'HideCaret':1, 'HookAllKeyStrokes':1, 'HookKeyStroke':1, 'HookMessage':1, 'InvalidateRect':1, 'InvalidateRgn':1, 'IsChild':1, 'IsDlgButtonChecked':1, 'IsIconic':1, 'IsZoomed':1, 'IsWindow':1, 'IsWindowVisible':1, 'IsWindowEnabled':1, 'KillTimer':1, 'LockWindowUpdate':1, 'MapWindowPoints':1, 'MouseCaptured':1, 'MessageBox':1, 'ModifyStyle':1, 'ModifyStyleEx':1, 'MoveWindow':1, 'OnClose':1, 'OnCtlColor':1, 'OnEraseBkgnd':1, 'OnNcHitTest':1, 'OnPaint':1, 'OnQueryDragIcon':1, 'OnQueryNewPalette':1, 'OnSetCursor':1, 'OnMouseActivate':1, 'OnWndMsg':1, 'PreCreateWindow':1, 'PumpWaitingMessages':1, 'ReadrawWindow':1, 'ReleaseCapture':1, 'ReleaseDC':1, 'RepositionBars':1, 'RunModalLoop':1, 'PostMessage':1, 'SendMessageToDescendants':1, 'SendMessage':1, 'SetActiveWindow':1, 'SetForegroundWindow':1, 'SetWindowPos':1, 'SetScreenToClient':1, 'SetCapture':1, 'SetDlgItemText':1, 'SetFocus':1, 'SetFont':1, 'SetMenu':1, 'SetRedraw':1, 'SetScrollPos':1, 'SetScrollInfo':1, 'SetTimer':1, 'SetWindowPlacement':1, 'SetWindowText':1, 'ShowCaret':1, 'ShowScrollBar':1, 'ShowWindow':1, 'UnlockWindowUpdate':1, 'UpdateDialogControls':1, 'UpdateWindow':1, # 'BeginModalState':1, 'CreateWindow':1, 'EndModalState':1, 'DockControlBar':1, 'EnableDocking':1, 'FloatControlBar':1, 'GetActiveDocument':1, 'GetControlBar':1, 'GetMessageString':1, 'GetMessageBar':1, 'IsTracking':1, 'InModalState':1, 'LoadAccelTable':1, 'LoadFrame':1, 'LoadBarState':1, 'SaveBarState':1, 'ShowControlBar':1, 'RecalcLayout':1, 'GetActiveView':1, 'OnBarCheck':1, 'OnUpdateControlBarMenu':1, 'SetActiveView':1, # 'GetMDIClient':1, 'MDIGetActive':1, 'MDIActivate':1, 'MDINext':1, 'PreTranslateMessage':1, 'OnCommand':1, 'OnContextHelp':1, 'OnClose':1, 'GetMDIFrame':1, } elif modname == 'win32uiole': d = { # win32oleDlgInsert.cpp 'GetClassID':1, 'GetSelectionType':1, 'GetPathName':1, # win32uiole.cpp 'CreateInsertDialog':1, 'CreateOleClientItem':1, 'CreateOleDocument':1, 'DaoGetEngine':1, 'GetIDispatchForWindow':1, 'OleGetUserCtrl':1, 'OleSetUserCtrl':1, # win32uioleClientItem.cpp 'CreateNewItem':1, 'Close':1, 'DoVerb':1, 'Draw':1, 'GetActiveView':1, 'GetDocument':1, 'GetInPlaceWindow':1, 'GetItemState':1, 'GetObject':1, 'GetStorage':1, 'OnActivate':1, 'OnChange':1, 'OnChangeItemPosition':1, 'OnDeactivateUI':1, 'Run':1, 'SetItemRects':1, # win32uioledoc.cpp 'EnableCompoundFile':1, 'GetStartPosition':1, 'GetNextItem':1, 'GetInPlaceActiveItem':1, } if d: attrs.update(d) # merge return # # Find line number if compiled with -O # See traceback.tb_lineno() for algorithm # def FindLineno(co, lasti, lineno): if lineno: return lineno # not -O, SET_LINENO lineno = co.co_firstlineno ltab = co.co_lnotab iaddr = 0 i = 0 n = len(ltab) while i < n: iaddr = iaddr + ord(ltab[i]) if iaddr > lasti: break lineno = lineno + ord(ltab[i+1]) i = i + 2 return lineno # # Import and return the named module # def do_import(import_name, fromlist=[]): try: module = __import__(import_name, {}, None, fromlist) except ImportError, e: # dont report failures for common conditional imports if import_name not in \ ['posix','nt','dos','os2','mac','MacOS', 'ce','riscos','riscosenviron', 'pre', 'pcre', 'ssl']: print 'Warning: %s'%str(e) return None if not fromlist: # otherwise module is already the rightmost component # # import "os.path" really returns m=os # We must explicitly drill down to the rightmost component (m=path) # comps = string.split(import_name,'.') i = 0 while i < len(comps)-1: module = getattr(module, comps[i+1]) i = i + 1 file = getattr(module,'__file__',None) if file: # # Handle sub-imports within a package by adding the # calling module's dir to sys.path # if file[-4:] == suffix: # .pyc or .pyo file directory = string.join(string.split(file, os.sep)[:-1], os.sep) if not directory in sys.path: sys.path.append(directory) return module # # Return a dict of stored names in the co # def do_collect_names(co, globals, attrs, importLevel): local_attrs = {} # # Walk the code recursively # code = co.co_code n = len(code) i = 0 extended_arg = 0 last_import_name = None while i < n: c = code[i] op = ord(c) i = i + 1 if op == 84: # IMPORT_STAR # Python 2.x # # from foo import * # # Add the module's dictionary to globals # module = do_import(last_import_name, []) if module: # # Decrement the nest level so all names are included as attrs # _collect_attrs_from_file(module, local_attrs, importLevel-1) continue if op < 90: # if opcode has no argument extended_arg = 0 continue #################### Opcodes with argument ##################### oparg = ord(code[i]) + (ord(code[i+1]) << 8) + (extended_arg << 16) i = i + 2 extended_arg = 0 if op == 143: # EXTENDED_ARG extended_arg = oparg continue ################################################################# if op == 90: # STORE_NAME name = co.co_names[oparg] if ((co.co_flags & (CO_OPTIMIZED|CO_NEWLOCALS)) == CO_NEWLOCALS): # # Class level definition (var or func) # (May include defns in a non-optimized function) # local_attrs[name] = 1 # class C:\n name=1\n def f(self): self.name # if main module and module-level code if importLevel == 0 and (co.co_flags & CO_NEWLOCALS)==0: globals[name] = 1 # fwd ref: def f(): print name\n name=1 continue if op == 95: # STORE_ATTR name = co.co_names[oparg] if importLevel == 0: # if main code local_attrs[name] = 1 continue if op == 97: # STORE_GLOBAL name = co.co_names[oparg] if importLevel == 0: globals[name] = 1 # fwd ref: def f(): print name\n name=1 continue if op == 125: # STORE_FAST name = co.co_varnames[oparg] if ((co.co_flags & (CO_OPTIMIZED|CO_NEWLOCALS)) == CO_NEWLOCALS): # # Class level definition (var or func) # (May include defns in a non-optimized function) # local_attrs[name] = 1 # class C:\n name=1\n def f(self): self.name continue if op == 107: # IMPORT_NAME name = co.co_names[oparg] last_import_name = name if importLevel == 0: # if main code if ord(code[i]) <> 108: # if next opcode is not IMPORT_FROM # import win32com.server.register -> .server, .register comps = string.split(last_import_name,'.')[1:] for c in comps: local_attrs[c] = 1 # module = do_import(last_import_name, []) if module: # # Collect names as attributes: import foo; foo.woz # _collect_attrs_from_file(module, local_attrs, importLevel) # # Hack: import os.path if import os. # Unlike packaged modules, os.path is _implicitly_ loaded!! # if last_import_name == 'os': module = do_import('os.path', []) _collect_attrs_from_file(module, local_attrs, importLevel) continue if op == 108: # IMPORT_FROM # from xxx import name name = co.co_names[oparg] if name == '*': # Python 1.5.2 # # from foo import * # # Add the module's dictionary to globals # module = do_import(last_import_name, []) if module: # # Decrement the nest level so all names are included as attrs # _collect_attrs_from_file(module, local_attrs, importLevel-1) continue module = do_import(last_import_name, [name]) if module: fromobj = getattr(module, name, None) if type(fromobj) is types.ModuleType: # standard import if importLevel == 0: # if main code module = fromobj # Collect names as attributes: import foo; foo.woz _collect_attrs_from_file(module, local_attrs, importLevel) else: # from xxx import name (any non-module object) # Decrement the nest level so all names are included as attrs _collect_attrs_from_file(module, local_attrs, importLevel-1) continue if op == 100: # LOAD_CONST obj = co.co_consts[oparg] if type(obj) is types.CodeType: # # Recursively collect attrs in the same module (e.g., def f()) # do_collect_names(obj, globals, local_attrs, importLevel) continue if importLevel == 1: # # For first-level imports, include names as attrs # # Example, # import foo # declares name woz # foo.woz # for n in co.co_names: local_attrs[n] = 1 attrs.update(local_attrs) # merge # # Load the file's code and collect stored attributes from it # attr_files = {} def _collect_attrs_from_file(module, attrs, importLevel): if not hasattr(module, '__file__'): # # builtin - collect all names in __dict__ # if importLevel == 0: attrs.update(module.__dict__) # merge collect_extension_attrs(module.__name__, attrs) return file = module.__file__ filekey = file + "_imp_" + str(importLevel) if attr_files.has_key(filekey): return # avoid recursive loop attr_files[filekey] = 1 if file[-3:] == '.py': try: py_compile.compile(file) except IOError, e: print 'Cannot compile %s: %s'%(file, e[1]) return file = file[:-3] + suffix if file[-4:] <> suffix: # # .pyd or .so - collect all names in __dict__ # if importLevel == 0: attrs.update(module.__dict__) # merge collect_extension_attrs(module.__name__, attrs) return import marshal f = open(file, 'rb') magic = f.read(4) if magic <> MAGIC: print '%s: file is not a %s module.' % (file,suffix) return timestamp = f.read(4) # skip timestamp codeobject = marshal.load(f) f.close() if not (type(codeobject) is types.CodeType): raise Exception, '%s: file does not contain code.' % file dummy_globals = {} do_collect_names(codeobject, dummy_globals, attrs, importLevel+1) # # Recursively examine code for typos # def examine(co, file, parent_globals, attrs): if disasm: import dis codename = co.co_name if codename == '?': codename = '' print "\n * CODE BLOCK %s *******************"%codename #print "\n * CODE BLOCK %s,co_nlocals=%d,co_varnames=%s,co_flags=%s,co_argcount=%d" % (codename, co.co_nlocals,co.co_varnames,co.co_flags,co.co_argcount) dis.dis(co) globals = parent_globals.copy() code = co.co_code n = len(code) i = 0 lineno = 0 extended_arg = 0 last_import_name = None last_load_name = None last_load_const = None while i < n: c = code[i] op = ord(c) name = None i = i + 1 if op == 84: # IMPORT_STAR Python 2.x # # from foo import * # # Add the module's dictionary to globals # module = do_import(last_import_name, []) if module: for x in module.__dict__.keys(): globals[x] = 1 continue if op < 90: # if opcode has no argument extended_arg = 0 continue #################### Opcodes with argument ##################### oparg = ord(code[i]) + (ord(code[i+1]) << 8) + (extended_arg << 16) i = i + 2 extended_arg = 0 if op == 143: # EXTENDED_ARG extended_arg = oparg continue ################################################################# if op == 127: # SET_LINENO lineno = oparg continue if op == 124: # LOAD_FAST name = co.co_varnames[oparg] last_load_name = name continue if op == 125: # STORE_FAST, oparg is index into varnames name = co.co_varnames[oparg] #attrs[name] = 1 # Class C:\n cVar=123\n def x(self): self.cVar continue # # All of the following opcodes use oparg to index into # the co_names list. # if op == 90 or op == 97: # STORE_NAME or STORE_GLOBAL name = co.co_names[oparg] globals[name] = 1 #attrs[name] = 1 # Class C:\n cVar=123\n def x(self): self.cVar continue if op == 95: # STORE_ATTR name = co.co_names[oparg] attrs[name] = 1 continue if op == 107: # IMPORT_NAME name = co.co_names[oparg] last_import_name = name if ord(code[i]) <> 108: # if next opcode is not IMPORT_FROM globals[string.split(last_import_name, ".")[0]] = 1 continue if op == 108: # IMPORT_FROM # from xxx import name name = co.co_names[oparg] if name == '*': # Python 1.5.2 # # from foo import * # # Add the module's dictionary to globals # module = do_import(last_import_name, []) if module: for x in module.__dict__.keys(): globals[x] = 1 continue globals[name] = 1 continue # if op == 116 or op == 101: # LOAD_GLOBAL or LOAD_NAME name = co.co_names[oparg] if not disasm and not globals.has_key(name): print "%s might be used before set at line %d in %s." \ % (name, FindLineno(co,i-2,lineno), file) last_load_name = name continue if op == 105: # LOAD_ATTR name = co.co_names[oparg] if not disasm and not attrs.has_key(name): print "%s.%s might be undefined at line %d in %s."\ % (last_load_name, name, FindLineno(co,i-2,lineno), file) last_load_name = name # alpha.beta.gamma (beta) continue if op == 100: # LOAD_CONST obj = co.co_consts[oparg] last_load_const = obj if type(obj) is types.CodeType: # # Recursively examine code (e.g., def f(): ...) # if (co.co_flags & CO_NEWLOCALS) <> 0: # if interior code globals = parent_globals # use module-level globals examine(obj, file, globals, attrs) continue import imp MAGIC = imp.get_magic() def typo(file): import marshal f = open(file, 'rb') magic = f.read(4) if magic <> MAGIC: print '%s: file is not a %s module.' % (file,suffix) return timestamp = f.read(4) # skip timestamp codeobject = marshal.load(f) f.close() if not (type(codeobject) is types.CodeType): print '%s: file does not contain code.' % file globals = {} globals['__builtins__'] = 1 globals['__doc__'] = 1 globals['__file__'] = 1 globals['__name__'] = 1 if type(__builtins__) is types.DictType: # bug? d = __builtins__ # when loaded via import typo. Is this a python bug? elif type(__builtins__) is types.ModuleType: d = __builtins__.__dict__ # when loaded via the command line # # Add all builtin names # for x in d.keys(): globals[x] = 1 global attr_files attr_files = {} # reset attr cache # # Pass 1: Collect STORE_xxx names # attrs = builtin_attrs.copy() if not disasm: do_collect_names(codeobject, globals, attrs, 0) # # Pass 2: Examine code for typos # examine(codeobject, file, globals, attrs) def main(): import getopt try: opts, args = getopt.getopt(sys.argv[1:], 'd') except getopt.error, msg: print msg print "usage: %s [-d] file.py" % sys.argv[0] sys.exit(1) if len(args) <> 1: print "usage: %s [-d] file.py" % sys.argv[0] sys.exit(1) for opt in opts: if opt[0] == '-d': global disasm disasm = 1 # Note: because a module once loaded cannot be unloaded, we can # only process one script per run. for file in args: if file[-3:] == '.py': try: py_compile.compile(file) except IOError, e: print 'Cannot compile %s: %s'%(file, e[1]) sys.exit(1) file = file[:-3] + suffix if file[-4:] <> suffix: print '%s: file is not a python .py or %s file' % (file,suffix) typo(file) if __name__=='__main__': sys.path.append('.') # search cwd for .py files main()