3939import warnings
4040from collections import defaultdict
4141from collections .abc import Callable , Generator , Iterable , Sequence
42- from getopt import GetoptError , getopt
4342from io import BufferedIOBase , BufferedReader , BytesIO
4443from itertools import chain
4544from typing import TYPE_CHECKING , NamedTuple , NewType , NoReturn , TextIO , Union
@@ -750,15 +749,20 @@ class SimilaritiesChecker(BaseRawFileChecker, Symilar):
750749
751750 name = "similarities"
752751 msgs = MSGS
753- # for available dict keys/values see the optik parser 'add_option' method
752+ MIN_SIMILARITY_HELP = "Minimum lines number of a similarity."
753+ IGNORE_COMMENTS_HELP = "Comments are removed from the similarity computation"
754+ IGNORE_DOCSTRINGS_HELP = "Docstrings are removed from the similarity computation"
755+ IGNORE_IMPORTS_HELP = "Imports are removed from the similarity computation"
756+ IGNORE_SIGNATURES_HELP = "Signatures are removed from the similarity computation"
757+ # for available dict keys/values see the option parser 'add_option' method
754758 options : Options = (
755759 (
756760 "min-similarity-lines" ,
757761 {
758762 "default" : DEFAULT_MIN_SIMILARITY_LINE ,
759763 "type" : "int" ,
760764 "metavar" : "<int>" ,
761- "help" : "Minimum lines number of a similarity." ,
765+ "help" : MIN_SIMILARITY_HELP ,
762766 },
763767 ),
764768 (
@@ -767,7 +771,7 @@ class SimilaritiesChecker(BaseRawFileChecker, Symilar):
767771 "default" : True ,
768772 "type" : "yn" ,
769773 "metavar" : "<y or n>" ,
770- "help" : "Comments are removed from the similarity computation" ,
774+ "help" : IGNORE_COMMENTS_HELP ,
771775 },
772776 ),
773777 (
@@ -776,7 +780,7 @@ class SimilaritiesChecker(BaseRawFileChecker, Symilar):
776780 "default" : True ,
777781 "type" : "yn" ,
778782 "metavar" : "<y or n>" ,
779- "help" : "Docstrings are removed from the similarity computation" ,
783+ "help" : IGNORE_DOCSTRINGS_HELP ,
780784 },
781785 ),
782786 (
@@ -785,7 +789,7 @@ class SimilaritiesChecker(BaseRawFileChecker, Symilar):
785789 "default" : True ,
786790 "type" : "yn" ,
787791 "metavar" : "<y or n>" ,
788- "help" : "Imports are removed from the similarity computation" ,
792+ "help" : IGNORE_IMPORTS_HELP ,
789793 },
790794 ),
791795 (
@@ -794,7 +798,7 @@ class SimilaritiesChecker(BaseRawFileChecker, Symilar):
794798 "default" : True ,
795799 "type" : "yn" ,
796800 "metavar" : "<y or n>" ,
797- "help" : "Signatures are removed from the similarity computation" ,
801+ "help" : IGNORE_SIGNATURES_HELP ,
798802 },
799803 ),
800804 )
@@ -876,67 +880,53 @@ def register(linter: PyLinter) -> None:
876880 linter .register_checker (SimilaritiesChecker (linter ))
877881
878882
879- def usage (status : int = 0 ) -> NoReturn :
880- """Display command line usage information."""
881- print ("finds copy pasted blocks in a set of files" )
882- print ()
883- print (
884- "Usage: symilar [-d|--duplicates min_duplicated_lines] \
885- [-i|--ignore-comments] [--ignore-docstrings] [--ignore-imports] [--ignore-signatures] file1..."
886- )
887- sys .exit (status )
888-
889-
890883def Run (argv : Sequence [str ] | None = None ) -> NoReturn :
891884 """Standalone command line access point."""
892- if argv is None :
893- argv = sys .argv [1 :]
894-
895- s_opts = "hd:i:"
896- l_opts = [
897- "help" ,
898- "duplicates=" ,
899- "ignore-comments" ,
900- "ignore-imports" ,
901- "ignore-docstrings" ,
902- "ignore-signatures" ,
903- ]
904- min_lines = DEFAULT_MIN_SIMILARITY_LINE
905- ignore_comments = False
906- ignore_docstrings = False
907- ignore_imports = False
908- ignore_signatures = False
909- try :
910- opts , args = getopt (list (argv ), s_opts , l_opts )
911- except GetoptError as e :
912- print (e )
913- usage (2 )
914- for opt , val in opts :
915- if opt in {"-d" , "--duplicates" }:
916- try :
917- min_lines = int (val )
918- except ValueError as e :
919- print (e )
920- usage (2 )
921- elif opt in {"-h" , "--help" }:
922- usage ()
923- elif opt in {"-i" , "--ignore-comments" }:
924- ignore_comments = True
925- elif opt in {"--ignore-docstrings" }:
926- ignore_docstrings = True
927- elif opt in {"--ignore-imports" }:
928- ignore_imports = True
929- elif opt in {"--ignore-signatures" }:
930- ignore_signatures = True
931- if not args :
932- usage (1 )
933- sim = Symilar (
934- min_lines , ignore_comments , ignore_docstrings , ignore_imports , ignore_signatures
885+ parser = argparse .ArgumentParser (
886+ prog = "symilar" , description = "Finds copy pasted blocks in a set of files."
887+ )
888+ parser .add_argument ("files" , nargs = "+" )
889+ parser .add_argument (
890+ "-d" ,
891+ "--duplicates" ,
892+ type = int ,
893+ default = DEFAULT_MIN_SIMILARITY_LINE ,
894+ help = SimilaritiesChecker .MIN_SIMILARITY_HELP ,
895+ )
896+ parser .add_argument (
897+ "-i" ,
898+ "--ignore-comments" ,
899+ action = "store_true" ,
900+ help = SimilaritiesChecker .IGNORE_COMMENTS_HELP ,
901+ )
902+ parser .add_argument (
903+ "--ignore-docstrings" ,
904+ action = "store_true" ,
905+ help = SimilaritiesChecker .IGNORE_DOCSTRINGS_HELP ,
906+ )
907+ parser .add_argument (
908+ "--ignore-imports" ,
909+ action = "store_true" ,
910+ help = SimilaritiesChecker .IGNORE_IMPORTS_HELP ,
911+ )
912+ parser .add_argument (
913+ "--ignore-signatures" ,
914+ action = "store_true" ,
915+ help = SimilaritiesChecker .IGNORE_SIGNATURES_HELP ,
916+ )
917+ parsed_args = parser .parse_args (args = argv )
918+ similar_runner = Symilar (
919+ min_lines = parsed_args .duplicates ,
920+ ignore_comments = parsed_args .ignore_comments ,
921+ ignore_docstrings = parsed_args .ignore_docstrings ,
922+ ignore_imports = parsed_args .ignore_imports ,
923+ ignore_signatures = parsed_args .ignore_signatures ,
935924 )
936- for filename in args :
925+ for filename in parsed_args . files :
937926 with open (filename , encoding = "utf-8" ) as stream :
938- sim .append_stream (filename , stream )
939- sim .run ()
927+ similar_runner .append_stream (filename , stream )
928+ similar_runner .run ()
929+ # the sys exit must be kept because of the unit tests that rely on it
940930 sys .exit (0 )
941931
942932
0 commit comments