]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/samples/ide/activegrid/tool/checker.py
   3 # Copyright (c) 2001-2004, MetaSlash Inc.  All rights reserved. 
   6 Copyright notice from pychecker: 
   8 Copyright (c) 2000-2001, MetaSlash Inc. 
  11 Redistribution and use in source and binary forms, with or without 
  12 modification, are permitted provided that the following conditions are 
  15  - Redistributions of source code must retain the above copyright 
  16    notice, this list of conditions and the following disclaimer. 
  18  - Redistributions in binary form must reproduce the above copyright 
  19    notice, this list of conditions and the following disclaimer in the 
  20    documentation and/or other materials provided with the 
  23  - Neither name of MetaSlash Inc. nor the names of contributors 
  24    may be used to endorse or promote products derived 
  25    from this software without specific prior written permission. 
  27 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  28 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  29 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
  30 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR 
  31 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
  32 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
  33 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
  34 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
  35 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
  36 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
  37 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  42 Check python source code files for possible errors and print warnings 
  45   http://pychecker.sourceforge.net/ 
  46   pychecker-list@lists.sourceforge.net 
  60 # see __init__.py for meaning, this must match the version there 
  61 LOCAL_MAIN_VERSION 
= 1 
  64 def setupNamespace(path
) : 
  65     # remove pychecker if it's the first component, it needs to be last 
  66     if sys
.path
[0][-9:] == 'pychecker' : 
  69     # make sure pychecker is last in path, so we can import 
  70     checker_path 
= os
.path
.dirname(os
.path
.dirname(path
)) 
  71     if checker_path 
not in sys
.path 
: 
  72         sys
.path
.append(checker_path
) 
  74 if __name__ 
== '__main__' : 
  75     setupNamespace(sys
.argv
[0]) 
  77 from pychecker 
import utils
 
  78 from pychecker 
import printer
 
  79 from pychecker 
import warn
 
  80 from pychecker 
import OP
 
  81 from pychecker 
import Config
 
  82 from pychecker 
import function
 
  83 from pychecker
.Warning import Warning 
  85 # Globals for storing a dictionary of info about modules and classes 
  90 _DEFAULT_MODULE_TOKENS 
= ('__builtins__', '__doc__', '__file__', '__name__', 
  92 _DEFAULT_CLASS_TOKENS 
= ('__doc__', '__name__', '__module__') 
  94 _VERSION_MISMATCH_ERROR 
= ''' 
  95 There seem to be two versions of PyChecker being used. 
  96 One is probably in python/site-packages, the other in a local directory. 
  97 If you want to run the local version, you must remove the version 
  98 from site-packages.  Or you can install the current version 
  99 by doing python setup.py install. 
 105 def _flattenList(list) : 
 106     "Returns a list which contains no lists" 
 109     for element 
in list : 
 110         if type(element
) == types
.ListType 
: 
 111             new_list
.extend(_flattenList(element
)) 
 113             new_list
.append(element
) 
 117 def getModules(arg_list
) : 
 118     "Returns a list of module names that can be imported" 
 123     for arg 
in arg_list 
: 
 124         # is this a wildcard filespec? (necessary for windows) 
 125         if '*' in arg 
or '?' in arg 
or '[' in arg 
: 
 127         new_arguments
.append(arg
) 
 129     PY_SUFFIXES 
= ['.py'] 
 132         PY_SUFFIXES
.append('.ptl') 
 133         PY_SUFFIX_LENS
.append(4) 
 136     for arg 
in _flattenList(new_arguments
) : 
 139         for suf
, suflen 
in zip(PY_SUFFIXES
, PY_SUFFIX_LENS
): 
 140             if len(arg
) > suflen 
and arg
[-suflen
:] == suf
: 
 141                 arg_dir 
= os
.path
.dirname(arg
) 
 142                 if arg_dir 
and not os
.path
.exists(arg
) : 
 143                     txt 
= _('File or pathname element does not exist: "%s"') % arg
 
 144                     _output
.AddLines(txt
) 
 147                 module_name 
= os
.path
.basename(arg
)[:-suflen
] 
 148                 if arg_dir 
not in sys
.path 
: 
 149                     sys
.path
.insert(0, arg_dir
) 
 151         modules
.append((arg
, fullpath
)) 
 157     # imp.load_module requires a real file object, so we can't just 
 158     # fiddle def lines and yield them 
 160     fd
, newfname 
= tempfile
.mkstemp(suffix
=".py", text
=True) 
 161     newf 
= os
.fdopen(fd
, 'r+') 
 164         mat 
= re
.match(r
'(\s*def\s+\w+\s*)\[(html|plain)\](.*)', line
) 
 168             newf
.write(mat
.group(1)+mat
.group(3)+'\n') 
 172 def _q_find_module(p
, path
): 
 174         return imp
.find_module(p
, path
) 
 178                 return imp
.find_module(p
, [direc
]) 
 180                 f 
= os
.path
.join(direc
, p
+".ptl") 
 181                 if os
.path
.exists(f
): 
 182                     return _q_file(file(f
)), f
, ('.ptl', 'U', 1) 
 184 def _findModule(name
) : 
 185     """Returns the result of an imp.find_module(), ie, (file, filename, smt) 
 186        name can be a module or a package name.  It is *not* a filename.""" 
 189     packages 
= string
.split(name
, '.') 
 191         # smt = (suffix, mode, type) 
 192         file, filename
, smt 
= _q_find_module(p
, path
) 
 193         if smt
[-1] == imp
.PKG_DIRECTORY 
: 
 195                 # package found - read path info from init file 
 196                 m 
= imp
.load_module(p
, file, filename
, smt
) 
 198                 if file is not None : 
 201             # importing xml plays a trick, which replaces itself with _xmlplus 
 202             # both have subdirs w/same name, but different modules in them 
 203             # we need to choose the real (replaced) version 
 206                     file, filename
, smt 
= _q_find_module(m
.__name
__, path
) 
 207                     m 
= imp
.load_module(p
, file, filename
, smt
) 
 209                     if file is not None : 
 212             new_path 
= m
.__path
__ 
 213             if type(new_path
) == types
.ListType 
: 
 215             if new_path 
not in path 
: 
 216                 path
.insert(1, new_path
) 
 217         elif smt
[-1] != imp
.PY_COMPILED
: 
 218             if p 
is not packages
[-1] : 
 219                 if file is not None : 
 221                 raise ImportError, "No module named %s" % packages
[-1] 
 222             return file, filename
, smt
 
 224     # in case we have been given a package to check 
 225     return file, filename
, smt
 
 229     "Class to hold all information about a variable" 
 231     def __init__(self
, name
, type): 
 239     __repr__ 
= utils
.std_repr
 
 242 def _filterDir(object, ignoreList
) : 
 243     "Return a list of tokens (attributes) in a class, except for ignoreList" 
 246     for token 
in ignoreList 
: 
 251 def _getClassTokens(c
) : 
 252     return _filterDir(c
, _DEFAULT_CLASS_TOKENS
) 
 256     "Class to hold all information about a class" 
 258     def __init__(self
, name
, module
) : 
 260         self
.classObject 
= getattr(module
, name
) 
 262         modname 
= getattr(self
.classObject
, '__module__', None) 
 264             # hm, some ExtensionClasses don't have a __module__ attribute 
 265             # so try parsing the type output 
 266             typerepr 
= repr(type(self
.classObject
)) 
 267             mo 
= re
.match("^<type ['\"](.+)['\"]>$", typerepr
) 
 269                 modname 
= ".".join(mo
.group(1).split(".")[:-1]) 
 271         self
.module 
= sys
.modules
.get(modname
) 
 276             txt 
= _("warning: couldn't find real module for class %s (module name: %s)\n") % (self
.classObject
, modname
) 
 277             _output
.AddLines(txt
) 
 281         self
.members 
= { '__class__': types
.ClassType
, 
 282                          '__doc__': types
.StringType
, 
 283                          '__dict__': types
.DictType
, } 
 291     __repr__ 
= utils
.std_repr
 
 293     def getFirstLine(self
) : 
 294         "Return first line we can find in THIS class, not any base classes" 
 297         classDir 
= dir(self
.classObject
) 
 298         for m 
in self
.methods
.values() : 
 299             if m 
!= None and m
.function
.func_code
.co_name 
in classDir
: 
 300                 lineNums
.append(m
.function
.func_code
.co_firstlineno
) 
 306     def allBaseClasses(self
, c 
= None) : 
 307         "Return a list of all base classes for this class and it's subclasses" 
 312         for base 
in c
.__bases
__ : 
 313             baseClasses 
= baseClasses 
+ [ base 
] + self
.allBaseClasses(base
) 
 316     def __getMethodName(self
, func_name
, className 
= None) : 
 317         if func_name
[0:2] == '__' and func_name
[-2:] != '__' : 
 318             if className 
== None : 
 319                 className 
= self
.name
 
 320             if className
[0] != '_' : 
 321                 className 
= '_' + className
 
 322             func_name 
= className 
+ func_name
 
 325     def addMethod(self
, method
, methodName 
= None) : 
 326         if type(method
) == types
.StringType 
: 
 327             self
.methods
[method
] = None 
 329             assert methodName 
is not None, "must supply methodName" 
 330             self
.methods
[methodName
] = function
.Function(method
, 1) 
 332     def addMethods(self
, classObject
) : 
 333         for classToken 
in _getClassTokens(classObject
) : 
 334             token 
= getattr(classObject
, classToken
, None) 
 338             # Looks like a method.  Need to code it this way to 
 339             # accommodate ExtensionClass and Python 2.2.  Yecchh. 
 340             if (hasattr(token
, "func_code") and 
 341                 hasattr(token
.func_code
, "co_argcount")):  
 342                 self
.addMethod(token
, token
.__name
__) 
 344             elif hasattr(token
, '__get__') and \
 
 345                  not hasattr(token
, '__set__') and \
 
 346                  type(token
) is not types
.ClassType 
: 
 347                 self
.addMethod(getattr(token
, '__name__', classToken
)) 
 349                 self
.members
[classToken
] = type(token
) 
 350                 self
.memberRefs
[classToken
] = None 
 352         self
.cleanupMemberRefs() 
 353         # add standard methods 
 354         for methodName 
in ('__class__',) : 
 355             self
.addMethod(methodName
, classObject
.__name
__) 
 357     def addMembers(self
, classObject
) : 
 358         if not cfg().onlyCheckInitForMembers 
: 
 359             for classToken 
in _getClassTokens(classObject
) : 
 360                 method 
= getattr(classObject
, classToken
, None) 
 361                 if type(method
) == types
.MethodType 
: 
 362                     self
.addMembersFromMethod(method
.im_func
) 
 365                 self
.addMembersFromMethod(classObject
.__init
__.im_func
) 
 366             except AttributeError: 
 369     def addMembersFromMethod(self
, method
) : 
 370         if not hasattr(method
, 'func_code') : 
 373         func_code
, code
, i
, maxCode
, extended_arg 
= OP
.initFuncCode(method
) 
 376             op
, oparg
, i
, extended_arg 
= OP
.getInfo(code
, i
, extended_arg
) 
 377             if op 
>= OP
.HAVE_ARGUMENT 
: 
 378                 operand 
= OP
.getOperand(op
, func_code
, oparg
) 
 379                 if OP
.LOAD_CONST(op
) or OP
.LOAD_FAST(op
) : 
 380                     stack
.append(operand
) 
 381                 elif OP
.STORE_ATTR(op
) : 
 383                         if stack
[-1] == cfg().methodArgName
: 
 386                                 value 
= type(stack
[-2]) 
 387                             self
.members
[operand
] = value
 
 388                             self
.memberRefs
[operand
] = None 
 391         self
.cleanupMemberRefs() 
 393     def cleanupMemberRefs(self
) : 
 395             del self
.memberRefs
[Config
.CHECKER_VAR
] 
 399     def abstractMethod(self
, m
): 
 400         """Return 1 if method is abstract, None if not 
 401            An abstract method always raises an exception. 
 403         if not self
.methods
.get(m
, None): 
 405         func_code
, bytes, i
, maxCode
, extended_arg 
= \
 
 406                    OP
.initFuncCode(self
.methods
[m
].function
) 
 407         # abstract if the first conditional is RAISE_VARARGS 
 409             op
, oparg
, i
, extended_arg 
= OP
.getInfo(bytes, i
, extended_arg
) 
 410             if OP
.RAISE_VARARGS(op
): 
 412             if OP
.conditional(op
): 
 416     def isAbstract(self
): 
 417         """Return the method names that make a class abstract. 
 418            An abstract class has at least one abstract method.""" 
 420         for m 
in self
.methods
.keys(): 
 421             if self
.abstractMethod(m
): 
 425 def _getLineInFile(moduleName
, linenum
): 
 427     file, filename
, smt 
= _findModule(moduleName
) 
 429         lines 
= file.readlines() 
 430         line 
= string
.rstrip(lines
[linenum 
- 1]) 
 431     except (IOError, IndexError): 
 436 def importError(moduleName
): 
 437     exc_type
, exc_value
, tb 
= sys
.exc_info() 
 439     # First, try to get a nice-looking name for this exception type. 
 440     exc_name 
= getattr(exc_type
, '__name__', None) 
 442         # either it's a string exception or a user-defined exception class 
 443         # show string or fully-qualified class name 
 444         exc_name 
= str(exc_type
) 
 446     # Print a traceback, unless this is an ImportError.  ImportError is 
 447     # presumably the most common import-time exception, so this saves 
 448     # the clutter of a traceback most of the time.  Also, the locus of 
 449     # the error is usually irrelevant for ImportError, so the lack of 
 450     # traceback shouldn't be a problem. 
 451     if exc_type 
is SyntaxError: 
 452         # SyntaxErrors are special, we want to control how we format 
 453         # the output and make it consistent for all versions of Python 
 455         msg 
= '%s (%s, line %d)' % (e
.msg
, e
.filename
, e
.lineno
) 
 456         line 
= _getLineInFile(moduleName
, e
.lineno
) 
 458         if type(offset
) is not types
.IntType
: 
 460         exc_value 
= '%s\n    %s\n   %s^' % (msg
, line
, ' ' * offset
) 
 461     elif exc_type 
is not ImportError: 
 463         txt 
= _("  Caught exception importing module %s:\n") % moduleName
 
 464         _output
.AddLines(txt
) 
 467             tbinfo 
= traceback
.extract_tb(tb
) 
 470             txt 
= _("      Unable to format traceback\n") 
 471             _output
.AddLines(txt
) 
 472         for filename
, line
, func
, text 
in tbinfo
[1:]: 
 473             txt 
= _("    File \"%s\", line %d") % (filename
, line
) 
 474             _output
.AddLines(txt
) 
 476                 txt 
= _(", in %s()") % func
 
 477                 _output
.AddLines(txt
) 
 478             _output
.AddLines("\n") 
 480                 txt 
= _("      %s\n") % text
 
 481                 _output
.AddLines(txt
) 
 483     # And finally print the exception type and value. 
 484     # Careful formatting exc_value -- can fail for some user exceptions 
 485     txt 
= "  %s: " % exc_name
 
 486     _output
.AddLines(txt
) 
 488         txt 
= str(exc_value
) + '\n' 
 489         _output
.AddLines(txt
) 
 491         txt 
= _('**error formatting exception value**\n') 
 492         _output
.AddLines(txt
) 
 495 def _getPyFile(filename
): 
 496     """Return the file and '.py' filename from a filename which could 
 497     end with .py, .pyc, or .pyo""" 
 499     if filename
[-1] in 'oc' and filename
[-4:-1] == '.py': 
 504     "Class to hold all information for a module" 
 506     def __init__(self
, moduleName
, check 
= 1, fullpath 
= None) : 
 507         self
.moduleName 
= moduleName
 
 512         self
.moduleLineNums 
= {} 
 513         self
.attributes 
= [ '__dict__' ] 
 514         self
.main_code 
= None 
 517         self
.fullpath 
= fullpath
 
 518         _allModules
[moduleName
] = self
 
 521         return self
.moduleName
 
 523     __repr__ 
= utils
.std_repr
 
 525     def addVariable(self
, var
, varType
) : 
 526         self
.variables
[var
] = Variable(var
, varType
) 
 528     def addFunction(self
, func
) : 
 529         self
.functions
[func
.__name
__] = function
.Function(func
) 
 531     def __addAttributes(self
, c
, classObject
) : 
 532         for base 
in classObject
.__bases
__ : 
 533             self
.__addAttributes
(c
, base
) 
 534         c
.addMethods(classObject
) 
 535         c
.addMembers(classObject
) 
 537     def addClass(self
, name
) : 
 538         self
.classes
[name
] = c 
= Class(name
, self
.module
) 
 540             objName 
= str(c
.classObject
) 
 542             # this can happen if there is a goofy __getattr__ 
 545             packages 
= string
.split(objName
, '.') 
 546             c
.ignoreAttrs 
= packages
[0] in cfg().blacklist
 
 547         if not c
.ignoreAttrs 
: 
 548             self
.__addAttributes
(c
, c
.classObject
) 
 550     def addModule(self
, name
) : 
 551         module 
= _allModules
.get(name
, None) 
 553             self
.modules
[name
] = module 
= Module(name
, 0) 
 554             if imp
.is_builtin(name
) == 0 : 
 557                 globalModule 
= globals().get(name
) 
 559                     module
.attributes
.extend(dir(globalModule
)) 
 561             self
.modules
[name
] = module
 
 565             filename 
= self
.module
.__file
__ 
 566         except AttributeError : 
 567             filename 
= self
.moduleName
 
 568         return _getPyFile(filename
) 
 570     def load(self
, warnings 
= None): 
 572             # there's no need to reload modules we already have 
 573             global _output
, _statusDlg
, _count
 
 574             txt 
= _("Loading Module %s\n") % self
.moduleName
 
 575             _output
.AddLines(txt
) 
 579             _statusDlg
.Update(_count
, txt
) 
 581             module 
= sys
.modules
.get(self
.moduleName
) 
 583                 if not _allModules
[self
.moduleName
].module 
: 
 584                     return self
._initModule
(module
) 
 587             return self
._initModule
(self
.setupMainCode()) 
 588         except (SystemExit, KeyboardInterrupt) : 
 589             exc_type
, exc_value
, exc_tb 
= sys
.exc_info() 
 590             raise exc_type
, exc_value
 
 591         except SyntaxError, (message
, (fileName
, line
, col
, text
)): 
 592             # ActiveGrid: added this for better feedback when module couldn't be loaded. 
 593             w 
= Warning(self
.fullpath
, line
, _("Syntax Error: %s\n%s\n%s^error near here") % (message
, text
, ' '*(col
-1))) 
 597             exc_type
, exc_value
, exc_tb 
= sys
.exc_info() 
 598             w 
= Warning(self
.moduleName
, 1, "%s: %s.\nUnable to import module %s." % (exc_type
, exc_value
, self
.moduleName
)) 
 600             importError(self
.moduleName
) 
 603     def initModule(self
, module
) : 
 605             filename 
= _getPyFile(module
.__file
__) 
 606             if string
.lower(filename
[-3:]) == '.py': 
 608                     file = open(filename
) 
 612                     self
._setupMainCode
(file, filename
, module
) 
 613             return self
._initModule
(module
) 
 616     def _initModule(self
, module
): 
 618         self
.attributes 
= dir(self
.module
) 
 620         pychecker_attr 
= getattr(module
, Config
.CHECKER_VAR
, None) 
 621         if pychecker_attr 
is not None : 
 623             utils
.updateCheckerArgs(pychecker_attr
, 'suppressions', 0, []) 
 625         for tokenName 
in _filterDir(self
.module
, _DEFAULT_MODULE_TOKENS
) : 
 626             token 
= getattr(self
.module
, tokenName
) 
 627             if isinstance(token
, types
.ModuleType
) : 
 628                 # get the real module name, tokenName could be an alias 
 629                 self
.addModule(token
.__name
__) 
 630             elif isinstance(token
, types
.FunctionType
) : 
 631                 self
.addFunction(token
) 
 632             elif isinstance(token
, types
.ClassType
) or \
 
 633                  hasattr(token
, '__bases__') : 
 634                 self
.addClass(tokenName
) 
 636                 self
.addVariable(tokenName
, type(token
)) 
 638         if pychecker_attr 
is not None : 
 642     def setupMainCode(self
) : 
 643         file, filename
, smt 
= _findModule(self
.moduleName
) 
 644         # FIXME: if the smt[-1] == imp.PKG_DIRECTORY : load __all__ 
 645         module 
= imp
.load_module(self
.moduleName
, file, filename
, smt
) 
 646         self
._setupMainCode
(file, filename
, module
) 
 649     def _setupMainCode(self
, file, filename
, module
): 
 651             self
.main_code 
= function
.create_from_file(file, filename
, module
) 
 657 def getAllModules() : 
 658     "Returns a list of all modules that should be checked." 
 660     for module 
in _allModules
.values() : 
 662             modules
.append(module
) 
 665 _BUILTIN_MODULE_ATTRS 
= { 'sys': [ 'ps1', 'ps2', 'tracebacklimit',  
 666                                    'exc_type', 'exc_value', 'exc_traceback', 
 667                                    'last_type', 'last_value', 'last_traceback', 
 671 def fixupBuiltinModules(needs_init
=0): 
 672     for moduleName 
in sys
.builtin_module_names 
: 
 674             _ 
= Module(moduleName
, 0) 
 675         module 
= _allModules
.get(moduleName
, None) 
 676         if module 
is not None : 
 678                 m 
= imp
.init_builtin(moduleName
) 
 682                 extra_attrs 
= _BUILTIN_MODULE_ATTRS
.get(moduleName
, []) 
 683                 module
.attributes 
= [ '__dict__' ] + dir(m
) + extra_attrs
 
 686 def _printWarnings(warnings
, stream
=None): 
 692     for warning 
in warnings 
: 
 693         if lastWarning 
!= None : 
 694             # ignore duplicate warnings 
 695             if cmp(lastWarning
, warning
) == 0 : 
 697             # print blank line between files 
 698             if lastWarning
.file != warning
.file : 
 700                 _output
.AddLines("\n") 
 702         lastWarning 
= warning
 
 703         _output
.AddLines(warning
.format() + "\n") 
 706 def processFiles(files
, cfg 
= None, pre_process_cb 
= None) : 
 707     # insert this here, so we find files in the local dir before std library 
 708     if sys
.path
[0] != '' : 
 709         sys
.path
.insert(0, '') 
 711     # ensure we have a config object, it's necessary 
 716         _cfg 
= Config
.Config() 
 719     utils
.initConfig(_cfg
) 
 720     for moduleName
, filename 
in getModules(files
) : 
 721         if callable(pre_process_cb
) : 
 722             pre_process_cb(moduleName
) 
 723         module 
= Module(moduleName
, fullpath 
= filename
) 
 725         # reload the given module, otherwise won't get new syntax errors. 
 726         sysModule 
= sys
.modules
.get(moduleName
) 
 733         module
.load(warnings
) 
 738 def getWarnings(files
, cfg 
= None, suppressions 
= None): 
 739     warnings 
= processFiles(files
, cfg
) 
 740     fixupBuiltinModules() 
 741     return warnings 
+ warn
.find(getAllModules(), _cfg
, suppressions
) 
 744 def _print_processing(name
) : 
 746         global _output
, _statusDlg
, _count
 
 747         txt 
= _("Processing %s...\n") % name
 
 748         _output
.AddLines(txt
) 
 750         _statusDlg
.Update(_count
, txt
) 
 754 def checkSyntax(filename
, messageView
): 
 755     """ Massively hacked version of main for ActiveGrid IDE integration """ 
 757     _cfg
, files
, suppressions 
= Config
.setupFromArgs([filename
]) 
 761     global _output
, _statusDlg
, _count
 
 762     _output 
= messageView
 
 763     # wxBug:  Need to show progress dialog box, or message window never gets updated until the method returns     
 764     _statusDlg 
= wx
.ProgressDialog(_("Check Code"), _("Checking %s") % filename
, maximum 
= 100, style 
= wx
.PD_AUTO_HIDE | wx
.PD_APP_MODAL | wx
.PD_ELAPSED_TIME
)   
 767     # insert this here, so we find files in the local dir before std library 
 768     if sys
.path
[0] != '' : 
 769         sys
.path
.insert(0, '') 
 771     importWarnings 
= processFiles(files
, _cfg
, _print_processing
) 
 772     fixupBuiltinModules() 
 774         for module 
in getAllModules() : 
 775             printer
.module(module
) 
 777     warnings 
= warn
.find(getAllModules(), _cfg
, suppressions
) 
 779     _statusDlg
.Update(100, _("Done")) 
 783         _output
.AddLines(_("\nWarnings and Errors...\n")) 
 784     if warnings 
or importWarnings 
: 
 785         _printWarnings(importWarnings 
+ warnings
) 
 789         _output
.AddLines(_("No Syntax Errors")) 
 795 ##    __pychecker__ = 'no-miximport' 
 797 ##    if LOCAL_MAIN_VERSION != pychecker.MAIN_MODULE_VERSION : 
 798 ##        sys.stderr.write(_VERSION_MISMATCH_ERROR) 
 801 ##    # remove empty arguments 
 802 ##    argv = filter(None, argv) 
 804 ##    # if the first arg starts with an @, read options from the file 
 805 ##    # after the @ (this is mostly for windows) 
 806 ##    if len(argv) >= 2 and argv[1][0] == '@': 
 807 ##        # read data from the file 
 808 ##        command_file = argv[1][1:] 
 810 ##            f = open(command_file, 'r') 
 811 ##            command_line = f.read() 
 813 ##        except IOError, err: 
 814 ##            sys.stderr.write("Unable to read commands from file: %s\n  %s\n" % \ 
 815 ##                             (command_file, err)) 
 818 ##        # convert to an argv list, keeping argv[0] and the files to process 
 819 ##        argv = argv[:1] + string.split(command_line) + argv[2:] 
 822 ##    _cfg, files, suppressions = Config.setupFromArgs(argv[1:]) 
 826 ##    # insert this here, so we find files in the local dir before std library 
 827 ##    sys.path.insert(0, '') 
 829 ##    importWarnings = processFiles(files, _cfg, _print_processing) 
 830 ##    fixupBuiltinModules() 
 831 ##    if _cfg.printParse : 
 832 ##        for module in getAllModules() : 
 833 ##            printer.module(module) 
 835 ##    warnings = warn.find(getAllModules(), _cfg, suppressions) 
 836 ##    if not _cfg.quiet : 
 837 ##        print "\nWarnings...\n" 
 838 ##    if warnings or importWarnings : 
 839 ##        _printWarnings(importWarnings + warnings) 
 842 ##    if not _cfg.quiet : 
 847 ##if __name__ == '__main__' : 
 849 ##        sys.exit(main(sys.argv)) 
 850 ##    except Config.UsageError : 
 854 ##    _orig__import__ = None 
 855 ##    _suppressions = None 
 856 ##    _warnings_cache = {} 
 858 ##    def _get_unique_warnings(warnings): 
 859 ##        for i in range(len(warnings)-1, -1, -1): 
 860 ##            w = warnings[i].format() 
 861 ##            if _warnings_cache.has_key(w): 
 864 ##                _warnings_cache[w] = 1 
 867 ##    def __import__(name, globals=None, locals=None, fromlist=None): 
 868 ##        if globals is None: 
 870 ##        if locals is None: 
 872 ##        if fromlist is None: 
 875 ##        check = not sys.modules.has_key(name) and name[:10] != 'pychecker.' 
 876 ##        pymodule = _orig__import__(name, globals, locals, fromlist) 
 879 ##                module = Module(pymodule.__name__) 
 880 ##                if module.initModule(pymodule): 
 881 ##                    warnings = warn.find([module], _cfg, _suppressions) 
 882 ##                    _printWarnings(_get_unique_warnings(warnings)) 
 884 ##                    print 'Unable to load module', pymodule.__name__ 
 886 ##                name = getattr(pymodule, '__name__', str(pymodule)) 
 892 ##        global _cfg, _suppressions, _orig__import__ 
 894 ##        args = string.split(os.environ.get('PYCHECKER', '')) 
 895 ##        _cfg, files, _suppressions = Config.setupFromArgs(args) 
 896 ##        utils.initConfig(_cfg) 
 897 ##        fixupBuiltinModules(1) 
 899 ##        # keep the orig __import__ around so we can call it 
 900 ##        import __builtin__ 
 901 ##        _orig__import__ = __builtin__.__import__ 
 902 ##        __builtin__.__import__ = __import__ 
 904 ##    if not os.environ.get('PYCHECKER_DISABLED') :