22from pathlib import Path
33from sys import stdout
44from tempfile import mkstemp
5- from typing import Any , Callable , Container , List , NoReturn , Optional , Set
5+ from typing import Any , Callable , Container , List , Optional , Set
66
77from bibtexparser .bibdatabase import UndefinedString
88
4242 pass
4343
4444
45- def conflict (parser : MyParser , prefix : str , option1 : str , option2 : str ) -> NoReturn :
46- parser .error (
47- "{StBold}Conflicting options:\n {Reset}"
48- + " Specified both "
49- + prefix
50- + "{FgYellow}"
51- + option1
52- + "{Reset} and a {FgYellow}"
53- + option2
54- + "{Reset} option."
55- )
45+ def conflict (parser : MyParser , prefix : str , option1 : str , option2 : str ) -> int :
46+ try :
47+ parser .error (
48+ "{StBold}Conflicting options:\n {Reset}"
49+ + " Specified both "
50+ + prefix
51+ + "{FgYellow}"
52+ + option1
53+ + "{Reset} and a {FgYellow}"
54+ + option2
55+ + "{Reset} option."
56+ )
57+ except ValueError :
58+ return 2
5659
5760
58- def main (argv : Optional [List [str ]] = None ) -> None :
61+ def main (argv : Optional [List [str ]] = None ) -> int :
5962 """The main function of bibtexautocomplete
6063 Takes an argv like List as argument,
6164 if none, uses sys.argv
6265 see HELP_TEXT or main(["-h"]) for details"""
6366 parser = make_parser ()
6467 if parser_autocomplete is not None :
6568 parser_autocomplete (parser )
66- if argv is None :
67- args = parser .parse_args ()
68- else :
69- args = parser .parse_args (argv )
69+ try :
70+ if argv is None :
71+ args = parser .parse_args ()
72+ else :
73+ args = parser .parse_args (argv )
74+ except ValueError :
75+ return 2
7076
7177 ANSICodes .use_ansi = stdout .isatty () and not args .no_color
7278
@@ -85,14 +91,14 @@ def main(argv: Optional[List[str]] = None) -> None:
8591 PREFIX = FIELD_PREFIX ,
8692 )
8793 )
88- return
94+ return 0
8995 if args .version :
9096 print (
9197 "{NAME} version {VERSION} ({VERSION_DATE})" .format (
9298 NAME = SCRIPT_NAME , VERSION = VERSION_STR , VERSION_DATE = VERSION_DATE
9399 )
94100 )
95- return
101+ return 0
96102
97103 if args .silent :
98104 args .verbose = - args .silent
@@ -111,7 +117,7 @@ def main(argv: Optional[List[str]] = None) -> None:
111117
112118 lookups = OnlyExclude [str ].from_nonempty (args .only_query , args .dont_query ).filter (LOOKUPS , lambda x : x .name )
113119 if args .only_query != [] and args .dont_query != []:
114- conflict (parser , "a " , "-q/--only-query" , "-Q/--dont-query" )
120+ return conflict (parser , "a " , "-q/--only-query" , "-Q/--dont-query" )
115121 if args .only_query != []:
116122 # remove duplicate from list
117123 args .only_query , dups = list_unduplicate (args .only_query )
@@ -122,11 +128,11 @@ def main(argv: Optional[List[str]] = None) -> None:
122128
123129 fields = OnlyExclude [FieldType ].from_nonempty (args .only_complete , args .dont_complete )
124130 if args .only_complete != [] and args .dont_complete != []:
125- conflict (parser , "a " , "-c/--only-complete" , "-C/--dont-complete" )
131+ return conflict (parser , "a " , "-c/--only-complete" , "-C/--dont-complete" )
126132
127133 entries = OnlyExclude [str ].from_nonempty (args .only_entry , args .exclude_entry )
128134 if args .only_entry != [] and args .exclude_entry != []:
129- conflict (parser , "a " , "-e/--only-entry" , "-E/--exclude-entry" )
135+ return conflict (parser , "a " , "-e/--only-entry" , "-E/--exclude-entry" )
130136
131137 if args .protect_all_uppercase :
132138 fields_to_protect_uppercase : Container [str ] = FieldNamesSet
@@ -135,11 +141,11 @@ def main(argv: Optional[List[str]] = None) -> None:
135141 fields_to_protect_proto .default = False
136142 fields_to_protect_uppercase = fields_to_protect_proto
137143 if args .protect_all_uppercase and args .protect_uppercase != []:
138- conflict (parser , "" , "--fpa/--protect-all-uppercase" , "--fp/--protect-uppercase" )
144+ return conflict (parser , "" , "--fpa/--protect-all-uppercase" , "--fp/--protect-uppercase" )
139145 if args .protect_all_uppercase and args .dont_protect_uppercase != []:
140- conflict (parser , "" , "--fpa/--protect-all-uppercase" , "--FP/--dont-protect-uppercase" )
146+ return conflict (parser , "" , "--fpa/--protect-all-uppercase" , "--FP/--dont-protect-uppercase" )
141147 if args .protect_uppercase != [] and args .dont_protect_uppercase != []:
142- conflict (parser , "a " , "--fp/--protect-uppercase" , "--FP/--dont-protect-uppercase" )
148+ return conflict (parser , "a " , "--fp/--protect-uppercase" , "--FP/--dont-protect-uppercase" )
143149
144150 if args .force_overwrite :
145151 fields_to_overwrite : Set [FieldType ] = FieldNamesSet
@@ -148,20 +154,23 @@ def main(argv: Optional[List[str]] = None) -> None:
148154 overwrite .default = False
149155 fields_to_overwrite = set (overwrite .filter (FieldNamesSet , lambda x : x ))
150156 if args .force_overwrite and args .overwrite != []:
151- conflict (parser , "" , "-f/--force-overwrite" , "-w/--overwrite" )
157+ return conflict (parser , "" , "-f/--force-overwrite" , "-w/--overwrite" )
152158 if args .force_overwrite and args .dont_overwrite != []:
153- conflict (parser , "" , "-f/--force-overwrite" , "-W/--dont-overwrite" )
159+ return conflict (parser , "" , "-f/--force-overwrite" , "-W/--dont-overwrite" )
154160 if args .overwrite != [] and args .dont_overwrite != []:
155- conflict (parser , "a " , "-w/--overwrite" , "-W/--dont-overwrite" )
161+ return conflict (parser , "a " , "-w/--overwrite" , "-W/--dont-overwrite" )
156162
157163 if args .diff and args .inplace :
158- parser .error (
159- "Cannot use {FgYellow}-D/--diff{Reset} flag and {FgYellow}-i/--inplace{Reset} flag "
160- "simultaneously, as there\n "
161- " is a big risk of deleting data.\n "
162- " If that is truly what you want to do, specify the output file explictly\n "
163- " with {FgYellow}-o / --output {FgGreen}<filename>{Reset}."
164- )
164+ try :
165+ parser .error (
166+ "Cannot use {FgYellow}-D/--diff{Reset} flag and {FgYellow}-i/--inplace{Reset} flag "
167+ "simultaneously, as there\n "
168+ " is a big risk of deleting data.\n "
169+ " If that is truly what you want to do, specify the output file explictly\n "
170+ " with {FgYellow}-o / --output {FgGreen}<filename>{Reset}."
171+ )
172+ except ValueError :
173+ return 2
165174
166175 try :
167176 completer = BibtexAutocomplete (
@@ -200,7 +209,7 @@ def main(argv: Optional[List[str]] = None) -> None:
200209 logger .warn ("Interrupted" )
201210 if completer .position == 0 :
202211 logger .info ("No entries were completed" )
203- return None
212+ return 5
204213 _ , tempfile = mkstemp (suffix = ".btac.bib" , prefix = "btac-interrupt-" , text = True )
205214 logger .header ("Dumping data" )
206215 with open (tempfile , "w" ) as file :
@@ -226,12 +235,14 @@ def main(argv: Optional[List[str]] = None) -> None:
226235 if i == completer .position :
227236 logger .info ("Only completed entries up to and including '{}'.\n " .format (entry .get ("ID" , "<no_id>" )))
228237 break_next = True
229-
238+ return 5
230239 except KeyboardInterrupt :
231240 logger .warn ("Interrupted x2" )
241+ return 7
232242 except ValueError :
233- exit ( 2 )
243+ return 2
234244 except UndefinedString :
235- exit ( 1 )
245+ return 1
236246 except (IOError , UnicodeDecodeError ):
237- exit (1 )
247+ return 1
248+ return 0
0 commit comments