or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ast-nodes.mdbuild-system.mdcommand-line-tools.mddaemon-mode.mderror-system.mdindex.mdmypyc-compiler.mdplugin-system.mdprogrammatic-api.mdstub-tools.mdtype-system.md

programmatic-api.mddocs/

0

# Programmatic API

1

2

Simple API functions for integrating mypy into Python applications. These functions provide programmatic access to mypy's type checking functionality without requiring subprocess calls.

3

4

## Capabilities

5

6

### Basic Type Checking

7

8

Run mypy programmatically with the same interface as the command line tool.

9

10

```python { .api }

11

def run(args: list[str]) -> tuple[str, str, int]:

12

"""

13

Run mypy programmatically with command line arguments.

14

15

Parameters:

16

- args: list[str] - Command line arguments (same as mypy CLI)

17

18

Returns:

19

- tuple[str, str, int]: (stdout_output, stderr_output, exit_code)

20

- stdout_output: Normal type checking output and reports

21

- stderr_output: Error messages and warnings

22

- exit_code: 0 for success, non-zero for errors

23

24

Usage:

25

result = api.run(['--strict', 'myfile.py'])

26

"""

27

```

28

29

#### Usage Example

30

31

```python

32

from mypy import api

33

34

# Type check a single file

35

result = api.run(['myfile.py'])

36

stdout, stderr, exit_code = result

37

38

if exit_code == 0:

39

print("Type checking passed!")

40

if stdout:

41

print("Output:", stdout)

42

else:

43

print("Type checking failed!")

44

if stderr:

45

print("Errors:", stderr)

46

47

# Type check with options

48

result = api.run([

49

'--strict',

50

'--show-error-codes',

51

'--python-version', '3.11',

52

'src/'

53

])

54

55

# Type check multiple files

56

result = api.run(['file1.py', 'file2.py', 'package/'])

57

```

58

59

### Daemon Mode Type Checking

60

61

Run the dmypy daemon client programmatically for faster incremental type checking.

62

63

```python { .api }

64

def run_dmypy(args: list[str]) -> tuple[str, str, int]:

65

"""

66

Run dmypy daemon client programmatically.

67

68

Parameters:

69

- args: list[str] - Command line arguments for dmypy

70

71

Returns:

72

- tuple[str, str, int]: (stdout_output, stderr_output, exit_code)

73

74

Note:

75

- Not thread-safe, modifies sys.stdout and sys.stderr during execution

76

- Requires dmypy daemon to be running (start with: dmypy daemon)

77

78

Usage:

79

result = api.run_dmypy(['check', 'myfile.py'])

80

"""

81

```

82

83

#### Usage Example

84

85

```python

86

from mypy import api

87

88

# Start daemon first (usually done separately):

89

# subprocess.run(['dmypy', 'daemon'])

90

91

# Use daemon for faster checking

92

result = api.run_dmypy(['check', 'myfile.py'])

93

stdout, stderr, exit_code = result

94

95

# Daemon supports incremental checking

96

result = api.run_dmypy(['check', '--verbose', 'src/'])

97

98

# Stop daemon when done

99

result = api.run_dmypy(['stop'])

100

```

101

102

## Integration Patterns

103

104

### CI/CD Integration

105

106

```python

107

from mypy import api

108

import sys

109

110

def type_check_project():

111

"""Type check project in CI/CD pipeline."""

112

result = api.run([

113

'--strict',

114

'--show-error-codes',

115

'--junit-xml', 'mypy-results.xml',

116

'src/'

117

])

118

119

stdout, stderr, exit_code = result

120

121

if exit_code != 0:

122

print("Type checking failed:")

123

print(stderr)

124

sys.exit(1)

125

126

print("Type checking passed!")

127

return True

128

129

if __name__ == "__main__":

130

type_check_project()

131

```

132

133

### Development Tools Integration

134

135

```python

136

from mypy import api

137

import os

138

139

class TypeChecker:

140

"""Wrapper for mypy integration in development tools."""

141

142

def __init__(self, strict=True, python_version="3.11"):

143

self.strict = strict

144

self.python_version = python_version

145

146

def check_file(self, filepath):

147

"""Check a single file."""

148

args = []

149

150

if self.strict:

151

args.append('--strict')

152

153

args.extend(['--python-version', self.python_version])

154

args.append(filepath)

155

156

return api.run(args)

157

158

def check_files(self, filepaths):

159

"""Check multiple files."""

160

args = []

161

162

if self.strict:

163

args.append('--strict')

164

165

args.extend(['--python-version', self.python_version])

166

args.extend(filepaths)

167

168

return api.run(args)

169

170

def has_errors(self, result):

171

"""Check if result has type errors."""

172

stdout, stderr, exit_code = result

173

return exit_code != 0

174

175

# Usage

176

checker = TypeChecker(strict=True)

177

result = checker.check_file('mymodule.py')

178

179

if checker.has_errors(result):

180

print("Type errors found!")

181

```

182

183

### IDE/Editor Integration

184

185

```python

186

from mypy import api

187

import tempfile

188

import os

189

190

def check_code_snippet(code, filename="<string>"):

191

"""Type check a code snippet from an editor."""

192

# Write code to temporary file

193

with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:

194

f.write(code)

195

temp_path = f.name

196

197

try:

198

# Run mypy on the temporary file

199

result = api.run(['--show-error-codes', temp_path])

200

stdout, stderr, exit_code = result

201

202

# Parse errors and convert file paths back to original filename

203

if stderr:

204

stderr = stderr.replace(temp_path, filename)

205

206

return stdout, stderr, exit_code

207

finally:

208

# Clean up temporary file

209

os.unlink(temp_path)

210

211

# Usage in editor plugin

212

code = '''

213

def greet(name: str) -> str:

214

return f"Hello, {name}!"

215

216

# This will cause a type error

217

result = greet(42)

218

'''

219

220

stdout, stderr, exit_code = check_code_snippet(code, "editor_buffer.py")

221

if exit_code != 0:

222

print("Type errors in code:")

223

print(stderr)

224

```

225

226

## Error Handling

227

228

### Common Return Codes

229

230

- **0**: No errors found

231

- **1**: Type errors found

232

- **2**: Mypy crashed or invalid arguments

233

234

### Parsing Output

235

236

```python

237

from mypy import api

238

import re

239

240

def parse_mypy_output(result):

241

"""Parse mypy output into structured format."""

242

stdout, stderr, exit_code = result

243

244

errors = []

245

if stderr:

246

# Parse error lines: filename:line:column: error: message [error-code]

247

error_pattern = r'([^:]+):(\d+):(\d+): (error|warning|note): (.+?)(?:\s+\[([^\]]+)\])?$'

248

249

for line in stderr.strip().split('\n'):

250

match = re.match(error_pattern, line)

251

if match:

252

filename, line_num, col_num, level, message, error_code = match.groups()

253

errors.append({

254

'file': filename,

255

'line': int(line_num),

256

'column': int(col_num),

257

'level': level,

258

'message': message,

259

'error_code': error_code

260

})

261

262

return {

263

'exit_code': exit_code,

264

'stdout': stdout,

265

'stderr': stderr,

266

'errors': errors

267

}

268

269

# Usage

270

result = api.run(['myfile.py'])

271

parsed = parse_mypy_output(result)

272

273

for error in parsed['errors']:

274

print(f"{error['file']}:{error['line']}: {error['message']}")

275

```

276

277

## Performance Considerations

278

279

### Single vs Multiple Files

280

281

```python

282

# Less efficient - multiple mypy invocations

283

for file in files:

284

result = api.run([file])

285

286

# More efficient - single mypy invocation

287

result = api.run(files)

288

```

289

290

### Daemon Mode for Repeated Checks

291

292

```python

293

# For repeated type checking, use daemon mode

294

result = api.run_dmypy(['check'] + files) # Much faster for large projects

295

```

296

297

### Configuration via Files

298

299

```python

300

# Use mypy.ini or pyproject.toml for configuration instead of command line args

301

result = api.run(['src/']) # Configuration loaded from files

302

```