21
21
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
22
# THE SOFTWARE.
23
23
24
+ # To gradually migrate to mypy we aren't setting these globally yet
25
+ # mypy: disallow_untyped_defs=True
26
+ # mypy: disallow_untyped_calls=True
27
+
24
28
"""
25
29
Module to handle command line argument parsing, for all front-ends.
26
30
"""
27
31
28
32
import argparse
29
- from typing import Tuple
33
+ from typing import Tuple ,List ,Optional ,NoReturn ,Callable
34
+ import code
30
35
import curtsies
31
36
import cwcwidth
32
37
import greenlet
@@ -50,11 +55,11 @@ class ArgumentParserFailed(ValueError):
50
55
51
56
52
57
class RaisingArgumentParser (argparse .ArgumentParser ):
53
- def error (self ,msg ) :
58
+ def error (self ,msg : str ) -> NoReturn :
54
59
raise ArgumentParserFailed ()
55
60
56
61
57
- def version_banner (base = "bpython" )-> str :
62
+ def version_banner (base : str = "bpython" )-> str :
58
63
return _ ("{} version {} on top of Python {} {}" ).format (
59
64
base ,
60
65
__version__ ,
@@ -67,7 +72,14 @@ def copyright_banner() -> str:
67
72
return _ ("{} See AUTHORS.rst for details." ).format (__copyright__ )
68
73
69
74
70
- def parse (args ,extras = None ,ignore_stdin = False )-> Tuple :
75
+ Options = Tuple [str ,str ,Callable [[argparse ._ArgumentGroup ],None ]]
76
+
77
+
78
+ def parse (
79
+ args :Optional [List [str ]],
80
+ extras :Options = None ,
81
+ ignore_stdin :bool = False ,
82
+ )-> Tuple :
71
83
"""Receive an argument list - if None, use sys.argv - parse all args and
72
84
take appropriate action. Also receive optional extra argument: this should
73
85
be a tuple of (title, description, callback)
@@ -214,7 +226,9 @@ def callback(group):
214
226
return Config (options .config ),options ,options .args
215
227
216
228
217
- def exec_code (interpreter ,args ):
229
+ def exec_code (
230
+ interpreter :code .InteractiveInterpreter ,args :List [str ]
231
+ )-> None :
218
232
"""
219
233
Helper to execute code in a given interpreter, e.g. to implement the behavior of python3 [-i] file.py
220
234
@@ -230,9 +244,10 @@ def exec_code(interpreter, args):
230
244
old_argv ,sys .argv = sys .argv ,args
231
245
sys .path .insert (0 ,os .path .abspath (os .path .dirname (args [0 ])))
232
246
spec = importlib .util .spec_from_loader ("__console__" ,loader = None )
247
+ assert spec
233
248
mod = importlib .util .module_from_spec (spec )
234
249
sys .modules ["__console__" ]= mod
235
- interpreter .locals .update (mod .__dict__ )
236
- interpreter .locals ["__file__" ]= args [0 ]
250
+ interpreter .locals .update (mod .__dict__ )# type: ignore # TODO use a more specific type that has a .locals attribute
251
+ interpreter .locals ["__file__" ]= args [0 ]# type: ignore # TODO use a more specific type that has a .locals attribute
237
252
interpreter .runsource (source ,args [0 ],"exec" )
238
253
sys .argv = old_argv