or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

admin.mdauth.mdcontrib.mddatabase-orm.mdforms.mdhttp.mdindex.mdmigrations.mdmypy-plugin.mdsignals.mdtemplates.mdtransactions.mdurls.mdviews.md

mypy-plugin.mddocs/

0

# MyPy Plugin

1

2

Django-stubs includes a comprehensive MyPy plugin that enhances type checking for Django-specific patterns, providing better inference for QuerySets, model fields, forms, and request handling.

3

4

## Capabilities

5

6

### Plugin Configuration

7

8

Main plugin class and configuration for enhanced Django type checking.

9

10

```python { .api }

11

class DjangoPlugin:

12

"""

13

Main MyPy plugin class for Django type checking enhancement.

14

15

Provides Django-specific type inference and validation.

16

"""

17

def __init__(self, options: Options): ...

18

19

def get_method_context_hook(self, fullname: str): ...

20

def get_method_signature_hook(self, fullname: str): ...

21

def get_attribute_hook(self, fullname: str): ...

22

def get_class_decorator_hook(self, fullname: str): ...

23

def get_metaclass_hook(self, fullname: str): ...

24

def get_base_class_hook(self, fullname: str): ...

25

def get_customize_class_mro_hook(self, fullname: str): ...

26

def get_dynamic_class_hook(self, fullname: str): ...

27

28

class DjangoPluginConfig:

29

"""

30

Configuration settings for Django MyPy plugin.

31

32

Controls plugin behavior and feature flags.

33

"""

34

django_settings_module: str = None

35

ignore_missing_model_attributes: bool = False

36

ignore_missing_settings: bool = False

37

strict_settings: bool = False

38

39

def __init__(self, config_file: str = None): ...

40

```

41

42

### Model Field Transformations

43

44

Enhanced type inference for Django model fields and attributes.

45

46

```python { .api }

47

class ModelFieldTransformer:

48

"""

49

Transformer for model field type resolution.

50

51

Provides accurate type information for model fields and relationships.

52

"""

53

def transform_model_field(self, field_node, field_type: Type, ctx) -> Type: ...

54

def get_field_descriptor_type(self, field: Field, is_set: bool = False) -> Type: ...

55

def resolve_field_access_type(self, field: Field, access_type: str) -> Type: ...

56

57

# Field type mappings

58

def get_char_field_type(self, max_length: int = None) -> Type: ...

59

def get_integer_field_type(self) -> Type: ...

60

def get_boolean_field_type(self) -> Type: ...

61

def get_datetime_field_type(self) -> Type: ...

62

def get_foreign_key_type(self, related_model: Type) -> Type: ...

63

def get_many_to_many_type(self, related_model: Type) -> Type: ...

64

65

class FieldDescriptorTypes:

66

"""

67

Type definitions for model field descriptors.

68

69

Provides proper typing for field access patterns.

70

"""

71

# Descriptor return types

72

FIELD_GET_TYPES: dict = {

73

'CharField': 'str',

74

'TextField': 'str',

75

'IntegerField': 'int',

76

'BooleanField': 'bool',

77

'DateTimeField': 'datetime.datetime',

78

'DateField': 'datetime.date',

79

'TimeField': 'datetime.time',

80

'DecimalField': 'decimal.Decimal',

81

'FloatField': 'float',

82

'EmailField': 'str',

83

'URLField': 'str',

84

'UUIDField': 'uuid.UUID',

85

'JSONField': 'Any',

86

}

87

88

# Descriptor set types (for assignment)

89

FIELD_SET_TYPES: dict = {

90

'CharField': 'Union[str, Combinable]',

91

'TextField': 'Union[str, Combinable]',

92

'IntegerField': 'Union[int, Combinable]',

93

'BooleanField': 'Union[bool, Combinable]',

94

'DateTimeField': 'Union[datetime.datetime, str, Combinable]',

95

'DateField': 'Union[datetime.date, str, Combinable]',

96

'TimeField': 'Union[datetime.time, str, Combinable]',

97

'DecimalField': 'Union[Decimal, int, float, str, Combinable]',

98

'FloatField': 'Union[float, int, Combinable]',

99

}

100

```

101

102

### QuerySet Method Resolution

103

104

Enhanced type checking for QuerySet operations and method chaining.

105

106

```python { .api }

107

class QuerySetMethodResolver:

108

"""

109

Resolver for QuerySet method types and return values.

110

111

Provides accurate type inference for QuerySet operations.

112

"""

113

def resolve_queryset_method(self, method_name: str, base_type: Type, args: list) -> Type: ...

114

def get_queryset_filter_type(self, base_type: Type, filter_args: dict) -> Type: ...

115

def get_values_return_type(self, base_type: Type, field_names: list) -> Type: ...

116

def get_values_list_return_type(self, base_type: Type, field_names: list, flat: bool = False, named: bool = False) -> Type: ...

117

def get_annotate_return_type(self, base_type: Type, annotations: dict) -> Type: ...

118

def get_aggregate_return_type(self, aggregations: dict) -> Type: ...

119

120

# QuerySet method return types

121

QUERYSET_METHOD_TYPES: dict = {

122

'all': lambda base_type: f'QuerySet[{base_type}, {base_type}]',

123

'filter': lambda base_type: f'QuerySet[{base_type}, {base_type}]',

124

'exclude': lambda base_type: f'QuerySet[{base_type}, {base_type}]',

125

'order_by': lambda base_type: f'QuerySet[{base_type}, {base_type}]',

126

'distinct': lambda base_type: f'QuerySet[{base_type}, {base_type}]',

127

'select_related': lambda base_type: f'QuerySet[{base_type}, {base_type}]',

128

'prefetch_related': lambda base_type: f'QuerySet[{base_type}, {base_type}]',

129

'get': lambda base_type: base_type,

130

'first': lambda base_type: f'Optional[{base_type}]',

131

'last': lambda base_type: f'Optional[{base_type}]',

132

'exists': lambda base_type: 'bool',

133

'count': lambda base_type: 'int',

134

'delete': lambda base_type: 'Tuple[int, Dict[str, int]]',

135

'update': lambda base_type: 'int',

136

}

137

138

class ValuesQuerySetResolver:

139

"""

140

Special resolver for ValuesQuerySet type inference.

141

142

Handles values() and values_list() return type resolution.

143

"""

144

def resolve_values_type(self, model_type: Type, field_names: list) -> Type: ...

145

def resolve_values_list_type(self, model_type: Type, field_names: list, flat: bool = False, named: bool = False) -> Type: ...

146

def get_field_value_type(self, model_type: Type, field_name: str) -> Type: ...

147

148

# Generate proper TypedDict for values() calls

149

def create_values_typed_dict(self, model_type: Type, field_names: list) -> Type: ...

150

```

151

152

### Manager Class Processing

153

154

Type inference enhancement for model managers and custom manager methods.

155

156

```python { .api }

157

class ManagerClassProcessor:

158

"""

159

Processor for Manager class creation and method resolution.

160

161

Provides proper typing for custom manager methods.

162

"""

163

def process_manager_class(self, manager_class: Type, model_type: Type) -> Type: ...

164

def add_manager_methods(self, manager_class: Type, model_type: Type) -> None: ...

165

def resolve_manager_method_type(self, method_name: str, manager_class: Type, model_type: Type) -> Type: ...

166

167

# Default manager method types

168

MANAGER_METHOD_TYPES: dict = {

169

'get_queryset': lambda model_type: f'QuerySet[{model_type}, {model_type}]',

170

'all': lambda model_type: f'QuerySet[{model_type}, {model_type}]',

171

'filter': lambda model_type: f'QuerySet[{model_type}, {model_type}]',

172

'exclude': lambda model_type: f'QuerySet[{model_type}, {model_type}]',

173

'get': lambda model_type: model_type,

174

'create': lambda model_type: model_type,

175

'get_or_create': lambda model_type: f'Tuple[{model_type}, bool]',

176

'update_or_create': lambda model_type: f'Tuple[{model_type}, bool]',

177

'bulk_create': lambda model_type: f'List[{model_type}]',

178

'bulk_update': lambda model_type: 'int',

179

}

180

181

class RelatedManagerProcessor:

182

"""

183

Processor for related object managers (ForeignKey, ManyToMany).

184

185

Provides typing for relationship manager methods.

186

"""

187

def process_related_manager(self, field: Field, related_type: Type) -> Type: ...

188

def get_foreign_key_manager_type(self, related_type: Type) -> Type: ...

189

def get_many_to_many_manager_type(self, related_type: Type) -> Type: ...

190

def get_reverse_foreign_key_manager_type(self, related_type: Type) -> Type: ...

191

```

192

193

### Form Processing

194

195

Enhanced type checking for Django forms and form fields.

196

197

```python { .api }

198

class FormFieldProcessor:

199

"""

200

Processor for form field types and validation.

201

202

Provides accurate typing for form field operations.

203

"""

204

def process_form_field(self, field_type: Type, field_kwargs: dict) -> Type: ...

205

def get_field_clean_return_type(self, field_type: Type) -> Type: ...

206

def get_widget_type(self, field_type: Type, widget_class: Type = None) -> Type: ...

207

208

# Form field clean method return types

209

FIELD_CLEAN_TYPES: dict = {

210

'CharField': 'str',

211

'IntegerField': 'int',

212

'BooleanField': 'bool',

213

'EmailField': 'str',

214

'URLField': 'str',

215

'DateField': 'datetime.date',

216

'DateTimeField': 'datetime.datetime',

217

'TimeField': 'datetime.time',

218

'DecimalField': 'decimal.Decimal',

219

'FloatField': 'float',

220

'ChoiceField': 'str',

221

'MultipleChoiceField': 'List[str]',

222

'FileField': 'UploadedFile',

223

'ImageField': 'UploadedFile',

224

'ModelChoiceField': 'Model',

225

'ModelMultipleChoiceField': 'QuerySet',

226

}

227

228

class ModelFormProcessor:

229

"""

230

Processor for ModelForm type inference and validation.

231

232

Connects model fields to form fields with proper typing.

233

"""

234

def process_model_form(self, form_class: Type, model_class: Type) -> Type: ...

235

def get_model_form_fields(self, model_class: Type, fields: list = None, exclude: list = None) -> dict: ...

236

def convert_model_field_to_form_field(self, model_field: Field) -> Type: ...

237

def get_form_save_type(self, model_class: Type, commit: bool = True) -> Type: ...

238

239

class FormSetProcessor:

240

"""

241

Processor for FormSet and ModelFormSet types.

242

243

Provides typing for formset operations and validation.

244

"""

245

def process_formset(self, form_class: Type, formset_class: Type) -> Type: ...

246

def process_model_formset(self, model_class: Type, form_class: Type) -> Type: ...

247

def get_formset_forms_type(self, form_class: Type) -> Type: ...

248

def get_formset_save_type(self, model_class: Type) -> Type: ...

249

```

250

251

### Request Type Resolution

252

253

Enhanced type inference for HttpRequest and user attributes.

254

255

```python { .api }

256

class RequestTypeResolver:

257

"""

258

Resolver for HttpRequest type inference and user types.

259

260

Provides accurate typing for request attributes and methods.

261

"""

262

def resolve_request_type(self, request_type: Type) -> Type: ...

263

def get_request_user_type(self, request_type: Type) -> Type: ...

264

def get_request_session_type(self) -> Type: ...

265

def resolve_request_method_type(self, method_name: str) -> Type: ...

266

267

# Request attribute types

268

REQUEST_ATTRIBUTE_TYPES: dict = {

269

'method': 'str',

270

'path': 'str',

271

'path_info': 'str',

272

'GET': 'QueryDict',

273

'POST': 'QueryDict',

274

'COOKIES': 'Dict[str, str]',

275

'FILES': 'MultiValueDict',

276

'META': 'Dict[str, str]',

277

'content_type': 'str',

278

'content_params': 'Dict[str, str]',

279

'resolver_match': 'ResolverMatch',

280

}

281

282

class UserTypeResolver:

283

"""

284

Resolver for User model types in requests and authentication.

285

286

Handles custom user models and AnonymousUser types.

287

"""

288

def resolve_user_type(self, user_model: Type = None) -> Type: ...

289

def get_authenticated_user_type(self) -> Type: ...

290

def get_anonymous_user_type(self) -> Type: ...

291

def resolve_user_attribute_type(self, attr_name: str, user_type: Type) -> Type: ...

292

```

293

294

### Settings Type Resolution

295

296

Type checking for Django settings access and configuration.

297

298

```python { .api }

299

class SettingsTypeResolver:

300

"""

301

Resolver for Django settings attribute types.

302

303

Provides type information for settings access patterns.

304

"""

305

def resolve_settings_attribute(self, attr_name: str) -> Type: ...

306

def get_settings_type_from_default(self, setting_name: str, default_value) -> Type: ...

307

def validate_settings_access(self, attr_name: str) -> bool: ...

308

309

# Common Django settings types

310

SETTINGS_TYPES: dict = {

311

'DEBUG': 'bool',

312

'SECRET_KEY': 'str',

313

'ALLOWED_HOSTS': 'List[str]',

314

'INSTALLED_APPS': 'List[str]',

315

'MIDDLEWARE': 'List[str]',

316

'ROOT_URLCONF': 'str',

317

'TEMPLATES': 'List[Dict[str, Any]]',

318

'DATABASES': 'Dict[str, Dict[str, Any]]',

319

'STATIC_URL': 'str',

320

'STATIC_ROOT': 'str',

321

'MEDIA_URL': 'str',

322

'MEDIA_ROOT': 'str',

323

'DEFAULT_AUTO_FIELD': 'str',

324

'USE_TZ': 'bool',

325

'USE_I18N': 'bool',

326

'TIME_ZONE': 'str',

327

'LANGUAGE_CODE': 'str',

328

}

329

330

class LazySettingsProcessor:

331

"""

332

Processor for lazy settings object type resolution.

333

334

Handles django.conf.settings lazy loading patterns.

335

"""

336

def process_lazy_settings(self) -> Type: ...

337

def resolve_lazy_attribute_access(self, attr_name: str) -> Type: ...

338

def validate_settings_configured(self) -> bool: ...

339

```

340

341

### ORM Lookup Processing

342

343

Enhanced type checking for ORM field lookups and query expressions.

344

345

```python { .api }

346

class ORMLookupProcessor:

347

"""

348

Processor for ORM lookup type validation and inference.

349

350

Validates field lookups in filter/exclude/get operations.

351

"""

352

def process_lookup_expression(self, field_name: str, lookup_type: str, model_type: Type) -> Type: ...

353

def validate_field_lookup(self, field: Field, lookup_type: str) -> bool: ...

354

def get_lookup_value_type(self, field: Field, lookup_type: str) -> Type: ...

355

356

# Field lookup compatibility matrix

357

FIELD_LOOKUP_TYPES: dict = {

358

'CharField': ['exact', 'iexact', 'contains', 'icontains', 'startswith', 'istartswith',

359

'endswith', 'iendswith', 'regex', 'iregex', 'in', 'isnull'],

360

'IntegerField': ['exact', 'lt', 'lte', 'gt', 'gte', 'in', 'range', 'isnull'],

361

'DateTimeField': ['exact', 'lt', 'lte', 'gt', 'gte', 'in', 'range', 'year', 'month',

362

'day', 'hour', 'minute', 'second', 'date', 'time', 'isnull'],

363

'BooleanField': ['exact', 'isnull'],

364

'ForeignKey': ['exact', 'in', 'isnull', 'pk', 'related_field_lookups'],

365

}

366

367

class QueryExpressionProcessor:

368

"""

369

Processor for query expression types (F, Q, etc.).

370

371

Provides typing for complex query expressions and aggregations.

372

"""

373

def process_f_expression(self, field_name: str, model_type: Type) -> Type: ...

374

def process_q_expression(self, q_expr: dict, model_type: Type) -> Type: ...

375

def process_case_expression(self, when_clauses: list, default_value: Type) -> Type: ...

376

def process_subquery_expression(self, subquery_type: Type) -> Type: ...

377

378

class AggregationProcessor:

379

"""

380

Processor for aggregation function types and return values.

381

382

Provides accurate typing for aggregate operations.

383

"""

384

def process_aggregation(self, func_name: str, field_type: Type) -> Type: ...

385

def get_aggregate_return_type(self, func_name: str, field_type: Type) -> Type: ...

386

387

# Aggregation function return types

388

AGGREGATION_TYPES: dict = {

389

'Count': 'int',

390

'Sum': lambda field_type: field_type,

391

'Avg': lambda field_type: 'Optional[Decimal]' if field_type == 'Decimal' else 'Optional[float]',

392

'Min': lambda field_type: f'Optional[{field_type}]',

393

'Max': lambda field_type: f'Optional[{field_type}]',

394

'StdDev': 'Optional[float]',

395

'Variance': 'Optional[float]',

396

}

397

```

398

399

### Error Codes

400

401

Custom error codes for Django-specific type checking issues.

402

403

```python { .api }

404

class DjangoErrorCodes:

405

"""

406

Error codes for Django-specific MyPy errors.

407

408

Provides descriptive error messages for Django patterns.

409

"""

410

# Model-related errors

411

INVALID_FIELD_ACCESS: str = 'django-field-access'

412

MISSING_MODEL_ATTRIBUTE: str = 'django-missing-model-attr'

413

INVALID_MANAGER_METHOD: str = 'django-manager-method'

414

415

# QuerySet-related errors

416

INVALID_QUERYSET_METHOD: str = 'django-queryset-method'

417

INVALID_LOOKUP: str = 'django-invalid-lookup'

418

INCOMPATIBLE_LOOKUP_TYPE: str = 'django-lookup-type'

419

420

# Form-related errors

421

INVALID_FORM_FIELD: str = 'django-form-field'

422

MISSING_FORM_ATTRIBUTE: str = 'django-missing-form-attr'

423

424

# Settings-related errors

425

MISSING_SETTING: str = 'django-missing-setting'

426

INVALID_SETTING_TYPE: str = 'django-setting-type'

427

428

# Request-related errors

429

INVALID_REQUEST_ATTRIBUTE: str = 'django-request-attr'

430

MISSING_USER_ATTRIBUTE: str = 'django-user-attr'

431

432

def register_error_code(code: str, description: str, category: str = 'django') -> None:

433

"""

434

Register custom Django error code with MyPy.

435

436

Args:

437

code: Error code identifier

438

description: Human-readable error description

439

category: Error category for grouping

440

"""

441

442

def emit_django_error(ctx, code: str, message: str, node) -> None:

443

"""

444

Emit Django-specific error through MyPy.

445

446

Args:

447

ctx: MyPy context object

448

code: Django error code

449

message: Error message

450

node: AST node where error occurred

451

"""

452

```

453

454

### Plugin Hooks

455

456

Integration points for extending MyPy's Django type checking.

457

458

```python { .api }

459

class DjangoMethodSignatureHook:

460

"""

461

Hook for customizing method signature inference.

462

463

Allows custom typing for Django method patterns.

464

"""

465

def __call__(self, ctx) -> CallableType: ...

466

467

class DjangoAttributeHook:

468

"""

469

Hook for customizing attribute type inference.

470

471

Provides custom typing for Django attribute access.

472

"""

473

def __call__(self, ctx) -> Type: ...

474

475

class DjangoClassDecoratorHook:

476

"""

477

Hook for processing Django class decorators.

478

479

Handles typing for Django decorator patterns.

480

"""

481

def __call__(self, ctx) -> None: ...

482

483

class DjangoMetaclassHook:

484

"""

485

Hook for processing Django metaclasses.

486

487

Handles Model metaclass and other Django metaclass patterns.

488

"""

489

def __call__(self, ctx) -> None: ...

490

491

def register_django_hook(hook_name: str, hook_function) -> None:

492

"""

493

Register custom Django plugin hook.

494

495

Args:

496

hook_name: Name of the hook to register

497

hook_function: Hook implementation function

498

"""

499

500

def get_django_hook(hook_name: str):

501

"""

502

Get registered Django plugin hook by name.

503

504

Args:

505

hook_name: Name of hook to retrieve

506

507

Returns:

508

Hook function or None if not registered

509

"""

510

```

511

512

### Plugin Utilities

513

514

Utility functions for Django plugin development and debugging.

515

516

```python { .api }

517

def is_django_model(cls: Type) -> bool:

518

"""

519

Check if class is a Django model.

520

521

Args:

522

cls: Class type to check

523

524

Returns:

525

True if class inherits from django.db.models.Model

526

"""

527

528

def is_django_form(cls: Type) -> bool:

529

"""

530

Check if class is a Django form.

531

532

Args:

533

cls: Class type to check

534

535

Returns:

536

True if class inherits from django.forms.Form

537

"""

538

539

def is_django_manager(cls: Type) -> bool:

540

"""

541

Check if class is a Django manager.

542

543

Args:

544

cls: Class type to check

545

546

Returns:

547

True if class inherits from django.db.models.Manager

548

"""

549

550

def get_model_from_manager(manager_type: Type) -> Type:

551

"""

552

Extract model type from manager class.

553

554

Args:

555

manager_type: Manager class type

556

557

Returns:

558

Associated model type

559

"""

560

561

def resolve_lazy_reference(reference: str, module_name: str) -> Type:

562

"""

563

Resolve lazy string reference to actual type.

564

565

Args:

566

reference: String reference to resolve

567

module_name: Module context for resolution

568

569

Returns:

570

Resolved type object

571

"""

572

573

def debug_django_plugin(message: str, level: str = 'info') -> None:

574

"""

575

Debug logging for Django plugin development.

576

577

Args:

578

message: Debug message to log

579

level: Log level (debug, info, warning, error)

580

"""

581

```