Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1"""This module makes it possible to use mypy as part of a Python application. 

2 

3Since mypy still changes, the API was kept utterly simple and non-intrusive. 

4It just mimics command line activation without starting a new interpreter. 

5So the normal docs about the mypy command line apply. 

6Changes in the command line version of mypy will be immediately useable. 

7 

8Just import this module and then call the 'run' function with a parameter of 

9type List[str], containing what normally would have been the command line 

10arguments to mypy. 

11 

12Function 'run' returns a Tuple[str, str, int], namely 

13(<normal_report>, <error_report>, <exit_status>), 

14in which <normal_report> is what mypy normally writes to sys.stdout, 

15<error_report> is what mypy normally writes to sys.stderr and exit_status is 

16the exit status mypy normally returns to the operating system. 

17 

18Any pretty formatting is left to the caller. 

19 

20The 'run_dmypy' function is similar, but instead mimics invocation of 

21dmypy. Note that run_dmypy is not thread-safe and modifies sys.stdout 

22and sys.stderr during its invocation. 

23 

24Note that these APIs don't support incremental generation of error 

25messages. 

26 

27Trivial example of code using this module: 

28 

29import sys 

30from mypy import api 

31 

32result = api.run(sys.argv[1:]) 

33 

34if result[0]: 

35 print('\nType checking report:\n') 

36 print(result[0]) # stdout 

37 

38if result[1]: 

39 print('\nError report:\n') 

40 print(result[1]) # stderr 

41 

42print('\nExit status:', result[2]) 

43 

44""" 

45 

46import sys 

47 

48from io import StringIO 

49from typing import List, Tuple, TextIO, Callable 

50 

51 

52def _run(main_wrapper: Callable[[TextIO, TextIO], None]) -> Tuple[str, str, int]: 

53 

54 stdout = StringIO() 

55 stderr = StringIO() 

56 

57 try: 

58 main_wrapper(stdout, stderr) 

59 exit_status = 0 

60 except SystemExit as system_exit: 

61 exit_status = system_exit.code 

62 

63 return stdout.getvalue(), stderr.getvalue(), exit_status 

64 

65 

66def run(args: List[str]) -> Tuple[str, str, int]: 

67 # Lazy import to avoid needing to import all of mypy to call run_dmypy 

68 from mypy.main import main 

69 return _run(lambda stdout, stderr: main(None, args=args, 

70 stdout=stdout, stderr=stderr, clean_exit=True)) 

71 

72 

73def run_dmypy(args: List[str]) -> Tuple[str, str, int]: 

74 from mypy.dmypy.client import main 

75 

76 # A bunch of effort has been put into threading stdout and stderr 

77 # through the main API to avoid the threadsafety problems of 

78 # modifying sys.stdout/sys.stderr, but that hasn't been done for 

79 # the dmypy client, so we just do the non-threadsafe thing. 

80 def f(stdout: TextIO, stderr: TextIO) -> None: 

81 old_stdout = sys.stdout 

82 old_stderr = sys.stderr 

83 try: 

84 sys.stdout = stdout 

85 sys.stderr = stderr 

86 main(args) 

87 finally: 

88 sys.stdout = old_stdout 

89 sys.stderr = old_stderr 

90 

91 return _run(f)