34 "E125", "E126", "E127", "E128", "E133", "E201", |
34 "E125", "E126", "E127", "E128", "E133", "E201", |
35 "E202", "E203", "E211", "E221", "E222", "E223", |
35 "E202", "E203", "E211", "E221", "E222", "E223", |
36 "E224", "E225", "E226", "E227", "E228", "E231", |
36 "E224", "E225", "E226", "E227", "E228", "E231", |
37 "E241", "E242", "E251", "E261", "E262", "E271", |
37 "E241", "E242", "E251", "E261", "E262", "E271", |
38 "E272", "E273", "E274", "E301", "E302", "E303", |
38 "E272", "E273", "E274", "E301", "E302", "E303", |
39 "E304", "E401", "E501", "E502", "E701", "E702", |
39 "E304", "E305", "E306", "E307", "E308", "E401", |
40 "E703", "E711", "E712", |
40 "E501", "E502", "E701", "E702", "E703", "E711", |
|
41 "E712", |
41 "N804", "N805", "N806", |
42 "N804", "N805", "N806", |
42 "W191", "W291", "W292", "W293", "W391", "W603", |
43 "W191", "W291", "W292", "W293", "W391", "W603", |
43 ] |
44 ] |
44 |
45 |
45 |
46 |
46 class CodeStyleFixer(object): |
47 class CodeStyleFixer(object): |
47 """ |
48 """ |
48 Class implementing a fixer for certain code style issues. |
49 Class implementing a fixer for certain code style issues. |
49 """ |
50 """ |
50 def __init__(self, filename, sourceLines, fixCodes, noFixCodes, |
51 def __init__(self, filename, sourceLines, fixCodes, noFixCodes, |
51 maxLineLength, inPlace, eol, backup=False): |
52 maxLineLength, blankLines, inPlace, eol, backup=False): |
52 """ |
53 """ |
53 Constructor |
54 Constructor |
54 |
55 |
55 @param filename name of the file to be fixed (string) |
56 @param filename name of the file to be fixed |
|
57 @type str |
56 @param sourceLines list of source lines including eol marker |
58 @param sourceLines list of source lines including eol marker |
57 (list of string) |
59 @type list of str |
58 @param fixCodes list of codes to be fixed as a comma separated |
60 @param fixCodes list of codes to be fixed as a comma separated |
59 string (string) |
61 string |
|
62 @type str |
60 @param noFixCodes list of codes not to be fixed as a comma |
63 @param noFixCodes list of codes not to be fixed as a comma |
61 separated string (string) |
64 separated string |
62 @param maxLineLength maximum allowed line length (integer) |
65 @type str |
63 @param inPlace flag indicating to modify the file in place (boolean) |
66 @param maxLineLength maximum allowed line length |
64 @param eol end of line character(s) (string) |
67 @type int |
|
68 @param blanklines tuple containg the number of blank lines before |
|
69 a top level class or function and before a method or nested class |
|
70 or function |
|
71 @type tuple of (int, int) |
|
72 @param inPlace flag indicating to modify the file in place |
|
73 @type bool |
|
74 @param eol end of line character(s) |
|
75 @type str |
65 @param backup flag indicating to create a backup before fixing |
76 @param backup flag indicating to create a backup before fixing |
66 anything (boolean) |
77 anything |
|
78 @type bool |
67 """ |
79 """ |
68 super(CodeStyleFixer, self).__init__() |
80 super(CodeStyleFixer, self).__init__() |
69 |
81 |
70 self.__filename = filename |
82 self.__filename = filename |
71 self.__origName = "" |
83 self.__origName = "" |
72 self.__source = sourceLines[:] # save a copy |
84 self.__source = sourceLines[:] # save a copy |
73 self.__fixCodes = [c.strip() for c in fixCodes.split(",") if c.strip()] |
85 self.__fixCodes = [c.strip() for c in fixCodes.split(",") if c.strip()] |
74 self.__noFixCodes = [ |
86 self.__noFixCodes = [ |
75 c.strip() for c in noFixCodes.split(",") if c.strip()] |
87 c.strip() for c in noFixCodes.split(",") if c.strip()] |
76 self.__maxLineLength = maxLineLength |
88 self.__maxLineLength = maxLineLength |
|
89 self.__blankLines = { |
|
90 "toplevel": blankLines[0], |
|
91 "method": blankLines[1], |
|
92 } |
77 self.fixed = 0 |
93 self.fixed = 0 |
78 |
94 |
79 self.__reindenter = None |
95 self.__reindenter = None |
80 self.__indentWord = self.__getIndentWord() |
96 self.__indentWord = self.__getIndentWord() |
81 |
97 |
140 "E262": self.__fixE261, |
156 "E262": self.__fixE261, |
141 "E271": self.__fixE221, |
157 "E271": self.__fixE221, |
142 "E272": self.__fixE221, |
158 "E272": self.__fixE221, |
143 "E273": self.__fixE221, |
159 "E273": self.__fixE221, |
144 "E274": self.__fixE221, |
160 "E274": self.__fixE221, |
145 "E301": self.__fixE301, |
161 "E301": self.__fixBlankLinesBefore, |
146 "E302": self.__fixE302, |
162 "E302": self.__fixBlankLinesBefore, |
147 "E303": self.__fixE303, |
163 "E303": self.__fixBlankLinesBefore, |
148 "E304": self.__fixE304, |
164 "E304": self.__fixE304, |
|
165 "E305": self.__fixBlankLinesBefore, |
|
166 "E306": self.__fixBlankLinesBefore, |
|
167 "E307": self.__fixBlankLinesBefore, |
|
168 "E308": self.__fixBlankLinesBefore, |
149 "E401": self.__fixE401, |
169 "E401": self.__fixE401, |
150 "E501": self.__fixE501, |
170 "E501": self.__fixE501, |
151 "E502": self.__fixE502, |
171 "E502": self.__fixE502, |
152 "E701": self.__fixE701, |
172 "E701": self.__fixE701, |
153 "E702": self.__fixE702, |
173 "E702": self.__fixE702, |
1333 newText = left + (" # " + right if right.strip() else right) |
1353 newText = left + (" # " + right if right.strip() else right) |
1334 self.__source[line] = newText |
1354 self.__source[line] = newText |
1335 # Whitespace around comment sign corrected. |
1355 # Whitespace around comment sign corrected. |
1336 return (1, "FE261", 0) |
1356 return (1, "FE261", 0) |
1337 |
1357 |
1338 def __fixE301(self, code, line, pos, apply=False): |
1358 def __fixBlankLinesBefore(self, code, line, pos, apply=False): |
1339 """ |
1359 """ |
1340 Private method to fix the need for one blank line. |
1360 Private method to fix the need for blank lines before class, function |
1341 |
1361 and method definitions. |
1342 Codes: E301 |
1362 |
|
1363 Codes: E301, E302, E303, E305, E306, E307, E308 |
1343 |
1364 |
1344 @param code code of the issue (string) |
1365 @param code code of the issue (string) |
1345 @param line line number of the issue (integer) |
1366 @param line line number of the issue (integer) |
1346 @param pos position inside line (integer) |
1367 @param pos position inside line (integer) |
1347 @keyparam apply flag indicating, that the fix should be applied |
1368 @keyparam apply flag indicating, that the fix should be applied |
1349 @return value indicating an applied/deferred fix (-1, 0, 1), |
1370 @return value indicating an applied/deferred fix (-1, 0, 1), |
1350 a message for the fix (string) and an ID for a deferred |
1371 a message for the fix (string) and an ID for a deferred |
1351 fix (integer) |
1372 fix (integer) |
1352 """ |
1373 """ |
1353 if apply: |
1374 if apply: |
1354 self.__source.insert(line - 1, self.__eol) |
1375 if code in ["E301", "E306", "E307"]: |
1355 # One blank line inserted. |
1376 blankLinesBefore = self.__blankLines["method"] |
1356 return (1, "FE301", 0) |
1377 elif code == "E308": |
1357 else: |
1378 blankLinesBefore = 1 |
1358 fixId = self.__getID() |
1379 else: |
1359 self.__stack.append((fixId, code, line, pos)) |
1380 blankLinesBefore = self.__blankLines["toplevel"] |
1360 return (-1, "", fixId) |
1381 |
1361 |
|
1362 def __fixE302(self, code, line, pos, apply=False): |
|
1363 """ |
|
1364 Private method to fix the need for two blank lines. |
|
1365 |
|
1366 Codes: E302 |
|
1367 |
|
1368 @param code code of the issue (string) |
|
1369 @param line line number of the issue (integer) |
|
1370 @param pos position inside line (integer) |
|
1371 @keyparam apply flag indicating, that the fix should be applied |
|
1372 (boolean) |
|
1373 @return value indicating an applied/deferred fix (-1, 0, 1), |
|
1374 a message for the fix (string) and an ID for a deferred |
|
1375 fix (integer) |
|
1376 """ |
|
1377 if apply: |
|
1378 # count blank lines |
1382 # count blank lines |
1379 index = line - 1 |
1383 index = line - 1 |
1380 blanks = 0 |
1384 blanks = 0 |
1381 while index: |
1385 while index: |
1382 if self.__source[index - 1].strip() == "": |
1386 if self.__source[index - 1].strip() == "": |
1383 blanks += 1 |
1387 blanks += 1 |
1384 index -= 1 |
1388 index -= 1 |
1385 else: |
1389 else: |
1386 break |
1390 break |
1387 delta = blanks - 2 |
1391 delta = blanks - blankLinesBefore |
1388 |
1392 |
1389 line -= 1 |
1393 line -= 1 |
1390 if delta < 0: |
1394 if delta < 0: |
1391 # insert blank lines (one or two) |
1395 # insert blank lines (one or two) |
1392 while delta < 0: |
1396 while delta < 0: |
1393 self.__source.insert(line, self.__eol) |
1397 self.__source.insert(line, self.__eol) |
1394 delta += 1 |
1398 delta += 1 |
1395 # %n blank line(s) inserted. |
1399 # %n blank line(s) inserted. |
1396 return (1, ("FE302+", 2 - blanks), 0) |
1400 return (1, ("FE302+", blankLinesBefore - blanks), 0) |
1397 elif delta > 0: |
1401 elif delta > 0: |
1398 # delete superfluous blank lines |
1402 # delete superfluous blank lines |
1399 while delta > 0: |
1403 while delta > 0: |
1400 del self.__source[line - 1] |
1404 del self.__source[line - 1] |
1401 line -= 1 |
1405 line -= 1 |
1402 delta -= 1 |
1406 delta -= 1 |
1403 # %n superfluous line(s) removed. |
1407 # %n superfluous line(s) removed. |
1404 return (1, ("FE302-", blanks - 2), 0) |
1408 return (1, ("FE302-", blanks - blankLinesBefore), 0) |
1405 else: |
1409 else: |
1406 return (0, "", 0) |
1410 return (0, "", 0) |
1407 else: |
|
1408 fixId = self.__getID() |
|
1409 self.__stack.append((fixId, code, line, pos)) |
|
1410 return (-1, "", fixId) |
|
1411 |
|
1412 def __fixE303(self, code, line, pos, apply=False): |
|
1413 """ |
|
1414 Private method to fix superfluous blank lines. |
|
1415 |
|
1416 Codes: E303 |
|
1417 |
|
1418 @param code code of the issue (string) |
|
1419 @param line line number of the issue (integer) |
|
1420 @param pos position inside line (integer) |
|
1421 @keyparam apply flag indicating, that the fix should be applied |
|
1422 (boolean) |
|
1423 @return value indicating an applied/deferred fix (-1, 0, 1), |
|
1424 a message for the fix (string) and an ID for a deferred |
|
1425 fix (integer) |
|
1426 """ |
|
1427 if apply: |
|
1428 index = line - 3 |
|
1429 while index: |
|
1430 if self.__source[index].strip() == "": |
|
1431 del self.__source[index] |
|
1432 index -= 1 |
|
1433 else: |
|
1434 break |
|
1435 # Superfluous blank lines removed. |
|
1436 return (1, "FE303", 0) |
|
1437 else: |
1411 else: |
1438 fixId = self.__getID() |
1412 fixId = self.__getID() |
1439 self.__stack.append((fixId, code, line, pos)) |
1413 self.__stack.append((fixId, code, line, pos)) |
1440 return (-1, "", fixId) |
1414 return (-1, "", fixId) |
1441 |
1415 |