Revision: 413
Author: roman_yakovenko
Date: 2006-08-16 05:44:41 -0700 (Wed, 16 Aug 2006)
ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=413&view=rev
Log Message:
-----------
fixing recursive bug
Modified Paths:
--------------
pydsc_dev/pydsc/pydsc.py
Modified: pydsc_dev/pydsc/pydsc.py
===================================================================
--- pydsc_dev/pydsc/pydsc.py 2006-08-16 08:48:33 UTC (rev 412)
+++ pydsc_dev/pydsc/pydsc.py 2006-08-16 12:44:41 UTC (rev 413)
@@ -1,26 +1,26 @@
-# Copyright 2004 Roman Yakovenko.
-# Distributed under the Boost Software License, Version 1.0. (See
-# accompanying file LICENSE_1_0.txt or copy at
-# http://www.boost.org/LICENSE_1_0.txt)
-
-"""
-Python Documentation Spell Checker.
-
-The pydsc module contains functionality needed to check documentation strings
-and comments for spelling errors, within Python code. The pydsc module depends
-on PyEnchant spell checker. PyEnchant provides interface for different spell
+# Copyright 2004 Roman Yakovenko.
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+"""
+Python Documentation Spell Checker.
+
+The pydsc module contains functionality needed to check documentation strings
+and comments for spelling errors, within Python code. The pydsc module depends
+on PyEnchant spell checker. PyEnchant provides interface for different spell
engines:
- * ispell
- * aspell
- * OpenOffice
-
-The use of the pydsc module is very simple - just import pydsc and all modules
-that will be imported after it will be checked. By default all spelling errors
-will be printed to sys.stdout. The pydsc checker could be customized in many
-different ways:
- * you can define set of files/directories that should be included/excluded
- from check process
- * you can redefine error messages destination
+ * ispell
+ * aspell
+ * OpenOffice
+
+The use of the pydsc module is very simple - just import pydsc and all modules
+that will be imported after it will be checked. By default all spelling errors
+will be printed to sys.stdout. The pydsc checker could be customized in many
+different ways:
+ * you can define set of files/directories that should be included/excluded
+ from check process
+ * you can redefine error messages destination
* you can redefine and/or re-configurate spell checker
Install:
@@ -28,228 +28,229 @@
Usage example:
-import pydsc
+import pydsc
import readline #errors will be printed to standart output
more complex example ( taken from pygccxml project ):
-import pydsc
+import pydsc
#test only pygccxml
-#package_directory defined earlier
-pydsc.doc_checker.filter.append( package_directory )
-pydsc.doc_checker.filter_type = pydsc.FILTER_TYPE.INCLUDE
-#
-map( pydsc.doc_checker.speller.ignore_always
- , [ 'org'
- , 'http'
- , 'bool'
- , 'str'
- , 'www'
- , 'param'
- , 'txt'
- , 'decl'
- , 'decls'
- , 'namespace'
- , 'enum'
- , 'const'
- , 'GCC'
- , 'xcc'
- , 'TODO'
- , 'typedef'
- , 'os'
- , 'normcase'
+#package_directory defined earlier
+pydsc.doc_checker.filter.append( package_directory )
+pydsc.doc_checker.filter_type = pydsc.FILTER_TYPE.INCLUDE
+#
+map( pydsc.doc_checker.speller.ignore_always
+ , [ 'org'
+ , 'http'
+ , 'bool'
+ , 'str'
+ , 'www'
+ , 'param'
+ , 'txt'
+ , 'decl'
+ , 'decls'
+ , 'namespace'
+ , 'enum'
+ , 'const'
+ , 'GCC'
+ , 'xcc'
+ , 'TODO'
+ , 'typedef'
+ , 'os'
+ , 'normcase'
, 'normpath' ] )
-
-"""
+"""
+
__version__ = '0.1'
-__author__ = 'Roman Yakovenko <rom...@gm...>'
-__url__ = 'http://sourceforge.net/projects/pygccxml/'
-__license__ = 'Boost Software License <http://boost.org/more/license_info.html>'
-
-import os
-import sys
-import pprint
-import inspect
-import __builtin__
-from enchant import checker
-
-
-#TODO: source code encoding
-# -*- coding: encoding -*-
-# -*- coding: iso-8859-15 -*-
-
-def normalize_path( some_path ):
- """return os.path.normcase( os.path.normpath( some_path ) )"""
- return os.path.normcase( os.path.normpath( some_path ) )
-
-def contains_parent_dir( path, dirs ):
- """
- returns true if one of the directories is root directory for the path,
- false otherwise
-
- @param path: path
- @type path: str
-
- @param dirs: list of directories and\\or files
- @type dirs: [ str ]
-
- @return: bool
- """
- #precondition: dirs and fpath should be normalize_path'ed before calling this function
- return bool( filter( lambda dir: path.startswith( dir ), dirs ) )
-
-class FILTER_TYPE:
- """defines few filter constants"""
- INCLUDE = 'include'
- EXCLUDE = 'exclude'
-
-class checker_t( object ):
- """
- applies spell check process on every imported module
-
- This is the main class of this module. This class applies spell check
- process on every imported module. Every documentation string within the
- module will be checked. Some comments will be checked too. You should read
- inspect module documentation, in order to find out which comments will be
- checked.
- """
-
- def __init__( self
- , speller
- , writer=None
- , filter=None
- , filter_type=None
- , ignore_identifiers=True ):
- """
- initialization method
-
- During this method, reference to __builtin__.__import__ function is
- saved in one of the members of the class, and replaced with import_
- member function.
-
- @param speller: reference to enchant.checker.SpellChecker object
- @type speller: enchant.checker.SpellChecker
-
- @param writer: reference to instance of class that has write method.
- By default sys.stdout will be used.
-
- @param filter: list of files or directories
- @type filter: [ str ]
-
- @param filter_type: provides interpretation for content of filter parameter
- @type filter_type: L{FILTER_TYPE}
-
- @param ignore_identifiers: often comments/documentation strings contains
- class\\method\\function names. Those names,
- usually introduce spell error. If ignore_identifiers
- set to True, those names will be ignored.
- @type ignore_identifiers: bool
- """
- object.__init__( self )
- self.__checked = set()
- self.__orig_import = __builtin__.__import__
- __builtin__.__import__ = self.import_
- self.__already_imported = set( sys.modules.keys() )
- self.__checked = set()
- self.speller = speller
- self.writer = writer
- if self.writer is None:
- self.writer = sys.stdout
- self.filter = filter
- if self.filter is None:
- self.filter = []
- self.filter_type = None
- if self.filter_type is None:
- self.filter_type = FILTER_TYPE.EXCLUDE
- self.ignore_identifiers = ignore_identifiers
-
- def should_be_checked( self, obj, module=None ):
- if id(obj) in self.__checked:
- return False
- if inspect.isbuiltin( obj ):
- return False
- if inspect.ismodule( obj ):
- if obj.__name__ in self.__already_imported:
- return False #do not check already imported modules
- try:
- source_file = inspect.getsourcefile(obj)
- if source_file is None:
- source_file = inspect.getfile( obj )
- source_file = normalize_path( source_file )
- if source_file in self.filter \
- or contains_parent_dir( source_file, self.filter ):
- return self.filter_type == FILTER_TYPE.INCLUDE
- else:
- return self.filter_type == FILTER_TYPE.EXCLUDE
- except TypeError:
- return False #built in module
- obj_module = inspect.getmodule( obj )
- if not obj_module is module:
- return False
- if inspect.isclass( obj ) \
- or inspect.ismethod( obj ) \
- or inspect.isfunction( obj ) \
- or inspect.isroutine( obj ) \
- or inspect.ismethoddescriptor( obj ) \
- or inspect.isdatadescriptor( obj ):
- return True
- return False
-
- def import_( self, name, globals=None, locals=None, fromlist=None ):
- self.filter = map( normalize_path, self.filter )
- pymodule = self.__orig_import( name, globals, locals, fromlist )
- if self.should_be_checked(pymodule):
- #write = self.writer.write
- #write( 'inspecting %s%s' % ( inspect.getsourcefile( pymodule ), os.linesep ) )
- self.__already_imported.add( name )
- self.check( pymodule )
- #write( 'inspecting %s done%s' % ( inspect.getsourcefile( pymodule ), os.linesep ) )
- return pymodule
-
- def __check_text_impl( self, obj, text, text_type ):
- if not text:
- return
- if self.ignore_identifiers \
- and hasattr( obj, '__name__' ) \
- and obj.__name__:
- self.speller.ignore_always( obj.__name__ )
- errors = {}
- self.speller.set_text( text )
- for error in self.speller:
- if not errors.has_key( error.word ):
- errors[ error.word ] = []
- errors[ error.word ] = self.speller.suggest()
- if not errors:
- return
- write = self.writer.write
- if inspect.getsourcefile( inspect.getmodule( obj ) ):
- write( ' error details: %s' % os.linesep )
- write( ' file : %s%s' % ( inspect.getsourcefile( inspect.getmodule( obj ) ), os.linesep ) )
- write( ' line : %d%s' % ( inspect.getsourcelines( obj )[1], os.linesep ) )
- write( ' text type : %s%s' % ( text_type, os.linesep ) )
- else:
- write( ' error details: %s' % os.linesep )
- write( ' text type : %s%s' % ( text_type, os.linesep ) )
- for word, suggestions in errors.items():
- write( ' misspelled word: %s%s' % ( word, os.linesep ) )
- write( ' suggestions : %s%s' % ( `suggestions`, os.linesep ) )
-
- def check_text( self, obj):
- self.__check_text_impl( obj, inspect.getdoc( obj ), 'documentation string' )
- if inspect.getsourcefile( obj ):
- self.__check_text_impl( obj, inspect.getcomments( obj ), 'comment' )
-
- def check( self, module ):
- self.check_text( module )
- to_be_checked = map( lambda x: x[1], inspect.getmembers( module ) )
- while to_be_checked:
- member = to_be_checked.pop(0)
- if not self.should_be_checked( member, module ):
- continue
- self.check_text( member )
- to_be_checked.extend( map( lambda x: x[1], inspect.getmembers( member ) ) )
- self.__checked.add( id(member) )
+__author__ = 'Roman Yakovenko <rom...@gm...>'
+__url__ = 'http://sourceforge.net/projects/pygccxml/'
+__license__ = 'Boost Software License <http://boost.org/more/license_info.html>'
-"""documentation spell checker instance"""
-doc_checker = checker_t( checker.SpellChecker( "en_US" ) )
\ No newline at end of file
+import os
+import sys
+import pprint
+import inspect
+import __builtin__
+from enchant import checker
+
+
+#TODO: source code encoding
+# -*- coding: encoding -*-
+# -*- coding: iso-8859-15 -*-
+
+def normalize_path( some_path ):
+ """return os.path.normcase( os.path.normpath( some_path ) )"""
+ return os.path.normcase( os.path.normpath( some_path ) )
+
+def contains_parent_dir( path, dirs ):
+ """
+ returns true if one of the directories is root directory for the path,
+ false otherwise
+
+ @param path: path
+ @type path: str
+
+ @param dirs: list of directories and\\or files
+ @type dirs: [ str ]
+
+ @return: bool
+ """
+ #precondition: dirs and fpath should be normalize_path'ed before calling this function
+ return bool( filter( lambda dir: path.startswith( dir ), dirs ) )
+
+class FILTER_TYPE:
+ """defines few filter constants"""
+ INCLUDE = 'include'
+ EXCLUDE = 'exclude'
+
+class checker_t( object ):
+ """
+ applies spell check process on every imported module
+
+ This is the main class of this module. This class applies spell check
+ process on every imported module. Every documentation string within the
+ module will be checked. Some comments will be checked too. You should read
+ inspect module documentation, in order to find out which comments will be
+ checked.
+ """
+
+ def __init__( self
+ , speller
+ , writer=None
+ , filter=None
+ , filter_type=None
+ , ignore_identifiers=True ):
+ """
+ initialization method
+
+ During this method, reference to __builtin__.__import__ function is
+ saved in one of the members of the class, and replaced with import_
+ member function.
+
+ @param speller: reference to enchant.checker.SpellChecker object
+ @type speller: enchant.checker.SpellChecker
+
+ @param writer: reference to instance of class that has write method.
+ By default sys.stdout will be used.
+
+ @param filter: list of files or directories
+ @type filter: [ str ]
+
+ @param filter_type: provides interpretation for content of filter parameter
+ @type filter_type: L{FILTER_TYPE}
+
+ @param ignore_identifiers: often comments/documentation strings contains
+ class\\method\\function names. Those names,
+ usually introduce spell error. If ignore_identifiers
+ set to True, those names will be ignored.
+ @type ignore_identifiers: bool
+ """
+ object.__init__( self )
+ self.__checked = set()
+ self.__orig_import = __builtin__.__import__
+ __builtin__.__import__ = self.import_
+ self.__already_imported = set( sys.modules.keys() )
+ self.__checked = set()
+ self.speller = speller
+ self.writer = writer
+ if self.writer is None:
+ self.writer = sys.stdout
+ self.filter = filter
+ if self.filter is None:
+ self.filter = []
+ self.filter_type = None
+ if self.filter_type is None:
+ self.filter_type = FILTER_TYPE.EXCLUDE
+ self.identifiers = set()
+ self.ignore_identifiers = ignore_identifiers
+
+ def should_be_checked( self, obj, module=None ):
+ if id(obj) in self.__checked:
+ return False
+ if inspect.isbuiltin( obj ):
+ return False
+ if inspect.ismodule( obj ):
+ if obj.__name__ in self.__already_imported:
+ return False #do not check already imported modules
+ try:
+ source_file = inspect.getsourcefile(obj)
+ if source_file is None:
+ source_file = inspect.getfile( obj )
+ source_file = normalize_path( source_file )
+ if source_file in self.filter \
+ or contains_parent_dir( source_file, self.filter ):
+ return self.filter_type == FILTER_TYPE.INCLUDE
+ else:
+ return self.filter_type == FILTER_TYPE.EXCLUDE
+ except TypeError:
+ return False #built in module
+ obj_module = inspect.getmodule( obj )
+ if not obj_module is module:
+ return False
+ if inspect.isclass( obj ) \
+ or inspect.ismethod( obj ) \
+ or inspect.isfunction( obj ) \
+ or inspect.isroutine( obj ) \
+ or inspect.ismethoddescriptor( obj ) \
+ or inspect.isdatadescriptor( obj ):
+ return True
+ return False
+
+ def import_( self, name, globals=None, locals=None, fromlist=None ):
+ self.filter = map( normalize_path, self.filter )
+ pymodule = self.__orig_import( name, globals, locals, fromlist )
+ if self.should_be_checked(pymodule):
+ #write = self.writer.write
+ #write( 'inspecting %s%s' % ( inspect.getsourcefile( pymodule ), os.linesep ) )
+ self.__already_imported.add( name )
+ self.check( pymodule )
+ #write( 'inspecting %s done%s' % ( inspect.getsourcefile( pymodule ), os.linesep ) )
+ return pymodule
+
+ def __check_text_impl( self, obj, text, text_type ):
+ if not text:
+ return
+ if self.ignore_identifiers and hasattr( obj, '__name__' ) and obj.__name__:
+ self.identifiers.add( obj.__name__ )
+ errors = {}
+ self.speller.set_text( text )
+ for error in self.speller:
+ if error.word in self.identifiers:
+ continue
+ if not errors.has_key( error.word ):
+ errors[ error.word ] = []
+ errors[ error.word ] = self.speller.suggest()
+ if not errors:
+ return
+ write = self.writer.write
+ if inspect.getsourcefile( inspect.getmodule( obj ) ):
+ write( ' error details: %s' % os.linesep )
+ write( ' file : %s%s' % ( inspect.getsourcefile( inspect.getmodule( obj ) ), os.linesep ) )
+ write( ' line : %d%s' % ( inspect.getsourcelines( obj )[1], os.linesep ) )
+ write( ' text type : %s%s' % ( text_type, os.linesep ) )
+ else:
+ write( ' error details: %s' % os.linesep )
+ write( ' text type : %s%s' % ( text_type, os.linesep ) )
+ for word, suggestions in errors.items():
+ write( ' misspelled word: %s%s' % ( word, os.linesep ) )
+ write( ' suggestions : %s%s' % ( `suggestions`, os.linesep ) )
+
+ def check_text( self, obj):
+ self.__check_text_impl( obj, inspect.getdoc( obj ), 'documentation string' )
+ if inspect.getsourcefile( obj ):
+ self.__check_text_impl( obj, inspect.getcomments( obj ), 'comment' )
+
+ def check( self, module ):
+ self.check_text( module )
+ to_be_checked = map( lambda x: x[1], inspect.getmembers( module ) )
+ while to_be_checked:
+ member = to_be_checked.pop(0)
+ if not self.should_be_checked( member, module ):
+ continue
+ self.check_text( member )
+ to_be_checked.extend( map( lambda x: x[1], inspect.getmembers( member ) ) )
+ self.__checked.add( id(member) )
+
+"""documentation spell checker instance"""
+doc_checker = checker_t( checker.SpellChecker( "en_US" ) )
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|