39
39
import warnings
40
40
from collections import defaultdict
41
41
from collections .abc import Callable , Generator , Iterable , Sequence
42
- from getopt import GetoptError , getopt
43
42
from io import BufferedIOBase , BufferedReader , BytesIO
44
43
from itertools import chain
45
44
from typing import TYPE_CHECKING , NamedTuple , NewType , NoReturn , TextIO , Union
@@ -750,15 +749,20 @@ class SimilaritiesChecker(BaseRawFileChecker, Symilar):
750
749
751
750
name = "similarities"
752
751
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
754
758
options : Options = (
755
759
(
756
760
"min-similarity-lines" ,
757
761
{
758
762
"default" : DEFAULT_MIN_SIMILARITY_LINE ,
759
763
"type" : "int" ,
760
764
"metavar" : "<int>" ,
761
- "help" : "Minimum lines number of a similarity." ,
765
+ "help" : MIN_SIMILARITY_HELP ,
762
766
},
763
767
),
764
768
(
@@ -767,7 +771,7 @@ class SimilaritiesChecker(BaseRawFileChecker, Symilar):
767
771
"default" : True ,
768
772
"type" : "yn" ,
769
773
"metavar" : "<y or n>" ,
770
- "help" : "Comments are removed from the similarity computation" ,
774
+ "help" : IGNORE_COMMENTS_HELP ,
771
775
},
772
776
),
773
777
(
@@ -776,7 +780,7 @@ class SimilaritiesChecker(BaseRawFileChecker, Symilar):
776
780
"default" : True ,
777
781
"type" : "yn" ,
778
782
"metavar" : "<y or n>" ,
779
- "help" : "Docstrings are removed from the similarity computation" ,
783
+ "help" : IGNORE_DOCSTRINGS_HELP ,
780
784
},
781
785
),
782
786
(
@@ -785,7 +789,7 @@ class SimilaritiesChecker(BaseRawFileChecker, Symilar):
785
789
"default" : True ,
786
790
"type" : "yn" ,
787
791
"metavar" : "<y or n>" ,
788
- "help" : "Imports are removed from the similarity computation" ,
792
+ "help" : IGNORE_IMPORTS_HELP ,
789
793
},
790
794
),
791
795
(
@@ -794,7 +798,7 @@ class SimilaritiesChecker(BaseRawFileChecker, Symilar):
794
798
"default" : True ,
795
799
"type" : "yn" ,
796
800
"metavar" : "<y or n>" ,
797
- "help" : "Signatures are removed from the similarity computation" ,
801
+ "help" : IGNORE_SIGNATURES_HELP ,
798
802
},
799
803
),
800
804
)
@@ -876,67 +880,53 @@ def register(linter: PyLinter) -> None:
876
880
linter .register_checker (SimilaritiesChecker (linter ))
877
881
878
882
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
-
890
883
def Run (argv : Sequence [str ] | None = None ) -> NoReturn :
891
884
"""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 ,
935
924
)
936
- for filename in args :
925
+ for filename in parsed_args . files :
937
926
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
940
930
sys .exit (0 )
941
931
942
932
0 commit comments