mirror of
https://github.com/davidhalter/django-stubs.git
synced 2025-12-08 21:14:49 +08:00
91 lines
3.2 KiB
Python
91 lines
3.2 KiB
Python
from typing import List, Optional, AbstractSet, MutableSet, Set
|
|
|
|
from mypy.build import BuildManager, Graph, State, PRI_ALL
|
|
from mypy.modulefinder import BuildSource
|
|
|
|
|
|
def is_module_present_in_sources(module_name: str, sources: List[BuildSource]):
|
|
return any([source.module == module_name for source in sources])
|
|
|
|
|
|
from mypy import build
|
|
|
|
old_load_graph = build.load_graph
|
|
OldState = build.State
|
|
old_sorted_components = build.sorted_components
|
|
|
|
|
|
def load_graph_to_add_settings_file_as_a_source_seed(settings_module: str):
|
|
def patched_load_graph(sources: List[BuildSource], manager: BuildManager,
|
|
old_graph: Optional[Graph] = None,
|
|
new_modules: Optional[List[State]] = None):
|
|
if not is_module_present_in_sources(settings_module, sources):
|
|
sources.append(BuildSource(None, settings_module, None))
|
|
|
|
return old_load_graph(sources=sources, manager=manager,
|
|
old_graph=old_graph,
|
|
new_modules=new_modules)
|
|
|
|
build.load_graph = patched_load_graph
|
|
|
|
|
|
def restore_original_load_graph():
|
|
from mypy import build
|
|
|
|
build.load_graph = old_load_graph
|
|
|
|
|
|
def inject_dependencies(settings_module: str):
|
|
from mypy import build
|
|
|
|
class PatchedState(build.State):
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
if self.id == 'django.conf':
|
|
self.dependencies.append(settings_module)
|
|
|
|
build.State = PatchedState
|
|
|
|
|
|
def restore_original_dependencies_handling():
|
|
from mypy import build
|
|
|
|
build.State = OldState
|
|
|
|
|
|
def _extract_dependencies(graph: Graph, state_id: str, visited_modules: Set[str]) -> Set[str]:
|
|
visited_modules.add(state_id)
|
|
dependencies = set(graph[state_id].dependencies)
|
|
for new_dep_id in dependencies.copy():
|
|
if new_dep_id not in visited_modules:
|
|
dependencies.update(_extract_dependencies(graph, new_dep_id, visited_modules))
|
|
return dependencies
|
|
|
|
|
|
def extract_module_dependencies(graph: Graph, state_id: str) -> Set[str]:
|
|
visited_modules = set()
|
|
return _extract_dependencies(graph, state_id, visited_modules=visited_modules)
|
|
|
|
|
|
def process_settings_before_dependants(settings_module: str):
|
|
def patched_sorted_components(graph: Graph,
|
|
vertices: Optional[AbstractSet[str]] = None,
|
|
pri_max: int = PRI_ALL) -> List[AbstractSet[str]]:
|
|
sccs = old_sorted_components(graph,
|
|
vertices=vertices,
|
|
pri_max=pri_max)
|
|
for i, scc in enumerate(sccs.copy()):
|
|
if 'django.conf' in scc:
|
|
django_conf_deps = set(extract_module_dependencies(graph, 'django.conf')).union({'django.conf'})
|
|
old_scc_modified = scc.difference(django_conf_deps)
|
|
new_scc = scc.difference(old_scc_modified)
|
|
if not old_scc_modified:
|
|
# already processed
|
|
break
|
|
sccs[i] = frozenset(old_scc_modified)
|
|
sccs.insert(i, frozenset(new_scc))
|
|
break
|
|
return sccs
|
|
|
|
build.sorted_components = patched_sorted_components
|