| 1278 | yield from ex.format_exception_only(show_group=show_group, _depth=_depth+1, colorize=colorize) |
| 1279 | |
| 1280 | def _find_keyword_typos(self): |
| 1281 | assert self._is_syntax_error |
| 1282 | try: |
| 1283 | import _suggestions |
| 1284 | except ImportError: |
| 1285 | _suggestions = None |
| 1286 | |
| 1287 | # Only try to find keyword typos if there is no custom message |
| 1288 | if self.msg != "invalid syntax" and "Perhaps you forgot a comma" not in self.msg: |
| 1289 | return |
| 1290 | |
| 1291 | if not self._exc_metadata: |
| 1292 | return |
| 1293 | |
| 1294 | line, offset, source = self._exc_metadata |
| 1295 | end_line = int(self.lineno) if self.lineno is not None else 0 |
| 1296 | lines = None |
| 1297 | from_filename = False |
| 1298 | |
| 1299 | if source is None: |
| 1300 | if self.filename: |
| 1301 | try: |
| 1302 | with open(self.filename) as f: |
| 1303 | lines = f.read().splitlines() |
| 1304 | except Exception: |
| 1305 | line, end_line, offset = 0,1,0 |
| 1306 | else: |
| 1307 | from_filename = True |
| 1308 | lines = lines if lines is not None else self.text.splitlines() |
| 1309 | else: |
| 1310 | lines = source.splitlines() |
| 1311 | |
| 1312 | error_code = lines[line -1 if line > 0 else 0:end_line] |
| 1313 | error_code = textwrap.dedent('\n'.join(error_code)) |
| 1314 | |
| 1315 | # Do not continue if the source is too large |
| 1316 | if len(error_code) > 1024: |
| 1317 | return |
| 1318 | |
| 1319 | error_lines = error_code.splitlines() |
| 1320 | tokens = tokenize.generate_tokens(io.StringIO(error_code).readline) |
| 1321 | tokens_left_to_process = 10 |
| 1322 | import difflib |
| 1323 | for token in tokens: |
| 1324 | start, end = token.start, token.end |
| 1325 | if token.type != tokenize.NAME: |
| 1326 | continue |
| 1327 | # Only consider NAME tokens on the same line as the error |
| 1328 | the_end = end_line if line == 0 else end_line + 1 |
| 1329 | if from_filename and token.start[0]+line != the_end: |
| 1330 | continue |
| 1331 | wrong_name = token.string |
| 1332 | if wrong_name in keyword.kwlist: |
| 1333 | continue |
| 1334 | |
| 1335 | # Limit the number of valid tokens to consider to not spend |
| 1336 | # to much time in this function |
| 1337 | tokens_left_to_process -= 1 |