-
Notifications
You must be signed in to change notification settings - Fork 6
/
migrate.py
122 lines (101 loc) · 4.18 KB
/
migrate.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import os
import sys
import re
import inspect
from PyQt5 import QtWidgets
class FilePatcher:
def __init__(self, path):
self._path = path
self._line_number = 1
self._previous_line = None
self._line = None
self._parent_classes = []
self._qtwidgets_imported = False
def error(self, msg):
print("ERROR: {}:{} {}".format(self._path,self._line_number, msg))
def info(self, msg , *args):
msg = msg + " ".join(args)
print("INFO: {}:{} {}".format(self._path,self._line_number, msg))
def patch(self):
out = ""
with open(self._path) as f:
previous_line = None
for self._line in f.readlines():
self.fix_object_inheritance()
self.get_parent_class()
if self._previous_line:
self.error_double_init()
self.fix_qt_widgets()
self.fix_init_with_self()
self.fix_super_with_argument()
self.fix_call_without_super()
self.error_import_missing()
self._line_number += 1
self._previous_line = self._line
out += self._line
with open(self._path, 'w+') as f:
f.write(out)
def get_parent_class(self):
"""Extract parent class to self._parent_classes var"""
if self._line.startswith("class "):
l = re.match(r".*\((.*)\):", self._line)
if l:
self._parent_classes = []
for cls in l.group(1).split(","):
self._parent_classes.append(cls.strip())
def fix_object_inheritance(self):
"""In Python3 you no longer need to inherit from object"""
if ":" in self._line:
self._line = re.sub(r"\(object\)", "", self._line)
def error_double_init(self):
"""
Detect double call to init and raise an error
"""
if ".__init__" in self._previous_line and ".__init__" in self._line:
self.error("Double init is no longer allowed")
def fix_super_with_argument(self):
"""
Thanks to Python 3 now we can call super() instead of super()
"""
if re.match(r".*super\([^)].*", self._line):
self._line = re.sub(r"super\([^)]+\)", "super()", self._line)
self.info("Fix ", self._line.strip())
def fix_init_with_self(self):
"""
In some part of the code we have super().__init__(
Now we can use super().__init__
"""
if ".__init__(self" in self._line:
self._line = re.sub(r"([A-Z\.a-z0-9_-]+)\.__init__\(self,? ?", "super().__init__(", self._line)
def fix_call_without_super():
"""
We need to call parent with super instead of class name in order to avoid issues
"""
for cls in self._parent_classes:
m = re.match(r"(.*)({})\.([a-zA-Z]+)\((self, ? ?)(.*)".format(cls), self._line)
if m:
fixed = m.group(1) + "super()." + m.group(3) + "(" + m.group(5) + "\n"
self._line = fixed
def fix_qt_widgets(self):
"""
Replace QtGui by QtWidgets when require
"""
if self._line.startswith("from ") and "import" in self._line and "QtGui" in self._line and not "QtWidgets" in self._line:
self._line = self._line.strip() + ", QtWidgets\n"
if "QtGui." in self._line:
for name, obj in inspect.getmembers(QtWidgets):
self._line = self._line.replace("QtGui." + name, "QtWidgets." + name)
def error_import_missing(self):
"""
Check if we use QtWidgets without QtGui
"""
if "QtWidgets" in self._line:
if " import " in self._line:
self._qtwidgets_imported = True
else:
if self._qtwidgets_imported is False:
self.error("QtWidgets import missing")
for root, dirs, files in os.walk('.'):
for file in files:
if file.endswith('.py'):
FilePatcher(os.path.join(root, file)).patch()