mirror of
https://github.com/davidhalter/django-stubs.git
synced 2025-12-07 04:34:29 +08:00
solve more use cases for related managers and settings
This commit is contained in:
@@ -1,12 +1,10 @@
|
||||
from typing import cast, List
|
||||
from typing import cast, List, Optional
|
||||
|
||||
from mypy.nodes import Var, Context, SymbolNode, SymbolTableNode
|
||||
from mypy.plugin import ClassDefContext
|
||||
from mypy.semanal import SemanticAnalyzerPass2
|
||||
from mypy.types import Instance, UnionType, NoneTyp, Type
|
||||
|
||||
from mypy_django_plugin import helpers
|
||||
|
||||
|
||||
def get_error_context(node: SymbolNode) -> Context:
|
||||
context = Context()
|
||||
@@ -18,10 +16,24 @@ def filter_out_nones(typ: UnionType) -> List[Type]:
|
||||
return [item for item in typ.items if not isinstance(item, NoneTyp)]
|
||||
|
||||
|
||||
def copy_sym_of_instance(sym: SymbolTableNode) -> SymbolTableNode:
|
||||
copied = sym.copy()
|
||||
copied.node.info = sym.type.type
|
||||
return copied
|
||||
def make_sym_copy_of_setting(sym: SymbolTableNode) -> Optional[SymbolTableNode]:
|
||||
if isinstance(sym.type, Instance):
|
||||
copied = sym.copy()
|
||||
copied.node.info = sym.type.type
|
||||
return copied
|
||||
elif isinstance(sym.type, UnionType):
|
||||
instances = filter_out_nones(sym.type)
|
||||
if len(instances) > 1:
|
||||
# plain unions not supported yet
|
||||
return None
|
||||
typ = instances[0]
|
||||
if isinstance(typ, Instance):
|
||||
copied = sym.copy()
|
||||
copied.node.info = typ.type
|
||||
return copied
|
||||
return None
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def add_settings_to_django_conf_object(ctx: ClassDefContext,
|
||||
@@ -33,25 +45,24 @@ def add_settings_to_django_conf_object(ctx: ClassDefContext,
|
||||
settings_file = api.modules[settings_module]
|
||||
for name, sym in settings_file.names.items():
|
||||
if name.isupper() and isinstance(sym.node, Var):
|
||||
if isinstance(sym.type, Instance):
|
||||
copied = sym.copy()
|
||||
copied.node.info = sym.type.type
|
||||
ctx.cls.info.names[name] = copied
|
||||
|
||||
elif isinstance(sym.type, UnionType):
|
||||
instances = filter_out_nones(sym.type)
|
||||
if len(instances) > 1:
|
||||
# plain unions not supported yet
|
||||
if sym.type is not None:
|
||||
copied = make_sym_copy_of_setting(sym)
|
||||
if copied is None:
|
||||
continue
|
||||
typ = instances[0]
|
||||
if isinstance(typ, Instance):
|
||||
copied = sym.copy()
|
||||
copied.node.info = typ.type
|
||||
ctx.cls.info.names[name] = copied
|
||||
ctx.cls.info.names[name] = copied
|
||||
else:
|
||||
context = Context()
|
||||
module, node_name = sym.node.fullname().rsplit('.', 1)
|
||||
module_file = api.modules.get(module)
|
||||
if module_file is None:
|
||||
return None
|
||||
context.set_line(sym.node)
|
||||
api.msg.report(f"Need type annotation for '{sym.node.name()}'", context,
|
||||
severity='error', file=module_file.path)
|
||||
|
||||
|
||||
class DjangoConfSettingsInitializerHook(object):
|
||||
def __init__(self, settings_module: str):
|
||||
def __init__(self, settings_module: Optional[str]):
|
||||
self.settings_module = settings_module
|
||||
|
||||
def __call__(self, ctx: ClassDefContext) -> None:
|
||||
|
||||
Reference in New Issue
Block a user