root / env / lib / python2.7 / site-packages / south / migration / utils.py @ d1a4905f
History | View | Annotate | Download (2.14 KB)
1 | d1a4905f | officers | import sys |
---|---|---|---|
2 | from collections import deque |
||
3 | |||
4 | from django.utils.datastructures import SortedDict |
||
5 | from django.db import models |
||
6 | |||
7 | from south import exceptions |
||
8 | |||
9 | |||
10 | class SortedSet(SortedDict): |
||
11 | def __init__(self, data=tuple()): |
||
12 | self.extend(data)
|
||
13 | |||
14 | def __str__(self): |
||
15 | return "SortedSet(%s)" % list(self) |
||
16 | |||
17 | def add(self, value): |
||
18 | self[value] = True |
||
19 | |||
20 | def remove(self, value): |
||
21 | del self[value] |
||
22 | |||
23 | def extend(self, iterable): |
||
24 | [self.add(k) for k in iterable] |
||
25 | |||
26 | |||
27 | def get_app_label(app): |
||
28 | """
|
||
29 | Returns the _internal_ app label for the given app module.
|
||
30 | i.e. for <module django.contrib.auth.models> will return 'auth'
|
||
31 | """
|
||
32 | return app.__name__.split('.')[-2] |
||
33 | |||
34 | |||
35 | def app_label_to_app_module(app_label): |
||
36 | """
|
||
37 | Given the app label, returns the module of the app itself (unlike models.get_app,
|
||
38 | which returns the models module)
|
||
39 | """
|
||
40 | # Get the models module
|
||
41 | app = models.get_app(app_label) |
||
42 | module_name = ".".join(app.__name__.split(".")[:-1]) |
||
43 | try:
|
||
44 | module = sys.modules[module_name] |
||
45 | except KeyError: |
||
46 | __import__(module_name, {}, {}, ['']) |
||
47 | module = sys.modules[module_name] |
||
48 | return module
|
||
49 | |||
50 | |||
51 | def flatten(*stack): |
||
52 | stack = deque(stack) |
||
53 | while stack:
|
||
54 | try:
|
||
55 | x = stack[0].next()
|
||
56 | except AttributeError: |
||
57 | stack[0] = iter(stack[0]) |
||
58 | x = stack[0].next()
|
||
59 | except StopIteration: |
||
60 | stack.popleft() |
||
61 | continue
|
||
62 | if hasattr(x, '__iter__'): |
||
63 | stack.appendleft(x) |
||
64 | else:
|
||
65 | yield x
|
||
66 | |||
67 | def _dfs(start, get_children, path): |
||
68 | if start in path: |
||
69 | raise exceptions.CircularDependency(path[path.index(start):] + [start])
|
||
70 | path.append(start) |
||
71 | yield start
|
||
72 | children = sorted(get_children(start), key=lambda x: str(x)) |
||
73 | if children:
|
||
74 | # We need to apply all the migrations this one depends on
|
||
75 | yield (_dfs(n, get_children, path) for n in children) |
||
76 | path.pop() |
||
77 | |||
78 | def dfs(start, get_children): |
||
79 | return flatten(_dfs(start, get_children, []))
|
||
80 | |||
81 | def depends(start, get_children): |
||
82 | result = SortedSet(reversed(list(dfs(start, get_children)))) |
||
83 | return list(result) |