Plugin

Protocols

class extended_mypy_django_plugin._plugin.protocols.KnownClasses(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
class extended_mypy_django_plugin._plugin.protocols.KnownAnnotations(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
classmethod resolve(fullname: str) KnownAnnotations | None

This function is an alternative to a try..catch(ValueError) that is quicker

protocol extended_mypy_django_plugin._plugin.protocols.Report

typing.Protocol.

Classes that implement this protocol must have the following methods / attributes:

additional_deps(*, file_import_path: str, imports: Set[str], super_deps: Sequence[tuple[int, str, int]], django_settings_module: str, using_incremental_cache: bool) Sequence[tuple[int, str, int]]

This is used to add to the result for the get_additional_deps mypy hook.

It takes the import path for the file being looked at, any additional deps that have already been determined for the file, the imports the file contains as a list of full imports, and the import path of the django settings module.

It must return the full set of additional deps the mypy plugin should use for this file

get_concrete_aliases(*models: str) Mapping[str, str | None]

Given import paths to some models, return a map of those models to a type alias with the concrete models for that model

If concrete models cannot be found for a model it’s entry will be given as None

get_queryset_aliases(*models: str) Mapping[str, str | None]

Given import paths to some models, return a map of those models to a type alias with the concrete querysets for that model

If concrete querysets cannot be found for a model it’s entry will be given as None

protocol extended_mypy_django_plugin._plugin.protocols.FailFunc

Used to insert an error into the mypy output

Classes that implement this protocol must have the following methods / attributes:

__call__(msg: str, code: ErrorCode | None = None) None

Call self as a function.

protocol extended_mypy_django_plugin._plugin.protocols.DeferFunc

Used to tell mypy to defer and come back later

Returns True if was able to defer

Classes that implement this protocol must have the following methods / attributes:

__call__() bool

Call self as a function.

protocol extended_mypy_django_plugin._plugin.protocols.LookupInfo

Given some fullname return a TypeInfo if one can be found

Classes that implement this protocol must have the following methods / attributes:

__call__(fullname: str) TypeInfo | None

Call self as a function.

protocol extended_mypy_django_plugin._plugin.protocols.NamedTypeOrNone

Given some fullname and arguments, find the type info for that fullname if can be found and return an instance representing that object with those arguments

Classes that implement this protocol must have the following methods / attributes:

__call__(fullname: str, args: list[Type] | None = None) Instance | None

Call self as a function.

protocol extended_mypy_django_plugin._plugin.protocols.AliasGetter

Given fullnames to zero or more models return a Mapping of those models to type aliases for the concrete aliases of that model where the value in the mapping is None if the alias could not be found.

Classes that implement this protocol must have the following methods / attributes:

__call__(*models: str) Mapping[str, str | None]

Call self as a function.

protocol extended_mypy_django_plugin._plugin.protocols.LookupAlias

Given an alias for the concrete of some model, return Instance of the models represented by that type alias

Classes that implement this protocol must have the following methods / attributes:

__call__(alias: str) Iterator[Instance | PlaceholderType]

Call self as a function.

protocol extended_mypy_django_plugin._plugin.protocols.LookupFullyQualified

Find a symbol for the provided fullname

Classes that implement this protocol must have the following methods / attributes:

__call__(fullname: str) SymbolTableNode | None

Call self as a function.

protocol extended_mypy_django_plugin._plugin.protocols.ResolveManagerMethodFromInstance

Used to fold the fix from https://github.com/typeddjango/django-stubs/pull/2027 into the plugin

Classes that implement this protocol must have the following methods / attributes:

__call__(instance: Instance, method_name: str, ctx: AttributeContext) Type

Call self as a function.

protocol extended_mypy_django_plugin._plugin.protocols.Resolver

Used to resolve concrete annotations

Classes that implement this protocol must have the following methods / attributes:

resolve(annotation: KnownAnnotations, model_type: ProperType) Instance | TypeType | UnionType | AnyType | PlaceholderType | None

Given a specific annotation and some model return the resolved concrete form.

protocol extended_mypy_django_plugin._plugin.protocols.ResolverMaker

This is used to create an instance of Resolver

Classes that implement this protocol must have the following methods / attributes:

__call__(*, ctx: DynamicClassDefContext | AnalyzeTypeContext | AttributeContext | MethodContext | FunctionContext) Resolver

Call self as a function.

protocol extended_mypy_django_plugin._plugin.protocols.SignatureInfo

This is used by the type checker to represent important information about a signature for a method or function

Classes that implement this protocol must have the following methods / attributes:

property is_guard: bool

Whether this signature represents a type guard

property transformed_ret_type: ProperType

The return type of the signature after resolving annotations

Plugin Entry

class extended_mypy_django_plugin._plugin.entry.PluginProvider(plugin_cls: type[ExtendedMypyStubs[T_Report]], virtual_dependency_handler: VirtualDependencyHandler[T_Report], locals: MutableMapping[str, object], /)

This can be used to provide both a mypy plugin as well as a __version__ that changes when mypy needs to do a full restart.

Given either the extended_mypy_django_plugin.plugin.ExtendedMypyStubs class or a subclass of that, usage is:

from extended_mypy_django_plugin.plugin import ExtendedMypyStubs, PluginProvider, VirtualDependencyHandler

plugin = PluginProvider(ExtendedMypyStubs, VirtualDependencyHandler.create_report, locals())

The Plugin

class extended_mypy_django_plugin._plugin.plugin.PlainHook(*, plugin: T_Plugin, super_hook_maker: Callable[[str], Callable[[T_Ctx], T_Ret] | None])
class extended_mypy_django_plugin._plugin.plugin.HookWithExtra(*, plugin: T_Plugin, super_hook_maker: Callable[[str], Callable[[T_Ctx], T_Ret] | None])
class extended_mypy_django_plugin._plugin.plugin.ExtendedMypyStubs(options: Options, mypy_version_tuple: tuple[int, int], virtual_dependency_handler: VirtualDependencyHandler[T_Report])

The ExtendedMypyStubs mypy plugin extends the mypy_django_plugin.main.NewSemanalDjangoPlugin found in the active python environment.

It implements the following mypy plugin hooks:

report_config_data(ctx: ReportConfigContext) dict[str, object]

Add our extra options to the report config data, so that mypy knows to clear the cache if those settings change.

get_additional_deps(file: MypyFile) list[tuple[int, str, int]]

Ensure that models are re-analyzed if any other models that depend on them change.

We use a generated “report” to re-analyze a file if a new dependency is discovered after this file has been processed.

get_type_analyze_hook

Resolve classes annotated with Concrete or DefaultQuerySet.

get_attribute_hook = <function NewSemanalDjangoPlugin.get_attribute_hook>
get_method_hook

Used to ensure Concrete.cast_as_concrete returns the appropriate type.

extra_init() None

Place to add extra logic after __init__

report_config_data(ctx: ReportConfigContext) dict[str, object]

Add our extra options to the report config data, so that mypy knows to clear the cache if those settings change.

get_additional_deps(file: MypyFile) list[tuple[int, str, int]]

Ensure that models are re-analyzed if any other models that depend on them change.

We use a generated “report” to re-analyze a file if a new dependency is discovered after this file has been processed.

get_type_analyze_hook

Resolve classes annotated with Concrete or DefaultQuerySet.

get_method_hook

Used to ensure Concrete.cast_as_concrete returns the appropriate type.

Virtual Dependencies

The documentation here still needs work and isn’t better than reading the source for extended_mypy_django_plugin._plugin.virtual_dependencies